コード例 #1
0
class TestOptions:

    # have to login to use round_up_price
    totp = pyotp.TOTP(os.environ['robin_mfa']).now()
    login = r.login(os.environ['robin_username'],
                    os.environ['robin_password'],
                    mfa_code=totp)
    #
    now = datetime.datetime.now()
    expiration_date = third_friday(now.year, now.month,
                                   now.day).strftime("%Y-%m-%d")
    symbol = 'AAPL'
    strike = round_up_price(symbol, 100)

    def test_find_tradable_options(self):
        info = r.find_options_by_expiration(self.symbol, self.expiration_date)
        first = info[0]
        assert (first['expiration_date'] == self.expiration_date)
        assert (len(info) > 100)
        info = r.find_options_by_expiration(self.symbol,
                                            self.expiration_date,
                                            info='strike_price')
        first = info[0]
        assert (type(first) == str)
        assert (len(info) > 100)
        info = r.find_options_by_expiration(self.symbol,
                                            self.expiration_date,
                                            info='expiration_date')
        assert (len(set(info)) == 1)

    def test_find_options_by_strike(self):
        info = r.find_options_by_strike(self.symbol, self.strike)
        assert (len(info) > 30)
        info = r.find_options_by_strike(self.symbol, self.strike, 'call')
        assert (info[0]['type'] == 'call')
        info = r.find_options_by_strike(self.symbol,
                                        self.strike,
                                        info='expiration_date')
        assert (len(set(info)) > 1)
        info = r.find_options_by_strike(self.symbol,
                                        self.strike,
                                        info='strike_price')
        assert (len(set(info)) == 1)

    def test_find_options_by_expiration_and_strike(self):
        info = r.find_options_by_expiration_and_strike(self.symbol,
                                                       self.expiration_date,
                                                       self.strike)
        assert (len(info) == 2)
        assert (info[0]['expiration_date'] == self.expiration_date)
        assert (float(info[0]['strike_price']) == self.strike)
        info = r.find_options_by_expiration_and_strike(self.symbol,
                                                       self.expiration_date,
                                                       self.strike, 'call')
        assert (len(info) == 1)
        assert (info[0]['type'] == 'call')
コード例 #2
0
def login():
    if not ('username' in request.json and 'password' in request.json):
        return 'Invalid Request', 400

    if 'mfa_code' in request.json:
        login = robinhood.login(request.json['username'],
                                request.json['password'],
                                mfa_code=request.json['mfa_code'],
                                store_session=False)
    else:
        login = robinhood.login(request.json['username'],
                                request.json['password'],
                                store_session=False)
    response = {}
    response['access_token'] = login['access_token']
    response['expires_in'] = login['expires_in']
    robinhood.logout()
    del login
    return response, 200
コード例 #3
0
    async def run(self):
        r.login(os.getenv('ROBINHOOD_USERNAME'),
                os.getenv('ROBINHOOD_PASSWORD'))
        stock = self.content.replace('$trade_info ', '').upper().split()
        for s in stock:
            instrumental_data = r.stocks.find_instrument_data(s)
            fund = r.stocks.get_fundamentals(s)

            for d, d2 in zip(fund, instrumental_data):
                if None in [d, d2]:
                    message = "'" + s + "' stock symbol doesn't exist."
                    self.response.set_state(False)
                    self.response.add_response(message)
                    continue
                name = d2['simple_name']
                symbol = d2['symbol']
                open = d['open']
                high = d['high']
                low = d['low']
                volume = d['volume']
                average_volume_2_weeks = d['average_volume_2_weeks']
                high52weeks = d['high_52_weeks']
                low52weeks = d['low_52_weeks']
                dividend_yield = d['dividend_yield']
                floatt = d['float']
                market = d['market_cap']
                pb_ratio = d['pb_ratio']
                pe_ratio = d['pe_ratio']
                shares_outstanding = d['shares_outstanding']
                link = 'https://robinhood.com/stocks/' + symbol

                message = company_trading_info(name, symbol, open, high, low,
                                               volume, average_volume_2_weeks,
                                               high52weeks, low52weeks,
                                               dividend_yield, floatt, market,
                                               pb_ratio, pe_ratio,
                                               shares_outstanding, link)
                self.response.set_state(True)
                self.response.add_response(message)

        if len(self.response.response) == 0:
            self.response.set_error_response(0)
        self.response.done = True
