def spanAvgs(tradingcrypto, interval, span): intervalhigh = r.get_crypto_historicals(tradingcrypto, interval, span, '24_7', 'high_price') intervallow = r.get_crypto_historicals(tradingcrypto, interval, span, '24_7', 'low_price') intervalopen = r.get_crypto_historicals(tradingcrypto, interval, span, '24_7', 'open_price') intervalclose = r.get_crypto_historicals(tradingcrypto, interval, span, '24_7', 'close_price') intervaltimes = r.get_crypto_historicals(tradingcrypto, interval, span, '24_7', 'begins_at') intervallowAverage = round(average(intervallow), 6) intervalhighAverage = round(average(intervalhigh), 6) intervalAvgs = [intervalhighAverage, intervallowAverage] intervalAverage = round(average(intervalAvgs), 6) intervalLists = [] intervalLists.append(intervalhighAverage) intervalLists.append(intervallowAverage) intervalLists.append(intervalAverage) intervalLists.append(intervalhigh) intervalLists.append(intervallow) intervalLists.append(intervalopen) intervalLists.append(intervalclose) intervalLists.append(intervaltimes) labels = [ 'high', 'low', 'true', 'highs', 'lows', 'opens', 'closes', 'times' ] return (intervalLists)
def averageHistoricalQuotes(tradingcrypto,interval,span): lowprices=[] highprices=[] history=r.get_crypto_historicals(tradingcrypto,interval,span,'24_7') #format the product for x in range (0,len(history)): dataset=history[x] #print('begins_at',dataset['begins_at']) #print('low price ',dataset['low_price']) #print('high price ',dataset['high_price']) #print('##########################################################') lowprices.append(dataset['low_price']) highprices.append(dataset['high_price']) #####Average out the low prices####################### lowtotal=0 hightotal=0 for x in range(0,len(lowprices)): adder=float(lowprices[x]) lowtotal+=adder for x in range(0,len(highprices)): adder=float(highprices[x]) hightotal+=adder lowavg=lowtotal/len(lowprices) highavg=hightotal/len(highprices) print('datapoints: ',len(lowprices)) print('low average: ', round(lowavg,6)) print('high average: ',round(highavg,6)) return(round(lowavg,6),round(highavg,6)) ####RETURNS TUPLE [LOWPRICE,HIGHPRICE]
def crypto_history(symbol, interval, span): ui.success(f'\nGetting {interval} stock historicals for {symbol} for the past {span}....\n') result = rh.get_crypto_historicals(symbol, interval, span) for i in result: for x in i: ui.success(f'{x}: {i[x]}') ui.bar()
def get_historicals(): global current_close_price global close_price_historicals global high_price_historicals global low_price_historicals global open_price_historicals global candle_check global candle_update global candle_color global swing_low #interval = '5minute' #span = 'day' #interval = '15second' #span = 'hour' interval = 'hour' span = 'week' historicals = robin_stocks.get_crypto_historicals(ticker, interval, span) close_prices = [] high_prices = [] low_prices = [] open_prices = [] for key in historicals: close = (float(key['close_price'])) high = (float(key['high_price'])) low = (float(key['low_price'])) popen = (float(key['open_price'])) close_prices.append(close) high_prices.append(high) low_prices.append(low) open_prices.append(popen) current_close_price = round(close_prices[-1], 2) close_price_historicals = np.array(close_prices) high_price_historicals = np.array(high_prices) low_price_historicals = np.array(low_prices) open_price_historicals = np.array(open_prices) current_candle = open_price_historicals[-1] candle_check.append(current_candle) if (len(candle_check) > 2): candle_check.remove(candle_check[0]) if (candle_check[0] == candle_check[1]): candle_update = False else: candle_update = True if (close_price_historicals[-1] > open_price_historicals[-1]): candle_color = "green" else: candle_color = "red"
def test_crypto_historicals(self): crypto = r.get_crypto_historicals(self.bitcoin, 'day', 'week', '24_7', info=None) assert (len(crypto) == 7) first_point = crypto[0] # check keys assert ('begins_at' in first_point) assert ('open_price' in first_point) assert ('close_price' in first_point) assert ('high_price' in first_point) assert ('low_price' in first_point) assert ('volume' in first_point) assert ('session' in first_point) assert ('interpolated' in first_point) # crypto = r.get_crypto_historicals(self.bitcoin, 'hour', 'day', 'regular', info=None) assert (len(crypto) <= 6) # 6 regular hours in a day crypto = r.get_crypto_historicals(self.bitcoin, 'hour', 'day', 'trading', info=None) assert (len(crypto) <= 9) # 9 trading hours in a day crypto = r.get_crypto_historicals(self.bitcoin, 'hour', 'day', 'extended', info=None) assert (len(crypto) <= 16) # 16 extended hours in a day crypto = r.get_crypto_historicals(self.bitcoin, 'hour', 'day', '24_7', info=None) assert (len(crypto) <= 24) # 24 24_7 hours in a day
def test_crypto_historical(self): crypto = r.get_crypto_historicals(self.bitcoin, 'day', 'week', '24_7', info=None) self.assertEqual(len(crypto), 7) first_point = crypto[0] # check keys self.assertIn('begins_at', first_point) self.assertIn('open_price', first_point) self.assertIn('close_price', first_point) self.assertIn('high_price', first_point) self.assertIn('low_price', first_point) self.assertIn('volume', first_point) self.assertIn('session', first_point) self.assertIn('interpolated', first_point) # crypto = r.get_crypto_historicals(self.bitcoin, 'hour', 'day', 'trading', info=None) self.assertEqual(len(crypto), 9) crypto = r.get_crypto_historicals(self.bitcoin, 'hour', 'day', 'regular', info=None) self.assertEqual(len(crypto), 6) crypto = r.get_crypto_historicals(self.bitcoin, 'hour', 'day', 'extended', info=None) self.assertEqual(len(crypto), 16) crypto = r.get_crypto_historicals(self.bitcoin, 'hour', 'day', '24_7', info=None) self.assertEqual(len(crypto), 24)
def train(self): try: training_data = r.get_crypto_historicals(symbol=self.coin.name, interval='15second', span='hour', bounds='24_7', info='close_price') for data in training_data: self.coinTrend.append(float(data)) except: print("Problem fetching training data") return
def standard14DayRSI(tradingcrypto): #measure period of closes history = r.get_crypto_historicals(tradingcrypto, 'day', 'month', '24_7') closeprices = [] for x in range(0, len(history) - 15): dataset = history[x + 15] closeprices.append(dataset['close_price']) #measure differences between closes and globulate gains and losses gains = [] losses = [] nochange = [] for x in range(0, len(closeprices) - 1): preresult = Decimal(float(closeprices[x])) - Decimal( float(closeprices[x + 1])) result = round(preresult, 6) if result < 0: losses.append(result) elif result > 0: gains.append(result) else: nochange.append(result) gaintotal = 0 losstotal = 0 #print('gains/losses amounts') #print(len(gains)) #print(len(losses)) for x in range(0, len(gains) - 1): gaintotal = Decimal(float(gaintotal)) + Decimal(float(gains[x])) for x in range(0, len(losses) - 1): losstotal = Decimal(float(losstotal)) + Decimal(float(losses[x])) #print('gain/loss totals') #print(round(gaintotal,6)) #print(round(losstotal,6)) #divide gains by periods and divide losses by periods gainstrength = Decimal(gaintotal) / len(closeprices) lossstrength = Decimal(abs(losstotal)) / len(closeprices) #print('gain/loss strength') #print(round(gainstrength,6)) #print(round(lossstrength,6)) #divide gain/periods by loss/periods. this is the relative strength relativestrength = Decimal(gainstrength) / Decimal(lossstrength) #print('relative strength') #print(round(relativestrength,6)) #RSI= 100-(100/(1+RS)) rsi = 100 - (100 / (1 + Decimal(relativestrength))) return (rsi)
def lastHourByMinute(cryptoSymbol, span, peak): history = r.get_crypto_historicals(cryptoSymbol, '15second', span, '24_7') #format the product localLows = [] localHighs = [] for x in range(0, len(history)): if x % 4 == 0: dataset = history[x] #print(dataset['begins_at']) localLows.append(dataset['low_price']) localHighs.append(dataset['high_price']) if peak == 'highs': return (localHighs) elif peak == 'lows': return (localLows) else: print('needs a peak specified')
def dailyHighLowsForMonth(cryptoSymbol,peak): interval='day' span='month' localHighs=[] localLows=[] history=r.get_crypto_historicals(cryptoSymbol,interval,span,'24_7') #format the product for x in range (0,len(history)): dataset=history[x] #printCryptoQuoteDataset(dataset) localLows.append(dataset['low_price']) localHighs.append(dataset['high_price']) if peak=='lows': return(localLows) elif peak =='highs': return(localHighs) else: print('peak not specified')
def getHistoricalQuotes( cryptoSymbol, interval, span, peak): #gets quotes at specific interval per span and stores history = r.get_crypto_historicals(cryptoSymbol, interval, span, '24_7') #format the product localHighs = [] localLows = [] for x in range(0, len(history)): dataset = history[x] #printCryptoQuoteDataset(dataset) localLows.append(dataset['low_price']) localHighs.append(dataset['high_price']) if peak == 'lows': return (localLows) elif peak == 'highs': return (localHighs) else: print('peak not specified') ''' symbol (str) – The crypto ticker. interval (str) – The time between data points. Can be ’15second’, ‘5minute’, ‘10minute’, ‘hour’, ‘day’, or ‘week’. Default is ‘hour’. span (str) – The entire time frame to collect data points. Can be ‘hour’, ‘day’, ‘week’, ‘month’, ‘3month’, ‘year’, or ‘5year’. Default is ‘week’ bound (str) – The times of day to collect data points. ‘Regular’ is 6 hours a day, ‘trading’ is 9 hours a day, ‘extended’ is 16 hours a day, ‘24_7’ is 24 hours a day. Default is ‘24_7’ info (Optional[str]) – Will filter the results to have a list of the values that correspond to key that matches info. Returns: [list] If info parameter is left as None then the list will contain a dictionary of key/value pairs for each ticker. Otherwise, it will be a list of strings where the strings are the values of the key that corresponds to info. Dictionary Keys: begins_at open_price close_price high_price low_price volume session interpolated symbol ''' '''
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)
import pickle import os.path as path from datetime import datetime, timedelta import time import pytz import pandas as pd import math import robin_stocks as r import tideconfig as cfg import talib import mplfinance as mpf r.login(cfg.rh['username'], cfg.rh['password']) data = r.get_crypto_historicals('BTC', interval='5minute', span='week', info=None) reformatted_data = dict() reformatted_data['Date'] = [] reformatted_data['Open'] = [] reformatted_data['High'] = [] reformatted_data['Low'] = [] reformatted_data['Close'] = [] reformatted_data['Volume'] = [] for dict in data: reformatted_data['Date'].append( datetime.strptime(dict['begins_at'], '%Y-%m-%dT%H:%M:%SZ')) reformatted_data['Open'].append(float(dict['open_price'])) reformatted_data['High'].append(float(dict['high_price'])) reformatted_data['Low'].append(float(dict['low_price'])) reformatted_data['Close'].append(float(dict['close_price']))
load_dotenv(find_dotenv()) #print(os.environ['RH_USERNAME']) #print(os.environ['RH_PASSWORD']) login = robin_stocks.login(os.environ['RH_USERNAME'], os.environ['RH_PASSWORD']) print(login) # Time between data points: 15second, 5minute, 10minute, hour, day, or week INTERVAL = '10minute' # Entire time frame to collect data points: hour, day, week, month, 3month, year, 5year SPAN = 'hour' # historicalData is a list of dictionaries containing every key/value pair historicalData = robin_stocks.get_crypto_historicals('BTC', interval=INTERVAL, span=SPAN, bounds='24_7', info=None) # Extract values we're interested in beginsAt = [data['begins_at'] for data in historicalData] closePrice = [data['close_price'] for data in historicalData] assert (len(beginsAt) == len(closePrice)) # Convert UTC timestamps to unix timestamps timeStamps = [ datetime.datetime.strptime(data, "%Y-%m-%dT%H:%M:%SZ").timestamp() for data in beginsAt ] print(closePrice)
def rsi_based_buy_sell(self, symbol): """ Check the RSI and possibly place a buy or sell order """ ## Check the RSI ## historical_data = rh.get_crypto_historicals( symbol=symbol, interval=RSI_WINDOW[symbol], span=RSI_SPAN[symbol], bounds="24_7", info=None) df = pd.DataFrame(historical_data) # convert prices to float since values are given as strings df["close_price"] = pd.to_numeric(df["close_price"], errors='coerce') # Get the current RSI rsi = RSI(df["close_price"], period=RSI_PERIOD[symbol], current_only=True) self.rsi[symbol] = rsi self.quantity_on_hand[ 'USD'] = self.cash_on_hand = cash = self.check_cash_on_hand() crypto_on_hand = self.check_cash_on_hand(symbol=symbol) self.quote[symbol] = quote = crypto_on_hand['quote'] self.quantity_on_hand[symbol] = quantity = crypto_on_hand['quantity'] self.cost_basis[symbol] = cost_basis = crypto_on_hand['cost'] self.symbol_value[symbol] = quote * quantity self.stop_loss_quote[symbol] = self.stop_loss_quote[ symbol] #smartdict(lambda k: self.cost_quote[k]*(100-self.stop_loss_percent[k])/100) self.stop_loss_delta[symbol] = self.stop_loss_delta[ symbol] #smartdict(lambda k: self.cost_quote[k] - self.stop_loss_quote[k]) ## If quantity is 0, reset trailing stops if self.quantity_on_hand[symbol] == 0: self.reset_stops(symbol) try: self.symbol_pnl_percent[symbol] = 100 * (quote * quantity - cost_basis) / cost_basis except ZeroDivisionError: self.symbol_pnl_percent[symbol] = 0 # TODO: Store data in instance variables and move output to mainloop or special output function: sign = "+" if self.symbol_pnl_percent[symbol] >= 0 else "" self.disp_usd.feedlines( f"USD\t\t\t{self.quantity_on_hand['USD']:.2f}\t${self.quantity_on_hand['USD']:.2f}\t\t" ) if symbol == 'BTC': quote_prec = 0 quant_prec = 5 elif symbol == 'DOGE': quote_prec = 5 quant_prec = 0 else: quote_prec = 2 quant_prec = 5 # self.disp_crypto.feedlines(f"{symbol}\t" + # f"{self.quote[symbol]:.{quote_prec}f}\t" + # f"{self.stop_loss_quote[symbol]:.{quote_prec}f}\t" + # f"{self.quantity_on_hand[symbol]:.{quant_prec}f}\t" + # f"${self.symbol_value[symbol]:.2f}\t" + # f"{sign}{self.symbol_pnl_percent[symbol]:.2f}%\t" + # f"${self.cost_basis[symbol]:.2f}\t" + # f"{self.rsi[symbol]:.2f}\t" + # f"{self.rsi_buy_at[symbol]:.2f}\t" + # f"{self.rsi_sell_at[symbol]:.2f}\t" + # f"{self.symbol_trades[symbol]}|{self.symbol_take_profits[symbol]}|{self.stop_losses_triggered[symbol]}\t" + # f"{self.take_profit_percent[symbol]}%|{self.stop_loss_percent[symbol]}% [{self.stop_loss_delta[symbol]}]") # ({100*(self.quote[symbol] - self.stop_loss_quote[symbol])/self.quote[symbol]:.2f})") alpha = -1 new_delta = -1 ## Adjust stop if price is high, but only if quantity is > 0 if self.symbol_pnl_percent[symbol] > 0 and self.quantity_on_hand[ symbol] > 0 and self.quote[symbol] > self.stop_loss_quote[ symbol] + self.stop_loss_delta[symbol]: self.disp_warn_feed.feedlines( f"Adjusting stop loss quote for {symbol} to {self.stop_loss_quote[symbol]}" ) self.stop_loss_quote[ symbol] = self.quote[symbol] - self.stop_loss_delta[symbol] elif SHRINKING_STOP_LOSS: if self.symbol_pnl_percent[symbol] > 0: tp = self.take_profit_percent[ symbol] if self.take_profit_percent[ symbol] is not None else 100 alpha = min(1, self.symbol_pnl_percent[symbol] / tp) # ratio of take profit % reached orig_sl_quote = self.cost_quote[symbol] * ( 100 - self.stop_loss_percent[symbol]) / 100 # At alpha = 1, delta = 1/2 orig_sl_delta # At alpha = 0, delta = orig_sl_delta orig_sl_delta = self.cost_quote[symbol] - orig_sl_quote new_delta = orig_sl_delta - alpha * 0.5 * orig_sl_delta # Only allow delta to shrink if new_delta < self.stop_loss_delta[symbol]: self.stop_loss_delta[symbol] = new_delta self.disp_warn_feed.feedlines( f"Adjusting stop loss delta for {symbol} to {self.stop_loss_delta[symbol]}" ) # new_delta = min(max(0,self.quote[symbol] - self.stop_loss_quote[symbol]), self.stop_loss_delta[symbol]) # tp = self.take_profit_percent[symbol] if self.take_profit_percent[symbol] is not None else 100 # alpha = min(1, self.symbol_pnl_percent[symbol]/tp)**5 # # Take a weighted average # new_delta = (1-alpha)*self.stop_loss_delta[symbol] + (alpha)*new_delta # self.stop_loss_quote[symbol] = self.stop_loss_quote[symbol] + (self.stop_loss_delta[symbol] - new_delta) # self.stop_loss_delta[symbol] = new_delta ## Adjust RSI buy/sell levels towards the defaults. self.adjust_rsi(symbol) self.disp_crypto.feedlines( f"{symbol}\t" + f"{self.quote[symbol]:.{quote_prec}f}\t" + f"{self.stop_loss_quote[symbol]:.{quote_prec}f}\t" + f"{self.quantity_on_hand[symbol]:.{quant_prec}f}\t" + f"${self.symbol_value[symbol]:.2f}\t" + f"{sign}{self.symbol_pnl_percent[symbol]:.2f}%\t" + f"${self.cost_basis[symbol]:.2f}\t" + f"{self.rsi[symbol]:.2f}\t" + f"{self.rsi_buy_at[symbol]:.2f}\t" + f"{self.rsi_sell_at[symbol]:.2f}\t" + f"{self.symbol_trades[symbol]}|{self.symbol_take_profits[symbol]}|{self.stop_losses_triggered[symbol]}\t" + f"{self.take_profit_percent[symbol]}%|{self.stop_loss_percent[symbol]}% [{self.stop_loss_delta[symbol]:.3f}] [{alpha:.3f}]" ) # ({100*(self.quote[symbol] - self.stop_loss_quote[symbol])/self.quote[symbol]:.2f})") ## Check for stop loss / take profits: if self.take_profit_percent[ symbol] is not None and self.symbol_pnl_percent[ symbol] > self.take_profit_percent[symbol]: # info = rh.order_sell_crypto_limit(symbol, quantity, round(0.999*quote,2)) self.disp_warn_feed.feedlines( f"Take profit triggered! Selling {quantity} of {symbol}") # info = self.trigger_tx(symbol, quantity, round(0.99*quote, 2), side="sell", quantity_on_hand = quantity) asyncio.get_event_loop().create_task( self.a_trigger_tx(symbol, quantity=quantity, price=0.99 * self.quote[symbol], side="sell", quantity_on_hand=quantity)) # if info is not None: # self.disp_warn_feed.feedlines(f"Take profit triggered! Selling {quantity} of {symbol}") # self.total_trades += 1 # self.total_take_profits += 1 # self.symbol_take_profits[symbol] += 1 return # skip checking rsi this time around elif self.stop_loss_percent[symbol] is not None and (self.symbol_pnl_percent[symbol] < -1*self.stop_loss_percent[symbol]\ or self.quote[symbol] < self.stop_loss_quote[symbol]): self.disp_warn_feed.feedlines( f"Stop loss triggered! Selling {quantity} of {symbol}") asyncio.get_event_loop().create_task( self.a_trigger_tx(symbol, quantity=quantity, price=0.95 * self.quote[symbol], side="sell", quantity_on_hand=quantity)) # info = rh.order_sell_crypto_limit(symbol, quantity, round(0.99*quote, 2)) # rh.order_sell_crypto_by_quantity(symbol, round(quantity,6)) # if info is not None: # self.disp_warn_feed.feedlines(f"Stop loss triggered! Selling {quantity} of {symbol}") # self.total_trades += 1 # self.total_stops_losses += 1 # self.stop_losses_triggered[symbol] += 1 # # Step RSI buy cutoff down so we don't buy again right away # self.bump_rsi(symbol, 'buy', 5) # 5x normal adjustment # pprint(info) return # skip checking rsi # Check RSI to see if we should buy or sell if rsi <= self.rsi_buy_at[symbol]: asyncio.get_event_loop().create_task( self.a_trigger_tx(symbol, quantity=None, price=1.01 * quote, side='buy', cash_on_hand=cash)) # info = self.trigger_tx(symbol, quantity = None, price = 1.01*quote, side = 'buy', cash_on_hand = cash) # if info is not None: # try: # if not isinstance(info['quantity'], list): # # self.disp_info_feed.feedlines(f"[{time.strftime('%X')}] Buying: {symbol}") # {info['quantity']:.6f} at {info['price']:.2f} ({info['quantity']*info['price']:.2f})") # self.bump_rsi(symbol, 'buy') # self.total_trades += 1 # self.symbol_trades[symbol] += 1 # except (ValueError, KeyError): # logging.warning(f"Failed buying: {info}") elif self.quantity_on_hand[symbol] > 0 and rsi >= self.rsi_sell_at[ symbol]: if REQUIRE_PNL_TO_SELL[symbol] is not None and\ self.symbol_pnl_percent[symbol] < REQUIRE_PNL_TO_SELL[symbol]: if EXTRA_INFO: self.disp_warn_feed.feedlines( f"RSI sell level met for {symbol}, but PnL not high enough" ) else: asyncio.get_event_loop().create_task( self.a_trigger_tx(symbol, quantity=None, price=None, side='sell', quantity_on_hand=quantity))
from tensortrade.oms.services.execution.simulated import execute_order from tensortrade.agents import DQNAgent import warnings warnings.filterwarnings("ignore", category=RuntimeWarning) load_dotenv() EMAIL = os.getenv('EMAIL') PASSWORD = os.getenv('PASSWORD') login = r.login(EMAIL, PASSWORD) interval = '5minute' span = 'day' btc_historicals = robin_stocks.get_crypto_historicals('DOGE', interval, span) price_data = robin_stocks.crypto.get_crypto_quote('DOGE') btc_data = [] for key in btc_historicals: data = { 'date': float(key['begins_at'].replace('T', '').replace('Z', '').replace( ':', '').replace('-', '')), 'open': float(key['open_price']), 'high': float(key['high_price']), 'low': float(key['low_price']), 'close':