def test_buy(self): #buy is trade withe positive quantity acct = Account.from_pk(jimid) result = acct.trade("aapl", 3, 100) #result is mv of trade result2 = acct.trade("pton", 1, 100) trade_hist = Trade.from_account_and_ticker(jimid, "aapl") trade_hist2 = Trade.from_account_and_ticker(jimid, "pton") pos_test = Position.from_account_and_ticker(jimid, "aapl") quant = pos_test.total_quantity self.assertAlmostEqual(result, 300, "mv = px * quantity") self.assertAlmostEqual( acct.balance, 600, "balance started at 1000 trades cost 400 so new bal should be 600") self.assertEqual( len(trade_hist), 2, "there shouold only be 2 trades with aapl one trade here and one from seed" ) self.assertEqual( len(trade_hist2), 1, "there shouold only be 1 trade with pton from here and one from seed" ) self.assertAlmostEqual( quant, 8, "seed gave 5 shs of aapl and this test bought 3 total position is now 8" ) with self.assertRaises( InsufficientFundsError ): #"tring buy shs that cost more then your balance causes an error" result3 = acct.trade("pton", 500, 100)
def buy(self, ticker, amount): """ if balance is greater than or equal to amount * current price, updates a Position if it exists, or creates a new Position for this ticker in our database. saves a new Trade object and updates self.balance""" # check current price price = get_price(ticker) * amount # check our balance if self.balance < price: raise ValueError("Insufficient Funds") # get our current position position = self.get_position_for(ticker) # add shares to position position.number_shares += amount # subtract from self.balance self.balance -= price # save the Trade trade = Trade(ticker=ticker, quantity=amount, type=1, price=price, account_pk=self.pk) trade.save() # save the Position, save the Account position.save() self.save()
def sell(self, ticker, amount): #Get account and positions details account = self.get_account() position = self.get_position_for(ticker) amount = int(amount) #Check stock exists and if so retrieve current price quote_price = get_price(ticker) if not quote_price: # raise KeyError msg = "Input Ticker doesn't exist" else: #Check sufficient shares if position.shares == 0 or amount > position.shares: # raise ValueError msg = "Insufficient shares" else: #Insert Trade row new_trade = Trade(accounts_pk=self.pk, ticker=ticker, \ volume=amount*-1, price=quote_price) new_trade.save() #Update Position row new_position = Position(pk=position.pk, accounts_pk=self.pk, ticker=ticker, \ shares=position.shares - amount) new_position.save() #Update balance on Account row new_balance = Account(pk=self.pk, username=account.username, \ password_hash=account.password_hash, \ balance=account.balance + (amount*quote_price), \ api_key=account.api_key) new_balance.save() msg = "Sell transaction completed successfully" return msg
def sell(self, ticker, amount): position = self.get_position_for(ticker) price = get_price(ticker)[1] trade = Trade(accounts_pk = self.pk, ticker=ticker, price=price, volume=amount) if position.shares < int(amount): raise ValueError("You do not have enough shares to sell") else: position.shares -= int(amount) # position.shares -= int(amount) print(position.shares) self.balance += int(amount) * price position.save() trade.save() self.save()
def sell(self, ticker, amount): """ make a sale. raise KeyErrror for a non-existent stock and ValueError for insufficient shares. will create a new Trade object, modify a Position, and alter the self.balance. returns nothing.""" position = self.get_position_for(ticker) if amount > position.shares: raise.ValueError('insufficient shares') price = get_price(ticker) trade = Trade(accounts_pk = self.pk, ticker = ticker, price = price, volume=-amount) position.shares -= amount self.balance += amount * price position.save() trade.save() self.save()
def buy(self, ticker, amount, current_price, total_cost): """ make a purchase. raise KeyError for a non-existent stock and ValueError for insufficient funds. will create a new Trade and modify a Position and alters the user's balance. returns nothing """ position = self.get_position_for(ticker) trade = Trade(accounts_pk=self.pk, ticker=ticker, price=current_price, volume=amount) self.balance -= int(total_cost) position.shares += int(amount) position.save() trade.save() self.save()
def get_trades_for(self, ticker): """ return all of a user's trades for a given ticker """ trade = Trade.select_one_where( "WHERE ticker = ? AND accounts_pk = ?", (ticker, self.pk)) if trade is None: return None #Todo: Info msg stating no trades for that ticker return trade
def buy(self, ticker, amount, current_price): position = self.get_position_for(ticker) total_cost = int(amount) * int(current_price[1]) if int(self.balance) > total_cost: trade = Trade(accounts_pk = self.pk, ticker=ticker, price=current_price[1], volume = amount) self.balance -= total_cost print(type(position.shares)) print(type(amount)) input() position.shares += int(amount) position.save() trade.save() self.save() else: raise ValueError("insufficient funds")
def test_sell(self): #sell is the same function, trade, as buy with negtive quantity # it has opposite effect on cash balance and position acct = Account.from_pk(jimid) result = acct.trade("aapl", -2, 100) #result is mv of trade pos_test = Position.from_account_and_ticker(jimid, "aapl") quant = pos_test.total_quantity trade_hist = Trade.from_account_and_ticker(jimid, "aapl") self.assertAlmostEqual(result, 200, "mv = quantity * px") self.assertAlmostEqual( quant, 3, "seed gave 5 shs of aapl and this test sold 2; total position is now 3" ) self.assertAlmostEqual(acct.balance, 1200, "started with 1000 and sell give +200") self.assertEqual( len(trade_hist), 2, "there shouold only be 2 trades with aapl one trade here and one from seed" ) with self.assertRaises( InsufficientSharesError ): #"tring sell shs that you don't have causes an error" result3 = acct.trade("pton", -10, 100) with self.assertRaises( InsufficientSharesError ): #"tring sell more shs than you have causes an error" result3 = acct.trade("aapl", -20, 100)
def sell(self, ticker, amount): """ if current Postion.number_shares is greater than or equal to amount, updates a Position, saves a new Trade object and updates self.balance""" position = self.get_position_for(ticker) price = get_price(ticker) * amount if position.number_shares < amount: raise ValueError("Insufficient stocks") print(position.ticker, ": ", position.number_shares) position.number_shares -= amount self.balance += price trade = Trade(ticker=ticker, quantity=amount, type=0, price=price, account_pk=self.pk) # changed type from 1 to 0 trade.save() position.save() self.save()
def buy(self, ticker, amount): """ if balance is greater than or equal to amount * current price, updates a Position if it exists, or creates a new Position for this ticker in our database. saves a new Trade object and updates self.balance""" price = get_price(ticker) * amount if self.balance < price: raise ValueError("Insufficient Funds") position = self.get_position_for(ticker) position.number_shares = +amount self.balance -= price trade = Trade(ticker=ticker, quantity=amount, type=1, price=price, account_pk=self.pk) trade.save() position.save() self.save()
def buy(self, ticker, amount): #Get account details account = self.get_account() #Check stock exists and if so retrieve current price quote_price = get_price(ticker) if not quote_price: # raise KeyError msg = "Input Ticker doesn't exist" else: #Check sufficient funds quote_price = float(quote_price) amount = float(amount) if not account.balance >= amount * quote_price: #raise ValueError msg = "Insufficient funds" else: #Insert Trade row new_trade = Trade(accounts_pk=self.pk, ticker=ticker, \ volume=amount, price=quote_price) new_trade.save() #Update or Insert Position row position = self.get_position_for(ticker) if position.shares == 0: #Insert new_position = Position(accounts_pk=self.pk, ticker=ticker, shares=amount) else: #Update new_position = Position(pk=position.pk, accounts_pk=self.pk, ticker=ticker, \ shares=position.shares + amount) new_position.save() #Update balance on Account row new_balance = Account(pk=self.pk, username=account.username, \ password_hash=account.password_hash, \ balance=account.balance - (amount*quote_price), \ api_key=account.api_key) new_balance.save() msg = "Buy transaction completed successfully" return msg
def get_all_trades_json(self): all_trades = {} trades = Trade.select_many_where("WHERE accounts_pk = ?", (self.pk, )) for trade in trades: all_trades[trade.pk] = { "ticker": trade.ticker, "volume": trade.volume, "price": trade.price } return all_trades
def buy(self, ticker, amount): price = get_price(ticker) if self.balance < price * amount: raise ValueError("Insufficient Funds") self.balance -= price * amount trade = Trade() trade.account_pk = self.pk trade.ticker = ticker trade.price = price trade.volume = amount trade.time = time.time() position = self.get_position_for(ticker) position.shares += amount self.save() trade.save() position.save()
def sell(self, ticker, amount): price = get_price(ticker) position = self.get_position_for(ticker) if position.shares < amount: raise ValueError("Insufficient Shares to Sell or Position Does not Exist") self.balance += price * amount trade = Trade() trade.account_pk = self.pk trade.ticker = ticker trade.price = price trade.volume = -1 * amount trade.time = time.time() position.shares -= amount self.save() trade.save() position.save()
def get_trades_by_ticker_json(self, ticker): trades = {} ticker_trades = Trade.select_many_where( "WHERE accounts_pk = ? AND ticker = ?", (self.pk, ticker)) if ticker_trades: for trade in ticker_trades: trades[trade.pk] = { "ticker": trade.ticker, "volume": trade.volume, "price": trade.price } return trades
def get_trades_json(self): trades = {} all_trades = Trade.select_many_where("WHERE accounts_pk = ?", (self.pk, )) for trade in all_trades: trades[trade.pk] = { 'ticker': trade.ticker, 'volume': trade.volume, 'price': trade.price, 'time': trade.time } return trades
def trades_for_json(self, ticker): trades_for_person = {} all_trades_for_person = Trade.select_many_where( "WHERE accounts_pk = ? AND ticker = ?", (self.pk, ticker)) for trade_one in all_trades_for_person: trades_for_person[trade_one.pk] = { 'ticker': trade_one.ticker, 'volume': trade_one.volume, 'price': trade_one.price, 'time': trade_one.time } return trades_for_person
def buy(self,symbol,amount): price=get_price(symbol) if self.balance<price*amount: raise ValueError("You do not have enough money for this stock") self.balance-=price*amount trade=Trade() trade.account_pk=self.pk trade.ticker=symbol trade.price=price trade.volume=amount trade.time=time.time() position=self.get_position_for(symbol) position.shares+=amount self.save() trade.save() position.save()
def sell(self, ticker, amount): """ if current Position.number_shares is greater than or equal to amount, updates a Position if it exists, or creates a new Position for this ticker in our database. saves a new Trade object and updates self.balance""" #check current price price = get_price(ticker) * amount position = self.get_position_for(ticker) if position.number_shares < amount: raise ValueError("You don't have enough Share") position.number_shares -=amount self.balance += price trade = Trade(ticker=ticker,quantity=amount,type=1, price=price,account_pk=self.pk) trade.save() position.save() self.save()
def show_trades_by_account(self): trades = Trade.from_account_pk(self.pk) if trades == []: print("\nYou have not made any trades yet.\n") else: for trade in trades: if trade.quantity < 0: trade_type = "Sell" else: trade_type = "Buy" print( f"Trade Type: {trade_type}, Ticker: {trade.ticker.upper()}, Quantity: {abs(trade.quantity)}, Price: ${trade.price}, Market Value: ${round(abs(trade.price*trade.quantity),2)}, Created At: {ctime(trade.created_at)}" ) print("\n")
def seed(dbpath=DBPATH): ORM.dbpath = dbpath mike_bloom = Account(username='******', balance=10000.00) mike_bloom.set_password('password') mike_bloom.save() # trade for a purchase of 10 shares yesterday # trade for a sell of 5 shares today buy_trade = Trade(accounts_pk = mike_bloom.pk, ticker='tsla', volume=10, price=100.0) sell_trade = Trade(accounts_pk=mike_bloom.pk, ticker='tsla', volume=5, price=200.0) buy_trade.save() sell_trade.save() tsla_position = Position(ticker='tsla', shares=5, accounts_pk=mike_bloom.pk) tsla_position.save()
def show_trades_by_account_and_ticker(self, ticker): trades = Trade.from_account_and_ticker(self.pk, ticker) if trades == []: view.never_traded_invalid( ) #TODO: run it through the quote function and include try/except for invalid ticker else: for trade in trades: if trade.quantity < 0: trade_type = "Sell" else: trade_type = "Buy" print( f"Trade Type: {trade_type}, Ticker: {trade.ticker.upper()}, Quantity: {abs(trade.quantity)}, Price: ${trade.price}, Market Value: ${round(abs(trade.price*trade.quantity), 2)}, Created At: {ctime(trade.created_at)}" ) print("\n")
def sell(self, ticker, quantity): """ SELL stock. checks if a stock exists in the user's positions and has sufficient shares. creates a new Trade and modifies the Position as well as adding to the user's balance. returns nothing """ trade = Trade() current_price = get_price(ticker) mv = current_price * int(quantity) trade.account_id = self.account_id trade.volume = quantity trade.ticker = ticker trade.price = current_price trade.market_value = mv * -1 self.balance += mv self.update_balance() position = Position() position.account_id = self.account_id position.ticker = trade.ticker stored_position = Position.select_one_where( 'WHERE account_id=? and ticker=?', (position.account_id, position.ticker)) if stored_position: position.num_shares = stored_position.num_shares position.position_id = stored_position.position_id if stored_position.num_shares < trade.volume or stored_position.num_shares == 0: transaction_error('Not enough shares') else: trade.save() if stored_position: position.num_shares = trade.volume else: position.num_shares -= trade.volume position.save() else: transaction_error('Ticker {} is invalid'.format(trade.ticker))
def get_all_trades_json(self): all_trades = [] trades = Trade.select_many_where("WHERE accounts_pk = ?", (self.pk, )) for trade in trades: one_trade = {} ts = int(trade.time) timestamp = datetime.utcfromtimestamp(ts).strftime( '%m-%d-%Y, %H:%M:%S') one_trade[trade.pk] = { "ticker": trade.ticker, "volume": trade.volume, "price": trade.price, "time": timestamp } all_trades.append(one_trade) return all_trades
def buy(self, ticker, quantity): """ BUY stock. checks if a stock exists in the user's positions and has sufficient shares. creates a new Trade and modifies the Position as well as adding to the user's balance. returns nothing """ trade = Trade() current_price = get_price(ticker) mv = current_price * int(quantity) if self.balance < mv: transaction_error('Insufficient funds') else: trade.account_id = self.account_id trade.volume = quantity trade.ticker = ticker trade.price = current_price trade.market_value = mv self.balance -= mv self.update_balance() position = Position() position.account_id = self.account_id position.ticker = trade.ticker stored_position = Position.select_one_where( 'WHERE account_id=? and ticker=?', (position.account_id, position.ticker)) if stored_position: position.position_id = stored_position.position_id position.num_shares = stored_position.num_shares position.num_shares += trade.volume else: position.num_shares = trade.volume trade.save() position.save()
def trade(self, ticker, quantity, price=None): quantity = int(quantity) quote = get_quote(ticker) if price == None: if quote['iexAskPrice'] != 0 and quote[ 'iexAskPrice'] is not None: ##added the or price = float(quote['iexAskPrice']) else: price = float(quote['latestPrice']) else: #price != None price = price market_value = price * quantity position = Position.from_account_and_ticker(self.pk, ticker) if market_value > 0: #BUY if self.balance < market_value: # return None raise InsufficientFundsError else: self.balance -= market_value self.save() else: #SELL so market_value < 0 if position.total_quantity < (quantity * -1): # raise InsufficientSharesError # return None else: #where we have more shares than whe are selling self.balance += market_value * -1 self.save() position.total_quantity += quantity #position.quantity is total quantity position.save() # now, create a new Trade object trade = Trade(ticker=ticker, account_pk=self.pk, quantity=quantity, price=price) trade.save() return abs(market_value) #had return True
def trades_for(self, ticker): """ return all of a user's trades for a given ticker """ return Trade.select_many_where("WHERE accounts_pk = ? AND ticker = ?", (self.pk, ticker))
def get_trades(self): """ return all of the user's trades ordered by time. returns a list of Trade objects """ return Trade.select_many_where("WHERE accounts_pk = ?", (self.pk, ))
def get_trades_for(self, ticker): """ return all Trades where account_pk == self.pk. returns a list of Trade objects """ return Trade.all_from_where_clause("WHERE account_pk=? AND ticker=?", (self.pk, ticker))