コード例 #1
0
def logoff():
    """Robinhood logoff"""
    robinhood.logout()
コード例 #2
0
 def test_login_failed(self):
     r.logout()
     profile = r.load_account_profile(info=None)
     assert profile
コード例 #3
0
ファイル: traderbot.py プロジェクト: michaeljecmen/traderbot
def run_traderbot():
    """Main function for this module.
    
    Spawns a thread for each ticker that trades on that symbol
    for the duration of the day."""
    # get info from config file and log in
    global USERNAME, PASSWORD, PAPER_TRADING, TIME_ZONE
    global START_OF_DAY, END_OF_DAY, TRADE_LIMIT, CONFIG
    CONFIG = get_json_dict()
    USERNAME = CONFIG["username"]
    PASSWORD = CONFIG["password"]
    MAX_LOSS_PERCENT = CONFIG["max-loss-percent"]/100.0
    TAKE_PROFIT_PERCENT = CONFIG["take-profit-percent"]/100.0
    SPEND_PERCENT = CONFIG["spend-percent"]/100.0
    PAPER_TRADING = CONFIG["paper-trading"]
    TIME_ZONE = CONFIG.get("time-zone-pandas-market-calendars", "America/New_York")
    full_start_time_str = CONFIG.get("start-of-day", "09:30") + "={}".format(TIME_ZONE)
    full_end_time_str = CONFIG.get("end-of-day", "16:00") + "={}".format(TIME_ZONE)
    START_OF_DAY = datetime.strptime(full_start_time_str, "%H:%M=%Z").time()
    END_OF_DAY = datetime.strptime(full_end_time_str, "%H:%M=%Z").time()
    TRADE_LIMIT = CONFIG.get("max-trades-per-day", None)
    BUDGET = CONFIG.get("budget", None)
    END_TIME_STR = CONFIG.get("end-time", None)
    START_TIME_STR = CONFIG.get("start-time", None)
    ALPACA_KEY = CONFIG["alpaca-api-key"]
    ALPACA_SECRET_KEY = CONFIG["alpaca-secret-key"]
    STRATEGIES_DICT = CONFIG["strategies"]
    HISTORY_SIZE = CONFIG.get("history-len", 16)
    if not ((HISTORY_SIZE & (HISTORY_SIZE-1) == 0) and HISTORY_SIZE != 0): 
        raise ConfigException("history-len must be a power of two, {} was entered".format(HISTORY_SIZE))
    TREND_SIZE = CONFIG.get("trend-len", 3)
    if TREND_SIZE > HISTORY_SIZE:
        raise ConfigException("trend-len must be less than or equal to history-len")
    IS_INSTANT_ACCT = CONFIG.get("instant", False)

    zero_time = timedelta()

    login = log_in_to_robinhood()

    # get list of unique tickers and enforce legality of strategies kv in the config
    ALL_TICKERS = []
    for st in STRATEGIES_DICT:
        enforce_keys_in_dict(['strategy', 'tickers'], st)
        enforce_strategy_dict_legal(st['strategy'])
        ALL_TICKERS.extend(st['tickers'])
    ALL_TICKERS = list(set(ALL_TICKERS))

    # generate parameters so we don't get flagged
    START_OF_DAY, END_OF_DAY, TRADE_LIMIT = generate_humanlike_parameters()
    datetime_fmt_str = '%H:%M:%S'
    if END_TIME_STR is not None:
        END_OF_DAY = datetime.strptime(END_TIME_STR, datetime_fmt_str).time()
    if START_TIME_STR is not None:
        START_OF_DAY = datetime.strptime(START_TIME_STR, datetime_fmt_str).time()

    print_with_lock("param: will start trading today at:", START_OF_DAY)
    print_with_lock("param: will stop trading today at:", END_OF_DAY)
    print_with_lock("param: will make a maximum of {} trades today".format(TRADE_LIMIT))

    # busy-spin until market open
    block_until_market_open()

    # these variables are shared by each trading thread. they are written by this
    # main traderbot thread, and read by each trading thread individually
    market_data = MarketData(ALL_TICKERS, ALPACA_KEY, ALPACA_SECRET_KEY, HISTORY_SIZE, TREND_SIZE)
    buying_power = BuyingPower(SPEND_PERCENT, IS_INSTANT_ACCT, BUDGET)
    trade_capper = TradeCapper(TRADE_LIMIT)

    # now that market open is today, update EOD for time checking
    now = datetime.now()
    END_OF_DAY = datetime(now.year, now.month, now.day, END_OF_DAY.hour, END_OF_DAY.minute, END_OF_DAY.second, END_OF_DAY.microsecond)
    market_time = MarketTime(END_OF_DAY)
    reports = Reports()

    # spawn thread for each ticker
    threads = []
    for st in STRATEGIES_DICT:
        strategy_dict = st['strategy']
        tickers = st['tickers']
        for ticker in tickers:
            print_with_lock("initializing thread {} with strategy configuration {}".format(ticker, strategy_dict))
            strategy = strategy_factory(strategy_dict, market_data, ticker)
            if not strategy.is_relevant():
                # don't add irrelevant tickers to the threadpool.
                # long term could figure out how to remove this
                # from the market data object too
                continue
            threads.append(TradingThread(ticker, market_data, market_time, buying_power, trade_capper, strategy, reports, TAKE_PROFIT_PERCENT, MAX_LOSS_PERCENT, PAPER_TRADING))

    # busy spin until we decided to start trading
    block_until_start_trading()

    # update before we start threads to avoid mass panic
    market_data.start_stream()
    market_time.update()

    # start all threads
    for t in threads:
        t.start()

    # update the timer in the main thread
    while market_time.is_time_left_to_trade():
        market_time.update()

    # wait for all threads to finish
    for t in threads:
        t.join()
    
    # now pretty print reports
    reports.print_eod_reports()

    # tidy up after ourselves
    r.logout()
    print_with_lock("logged out user {}".format(USERNAME))
