In [2]:
from IPython.display import HTML

HTML('''<script>
code_show=true; 
function code_toggle() {
 if (code_show){
 $('div.input').hide();
 } else {
 $('div.input').show();
 }
 code_show = !code_show
} 
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code."></form>''')
Out[2]:

Let's start by importing our stock info.

First, we have to get all the imports out of the way and then log in to our Robin_stocks account.

Note: I separately created a robin_credentials json file with my login info. I recommend you take a similar approach in case you intend to share your code.

In [3]:
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, Input
import dash_renderer
import dash_table
import plotly
import plotly.graph_objs as go
import random
from collections import deque
import robin_stocks as rs
import pandas as pd
import matplotlib.pyplot as plt
In [4]:
with open("robin_credentials.json", "r") as file:
    creds = json.load(file)

# Instantiate the rs login to login to your Robinhood account.

rs.login(creds['USER_ID'], creds['PASSCODE'])
ERROR: There was an issue loading pickle file. Authentication may be expired - logging in normally.
Out[4]:
{'access_token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJleHAiOjE1NzU5NTc0NjAsInRva2VuIjoiaXJiZ2Q3UFpVY0huZFJnVEFyTm1UTkxySHJpRDN6IiwidXNlcl9pZCI6ImE5ZWE3ZjFjLTNkNGMtNDcyNS1hY2ZmLWJmNjAwYmExYmE1NiIsImRldmljZV9oYXNoIjoiMzcxZDJjMTExYjc2ZWFlMGZmNzhkYzE3NjAxM2RlZDUiLCJzY29wZSI6ImludGVybmFsIiwidXNlcl9vcmlnaW4iOiJVUyIsIm9wdGlvbnMiOnRydWUsImxldmVsMl9hY2Nlc3MiOmZhbHNlfQ.jpMoSJqpBKILXYKZv1NMXECvzsikqZxywxV30yerm5TGpg5xcxnljkyv84t257AehQL8rTYWREFr08xenSM0XakjtpQwjTXXxl4Q9ju6BEz8NVEQxxs_KRmt0z8cdUngfm_aat21-eipmhnm1-QM20RnT4xo-AJNzSE49B-i5I4fu8TF0t30M5vq2FmGx50cdoAFBv3TEy_tQoYnM_P3FCwNg8EeIv1MzMixrTXZkE4A_hyn_fNTI4lCbXlPOHV1nW-LuquYD5ubbOfC1C_rRoOol-rjncVf36oEr8pNm-7RobebNHdbAKLmEX5KRispBmtySaUd8Wv59Zi4yzYgag',
 'expires_in': 118804,
 'token_type': 'Bearer',
 'scope': 'internal',
 'refresh_token': 'HbaU8o5AFBoykDIY0GEQ4pZ0qflWSP',
 'mfa_code': None,
 'backup_code': None,
 'detail': 'logged in with brand new authentication code.'}
In [5]:
# you can look at the list of your stocks
my_stocks = rs.build_holdings()
my_stocks
Out[5]:
{'FB': {'price': '200.900000',
  'quantity': '20.00000000',
  'average_buy_price': '161.2279',
  'equity': '4018.00',
  'percent_change': '24.61',
  'equity_change': '793.442000',
  'type': 'stock',
  'name': 'Facebook',
  'id': 'ebab2398-028d-4939-9f1d-13bf38f81c50',
  'pe_ratio': '31.844100',
  'percentage': '35.82'},
 'JD': {'price': '32.540000',
  'quantity': '100.00000000',
  'average_buy_price': '23.9088',
  'equity': '3254.00',
  'percent_change': '36.10',
  'equity_change': '863.120000',
  'type': 'adr',
  'name': 'JD.com',
  'id': 'b1e0ba21-bf54-454a-a409-89fe275bbe05',
  'pe_ratio': '83.031400',
  'percentage': '29.01'},
 'AAPL': {'price': '270.620000',
  'quantity': '10.00000000',
  'average_buy_price': '172.4320',
  'equity': '2706.20',
  'percent_change': '56.94',
  'equity_change': '981.880000',
  'type': 'stock',
  'name': 'Apple',
  'id': '450dfc6d-5510-4d40-abfb-f633b7d9be3e',
  'pe_ratio': '22.344300',
  'percentage': '24.12'},
 'BABA': {'price': '201.900000',
  'quantity': '5.00000000',
  'average_buy_price': '155.4640',
  'equity': '1009.50',
  'percent_change': '29.87',
  'equity_change': '232.180000',
  'type': 'adr',
  'name': 'Alibaba',
  'id': 'b2e06903-5c44-46a4-bd42-2a696f9d68e1',
  'pe_ratio': '23.486900',
  'percentage': '9.00'},
 'S': {'price': '5.520000',
  'quantity': '34.00000000',
  'average_buy_price': '5.7620',
  'equity': '187.68',
  'percent_change': '-4.20',
  'equity_change': '-8.228000',
  'type': 'stock',
  'name': 'Sprint',
  'id': '3ad11874-934e-4b7f-8686-c7c9115b1a0b',
  'pe_ratio': None,
  'percentage': '1.67'}}

There are many things you could do with robin_stocks built-in functions.

For instance, you can use build_holdings as shown above to look at your portfolio. You can use order_buy_market to make conditional stock purchases. You can build_user_profile and order_sell_limit to create user profiles and make limit sells of specific stocks you hold once it reaches a certain price point.

A few examples are provided at the quick start section of the robin_stocks website here.

In [6]:
df = pd.DataFrame(my_stocks)
In [7]:
df
Out[7]:
FB JD AAPL BABA S
price 200.900000 32.540000 270.620000 201.900000 5.520000
quantity 20.00000000 100.00000000 10.00000000 5.00000000 34.00000000
average_buy_price 161.2279 23.9088 172.4320 155.4640 5.7620
equity 4018.00 3254.00 2706.20 1009.50 187.68
percent_change 24.61 36.10 56.94 29.87 -4.20
equity_change 793.442000 863.120000 981.880000 232.180000 -8.228000
type stock adr stock adr stock
name Facebook JD.com Apple Alibaba Sprint
id ebab2398-028d-4939-9f1d-13bf38f81c50 b1e0ba21-bf54-454a-a409-89fe275bbe05 450dfc6d-5510-4d40-abfb-f633b7d9be3e b2e06903-5c44-46a4-bd42-2a696f9d68e1 3ad11874-934e-4b7f-8686-c7c9115b1a0b
pe_ratio 31.844100 83.031400 22.344300 23.486900 None
percentage 35.82 29.01 24.12 9.00 1.67
In [8]:
# The dataframe looks off with the variable names/features as index and the ticker as the column, so let's fix that first
df = df.T
df['ticker'] = df.index
df = df.reset_index(drop=True)
df.head()
Out[8]:
price quantity average_buy_price equity percent_change equity_change type name id pe_ratio percentage ticker
0 200.900000 20.00000000 161.2279 4018.00 24.61 793.442000 stock Facebook ebab2398-028d-4939-9f1d-13bf38f81c50 31.844100 35.82 FB
1 32.540000 100.00000000 23.9088 3254.00 36.10 863.120000 adr JD.com b1e0ba21-bf54-454a-a409-89fe275bbe05 83.031400 29.01 JD
2 270.620000 10.00000000 172.4320 2706.20 56.94 981.880000 stock Apple 450dfc6d-5510-4d40-abfb-f633b7d9be3e 22.344300 24.12 AAPL
3 201.900000 5.00000000 155.4640 1009.50 29.87 232.180000 adr Alibaba b2e06903-5c44-46a4-bd42-2a696f9d68e1 23.486900 9.00 BABA
4 5.520000 34.00000000 5.7620 187.68 -4.20 -8.228000 stock Sprint 3ad11874-934e-4b7f-8686-c7c9115b1a0b None 1.67 S
In [ ]:
# We can look at the ticker price history over the course of the past 'x' span where x can be day, week, year, or 5year
for tick in df['ticker']:
    data = rs.stocks.get_historicals(tick,span='year',bounds='regular')
    tick_df = pd.DataFrame(data)
    #switching to floats so pyplot can read the numbers
    column_list = ['close_price','high_price','low_price','open_price']
