Пример #1
0
def test_bad_logout():
    """logout without logging in"""
    if not LOGIN_OK:
        pytest.xfail('cannot test without valid user/passwd')
    rh_obj = Robinhood()
    with pytest.warns(UserWarning):
        req = rh_obj.logout()

    assert req.status_code != 200
Пример #2
0
def test_logout(config=CONFIG):
    """make sure logout works"""
    if not LOGIN_OK:
        pytest.xfail('cannot test without valid user/passwd')
    rh_obj = Robinhood()
    assert rh_obj.login(username=config.get('LOGIN', 'username'),
                        password=config.get('LOGIN', 'password'))
    assert rh_obj.auth_token is not None
    req = rh_obj.logout()

    assert req.status_code == 200
Пример #3
0
def test_intstruments(config=CONFIG):
    """test `instruments` endpoint"""
    #TODO: this test is bad, just repeat of code inside endpoint
    params = {'query': CONFIG.get('FETCH', 'test_ticker')}
    headers = {'User-Agent': CONFIG.get('FETCH', 'user_agent')}
    address = Robinhood().endpoints['instruments']
    res = requests.get(address, headers=headers, params=params)
    res.raise_for_status()
    hard_data = res.json()['results']

    data = Robinhood().instruments(CONFIG.get('FETCH', 'test_ticker'))

    assert data == hard_data
Пример #4
0
def test_intstruments(config=CONFIG):
    """test `instruments` endpoint"""
    # TODO: this test is bad, just repeat of code inside endpoint
    params = {"query": CONFIG.get("FETCH", "test_ticker")}
    headers = {"User-Agent": CONFIG.get("FETCH", "user_agent")}
    address = Robinhood().endpoints["instruments"]
    res = requests.get(address, headers=headers, params=params)
    res.raise_for_status()
    hard_data = res.json()["results"]

    data = Robinhood().instruments(CONFIG.get("FETCH", "test_ticker"))

    assert data == hard_data
Пример #5
0
class RobinhoodRepository:
    def __init__(self):
        self.robinhood_trader = Robinhood()
        self.robinhood_trader.login(username=credentials.get("robinhoodUsr"),
                                    password=credentials.get("robinhoodPwd"))

    def getStockQuote(self, ticker):
        quote = self.robinhood_trader.get_quote(ticker)
        return quote

    def getPortfolioValue(self):
        portfolioValue = self.robinhood_trader.portfolios()
        return portfolioValue

    def getPortfolio(self):
        print "fetching portfolio!"
        portfolio = self.robinhood_trader.securities_owned()["results"]
        returnPortfolio = []
        for position in portfolio:
            name = self.robinhood_trader.instrument_name_by_url(
                position["instrument"])
            position["name"] = name
            returnPortfolio.append(position)
        return returnPortfolio

    def buyStock(self, ticker):
        # Note: Sometimes more than one instrument may be returned for a given stock symbol
        stock_instrument = self.robinhood_trader.instruments(ticker)[0]
        buy_order = self.robinhood_trader.place_buy_order(stock_instrument, 1)
        print buy_order
Пример #6
0
def test_get_news(config=CONFIG):
    """test `get_news` endpoint"""
    test_ticker = CONFIG.get('FETCH', 'test_ticker')
    raw_news = helpers.fetch_REST_directly('news', test_ticker, config)
    get_news = Robinhood().get_news(test_ticker)

    assert get_news == raw_news
Пример #7
0
def test_get_news(config=CONFIG):
    """test `get_news` endpoint"""
    test_ticker = CONFIG.get("FETCH", "test_ticker")
    raw_news = helpers.fetch_REST_directly("news", test_ticker, config)
    get_news = Robinhood().get_news(test_ticker)

    assert get_news == raw_news
Пример #8
0
 def __init__(self, bot):
     self.bot = bot
     global ENDPOINTS
     with open(endpoints_path) as file:
         data = file.read()
     ENDPOINTS = json.loads(data)
     self.bot.add_cog(Webull(self.bot, self, ENDPOINTS, ENVIRONMENT))
     self.bot.add_cog(Robinhood(self.bot, self, ENDPOINTS, ENVIRONMENT))
Пример #9
0
def test_login_badpass(config=CONFIG):
    """try to login with bad creds"""
    if not LOGIN_OK:
        pytest.xfail('cannot test without valid user/passwd')
    bad_pass = '******'
    with pytest.raises(RH_exception.LoginFailed):
        Robinhood().login(username=config.get('LOGIN', 'username'),
                          password=bad_pass)
Пример #10
0
def test_get_historical_data(config=CONFIG):
    headers = {"User-Agent": CONFIG.get("FETCH", "user_agent")}

    address = Robinhood().endpoints["historicals"]
    res = requests.get(
        address,
        headers=headers,
        params={
            "symbols": ",".join([CONFIG.get("FETCH", "test_ticker")]).upper(),
            "interval": "day",
            "span": "year",
            "bounds": "regular",
        },
    )

    hard_data = res.json()["results"]

    data = Robinhood().get_historical_quotes(
        [CONFIG.get("FETCH", "test_ticker")], "day", "year")

    assert data == hard_data
