def handle_data(self, data, ctx): new_orders = [] quantity = .05 price = data.get('close', self.asset.symbol, ctx.exchange.id) current_time = data.get('utc') if random.random() > 0.5: order = order_manager.build_limit_buy_order( balance=ctx.record.portfolio.balance, exchange=ctx.exchange, asset=self.asset, quantity=quantity, price=price, current_time=current_time) new_orders.append(order) elif ctx.record.balance.get( self.asset.base)[BalanceType.FREE] > quantity: order = order_manager.build_market_sell_order( balance=ctx.record.portfolio.balance, exchange=ctx.exchange, asset=self.asset, quantity=quantity, current_time=current_time) new_orders.append(order) # Optionally cancel pending orders (LIVE trading) #pending_orders = ctx.exchange.fetch_open_orders(asset) cancel_ids = [] # Add Metrics and OHLCV to Record self.update_metric('SMA', 5.0, ctx) self.update_metric('RSI', 10.0, ctx) self.update_ohlcv(data, ctx) print(current_time) self.log_all(new_orders, data, ctx, current_time) return {'new_orders': new_orders, 'cancel_ids': cancel_ids}
def test_new_long_position_buy(self, portfolio, paperexchange, asset): quantity = 1.0 price = 10000.0 time = paperexchange.data_provider.get_time() print("START TIME = {}".format(time)) buy_order = build_limit_buy_order(portfolio.balance, paperexchange, asset, quantity, price, time) updated_orders = process_orders(paperexchange, portfolio.balance, [buy_order]) # Pre portfolio update: assert portfolio.cash == 20000 assert portfolio.total_value == 20000 latest_prices = {asset.symbol: 10000} print("updated_order trade time {}".format( updated_orders[0].trades[0].trade_time)) portfolio.update(time, updated_orders, latest_prices) portfolio.update_performance( time, time + paperexchange.data_provider.feed.timeframe.delta) assert portfolio.cash == 10000 assert portfolio.positions_value == 10000 # cash + positions_value = total value assert portfolio.total_value == 20000 assert portfolio.positions[0].cost_price == 10000 assert portfolio.positions[0].market_value == 10000 assert portfolio.perf.pnl == 0.0
def test_update_with_failed_order_buy(self, balance, paperexchange, asset): # resetting the balance balance = deepcopy(balance) balance.update(coins.BTC, 10, 0.0) # Setting quote funds to a Created order state balance.update(coins.USDT, 9, 1) assert balance.get(coins.BTC)[BalanceType.TOTAL] == 10.0 assert balance.get(coins.USDT)[BalanceType.TOTAL] == 10.0 quantity = 1.0 price = 1.0 start_time = paperexchange.data_provider.get_time() order = build_limit_buy_order(balance, paperexchange, asset, quantity, price, start_time) # Updating the order status to failed order.status = OrderStatus.FAILED balance.update_with_failed_order(order) # No change to BTC on a 0 trade failed order assert balance.get(coins.BTC)[BalanceType.FREE] == 10.0 assert balance.get(coins.BTC)[BalanceType.TOTAL] == 10.0 assert balance.get(coins.BTC)[BalanceType.USED] == 0.0 # Quote funds move back to Free from used assert balance.get(coins.USDT)[BalanceType.FREE] == 10.0 assert balance.get(coins.USDT)[BalanceType.USED] == 0.0 assert balance.get(coins.USDT)[BalanceType.TOTAL] == 10.0
def test_insufficient_balance(self, paperexchange, asset, balance): quantity = 1.0 price = 11000.0 start_time = paperexchange.data_provider.get_time() buy_order = om.build_limit_buy_order(balance, paperexchange, asset, quantity, price, start_time) assert buy_order.status == OrderStatus.FAILED
def test_get_created_order(self, paperexchange, asset, balance): quantity = 1.0 price = 10000.0 start_time = paperexchange.data_provider.get_time() order = om.build_limit_buy_order(balance, paperexchange, asset, quantity, price, start_time) assert balance.get(coins.USDT)[BalanceType.TOTAL] == 20000 assert balance.get(coins.BTC)[BalanceType.TOTAL] == 0.0 assert om.get_created_orders([order]) == [order]
def test_order_manager(self, paperexchange, asset, balance): quantity = 1.0 price = 10000.0 start_time = paperexchange.data_provider.get_time() buy_order = om.build_limit_buy_order(balance, paperexchange, asset, quantity, price, start_time) assert balance.get(coins.USDT)[BalanceType.TOTAL] == 20000 assert balance.get(coins.BTC)[BalanceType.TOTAL] == 0.0 updated_orders = om.process_orders(paperexchange, balance, [buy_order]) assert balance.get(coins.USDT)[BalanceType.TOTAL] == 20000 assert balance.get(coins.USDT)[BalanceType.FREE] == 10000 assert balance.get(coins.USDT)[BalanceType.USED] == 10000 assert balance.get(coins.BTC)[BalanceType.TOTAL] == 0.0 print("updated orders: ", updated_orders)
def test_existing_long_position_buy(self, portfolio, paperexchange, asset): quantity = 1.0 price = 9000 time = paperexchange.data_provider.get_time() buy_order = build_limit_buy_order(portfolio.balance, paperexchange, asset, quantity, price, time) updated_orders = process_orders(paperexchange, portfolio.balance, [buy_order]) latest_prices = {asset.symbol: 9000} portfolio.update(time, updated_orders, latest_prices) portfolio.update_performance( time, time + paperexchange.data_provider.feed.timeframe.delta) assert portfolio.cash == 1000 assert portfolio.positions_value == 18000 # cash + positions_value == total_value assert portfolio.total_value == 19000 assert portfolio.positions[0].cost_price == 9500 assert portfolio.positions[0].market_value == 18000 assert portfolio.positions[0].cost_value == 19000 # position.market_value - position.cost_value = pnl assert portfolio.perf.pnl == -1000 # price went down
def test_update_with_created_order_buy(self, balance, paperexchange, asset): balance = deepcopy(balance) balance.update(coins.BTC, 10, 0.0) balance.update(coins.USDT, 10, 0.0) assert balance.get(coins.BTC)[BalanceType.TOTAL] == 10.0 assert balance.get(coins.USDT)[BalanceType.TOTAL] == 10.0 quantity = 1.0 price = 1.0 start_time = paperexchange.data_provider.get_time() order = build_limit_buy_order(balance, paperexchange, asset, quantity, price, start_time) balance.update_with_created_order(order) # No change to BTC on created buy order assert balance.get(coins.BTC)[BalanceType.FREE] == 10.0 assert balance.get(coins.BTC)[BalanceType.TOTAL] == 10.0 assert balance.get(coins.BTC)[BalanceType.USED] == 0.0 # 1 USDT FREE balance should move into USED assert balance.get(coins.USDT)[BalanceType.FREE] == 9.0 assert balance.get(coins.USDT)[BalanceType.USED] == 1.0 assert balance.get(coins.USDT)[BalanceType.TOTAL] == 10.0