Пример #1
0
class RHTrader:
    """
    Algorithmic trader using Robinhood API to enter positions based on RSI period and historical prices.
    """
    def __init__(self, username, pwd, rsi=5):
        self.rh = Robinhood()
        self.rh.login(username=username, password=pwd)
        self.rsiPeriod = rsi
        self.enteredPosition = False
        self.s = sched.scheduler(time.time, time.sleep)
        self.data = np.array([])
        self.closePrices = []

    def populate(self):
        historical_quotes = self.rh.get_historical_quotes(
            "F", "5minute", "day")
        index = 0
        support = 0
        resistance = 0
        for key in historical_quotes["results"][0]["historicals"]:
            if index >= len(historical_quotes["results"][0]["historicals"]) - (
                    self.rsiPeriod + 1):
                if (index >= (self.rsiPeriod - 1) and datetime.strptime(
                        key['begins_at'], '%Y-%m-%dT%H:%M:%SZ').minute == 0):
                    support = 0
                    resistance = 0
                    print("Resetting support and resistance")
                if float(key['close_price']) < support or support == 0:
                    support = float(key['close_price'])
                    print("Current Support is : ")
                    print(support)
                if float(key['close_price']) > resistance:
                    resistance = float(key['close_price'])
                    print("Current Resistance is : ")
                    print(resistance)
                self.closePrices.append(float(key['close_price']))
            index += 1
        self.data = np.array(self.closePrices)

    def execute(self, sc):
        if len(self.closePrices) > self.rsiPeriod:
            # Calculate RSI
            rsi = ti.rsi(self.data, period=self.rsiPeriod)
            instrument = self.rh.instruments("F")[0]
            # If rsi is less than or equal to 30 buy
            if rsi[len(rsi) - 1] <= 30 and not self.enteredPosition:
                print("Buying RSI is below 30!")
                self.rh.place_buy_order(instrument, 1)
                self.enteredPosition = True
            # Sell when RSI reaches 70
            if rsi[len(rsi) - 1] >= 70 and self.enteredPosition:
                print("Selling RSI is above 70!")
                self.rh.place_sell_order(instrument, 1)
                self.enteredPosition = False
            print(rsi)
            # call this method again every 5 minutes for new price changes
        self.s.enter(300, 1, self.execute, (sc, ))

    def run(self):
        self.s.enter(1, 1, self.execute, (self.s, ))
        self.s.run()