Пример #11
0
def test_login_happypath(config=CONFIG):
    """try to log in to robinhood"""
    global LOGIN_OK

    if (not config.get('LOGIN', 'username')) or (not config.get(
            'LOGIN', 'password')):
        LOGIN_OK = False
        pytest.xfail('no login credentials given')

    try:
        LOGIN_OK = Robinhood().login(username=config.get('LOGIN', 'username'),
                                     password=config.get('LOGIN', 'password'))
    except Exception as err_msg:
        LOGIN_OK = False
        raise err_msg

    assert LOGIN_OK
Пример #12
0
class TestURLWrapper:
    """make sure get_url returns expected behavior"""
    base_url = 'https://api.robinhood.com/'
    rh_obj = Robinhood()

    def test_url_endpoint(self):
        """fetch url directly"""
        global TEST_URL_RESULT

        req = requests.get(self.base_url)
        req.raise_for_status()

        TEST_URL_RESULT = req.json()

    def test_get_url(self):
        """fetch url with get_url"""
        data = self.rh_obj.get_url(self.base_url)
        assert data == TEST_URL_RESULT
Пример #13
0
def fetch_REST_directly(endpoint_name, arg_string, config):
    """fetch REST endpoint (instead of ?arg1=val1&arg2=val2)

    Args:
        endpoint_name (str): endpoint name in RH class
        arg_string (str): additional args to pass onto endpoint
        config (:obj:`configparser.ConfigParser`, optional): config for args

    Returns:
        (:obj:`dict`) JSON-parsed data from robinhood endpoint

    """
    rh_object = Robinhood()
    address = rh_object.endpoints[endpoint_name]

    address = address + arg_string + '/'
    headers = {'User-Agent': config.get('FETCH', 'user_agent')}
    req = requests.get(address, headers=headers)
    req.raise_for_status()
    return req.json()
Пример #14
0
class TestFundamentalsHelpers:
    """wrapper to test fundamental architecture in order"""

    test_ticker = CONFIG.get("FETCH", "test_ticker")
    fake_ticker = CONFIG.get("FETCH", "fake_ticker")
    rh_obj = Robinhood()

    def test_fundamental_endpoint(self, config=CONFIG):
        """get raw data from Robinhood to test against"""
        global TEST_FUNDAMENTAL

        TEST_FUNDAMENTAL = helpers.fetch_REST_directly("fundamentals",
                                                       self.test_ticker,
                                                       config)
        TEST_FUNDAMENTAL["volume"] = "OVERWRITE"  # flaky value

    @flaky
    def test_validate_fundamental(self):
        """validate fetcher"""
        data = self.rh_obj.get_fundamentals(self.test_ticker)
        data["volume"] = "OVERWRITE"  # flaky value
        assert data == TEST_FUNDAMENTAL

    def test_validate_fail_fundamental(self):
        """validate bad-path exception"""
        with pytest.raises(NameError):
            data = self.rh_obj.get_fundamentals(self.fake_ticker)

    @flaky
    def test_validate_fundamental_wrapper(self):
        main_data = self.rh_obj.fundamentals(self.test_ticker)
        wrapped_data = self.rh_obj.fundamentals(self.test_ticker)

        main_data["volume"] = "OVERWRITE"  # flaky value
        wrapped_data["volume"] = "OVERWRITE"  # flaky value

        assert wrapped_data == main_data
        assert wrapped_data == TEST_FUNDAMENTAL
Пример #15
0
#Import class from the other file
from bot import telegram_chatbot
from datetime import datetime
from budgettracker import BudgetTracker
from robinhood import Robinhood

update_id = None

#Instantiate objects - telegram_chatbot and BudgetTracker
bot = telegram_chatbot('config.cfg')
tracker = BudgetTracker()
robinhood = Robinhood()


def make_reply(msg):
    try:
        if msg is not None:
            #Splits message into list of items
            output = msg.split(', ')

            #Get the command (1st item in the comma-separated list)
            command = output[0]

            #Get the arguments (if any) (subsequent items in the comma-separated list)
            if len(output) > 1:
                args = output[1:]
            else:
                args = None

            #Returns help text
            if command == 'Help':
Пример #16
0
from robinhood import Robinhood
import yaml

stream = open("../credentials/credentials.yml", "r")
credentials = yaml.load(stream)

# Setup
my_trader = Robinhood();
# login
my_trader.login(username=credentials.get("robinhoodUsr"), password=credentials.get("robinhoodPwd"))

# Get stock information
# Note: Sometimes more than one instrument may be returned for a given stock symbol
stock_instrument = my_trader.instruments("AMD")[0]
# print(stock_instrument)

# Get a stock's quote
my_trader.print_quote("AMD")

# Prompt for a symbol
# my_trader.print_quote();

# Print multiple symbols
my_trader.print_quotes(stocks=["BBRY", "FB", "MSFT"])

# View all data for a given stock ie. Ask price and size, bid price and size, previous close, adjusted previous close, etc.
# quote_info = my_trader.quote_data("GEVO")
# print(quote_info);

# Place a buy order (uses market bid price)
# buy_order = my_trader.place_buy_order(stock_instrument, 1)
    totalVolatility = spyVolatility + tltVolatility

    spyRawAllocation = 1 - (spyVolatility / totalVolatility)
    spyAllocation = 1 / (1 + math.exp(-20 * (spyRawAllocation - .5)))
    if spyAllocation > 1:
        spyAllocation = 1
    if spyAllocation < 0:
        spyAllocation = 0

    return spyAllocation