コード例 #4
0
ファイル: robincli.py プロジェクト: DavidM-Fox/robinhood-cli
def get_history(password, save, ticker, interval, span):
    """get_history - Get a historical data range for a specific stock.
    
    TICKER - The stock symbol, i.e. TSLA.
    
    INTERVAL - 5minute 10minute hour day week.
    
    SPAN - day week month 3month year 5year.

    example - python robincli.py get_history --save TSLA 5minute day

    """
    with open(ACCOUNT_JSON, 'r') as f:
        account = json.load(f)

    if checkpw(password, account['password']):
        # Login Successful
        click.echo("Logged in as " + account['email'] + "\n")
        r.login(account['email'], password)

        data = r.get_stock_historicals(ticker, interval, span)
        df = pd.DataFrame.from_dict(data)
        df = df.drop(['session', 'interpolated', 'symbol'], axis=1)

        echo = {
            '5minute': '5 minute interval data for ',
            '10minute': '10 minute interval data for ',
            'hour': 'hourly data for ',
            'day': 'daily data for ',
            'week': 'weekly data for '
        }

        click.echo("Getting " + echo[interval] + ticker + " from past " +
                   span + "\n")
        print(df.to_string(index=False))

        if save:
            filename = ticker + "_" + interval + "_" + span + ".csv"
            df.to_csv(filename, index=False)

    else:
        # Login Unsuccessful
        click.echo("Incorrect Robinhood Password")
コード例 #5
0
    def login(self):
        """
        Method to login

        :param: None
        :return: None
        """
        creds = self.fetch_credentials()
        logging.info('logging in to robinhood now...')
        login = api.login(creds.get('username'), creds.get('password'))
コード例 #6
0
def get_watchlist_symbols(email, password, rh_watchlist):
    import sys
    import csv
    import requests
    import robin_stocks as r
    try:
        r.login(email, password)
        watchlist = r.get_watchlist_by_name(name=rh_watchlist, info=None)
        watchlistsymbols = []
        for item in watchlist:
            url = item['instrument']
            r = requests.get(url)
            data_json = r.json()
            # print(str(data_json))  # print this to see more symbol info.
            watchlistsymbols.append(data_json['symbol'])
        # put watchlist into a file if
        return(watchlistsymbols)
    except Exception as e:
        sys.exit(e)
コード例 #7
0
def login(credentials):

    global logging

    logging.info('Login into Robinhood.')

    # Read the credentials from a file
    f = open(credentials, 'r')
    creds = f.readlines()

    login = r.login(creds[0], creds[1])
コード例 #8
0
 def __init__(self):
     login = r.login(LOGIN_EMAIL,
                     LOGIN_PASSWORD,
                     expiresIn=10,
                     by_sms=False)
     self.holdings = r.build_holdings()
     self.securities = []
     self.prices = {}
     self.equity = {}
     self.profile = r.profiles.load_portfolio_profile()
     self.acct = r.profiles.load_account_profile()
コード例 #9
0
def get_robinhood_data():
    logging.info(f'Logging into Robinhood...')
    login = robin_stocks.login(username=os.getenv('TJ_USERNAME'),
                               password=os.getenv('TJ_PASSWORD'))
    logging.debug(login)
    logging.info(f'Fetching options orders...')
    all_option_orders = reversed(robin_stocks.orders.get_all_option_orders())
    logging.debug(all_option_orders)
    for order in all_option_orders:
        if order['state'] == 'filled':
            for leg in order['legs']:
                instrument_data = instrument_cache.get(leg['option'])
                expiration_date = str_dt(instrument_data['expiration_date'],
                                         '%Y-%m-%d').date()
                option_prices = []
                for execution in leg['executions']:
                    option_prices.extend([
                        float(execution['price']) for quantity in range(
                            int(float(execution['quantity'])))
                    ])
                account.execute_trade_event(
                    TradeEvent(
                        ticker=order['chain_symbol'],
                        expiration_date=expiration_date,
                        execution_time=utc_to_eastern(order['created_at']),
                        options=[
                            Option(
                                id_=leg['option'],
                                ticker=order['chain_symbol'],
                                expiration_date=expiration_date,
                                strike=float(instrument_data['strike_price']),
                                price=price,
                                is_call=True if instrument_data['type']
                                == 'call' else False,
                                is_long=True
                                if leg['side'] == 'buy' else False,
                            ) for price in option_prices
                        ]))
    all_stock_orders = reversed(robin_stocks.orders.get_all_stock_orders())
    logging.debug(all_stock_orders)
    for order in all_stock_orders:
        ticker = instrument_cache.get(order['instrument'])['symbol']
        execution_time = utc_to_eastern(order['last_transaction_at'])
        quantity = int(float(order['quantity']))
        is_long = True if order['side'] == 'buy' else False
        # logging.info(f'Adding {"+" if is_long else "-"}{quantity} shares of {ticker}')
        if order['state'] == 'filled' and order['cancel'] is None:
            account.add_shares([
                Share(ticker=ticker,
                      open_time=execution_time,
                      open_price=float(order['average_price']),
                      is_long=is_long) for share in range(quantity)
            ])
