Ejemplo n.º 1
0
def sell_old_stocks():
    divies = [[x.get('instrument'), x.get('record_date')] for x in r.get_dividends()]
    positions_data = r.get_current_positions()
    for position in positions_data:
        for d in divies:
            if position.get('instrument') in d[0]:
                about = r.request_get(position['instrument'])
                div_diff = (datetime.strptime(d[1], '%Y-%m-%d') - today).days
                if div_diff <= 0:
                    stock_dict = r.stocks.get_stock_quote_by_symbol(about.get('symbol'))
                    last_trade_price = float(stock_dict.get('last_trade_price'))
                    if last_trade_price / float(position['average_buy_price']) > 1.005:
                        if float(position.get('shares_held_for_sells')) == 0:
                            if easygui.ccbox(msg=about.get('symbol') + '\n' + d[1] + '\nQuantity: ' + str(position['quantity']) + '\nPurchase $' + str(float(position['average_buy_price'])) + '\nCurrent price $' + str(last_trade_price) + '\nProfit per $' + str(float(last_trade_price) - float(position['average_buy_price'])) + '\nTotal win $' + str((float(last_trade_price) - float(position['average_buy_price']))*float(position['quantity'])) + '\nROI ' + str(100 - (float(last_trade_price) / float(position['average_buy_price']))*-100) + '%'  ):
                                r.order_sell_limit(about.get('symbol'), position['quantity'], round(last_trade_price*1.0035, 2))
                                print('selling ', about.get('symbol'))
                else:
                    stock_dict = r.stocks.get_stock_quote_by_symbol(about.get('symbol'))
                    last_trade_price = float(stock_dict.get('last_trade_price'))
                    if last_trade_price / float(position['average_buy_price']) > 1.015:
                        if float(position.get('shares_held_for_sells')) == 0:
                            if easygui.ccbox(msg='NO DIVVIE SALE\n' +about.get('symbol') + '\n' + d[1] + '\nQuantity: ' + str(position['quantity']) + '\nPurchase $' + str(float(position['average_buy_price'])) + '\nCurrent price $' + str(last_trade_price) + '\nProfit per $' + str(float(last_trade_price) - float(position['average_buy_price'])) + '\nTotal win $' + str((float(last_trade_price) - float(position['average_buy_price'])) * float(position['quantity'])) + '\nROI ' + str(100 - (float(last_trade_price) / float(position['average_buy_price'])) * -100) + '%'):
                                r.order_sell_limit(about.get('symbol'), position['quantity'], round(last_trade_price * 1.0035, 2))
                                print('selling ', about.get('symbol'))