#     tick_df['portfolio_share'] = tick_df['close_price']*df['quantity'].astype(float)
    for i in column_list:
        tick_df[i] = tick_df[i].astype(float)
# I will look at the close_price for now, however, we can look for other things too that might interest us. For instance, we can look at the changes in high_price
# We can also track the percent_change, equity_change, or pe_ratio  of each of our stocks
    tick_df['portfolio_share'].plot(legend=True,figsize=(20,5))
#     tick_df['open_price'].plot(legend=True,figsize=(12,5))
#     tick_df['high_price'].plot(legend=True,figsize=(12,5))
#     tick_df['low_price'].plot(legend=True,figsize=(12,5))

# We can look at the ticker price history over the course of the past 'x' span where x can be day, week, year, or 5year
for tick in df['ticker']:
    data = rs.stocks.get_historicals(tick,span='year',bounds='regular')
    tick_df = pd.DataFrame(data)

    #switching to floats so pyplot can read the numbers
    column_list = ['close_price','high_price','low_price','open_price']
    for i in column_list:
        tick_df[i] = tick_df[i].astype(float)
# I will look at the close_price for now, however, we can look for other things too that might interest us. For instance, we can look at the changes in high_price
# We can also track the percent_change, equity_change, or pe_ratio  of each of our stocks
    tick_df['close_price'].plot(legend=True,figsize=(20,5))
#     tick_df['open_price'].plot(legend=True,figsize=(12,5))
#     tick_df['high_price'].plot(legend=True,figsize=(12,5))
#     tick_df['low_price'].plot(legend=True,figsize=(12,5))

Let's also use another approach to visualize our data better using standard financial analyses to generate candlestick plots in the end.

In [85]:
rs.profiles.load_account_profile()
Out[85]:
{'rhs_account_number': 143771681,
 'received_ach_debit_locked': False,
 'deactivated': False,
 'updated_at': '2019-11-12T19:10:54.277677Z',
 'margin_balances': {'updated_at': '2019-12-04T06:02:25.287958Z',
  'gold_equity_requirement': '0.0000',
  'pending_deposit': '0.0000',
  'cash_held_for_restrictions': '0.0000',
  'crypto_buying_power': '7.5400',
  'cash_pending_from_options_events': '0.0000',
  'cash_held_for_options_collateral': '0.0000',
  'uncleared_nummus_deposits': '0.0000',
  'overnight_ratio': '0.50',
  'day_trade_buying_power': '7.5400',
  'portfolio_cash': '7.5400',
  'pending_debit_card_debits': '0.0000',
  'funding_hold_balance': '0.0000',
  'cash_available_for_withdrawal': '7.5400',
  'settled_amount_borrowed': '0.0000',
  'sma': '0',
  'cash_held_for_nummus_restrictions': '0.0000',
  'outstanding_interest': '0.0000',
  'net_moving_cash': '0.0000',
  'marked_pattern_day_trader_date': None,
  'unallocated_margin_cash': '7.5400',
  'day_trades_protection': True,
  'start_of_day_dtbp': '6159.3589',
  'overnight_buying_power_held_for_orders': '0.0000',
  'day_trade_ratio': '0.25',
  'margin_withdrawal_limit': None,
  'cash_held_for_orders': '0.0000',
  'unsettled_debit': '0.0000',
  'day_trade_buying_power_held_for_orders': '0.0000',
  'cash_held_for_dividends': '0.0000',
  'cash': '7.5400',
  'start_of_day_overnight_buying_power': '6159.3589',
  'margin_limit': '0.0000',
  'overnight_buying_power': '7.5400',
  'uncleared_deposits': '0.0000',
  'unsettled_funds': '0.0000',
  'created_at': '2018-01-31T19:53:23.372952Z'},
 'crypto_buying_power': '7.5400',
 'portfolio': 'https://api.robinhood.com/accounts/5UD77168/portfolio/',
 'cash_balances': None,
 'sma_held_for_orders': '0',
 'active_subscription_id': None,
 'permanently_deactivated': False,
 'can_downgrade_to_cash': 'https://api.robinhood.com/accounts/5UD77168/can_downgrade_to_cash/',
 'withdrawal_halted': False,
 'cash_available_for_withdrawal': '7.5400',
 'state': 'active',
 'type': 'margin',
 'sma': '0',
 'sweep_enabled': False,
 'deposit_halted': False,
 'buying_power': '6159.3589',
 'user': 'api.robinhood.com/user/',
 'max_ach_early_access_amount': '1000.00',
 'option_level': 'option_level_3',
 'instant_eligibility': {'reinstatement_date': None,
  'state': 'ok',
  'created_at': '2018-01-31T19:53:23.367208Z',
  'updated_at': None,
  'created_by': None,
  'reason': '',
  'additional_deposit_needed': '0.0000',
  'reversal': None,
  'compliance_user_major_oak_email': None},
 'cash_held_for_orders': '0.0000',
 'locked': False,
 'only_position_closing_trades': False,
 'url': 'https://api.robinhood.com/accounts/5UD77168/',
 'positions': 'https://api.robinhood.com/accounts/5UD77168/positions/',
 'created_at': '2018-01-31T19:53:23.367208Z',
 'cash': '7.5400',
 'portfolio_cash': '7.5400',
 'unsettled_debit': '0.0000',
 'account_number': '5UD77168',
 'is_pinnacle_account': True,
 'uncleared_deposits': '0.0000',
 'unsettled_funds': '0.0000'}
In [89]:
import datetime
date_created = rs.profiles.load_account_profile(info='created_at')
date_object = datetime.datetime.strptime(date_created, '%Y-%m-%dT%H:%M:%S.%fZ').date()
print(date_object)
new_fmt = "%Y, %m, %d"
print (date_object.strftime(new_fmt))
start_date = date_object.strftime(new_fmt)

# Alternatively, you could use the approach below for a standard python timetuple
# start_date = date_object.timetuple()
# start_date
2018-01-31
2018, 01, 31
In [109]:
# We can get the start year, month, and day for our profile by doing the following
start_year = int(start_date[0:4])
start_year