コード例 #10
0
ファイル: kivy_news.py プロジェクト: swethatandri/GeomHacks
def finance_news():
    rh.login("email", "password", store_session=True)
    print("logging in ...")
    q = open('/Users/adarshbulusu/Desktop/Kivy_News/StockMovements.txt', 'w')
    q.write("THESE ARE THE STOCKS THAT HAD THE BIGGEST GAINS RECENTLY!!!\n")
    q.write("\n")

    for i in range(len(rh.get_top_movers('up'))):
        q.write('\n')
        q.writelines(rh.get_top_movers('up')[i].get('symbol'))
        q.writelines(rh.get_top_movers('up')[i].get('description'))
        q.writelines("\n")

    q.write(("THESE ARE THE STOCKS THAT HAD THE BIGGEST LOSSES RECENTLY\n"))
    for i in range(len(rh.get_top_movers('down'))):
        q.write('\n')
        q.writelines(rh.get_top_movers('down')[i].get('symbol'))
        q.writelines(rh.get_top_movers('down')[i].get('description'))
        q.write("\n")

    q.close()
コード例 #11
0
ファイル: Background.py プロジェクト: xConde/Stonks
    async def background_loop(self, bot):
        """Runs on startup and every minute that the bot is running. [Specified in EST, but made in UTC]
        Task 1: If the US market is open (9AM[pre-market] - 8PM[after-hours] and not holiday), print a SPY chart``
         every 15 minutes.
        Task 2: Every 10 minutes (global time) write the stocks mentioned to 'stocks_mentioned.csv'.
        Task 3: If the US market is pre-market (9AM and weekday), but it's a holiday - make an announcement.

        :return:
        """
        await self.bot.wait_until_ready()
        channel = self.bot.get_channel(int(os.getenv('DISCORD_CHANNEL')))
        altchannel = self.bot.get_channel(int(
            os.getenv('DISCORD_CHANNEL_ALT')))
        holidayDate = cal.getHolidays()

        if cal.getDay() < 5 and not self.bot.is_closed() and cal.getCurrentDay() not in holidayDate and \
                (12 <= cal.getHour() <= 23):
            if cal.getMinute() % 15 == 0:
                res = s.autoPull()
                await channel.send("```" + res + "```")
            if cal.getMinute() % 5 == 0:
                if not s.validateTicker('SPY'):
                    user = await bot.fetch_user(
                        int(os.getenv('ROBINHOOD_USER_ACCOUNT')))
                    await channel.send(user.mention + " API key expired.")
                    if r.login(username=os.getenv('RH_USER'),
                               password=os.getenv('RH_PASS')):
                        await channel.send(
                            "```" +
                            'Restarted Robinhood instance successfully.' +
                            "```")
                        print("Restarted Robinhood instance successfully.")
                    else:
                        await channel.send(
                            "```" +
                            'Failed to create Robinhood instance. Bot owner has been sent an SMS.'
                            + "```")
                        print("Failed to create Robinhood instance.")
                s.stocks_mentioned['SPY'] = s.stocks_mentioned.get('SPY',
                                                                   0) - 1
            if cal.getMinute() % 1 == 0:
                msg, found = sweepcast()
                if found:
                    print('Option whales spotted')
                    await channel.send("```" + msg + "```")
                    await altchannel.send("```" + msg + "```")

        if cal.getMinute() % 10 == 0:
            s.writeStocksMentioned()
        if cal.getCurrentDay() in holidayDate and cal.getHour(
        ) == 14 and cal.getMinute() == 0:
            await channel.send("Today is " + holidayDate[cal.getCurrentDay()] +
                               " the market is closed. Enjoy your holiday!")
