def test_process_buy_true_prediction(): def patched_configure_poloniex(): polo = mock.Mock() polo.returnCompleteBalances.return_value = { config.get_pair_first_symbol(_pair): { 'available': 100.0 } } polo.buy.return_value = {'orderNumber': 777777} return polo patch1 = mock.patch('conf.config.DB_PATH', '.{}'.format(random.randint(10000, 90000))) patch2 = mock.patch('orders_engine_helpers.functions.configure_poloniex', patched_configure_poloniex) with patch1: with patch2: from orders_engine_helpers import process_buy from conf import database_setup as db with db.session_scope() as session: session.add( db.Transaction(pair=_pair, status=config.TransactionStatus.TO_ENQUEUE, ts=100)) session.add( db.Price(pair=_pair, buy=20, sell=10, avg=15, ts=100)) process_buy.process_buy(_pair)
def test_buy__order_cancel(): order_number = 1 def patched_configure_poloniex(): polo = mock.Mock() polo.returnCompleteBalances.return_value = { config.get_pair_first_symbol(_pair): { 'available': 100.0 }, config.get_pair_second_symbol(_pair): { 'available': 100.0 }, } polo.returnOpenOrders.return_value = [{ 'type': 'buy', 'orderNumber': order_number, 'rate': 1, 'amount': 1 }] polo.returnTradeHistory.return_value = [] # polo.moveOrder.return_value = [{'type': 'buy', 'orderNumber': order_number_3, 'rate': 1, 'amount': 1}] return polo patch1 = mock.patch('conf.config.DB_PATH', '.{}'.format(random.randint(10000, 90000))) patch2 = mock.patch('orders_engine_helpers.functions.configure_poloniex', patched_configure_poloniex) with patch1, patch2: from orders_engine_helpers import process_move_orders from conf import database_setup as db with db.session_scope() as session: session.add(db.Price( buy=200, sell=100, avg=150, pair=_pair, )) session.add( db.Transaction( id=order_number, ts=datetime.datetime.utcnow().timestamp() - config.DROP_BUY_ORDER_DELAY - 1, status=config.TransactionStatus.ON_STOP, type=config.TransactionType.BUY, amount=1, price=1, )) process_move_orders.move_orders(_pair) with db.session_scope() as session: transaction = session.query(db.Transaction).first() assert transaction.status == config.TransactionStatus.CANCELLED
def test_sell__order_cancel(): order_number = 1 def patched_configure_poloniex(): polo = mock.Mock() polo.returnCompleteBalances.return_value = { config.get_pair_first_symbol(_pair): { 'available': 100.0 }, config.get_pair_second_symbol(_pair): { 'available': 100.0 }, } polo.returnOpenOrders.return_value = [{ 'type': 'sell', 'orderNumber': order_number }] polo.returnTradeHistory.return_value = [] return polo patch1 = mock.patch('conf.config.DB_PATH', '.{}'.format(random.randint(10000, 90000))) patch2 = mock.patch('orders_engine_helpers.functions.configure_poloniex', patched_configure_poloniex) with patch1, patch2: from orders_engine_helpers import process_sell from conf import database_setup as db with db.session_scope() as session: session.add( db.Transaction( id=order_number, ts=datetime.datetime.utcnow().timestamp() - config.STOP_TIME - 1, )) process_sell.process_sell(_pair) with db.session_scope() as session: tr = session.query(db.Transaction).first() assert tr.status == config.TransactionStatus.ON_STOP
def test_sell__order_move(): order_number = 1 order_number2 = 2 sell_price = 100 buy_price = 200 def patched_configure_poloniex(): polo = mock.Mock() polo.returnCompleteBalances.return_value = { config.get_pair_first_symbol(_pair): { 'available': 100.0 }, config.get_pair_second_symbol(_pair): { 'available': 100.0 }, } polo.returnOpenOrders.return_value = [{ 'type': 'sell', 'orderNumber': order_number, 'rate': 1, 'amount': 1 }] polo.returnTradeHistory.return_value = [] polo.moveOrder.return_value = { 'type': 'sell', 'orderNumber': order_number2, 'rate': 1, 'amount': 1 } return polo patch1 = mock.patch('conf.config.DB_PATH', '.{}'.format(random.randint(10000, 90000))) patch2 = mock.patch('orders_engine_helpers.functions.configure_poloniex', patched_configure_poloniex) with patch1, patch2: from orders_engine_helpers import process_move_orders from conf import database_setup as db with db.session_scope() as session: session.add( db.Price( buy=buy_price, sell=sell_price, avg=None, pair=_pair, )) session.add( db.Transaction( id=order_number, ts=datetime.datetime.utcnow().timestamp() - config.DROP_BUY_ORDER_DELAY + 100, status=config.TransactionStatus.ON_STOP, type=config.TransactionType.SELL, amount=1, price=1, )) process_move_orders.move_orders(_pair) with db.session_scope() as session: transaction = session.query(db.Transaction).all() assert len(transaction) == 1 assert transaction[0].id == order_number2 assert transaction[ 0].price == buy_price / config.ORDERBOOK_FORCER_MOVE_PERCENT
def process_buy(pair): logging.info('START BUY PAIR %s', pair) with db.session_scope() as session: prediction_query = session.query(db.Transaction) prediction_query = prediction_query.filter(db.Transaction.pair == pair) prediction_query = prediction_query.filter( db.Transaction.status == config.TransactionStatus.TO_ENQUEUE) to_enqueue = prediction_query.all() balance = attrdict.AttrDict( polo.returnCompleteBalances()[config.get_pair_first_symbol(pair)]) logging.info(balance) balance.available = float(balance.available) session.add( db.Sensor(ts=int(time.time()) * 1000, value=balance.available, type=config.SensorType.BALANCE)) if not to_enqueue: logging.info('STOP BUY PAIR %s, BUY SKIP: NO PREDICTION', pair) telegram_log.online_log( 'BUY: no prediction for pair {} - skip buy'.format(pair)) return None to_enqueue = to_enqueue[0] # deleting old predictions prediction_query.delete() latest_order = functions._get_latest_order(pair) target_price = latest_order.sell * config.ORDERBOOK_FORCER_MOVE_PERCENT amount = config.ONE_BET / target_price if amount < config.MINIMAL_AMOUNT or amount > balance.available: logging.info('STOP BUY PAIR %s, BUY FAIL: NOT ENOUGH BALANCE', pair) telegram_log.online_log( 'BUY: prediction is True but not enought balance for pair {} - skip buy' .format(pair)) return False order_data = polo.buy(pair, target_price, amount) order_data = attrdict.AttrDict(order_data) telegram_log.online_log('BUY: {} - success'.format(pair)) telegram_log.online_log_important('BUY: Order {}'.format(order_data)) session.add( db.Transaction( id=order_data.orderNumber, ts=to_enqueue.ts, type=config.TransactionType.BUY, pair=pair, status=config.TransactionStatus.ENQUEUED, amount=amount, price=target_price, )) logging.info('STOP BUY PAIR %s, BUY SUCCESS', pair) return True
def process_sell(pair): # add stop statuses logging.info('START SELL PAIR %s', pair) with db.session_scope() as session: pair_orders = polo.returnOpenOrders(currencyPair=pair) for order_data in pair_orders: order_data = attrdict.AttrDict(order_data) if order_data.type == 'buy': continue order_data_query = session.query(db.Transaction).filter( db.Transaction.id == (order_data.orderNumber)) sql_order_data = order_data_query.all() if not sql_order_data: continue sql_order_data = sql_order_data[0] if sql_order_data.ts + config.STOP_TIME < datetime.datetime.utcnow( ).timestamp(): functions._update_status(order_data.orderNumber, config.TransactionStatus.ON_STOP) # reseiving done buy trades & generating new sell transactions trades = polo.returnTradeHistory(currencyPair=pair) old_sell_trades_ids = [i[0] for i in session.query(db.Trade.id).all()] new_trades = list( map( attrdict.AttrDict, filter( lambda tr: (tr['globalTradeID'] not in old_sell_trades_ids and tr['type'] == 'buy'), trades))) balance = attrdict.AttrDict(polo.returnCompleteBalances()[ config.get_pair_second_symbol(pair)]).available balance = float(balance) next_sell_amount = 0.0 for trade in new_trades: logging.exception('processing new trade for selling: %s', trade) trade.amount = float(trade.amount) trade.rate = float(trade.rate) can_sell_amount = balance target_price = trade.rate * config.STOP_PERCENT sell_amount = min(trade.amount + next_sell_amount, can_sell_amount) if sell_amount < config.MINIMAL_AMOUNT: next_sell_amount = sell_amount logging.exception( 'sell amount < minimal amount, skipping trade: %s', trade) continue next_sell_amount = 0 try: order_data = attrdict.AttrDict( polo.sell(pair, target_price, sell_amount)) except Exception as ex: session.add( db.Sensor(ts=int(time.time() * 1000), type=config.SensorType.ERROR, value=10)) logging.info('exception while trying to sell order: %s %s', trade, ex) continue session.add( db.Transaction( id=order_data.orderNumber, ts=datetime.datetime.utcnow().timestamp(), type=config.TransactionType.SELL, pair=pair, status=config.TransactionStatus.ENQUEUED, amount=sell_amount, price=target_price, )) balance -= sell_amount session.add( db.Trade(id=trade.globalTradeID, ts=datetime.datetime.utcnow().timestamp(), type=config.TradeType.BUY, status=config.TradeStatus.PROCESSED)) logging.info('STOP SELL PAIR %s', pair)
print('Too old price data') continue for row in data: if row.ts <= latest_ts - FIVE_MINS: result.append(row.avg) latest_ts -= FIVE_MINS result.reverse() prediction_data = upstream_signal.predict(result) logging.info('Prediction classes probability %s', prediction_data.class_proba) if prediction_data.buy: logging.info('Prediction for pair %s is UP!', pair) # deleting old predictions about this pair session.query(db.Transaction).filter( db.Transaction.status == config.TransactionStatus. TO_ENQUEUE).filter(db.Transaction.pair == pair).delete() # inserting new prediction session.add( db.Transaction( id=-1, ts=datetime.datetime.utcnow().timestamp(), type=config.TransactionType.BUY, status=config.TransactionStatus.TO_ENQUEUE, pair=pair, )) session.commit() else: logging.info('Prediction for pair %s is none', pair) time.sleep(config.PREDICT_DELAY)