start_month = int(start_date[6:8])
start_month

start_day = int(start_date[9:])
start_day
Out[109]:
31
In [132]:
import matplotlib as mpl
mpl.get_backend()
Out[132]:
'module://ipykernel.pylab.backend_inline'
In [136]:
import datetime as dt
import matplotlib.pyplot as plt
from matplotlib import style
import pandas as pd
import pandas_datareader.data as web
from mpl_finance import candlestick_ohlc
import matplotlib.dates as mdates
%matplotlib inline
style.use('ggplot')
# Let's inspect data from 2015 through now. I arbitrarily picked Jan 1st of 2015. However, you may chose to start it from any other day/date. 
start = datetime.datetime(start_year,start_month,start_day)
end = datetime.datetime.now()
for tick in df['ticker']:
    df_new = web.get_data_yahoo(tick, start, end)
    df_new.reset_index(inplace=True)
    df_new.set_index("Date", inplace=True)
    print(df_new.head())
    df_new.to_csv(tick + '.csv')
    df_new = pd.read_csv(tick + '.csv', parse_dates=True, index_col=0)
    df_new.plot()
    df_new['Adj Close'].plot()
    plt.show()
    df_new['100ma'] = df_new['Adj Close'].rolling(window=100).mean()
    print(df.head())
    df_new['100ma'] = df_new['Adj Close'].rolling(window=100,min_periods=0).mean()
    print(df.head())
    ax1 = plt.subplot2grid((8,1), (0,0), rowspan=5, colspan=1)
    ax2 = plt.subplot2grid((8,1), (5,0), rowspan=1, colspan=1,sharex=ax1)
    ax1.plot(df_new.index, df_new['Adj Close'])
    ax1.plot(df_new.index, df_new['100ma'])
    ax2.bar(df_new.index, df_new['Volume'])
    plt.show()
    df_ohlc = df_new['Adj Close'].resample('10D').ohlc()
    df_volume = df_new['Volume'].resample('10D').sum()
    print(df_ohlc.head())
    df_ohlc = df_ohlc.reset_index()
    df_ohlc['Date'] = df_ohlc['Date'].map(mdates.date2num)
    fig = plt.figure()
    ax1 = plt.subplot2grid((8,1), (0,0), rowspan=5, colspan=1)
    ax2 = plt.subplot2grid((8,1), (5,0), rowspan=1, colspan=1,sharex=ax1)
    ax1.xaxis_date
    candlestick_ohlc(ax1, df_ohlc.values, width=4, colorup='g')
    ax2.fill_between(df_volume.index.map(mdates.date2num),df_volume.values,0)
    plt.show()
                  High         Low        Open       Close    Volume  \
Date                                                                   
2018-01-31  189.830002  185.220001  188.369995  186.889999  43275100   
2018-02-01  195.320007  187.889999  188.220001  193.089996  54211300   
2018-02-02  194.210007  189.979996  192.039993  190.279999  26677500   
2018-02-05  190.610001  180.610001  186.929993  181.259995  33128200   
2018-02-06  185.770004  177.740005  178.570007  185.309998  37758500   

             Adj Close  
Date                    
2018-01-31  186.889999  
2018-02-01  193.089996  
2018-02-02  190.279999  
2018-02-05  181.259995  
2018-02-06  185.309998  
        price      quantity average_buy_price   equity percent_change  \
0  198.450000   20.00000000          161.2279  3969.00          23.09   
1   31.540000  100.00000000           23.9088  3154.00          31.92   
2  261.500000   10.00000000          172.4320  2615.00          51.65   
3  194.240000    5.00000000          155.4640   971.20          24.94   
4    5.670000   34.00000000            5.7620   192.78          -1.60   

  equity_change   type      name                                    id  \
0    744.442000  stock  Facebook  ebab2398-028d-4939-9f1d-13bf38f81c50   
1    763.120000    adr    JD.com  b1e0ba21-bf54-454a-a409-89fe275bbe05   
2    890.680000  stock     Apple  450dfc6d-5510-4d40-abfb-f633b7d9be3e   
3    193.880000    adr   Alibaba  b2e06903-5c44-46a4-bd42-2a696f9d68e1   
4     -3.128000  stock    Sprint  3ad11874-934e-4b7f-8686-c7c9115b1a0b   

    pe_ratio percentage ticker  
0  31.898400      36.38     FB  
1  82.393500      28.91     JD  
2  22.224800      23.97   AAPL  
3  23.053500       8.90   BABA  
4       None       1.77      S  
        price      quantity average_buy_price   equity percent_change  \
0  198.450000   20.00000000          161.2279  3969.00          23.09   
1   31.540000  100.00000000           23.9088  3154.00          31.92   
2  261.500000   10.00000000          172.4320  2615.00          51.65   
3  194.240000    5.00000000          155.4640   971.20          24.94   
4    5.670000   34.00000000            5.7620   192.78          -1.60   

  equity_change   type      name                                    id  \
0    744.442000  stock  Facebook  ebab2398-028d-4939-9f1d-13bf38f81c50   
1    763.120000    adr    JD.com  b1e0ba21-bf54-454a-a409-89fe275bbe05   
2    890.680000  stock     Apple  450dfc6d-5510-4d40-abfb-f633b7d9be3e   
3    193.880000    adr   Alibaba  b2e06903-5c44-46a4-bd42-2a696f9d68e1   
4     -3.128000  stock    Sprint  3ad11874-934e-4b7f-8686-c7c9115b1a0b   

    pe_ratio percentage ticker  
0  31.898400      36.38     FB  
1  82.393500      28.91     JD  
2  22.224800      23.97   AAPL  
3  23.053500       8.90   BABA  
4       None       1.77      S  
                  open        high         low       close
Date                                                      
2018-01-31  186.889999  193.089996  171.580002  176.110001
2018-02-10  176.410004  179.960007  173.149994  177.360001
2018-02-20  176.009995  184.929993  175.940002  175.940002
2018-03-02  176.619995  185.229996  176.619995  185.229996
2018-03-12  184.759995  185.089996  168.149994  169.389999
                 High        Low       Open      Close    Volume  Adj Close
Date                                                                       
2018-01-31  50.169998  49.035000  49.740002  49.230000  18376300  49.230000
2018-02-01  49.250000  45.500000  46.889999  47.549999  19814400  47.549999
2018-02-02  48.020000  45.919998  47.990002  46.029999  15944200  46.029999
2018-02-05  47.639999  44.110001  45.029999  44.599998  19415700  44.599998
2018-02-06  45.299999  42.599998  43.060001  45.049999  20648900  45.049999
        price      quantity average_buy_price   equity percent_change  \
0  198.450000   20.00000000          161.2279  3969.00          23.09   
1   31.540000  100.00000000           23.9088  3154.00          31.92   
2  261.500000   10.00000000          172.4320  2615.00          51.65   
3  194.240000    5.00000000          155.4640   971.20          24.94   
4    5.670000   34.00000000            5.7620   192.78          -1.60   

  equity_change   type      name                                    id  \