コード例 #12
0
    def login(self, username, password):
        self.username = username
        self.password = password
        
        # ensure that a device token has been generated
        if self.device_token == "":
                self.GenerateDeviceToken()

        # login via the robinhood api and update global authentication/refresh tokens
        login = rs.login(username, password)
        self.auth_token = login.get('access_token')
        self.refresh_token = login.get('refresh_token')
        return login
コード例 #13
0
	def login(self):
		pasw_file = None
		try:
			pasw_file = open("C:/Users/stbue/Desktop/robi_code.txt", 'r')
		except:
			try:
				pasw_file = open("C:/Users/Spencer/Desktop/robi_code.txt", 'r')
			except:
				sys.exit("No password provided, login unsuccessful. IYKYK")
		self.pasw += pasw_file.read()
		pasw_file.close()

		self.login_handle = r.login(self.user, self.pasw)
コード例 #14
0
    def Login(self,
              username=os.environ.get("robinhood_username"),
              password=os.environ.get("robinhood_password"),
              stayLoggedIn=True,
              mfaCode='mfa'):

        # Set the username and password envinroment variables as passed in
        os.environ["robinhood_username"] = username
        os.environ["robinhood_password"] = password

        # Grab the username and password environment variables
        robin_user = os.environ.get("robinhood_username")
        robin_pass = os.environ.get("robinhood_password")

        # Try to login
        try:
            rs.login(robin_user,
                     robin_pass,
                     store_session=stayLoggedIn,
                     mfa_code=mfaCode)
            return True
        except Exception as e:
            raise StockAPIException(e)
コード例 #15
0
    async def run(self):
        r.login(os.getenv('ROBINHOOD_USERNAME'),
                os.getenv('ROBINHOOD_PASSWORD'))
        crypto = self.content.replace('$crypto_price ', '').upper().split()
        for c in crypto:
            curr = r.get_crypto_info(c)
            if not curr:
                message = "❌ '" + c + "' Crypto symbol doesn't exist."
                self.response.add_response(message)
                continue
            for d in [curr]:
                name = d['name']
                symbol = c
                price = r.crypto.get_crypto_quote(c)
                for p in [price]:
                    cost = p['ask_price']
                message = name + ' (' + symbol + ') is currently worth' + '${:,.2f}'.format(
                    float(cost))
                self.response.add_response(message)

        if len(self.response.response) == 0:
            self.response.set_error_response(0)
        self.response.done = True
コード例 #16
0
def main():
    username = ''
    password = ''
    login = r.login(username, password)

    user_data = r.load_phoenix_account()
    portfolio_total = user_data['total_equity']['amount']
    total_dividends = r.get_total_dividends()

    print("Portfolio Value: " + str(portfolio_total) + fg.rs)
    print("Dividends Earned: " + str(total_dividends) + fg.rs)
    print("-")

    analyze_symbol('AAPL')
コード例 #17
0
    async def run(self):
        r.login(os.getenv('ROBINHOOD_USERNAME'), os.getenv('ROBINHOOD_PASSWORD'))
        minPE = 256
        if '$stocks_from_market ' in self.content:
            stock = self.content.replace('$stocks_from_market ', '').upper().split()
            tag = stock[0]
            market_info = (r.markets.get_all_stocks_from_market_tag(str(tag).lower()))
            for i in market_info:
                fundList = r.stocks.get_fundamentals((i['symbol']))
                fundDict = fundList[0]
                print(fundDict)
                print(i)
                if(fundDict['pe_ratio'] != None):
                    if minPE >= float(fundDict['pe_ratio']):
                        minPE = float((fundDict['pe_ratio']))
                        symbol = i['symbol']

        message = 'My recommendation for the ' + str(tag).lower() + ' industry is ' + symbol
        self.response.add_response(message, True)

        if len(self.response.response) == 0:
            self.response.set_error_response(0)
        self.response.done = True
コード例 #18
0
def main():
    # remove the store_session= false to ignore login everytime
    # login = r.login("*****@*****.**", "Warriors_123", store_session=False)
    login = r.login("*****@*****.**", "Warriors_123")
    if not login:
        sys.exit(1)

    while True:
        try:
            start()
            time.sleep(15)
        except KeyboardInterrupt:
            print("\n Thank you for using us...")
            r.logout()
            break