success = True

rh = Robinhood()
success = rh.marketOpenCheck()
if not success:
    print('markets are closed')
else:
    print('markets are open')

if success:
    success = rh.login(username=config.rhuser, password=config.rhpass)

if success:
    print('login succesful')
else:
    print('login unsuccesful')

if success:
Пример #18
0
import csv
from robinhood import Robinhood
from orderreader import OrderReader

rb = Robinhood()
rb.login(username="******", password="******")
order_reader = OrderReader()
order_reader.init_robinhood_from_client(rb)

orders = order_reader.get_orders()

keys = ['side', 'symbol', 'shares', 'price', 'date', 'state']
with open('orders.csv', 'w') as output_file:
    dict_writer = csv.DictWriter(output_file, keys)
    dict_writer.writeheader()
    dict_writer.writerows(orders)
Пример #19
0
from robinhood import Robinhood
from orderledger import OrderLedger
from orderreader import OrderReader

def print_pnl(pnls):
  '''
  '''
  print('-----------------------------------')
  print(pnls)


rb = Robinhood()
rb.login(username="******", password="******")
order_reader = OrderReader()
order_reader.init_firstrade('firstrade.csv')
#order_reader.init_robinhood_from_client(rb)
#order_reader.init_robinhood_from_csv('orders.csv')
ol = OrderLedger(order_reader.get_orders())

print("last year")
ol.get_last_year_pnl()

print("current year")
ol.get_current_year_pnl()

print("unrealized")
ol.get_unrealized_pnl(rb)

print("positions")
ol.show_positions()
Пример #20
0
def main():
  from robinhood import Robinhood
  # Setup
  my_trader = Robinhood();
  # Login
  #my_trader.login(username="******", password="******")
  my_trader.login()

  # Get stock information
  # Note: Sometimes more than one instrument may be returned for a
  #       given stock symbol
  stock_instrument = my_trader.instruments("GEVO")[0]

  # Get a stock's quote
  my_trader.print_quote("AAPL")

  # Prompt for a symbol
  my_trader.print_quote()

  # Print multiple symbols
  my_trader.print_quotes(stocks=["BBRY", "FB", "MSFT"])

  # View all data for a given stock ie. Ask price and size, bid price and size,
  # previous close, adjusted previous close, etc.
  quote_info = my_trader.quote_data("GEVO")
  print(quote_info)

  # View my account
  print(my_trader.portfolios())