コード例 #4
0
# Query last trading price for each stock ticker
lastPrice = r.get_quotes(tickers, "last_trade_price")

# Calculate the profit per share
profitPerShare = [
    float(lastPrice[i]) - float(prevClose[i]) for i in range(len(tickers))
]

# Calculate the percent change for each stock ticker
percentChange = [
    100.0 * profitPerShare[i] / float(prevClose[i])
    for i in range(len(tickers))
]

# Calcualte your profit for each stock ticker
profit = [profitPerShare[i] * quantities[i] for i in range(len(tickers))]

# Combine into list of lists, for sorting
tickersPerf = list(zip(profit, percentChange, tickers))

tickersPerf.sort(reverse=True)

print("My Positions Performance:")
print("Ticker | DailyGain | PercentChange")
for item in tickersPerf:
    print("%s %f$ %f%%" % (item[2], item[0], item[1]))

print("Net Gain:", sum(profit))

r.logout()
コード例 #5
0
 def teardown_class(cls):
     r.logout()
コード例 #6
0
def main():
    # login to Robinhood
    robinhood_login()
    logger.info('Robinhood login successful.')

    market_opens, market_closes = get_next_market_open_hours()
    logger.info('Market opens {} and closes {}.'.format(
        market_opens, market_closes))
    current_time = parser.parse(datetime.now(timezone.utc).isoformat())

    daily_open_positions = 0
    # while market is open, execute trading strategy
    while (current_time >= market_opens) & (current_time < market_closes) & (
            daily_open_positions < max_daily_open_positions):
        # get nearest Friday expiration
        nearest_friday_expiration = find_nearest_weekday_date(
            days_until_expiration_range=days_until_expiration_range,
            weekday_num=weekday_num,
        )

        # get implied volatility data
        iv_data = get_implied_volatility_data()

        # filter to tickers with high IV and volume
        ticker_list = iv_data.loc[
            (iv_data.optionsImpliedVolatilityRank1y > iv_rank_min) &
            (iv_data.optionsImpliedVolatilityPercentile1y > iv_percentile_min)
            & (iv_data.optionsTotalVolume >
               total_option_volume_min)]['symbol'].tolist()

        # get recent open positions
        remove_tickers = get_recent_open_option_tickers(option_type, day_lag)

        # remove tickers of positions from list
        for _ticker in remove_tickers:
            if _ticker in ticker_list:
                ticker_list.remove(_ticker)

        # create put credit spread trades dataframe
        put_credit_spread_trades = pd.DataFrame(
            data=[],
            columns=[
                'symbol', 'type', 'expiration_date', 'short_strike_price',
                'short_mark_price', 'short_ask_price', 'short_bid_price',
                'short_spread', 'short_volume', 'short_open_interest',
                'short_delta', 'short_gamma', 'short_rho', 'short_theta',
                'short_vega', 'long_strike_price', 'long_mark_price',
                'long_ask_price', 'long_bid_price', 'long_spread',
                'long_volume', 'long_open_interest', 'long_delta',
                'long_gamma', 'long_rho', 'long_theta', 'long_vega',
                'trade_strike_width', 'trade_limit_price', 'trade_spread',
                'trade_spread_ratio', 'avg_trade_volume',
                'trade_expected_dollar_return', 'trade_expected_percent_return'
            ],
        )

        # sort through each ticker looking for possible trades
        for _ticker in ticker_list:
            try:
                expiration_option_chain_data = pd.DataFrame(
                    rs.options.find_options_by_expiration(
                        inputSymbols=_ticker,
                        expirationDate=nearest_friday_expiration,
                        optionType='put',
                    ))
            except TypeError:
                expiration_option_chain_data = pd.DataFrame()

            if not expiration_option_chain_data.empty:

                # different from call script
                short_put_df = expiration_option_chain_data.loc[
                    (abs(
                        expiration_option_chain_data.delta.astype(float) +
                        target_delta) <= delta_tolerance)
                    & (expiration_option_chain_data.volume.astype(float) >=
                       option_volume_min) &
                    (expiration_option_chain_data.open_interest.astype(float)
                     >= option_open_interest_min)].copy()

                if short_put_df.shape[0] > 0:
                    if short_put_df.shape[0] > 1:
                        short_put_df.sort_values(by='volume',
                                                 ascending=False,
                                                 inplace=True)
                        short_put_df.reset_index(drop=True, inplace=True)
                        short_put_df = short_put_df.loc[short_put_df.index ==
                                                        0]

                    _symbol = short_put_df['symbol'].astype(str).values[0]
                    _type = 'put credit spread'
                    _expiration_date = short_put_df['expiration_date'].astype(
                        str).values[0]
                    _short_strike_price = short_put_df['strike_price'].astype(
                        float).values[0]
                    _short_mark_price = short_put_df['mark_price'].astype(
                        float).values[0]
                    _short_ask_price = short_put_df['ask_price'].astype(
                        float).values[0]
                    _short_bid_price = short_put_df['bid_price'].astype(
                        float).values[0]
                    _short_spread = _short_ask_price - _short_bid_price
                    _short_volume = short_put_df['volume'].astype(
                        float).values[0]
                    _short_open_interest = short_put_df[
                        'open_interest'].astype(float).values[0]
                    _short_delta = short_put_df['delta'].astype(
                        float).values[0]
                    _short_gamma = short_put_df['gamma'].astype(
                        float).values[0]
                    _short_rho = short_put_df['rho'].astype(float).values[0]
                    _short_theta = short_put_df['theta'].astype(
                        float).values[0]
                    _short_vega = short_put_df['vega'].astype(float).values[0]

                    # to do: cast expiration_option_chain_data columns to float type
                    expiration_option_chain_data[
                        'strike_price'] = expiration_option_chain_data[
                            'strike_price'].astype(float)

                    # different from call script
                    long_put_df = expiration_option_chain_data.loc[
                        expiration_option_chain_data['strike_price'].astype(
                            float) < _short_strike_price].sort_values(
                                by='strike_price', ascending=False).head(1)

                    _long_strike_price = long_put_df['strike_price'].astype(
                        float).values[0]
                    _long_mark_price = long_put_df['mark_price'].astype(
                        float).values[0]
                    _long_ask_price = long_put_df['ask_price'].astype(
                        float).values[0]
                    _long_bid_price = long_put_df['bid_price'].astype(
                        float).values[0]
                    _long_spread = _long_ask_price - _long_bid_price
                    _long_volume = long_put_df['volume'].astype(
                        float).values[0]
                    _long_open_interest = long_put_df['open_interest'].astype(
                        float).values[0]
                    _long_delta = long_put_df['delta'].astype(float).values[0]
                    _long_gamma = long_put_df['gamma'].astype(float).values[0]
                    _long_rho = long_put_df['rho'].astype(float).values[0]
                    _long_theta = long_put_df['theta'].astype(float).values[0]
                    _long_vega = long_put_df['vega'].astype(float).values[0]

                    # different from call script
                    _trade_strike_width = -1 * (_long_strike_price -
                                                _short_strike_price)
                    _trade_limit_price = _short_mark_price - _long_mark_price
                    _trade_spread = _short_ask_price - _long_bid_price
                    _trade_spread_ratio = _trade_spread / _trade_strike_width
                    _avg_trade_volume = (_short_volume + _long_volume) / 2

                    # different from call script
                    _trade_expected_dollar_return = (
                        1 + _short_delta) * _trade_limit_price
                    _trade_expected_percent_return = _trade_expected_dollar_return / (
                        _trade_strike_width - _trade_limit_price)

                    put_credit_spread_trades.loc[-1] = [
                        _symbol,
                        _type,
                        _expiration_date,
                        _short_strike_price,
                        _short_mark_price,
                        _short_ask_price,
                        _short_bid_price,
                        _short_spread,
                        _short_volume,
                        _short_open_interest,
                        _short_delta,
                        _short_gamma,
                        _short_rho,
                        _short_theta,
                        _short_vega,
                        _long_strike_price,
                        _long_mark_price,
                        _long_ask_price,
                        _long_bid_price,
                        _long_spread,
                        _long_volume,
                        _long_open_interest,
                        _long_delta,
                        _long_gamma,
                        _long_rho,
                        _long_theta,
                        _long_vega,
                        _trade_strike_width,
                        _trade_limit_price,
                        _trade_spread,
                        _trade_spread_ratio,
                        _avg_trade_volume,
                        _trade_expected_dollar_return,
                        _trade_expected_percent_return,
                    ]

                    put_credit_spread_trades.index += 1

        # identify possible trades to execute, if any
        possible_put_credit_spread_trades = put_credit_spread_trades.loc[
            (put_credit_spread_trades.trade_strike_width <= max_strike_width)
            & (put_credit_spread_trades.trade_expected_percent_return >
               min_percent_return)].sort_values(by='avg_trade_volume',
                                                ascending=True)

        # select a trade to execute, if any
        if possible_put_credit_spread_trades.shape[0] > 0:
            put_credit_spread_trade = possible_put_credit_spread_trades.iloc[
                -1]

            # set option orders as list
            put_credit_spread_open_order_list = [
                {
                    'expirationDate':
                    put_credit_spread_trade['expiration_date'],
                    'strike': put_credit_spread_trade['short_strike_price'],
                    'optionType': 'put',
                    'effect': 'open',
                    'action': 'sell',
                },
                {
                    'expirationDate':
                    put_credit_spread_trade['expiration_date'],
                    'strike': put_credit_spread_trade['long_strike_price'],
                    'optionType': 'put',
                    'effect': 'open',
                    'action': 'buy',
                },
            ]

            # send order to Robinhood
            put_credit_spread_open_order_receipt = rs.order_option_credit_spread(
                price=put_credit_spread_trade['trade_limit_price'].round(2),
                symbol=put_credit_spread_trade['symbol'],
                quantity=1,
                spread=put_credit_spread_open_order_list,
                timeInForce='gfd',
            )

            # check order status
            updated_put_credit_spread_open_order_receipt = rs.get_option_order_info(
                order_id=put_credit_spread_open_order_receipt['id'], )

            # check until trade is executed or canceled
            check_for_trade_execution = True
            while check_for_trade_execution:
                updated_put_credit_spread_open_order_receipt = rs.get_option_order_info(
                    order_id=put_credit_spread_open_order_receipt['id'], )
                if updated_put_credit_spread_open_order_receipt[
                        'state'] == 'filled':
                    trade_filled = True
                    check_for_trade_execution = False
                elif updated_put_credit_spread_open_order_receipt[
                        'state'] == 'cancelled':
                    trade_filled = False
                    check_for_trade_execution = False
                else:
                    # sleep for 5 minutes
                    sleep(300)

            if trade_filled:
                # send closing trade order to Robinhood
                if updated_put_credit_spread_open_order_receipt[
                        'state'] == 'filled':
                    put_credit_spread_close_order_list = [
                        {
                            'expirationDate':
                            put_credit_spread_trade['expiration_date'],
                            'strike':
                            put_credit_spread_trade['short_strike_price'],
                            'optionType':
                            'put',
                            'effect':
                            'close',
                            'action':
                            'buy',
                        },
                        {
                            'expirationDate':
                            put_credit_spread_trade['expiration_date'],
                            'strike':
                            put_credit_spread_trade['long_strike_price'],
                            'optionType':
                            'put',
                            'effect':
                            'close',
                            'action':
                            'sell',
                        },
                    ]

                    put_credit_spread_close_order_receipt = rs.order_option_debit_spread(
                        price=(put_credit_spread_trade['trade_limit_price'] *
                               profit_target_percent).round(2),
                        symbol=put_credit_spread_trade['symbol'],
                        quantity=1,
                        spread=put_credit_spread_close_order_list,
                        timeInForce='gtc',
                    )

                put_credit_spread_logging = pd.read_csv(
                    trade_logging_file_path)
                put_credit_spread_logging_new_trade = pd.DataFrame(
                    put_credit_spread_trade).T.round(6)

                for _col in put_credit_spread_logging_new_trade.columns:
                    if _col not in [
                            'index', 'symbol', 'type', 'expiration_date'
                    ]:
                        put_credit_spread_logging_new_trade[
                            _col] = put_credit_spread_logging_new_trade[
                                _col].astype(float).round(6)

                put_credit_spread_logging_new_trade[
                    'trade_open_id'] = put_credit_spread_open_order_receipt[
                        'id']
                put_credit_spread_logging_new_trade[
                    'trade_close_id'] = put_credit_spread_close_order_receipt[
                        'id']

                if 'index' in put_credit_spread_logging_new_trade.columns:
                    put_credit_spread_logging_new_trade.drop(columns=['index'],
                                                             inplace=True)

                put_credit_spread_logging = pd.concat([
                    put_credit_spread_logging,
                    put_credit_spread_logging_new_trade
                ])
                put_credit_spread_logging.drop_duplicates(inplace=True)
                put_credit_spread_logging.to_csv(trade_logging_file_path,
                                                 index=False)

                daily_open_positions += 1

        # delay to prevent overwhelming Robinhood API
        logger.info('Sleep for 300 seconds.')
        sleep(300)

        # get new current time
        current_time = parser.parse(datetime.now(timezone.utc).isoformat())
        pass

    # logout while not trading
    rs.logout()
    logger.info('Robinhood logout successful.')

    # pause trading if max daily open positions are reached
    if daily_open_positions >= max_daily_open_positions:
        logger.info('Max daily open positions reached. Sleep for {}.'.format(
            timedelta(seconds=23400)))
        sleep(23400)

    # seconds until next market open
    wait_time = max(seconds_until_market_open(market_opens), 0)

    # require login at least once per day to avoid error
    wait_time = wait_time / 4
    logger.info('Market closed. Waiting {}.'.format(
        timedelta(seconds=wait_time)))
    sleep(wait_time)