コード例 #19
0
ファイル: views.py プロジェクト: Rushilwiz/reinvest
 def get(self, request, format=None):
     login = r.login(os.getenv("ROBINHOOD_USER"),
                     os.getenv("ROBINHOOD_PASS"))
     stonks = r.build_holdings()
     for key, value in stonks.items():
         if Stock.objects.filter(uuid=value['id']).count() != 1:
             stock = Stock.objects.create(user=request.user.profile,
                                          quantity=ceil(
                                              float(value['quantity'])),
                                          ticker=key,
                                          buy_price=value['price'],
                                          uuid=value['id'])
     queryset = request.user.profile.stocks.all()
     serializer = StockSerializer(queryset, many=True)
     return Response(serializer.data, status=status.HTTP_200_OK)
コード例 #20
0
def sign_in():
    """
    Sign in to RobinHood to access data when server starts up
    :return: None
    """
    try:
        try:
            rbh.load_account_profile()
        except Exception as e:
            totp = pyotp.TOTP('My2factorAppHere').now()
            login = rbh.login(username, password, mfa_code=totp)
            print('sign in successfully')
            return login
    except Exception as e:
        print('fail login')
        print(e)
コード例 #21
0
    def login(self, username, password, mfa_code=None):

        self.username = username
        self.password = password

        # try getting access_token with new API
        l = r.login(username, password)
        if 'access_token' in l.keys():
            self.oauth_token = l['access_token']
            self.headers['Authorization'] = 'Bearer ' + self.oauth_token
            print(l)
            return True
        # /try getting access_token with new API

        payload = {
            'client_id': 'c82SH0WZOsabOXGP2sxqcj34FxkvfnWRZBKlBjFS',
            'expires_in': 86400,
            'grant_type': 'password',
            'password': self.password,
            'scope': 'internal',
            'username': self.username
        }

        if mfa_code:
            payload['mfa_code'] = mfa_code

        try:
            res = self.session.post('https://api.robinhood.com/oauth2/token/',
                                    data=payload,
                                    timeout=300)
            res.raise_for_status()
            data = res.json()
        except requests.exceptions.HTTPError:
            raise RH_exception.LoginFailed()

        if 'mfa_required' in data.keys():  # pragma: no cover
            raise RH_exception.TwoFactorRequired(
            )  # requires a second call to enable 2FA

        if 'access_token' in data.keys():
            self.oauth_token = data['access_token']
            self.headers['Authorization'] = 'Bearer ' + self.oauth_token
            return True

        return False
コード例 #22
0
    def buyBitcoinOnRobinhood(self):
        if default_config.robinhood_dca_usd_amount <= 0:
            Logger.info("Skip Robinhood DCA because the dca amount is no larger than 0")
            return
        username = self.secrets["robinhood_user"]
        passwd = self.secrets["robinhood_password"]
        totp = self.secrets["robinhood_totp"]
        login = robin_stocks.login(username, passwd, mfa_code=pyotp.TOTP(totp).now())
        Logger.info(f"{login['detail']}\n")

        dca_amount = default_config.robinhood_dca_usd_amount
        buy_order = robin_stocks.order_buy_crypto_by_price("BTC", dca_amount)
        Logger.info(f"{buy_order}\n")

        self.db_manager.saveRobinhoodBuyTransaction(
            date=buy_order["created_at"],
            price=round(float(buy_order["price"]), 2),
            size=buy_order["quantity"],
        )
コード例 #23
0
ファイル: views.py プロジェクト: Rushilwiz/reinvest
    def create(self, request, *args, **kwargs):
        import copy
        data = copy.deepcopy(request.data)
        data.update({'user': request.user})
        serializer = StockCreateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        login = r.login(os.getenv("ROBINHOOD_USER"),
                        os.getenv("ROBINHOOD_PASS"))
        order = r.order_buy_market(symbol=serializer.data['ticker'],
                                   quantity=serializer.data['quantity'])
        stonks = r.build_holdings()
        for key, value in stonks.items():
            if Stock.objects.filter(uuid=value['id']).count() != 1:
                stock = Stock.objects.create(user=request.user.profile,
                                             quantity=ceil(
                                                 float(value['quantity'])),
                                             ticker=key,
                                             buy_price=value['price'],
                                             uuid=value['id'])

        return Response(serializer.data, status=status.HTTP_200_OK)
