def test_create_OHLCV(self): market: Market = MarketFactory() timeframe: Timeframes = Timeframes.HOUR_1 test_candel: List[float] = [ 1504541580000, # UTC timestamp in milliseconds, integer 4235.4, # (O)pen price, float 4240.6, # (H)ighest price, float 4230.0, # (L)owest price, float 4230.7, # (C)losing price, float 37.72941911, # (V)olume (in terms of the base currency), float ] ohlcv: OHLCV = OHLCV.create_OHLCV(candle=test_candel, timeframe=timeframe, market=market) assert isinstance(ohlcv.pk, int) # check if object was saved to db assert ohlcv.market == market assert ohlcv.timeframe == timeframe assert ohlcv.timestamp == datetime(year=2017, month=9, day=4, hour=16, minute=13, tzinfo=pytz.UTC) assert ohlcv.open_price == Decimal(test_candel[1]) assert ohlcv.highest_price == Decimal(test_candel[2]) assert ohlcv.lowest_price == Decimal(test_candel[3]) assert ohlcv.closing_price == Decimal(test_candel[4]) assert ohlcv.volume == Decimal(test_candel[5])
def test_normal_update(self): buy_order: Order = BuyOrderFactory() sell_order: Order = SellOrderFactory() candle: OHLCV = OHLCV( market=buy_order.bot.market, timeframe=Timeframes.MONTH_1, timestamp=timezone.now(), open_price=Decimal(8.3), highest_price=Decimal(9.4), lowest_price=Decimal(7.5), closing_price=Decimal(8), volume=Decimal(100), ) run_wave_rider(candle=candle, test=True) buy_order_reload: Order = Order.objects.get(pk=buy_order.pk) sell_order_reload: Order = Order.objects.get(pk=sell_order.pk) assert buy_order_reload.next_order is not None assert sell_order_reload.next_order is not None Saving.objects.get(order=sell_order) assert Saving.objects.all().count() == 2
def handle(self, *args, **options): bot: Bot = Bot.objects.get(pk=options["bot_id"]) exchange: Exchange = bot.account.get_account_client() candles: List[List[float]] = exchange.fetch_ohlcv( symbol=bot.market.symbol, timeframe=bot.timeframe, limit=1, ) candle: OHLCV = OHLCV.get_OHLCV( candle=candles[0], timeframe=bot.timeframe, market=bot.market, ) order: Order if options["sell_order"]: order = create_order( amount=Decimal(options["amount"]), price=candle.highest_price, side=Order.Side.SIDE_SELL, bot=bot, ) else: order = create_order( amount=Decimal(options["amount"]), price=candle.lowest_price, side=Order.Side.SIDE_BUY, bot=bot, ) order.save()
def test_last_candle(self): market: Market = MarketFactory() timeframe: Timeframes = Timeframes.MINUTE_1 # test without any candle assert OHLCV.last_candle(timeframe=timeframe, market=market) is None # test with 1 candles OHLCV.create_OHLCV(candle=[0, 0, 0, 0, 0, 0], timeframe=timeframe, market=market) last_candle_1: Optional[OHLCV] = OHLCV.last_candle(timeframe=timeframe, market=market) assert last_candle_1 is not None assert last_candle_1.timestamp == datetime(year=1970, month=1, day=1, tzinfo=pytz.UTC) # test with 2 candles OHLCV.create_OHLCV(candle=[1504541580000, 0, 0, 0, 0, 0], timeframe=timeframe, market=market) last_candle_2: Optional[OHLCV] = OHLCV.last_candle(timeframe=timeframe, market=market) assert last_candle_2 is not None assert last_candle_2.timestamp == datetime(year=2017, month=9, day=4, hour=16, minute=13, tzinfo=pytz.UTC)
def test_update_new_candles(self): market: Market = MarketFactory() # update market with timeframe of 1 month OHLCV.update_new_candles(timeframe=Timeframes.MONTH_1, market=MarketFactory()) assert (OHLCV.objects.filter(timeframe=Timeframes.MONTH_1, market=market).count() > 20) # update 550 candles exchange: Exchange = get_client(exchange_id=market.exchange) exchange_time: int = exchange.milliseconds() OHLCV.create_OHLCV( candle=[exchange_time - 550 * 1000 * 60, 0, 0, 0, 0, 0], timeframe=Timeframes.MINUTE_1, market=market, ) OHLCV.update_new_candles(timeframe=Timeframes.MINUTE_1, market=MarketFactory()) candles_amount: int = OHLCV.objects.filter( timeframe=Timeframes.MINUTE_1, market=market).count() assert candles_amount >= 550 assert candles_amount <= 553
def run_wave_rider(candle: Optional[OHLCV] = None, test: bool = False): order: Order for order in Order.objects.filter( next_order=None, status=Order.Status.CLOSED, bot__trade_mode=Bot.TradeMode.WAVE_RIDER, ): # todo test add exeception if not order.bot.market: raise NoMarket("Bot has no market!") if not order.bot.timeframe: raise NoTimeFrame("Bot has no time frame!") if not candle: exchange: Exchange = order.bot.account.get_account_client() candles: List[List[float]] while True: try: candles = exchange.fetch_ohlcv( symbol=order.bot.market.symbol, timeframe=order.bot.timeframe, limit=1, ) break except (RequestTimeout, ExchangeNotAvailable): sleep(30) candle = OHLCV.get_OHLCV( candle=candles[0], timeframe=order.bot.timeframe, market=order.bot.market, ) if candle: getcontext().prec = 8 getcontext().rounding = ROUND_DOWN saving_amount: Decimal = Decimal(0) retrade_amount: Decimal if order.side == Order.Side.SIDE_BUY: retrade_amount = order.get_retrade_amount( price=candle.highest_price) else: retrade_amount = order.get_retrade_amount( price=candle.lowest_price) limits_amount_min: Decimal = order.bot.market.limits_amount_min if retrade_amount < limits_amount_min: if order.side == Order.Side.SIDE_BUY: Saving.objects.create( order=order, bot=order.bot, amount=order.amount * order.price, currency=order.bot.market.quote, ) else: Saving.objects.create( order=order, bot=order.bot, amount=order.amount, currency=order.bot.market.base, ) order.bot.active = False order.status = Order.Status.NOT_MIN_NOTIONAL order.bot.save() order.save() else: # todo add exceptions -> https://github.com/ccxt/ccxt/blob/master/python/ccxt/binance.py try: if order.side == Order.Side.SIDE_BUY: while True: try: order.next_order = create_order( amount=retrade_amount, price=candle.highest_price, side=Order.Side.SIDE_SELL, bot=order.bot, market=order.bot.market, isTestOrder=test, ) break except (RequestTimeout, ExchangeNotAvailable): sleep(30) saving_amount = (order.amount - retrade_amount) * order.price if saving_amount: Saving.objects.create( order=order, bot=order.bot, amount=saving_amount, currency=order.bot.market.quote, ) else: while True: try: order.next_order = create_order( amount=retrade_amount, price=candle.lowest_price, side=Order.Side.SIDE_BUY, bot=order.bot, market=order.bot.market, isTestOrder=test, ) break except (RequestTimeout, ExchangeNotAvailable): sleep(30) saving_amount = order.amount - retrade_amount if saving_amount: Saving.objects.create( order=order, bot=order.bot, amount=saving_amount, currency=order.bot.market.base, ) except InsufficientFunds as e: logger.info("create retrade error for {} with {}".format( order.__str__(), e)) OrderErrorLog.objects.create( order=order, error_type=OrderErrorLog.ErrorTypes.Insufficient_Funds, error_message=e, ) continue except InvalidOrder as e: logger.info("create retrade error for {} with {}".format( order.__str__(), e)) OrderErrorLog.objects.create( order=order, error_type=OrderErrorLog.ErrorTypes.InvalidOrder, error_message=e, ) continue order.save() logger.info("create retrade {}".format(order.__str__()))
def handle(self, *args, **options): OHLCV.update_new_candles_all_markets(timeframe=options["timeframe"])