0    744.442000  stock  Facebook  ebab2398-028d-4939-9f1d-13bf38f81c50   
1    763.120000    adr    JD.com  b1e0ba21-bf54-454a-a409-89fe275bbe05   
2    890.680000  stock     Apple  450dfc6d-5510-4d40-abfb-f633b7d9be3e   
3    193.880000    adr   Alibaba  b2e06903-5c44-46a4-bd42-2a696f9d68e1   
4     -3.128000  stock    Sprint  3ad11874-934e-4b7f-8686-c7c9115b1a0b   

    pe_ratio percentage ticker  
0  31.898400      36.38     FB  
1  82.393500      28.91     JD  
2  22.224800      23.97   AAPL  
3  23.053500       8.90   BABA  
4       None       1.77      S  
        price      quantity average_buy_price   equity percent_change  \
0  198.450000   20.00000000          161.2279  3969.00          23.09   
1   31.540000  100.00000000           23.9088  3154.00          31.92   
2  261.500000   10.00000000          172.4320  2615.00          51.65   
3  194.240000    5.00000000          155.4640   971.20          24.94   
4    5.670000   34.00000000            5.7620   192.78          -1.60   

  equity_change   type      name                                    id  \
0    744.442000  stock  Facebook  ebab2398-028d-4939-9f1d-13bf38f81c50   
1    763.120000    adr    JD.com  b1e0ba21-bf54-454a-a409-89fe275bbe05   
2    890.680000  stock     Apple  450dfc6d-5510-4d40-abfb-f633b7d9be3e   
3    193.880000    adr   Alibaba  b2e06903-5c44-46a4-bd42-2a696f9d68e1   
4     -3.128000  stock    Sprint  3ad11874-934e-4b7f-8686-c7c9115b1a0b   

    pe_ratio percentage ticker  
0  31.898400      36.38     FB  
1  82.393500      28.91     JD  
2  22.224800      23.97   AAPL  
3  23.053500       8.90   BABA  
4       None       1.77      S  
                 open       high        low      close
Date                                                  
2018-01-31  49.230000  49.230000  42.250000  42.930000
2018-02-10  43.720001  47.110001  43.720001  46.419998
2018-02-20  46.930000  48.799999  46.209999  46.209999
2018-03-02  43.799999  45.709999  42.990002  45.709999
2018-03-12  46.009998  46.009998  43.509998  43.509998
                  High         Low        Open       Close      Volume  \
Date                                                                     
2018-01-31  168.440002  166.500000  166.869995  167.429993  32478900.0   
2018-02-01  168.619995  166.759995  167.169998  167.779999  47230800.0   
2018-02-02  166.800003  160.100006  166.000000  160.500000  86593800.0   
2018-02-05  163.880005  156.000000  159.100006  156.490005  72738500.0   
2018-02-06  163.720001  154.000000  154.830002  163.029999  68243800.0   

             Adj Close  
Date                    
2018-01-31  162.511780  
2018-02-01  162.851486  
2018-02-02  155.785370  
2018-02-05  151.893127  
2018-02-06  158.241013  
        price      quantity average_buy_price   equity percent_change  \
0  198.450000   20.00000000          161.2279  3969.00          23.09   
1   31.540000  100.00000000           23.9088  3154.00          31.92   
2  261.500000   10.00000000          172.4320  2615.00          51.65   
3  194.240000    5.00000000          155.4640   971.20          24.94   
4    5.670000   34.00000000            5.7620   192.78          -1.60   

  equity_change   type      name                                    id  \
0    744.442000  stock  Facebook  ebab2398-028d-4939-9f1d-13bf38f81c50   
1    763.120000    adr    JD.com  b1e0ba21-bf54-454a-a409-89fe275bbe05   
2    890.680000  stock     Apple  450dfc6d-5510-4d40-abfb-f633b7d9be3e   
3    193.880000    adr   Alibaba  b2e06903-5c44-46a4-bd42-2a696f9d68e1   
4     -3.128000  stock    Sprint  3ad11874-934e-4b7f-8686-c7c9115b1a0b   

    pe_ratio percentage ticker  
0  31.898400      36.38     FB  
1  82.393500      28.91     JD  
2  22.224800      23.97   AAPL  
3  23.053500       8.90   BABA  
4       None       1.77      S  
        price      quantity average_buy_price   equity percent_change  \
0  198.450000   20.00000000          161.2279  3969.00          23.09   
1   31.540000  100.00000000           23.9088  3154.00          31.92   
2  261.500000   10.00000000          172.4320  2615.00          51.65   
3  194.240000    5.00000000          155.4640   971.20          24.94   
4    5.670000   34.00000000            5.7620   192.78          -1.60   

  equity_change   type      name                                    id  \
0    744.442000  stock  Facebook  ebab2398-028d-4939-9f1d-13bf38f81c50   
1    763.120000    adr    JD.com  b1e0ba21-bf54-454a-a409-89fe275bbe05   
2    890.680000  stock     Apple  450dfc6d-5510-4d40-abfb-f633b7d9be3e   
3    193.880000    adr   Alibaba  b2e06903-5c44-46a4-bd42-2a696f9d68e1   
4     -3.128000  stock    Sprint  3ad11874-934e-4b7f-8686-c7c9115b1a0b   

    pe_ratio percentage ticker  
0  31.898400      36.38     FB  
1  82.393500      28.91     JD  
2  22.224800      23.97   AAPL  
3  23.053500       8.90   BABA  
4       None       1.77      S  
                  open        high         low       close
Date                                                      
2018-01-31  162.511780  162.851486  150.592499  152.434464
2018-02-10  158.574326  168.593033  158.574326  168.047272
2018-02-20  167.482025  174.421036  166.721848  170.551941
2018-03-02  171.731186  175.405365  170.581207  175.405365
2018-03-12  177.101135  177.101135  166.916748  166.916748
                  High         Low        Open       Close    Volume  \
Date                                                                   
2018-01-31  206.199997  202.800003  202.820007  204.289993  26982500   
2018-02-01  199.490005  191.139999  192.750000  192.220001  52628900   
2018-02-02  195.679993  186.800003  194.789993  187.309998  32233900   
2018-02-05  190.470001  179.899994  183.699997  180.529999  31084000   
2018-02-06  185.589996  174.169998  174.720001  185.169998  35804500   

             Adj Close  
Date                    
2018-01-31  204.289993  
2018-02-01  192.220001  
2018-02-02  187.309998  
2018-02-05  180.529999  
2018-02-06  185.169998  
        price      quantity average_buy_price   equity percent_change  \
0  198.450000   20.00000000          161.2279  3969.00          23.09   
1   31.540000  100.00000000           23.9088  3154.00          31.92   
2  261.500000   10.00000000          172.4320  2615.00          51.65   
3  194.240000    5.00000000          155.4640   971.20          24.94   
4    5.670000   34.00000000            5.7620   192.78          -1.60   

  equity_change   type      name                                    id  \
