Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
a2cbc7b
setting up render functions
canaanwest Dec 11, 2017
dfddbde
adding taskListView to doc ready
canaanwest Dec 11, 2017
d3cbd09
creating quoteList
canaanwest Dec 11, 2017
1fea13d
adding buy and sell methods
canaanwest Dec 12, 2017
a7251e5
reimplementing simulator.start
canaanwest Dec 12, 2017
ab6ab46
identifying key pieces for displaying purchase
canaanwest Dec 13, 2017
780eec5
adding append function to quotelistview
canaanwest Dec 13, 2017
1194f85
documenting 'buyat' price issue
canaanwest Dec 13, 2017
f4744ac
fixing buy-price inaccuracy issue
canaanwest Dec 13, 2017
7973bbe
adding openquote model
canaanwest Dec 13, 2017
0331a3b
adding some pseudocode
canaanwest Dec 13, 2017
fca510c
modifying export statement for openquote
canaanwest Dec 13, 2017
3f0b3aa
renaming and importing open orders
canaanwest Dec 14, 2017
61357f1
adding open order list collection
canaanwest Dec 14, 2017
42e8653
reset to beginning of wave 3
canaanwest Dec 15, 2017
c88d769
recreating order-related files
canaanwest Dec 15, 2017
69eeae1
extending backbone functionality to new models
canaanwest Dec 15, 2017
e18f1f3
basic functionality for order_view; init and render
canaanwest Dec 15, 2017
d682570
init and render for orderlistview
canaanwest Dec 15, 2017
89dd69f
adding appendOrder function to quotelistview
canaanwest Dec 15, 2017
6b1bd7b
targeting form successfully
canaanwest Dec 15, 2017
becb2e5
functioning open-order list
canaanwest Dec 15, 2017
8d3c6b2
cancel button working on open orders
canaanwest Dec 15, 2017
ae439d0
inserting quote into order
canaanwest Dec 15, 2017
b09bed0
callback function for executing trade
canaanwest Dec 15, 2017
a0fb188
buy/sell trade working from limit order
canaanwest Dec 16, 2017
b366d46
cleaning up comments
canaanwest Dec 17, 2017
3e71093
error messages appending; preventing open orders from appending
canaanwest Dec 18, 2017
c2cf3b3
executing a trade was appending orders to open orders; seems to be fixed
canaanwest Dec 18, 2017
37e5837
fixing error with sell button
canaanwest Dec 18, 2017
b55d131
using testing to adjust validation code
canaanwest Dec 18, 2017
b05c78b
validations tested for order.js
canaanwest Dec 18, 2017
aa9d882
infrastructure for priceCheck tests
canaanwest Dec 18, 2017
19aa2dd
finishing testing for priceCheck/exection of buy/sell
canaanwest Dec 18, 2017
e85ecfc
fixing typo
canaanwest Dec 18, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ <h3>Order Entry Form</h3>
<label for="symbol">Symbol</label>
<select name="symbol">
<!-- Option entries should be added here using JavaScript -->
<% quote.each
<option name='HUMOR'>HUMOR</option>
<option name='CLOTH'>CLOTH</option>
<option name='HABIT'>HABIT</option>
<option name='SUPER'>SUPER</option>
</select>
<label for="price-target">Price</label>
<input type="number" name="price-target" step="0.10" min="0.00" placeholder="100.00" />
Expand Down
132 changes: 132 additions & 0 deletions spec/models/order_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import Order from 'models/order';
import Quote from 'models/quote';
import OrderList from 'collections/order_list'