Пример #21
0
def run_gather_data():
    #code that gets and logs performance data
    print("Gathering Data")
    success = True

    rh = Robinhood()
    now = datetime.datetime.utcnow()
    try:
        success = rh.marketOpenCheck()
        if not success:
            print('markets are closed')
        else:
            print('markets are open')
    except Exception as e:
        success = False
        print('rh market check error ', str(e))
        send_email(mailgun_domain, mailgun_api_key, diag_email_dest,
                   ('resiliant-trader data gather error ' +
                    str(datetime.datetime.now())),
                   ("rh market check error. Unexpected error: " + str(e)))

    if success:
        try:
            success = rh.login(username=rhuser, password=rhpass)
            if success:
                print('robinhood login succesful')
            else:
                print('robinhood login unsuccesful')
        except Exception as e:
            success = False
            print('rh login error ', str(e))
            send_email(mailgun_domain, mailgun_api_key, diag_email_dest,
                       ('resiliant-trader data gather error ' +
                        str(datetime.datetime.now())),
                       ("rh login error. Unexpected error: " + str(e)))

    if success:
        try:
            client = MongoClient(mongodb_uri)
            db = client.get_database()
        except Exception as e:
            print('mongo login error ', str(e))
            success = False
            send_email(mailgun_domain, mailgun_api_key, diag_email_dest,
                       ('resiliant-trader data gather error ' +
                        str(datetime.datetime.now())),
                       ("mongo login error. Unexpected error: " + str(e)))

    if success:
        try:
            #get pricing data
            spyAskPrice = rh.ask_price('SPY')
            spyBidPrice = rh.bid_price('SPY')
            spyAvgCost = (spyAskPrice + spyBidPrice) / 2
            print('spyAvgCost = ', spyAvgCost)

            tltAskPrice = rh.ask_price('TLT')
            tltBidPrice = rh.bid_price('TLT')
            tltAvgCost = (tltAskPrice + tltBidPrice) / 2
            print('tltAvgCost = ', tltAvgCost)
        except Exception as e:
            print('etf price error ', str(e))
            success = False
            send_email(mailgun_domain, mailgun_api_key, diag_email_dest,
                       ('resiliant-trader data gather error ' +
                        str(datetime.datetime.now())),
                       ("etf price error. Unexpected error: " + str(e)))

    if success:
        try:
            #get portfolioValue
            portfolioValue = rh.equity()
            tltPosition = 0
            spyPosition = 0
            print('portfolioValue =', portfolioValue)
            openPositions = rh.securities_owned()['results']
            for position in openPositions:
                instrumentURL = position['instrument']
                positionTicker = rh.get_url(instrumentURL)['symbol']
                positionQuantity = float(position['quantity'])
                if (positionTicker == 'SPY'):
                    spyPosition = positionQuantity
                if (positionTicker == 'TLT'):
                    tltPosition = positionQuantity
            print('spyPosition = ', spyPosition)
            print('tltPosition = ', tltPosition)
        except Exception as e:
            print('portfolio value error ', str(e))
            success = False
            send_email(mailgun_domain, mailgun_api_key, diag_email_dest,
                       ('resiliant-trader data gather error ' +
                        str(datetime.datetime.now())),
                       ("portfolio value error. Unexpected error: " + str(e)))

    if success:
        try:
            #get treasury risk free rate
            quandl.ApiConfig.api_key = quandl_key
            riskFree = (quandl.get("USTREASURY/BILLRATES.3",
                                   rows=1,
                                   returns='numpy')[0])[1]
            print('riskFree =', riskFree)
        except Exception as e:
            print('risk free error ', str(e))
            success = False
            send_email(mailgun_domain, mailgun_api_key, diag_email_dest,
                       ('resiliant-trader data gather error ' +
                        str(datetime.datetime.now())),
                       ("risk free error. Unexpected error: " + str(e)))

    if success:
        try:
            #get last data
            lastData = db.rawPrices.find_one(sort=[("timestamp", -1)])
            lastTimestamp = lastData['timestamp']
            lastSpy = lastData['spy']
            lastTlt = lastData['tlt']
            lastPortfolio = lastData['portfolio']
            lastRiskFree = lastData['annualized90day']
        except Exception as e:
            print('error getting previous data ', str(e))
            success = False
            send_email(
                mailgun_domain, mailgun_api_key, diag_email_dest,
                ('resiliant-trader data gather error ' +
                 str(datetime.datetime.now())),
                ("error getting previous data. Unexpected error: " + str(e)))

    if success:
        try:
            # save data
            rawData = {
                "timestamp": now,
                "spy": spyAvgCost,
                "tlt": tltAvgCost,
                "portfolio": portfolioValue,
                "annualized90day": riskFree
            }
            data_id = db.rawPrices.insert_one(rawData).inserted_id
            print("data saved to", data_id)
        except Exception as e:
            print('data save error ', str(e))
            success = False
            send_email(
                mailgun_domain, mailgun_api_key, diag_email_dest,
                ('resiliant-trader data gather error ' +
                 str(datetime.datetime.now())),
                ("error calculating change. Unexpected error: " + str(e)))

    if success:
        try:
            # calculate percentage changes
            spyChange = (spyAvgCost - lastSpy) / lastSpy
            print('spyChange = ', spyChange)
            tltChange = (tltAvgCost - lastTlt) / lastTlt
            print('tltChange = ', tltChange)
            portfolioChange = (portfolioValue - lastPortfolio) / lastPortfolio
            print('portfolioChange = ', portfolioChange)
            elapsedTime = now - lastTimestamp
            year = datetime.timedelta(days=365)
            treasuryChange = ((1 + (((lastRiskFree + riskFree) / 2)) / 100)
                              **(divtd(elapsedTime, year))) - 1
            print('treasuryChange = ', treasuryChange)
        except Exception as e:
            print('error calculating change ', str(e))
            success = False
            send_email(
                mailgun_domain, mailgun_api_key, diag_email_dest,
                ('resiliant-trader data gather error ' +
                 str(datetime.datetime.now())),
                ("error calculating change. Unexpected error: " + str(e)))

    if success:
        try:
            # save data
            percentageData = {
                "timestamp": now,
                "spy": spyChange,
                "tlt": tltChange,
                "portfolio": portfolioChange,
                "90dayTreasury": treasuryChange
            }
            data_id = db.percentageMove.insert_one(percentageData).inserted_id
            print("data saved to", data_id)
        except Exception as e:
            print('data save error ', str(e))
            success = False
            send_email(mailgun_domain, mailgun_api_key, diag_email_dest,
                       ('resiliant-trader data gather error ' +
                        str(datetime.datetime.now())),
                       ("data save error. Unexpected error: " + str(e)))

    if success:
        try:
            # calculate tracking
            spyTarget = calcAlloc(rh)
            print('spyTarget = ', spyTarget)
            tltTarget = 1 - spyTarget
            print('tltTarget = ', tltTarget)

            spyActual = (spyPosition * spyAvgCost) / portfolioValue
            tltActual = (tltPosition * tltAvgCost) / portfolioValue
            print('spyActual = ', spyActual)
            print('tltActual = ', tltActual)
        except Exception as e:
            print('error calculating tracking ', str(e))
            success = False
            send_email(
                mailgun_domain, mailgun_api_key, diag_email_dest,
                ('resiliant-trader data gather error ' +
                 str(datetime.datetime.now())),
                ("error calculating tracking. Unexpected error: " + str(e)))

    if success:
        try:
            # save tracking data
            trackingData = {
                "timestamp": now,
                "spyActual": spyActual,
                "tltActual": tltActual,
                "spyTarget": spyTarget,
                "tltTarget": tltTarget
            }
            data_id = db.tracking.insert_one(trackingData).inserted_id
            print("data saved to", data_id)
        except Exception as e:
            print('tracking data save error ', str(e))
            success = False
            send_email(
                mailgun_domain, mailgun_api_key, diag_email_dest,
                ('resiliant-trader data gather error ' +
                 str(datetime.datetime.now())),
                ("tracking data save error. Unexpected error: " + str(e)))