0    744.442000  stock  Facebook  ebab2398-028d-4939-9f1d-13bf38f81c50   
1    763.120000    adr    JD.com  b1e0ba21-bf54-454a-a409-89fe275bbe05   
2    890.680000  stock     Apple  450dfc6d-5510-4d40-abfb-f633b7d9be3e   
3    193.880000    adr   Alibaba  b2e06903-5c44-46a4-bd42-2a696f9d68e1   
4     -3.128000  stock    Sprint  3ad11874-934e-4b7f-8686-c7c9115b1a0b   

    pe_ratio percentage ticker  
0  31.898400      36.38     FB  
1  82.393500      28.91     JD  
2  22.224800      23.97   AAPL  
3  23.053500       8.90   BABA  
4       None       1.77      S  
        price      quantity average_buy_price   equity percent_change  \
0  198.450000   20.00000000          161.2279  3969.00          23.09   
1   31.540000  100.00000000           23.9088  3154.00          31.92   
2  261.500000   10.00000000          172.4320  2615.00          51.65   
3  194.240000    5.00000000          155.4640   971.20          24.94   
4    5.670000   34.00000000            5.7620   192.78          -1.60   

  equity_change   type      name                                    id  \
0    744.442000  stock  Facebook  ebab2398-028d-4939-9f1d-13bf38f81c50   
1    763.120000    adr    JD.com  b1e0ba21-bf54-454a-a409-89fe275bbe05   
2    890.680000  stock     Apple  450dfc6d-5510-4d40-abfb-f633b7d9be3e   
3    193.880000    adr   Alibaba  b2e06903-5c44-46a4-bd42-2a696f9d68e1   
4     -3.128000  stock    Sprint  3ad11874-934e-4b7f-8686-c7c9115b1a0b   

    pe_ratio percentage ticker  
0  31.898400      36.38     FB  
1  82.393500      28.91     JD  
2  22.224800      23.97   AAPL  
3  23.053500       8.90   BABA  
4       None       1.77      S  
                  open        high         low       close
Date                                                      
2018-01-31  204.289993  204.289993  173.699997  176.669998
2018-02-10  177.440002  187.449997  177.440002  183.679993
2018-02-20  187.190002  194.190002  181.990005  181.990005
2018-03-02  179.759995  190.550003  179.759995  190.550003
2018-03-12  192.740005  200.279999  188.410004  195.300003
            High   Low  Open  Close    Volume  Adj Close
Date                                                    
2018-01-31  5.33  5.22  5.31   5.33  12501500       5.33
2018-02-01  5.28  4.91  5.26   5.10  42406100       5.10
2018-02-02  5.51  5.21  5.50   5.36  36195200       5.36
2018-02-05  5.42  5.10  5.36   5.13  20358100       5.13
2018-02-06  5.24  5.01  5.06   5.10  17242100       5.10
        price      quantity average_buy_price   equity percent_change  \
0  198.450000   20.00000000          161.2279  3969.00          23.09   
1   31.540000  100.00000000           23.9088  3154.00          31.92   
2  261.500000   10.00000000          172.4320  2615.00          51.65   
3  194.240000    5.00000000          155.4640   971.20          24.94   
4    5.670000   34.00000000            5.7620   192.78          -1.60   

  equity_change   type      name                                    id  \
0    744.442000  stock  Facebook  ebab2398-028d-4939-9f1d-13bf38f81c50   
1    763.120000    adr    JD.com  b1e0ba21-bf54-454a-a409-89fe275bbe05   
2    890.680000  stock     Apple  450dfc6d-5510-4d40-abfb-f633b7d9be3e   
3    193.880000    adr   Alibaba  b2e06903-5c44-46a4-bd42-2a696f9d68e1   
4     -3.128000  stock    Sprint  3ad11874-934e-4b7f-8686-c7c9115b1a0b   

    pe_ratio percentage ticker  
0  31.898400      36.38     FB  
1  82.393500      28.91     JD  
2  22.224800      23.97   AAPL  
3  23.053500       8.90   BABA  
4       None       1.77      S  
        price      quantity average_buy_price   equity percent_change  \
0  198.450000   20.00000000          161.2279  3969.00          23.09   
1   31.540000  100.00000000           23.9088  3154.00          31.92   
2  261.500000   10.00000000          172.4320  2615.00          51.65   
3  194.240000    5.00000000          155.4640   971.20          24.94   
4    5.670000   34.00000000            5.7620   192.78          -1.60   

  equity_change   type      name                                    id  \
0    744.442000  stock  Facebook  ebab2398-028d-4939-9f1d-13bf38f81c50   
1    763.120000    adr    JD.com  b1e0ba21-bf54-454a-a409-89fe275bbe05   
2    890.680000  stock     Apple  450dfc6d-5510-4d40-abfb-f633b7d9be3e   
3    193.880000    adr   Alibaba  b2e06903-5c44-46a4-bd42-2a696f9d68e1   
4     -3.128000  stock    Sprint  3ad11874-934e-4b7f-8686-c7c9115b1a0b   

    pe_ratio percentage ticker  
0  31.898400      36.38     FB  
1  82.393500      28.91     JD  
2  22.224800      23.97   AAPL  
3  23.053500       8.90   BABA  
4       None       1.77      S  
            open  high   low  close
Date                               
2018-01-31  5.33  5.51  5.10   5.30
2018-02-10  5.27  5.49  5.26   5.39
2018-02-20  5.45  5.45  5.19   5.25
2018-03-02  5.29  5.38  5.29   5.30
2018-03-12  5.32  5.36  5.16   5.16
In [20]:
 
                  High         Low        Open       Close     Volume  \
Date                                                                    
2015-01-02  529.815369  522.665039  527.561584  523.373108  1447500.0   
2015-01-05  522.894409  511.655243  521.827332  512.463013  2059800.0   
2015-01-06  514.761719  499.678131  513.589966  500.585632  2899900.0   
2015-01-07  505.855164  498.281952  505.611847  499.727997  2065000.0   
2015-01-08  502.101471  489.655640  496.626526  501.303680  3353500.0   

             Adj Close  100ma  
Date                           
2015-01-02  523.373108    NaN  
2015-01-05  512.463013    NaN  
2015-01-06  500.585632    NaN  
2015-01-07  499.727997    NaN  
2015-01-08  501.303680    NaN  
In [21]:
 
                  High         Low        Open       Close     Volume  \
Date                                                                    
2015-01-02  529.815369  522.665039  527.561584  523.373108  1447500.0   
2015-01-05  522.894409  511.655243  521.827332  512.463013  2059800.0   
2015-01-06  514.761719  499.678131  513.589966  500.585632  2899900.0   
2015-01-07  505.855164  498.281952  505.611847  499.727997  2065000.0   
2015-01-08  502.101471  489.655640  496.626526  501.303680  3353500.0   

             Adj Close       100ma  
Date                                
2015-01-02  523.373108  523.373108  
2015-01-05  512.463013  517.918060  
2015-01-06  500.585632  512.140584  
2015-01-07  499.727997  509.037437  
2015-01-08  501.303680  507.490686  
In [22]:
 
In [24]:
df_ohlc = df['Adj Close'].resample('10D').ohlc()
df_volume = df['Volume'].resample('10D').sum()

print(df_ohlc.head())

df_ohlc = df_ohlc.reset_index()
                  open        high         low       close
