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 test_save_insert(self): tester = Position(account_pk = jimid, total_quantity = 10, ticker = "pton") tester.save() result = Position.all() self.assertEqual(len(result),2, "len =2 b/c seeded 1 pos and added another") self.assertEqual(result[0].ticker,"aapl","all func populates attributes, checking first for row[0] / pk1" ) self.assertEqual(result[1].ticker,"pton","all func populates attributes, checking email for row[1] / pk2" )
def play_hand(self, feedback_file_name, action): date_time = datetime.datetime.now().strftime("%m-%d-%y %H:%M:%S") deck = Deck() deck.create() deck.shuffle() hand = Hand() hand.get_hand(deck) hand.order_hand() hand_type = hand.hand_type() position = Position() position.current_position(self.num_players) position_min = position.min_open() r = Range(self.hand_range) correct_decision, hand_percent, total_cards = r.correct_decision( hand_type, position_min) min_open_hand = r.min_open_card(position_min) decision = Decision(action).decision() if self.show_feedback: if decision == correct_decision: feedback = "Correct" # report feedback self.score += 1 else: feedback = "Incorrect" # report feedback feedback_file_name.save_hand(self.hand_num, date_time, self.hand_range, feedback, position, position_min, min_open_hand, hand, hand_type, hand_percent, decision, correct_decision, self.score) self.hand_num += 1 else: self.hand_num += 1 return self.hand_num
def get_position_for(self, ticker): """ return a specific Position object for the user. if the position does not exist, return a new Position with zero shares. Returns a Position object """ position = Position.select_one_where( "WHERE ticker = ? AND accounts_pk = ?", (ticker, self.pk)) if position is None: return Position(ticker=ticker, accounts_pk=self.pk, shares=0) return position
def get_position_for(self, ticker): """ return Position for a given ticker symbol for this Account. returns a list of Position objects """ ticker = ticker.lower() position = Position.all_from_where_clause( "WHERE account_pk=? AND ticker=?", (self.pk, ticker)) if not Position: return Position(ticker=ticker, number_shares=0, account_pk=self.pk) return position
def test_smallest_random_position(self): """This makes the only valid choice become the button.""" from app.players import Players session_size = str(Players(3)) num_players = int(session_size) position = Position() cp = position.current_position(num_players) assert num_players == 3 assert cp == "Button"
def test_default_random_position(self): """Could improve this test in relation to what the current position becomes. However, if there was an error it could be hard to track down because the random functionality isn't always reproducible. Therefore, this test is to confirm there are no errors with the default table size. Another test case that saves data to a file will record what position is getting randomly assigned.""" from app.players import Players session_size = str(Players()) # Default is 10 players. num_players = int(session_size) position = Position() cp = position.current_position(num_players) assert num_players == 10 assert len(cp) > 5 # The button has the shortest length of 6 characters. These names are also constants (POSITIONS) so they shouldn't be changed; i.e. changing 'button' to 'b'.
def positions(api_key, ticker): if Account.api_authenticate(api_key) == None: msg = "Invalid login credentials, pls retry" else: pk = Account.api_authenticate(api_key).pk user_position = Account(pk=pk) position = user_position.get_position_for(ticker) valuation = Position() getval = valuation.current_value(ticker, position.shares) msg = "Ticker Symbol: {}, Shares: {}, Valuation: ${}".format(position.ticker, position.shares, getval) return jsonify({'message':msg})
def positions(name, password, ticker): if not Account.login(name, password): msg = "Invalid login credentials, pls retry" else: pk = Account.login(name, password).pk user_position = Account(pk=pk) position = user_position.get_position_for(ticker) valuation = Position() getval = valuation.current_value(ticker, position.shares) msg = "Ticker Symbol: {}, Shares: {}, Valuation: ${}".format( position.ticker, position.shares, getval) return jsonify({'message': msg})
def allpositions(api_key): if Account.api_authenticate(api_key) == None: msg = "Invalid login credentials, pls retry" else: pk = Account.api_authenticate(api_key).pk user_positions = Account(pk=pk) positions = user_positions.get_positions() msg = {'positions':[]} for position in positions: valuation = Position() getval = valuation.current_value(position.ticker, position.shares) msg['positions'].append("Ticker Symbol: {}, Shares: {}, Valuation: ${}".format(position.ticker, position.shares, getval)) return jsonify({'message':msg})
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 tsla_position = Position(ticker='tsla', shares=5, account_pk=mike_bloom.values['pk']) tsla_position.save()
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 get_positions(self): view = View() positions = Position.select_many_where("WHERE accounts_pk = ?", (self.pk, )) for position in positions: view.positions(self, position) return positions
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 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 get_position_for_json(self, ticker): get_positions = {} position = Position.select_one_where( "WHERE ticker = ? AND accounts_pk = ?", (ticker, self.pk)) get_positions[position.ticker] = { 'ticker': position.ticker, 'shares': position.shares } return get_positions
def leaderboard_stats_by_acct(self, account_pk, username): positions = Position.all_from_account(account_pk) stock_mv = [] for x in positions: if x.total_quantity > 0: stock_mv.append(x.value()) print( f"Account pk: {account_pk}, Username: {username}, Total Stock Value: ${round(sum(stock_mv),2)}, Cash Balance: ${round(self.balance,2)}, Total Portfolio Value: ${round(sum(stock_mv),2)+round(self.balance,2)}" )
def is_check_for_current_player(self): king_position = self.get_king_position(self.current_player_color) for x_index, line in enumerate(self.board): for y_index, square in enumerate(line): if square.color == self.current_player_color * (-1): for target in square.get_targets(Position(x_index, y_index), self.board): if king_position == target: return True return False
def is_check_for_current_player(self): king_position = self.get_king_position(self.current_player_color) # Взяти позицію короля for x_index, line in enumerate(self.board): # Для всіх фігур суперника перевірити, чи є хоч одна, для якої можливий хід - це король поточного гравця for y_index, square in enumerate(line): if square.color == self.current_player_color * (-1): for target in square.get_targets(Position(x_index, y_index), self.board): if king_position == target: return True return False
def get_positions_json(self): positions = {} all_positions = Position.select_many_where("WHERE accounts_pk = ?", (self.pk, )) for position in all_positions: positions[position.ticker] = { "ticker": position.ticker, "shares": position.shares } return positions
def get_positions_json(self): positions = {} get_position = Position.select_many_where( "WHERE accounts_pk = ? AND shares = ?", (self.pk, )) for position in get_position: positions[position.ticker] = { 'ticker': position.ticker, 'shares': position.shares } return position
def is_checkmate_for_current_player(self): if not self.is_check_for_current_player(): # Перевірити, чи є шах return False else: for x_index, line in enumerate(self.board): # Для всіх фігур поточного гравця перевірити, чи зникне шах після будь якого можливого ходу for y_index, square in enumerate(line): if square.color == self.current_player_color: targets = self.get_targets_of_parsed_position(Position(x_index, y_index)) if len(targets) > 0: return False return True
def is_checkmate_for_current_player(self): if not self.is_check_for_current_player(): return False else: for x_index, line in enumerate(self.board): for y_index, square in enumerate(line): if square.color == self.current_player_color: targets = self.get_targets_of_parsed_position(Position(x_index, y_index)) if len(targets) > 0: return False return True
def get_positions_json(self): positions = [] all_positions = Position.select_many_where("WHERE accounts_pk = ?", (self.pk, )) for position in all_positions: posish = {} posish[position.ticker] = { "ticker": position.ticker, "shares": position.shares } positions.append(posish) return positions
def positions_sub_menu(pk): retrieve_bal = Account(pk=pk) views.generic_msg("Your current balance = {}".format( retrieve_bal.get_account().balance)) while True: position_choice = views.position_menu() if position_choice is None: #Bad input views.generic_msg( "Please enter a number that corresponds to a stated option") elif position_choice == 3: #Exit break elif position_choice == 1: #Retrieve and display a given position ticker = views.get_input("Please enter a Ticker Symbol") user_position = Account(pk=pk) position = user_position.get_position_for(ticker) valuation = Position() getval = valuation.current_value(ticker, position.shares) views.show_positions(position, getval) elif position_choice == 2: #Retrieve and display all positions user_positions = Account(pk=pk) positions = user_positions.get_positions() for position in positions: valuation = Position() getval = valuation.current_value(position.ticker, position.shares) views.show_positions(position, getval)
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_targets(self, position, board): result = [] for single_direction_moves in self.moves: for single_direction_move in single_direction_moves: x_target = position.x + single_direction_move[0] y_target = position.y + single_direction_move[1] if 0 <= x_target <= 7 and 0 <= y_target <= 7: target_piece = board[x_target][y_target] if target_piece.color != self.color: result.append(Position(x_target, y_target)) if target_piece.color != Color.EMPTY: break return result
def get_targets(self, position, board): result = [] if self.color == Color.WHITE: x_target = position.x - 1 y_target = position.y + 1 if 0 <= x_target <= 7 and 0 <= y_target <= 7 and board[x_target][ y_target].color == Color.BLACK: result.append(Position(x_target, y_target)) x_target = position.x + 1 y_target = position.y + 1 if 0 <= x_target <= 7 and 0 <= y_target <= 7 and board[x_target][ y_target].color == Color.BLACK: result.append(Position(x_target, y_target)) x_target = position.x y_target = position.y + 1 if 0 <= x_target <= 7 and 0 <= y_target <= 7 and board[x_target][ y_target].color == Color.EMPTY: result.append(Position(x_target, y_target)) if position.y == 1: x_target = position.x y_target = position.y + 2 if 0 <= x_target <= 7 and 0 <= y_target <= 7 and board[ x_target][y_target - 1].color == board[x_target][ y_target].color == Color.EMPTY: result.append(Position(x_target, y_target)) else: x_target = position.x - 1 y_target = position.y - 1 if 0 <= x_target <= 7 and 0 <= y_target <= 7 and board[x_target][ y_target].color == Color.WHITE: result.append(Position(x_target, y_target)) x_target = position.x + 1 y_target = position.y - 1 if 0 <= x_target <= 7 and 0 <= y_target <= 7 and board[x_target][ y_target].color == Color.WHITE: result.append(Position(x_target, y_target)) x_target = position.x y_target = position.y - 1 if 0 <= x_target <= 7 and 0 <= y_target <= 7 and board[x_target][ y_target].color == Color.EMPTY: result.append(Position(x_target, y_target)) if position.y == 6: x_target = position.x y_target = position.y - 2 if 0 <= x_target <= 7 and 0 <= y_target <= 7 and board[ x_target][y_target + 1].color == board[x_target][ y_target].color == Color.EMPTY: result.append(Position(x_target, y_target)) return result
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 get_position_for(self,symbol): where="WHERE account_pk=? and ticker=?" values=(self.pk,symbol) result=Position.select_one(where,values) if result: return result position=Position() position.account_pk=self.pk position.ticker=symbol position.shares=0 return position