Пример #2
0
def watcher():
    global graph_msg, graph_min, graph_max
    rh = Robinhood()
    rh.login(username=rh_user, password=rh_pass, qr_code=rh_qr)
    raw_result = rh.positions()
    result = raw_result['results']
    shares_total = []
    port_msg = f"Your portfolio ({rh.get_account()['account_number']}):\n"
    loss_output = 'Loss:'
    profit_output = 'Profit:'
    loss_total = []
    profit_total = []
    graph_msg = None  # initiates a variable graph_msg as None for looped condition below
    n = 0
    n_ = 0
    for data in result:
        share_id = str(data['instrument'].split('/')[-2])
        buy = round(float(data['average_buy_price']), 2)
        shares_count = int(data['quantity'].split('.')[0])
        if shares_count != 0:
            n = n + 1
            n_ = n_ + shares_count
        else:
            continue
        raw_details = rh.get_quote(share_id)
        share_name = raw_details['symbol']
        call = raw_details['instrument']
        share_full_name = loads(get(call).text)['simple_name']
        total = round(shares_count * float(buy), 2)
        shares_total.append(total)
        current = round(float(raw_details['last_trade_price']), 2)
        current_total = round(shares_count * current, 2)
        difference = round(float(current_total - total), 2)
        if difference < 0:
            loss_output += (
                f'\n{share_full_name}:\n{shares_count} shares of {share_name} at ${buy} Currently: ${current}\n'
                f'Total bought: ${total} Current Total: ${current_total}'
                f'\nLOST ${-difference}\n')
            loss_total.append(-difference)
        else:
            profit_output += (
                f'\n{share_full_name}:\n{shares_count} shares of {share_name} at ${buy} Currently: ${current}\n'
                f'Total bought: ${total} Current Total: ${current_total}'
                f'\nGained ${difference}\n')
            profit_total.append(difference)
        if graph_min and graph_max:
            graph_min = float(graph_min)
            graph_max = float(graph_max)
            if difference > graph_max or difference < -graph_min:
                time_now = datetime.now()
                metrics = time_now - timedelta(days=7)
                numbers = []
                historic_data = (rh.get_historical_quotes(
                    share_name, '10minute', 'week'))
                historical_values = historic_data['results'][0]['historicals']
                for close_price in historical_values:
                    numbers.append(round(float(close_price['close_price']), 2))
                fig, ax = plt.subplots()
                if difference > graph_max:
                    plt.title(
                        f"Stock Price Trend for {share_full_name}\nShares: {shares_count}  Profit: ${difference}"
                    )
                elif difference < graph_min:
                    plt.title(
                        f"Stock Price Trend for {share_full_name}\nShares: {shares_count}  LOSS: ${-difference}"
                    )
                plt.xlabel(
                    f"1 Week trend with 10 minutes interval from {metrics.strftime('%m-%d %H:%M')} to "
                    f"{time_now.strftime('%m-%d %H:%M')}")
                plt.ylabel('Price in USD')
                ax.plot(numbers, linewidth=1.5)
                if not path.isdir('img'):
                    mkdir('img')
                fig.savefig(f"img/{share_full_name}.png", format="png")
                plt.close(
                )  # close plt to avoid memory exception when more than 20 graphs are generated
                # stores graph_msg only if a graph is generated else graph_msg remains None
                if not graph_msg:  # used if not to avoid storing the message repeatedly
                    graph_msg = f"Attached are the graphs for stocks which exceeded a profit of " \
                                f"${graph_max} or deceeded a loss of ${graph_min}"
        elif not graph_msg:  # used elif not to avoid storing the message repeatedly
            graph_msg = "Add the env variables for <graph_min> and <graph_max> to include a graph of previous " \
                        "week's trend."

    lost = round(fsum(loss_total), 2)
    gained = round(fsum(profit_total), 2)
    port_msg += f'The below values will differ from overall profit/loss if shares were purchased ' \
                f'with different price values.\nTotal Profit: ${gained}\nTotal Loss: ${lost}\n'
    net_worth = round(float(rh.equity()), 2)
    output = f'Total number of stocks purchased: {n}\n'
    output += f'Total number of shares owned: {n_}\n\n'
    output += f'Current value of your total investment is: ${net_worth}\n'
    total_buy = round(fsum(shares_total), 2)
    output += f'Value of your total investment while purchase is: ${total_buy}\n'
    total_diff = round(float(net_worth - total_buy), 2)
    if total_diff < 0:
        output += f'Overall Loss: ${total_diff}'
    else:
        output += f'Overall Profit: ${total_diff}'
    yesterday_close = round(float(rh.equity_previous_close()), 2)
    two_day_diff = round(float(net_worth - yesterday_close), 2)
    output += f"\n\nYesterday's closing value: ${yesterday_close}"
    if two_day_diff < 0:
        output += f"\nCurrent Dip: ${two_day_diff}"
    else:
        output += f"\nCurrent Spike: ${two_day_diff}"
    if not graph_msg:  # if graph_msg was not set above
        graph_msg = f"You have not lost more than ${graph_min} or gained more than " \
                    f"${graph_max} to generate a graph."

    return port_msg, profit_output, loss_output, output, graph_msg
Пример #3
0
# Log in to Robinhood app (will prompt for two-factor)
rh = Robinhood()
rh.login(username=config.USERNAME,
         password=config.PASSWORD,
         qr_code=config.MFA)

# STOCK TICKER
stock_ticker = input("Enter Stock ticker you would like to trade: ").upper()
# Create a User and set the day trade limit.

number_of_trades = database_function.get_number_of_trades("database.txt")

user = User(0,0,0,0,int(number_of_trades),None)

# Get quote data from RH API
day_year_quotes = rh.get_historical_quotes(stock_ticker, 'day', 'year')
#print(* day_year_quotes["results"][0]["historicals"], sep='\n')

async def run():
    while True:
        time_string = time.strftime("%m/%d/%Y, %H:%M:%S", time.localtime())

        # POST TIME
        print("\nGetting historical quotes on {}".format(time_string))

        # This gets the last 60 days including today.
        five_min_day_yahoo = yahoo_finance.get_stock_history(stock_ticker, "5m")

        # Create list of closing prices from RH API
        close_prices = []
        [close_prices.append(float(key['close_price'])) for key in day_year_quotes["results"][0]["historicals"]]