Пример #22
0
 def __init__(self):
     self.robinhood_trader = Robinhood()
     self.robinhood_trader.login(username=credentials.get("robinhoodUsr"),
                                 password=credentials.get("robinhoodPwd"))
Пример #23
0
class TestPortfolioMethods:
    """test wrappers on `portfolio` endpoint

    NOTE: reliant on an active account to pull data from

    """
    rh_obj = Robinhood()
    try:
        rh_obj.login(
            username=CONFIG.get('LOGIN',
                                'username'),  #NOTE: py.test fails w/o password
            password=CONFIG.get('LOGIN', 'password'))
    except Exception:
        pass

    def test_portfolios(self):
        """check `portfolio` method"""
        global TEST_PORTFOLIO
        if not LOGIN_OK:
            print('Unable to test Portfolio without auth')
            pytest.xfail('cannot test without valid user/passwd')
        print(self.rh_obj.auth_token)
        data = self.rh_obj.portfolios()
        #TODO validate data

        TEST_PORTFOLIO = data

    def test_validate_adjusted_equity(self):
        """test `adjusted_equity_previous_close` method"""
        value = self.rh_obj.adjusted_equity_previous_close()
        assert isinstance(value, float)
        assert format(
            value, '.4f') == TEST_PORTFOLIO['adjusted_equity_previous_close']

    def test_validate_equity(self):
        """test `equity` method"""
        value = self.rh_obj.equity()
        assert isinstance(value, float)
        assert format(value, '.4f') == TEST_PORTFOLIO['equity']

    def test_equity_previous_close(self):
        """test `equity_previous_close` method"""
        value = self.rh_obj.equity_previous_close()
        assert isinstance(value, float)
        assert format(value, '.4f') == TEST_PORTFOLIO['equity_previous_close']

    def test_excess_margin(self):
        """test `excess_margin` method"""
        value = self.rh_obj.excess_margin()
        assert isinstance(value, float)
        assert format(value, '.4f') == TEST_PORTFOLIO['excess_margin']

    def test_ex_hours_equity(self):
        """test `extended_hours_equity method"""
        value = self.rh_obj.extended_hours_equity()
        assert isinstance(value, float) or (value is None)
        if value:
            assert format(value,
                          '.4f') == TEST_PORTFOLIO['extended_hours_equity']

    def test_ex_hours_market_value(self):
        """test `extended_hours_market_value` method"""
        value = self.rh_obj.extended_hours_market_value()
        assert isinstance(value, float) or (value is None)
        if value:
            assert format(
                value, '.4f') == TEST_PORTFOLIO['extended_hours_market_value']

    def test_last_core_equity(self):
        """test `last_core_equity` method"""
        value = self.rh_obj.last_core_equity()
        assert isinstance(value, float)
        assert format(value, '.4f') == TEST_PORTFOLIO['last_core_equity']

    def test_last_core_market_value(self):
        """test `last_core_market_value` method"""
        value = self.rh_obj.last_core_market_value()
        assert isinstance(value, float)
        assert format(value, '.4f') == TEST_PORTFOLIO['last_core_market_value']

    def test_market_value(self):
        """test `market_value` method"""
        value = self.rh_obj.market_value()
        assert isinstance(value, float)
        assert format(value, '.4f') == TEST_PORTFOLIO['market_value']

    def test_investment_profile(self):
        """test `investment_profile` endpoint"""
        data = self.rh_obj.investment_profile()
        #TODO: validate keys

    def test_get_account(self):
        """test `get_account` endpoing"""
        data = self.rh_obj.get_account()
Пример #24
0
def main():
    from robinhood import Robinhood
    # Setup
    my_trader = Robinhood()
    # Login
    #my_trader.login(username="******", password="******")
    my_trader.login()

    # Get stock information
    # Note: Sometimes more than one instrument may be returned for a
    #       given stock symbol
    stock_instrument = my_trader.instruments("GEVO")[0]

    # Get a stock's quote
    my_trader.print_quote("AAPL")

    # Prompt for a symbol
    my_trader.print_quote()

    # Print multiple symbols
    my_trader.print_quotes(stocks=["BBRY", "FB", "MSFT"])

    # View all data for a given stock ie. Ask price and size, bid price and size,
    # previous close, adjusted previous close, etc.
    quote_info = my_trader.quote_data("GEVO")
    print(quote_info)

    # View my account
    print(my_trader.portfolios())
Пример #25
0
        "symbol": symbol,
        "date": order["last_transaction_at"],
        "state": order["state"],
    }


def get_all_history_orders(rb_client):
    orders = []
    past_orders = rb_client.order_history()
    orders.extend(past_orders["results"])
    while past_orders["next"]:
        print("{} order fetched".format(len(orders)))
        next_url = past_orders["next"]
        past_orders = fetch_json_by_url(rb_client, next_url)
        orders.extend(past_orders["results"])
    print("{} order fetched".format(len(orders)))
    return orders


rb = Robinhood()
# !!!!!! change the username and passs, be careful when paste the code to public
rb.login(username="******", password="******")
past_orders = get_all_history_orders(rb)
instruments_db = shelve.open("instruments.db")
orders = [order_item_info(order, rb, instruments_db) for order in past_orders]
keys = ["side", "symbol", "shares", "price", "date", "state"]
with open("orders.csv", "w") as output_file:
    dict_writer = csv.DictWriter(output_file, keys)
    dict_writer.writeheader()
    dict_writer.writerows(orders)