describe('Order spec', () => {
let quote;
let order;
beforeEach(() => {
quote = new Quote({
symbol: 'HELLO',
price: 100.00,
});

order = new Order({
quote: quote,
buy: true,
symbol: 'HELLO',
targetPrice: 100.00,
})
});

describe('Create a valid order', () => {
it('Creates a buy order when given a valid symbol and price', () => {

order.set('targetPrice', 99.00)

expect(order.invalid()).toEqual(false);
});

it('Creates a sell order when given a valid symbol and price', () => {

order.set('buy', false);
order.set('targetPrice', 101.00)

expect(order.invalid()).toEqual(false);
})
})

describe('Validating Orders', () => {
describe('Invalid Orders', () => {
it('Price must be a number', () => {
order.set('targetPrice', 'cool')

expect(order.invalid()).toEqual({price: [ 'Invalid Price!'] });
});

it('Price must be greater than 0', () => {
order.set('targetPrice', 0)

expect(order.invalid()).toEqual({price: [ 'Invalid Price!']});
});


it('Symbol must not be empty', () => {
order.set('symbol', '')
order.set('targetPrice', 99.00)

expect(order.invalid()).toEqual({symbol: [ 'Invalid Symbol']});
});
})

describe('Buy Orders', () => {
it('targetPrice must be lower than market price', () => {

expect(order.invalid()).toEqual({price: [ 'Target Price higher than Market Price!'] });

});
})

describe('Sell Orders', () => {
beforeEach(() => {
order.set('buy', false)
});

it('targetPrice must be higher than marketPrice', () => {
order.set('targetPrice', 99);
expect(order.invalid()).toEqual({price: [ 'Target Price at or below Market Price!'] });
});
})

describe('priceCheck', () => {
describe('buyOrder', () => {
it('executes a buy when quote price drops below targetPrice', () => {
order.set('buy', true);
order.set('targetPrice', 99.00);

quote.set('price', 98.99);
order.priceCheck();

expect(quote.get('price')).toBe(99.99);
});

it('does not execute order until price drops below target', () => {

order.set('buy', true);
order.set('targetPrice', 99.00);

quote.set('price', 99.01);
order.priceCheck();

expect(quote.get('price')).toBe(99.01);

});
});

describe('sellOrder', () => {
it('executes order when quote exceeds targetPrice', () => {
order.set('buy', false);
order.set('targetPrice', 99.00);

quote.set('price', 99.01);
order.priceCheck();

expect(quote.get('price')).toBe(98.01);

});

it('does not execute order until quote exceeds targetPrice', () => {
order.set('buy', false);
order.set('targetPrice', 99.00);

quote.set('price', 98.99);
order.priceCheck();

expect(quote.get('price')).toBe(98.99);


})
})
});
});
});
42 changes: 39 additions & 3 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@ import 'foundation-sites/dist/foundation.css';
import 'css/app.css';

import $ from 'jquery';
import _ from 'underscore';

import Simulator from 'models/simulator';
import Quote from 'models/quote';
import QuoteView from 'views/quote_view';
import QuoteList from 'collections/quote_list';
import QuoteListView from 'views/quote_list_view';
import Order from 'models/order';
import OrderList from 'collections/order_list';
import OrderView from 'views/order_view';
import OrderListView from 'views/order_list_view.js';