Date                                                      
2015-01-02  523.373108  523.373108  494.811493  494.811493
2015-01-12  491.201416  516.621643  491.201416  516.621643
2015-01-22  532.926819  538.471619  508.603638  533.056519
2015-02-01  527.033020  535.469849  521.328674  535.469849
2015-02-11  534.502502  547.506836  534.502502  537.474365
In [29]:
from mpl_finance import candlestick_ohlc
import matplotlib.dates as mdates

df_ohlc['Date'] = df_ohlc['Date'].map(mdates.date2num)

fig = plt.figure()
ax1 = plt.subplot2grid((6,1), (0,0), rowspan=5, colspan=1)
ax2 = plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1,sharex=ax1)
ax1.xaxis_date

candlestick_ohlc(ax1, df_ohlc.values, width=2, colorup='g')
ax2.fill_between(df_volume.index.map(mdates.date2num),df_volume.values,0)
plt.show()
In [35]:
import bs4 as bs
import datetime as dt
import matplotlib.pyplot as plt
from matplotlib import style
import numpy as np
import os
import pandas as pd
import pandas_datareader.data as web
import pickle
import requests

style.use('ggplot')


def save_sp500_tickers():
    resp = requests.get('http://en.wikipedia.org/wiki/List_of_S%26P_500_companies')
    soup = bs.BeautifulSoup(resp.text, 'lxml')
    table = soup.find('table', {'class': 'wikitable sortable'})
    tickers = []
    for row in table.findAll('tr')[1:]:
        ticker = row.findAll('td')[0].text
        tickers.append(ticker)
    with open("sp500tickers.pickle", "wb") as f:
        pickle.dump(tickers, f)
    return tickers


# save_sp500_tickers()
def get_data_from_yahoo(reload_sp500=False):
    if reload_sp500:
        tickers = save_sp500_tickers()
    else:
        with open("sp500tickers.pickle", "rb") as f:
            tickers = pickle.load(f)
    if not os.path.exists('stock_dfs'):
        os.makedirs('stock_dfs')

    start = dt.datetime(2010, 1, 1)
    end = dt.datetime.now()
    for ticker in tickers:
        # just in case your connection breaks, we'd like to save our progress!
        if not os.path.exists('stock_dfs/{}.csv'.format(ticker)):
            df = web.DataReader(ticker, 'morningstar', start, end)
            df.reset_index(inplace=True)
            df.set_index("Date", inplace=True)
            df = df.drop("Symbol", axis=1)
            df.to_csv('stock_dfs/{}.csv'.format(ticker))
        else:
            print('Already have {}'.format(ticker))


def compile_data():
    with open("sp500tickers.pickle", "rb") as f:
        tickers = pickle.load(f)

    main_df = pd.DataFrame()

    for count, ticker in enumerate(tickers):
        df = pd.read_csv('stock_dfs/{}.csv'.format(ticker))
        df.set_index('Date', inplace=True)

        df.rename(columns={'Adj Close': ticker}, inplace=True)
        df.drop(['Open', 'High', 'Low', 'Close', 'Volume'], 1, inplace=True)

        if main_df.empty:
            main_df = df
        else:
            main_df = main_df.join(df, how='outer')

        if count % 10 == 0:
            print(count)
    print(main_df.head())
    main_df.to_csv('sp500_joined_closes.csv')


def visualize_data():
    df = pd.read_csv('sp500_joined_closes.csv')
    df_corr = df.corr()
    print(df_corr.head())
    df_corr.to_csv('sp500corr.csv')
    data1 = df_corr.values
    fig1 = plt.figure()
    ax1 = fig1.add_subplot(111)

    heatmap1 = ax1.pcolor(data1, cmap=plt.cm.RdYlGn)
    fig1.colorbar(heatmap1)

    ax1.set_xticks(np.arange(data1.shape[1]) + 0.5, minor=False)
    ax1.set_yticks(np.arange(data1.shape[0]) + 0.5, minor=False)
    ax1.invert_yaxis()
    ax1.xaxis.tick_top()
    column_labels = df_corr.columns
    row_labels = df_corr.index
    ax1.set_xticklabels(column_labels)
    ax1.set_yticklabels(row_labels)
    plt.xticks(rotation=90)
    heatmap1.set_clim(-1, 1)
    plt.tight_layout()
    plt.show()


visualize_data()

import robin_stocks as rs
import pandas as pd
import json

def update_trade_history(symbols, holdings_data, file_name):
    """ Writes data about a trade to a JSON file, containing the sell date, buy date,
        price at which the stock was bought and sold at, etc.
    Args:
        symbols(list): List of strings, strings are the symbols of the stocks we've just sold and want to write data for.
        holdings_data(dict): dict obtained from get_modified_holdings() method. We need this method rather than r.build_holdings() to get a stock's buying date
        file_name(str): name of the file we are writing the data to. Should be "tradehistory.txt" if this method is normally called by scan_stocks().
                        If you want to write to another file, create a new text file with two empty brackets with an empty line between them, to meet JSON formatting standards.
    """
    with open(file_name) as json_file:
        data = json.load(json_file)
    current_time = str(pd.Timestamp("now"))
    data[current_time] = ({})
    for symbol in symbols:
        data[current_time].update({symbol: holdings_data[symbol]})
    with open(file_name, 'w') as outfile:
        json.dump(data, outfile)

def read_trade_history(file_name):
    """ Reads data about previous trades from JSON file and prints it out
    Args:
        file_name(str): name of the file we are reading from. Should be "tradehistory.txt" by default
    """
    with open(file_name) as json_file:
        data = json.load(json_file)
    for sell_date, event in data.items():
        print(sell_date + ": ")
        for symbol, dict in event.items():
            quantity, price, change, percent, bought_at = str(int(float(dict.get("quantity")))), dict.get("price"), dict.get("equity_change"), dict.get("percent_change"), dict.get("bought_at")
            print("\tSold " + quantity + " shares of "+ symbol + " at " + price + ", " + change + " (" +
                percent + "%) profit/loss, bought on " + bought_at)

def get_total_gains_minus_dividends():
    """ Returns the amount of money you've gained/lost through trading since the creation of your account, minus dividends
    """
    profileData = rs.load_portfolio_profile()
    print(profileData)
    allTransactions = rs.get_bank_transfers()
    deposits = sum(float(x['amount']) for x in allTransactions if (x['direction'] == 'deposit')) # and (x['state'] == 'completed'))
    withdrawals = sum(float(x['amount']) for x in allTransactions if (x['direction'] == 'withdraw') and (x['state'] == 'completed'))
    money_invested = deposits - withdrawals
    print(deposits)
    dividends = rs.get_total_dividends()
    percentDividend = dividends/money_invested*100
    totalGainMinusDividends =float(profileData['extended_hours_equity'])-dividends-money_invested
    return totalGainMinusDividends
In [49]:
import robin_stocks as r
import pandas as pd
import numpy as np
from pandas.plotting import register_matplotlib_converters
import ta as ta
from ta import *
from misc import *
from tradingstats import *

#Log in to Robinhood
login = r.login(creds['USER_ID'], creds['PASSCODE'])

