def test_Trader(): syms = ['AAPL','TSLA'] #syms = ['SPY'] td = Trader() td.assign_data_source(Robinhood.RobinhoodPlayer()) td.add_syms(syms) td.run()
def __init__(self,login_path,log_loc='.'): self.login_path = login_path self.log_loc = log_loc self.rb = Robinhood.Robinhood() self.login() self.trackers = dict() self.session = requests.session()
def DoMyStuff(): #login to rh configfile = 'config.json' if not os.path.exists(configfile): print("Make sure that config.json exists.") return data = json.load(open('config.json')) if 'Sites' not in data or 'Robinhood' not in data[ 'Sites'] or 'u' not in data['Sites'][ 'Robinhood'] or 'p' not in data['Sites']['Robinhood']: print("Please make sure u and p are in config.json") return u = data['Sites']['Robinhood']['u'] p = data['Sites']['Robinhood']['p'] if 'base64' == data['Sites']['Robinhood']['dec']: u = base64.b64decode(u) p = base64.b64decode(p) rhapi = Robinhood.Robinhood() #print("Logging in using [{0},{1}]".format(u,p)) do = open("dividends.csv", 'w') if False == rhapi.login(username=u, password=p): print("Login failed.") return div = rhapi.dividends() open('dividends.json', 'w').write(json.dumps(div)) data = "{:>15}\t{:>15}\t{:>15}\t{:>15}\t{:>15}".format( 'Symbol', 'Position', 'Rate', 'Amount', 'Payable Date') print(data) do.write(data + "\n") if 'results' in div: for d in div['results']: if 'instrument' in d: ret = rhapi.get_url(d['instrument']) #get dividend if 'symbol' in ret and 'rate' in d and 'amount' in d and 'paid_at' in d and 'position' in d: data = "{:>15}\t{:>15.4f}\t{:>15.4f}\t{:>15.4f}\t{:>15}".format( ret['symbol'], float(d['position']), float(d['rate']), float(d['amount']), d['payable_date']) print(data) #write divident to csv do.write(data + "\n") do.close() print("Written stuff to dividends.csv") pass
def __init__(self, username, password): self._trader = Robinhood.Robinhood() self._cached_portfolio_dictionary = None self._cached_positions_dictionary = None try: logged_in = self._trader.login(username=username, password=password) except Robinhood.exceptions.LoginFailed: raise RuntimeError("Login failed, wrong password?")
def main(): rh = Robinhood.Robinhood() #rh.login('C:/Users/Lucy/Documents/use_pw.txt') rh.login('C:/Users/Derek/OneDrive/Documents/use_pw.txt') leveraged_tickers = ['SPXL','TQQQ', 'SOXL','UPRO','KORU','FAS','YINN', 'CWEB','EDC'] set_dynamic_stop_losses(rh,leveraged_tickers) rh.logout()
def findEarliestOptionExpiration(ticker): ''' returns an option date closest to today ''' myList = Robinhood.find_tradable_options_for_stock(ticker, optionType='call', info="expiration_date") myList.sort(key=lambda date: datetime.datetime.strptime(date, "%Y-%m-%d")) if len(myList) != 0: return myList[0] else: return None
def __init__(self, username_email, password): self.trader = Robinhood.Robinhood() self.trader.login(username_email, password) self.portfolio = self.trader.portfolios() self.positions = self.trader.positions()['results'] self.open_positions = self.trader.securities_owned()['results'] self.total_value = float(self.portfolio['equity']) self.cash = float(self.portfolio['withdrawable_amount']) self.stocks = { open_position['instrument']: int(float(open_position['quantity'])) for open_position in self.open_positions } self.stocks = { self.get_Robinhood_asset_data(k)['symbol']: v for k, v in self.stocks.items() }
def ConnectToRobinhood(): try: user = os.environ["ROBINHOODUSER"] pw = os.environ["ROBINHOODPASSWORD"] except Exception as e: print(e) print("Failed to recieve system variables.") print( "Did you set system variables for ROBINHOODUSER and ROBINHOODPASSWORD?" ) return False success = Robinhood.login(user, pw) if success is False: print("Failed to connect to Robinhood.") print("Either user/pw combination failed, or the api is down.") else: return True
def set_dynamic_stop_losses(rh,tickers=None): if tickers is None: print("Feature not yet implemented. Input 'tickers' is required...") return rl = Robinhood.Robinhood() # Local robinhood for data access #rh.print_positions() #a = rh.stop_loss('UPRO',1,0).json() #print a['id'] #rh.limit_sell('UPRO',1,200) #time.sleep(1) #rh.cancel_order(a['id']) #rh.print_open_orders() #rh.cancel_stop_orders() days = [2,7,20] for ticker in tickers: print ticker h_struct = rl.get_historical(ticker,'day') historicals = h_struct['historicals'] print historicals[0] break
async def generateSpread(ticker): date = findEarliestOptionExpiration(ticker) myList = Robinhood.find_options_for_stock_by_expiration(ticker, date, optionType="call") myOptions = [StockOption(x) for x in myList] myOptions.sort(key=lambda data: data.option_sort()) if len(myOptions) >= 2: bestDeal = [-10000, myOptions[0], myOptions[1]] else: return None for first in range(len(myOptions) - 1): for second in range(first + 1, len(myOptions)): temp = myOptions[first].calculateProfit(myOptions[second]) if temp > bestDeal[0]: bestDeal = [temp, myOptions[first], myOptions[second]] return bestDeal
def test_DayTrader(): dt = DayTrader('2017-12-28') dt.set_fetcher(Robinhood.RobinhoodFetcher()) dt.set_updater(DataManager.DayPlayer()) dt.add_syms(['AAPL','TSLA'])
def rh_profit_and_loss(username=None, password=None, access_token=None, starting_allocation=5000, start_date=None, end_date=None, csv_export=1, buy_and_hold=0, pickle=0, options=1): # from rmccorm4 Robinhood-Scraper class Order: def __init__(self, side, symbol, shares, price, date, state): self.side = side self.symbol = symbol self.shares = float(shares) self.price = float(price) self.date = date self.state = state def pl(self): if self.side == 'buy': return -1 * int(self.shares) * float(self.price) else: return int(self.shares) * float(self.price) class Stock: def __init__(self, symbol): self.symbol = symbol self.orders = [] self.net_shares = 0 self.net_pl = 0 def itemize_stocks(): # Create list for each stock stocks = {} with open('orders.csv', 'r') as csvfile: lines = csv.reader(csvfile, delimiter=',') for line in lines: ticker = line[1] price = line[3] # Check for header or invalid entries if ticker == 'symbol' or price == '': continue # Add stock to dict if not already in there if ticker not in stocks: stocks[ticker] = Stock(ticker) # Add order to stock stocks[ticker].orders.append( Order(line[0], line[1], line[2], line[3], line[4], line[5])) return stocks def calculate_itemized_pl(stocks, my_trader): for stock in stocks.values(): for order in stock.orders: if order.side == 'buy': stock.net_shares += order.shares else: stock.net_shares -= order.shares # order.pl() is positive for selling and negative for buying stock.net_pl += order.pl() # Handle outstanding shares - should be current positions if stock.net_shares > 0: price = my_trader.last_trade_price(stock.symbol)[0][0] last_price = float(price) # Add currently held shares from net_pl as if selling now (unrealized PnL) stock.net_pl += stock.net_shares * last_price # Should handle free gift stocks elif stock.net_shares < 0: stock.symbol += ' ' def calculate_outstanding_options(my_trader): owned = my_trader.options_owned() pending = None if (len(owned) > 0): df_owned = pd.DataFrame(owned) df_owned['quantity'] = pd.to_numeric(df_owned['quantity']) df_owned['average_price'] = pd.to_numeric( df_owned['average_price']) df_owned['trade_value_multiplier'] = pd.to_numeric( df_owned['trade_value_multiplier']) pending = df_owned[df_owned['quantity'] > 0] pending = pending[[ 'chain_symbol', 'quantity', 'average_price', 'option_id', 'trade_value_multiplier' ]].reset_index(drop=True) pending['avg_option_cost'] = pending['average_price'] / pending[ 'trade_value_multiplier'] current_option_values = [] for each in pending['option_id'].values: try: current_price = my_trader.get_option_market_data( each)['adjusted_mark_price'] except Exception: current_price = np.nan current_option_values.append(current_price) pending['current_option_values'] = [ float(x) for x in current_option_values ] pending['current_value'] = pending[ 'current_option_values'] * pending['quantity'] * 100 pending['date'] = pd.Timestamp.now() pending = pending.set_index('date') pending.to_csv('pending_options_orders_df.csv') pending['position_effect'] = 'pending' pending['value'] = pending['current_value'] pending['ticker'] = pending['chain_symbol'] pending['original_value'] = pending['quantity'] * pending[ 'average_price'] return pending # INSTANTIATE ROBINHOOD my_trader # my_trader = Robinhood.Robinhood() logged_in = my_trader.set_oath_access_token(username, password, access_token) if not logged_in: logged_in = my_trader.login(username=username, password=password) my_account = my_trader.get_account()['url'] df_order_history, _ = rh.get_order_history(my_trader) df_orders = df_order_history[[ 'side', 'symbol', 'shares', 'avg_price', 'date', 'state' ]] df_orders.columns = ['side', 'symbol', 'shares', 'price', 'date', 'state'] # Filter for input dates df_orders['date'] = pd.to_datetime(df_orders['date']) df_orders = df_orders.sort_values('date') df_orders = df_orders.set_index('date') df_orders = df_orders[start_date:end_date] df_orders['date'] = df_orders.index if pickle == 1: df_orders.to_pickle('df_orders_history') if start_date == 'January 1, 2012': start_date = df_orders.iloc[0]['date'].strftime('%B %d, %Y') df_orders.set_index('side').to_csv('orders.csv', header=None) stocks = itemize_stocks() calculate_itemized_pl(stocks, my_trader) with open('stockwise_pl.csv', 'w') as outfile: writer = csv.writer(outfile, delimiter=',') writer.writerow(['SYMBOL', 'net_pnl', 'n_trades']) sorted_pl = sorted(stocks.values(), key=operator.attrgetter('net_pl'), reverse=True) total_pl = 0 total_trades = 0 for stock in sorted_pl: num_trades = len(stock.orders) writer.writerow([ stock.symbol, '{0:.2f}'.format(stock.net_pl), len(stock.orders) ]) total_pl += stock.net_pl total_trades += num_trades writer.writerow(['Totals', total_pl, total_trades]) # print('Created', outfile.name, 'in this directory.') # Read the pnl we generated df_pnl = pd.read_csv('stockwise_pl.csv') # Get dividends from Robinhood dividends = Robinhood.Robinhood.dividends(my_trader) # Put the dividends in a dataframe list_of_records = [] for each in dividends['results']: list_of_records.append(pd.DataFrame(pd.Series(each)).T) df_dividends = pd.concat(list_of_records) df_dividends = df_dividends.set_index('id') df_dividends['id'] = df_dividends.index # Load in our pickled database of instrument-url lookups instruments_df = pd.read_pickle('symbol_and_instrument_urls') df_dividends['ticker'] = np.nan for each in df_dividends.itertuples(): symbol, instruments_df = rh.get_symbol_from_instrument_url( each.instrument, instruments_df) df_dividends.loc[each.id, 'ticker'] = symbol if pickle == 1: df_dividends.to_pickle('df_dividends') if csv_export == 1: df_dividends.to_csv('divs_raw.csv') # df_pnl.to_csv('pnl.csv') # Filter df_dividends df_dividends['record_date'] = pd.to_datetime(df_dividends['record_date']) df_dividends = df_dividends.sort_values('record_date') df_dividends = df_dividends.set_index('record_date') df_dividends = df_dividends[start_date:end_date] # convert numbers to actual numbers df_dividends['amount'] = pd.to_numeric(df_dividends['amount']) # Group dividend payouts by ticker and sum df_divs_summed = df_dividends.groupby('ticker').sum() # Set a column to the ticker df_divs_summed['ticker'] = df_divs_summed.index # For the stockwise pnl, set index to the ticker ('SYMBOL') df_pnl = df_pnl.set_index('SYMBOL') try: df_pnl = df_pnl.drop('Totals') except KeyError as e: print("Totals row not found") # Set div payouts column df_pnl['div_payouts'] = np.nan # For each in the summed for each in df_divs_summed.itertuples(): amount = each.amount df_pnl.loc[each.ticker, 'div_payouts'] = amount if pickle == 1: df_divs_summed.to_pickle('df_divs_summed') df_pnl.to_pickle('df_pnl') if csv_export == 1: # df_divs_summed.to_csv('divs_summed_df.csv') df_pnl.to_csv('pnl_df.csv') # Calculate the dividends received (or that are confirmed you will receive in the future) dividends_paid = float(df_pnl.sum()['div_payouts']) # Calculate the total pnl pnl = float(df_pnl.sum()['net_pnl']) # When printing the final output, if no date was provided, print "today" if end_date == 'January 1, 2030': end_date_string = 'today' else: end_date_string = end_date # Retrieve options history if options == 1: try: df_options_orders_history = rh.get_all_history_options_orders( my_trader) pending_options = calculate_outstanding_options(my_trader) options_pnl = 0 if (pending_options is not None and pending_options.len() > 0): df_options = pd.concat([ df_options_orders_history, pending_options[['ticker', 'value', 'position_effect']], ]) # More hacky shit cause this code is a mess df_options = df_options.reset_index() df_options['date'] = pd.to_datetime(df_options['date'], utc=True) df_options = df_options.set_index(df_options['date']) if csv_export == 1: df_options.to_csv('options_orders_history_df.csv') if pickle == 1: df_options.to_pickle('df_options_orders_history') df_options = df_options[start_date:end_date] options_pnl = df_options['value'].sum() except Exception as e: print(traceback.format_exc()) print(sys.exc_info()[0]) options_pnl = 0 total_pnl = round(pnl + dividends_paid + options_pnl, 2) # Print final output print("~~~") print("From {} to {}, your total PnL is ${}".format( start_date, end_date_string, total_pnl)) print( "You've made ${} buying and selling individual equities, received ${} in dividends, and ${} on options trades" .format(round(pnl, 2), round(dividends_paid, 2), round(options_pnl, 2))) # Calculate ROI, if the user input a starting allocation if roi == 1: # Calculate Stocks ROI long_entries = df_orders[(df_orders['side'] == 'buy') & (df_orders['state'] == 'filled')] long_entries['value'] = pd.to_numeric( long_entries['price']) * pd.to_numeric(long_entries['shares']) starting_stock_investment = long_entries['value'].sum() stocks_roi = rh.pct_change(pnl + starting_stock_investment, starting_stock_investment) print( "Your return-on-investment (ROI) for stock trades is: %{}".format( stocks_roi)) # Calculate Options ROI # More hacky shit cause this code is a mess df_options_orders_history = df_options_orders_history.reset_index() df_options_orders_history['date'] = pd.to_datetime( df_options_orders_history['date'], utc=True) df_options_orders_history = df_options_orders_history.set_index( df_options_orders_history['date']) df_options_orders_history = df_options_orders_history[ start_date:end_date] options_entries = df_options_orders_history[ df_options_orders_history['value'] < 0] starting_options_investment = options_entries['value'].sum() * -1 options_roi = rh.pct_change(options_pnl + starting_options_investment, starting_options_investment) print("Your return-on-investment (ROI) for options trades is: %{}". format(options_roi)) # print(starting_options_investment) # print(options_pnl) # print(pnl) # print(starting_stock_investment) return_on_investment = rh.pct_change( options_pnl + starting_options_investment + pnl + starting_stock_investment, starting_options_investment + starting_stock_investment) print( "Your return-on-investment (ROI) on overall capital deployed is: %{}" .format(return_on_investment)) if buy_and_hold == 1: print( "With a starting allocation of ${}, if you had just bought and held QQQ, your PnL would be ${}" .format(starting_allocation, round(QQQ_buy_and_hold_gain, 2))) print("~~~")
def rh_profit_and_loss(username=None, password=None, starting_allocation=5000, start_date=None, end_date=None, csv_export=1, buy_and_hold=0, pickle=0, options=1): # from rmccorm4 Robinhood-Scraper class Order: def __init__(self, side, symbol, shares, price, date, state): self.side = side self.symbol = symbol self.shares = float(shares) self.price = float(price) self.date = date self.state = state def pl(self): if self.side == 'buy': return -1 * int(self.shares) * float(self.price) else: return int(self.shares) * float(self.price) class Stock: def __init__(self, symbol): self.symbol = symbol self.orders = [] self.net_shares = 0 self.net_pl = 0 def itemize_stocks(): # Create list for each stock stocks = {} with open('orders.csv', 'r') as csvfile: lines = csv.reader(csvfile, delimiter=',') for line in lines: ticker = line[1] price = line[3] # Check for header or invalid entries if ticker == 'symbol' or price == '': continue # Add stock to dict if not already in there if ticker not in stocks: stocks[ticker] = Stock(ticker) # Add order to stock stocks[ticker].orders.append( Order(line[0], line[1], line[2], line[3], line[4], line[5])) return stocks def calculate_itemized_pl(stocks): for stock in stocks.values(): for order in stock.orders: if order.side == 'buy': stock.net_shares += order.shares else: stock.net_shares -= order.shares # order.pl() is positive for selling and negative for buying stock.net_pl += order.pl() # Handle outstanding shares - should be current positions if stock.net_shares > 0: requestResponse = requests.get( "https://api.iextrading.com/1.0/stock/{}/price".format( stock.symbol.lower())) json = requestResponse.json() last_price = float(json) # Add currently held shares from net_pl as if selling now (unrealized PnL) stock.net_pl += stock.net_shares * last_price # Should handle free gift stocks elif stock.net_shares < 0: stock.symbol += ' ' # INSTANTIATE ROBINHOOD my_trader # my_trader = Robinhood.Robinhood() logged_in = my_trader.login(username=username, password=password) my_account = my_trader.get_account()['url'] df_order_history, _ = rh.get_order_history(my_trader) df_orders = df_order_history[[ 'side', 'symbol', 'shares', 'avg_price', 'date', 'state' ]] df_orders.columns = ['side', 'symbol', 'shares', 'price', 'date', 'state'] # Filter for input dates df_orders['date'] = pd.to_datetime(df_orders['date']) df_orders = df_orders.sort_values('date') df_orders = df_orders.set_index('date') df_orders = df_orders[start_date:end_date] df_orders['date'] = df_orders.index if pickle == 1: df_orders.to_pickle('df_orders_history') if start_date == 'January 1, 2012': start_date = df_orders.iloc[0]['date'].strftime('%B %d, %Y') df_orders.set_index('side').to_csv('orders.csv', header=None) stocks = itemize_stocks() calculate_itemized_pl(stocks) with open('stockwise_pl.csv', 'w') as outfile: writer = csv.writer(outfile, delimiter=',') writer.writerow(['SYMBOL', 'net_pnl', 'n_trades']) sorted_pl = sorted(stocks.values(), key=operator.attrgetter('net_pl'), reverse=True) total_pl = 0 total_trades = 0 for stock in sorted_pl: num_trades = len(stock.orders) writer.writerow([ stock.symbol, '{0:.2f}'.format(stock.net_pl), len(stock.orders) ]) total_pl += stock.net_pl total_trades += num_trades writer.writerow(['Totals', total_pl, total_trades]) # print('Created', outfile.name, 'in this directory.') # Read the pnl we generated df_pnl = pd.read_csv('stockwise_pl.csv') # Get dividends from Robinhood dividends = Robinhood.Robinhood.dividends(my_trader) # Put the dividends in a dataframe list_of_records = [] for each in dividends['results']: list_of_records.append(pd.DataFrame(pd.Series(each)).T) df_dividends = pd.concat(list_of_records) df_dividends = df_dividends.set_index('id') df_dividends['id'] = df_dividends.index # Load in our pickled database of instrument-url lookups instruments_df = pd.read_pickle('symbol_and_instrument_urls') df_dividends['ticker'] = np.nan for each in df_dividends.itertuples(): symbol, instruments_df = rh.get_symbol_from_instrument_url( each.instrument, instruments_df) df_dividends.loc[each.id, 'ticker'] = symbol if pickle == 1: df_dividends.to_pickle('df_dividends') if csv_export == 1: df_dividends.to_csv('divs_raw.csv') # df_pnl.to_csv('pnl.csv') # Filter df_dividends df_dividends['record_date'] = pd.to_datetime(df_dividends['record_date']) df_dividends = df_dividends.sort_values('record_date') df_dividends = df_dividends.set_index('record_date') df_dividends = df_dividends[start_date:end_date] # convert numbers to actual numbers df_dividends['amount'] = pd.to_numeric(df_dividends['amount']) # Group dividend payouts by ticker and sum df_divs_summed = df_dividends.groupby('ticker').sum() # Set a column to the ticker df_divs_summed['ticker'] = df_divs_summed.index # For the stockwise pnl, set index to the ticker ('SYMBOL') df_pnl = df_pnl.set_index('SYMBOL') try: df_pnl = df_pnl.drop('Totals') except KeyError as e: print("Totals row not found") # Set div payouts column df_pnl['div_payouts'] = np.nan # For each in the summed for each in df_divs_summed.itertuples(): amount = each.amount df_pnl.loc[each.ticker, 'div_payouts'] = amount if pickle == 1: df_divs_summed.to_pickle('df_divs_summed') df_pnl.to_pickle('df_pnl') if csv_export == 1: # df_divs_summed.to_csv('divs_summed_df.csv') df_pnl.to_csv('pnl_df.csv') # Calculate the dividends received (or that are confirmed you will receive in the future) dividends_paid = float(df_pnl.sum()['div_payouts']) # Calculate the total pnl pnl = float(df_pnl.sum()['net_pnl']) if buy_and_hold == 1: # Get historical price of QQQ requestResponse = requests.get( "https://api.iextrading.com/1.0/stock/qqq/chart/5y") json = requestResponse.json() df_qqq = pd.DataFrame(json) df_qqq.index = pd.to_datetime(df_qqq['date']) # If the date is older than we can get from IEX, load the historical data if pd.to_datetime(start_date) < df_qqq.iloc[0].name: df_QQQ_history = pd.read_pickle('data/QQQ_close') QQQ_starting_price = float(df_QQQ_history.iloc[0]['close']) else: df_qqq = df_qqq[start_date:end_date] QQQ_starting_price = float(df_qqq.iloc[0]['close']) # Filter the dataframe for start and end date df_qqq = df_qqq[start_date:end_date] # Set end price of the trading period QQQ_ending_price = float(df_qqq.iloc[-1]['close']) # Calculate the buy-and-hold value QQQ_buy_and_hold_gain = starting_allocation * ( QQQ_ending_price - QQQ_starting_price) / QQQ_starting_price # When printing the final output, if no date was provided, print "today" if end_date == 'January 1, 2030': end_date_string = 'today' else: end_date_string = end_date # Retrieve options history if options == 1: try: df_options_orders_history = rh.get_all_history_options_orders( my_trader) if csv_export == 1: df_options_orders_history.to_csv( 'options_orders_history_df.csv') if pickle == 1: df_options_orders_history.to_pickle( 'df_options_orders_history') options_pnl = df_options_orders_history[start_date:end_date][ 'value'].sum() except Exception as e: options_pnl = 0 total_pnl = round(pnl + dividends_paid + options_pnl, 2) # Print final output print("~~~") print("From {} to {}, your total PnL is ${}".format( start_date, end_date_string, total_pnl)) print( "You've made ${} buying and selling individual equities, received ${} in dividends, and ${} on options trades" .format(round(pnl, 2), round(dividends_paid, 2), round(options_pnl, 2))) # Calculate ROI, if the user input a starting allocation if roi == 1: return_on_investment = round((total_pnl / starting_allocation) * 100, 2) print("Your return-on-investment (ROI) is: %{}".format( return_on_investment)) if buy_and_hold == 1: print( "With a starting allocation of ${}, if you had just bought and held QQQ, your PnL would be ${}" .format(starting_allocation, round(QQQ_buy_and_hold_gain, 2))) print("~~~") # Delete the csv we were processing earlier os.remove('stockwise_pl.csv')
tz = config.timezone # wrapper fro the get_historical quotes functions in Robinhood def get_news(trader, ticker): return trader.get_news(ticker) if __name__ == '__main__': # Login to my Robinhood Account print("Login to robinhood") #TODO: replace username and password with raw_input once the code is ready username = config.username password = config.password trader = Robinhood.Robinhood() my_portfolio = trader.login(username=username, password=password) # Load all tradable stocks tradable_ticker = [] with open(tradable) as f: for stock in f: ticker = stock.split(",")[0] tradable_ticker.append(ticker) # Today's date today_date = (datetime.now(tz)).date() ######### Manually update a gap day ########## today_date = datetime.strptime("2018-06-08", '%Y-%m-%d').date() ############################################## print('Today is: ' + str(today_date))