const quoteData = [
{
Expand All @@ -24,12 +33,39 @@ const quoteData = [
price: 83.10,
},
];
//
// let bus = {}
// bus = _.extend(bus, Backbone.Events)

const quoteList = new QuoteList(quoteData)
const orderList = new OrderList();

$(document).ready(function() {
const quotes = new QuoteList(quoteData);
$(document).ready(() => {
const simulator = new Simulator({
quotes: quotes,
quotes: quoteList,
});

const quoteTemplate = _.template($('#quote-template').html());
const tradeTemplate = _.template($('#trade-template').html());
const orderTemplate = _.template($('#order-template').html());

const quoteListView = new QuoteListView({
model: quoteList,
quoteTemplate: quoteTemplate,
tradeTemplate: tradeTemplate,
el: 'main',
});

const orderListView = new OrderListView({
model: orderList,
template: _.template($('#order-template').html()),
el: 'main',
quotes: quoteList
});

console.log(orderListView);

orderListView.render()
quoteListView.render()
simulator.start();
});
9 changes: 9 additions & 0 deletions src/collections/order_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Backbone from 'backbone';
import Order from '../models/order';
import _ from 'underscore';

const OrderList = Backbone.Collection.extend({
model: Order,
});

export default OrderList;
59 changes: 59 additions & 0 deletions src/models/order.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import Backbone from 'backbone';

const Order = Backbone.Model.extend({
default: {
symbol: 'UNDEF',
targetPrice: 0.00,
},

initialize(params) {
if (!this.invalid()) {
this.listenTo(this.attributes.quote, 'change', this.priceCheck);
}
},

invalid() {
let errors = {}
if (this.get('symbol') === "" || this.get('symbol') === "UNEF") {
errors.symbol = ['Invalid Symbol'];
}

if (this.get('buy') && this.get('quote').get('price') <= this.get('targetPrice')) {
errors.price = ['Target Price higher than Market Price!' ]
}

if (!this.get('buy') && this.get('quote').get('price') >= this.get('targetPrice')) {
errors.price = ['Target Price at or below Market Price!' ]
}

if (isNaN(this.get('targetPrice')) || this.get('targetPrice') <= 0) {
errors.price = ['Invalid Price!']
}

if (Object.keys(errors).length > 0) {
return errors
} else {
return false
}

},

priceCheck() {
let toBuy = this.get('quote')
if (this.get('buy') && this.get('quote').get('price') <= this.get('targetPrice')) {
this.set('buy', true)
this.trigger('appendTrade', this.get('quote'))
this.destroy()
toBuy.buy();
}

if (!this.get('buy') && this.get('quote').get('price') >= this.get('targetPrice')) {
this.set('buy', false)
this.trigger('appendTrade', this)
this.destroy()
toBuy.sell();
}
}
});

export default Order;
20 changes: 18 additions & 2 deletions src/models/quote.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,28 @@ const Quote = Backbone.Model.extend({
},

buy() {
// Implement this function to increase the price by $1.00
const data = {
}
data.buy = true;
data.symbol = this.get('symbol');
data.price = this.get('price')

this.trigger('appendTrade', data);
this.set('price', this.get('price') + 1.00)

},

sell() {
// Implement this function to decrease the price by $1.00
const data = {
}
data.buy = false;
data.symbol = this.get('symbol');
data.price = this.get('price')

this.trigger('appendTrade', data);
this.set('price', this.get('price') - 1.00)
},

});

export default Quote;
68 changes: 68 additions & 0 deletions src/views/order_list_view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import Backbone from 'backbone';
import Order from '../models/order'
import OrderView from '../views/order_view'
import OrderList from '../collections/order_list';
import _ from 'underscore';

const OrderListView = Backbone.View.extend({
initialize(params){
this.template = params.template;
this.quotes = params.quotes;
this.listenTo(this.model, "update", this.render);
},

render() {
this.$('#orders').empty();
this.model.each((order) => {
const orderView = new OrderView({
model: order,
template: this.template,
tagName: 'li',
className: 'order'
});
this.$('#orders').append(orderView.render().$el);
})
return this
},

events: {
'click button.btn-buy': 'buyOrder',
'click button.btn-sell': 'sellOrder',
'click button.btn-cancel': 'cancelOrder'
},

buyOrder(e){
e.preventDefault();
this.appendOrder(true);
},

sellOrder(e) {
e.preventDefault();
this.appendOrder(false)
},

appendOrder(isBuy) {
this.$('.form-errors').empty();
let orderData = {
buy: isBuy
}

orderData.symbol = this.$(`[name='symbol']`).val();
orderData.targetPrice = parseFloat(this.$(`[name='price-target']`).val());
orderData.quote = this.quotes.findWhere({symbol: orderData.symbol})

const order = new Order(orderData);

if (!order.invalid()) {
this.model.add(order);
} else {
for (let errors in order.invalid()) {
order.invalid()[errors].forEach((error) => {
this.$('.form-errors').append(error)
})
}
}
},
})

export default OrderListView;
Loading