def get_watchlist_symbols():
    """
    Returns: the symbol for each stock in your watchlist as a list of strings
    """
    my_list_names = []
    symbols = []
    for name in r.get_all_watchlists(info='name'):
        my_list_names.append(name)
    for name in my_list_names:
        list = r.get_watchlist_by_name(name)
        for item in list:
            instrument_data = r.get_instrument_by_url(item.get('instrument'))
            symbol = instrument_data['symbol']
            symbols.append(symbol)
    return symbols

def get_portfolio_symbols():
    """
    Returns: the symbol for each stock in your portfolio as a list of strings
    """
    symbols = []
    holdings_data = r.get_current_positions()
    for item in holdings_data:
        if not item:
            continue
        instrument_data = r.get_instrument_by_url(item.get('instrument'))
        symbol = instrument_data['symbol']
        symbols.append(symbol)
    return symbols

def get_position_creation_date(symbol, holdings_data):
    """Returns the time at which we bought a certain stock in our portfolio
    Args:
        symbol(str): Symbol of the stock that we are trying to figure out when it was bought
        holdings_data(dict): dict returned by r.get_current_positions()
    Returns:
        A string containing the date and time the stock was bought, or "Not found" otherwise
    """
    instrument = r.get_instruments_by_symbols(symbol)
    url = instrument[0].get('url')
    for dict in holdings_data:
        if(dict.get('instrument') == url):
            return dict.get('created_at')
    return "Not found"

def get_modified_holdings():
    """ Retrieves the same dictionary as r.build_holdings, but includes data about
        when the stock was purchased, which is useful for the read_trade_history() method
        in tradingstats.py
    Returns:
        the same dict from r.build_holdings, but with an extra key-value pair for each
        position you have, which is 'bought_at': (the time the stock was purchased)
    """
    holdings = r.build_holdings()
    holdings_data = r.get_current_positions()
    for symbol, dict in holdings.items():
        bought_at = get_position_creation_date(symbol, holdings_data)
        bought_at = str(pd.to_datetime(bought_at))
        holdings[symbol].update({'bought_at': bought_at})
    return holdings

def get_last_crossing(df, days, symbol="", direction=""):
    """Searches for a crossing between two indicators for a given stock
    Args:
        df(pandas.core.frame.DataFrame): Pandas dataframe with columns containing the stock's prices, both indicators, and the dates
        days(int): Specifies the maximum number of days that the cross can occur by
        symbol(str): Symbol of the stock we're querying. Optional, used for printing purposes
        direction(str): "above" if we are searching for an upwards cross, "below" if we are searching for a downwaords cross. Optional, used for printing purposes
    Returns:
        1 if the short-term indicator crosses above the long-term one
        0 if there is no cross between the indicators
        -1 if the short-term indicator crosses below the long-term one
    """
    prices = df.loc[:,"Price"]
    shortTerm = df.loc[:,"Indicator1"]
    LongTerm = df.loc[:,"Indicator2"]
    dates = df.loc[:,"Dates"]
    lastIndex = prices.size - 1
    index = lastIndex
    found = index
    recentDiff = (shortTerm.at[index] - LongTerm.at[index]) >= 0
    if((direction == "above" and not recentDiff) or (direction == "below" and recentDiff)):
        return 0
    index -= 1
    while(index >= 0 and found == lastIndex and not np.isnan(shortTerm.at[index]) and not np.isnan(LongTerm.at[index]) \
                        and ((pd.Timestamp("now", tz='UTC') - dates.at[index]) <= pd.Timedelta(str(days) + " days"))):
        if(recentDiff):
            if((shortTerm.at[index] - LongTerm.at[index]) < 0):
                found = index
        else:
            if((shortTerm.at[index] - LongTerm.at[index]) > 0):
                found = index
        index -= 1
    if(found != lastIndex):
        if((direction == "above" and recentDiff) or (direction == "below" and not recentDiff)):
            print(symbol + ": Short SMA crossed" + (" ABOVE " if recentDiff else " BELOW ") + "Long SMA at " + str(dates.at[found]) \
                +", which was " + str(pd.Timestamp("now", tz='UTC') - dates.at[found]) + " ago", ", price at cross: " + str(prices.at[found]) \
                + ", current price: " + str(prices.at[lastIndex]))
        return (1 if recentDiff else -1)
    else:
        return 0

def five_year_check(stockTicker):
    """Figure out if a stock has risen or been created within the last five years.
    Args:
        stockTicker(str): Symbol of the stock we're querying
    Returns:
        True if the stock's current price is higher than it was five years ago, or the stock IPO'd within the last five years
        False otherwise
    """
    instrument = r.get_instruments_by_symbols(stockTicker)
    list_date = instrument[0].get("list_date")
    if ((pd.Timestamp("now") - pd.to_datetime(list_date)) < pd.Timedelta("5 Y")):
        return True
    fiveyear = r.get_historicals(stockTicker,span='5year',bounds='regular')
    closingPrices = []
    for item in fiveyear:
        closingPrices.append(float(item['close_price']))
    recent_price = closingPrices[len(closingPrices) - 1]
    oldest_price = closingPrices[0]
    return (recent_price > oldest_price)

def golden_cross(stockTicker, n1, n2, days, direction=""):
    """Determine if a golden/death cross has occured for a specified stock in the last X trading days
    Args:
        stockTicker(str): Symbol of the stock we're querying
        n1(int): Specifies the short-term indicator as an X-day moving average.
        n2(int): Specifies the long-term indicator as an X-day moving average.
                 (n1 should be smaller than n2 to produce meaningful results, e.g n1=50, n2=200)
        days(int): Specifies the maximum number of days that the cross can occur by
        direction(str): "above" if we are searching for an upwards cross, "below" if we are searching for a downwaords cross. Optional, used for printing purposes
    Returns:
        1 if the short-term indicator crosses above the long-term one
        0 if there is no cross between the indicators
        -1 if the short-term indicator crosses below the long-term one
        False if direction == "above" and five_year_check(stockTicker) returns False, meaning that we're considering whether to
            buy the stock but it hasn't risen overall in the last five years, suggesting it contains fundamental issues
    """
    if(direction == "above" and not five_year_check(stockTicker)):
        return False
    history = r.get_historicals(stockTicker,span='year',bounds='regular')
    closingPrices = []
    dates = []
    for item in history:
        closingPrices.append(float(item['close_price']))
        dates.append(item['begins_at'])
    price = pd.Series(closingPrices)
    dates = pd.Series(dates)
    dates = pd.to_datetime(dates)
    sma1 = ta.volatility.bollinger_mavg(price, n=int(n1), fillna=False)
    sma2 = ta.volatility.bollinger_mavg(price, n=int(n2), fillna=False)
    series = [price.rename("Price"), sma1.rename("Indicator1"), sma2.rename("Indicator2"), dates.rename("Dates")]
    df = pd.concat(series, axis=1)
    cross = get_last_crossing(df, days, symbol=stockTicker, direction=direction)
    # if(cross):
    #     show_plot(price, sma1, sma2, dates, symbol=stockTicker, label1=str(n1)+" day SMA", label2=str(n2)+" day SMA")
    return cross