Ejemplo n.º 2
0
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://sandbox.iexapis.com/stable/stock/{}/price?token={}"
                    .format(stock.symbol.lower(), os.environ.get('IEX_TOKEN')))
                # 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 auth_information #
    auth_information = r.login(username, password)
    print(auth_information)

    # optionorders = df_options_orders_history

    # Retrieve options history
    start_date == 'January 1, 2020'
    options_pnl = 0
    if options == 1:
        df_options_orders_history = rh.get_all_history_options_orders(r)

        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()
        print(
            "*************FILE EXPORTED    ******************************\n options_orders_history_df.csv\n\n"
        )
        print("OPTIONS PROFIT OR LOSS :")
        print(options_pnl)
        open_options = r.get_all_open_option_orders()
        for i in open_options:
            print(i)

    df_order_history, _ = rh.get_order_history(r)
    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 = r.get_dividends()

    # Put the dividends in a dataframe
    list_of_records = []
    for each in dividends:
        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
    options_pnl = 0
    if options == 1:
        df_options_orders_history = rh.get_all_history_options_orders(r)
        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()

    total_pnl = round(pnl + dividends_paid + options_pnl, 2)

    # Print final output
    print("~~~")
    print("From {} to {}, your total Profit/Loss 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')
Ejemplo n.º 3
0
def import_portfolio_robinhood(access_token,
                               username=None,
                               password=None,
                               name="Robinhood",
                               free_stock=False):
    """
    Accesses Robinhood account and downloads transactions 

    Parameters
    ==========
    username : Robinhood username
    password : Robinhood account password
    name : desired portfolio name 
    free_stock : include a free stock not captured by transaction history (see below)

    Returns
    =======
    df : dataframe with transactions
    p : portfolio (Portfolio class object)

    """
    if not access_token:
        if username is None:
            username = getpass("Username: "******"Password: "******"Parsing orders ...")

    # pre-pull all tickers before creating order history df
    Tickerset = []
    for order in orders:
        if len(order["executions"]):
            Tickerset.append(order["instrument"])
    Tickerset = list(set(Tickerset))

    # make a lookup dict for ticker symbols
    Tickersymbols = {}
    for element in Tickerset:
        Tickersymbols[element] = r.get_instrument_by_url(element)["symbol"]

    for order in orders:
        if len(order["executions"]):
            Date.append(pd.to_datetime(order["last_transaction_at"]))
            Transaction.append(order["side"])
            Ticker.append(Tickersymbols[order["instrument"]])
            Currency.append("USD")
            Price.append(order["average_price"])
            Quantity.append(order["quantity"])

    # add deposits
    transfers = r.get_bank_transfers()
    print("Parsing bank transfers ...")
    for transfer in transfers:
        if transfer["cancel"] is None:
            Date.append(pd.to_datetime(transfer["created_at"]))
            Transaction.append(transfer["direction"])
            Ticker.append(None)
            Currency.append("USD")
            Price.append(1.0)
            Quantity.append(transfer["amount"])

    # add dividends
    dividends = r.get_dividends()
    print("Parsing dividends ...")
    for dividend in dividends:
        if dividend["state"] == "paid":
            Date.append(pd.to_datetime(dividend["paid_at"]))
            Transaction.append("dividend")
            Ticker.append(Tickersymbols[dividend["instrument"]])
            Currency.append("USD")
            Price.append(1.0)
            Quantity.append(dividend["amount"])

    if free_stock == True:
        # include free stock (Robinhood promotion, not included in transaction history)
        print("Adding promotional stock ...")
        Date.append(pd.to_datetime("2/1/18"))
        Transaction.append("buy")
        Ticker.append("CHK")
        Currency.append("USD")
        Price.append(0.0)
        Quantity.append(1.0)

    # build dataframe
    d = {
        "Date": Date,
        "Transaction": Transaction,
        "Ticker": Ticker,
        "Currency": Currency,
        "Price": pd.to_numeric(Price),
        "Quantity": pd.to_numeric(Quantity),
    }
    df = pd.DataFrame(data=d)

    # strip time of day information
    df.Date = df.Date.map(lambda x: x.strftime("%m-%d-%Y"))
    df.Date = pd.to_datetime(df.Date)

    # create a new portfolio object
    p = Portfolio(name=name)

    # parse
    p = parse_portfolio(df, p)

    return p
Ejemplo n.º 4
0
 def test_dividends(self):
     stock = r.get_dividends(info=None)
     self.assertNotEqual(len(stock), 0)
Ejemplo n.º 5
0
def import_portfolio_robinhood(username=None,
                               password=None,
                               name="Robinhood",
                               free_stock=False):
    """
    Accesses Robinhood account and downloads transactions 

    Parameters
    ==========
    username : Robinhood username
    password : Robinhood account password
    name : desired portfolio name 
    free_stock : include a free stock not captured by transaction history (see below)

    Returns
    =======
    df : dataframe with transactions
    p : portfolio (Portfolio class object)

    """
    import robin_stocks as r
    from getpass import getpass

    if username is None: username = getpass("Username: "******"Password: "******"Parsing orders ...")
    for order in orders:
        if len(order['executions']):
            Date.append(pd.to_datetime(order['last_transaction_at']))
            Transaction.append(order['side'])
            Ticker.append(
                r.get_instrument_by_url(order['instrument'])['symbol'])
            Currency.append('USD')
            Price.append(order['average_price'])
            Quantity.append(order['quantity'])

    # add deposits
    transfers = r.get_bank_transfers()
    print("Parsing bank transfers ...")
    for transfer in transfers:
        if transfer['cancel'] is None:
            Date.append(pd.to_datetime(transfer['created_at']))
            Transaction.append('deposit')
            Ticker.append(None)
            Currency.append('USD')
            Price.append(1.0)
            Quantity.append(transfer['amount'])

    # add dividends
    dividends = r.get_dividends()
    print("Parsing dividends ...")
    for dividend in dividends:
        if dividend['state'] == 'paid':
            Date.append(pd.to_datetime(dividend['paid_at']))
            Transaction.append('dividend')
            Ticker.append(
                r.get_instrument_by_url(dividend['instrument'])['symbol'])
            Currency.append('USD')
            Price.append(
                float(dividend['amount']) / float(dividend['position']))
            Quantity.append(dividend['position'])

    if free_stock == True:
        # include free stock (Robinhood promotion, not included in transaction history)
        print("Adding promotional stock ...")
        Date.append(pd.to_datetime('2/1/18'))
        Transaction.append('buy')
        Ticker.append('CHK')
        Currency.append('USD')
        Price.append(0.0)
        Quantity.append(1.0)

    # build dataframe
    d = {
        'Date': Date,
        'Transaction': Transaction,
        'Ticker': Ticker,
        'Currency': Currency,
        'Price': pd.to_numeric(Price),
        'Quantity': pd.to_numeric(Quantity)
    }
    df = pd.DataFrame(data=d)

    # strip time of day information
    df.Date = df.Date.map(lambda x: x.strftime('%m-%d-%Y'))
    df.Date = pd.to_datetime(df.Date)

    # create a new portfolio object
    p = Portfolio(name=name)

    # parse
    p = parse_portfolio(df, p)

    return p
Ejemplo n.º 6
0
 def getDividends(self):
     return self.masterFormat(robin_stocks.get_dividends(), "dividend")
Ejemplo n.º 7
0
def LOAD_DIVIDENDS():
    func=r.get_dividends()
    return func