コード例 #7
0
if __name__ == '__main__':
    args = parser.parse_args()

    RH_UNAME = os.environ.get("robinhood_username")
    RH_PWD = os.environ.get("robinhood_password")
    totp = pyotp.TOTP("authy").now()
    lg = rh.login(username=RH_UNAME, password=RH_PWD, mfa_code=totp)

    file_name = None
    dir_name = None
    if args.name:
        try:
            dir_name = os.path.dirname(args.name)
            file_name = args.name.split(dir_name)[1][1:]
        except:
            pass

    if args.type == 'crypto':
        export_crypto(dir_name=dir_name, file_name=file_name, rh=rh)
    elif args.type == 'stocks':
        export_stocks(dir_name=dir_name, file_name=file_name, rh=rh)
    elif args.type == 'both' or args.type == '':
        export_crypto(dir_name=dir_name, file_name=file_name, rh=rh)
        export_stocks(dir_name=dir_name, file_name=file_name, rh=rh)
    else:
        print("Please specify valid type")

    rh.logout()

    print('Done!')
コード例 #8
0
def logout():
    r.logout()
コード例 #9
0
def logoff():
    robinhood.logout()
コード例 #10
0
ファイル: robinhood.py プロジェクト: honording/make1million
 def MFALogoff(self):
     """
     Log off from robinhood account
     """
     rs.logout()
     print(f"{bColors.OKGREEN}Info: Logoff successful.{bColors.ENDC}")