Пример #26
0
class TestQuoteHelpers:
    """wrapper to test quote architecture in order"""
    test_ticker = CONFIG.get('FETCH', 'test_ticker')
    fake_ticker = CONFIG.get('FETCH', 'fake_ticker')
    rh_obj = Robinhood()

    def test_quote_endpoint(self, config=CONFIG):
        """get raw data from robinhood to test against"""
        global TEST_QUOTE

        TEST_QUOTE = helpers.fetch_REST_directly('quotes', self.test_ticker,
                                                 config)

    def test_validate_quote(self):
        """validate fetcher"""
        data = self.rh_obj.quote_data(self.test_ticker)
        if data['updated_at'] == TEST_QUOTE['updated_at']:
            assert data == TEST_QUOTE
        else:
            for key in data.keys():  #SKIP PRICE DATA
                if key in TESTABLE_KEYS:
                    assert data[key] == TEST_QUOTE[key]

    def test_validate_fail_quote(self):
        """validate bad-path exception"""
        with pytest.raises(NameError):
            data = self.rh_obj.quote_data(self.fake_ticker)

    def test_validate_get_quote(self):
        """validate `get_quote` call"""
        data = self.rh_obj.get_quote(self.test_ticker)
        assert data == TEST_QUOTE['symbol']

    @flaky
    def test_validate_ask_price(self):
        """validate `ask_price` call"""
        data = self.rh_obj.ask_price(self.test_ticker)
        quote = self.rh_obj.quote_data(self.test_ticker)

        assert data == quote['ask_price']

    @flaky
    def test_validate_ask_size(self):
        """validate `ask_size` call"""
        data = self.rh_obj.ask_size(self.test_ticker)
        quote = self.rh_obj.quote_data(self.test_ticker)

        assert data == quote['ask_size']

    @flaky
    def test_validate_bid_price(self):
        """validate `bid_price` call"""
        data = self.rh_obj.bid_price(self.test_ticker)
        quote = self.rh_obj.quote_data(self.test_ticker)

        assert data == quote['bid_price']

    @flaky
    def test_validate_bid_size(self):
        """validate `bid_size` call"""
        data = self.rh_obj.bid_size(self.test_ticker)
        quote = self.rh_obj.quote_data(self.test_ticker)

        assert data == quote['bid_size']

    @flaky
    def test_validate_last_trade_price(self):
        """validate `last_trade_price` call"""
        data = self.rh_obj.last_trade_price(self.test_ticker)
        quote = self.rh_obj.quote_data(self.test_ticker)

        assert data == quote['last_trade_price']

    def test_validate_previous_close(self):
        """validate `previous_close` call"""
        data = self.rh_obj.previous_close(self.test_ticker)

        assert data == TEST_QUOTE['previous_close']

    def test_validate_previous_close_date(self):
        """validate `previous_close_date` call"""
        data = self.rh_obj.previous_close_date(self.test_ticker)

        assert data == TEST_QUOTE['previous_close_date']

    def test_validate_adjusted_previous_close(self):
        """validate `adjusted_previous_close` call"""
        data = self.rh_obj.adjusted_previous_close(self.test_ticker)

        assert data == TEST_QUOTE['adjusted_previous_close']

    def test_validate_symbol(self):
        """validate `symbol` call"""
        data = self.rh_obj.symbol(self.test_ticker)

        assert data == TEST_QUOTE['symbol']

    @flaky
    def test_validate_last_updated_at(self):
        """validate `last_updated_at` call"""
        data = self.rh_obj.last_updated_at(self.test_ticker)
        quote = self.rh_obj.quote_data(self.test_ticker)

        assert data == quote['updated_at']