コード例 #24
0
    def get_robin_data(self, username, password):
        """
        :param username: enter robinhood username
        :param password: enter robinhood password
        :return: a dictionary of your Robinhood stocks
        """
        try:
            # Creates a connection with Robinhood
            login = robin_stocks.login(username, password)
        except Exception as e:
            print(e, "Username or Password is incorrect.")

        # Pulls in user portfolio data from Robinhood
        my_stocks = robin_stocks.build_holdings()
        robinhood_dict = dict()
        # Extracts Ticker symbols as well as quantity of each ticker and average buy price of that ticker
        # Store that data in a list
        for key, value in my_stocks.items():
            robinhood_dict[key] = [value['quantity'], value['average_buy_price']]
        # Add stock to portfolio text file
        self.__add_stock_from_robinhood(robinhood_dict)
        return robinhood_dict
コード例 #25
0
def robinhood_login(account_path, args):
    """

    :param account_path: path to the account info
    :param args: --two-factor enabled
    :return:
    """
    with open(account_path, 'r') as f:
        acc_info = f.readlines()
    acc_info = acc_info[0].split(" ")
    args = args
    two_factor = ("--two_factor" in args)

    print("Logging in")
    if two_factor:
        print("Two Factor authentication required")
        print("Not Implemented")
        exit()

    login_info = r.login(acc_info[0], acc_info[1])
    print("Successfully Logged in")
    return login_info
コード例 #26
0
def main():

    # Parse command line arguments
    parser = argparse.ArgumentParser(description='')
    parser.add_argument("-c",
                        action='store',
                        dest='config',
                        help="Path to the configuration for this bot.")
    args = parser.parse_args()

    # If a configuration file was not specified, warn the user and exit.
    if not args.config:
        parser.error('A configuration file needs to be specified.')

    # Parse the configuration file.
    logging.info('Parsing configuration located at %s' % args.config.strip())
    config = yaml.load(open(args.config.strip(), 'r'), Loader=yaml.FullLoader)

    logging.info('Login into RobinHood.')
    login = r.login(config['user'], config['pass'])

    coin = config['coin'].strip()
    logging.info('Trading %s ... wish me luck!' % coin)

    while True:
        hist = r.get_crypto_historicals(coin,
                                        interval='15second',
                                        span='hour',
                                        bounds='24_7')

        hist_dict = merge_dict(hist)
        hist_frame = pd.DataFrame.from_dict(hist_dict)
        logging.info('Current price of %s: %s' %
                     (coin, hist_frame['close_price'].iloc[-1]))

        time.sleep(15)
コード例 #27
0
# Cancel all pending sell orders before running to apply to every stock
import os, sys
currentdir = os.path.dirname(os.path.realpath(__file__))
parentdir = os.path.dirname(currentdir)
sys.path.append(parentdir)
import config
import holdings

import robin_stocks as r
import pyotp

from selenium import webdriver
import time

totp = pyotp.TOTP("My2factorAppHere").now()
login = r.login(config.USERNAME, config.PASSWORD, mfa_code=totp)

# my_stocks = holdings.stocks
my_stocks = r.build_holdings()

PATH = "/home/hopper/chromedriver"

# stocks = ['AMC', 'AMD', 'AMZN', 'BABA', 'BB', 'BSIG', 'CFII', 'CVX', 'DAL', 'EPD', 'ETSY', 'FB', 'GOOGL', 'KO', 'LAC', 'MSFT', 'NIO', 'NTDOY', 'NVDA', 'POWW', 'QQQ', 'RCL', 'RTX', 'SNDL', 'SPY', 'SQ', 'TEVA']
# Stopped at EPD

holdingsFile = open("holdings.py", "a")
holdingsFile.write(str(my_stocks))
holdingsFile.close()

soldFile = open("sold.py", "a")
コード例 #28
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')
コード例 #29
0
import robin_stocks as r
import pandas as pd
import numpy as np
import ta as ta
from pandas.plotting import register_matplotlib_converters
from ta import *
from misc import *
from tradingstats import *
from config import *

#Log in to Robinhood
#Put your username and password in a config.py file in the same directory (see sample file)
login = r.login(rh_username, rh_password)


#Safe divide by zero division function
def safe_division(n, d):
    return n / d if d else 0


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:
コード例 #30
0
 def __init__(self):
     user = os.environ.get("robinhood_username")
     passwd = os.environ.get("robinhood_password")
     log.debug(f"login {user}/{sensitive(passwd)}")
     rs.login(user, passwd, expiresIn=EXPIRATION)