df['30_MA_Close'] = df['Close'].rolling(window=30).mean()
#calculating 20 days rolling standard devtaion
df['20_std_Close'] = df['Close'].rolling(window=20).std()


def sell_holdings(symbol, holdings_data):
    """ Place an order to sell all holdings of a stock.
    Args:
        symbol(str): Symbol of the stock we want to sell
        holdings_data(dict): dict obtained from get_modified_holdings() method
    """
    shares_owned = int(float(holdings_data[symbol].get("quantity")))
    r.order_sell_market(symbol, shares_owned)
    print("####### Selling " + str(shares_owned) + " shares of " + symbol + " #######")

def buy_holdings(potential_buys, profile_data, holdings_data):
    """ Places orders to buy holdings of stocks. This method will try to order
        an appropriate amount of shares such that your holdings of the stock will
        roughly match the average for the rest of your portfoilio. If the share
        price is too high considering the rest of your holdings and the amount of
        buying power in your account, it will not order any shares.
    Args:
        potential_buys(list): List of strings, the strings are the symbols of stocks we want to buy
        symbol(str): Symbol of the stock we want to sell
        holdings_data(dict): dict obtained from r.build_holdings() or get_modified_holdings() method
    """
    cash = float(profile_data.get('cash'))
    portfolio_value = float(profile_data.get('equity')) - cash
    ideal_position_size = (portfolio_value/len(holdings_data)+cash/len(potential_buys))/(2 * len(potential_buys))
    prices = r.get_latest_price(potential_buys)
    for i in range(0, len(potential_buys)):
        stock_price = float(prices[i])
        if(ideal_position_size < stock_price < ideal_position_size*1.5):
            num_shares = int(ideal_position_size*1.5/stock_price)
        elif (stock_price < ideal_position_size):
            num_shares = int(ideal_position_size/stock_price)
        else:
            print("####### Tried buying shares of " + potential_buys[i] + ", but not enough buying power to do so#######")
            break
        print("####### Buying " + str(num_shares) + " shares of " + potential_buys[i] + " #######")
        r.order_buy_market(potential_buys[i], num_shares)

def scan_stocks():
    """ The main method. Sells stocks in your portfolio if their 50 day moving average crosses
        below the 200 day, and buys stocks in your watchlist if the opposite happens.
        ###############################################################################################
        WARNING: Comment out the sell_holdings and buy_holdings lines if you don't actually want to execute the trade.
        ###############################################################################################
        If you sell a stock, this updates tradehistory.txt with information about the position,
        how much you've earned/lost, etc.
    """
    print("----- Starting scan... -----\n")
    register_matplotlib_converters()
    watchlist_symbols = get_watchlist_symbols()
    portfolio_symbols = get_portfolio_symbols()
    holdings_data = get_modified_holdings()
    potential_buys = []
    sells = []
    print("Current Portfolio: " + str(portfolio_symbols) + "\n")
    print("Current Watchlist: " + str(watchlist_symbols) + "\n")
    print("----- Scanning portfolio for stocks to sell -----\n")
    for symbol in portfolio_symbols:
        cross = golden_cross(symbol, n1=50, n2=200, days=30, direction="below")
        if(cross == -1):
            sell_holdings(symbol, holdings_data)
            sells.append(symbol)
    profile_data = r.build_user_profile()
    print("\n----- Scanning watchlist for stocks to buy -----\n")
    for symbol in watchlist_symbols:
        if(symbol not in portfolio_symbols):
            cross = golden_cross(symbol, n1=50, n2=200, days=10, direction="above")
            if(cross == 1):
                potential_buys.append(symbol)
    if(len(potential_buys) > 0):
        buy_holdings(potential_buys, profile_data, holdings_data)
    if(len(sells) > 0):
        update_trade_history(sells, holdings_data, "tradehistory.txt")
    print("----- Scan over -----\n")

#execute the scan
scan_stocks()
----- Starting scan... -----

Current Portfolio: ['FB', 'JD', 'AAPL', 'BABA', 'S']

Current Watchlist: ['S', 'BDSI', 'IBM', 'EQIX', 'FB', 'SBUX', 'NFLX', 'AAPL', 'GE', 'F', 'BABA', 'GOOG', 'GOOGL', 'FIT', 'GLUU', 'WIX', 'ZNGA', 'GM', 'GME', 'FSLR', 'WMT', 'HPQ', 'AGN', 'NVDA', 'AMAT', 'SPOT', 'BA', 'BAC', 'JPM', 'RYAAY', 'DLPH', 'AMD', 'INFY', 'SNAP', 'PXLW', 'BLNK', 'CHK', 'AXAS', 'VZ', 'HPE', 'WB', 'JD', 'DIS', 'CVS', 'LUV', 'GS', 'EAD', 'HDB', 'YEXT', 'INTC', 'CSCO', 'NOK', 'TMUS', 'BB', 'ATVI', 'SNE', 'ADBE', 'BRK.B', 'BIDU', 'C', 'CMCSA', 'CVX', 'CRM', 'MSFT', 'COST', 'DAL', 'EA', 'EBAY', 'FDX', 'M', 'MU', 'MA', 'MCD', 'NKE', 'ORCL', 'PFE', 'PYPL', 'QCOM', 'PEP', 'ROKU', 'ROST', 'SQ', 'SPGI', 'SLB', 'SCHW', 'UNH', 'TQQQ', 'UTX', 'UPS', 'V', 'VMW', 'WFC', 'WDC', 'XOM', 'YELP', 'OLED', 'MS', 'NTDOY', 'ADDYY', 'VWAGY', 'BMWYY', 'NSANY', 'TSLA', 'MZDAY', 'AMRN', 'BSX', 'SFTBY', 'DELL', 'DBX', 'JVA', 'LUNA', 'ALSK', 'III', 'GORO', 'TRQ', 'NXPI', 'SFIX', 'WIT', 'INDY', 'RDY', 'VEDL', 'SMIN', 'INDA', 'AMZN', 'JNJ', 'POAHY', 'UL', 'RKUNY', 'NPSNY', 'SHOP', 'LYFT', 'LEVI', 'UBER', 'BYND', 'AVGO', 'HAL', 'TWTR', 'UUU']

----- Scanning portfolio for stocks to sell -----


----- Scanning watchlist for stocks to buy -----

UNH: Short SMA crossed ABOVE Long SMA at 2019-11-26 00:00:00+00:00, which was 8 days 00:58:23.385126 ago , price at cross: 281.4, current price: 279.66
BMWYY: Short SMA crossed ABOVE Long SMA at 2019-11-27 00:00:00+00:00, which was 7 days 00:58:27.019294 ago , price at cross: 27.43, current price: 26.55
INDY: Short SMA crossed ABOVE Long SMA at 2019-11-25 00:00:00+00:00, which was 9 days 00:58:31.167335 ago , price at cross: 38.01, current price: 38.03
####### Buying 1 shares of UNH #######
####### Buying 13 shares of BMWYY #######
####### Buying 9 shares of INDY #######
----- Scan over -----

In [46]:
from yahoo_fin import stock_info as si
si.get_live_price("FB")
Out[46]:
198.82000732421875