Пример #27
0
def run_trader():
    try:
        print("running trader at: " + str(datetime.datetime.now()))
        message = "running trader at: " + str(datetime.datetime.now())
        success = True

        rh = Robinhood()
        success = rh.marketOpenCheck()
        if not success:
            print('markets are closed')
            message += '\nmarkets are closed'
        else:
            print('markets are open')
            message += '\nmarkets are open'

        if success:
            success = rh.login(username=rhuser, password=rhpass)

        if success:
            print('login succesful')
            message += '\nlogin succesful'
        else:
            print('login unsuccesful')
            message += '\nlogin unsuccesful'

        if success:
            #exit extra postions
            openPositions = rh.securities_owned()['results']

            sellOrders = {}
            for position in openPositions:
                instrumentURL = position['instrument']
                positionTicker = rh.get_url(instrumentURL)['symbol']
                positionQuantity = position['quantity']
                if (positionTicker != 'SPY') and (positionTicker != 'TLT'):
                    print('position in ', positionTicker,
                          ' is not needed, selling')
                    stock_instrument = rh.instruments(positionTicker)[0]
                    sellOrders[
                        positionTicker] = rh.place_immediate_market_order(
                            instrumentURL, positionTicker, 'gfd',
                            positionQuantity, 'sell')
            if sellOrders == {}:
                print('no extra positions found to close')
                message += '\nno extra positions found to close'
            else:
                print(sellOrders)

            orderOutcome = 'unresolved'

            while orderOutcome != 'resolved':
                remainingUnresolved = False
                for order in sellOrders:
                    orderDetail = sellOrders[order]
                    orderDetail['status'] = rh.check_order_status(
                        orderDetail['url'])
                    if orderDetail['status'] == 'unresolved':
                        remainingUnresolved = True
                if not remainingUnresolved:
                    orderOutcome = 'resolved'
                else:
                    print('remaining unresolved orders, waiting')
                    message += '\nremaining unresolved orders, waiting'
                    time.sleep(60)

            for order in sellOrders:
                orderDetail = sellOrders[order]
                if orderDetail['status'] == 'failure':
                    success = False

        if not success:
            print('unable to sell extra positions correctly')
            message += '\nunable to sell extra positions correctly'

        if success:
            #get portfolio current value
            portfolioValue = rh.equity()
            print('portfolioValue =', portfolioValue)
            message += '\nportfolioValue = '
            message += str(portfolioValue)

            #allocate portfolio
            spyAllocationPercentage = calcAlloc(rh)
            tltAllocationPercentage = 1 - spyAllocationPercentage
            print('spyAllocationPercentage = ', spyAllocationPercentage)
            message += '\nspyAllocationPercentage = '
            message += str(spyAllocationPercentage)
            print('tltAllocationPercentage = ', tltAllocationPercentage)
            message += '\ntltAllocationPercentage = '
            message += str(tltAllocationPercentage)

            spyTargetAllocation = spyAllocationPercentage * portfolioValue
            tltTargetAllocation = tltAllocationPercentage * portfolioValue
            print('spyTargetAllocation = ', spyTargetAllocation)
            message += '\nspyTargetAllocation = '
            message += str(spyTargetAllocation)
            print('tltTargetAllocation = ', tltTargetAllocation)
            message += '\ntltTargetAllocation = '
            message += str(tltTargetAllocation)

            #get pricing data
            spyAskPrice = rh.ask_price('SPY')
            spyBidPrice = rh.bid_price('SPY')
            spyAvgCost = (spyAskPrice + spyBidPrice) / 2
            spyBuyPrice = spyAskPrice + (spyAskPrice - spyBidPrice)
            spySellPrice = spyBidPrice - (spyAskPrice - spyBidPrice)
            print('spyAskPrice = ', spyAskPrice)
            message += '\nspyAskPrice = '
            message += str(spyAskPrice)
            print('spyBidPrice = ', spyBidPrice)
            message += '\nspyBidPrice = '
            message += str(spyBidPrice)

            tltAskPrice = rh.ask_price('TLT')
            tltBidPrice = rh.bid_price('TLT')
            tltAvgCost = (tltAskPrice + tltBidPrice) / 2
            tltBuyPrice = tltAskPrice + (tltAskPrice - tltBidPrice)
            tltSellPrice = tltBidPrice - (tltAskPrice - tltBidPrice)
            print('tltAskPrice = ', tltAskPrice)
            message += '\ntltAskPrice = '
            message += str(tltAskPrice)
            print('tltBidPrice = ', tltBidPrice)
            message += '\ntltBidPrice = '
            message += str(tltBidPrice)

            #recommend position sizes
            #[spyTargetShares,tltTargetShares] = recommendTarget(portfolioValue,spyAllocationPercentage,tltAllocationPercentage,spyBuyPrice,tltBuyPrice)
            [spyTargetShares, tltTargetShares] = recommendInitialTarget(
                portfolioValue, spyAllocationPercentage,
                tltAllocationPercentage, spyBuyPrice, tltBuyPrice)

            print('spyTargetShares = ', spyTargetShares)
            message += '\nspyTargetShares = '
            message += str(spyTargetShares)
            print('tltTargetShares = ', tltTargetShares)
            message += '\ntltTargetShares = '
            message += str(tltTargetShares)

            targetPurchaseCost = targetTotalCost(spyTargetShares,
                                                 tltTargetShares, spyBuyPrice,
                                                 tltBuyPrice)

            spyTargetAllocationPercentage = allocationPercentage(
                spyTargetShares, spyBuyPrice, targetPurchaseCost)
            tltTargetAllocationPercentage = allocationPercentage(
                tltTargetShares, tltBuyPrice, targetPurchaseCost)
            print('spyTargetAllocationPercentage = ',
                  spyTargetAllocationPercentage)
            message += '\nspyTargetAllocationPercentage = '
            message += str(spyTargetAllocationPercentage)
            print('tltTargetAllocationPercentage = ',
                  tltTargetAllocationPercentage)
            message += '\ntltTargetAllocationPercentage = '
            message += str(tltTargetAllocationPercentage)

            targetLoss = allocationLoss(spyTargetAllocationPercentage,
                                        spyAllocationPercentage,
                                        tltTargetAllocationPercentage,
                                        tltAllocationPercentage)
            print('target loss = ', targetLoss)

            targetRemainingCash = portfolioValue - targetPurchaseCost
            print('targetPurchaseCost = ', targetPurchaseCost)
            message += '\ntargetPurchaseCost = '
            message += str(targetPurchaseCost)
            print('targetRemainingCash = ', targetRemainingCash)
            message += '\ntargetRemainingCash = '
            message += str(targetRemainingCash)

            #detemine required rebalancing
            spyRequired = spyTargetShares
            tltRequired = tltTargetShares
            for position in openPositions:
                instrumentURL = position['instrument']
                positionTicker = rh.get_url(instrumentURL)['symbol']
                positionQuantity = float(position['quantity'])
                if (positionTicker == 'SPY'):
                    spyRequired = spyTargetShares - positionQuantity
                if (positionTicker == 'TLT'):
                    tltRequired = tltTargetShares - positionQuantity

            print('spyRequired = ', spyRequired)
            message += '\nspyRequired = '
            message += str(spyRequired)
            print('tltRequired = ', tltRequired)
            message += '\ntltRequired = '
            message += str(tltRequired)

            spyInstrumentUrl = (rh.instruments('SPY')[0])['url']
            tltInstrumentUrl = (rh.instruments('TLT')[0])['url']

        if success:
            #sell positions
            if spyRequired < 0.0:
                print('selling ', -spyRequired, ' of SPY')
                spySellOrder = rh.place_immediate_market_order(
                    spyInstrumentUrl, 'SPY', 'gfd', -spyRequired, 'sell')
                print(spySellOrder)

                orderOutcome = 'unresolved'

                while orderOutcome != 'resolved':
                    remainingUnresolved = False
                    orderResponse = rh.check_order_status(spySellOrder['url'])
                    if orderResponse == 'unresolved':
                        remainingUnresolved = True
                    if not remainingUnresolved:
                        orderOutcome = 'resolved'
                    else:
                        print('remaining unresolved spySell, waiting')
                        message += '\nremaining unresolved spySell, waiting'
                        time.sleep(60)

                if orderResponse == 'failure':
                    success = False

        if not success:
            print('unable to sell required spy')
            message += '\nunable to sell required spy'

        if success:
            if tltRequired < 0.0:
                print('selling ', -tltRequired, ' of TLT')
                tltSellOrder = rh.place_immediate_market_order(
                    tltInstrumentUrl, 'TLT', 'gfd', -tltRequired, 'sell')
                print(tltSellOrder)

                orderOutcome = 'unresolved'

                while orderOutcome != 'resolved':
                    remainingUnresolved = False
                    orderResponse = rh.check_order_status(tltSellOrder['url'])
                    if orderResponse == 'unresolved':
                        remainingUnresolved = True
                    if not remainingUnresolved:
                        orderOutcome = 'resolved'
                    else:
                        print('remaining unresolved tltSell, waiting')
                        message += '\nremaining unresolved tltSell, waiting'
                        time.sleep(60)

                if orderResponse == 'failure':
                    success = False

        if not success:
            print('unable to sell required tlt')
            message += '\nunable to sell required tlt'

        #buy positions
        if success:
            if spyRequired > 0.0:
                print('buying ', spyRequired, ' of SPY')
                spyBuyOrder = rh.place_immediate_market_order(
                    spyInstrumentUrl, 'SPY', 'gfd', spyRequired, 'buy',
                    round(spyBuyPrice, 3))
                print(spyBuyOrder)

                orderOutcome = 'unresolved'

                while orderOutcome != 'resolved':
                    remainingUnresolved = False
                    orderResponse = rh.check_order_status(spyBuyOrder['url'])
                    if orderResponse == 'unresolved':
                        remainingUnresolved = True
                    if not remainingUnresolved:
                        orderOutcome = 'resolved'
                    else:
                        print('remaining unresolved spyBuy, waiting')
                        message += '\nremaining unresolved spyBuy, waiting'
                        time.sleep(60)

                if orderResponse == 'failure':
                    success = False
        if not success:
            print('unable to buy required spy')
            message += '\nunable to buy required spy'

        if success:
            if tltRequired > 0.0:
                print('buying ', tltRequired, ' of TLT')
                tltBuyOrder = rh.place_immediate_market_order(
                    tltInstrumentUrl, 'TLT', 'gfd', tltRequired, 'buy',
                    round(tltBuyPrice, 3))
                print(tltBuyOrder)

                orderOutcome = 'unresolved'

                while orderOutcome != 'resolved':
                    remainingUnresolved = False
                    orderResponse = rh.check_order_status(tltBuyOrder['url'])
                    if orderResponse == 'unresolved':
                        remainingUnresolved = True
                    if not remainingUnresolved:
                        orderOutcome = 'resolved'
                    else:
                        print('remaining unresolved tltBuy, waiting')
                        message += '\nremaining unresolved tltBuy, waiting'
                        time.sleep(60)

                if orderResponse == 'failure':
                    success = False

        if not success:
            print('unable to buy required tlt')
            message += '\nunable to buy required tlt'

        if success:
            success = rh.logout()
        if not success:
            print('unable to logout')
            message += '\nunable to logout'
        else:
            print('succesfully logged out')
            message += '\nsuccesfully logged out'
        send_email(mailgun_domain, mailgun_api_key, diag_email_dest,
                   ('resiliant-trader log ' + str(datetime.datetime.now())),
                   message)
    except Exception as e:
        print("Unexpected error:", str(e))
        send_email(mailgun_domain, mailgun_api_key, diag_email_dest,
                   ('resiliant-trader log ' + str(datetime.datetime.now())),
                   ("Unexpected error: " + str(e)))
        raise