diff --git a/README.md b/README.md index 5e9749c..3c44d2e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,10 @@ -# Ada Trader -In this project you will create the Ada Trader platform for real-time stock trading. All trading will happen with fake stocks that represent previous Ada capstone projects, and will be connected to a "real-time" simulation that randomly adjusts the prices for each stock over time. +# Crypto Trader -This is an individual, [stage 2](https://github.com/Ada-Developers-Academy/pedagogy/blob/master/rule-of-three.md) project. +This was a project with the aim of learning more about event handling. Stocks, or in this case cryptocurrencies, are updated every second. You can buy, sell, view your trade history, and set up automatic orders. -![Ada Trader](ada-trader.gif) ## Learning Goals -This project should demonstrate your ability to: +This project should demonstrates the ability to: - Create Backbone Views of Models - Create Backbone Views of Collections - Create multiple Backbone Models that relate to each other @@ -15,16 +13,17 @@ This project should demonstrate your ability to: - Create Model instances from the user input in that form - Test model logic in a Backbone application -Although real terminology is used throughout this project, and the interface design is intended to loosely mimic real-world trading platforms, having actual trading "domain knowledge" is **NOT** a learning goal. If you're unclear on any of the terminology used in this document please consult the [vocabulary section](#trading-vocabulary) for an explanation, or ask Charles / other instructional staff! ## Setup ### Starting project -To get started with the Ada Trader project follow these steps: +To get started with the Crypto Trader project follow these steps: 1. Fork and clone this repository 1. `cd` into the directory for your cloned project -1. `npm install` -1. `npm start` +``` +npm install +npm start +``` ### Project Baseline This project uses the same structure as BackTREK and is based on our [backbone baseline](https://github.com/AdaGold/backbone-baseline). The baseline for this project includes some models and collections that have already been implemented: @@ -147,24 +146,3 @@ Additionally, when: - Each order executes, in the same manner as though the user had clicked "Buy" on the quote - Each order is removed from the open order list - Each order will never execute again - -### Testing -You should have tests for any validations your models have, as well as any custom functions that you create on those models. **Optional**: Write a test which verifies that limit orders are executed and destroyed when the relevant stock reaches the order's target price. - -### Advice -Before you start working on this wave, set aside time with another Adie and make a diagram to explore the flow of events, and make a plan of action. Discuss with that person where the pieces of information currently exist, and how they can flow and propagate to where they need to be. - -To get the list of symbols for the order entry form's drop-down, you may need to give the View that controls the form access to the quote collection. - -When removing a Backbone View from the page, that does not mean that the associated Model is gone! Be careful when cancelling an order, because an order that isn't shown on the page might still "hear" events that are triggered. You may observe this bug if the trade history continues to update with transactions from "lingering" orders, even if the order is not rendered within the list of open orders. - -The rules above for when an order can or cannot be created are a great place to use Backbone's model validation system! Make sure to include tests for those validations as well. - -## Trading Vocabulary -| Term | Definition | -|:-----|:-----------| -| Market Order | An order to purchase or sell a particular stock at the "market" price. [More details here.](https://www.investopedia.com/terms/m/marketorder.asp) | -| Limit Order | An order to purchase or sell a particular stock at a trader-specified "target" price. [More details here.](https://www.investopedia.com/terms/l/limitorder.asp) | -| Market Price | The **current** price for a stock, listed with its symbol in the quote ticker. This price will change over time. | -| Target Price | The desired price for a limit order to execute. This price is higher than "market" price if the order is to sell, and it is lower than the "market" price if the order is to buy. This price is fixed for a given order. | -| Trade Price | The price that a stock was traded at (either buy or sell) for a given trade. This price is fixed because it represents an historical event. | diff --git a/dist/index.html b/dist/index.html index 8a046fa..a7b86f0 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1,120 +1,127 @@ - - Ada Trader - - - - - - -
-
-

Ada Trader

-
- -
- -
- -
-

Quotes

-
-
    -
-
+ + Ada Trader + + + + + + +
+
+

Crypto Trader

+
+ +
+ +
+ +
+

Quotes

+
+
    +
-
-
+
-
-

