def get_total_profit_for_pair(symbol): buy_prices = Trade.select(Trade.price).where(Trade.symbol == symbol, Trade.side == 'BUY').dicts() sell_prices = Trade.select(Trade.price).where( Trade.symbol == symbol, Trade.side == 'SELL').dicts() if len(buy_prices) <= 0 or len(sell_prices) <= 0: return buy_prices = list(price['price'] for price in buy_prices) sell_prices = list(price['price'] for price in sell_prices) buy_prices_average = sum(buy_prices) / len(buy_prices) sell_prices_average = sum(sell_prices) / len(sell_prices) price_difference = sell_prices_average / buy_prices_average buy_qty = Trade.select(Trade.quantity).where(Trade.symbol == symbol, Trade.side == 'BUY').dicts() sell_qty = Trade.select(Trade.quantity).where( Trade.symbol == symbol, Trade.side == 'SELL').dicts() if len(buy_qty) <= 0 or len(sell_qty) <= 0: return buy_qty = list(qty['quantity'] for qty in buy_qty) sell_qty = list(qty['quantity'] for qty in sell_qty) buy_qty_sum = sum(buy_qty) sell_qty_sum = sum(sell_qty) executed_qty = min(buy_qty_sum, sell_qty_sum) profit = (price_difference - 1) * executed_qty return profit
def get_all_trades_by_user(username): """This method return a list of all trades that the user is involved with.""" trades = [] as_primary = Trade.select().where(Trade.user_one == username) as_secondary = Trade.select().where(Trade.user_two == username) for t in as_primary: trades.append(t) for t in as_secondary: trades.append(t) return trades
def __init__(self, tickers, test=False): self.test = test self.tickers = tickers self.ticker = self.tickers[0] self.start_ticker = self.tickers[-1] (self.diff, self.diff_pct) = calc_diff( self.start_ticker.price, self.ticker.price) self.buys = Trade.select().where(Trade.test == self.test, Trade.currency == self.ticker.currency, Trade.type == 'buy').count() self.sells = Trade.select().where(Trade.test == self.test, Trade.currency == self.ticker.currency, Trade.type == 'sell').count()
def start(): # remove all previous test trades test_trades = Trade.select().where(Trade.test == True) for test_trade in test_trades: test_trade.delete_instance() for symbol in SYMBOLS: tickers = reverse(Ticker.select().where( Ticker.currency == symbol, Ticker.epoch > 1614766446).order_by(-Ticker.epoch)) for i in range(len(tickers)): last_30_tickers = reverse(get_last_x_items(tickers, i, 30)) if len(last_30_tickers) < 30: continue strategy = Strategy(last_30_tickers, test=True) if strategy.when_buy(): test_buy(symbol, strategy.ticker) if strategy.when_sell(): test_sell(symbol, strategy.ticker) wallet(test=True)
def when_sell(self): if len(self.tickers) != 30: return False if (self.buys - self.sells) == 0: return False # make sure we dont sell with loss last_buy = Trade.select().where(Trade.test == self.test, Trade.currency == self.ticker.currency, Trade.type == 'buy').order_by(Trade.date.desc()).get() (profit, profit_pct) = calc_diff(last_buy.price, self.ticker.price) self.profit_pct = profit_pct self.profit = (last_buy.quantity * self.ticker.price) - \ (last_buy.quantity * last_buy.price) # sell at loss when -10% # if profit_pct <= -10: # return True if last_buy.price >= self.ticker.price or profit_pct <= 5: return False if profit_pct >= 5: return True return self.diff_pct >= 2.75
def get_base_wallet_value(test=False): trades = Trade.select().where(Trade.test == test).order_by( Trade.date.asc()) buy_count = 0 sell_count = 0 total_bought = 0 total_sold = 0 value_invested = 0 # total amount needed to make these trades (capital needed) highest_amount_entered = 0 for trade in trades: order_amount = trade.quantity * trade.price if trade.type == 'buy': buy_count += 1 total_bought += order_amount value_invested += order_amount if trade.type == 'sell': sell_count += 1 total_sold += order_amount value_invested -= order_amount if value_invested > highest_amount_entered: highest_amount_entered = value_invested print('BUYS: {} \t => {}{}'.format(buy_count, total_bought, CURRENCY)) print('SELLS: {} \t => {}{}'.format(sell_count, total_sold, CURRENCY)) print('INPUT \t\t => {}{}'.format(highest_amount_entered, CURRENCY)) return (total_bought, total_sold, highest_amount_entered)
def get_quantity(currency, test=False): trades = Trade.select().where(Trade.currency == currency, Trade.test == test).order_by(Trade.epoch) quantity = 0 for trade in trades: if trade.type == 'buy': quantity += trade.quantity if trade.type == 'sell': quantity -= trade.quantity return quantity
def get_currency_wallet_value(symbol, test=False): wallet = Trade.select().where(Trade.currency == symbol, Trade.test == test) quantity = 0 value = 0 for trade in wallet: if trade.type == 'buy': quantity += trade.quantity elif trade.type == 'sell': quantity -= trade.quantity value = quantity * trade.price return (quantity, value)
def calculate_profit(currency, test=False): trades = Trade.select().where(Trade.currency == currency, Trade.test == test).order_by(Trade.epoch) profit = 0 for i in range(len(trades)): if trades[i].type == 'sell': profit += trades[i].total if i + 1 != len(trades): if trades[i].type == 'buy': profit -= trades[i].total return profit
def get_balance(test=False): trades = Trade.select().where(Trade.test == test).order_by(Trade.epoch) value = MAX_INPUT for trade in trades: order_amount = trade.quantity * trade.price if trade.type == 'buy': value -= order_amount if trade.type == 'sell': value += order_amount return value
def get_total_profit(measure): pairs = list( set(list(pair['symbol'] for pair in Trade.select(Trade.symbol).dicts()))) measure_quantity = [] for pair in pairs: profit = get_total_profit_for_pair(pair) if profit is None: continue asset = split_symbol(pair)['base'] preferred_wallet_quantity = convert(asset, profit, PREF_WALL) # print(pair, '{0:.10f}'.format(profit), f'{asset} ', '{0:.10f}'.format(preferred_wallet_quantity), PREF_WALL) measure_quantity.append( convert(PREF_WALL, preferred_wallet_quantity, measure)) return sum(measure_quantity)
def get_total_fees_for_asset(fee_asset): fees = Trade.select(Trade.fee).where(Trade.fee_asset == fee_asset).dicts() return sum(list(fee['fee'] for fee in fees))
def get_trades(): return list(Trade.select().dicts())
def get_trades(ticker_code): trades = Trade.select().where(Trade.stock == ticker_code.upper()).order_by( Trade.last_date.desc()) return trades
def get_trades_as_secondary(username): """This method return a list of all trades that the passed user is a secondary.""" return Trade.select().where(Trade.user_two == username)
def get_trades_as_primary(username): """This method return a list of all trades that the passed user is a primary.""" return Trade.select().where(Trade.user_one == username)
def figure(symbol): # https://plotly.com/python/line-charts/ fig = go.Figure( layout={ 'yaxis': { 'title': 'PRICE axis' }, 'yaxis2': { 'title': 'DIFF axis', 'overlaying': 'y', 'side': 'right' } }) tickers = Ticker.select().where( Ticker.currency == symbol, Ticker.epoch > 1614809646).order_by(-Ticker.epoch) timestamps = [] prices = [] diffs = [] # for ticker in tickers: for i in range(len(tickers)): timestamps.append(tickers[i].datetime) prices.append(tickers[i].price) last_30_tickers = get_last_x_items(tickers, i, 30) if (len(last_30_tickers) == 30): (diff, diff_pct) = calc_diff(last_30_tickers[0].price, tickers[i].price) diffs.append(diff_pct) fig.add_trace( go.Scatter(x=timestamps, y=prices, name=symbol, line=dict(color='dodgerblue', width=4))) # fig.add_bar(x=timestamps, y=diffs, name='diffs', yaxis='y2', offsetgroup=1) # fig.add_trace(go.Scatter(x=timestamps, y=diffs, name=symbol, # line=dict(color='green', width=4))) trades = Trade.select().where(Trade.currency == symbol) buy_timestamps = [] buy_prices = [] sell_timestamps = [] sell_prices = [] for trade in trades: if trade.type == 'buy': buy_timestamps.append(trade.date) buy_prices.append(trade.price) if trade.type == 'sell': sell_timestamps.append(trade.date) sell_prices.append(trade.price) fig.add_trace( go.Scatter(x=buy_timestamps, y=buy_prices, mode='markers', line=dict(width=10, color='Green'), name='BUY')) fig.add_trace( go.Scatter(x=sell_timestamps, y=sell_prices, mode='markers', line=dict(width=10, color='Red'), name='SELL')) # Edit the layout fig.update_layout(title='{} Backtest results'.format(symbol), xaxis_title='Timestamp', yaxis_title='Price') fig.show() app = dash.Dash() app.layout = html.Div([dcc.Graph(figure=fig)]) # Turn off reloader if inside Jupyter app.run_server(debug=False, use_reloader=False)