Trade History

-
-
    -
-
-
+
+
+

Trade History

+
+
    +
+
+
+
+ +
-
- -
- -
-
-

Open Orders

-
-
    -
-
-
-
- -
-
-

Order Entry Form

-
- - - - - - - -
-
-
-
- -
+
+
+
+

Open Orders

+
+
    +
+
+
-
-
-
- -
-
- - - - - - +
+ + + + + + + + - - + + diff --git a/spec/collections/market_order_spec.js b/spec/collections/market_order_spec.js new file mode 100644 index 0000000..064e001 --- /dev/null +++ b/spec/collections/market_order_spec.js @@ -0,0 +1,24 @@ +import MarketOrder from 'collections/market_order'; + +describe('MarketOrder spec', () => { + let marketOrder; + beforeEach(() => { + marketOrder = new MarketOrder({ }); + }); + + describe('Instantiation', () => { + it('can be instantiated', () => { + + expect(marketOrder).toBeTruthy; + expect(marketOrder).toBeDefined; + }); + it('must have a model', () =>{ + expect(marketOrder.get('model')).toBeDefined; + // expect(marketOrder.get('model')).toEqual(Trade); + }); + // it('must be a type of MarketOrder', () =>{ + // expect(marketOrder). + // }); + }); + +}); diff --git a/spec/collections/quote_list_spec.js b/spec/collections/quote_list_spec.js new file mode 100644 index 0000000..97f5449 --- /dev/null +++ b/spec/collections/quote_list_spec.js @@ -0,0 +1,24 @@ +import QuoteList from 'collections/quote_list'; + +describe('QuoteList spec', () => { + let quoteList; + beforeEach(() => { + quoteList = new QuoteList({ }); + }); + + describe('Instantiation', () => { + it('can be instantiated', () => { + + expect(quoteList).toBeTruthy; + expect(quoteList).toBeDefined; + }); + it('must have a model', () =>{ + expect(quoteList.get('model')).toBeDefined; + // expect(marketOrder.get('model')).toEqual(Trade); + }); + // it('must be a type of MarketOrder', () =>{ + // expect(marketOrder). + // }); + }); + +}); diff --git a/spec/models/trade_spec.js b/spec/models/trade_spec.js new file mode 100644 index 0000000..bfeff43 --- /dev/null +++ b/spec/models/trade_spec.js @@ -0,0 +1,24 @@ +import Trade from 'models/trade'; + +describe('Trade spec', () => { + let trade; + beforeEach(() => { + trade = new Trade({ + + }); + }); + + describe('defaults', () => { + it('has a default buy', () => { + expect(trade.get('buy')).toBeTruthy; + }); + it('has a default price', () => { + expect(trade.get('buy')).toBeTruthy; + }); + it('has a default symbol', () => { + expect(trade.get('buy')).toBeTruthy; + }); + }); + + +}); diff --git a/src/app.js b/src/app.js index 03ec910..16c7c6a 100644 --- a/src/app.js +++ b/src/app.js @@ -1,35 +1,103 @@ import 'foundation-sites/dist/foundation.css'; import 'css/app.css'; + import $ from 'jquery'; +import _ from 'underscore'; +import Backbone from 'backbone'; import Simulator from 'models/simulator'; import QuoteList from 'collections/quote_list'; +// import LimitOrder from 'models/LimitOrder'; +import QuoteListView from './views/quote_list_view'; +import MarketOrder from 'collections/market_order'; +import MarketOrderView from './views/market_order_view'; +import LimitOrderList from './collections/limit_order_list'; +import LimitOrderListView from './views/limit_order_list_view'; + +let quoteTemplate; +let tradeTemplate; +let orderTemplate; +let dropdownTemplate; + +let hamRadio = {}; +hamRadio = _.extend(hamRadio, Backbone.Events); +// const quoteList = new QuoteList(); const quoteData = [ { - symbol: 'HUMOR', + symbol: 'ETHEREUM', price: 88.50, }, { - symbol: 'CLOTH', + symbol: 'ZCOIN', price: 81.70, }, { - symbol: 'HABIT', + symbol: 'BITCOIN', price: 98.00, }, { - symbol: 'SUPER', + symbol: 'LITECOIN', price: 83.10, }, ]; +// const renderOrderDropdown = function renderOrderDropdown(event){ +// const dropdownElement = $('#dropdown'); +// console.log('banana'); +// dropdownElement.html(''); +// console.log(event); +// console.log('this is event'); +// event.forEach( (symbol) => { +// let generatedHTML = dropdownTemplate({symbol: symbol}); +// dropdownElement.append(generatedHTML); +// }); +// }; + $(document).ready(function() { + quoteTemplate = _.template($('#quote-template').html()); + tradeTemplate = _.template($('#trade-template').html()); + orderTemplate = _.template($('#order-template').html()); + dropdownTemplate = _.template($('#dropdown-symbol').html()); + // hamRadio.listenTo(hamRadio, 'render_order_dropdown', renderOrderDropdown); + const quotes = new QuoteList(quoteData); + + console.log(quotes); + console.log('those are quotes'); const simulator = new Simulator({ quotes: quotes, }); + const quoteListView = new QuoteListView({ + el: 'main', + model: quotes, + template: quoteTemplate, + hamRadio: hamRadio, + }); + + const marketOrder = new MarketOrder(); + console.log(marketOrder); + console.log('that is the market order^^^^'); + const marketOrderView = new MarketOrderView({ + el:'main', + model: marketOrder, + template: tradeTemplate, + hamRadio: hamRadio, + }); + + // const limitOrder = new LimitOrder(); + const limitOrderList = new LimitOrderList(); + console.log(limitOrderList); + console.log('limit order list up there^^^'); + const limitOrderListView = new LimitOrderListView({ + el:'#order-workspace', + model: limitOrderList, + template: orderTemplate, + // dropdownTemplate: dropdownTemplate, + hamRadio: hamRadio, + }); + quoteListView.render(); simulator.start(); }); diff --git a/src/collections/limit_order_list.js b/src/collections/limit_order_list.js new file mode 100644 index 0000000..4efd51d --- /dev/null +++ b/src/collections/limit_order_list.js @@ -0,0 +1,8 @@ +import Backbone from 'backbone'; +import LimitOrder from 'models/limit_order'; + +const LimitOrderList = Backbone.Collection.extend({ + model: LimitOrder, +}); + +export default LimitOrderList; diff --git a/src/collections/market_order.js b/src/collections/market_order.js new file mode 100644 index 0000000..57c9269 --- /dev/null +++ b/src/collections/market_order.js @@ -0,0 +1,8 @@ +import Backbone from 'backbone'; +import Trade from 'models/trade'; + +const MarketOrder = Backbone.Collection.extend({ + model: Trade, +}); + +export default MarketOrder; diff --git a/src/models/limit_order.js b/src/models/limit_order.js new file mode 100644 index 0000000..77aa58f --- /dev/null +++ b/src/models/limit_order.js @@ -0,0 +1,10 @@ +import Backbone from 'backbone'; + +const LimitOrder = Backbone.Model.extend({ + defaults: { + symbol: 'UNDEF', + price: 0.00, + buy: true, + } +}); +export default LimitOrder diff --git a/src/models/quote.js b/src/models/quote.js index 4fbf466..d1356d2 100644 --- a/src/models/quote.js +++ b/src/models/quote.js @@ -8,10 +8,16 @@ const Quote = Backbone.Model.extend({ buy() { // Implement this function to increase the price by $1.00 + this.set('price', (this.get('price') + 1)); + + return this; }, sell() { // Implement this function to decrease the price by $1.00 + this.set('price', (this.get('price') - 1)); + + return this; }, }); diff --git a/src/models/trade.js b/src/models/trade.js new file mode 100644 index 0000000..af83a14 --- /dev/null +++ b/src/models/trade.js @@ -0,0 +1,16 @@ +import Backbone from 'backbone'; + +const Trade = Backbone.Model.extend({ + defaults: { + symbol: 'UNDEF', + price: 0.00, + buy: true, + }, + // newTrade(model){ + // console.log(model); + // console.log('that is the model^^'); + // return this; + // }, +}); + +export default Trade; diff --git a/src/views/limit_order_list_view.js b/src/views/limit_order_list_view.js new file mode 100644 index 0000000..dbf37ea --- /dev/null +++ b/src/views/limit_order_list_view.js @@ -0,0 +1,147 @@ +import Backbone from 'backbone'; +import LimitOrder from '../models/limit_order'; +import TradeView from './trade_view'; +import QuoteListView from './quote_list_view'; +import LimitOrderList from '../collections/limit_order_list'; +import LimitOrderView from './limit_order_view'; + +const LimitOrderListView = Backbone.View.extend({ + initialize(params){ + console.log(params); + console.log('these are the params'); + this.template = params.template; + this.hamRadio = params.hamRadio; + this.dropdownTemplate = params.dropdownTemplate; + this.listenTo(this.hamRadio, 'render_order_dropdown', this.renderOrderDropdown); + this.listenTo(this, 'order_purchase', this.addLimitOrder); + this.listenTo(this, 'order_sell', this.addLimitOrder); + this.listenTo(this.model, 'update', this.render); + this.listenTo(this.hamRadio, 'deleteOrder', this.deleteOrder); + }, + events:{ + 'click form button.btn-buy': 'addLimitOrder', + 'click form button.btn-sell': 'addLimitOrder', + // 'click button.btn-cancel': 'cancelLimitOrder', + }, + updateStatusMessageFrom(messageHash) { + const $statusMessages = this.$('#status-messages'); + $statusMessages.empty(); + Object.keys(messageHash).forEach((messageType) => { + messageHash[messageType].forEach((message) => { + $statusMessages.append(`
  • ${message}
  • `); + }); + }); + $statusMessages.show(); + }, + updateStatusMessage(message) { + this.updateStatusMessageFrom({ + 'Limit Order': [message], + }); + }, + + render() { + + this.$('#orders').empty(); + console.log('This is the limit order view model:' + this.model); + // debugger + this.model.each((order) => { + console.log(order); + console.log(this.template); + const limitOrderView = new LimitOrderView({ + model: order, + template: this.template, + tagName: 'li', + className: 'order', + hamRadio: this.hamRadio, + }); + this.$('#orders').prepend(limitOrderView.render().$el); + }); + + return this; + }, + renderOrderDropdown(symbols){ + // debugger; + this.$('#dropdown').empty(); + console.log(symbols); + console.log('this is event'); + + for( let symbol of symbols){ + // debugger + let optionSymbol = symbol; + + this.$('#dropdown').append(`` ); + }; + return this; + }, + getFormData(){ + const orderData = {}; + const targetPrice = + this.$(`#create-order input`).val(); + if (targetPrice !== '') { + orderData['targetPrice'] = parseFloat(targetPrice); + }; + const targetSymbol = this.$( `#create-order select`).val(); + if (targetPrice !== '') { + orderData['symbol'] = targetSymbol; + }; + let btnSell = event['target'].classList.contains('btn-sell') + if( btnSell){ + orderData['buy'] = false; + } + return orderData; + + }, + clearFormData() { + this.$(`#create-order input[name="price-target"]`).val(''); + }, + cancelLimitOrder(event){ + console.log(event); + + }, + addLimitOrder(event) { + event.preventDefault(); + console.log('cake'); + const formData = this.getFormData(); + console.log(quotes); + const formSymbol = formData['symbol']; + + // const foundQuote = quotes.findWhere({ symbol: formData['symbol'] }); + // const foundQuote = quotes.find(function(model) { return model.get('symbol') === formData['symbol']; }); + + // console.log(foundQuote); + // console.log('here is my found quote'); + this.hamRadio.trigger('find_quote_model', formData); + const newLimitOrder = new LimitOrder(formData); + if (newLimitOrder.isValid()) { + this.model.add(newLimitOrder); + this.clearFormData(); + console.log(newLimitOrder); + console.log('that is a new limit order '); + this.updateStatusMessage(`${newLimitOrder.get('symbol')} Limit Order Created!`); + + this.hamRadio.trigger('add_listener', this.model); + } + else { + console.log('ERROR'); + this.updateStatusMessageFrom(newTask.validationError); + newTask.destroy(); + } + return this; + }, + deleteOrder(quote) { + // debugger + let quoteName = quote.attributes.symbol; + let quotePrice = quote.attributes.price; + let quoteBuy = quote.attributes.buy; + this.model.each((order) => { + if(order.attributes.symbol === quoteName && order.attributes.buy === true && quotePrice <= order.attributes.targetPrice|| order.attributes.symbol === quoteName && quoteBuy === false && quotePrice >= order.attributes.targetPrice){ + // this.$('#trades').prepend(tradeView.render().$el); + order.destroy(); + } + }); + + // this.remove(); + }, +}); + +export default LimitOrderListView diff --git a/src/views/limit_order_view.js b/src/views/limit_order_view.js new file mode 100644 index 0000000..abd6bf4 --- /dev/null +++ b/src/views/limit_order_view.js @@ -0,0 +1,81 @@ +import Backbone from 'backbone'; +import LimitOrder from '../models/limit_order'; + + +const LimitOrderView = Backbone.View.extend({ + initialize(params){ + // debugger + console.log(params); + this.template = params.template; + this.hamRadio = params.hamRadio; + this.listenTo(this.model, 'change', this.render); + this.listenTo(this.model, 'update', this.checkTargetPrice); + this.listenTo(this.hamRadio, 'update_price', this.checkTargetPrice); + }, + addQuoteAttribute(quoteModel){ + if(!this.quoteModel){ + } + }, + render(){ + + const compiledTemplate = this.template(this.model.toJSON()); + + this.$el.html(compiledTemplate); + return this; + }, + events:{ + 'click button.btn-cancel': 'cancelLimitOrder', + // 'click form button.btn-buy': 'order_purchase', + // 'click form button.btn-sell': 'order_sell', + }, + cancelLimitOrder(){ + this.model.destroy(); + }, + checkTargetPrice(event){ + console.log('inside check target price'); + let thisSymbol = this.model.attributes.symbol; + let buyTrue = this.model.attributes.buy; + let targetPrice = this.model.attributes.targetPrice; + if(event['symbol'] == thisSymbol){ + if(buyTrue && event['price'] <= targetPrice){ + this.hamRadio.trigger(`buy_${thisSymbol}`); + this.model.destroy(); + console.log('destroyed order'); + }else if(!buyTrue && event['price'] >= targetPrice){ + this.hamRadio.trigger(`sell_${thisSymbol}`); + his.model.destroy(); + console.log('destroyed order'); + } + + }; + // console.log(' in the if statement and it matches'); + // console.log(this); + // console.log("inside addListener"); + // debugger + // let currentPrice = this.model.attributes.targetPrice; + // console.log(currentPrice); + // console.log('this price'); + // if (buy == true){ + // console.log('pie'); + // if(currentPrice <= price){ + // console.log('buying quote'); + // this.buyQuote(); + // this.trigger('deleteOrder'); + // console.log('deleted Order'); + // } + // } else if (currentPrice >= price) { + // console.log('selling quote'); + // this.sellQuote(); + // } + // return this; + + }, + // addQuoteAttribute(quote){ + // console.log('in add quote attribute'); + // if(this.get('symbol') == quote.get('symbol')){ + // this.quote = quote; + // } + // } +}); + +export default LimitOrderView; diff --git a/src/views/market_order_view.js b/src/views/market_order_view.js new file mode 100644 index 0000000..e73b0e1 --- /dev/null +++ b/src/views/market_order_view.js @@ -0,0 +1,59 @@ +import Backbone from 'backbone'; +import MarketOrder from '../collections/market_order'; +import TradeView from './trade_view' +import Trade from '../models/trade'; + +const MarketOrderView = Backbone.View.extend({ + initialize(params){ + this.template = params.template; + this.hamRadio = params.hamRadio; + this.listenTo(this.hamRadio, 'bought_quote', this.addTrade); + this.listenTo(this.hamRadio, 'sold_quote', (this.addTrade)); + this.listenTo(this.model, 'update', this.render); + }, + events:{ + // 'click #add-new-task': 'addTask', + }, + updateStatusMessageFrom(messageHash){ + + }, + updateStatusMessage(message){ + + }, + addTrade(model){ + console.log(event); + console.log('thats the event'); + let tradeData = {symbol: model.attributes.symbol, price: model.attributes.price} + let btnSell = event['target'].classList.contains('btn-sell'); + if(btnSell){ + tradeData['buy'] = false; + } + const newTrade = new Trade(tradeData); + + if(newTrade.isValid()){ + this.model.add(newTrade); + this.updateStatusMessage(`${newTrade.get('symbol')} Created!`); + }else{ + console.log('Something went wrong!'); + this.updateStatusMessageFrom(newTrade.validationError); + } + return newTrade; + }, + render(){ + + this.$('#trades').empty(); + this.model.each((trade) => { + const tradeView = new TradeView({ + model: trade, + template: this.template, + tagName: 'li', + className: 'trade' + }); + this.$('#trades').prepend(tradeView.render().$el); + }); + + return this; + }, +}); + +export default MarketOrderView; diff --git a/src/views/quote_list_view.js b/src/views/quote_list_view.js new file mode 100644 index 0000000..a78dbf4 --- /dev/null +++ b/src/views/quote_list_view.js @@ -0,0 +1,112 @@ +import Backbone from 'backbone'; +import QuoteView from './quote_view'; +import Quote from '../models/quote'; + +const QuoteListView = Backbone.View.extend({ + initialize(params){ + this.template = params.template; + this.hamRadio = params.hamRadio; + // this.uniqueQuoteSymbols(); + // this.listenTo(this.model, 'change', this.uniqueQuoteSymbols); + this.listenTo(this.model, 'update', this.render); + this.listenTo(this.hamRadio, 'find_quote_model', this.findQuoteBySymbol); + // this.listenTo(this.model, 'update', this.uniqueQuoteSymbols); + + }, + events:{ + + // this.listenTo(this.hamRadio, 'bought_quote', this.setModel); + // this.listenTo(this.hamRadio, 'sold_quote', this.setModel); + // 'click #add-new-task': 'addTask', + }, + updateStatusMessageFrom(messageHash){ + // const $statusMessage = this.$('#status-messages'); + // $statusMessage.empty(); + // Object.keys(messageHash).forEach((messageType)=>{ + // messageHash[messageType].forEach((message) =>{ + // $statusMessage.append(`
  • ${message}
  • `); + // }); + // }); + // $statusMessage.show(); + }, + updateStatusMessage(message){ + // this.updateStatusMessageFrom({ + // task: message, + // }); + }, + addQuote(event){ + event.preventDefault(); + const formData = this.getFormData(); + const newQuote = new Quote(formData); + if(newQuote.isValid()){ + this.model.add(newQuote); + this.clearFormData(); + this.updateStatusMessage(`${newQuote.get('quote_name')} Created!`); + }else{ + console.log('Something went wrong!'); + this.updateStatusMessageFrom(newQuote.validationError); + } + }, + clearFormData(){ + ['quote_name', 'assignee'].forEach((field) => { + this.$(`#add-quote-form input[name=${field}]`).val(''); + }); + }, + getFormData(){ + const quoteData = {}; + ['quote_name', 'assignee'].forEach((field) =>{ + const val = this.$(`#add-quote-form input[name=${field}]`).val(); + if (val !== ''){ + quoteData[field]=val; + } + }); + return quoteData; + }, + render(){ + // backbone has it worked out that when using jquery only searches within this specific view + this.$('#quotes').empty(); + + this.model.each((quote) => { + const quoteView = new QuoteView({ + model: quote, + template: this.template, + tagName: 'li', + className: 'quote', + hamRadio: this.hamRadio, + }); + this.$('#quotes').append(quoteView.render().$el); + + }); + this.uniqueQuoteSymbols(); + return this; + }, + findQuoteBySymbol(quoteData){ + console.log('in findQuoteBySymbol'); + let foundQuote; + this.model.each((quote) => { + if(quote.get('symbol')=== quoteData['symbol']){ + foundQuote = quote + this.hamRadio.trigger('send_quote', quote) + // foundQuote.listenTo('update', ); + }; + }); + + return foundQuote; + }, + uniqueQuoteSymbols(){ + // this.$('#quotes').empty(); + let quoteSymbols = []; + this.model.each((quote) => { + let symbol = quote.get('symbol'); + if( !quoteSymbols.includes(symbol)){ + quoteSymbols.push(symbol); + }; + }); + // debugger; + this.hamRadio.trigger('render_order_dropdown', quoteSymbols); + return quoteSymbols; + }, + +}); + +export default QuoteListView; diff --git a/src/views/quote_view.js b/src/views/quote_view.js new file mode 100644 index 0000000..edeafcf --- /dev/null +++ b/src/views/quote_view.js @@ -0,0 +1,75 @@ +import Backbone from 'backbone'; +import Quote from '../models/quote'; + +const QuoteView = Backbone.View.extend({ + initialize(params){ + this.template = params.template; + this.hamRadio = params.hamRadio; + this.listenTo(this.model, 'change', this.render); + this.listenTo(this.hamRadio, 'add_listener', this.addListener); + this.listenTo(this.hamRadio, `buy_${this.model.attributes.symbol}`, this.buyQuote); + this.listenTo(this.hamRadio, `sell_${this.model.attributes.symbol}`, this.buyQuote); + }, + render(){ + const compiledTemplate = this.template(this.model.toJSON()); + this.$el.html(compiledTemplate); + let priceObject = {symbol: this.model.attributes.symbol, price: this.model.attributes.price} + console.log('in quote view render'); + this.hamRadio.trigger('update_price', priceObject); + + return this; + }, + events:{ + 'click button.btn-buy': 'buyQuote', + 'click button.btn-sell': 'sellQuote', + + }, + addListener(event){ + + let listOrderAttributes = event.models[0].attributes; + let thisSymbol = this.model.attributes.symbol; + let buyTrue = event.models[0].attributes['buy']; + let targetPrice = listOrderAttributes['targetPrice']; + if(listOrderAttributes['symbol'] == thisSymbol){ + console.log(' in the if statement and it matches'); + console.log(this); + console.log("inside addListener"); + this.listenTo(this.model, 'update', this.checkTargetPrice(targetPrice, buyTrue)); + } + return this; + }, + checkTargetPrice(price, buy){ + let currentPrice = this.model.attributes.price; + console.log(currentPrice); + console.log('this price'); + if (buy == true){ + console.log('pie'); + if(currentPrice <= price){ + console.log('buying quote'); + this.buyQuote(); + // this.hamRadio.trigger('deleteOrder', this.model); + console.log('deleted Order'); + } + } else if (currentPrice >= price) { + console.log('selling quote'); + this.sellQuote(); + // this.hamRadio.trigger('deleteOrder', this.model); + } + // return this; + }, + + buyQuote(){ + + this.model.buy(); + this.hamRadio.trigger('sold_quote', this.model); + return this; + }, + sellQuote(){ + this.model.sell(); + this.hamRadio.trigger('bought_quote', this.model); + console.log(this.model); + return this; + }, + +}); +export default QuoteView; diff --git a/src/views/trade_view.js b/src/views/trade_view.js new file mode 100644 index 0000000..7063c1e --- /dev/null +++ b/src/views/trade_view.js @@ -0,0 +1,37 @@ +import Backbone from 'backbone'; +import Trade from '../models/trade'; + +const TradeView = Backbone.View.extend({ + initialize(params){ + this.template = params.template; + this.hamRadio = params.hamRadio; + + this.listenTo(this.model, 'change', this.render) + + }, + events:{ + // 'click button.btn-cancel': 'cancelLimitOrder', + }, + render(){ + const compiledTemplate = this.template(this.model.toJSON()); + this.$el.html(compiledTemplate); + + return this; + }, + addTrade(event){ + this.model.newTrade(event); + return this; + }, + cancelLimitOrder(){ + this.model.destroy(); + } + + // buyQuote(event){ + // this.model.buy(); + // }, + // sellQuote(event){ + // this.model.sell(); + // }, + +}); +export default TradeView;