def entry_market_order(self, side, size): if self.ac.order_side == '': self.ac.update_order(side, 0, 0, size, '', 10, '') ltp = TickData.get_ltp() res, size, price, order_id = Trade.market_order_wait_till_execution3( side, size) if res == 0: print(side + ' entry market order has been executed.' + 'price=' + str(price) + ', size=' + str(size)) self.ac.update_holding(side, price, size, order_id) self.ac.sync_position_order() self.ac.calc_collateral_change() self.ac.calc_pl(TickData.get_ltp()) self.ac.add_order_exec_price_gap(price, ltp, side) print( 'holding_side={},holding_price={},holding_size={},total_pl={},collateral={},collateral_change={},realized_pl={}' .format(self.ac.holding_side, self.ac.holding_price, self.ac.holding_size, self.ac.total_pl, self.ac.collateral, self.ac.collateral_change, self.ac.realized_pl)) LogMaster.add_log( 'Market order entry has been executed. ' + ' side=' + side + ' size=' + str(size) + ' price=' + str(price), self.prediction[0], self.ac) else: LogMaster.add_log( 'Market order has been failed.' + ' side=' + side + ' ' + str(size), self.prediction[0], self.ac) print('market order failed!') self.ac.initialize_order() else: print('Entry market order - order is already exitst!') LogMaster.add_log('Entry market order - order is already exitst!', self.prediction[0], self.ac)
def entry_price_tracing_order(self, side, size): ltp = TickData.get_ltp() res, order_sizes, price, order_ids, total_executed = Trade.price_tracing_order( side, size) # round(sum(exec_size), 2), ave_p, order_id if res == 0: print(side + ' entry price tracing order has been executed.' + 'price=' + str(price) + ', size=' + str(total_executed)) self.ac.add_orders(order_ids, order_sizes) self.ac.add_order_exec_price_gap(price, ltp, side) self.ac.calc_pl(side, price, total_executed) print( 'holding_side={},holding_price={},holding_size={},total_pl={},collateral={},collateral_change={},realized_pl={}' .format(self.ac.holding_side, self.ac.holding_price, self.ac.holding_size, self.ac.total_pl, self.ac.collateral, self.ac.collateral_change, self.ac.realized_pl)) LogMaster.add_log( 'Price tracing order entry has been executed. ' + ' side=' + side + ' size=' + str(size) + ' price=' + str(price), self.prediction, self.ac) else: LogMaster.add_log( 'Limit order has been failed.' + ' side=' + side + ' ' + str(total_executed), self.prediction, self.ac) print('etnry price tracing order failed!')
def exit_order(self): if self.ac.holding_side != '': print('quick exit order') side = 'buy' if self.ac.holding_side == 'sell' else 'sell' ltp = TickData.get_ltp() res, order_sizes, price, order_ids, total_executed = Trade.price_tracing_order( side, self.ac.holding_size ) #return 0, round(sum(exec_size), 2), ave_p, order_id if res == 0: print(side + ' exit price tracing order has been executed.' + 'price=' + str(price) + ', size=' + str(total_executed)) self.ac.add_orders(order_ids, order_sizes) self.ac.add_order_exec_price_gap(price, ltp, side) self.ac.calc_pl(side, price, total_executed) LogMaster.add_log('exit order completed!', self.prediction, self.ac) return 0 else: print(side + ' exit price tracing order has been failed.' + 'price=' + str(price) + ', size=' + str(total_executed)) self.ac.add_orders(order_ids, order_sizes) self.ac.add_order_exec_price_gap(price, ltp, side) self.ac.calc_pl(side, price, total_executed) LogMaster.add_log('exit order failed!', self.prediction, self.ac) return -1
def check_and_do_lc(self): if self.ac.holding_side != '': if self.ac.holding_side == 'buy' and TickData.get_ltp( ) - self.ac.holding_price <= -self.ls: print('hit loss cut kijun') LogMaster.add_log('hit loss cut kijun', self.prediction, self.ac) LineNotification.send_error('hit loss cut kijun') self.flg_loss_cut = True self.exit_order() self.cancel_pt_order() elif self.ac.holding_side == 'sell' and self.ac.holding_price - TickData.get_ltp( ) <= -self.ls: print('hit loss cut kijun') LogMaster.add_log('hit loss cut kijun', self.prediction, self.ac) LineNotification.send_error('hit loss cut kijun') self.flg_loss_cut = True self.exit_order() self.cancel_pt_order()
def get_current_asset(cls): try: cls.num_private_access += 1 res = cls.bf.fetch_balance() except Exception as e: print('error i get_current_asset ' + e) LogMaster.add_log('action_message - Trade-get current asset error! ' + str(e),0,None) LineNotification.send_error('action_message - Trade-get current asset error! ' + str(e)) if cls.check_exception(e) == 'ok': pass finally: return res['total']['BTC'] * TickData.get_ltp() + res['total']['JPY']
def calc_opt_size(self): collateral = Trade.get_collateral()['collateral'] if TickData.get_1m_std() > 10000: multiplier = 0.5 print('changed opt size multiplier to 0.5') LogMaster.add_log( 'action_message - changed opt size multiplier to 0.5', self.prediction[0], self.ac) LineNotification.send_error('changed opt size multiplier to 0.5') else: multiplier = 1.5 size = round((multiplier * collateral * self.margin_rate) / TickData.get_ltp() * 1.0 / self.leverage, 2) return size
def __update_ohlc( self): #should download ohlc soon after when it finalized if self.last_ohlc_min < datetime.now( self.JST).minute or (self.last_ohlc_min == 59 and datetime.now(self.JST).minute == 0): flg = True num_conti = 0 num_max_trial = 10 time.sleep(1) omd = TickData.get_ohlc() if omd is not None: for i in range(len(omd.unix_time)): if OneMinMarketData.ohlc.unix_time[-1] < omd.unix_time[i]: OneMinMarketData.ohlc.add_and_pop( omd.unix_time[i], omd.dt[i], omd.open[i], omd.high[i], omd.low[i], omd.close[i], omd.size[i]) flg = False LogMaster.add_log( 'updated ws ohlc at ' + str(datetime.now(self.JST)), self.prediction[0], self.ac) else: while flg: res, omd = CryptowatchDataGetter.get_data_after_specific_ut( OneMinMarketData.ohlc.unix_time[-1]) if res == 0 and omd is not None: if len(omd.unix_time) > 0: omd.cut_data( len(omd.unix_time )) #remove first data to exclude after ut for i in range(len(omd.unix_time)): if OneMinMarketData.ohlc.unix_time[ -1] < omd.unix_time[i]: OneMinMarketData.ohlc.add_and_pop( omd.unix_time[i], omd.dt[i], omd.open[i], omd.high[i], omd.low[i], omd.close[i], omd.size[i]) flg = False if flg == False: print('data download dt=' + str(datetime.now(self.JST))) LogMaster.add_log( 'updated ohlc at ' + str(datetime.now(self.JST)), self.prediction[0], self.ac) num_conti += 1 time.sleep(1) if num_conti >= num_max_trial: print('data can not be downloaded from cryptowatch.') LogMaster.add_log('ohlc download error', self.prediction[0], self.ac) break if flg == False: self.last_ohlc_min = datetime.now(self.JST).minute OneMinMarketData.update_for_bot() df = OneMinMarketData.generate_df_for_bot() pred_x = self.model.generate_bot_pred_data(df) #self.prediction = self.cbm.predict(Pool(pred_x)) self.prediction = self.model.prediction2(self.bst, pred_x) if len(self.prediction) > 1: print('prediction length error!') print(self.prediction) self.pred_side = str(int(self.prediction[0])).translate( str.maketrans({ '0': 'no', '1': 'buy', '2': 'sell', '3': 'both' })) self.ac.sync_position_order() self.ac.calc_pl(TickData.get_ltp()) print('dt={}, open={},high={},low={},close={}'.format( OneMinMarketData.ohlc.dt[-1], OneMinMarketData.ohlc.open[-1], OneMinMarketData.ohlc.high[-1], OneMinMarketData.ohlc.low[-1], OneMinMarketData.ohlc.close[-1])) print( 'total_pl={}, pl per min={}, collateral change={},num_trade={},win_rate={},prediction={},holding_side={},holding_price={},holding_size={},ltp={}' .format(self.ac.total_pl, self.ac.total_pl_per_min, self.ac.collateral_change, self.ac.num_trade, self.ac.win_rate, self.prediction[0], self.ac.holding_side, self.ac.holding_price, self.ac.holding_size, TickData.get_ltp())) print('private access per 300sec={}'.format( Trade.total_access_per_300s)) LogMaster.add_log( 'private access per 300sec = ' + str(Trade.total_access_per_300s), self.prediction[0], self.ac) LineNotification.send_notification( LogMaster.get_latest_performance())
def start_flyer_bot(self, num_term, window_term, pl_kijun, future_period, zero_three_exit_when_loss, zero_three_exit_when_profit): self.__bot_initializer(num_term, window_term, pl_kijun, future_period) self.start_time = time.time() self.fixed_order_size = 0.1 while SystemFlg.get_system_flg(): self.__check_system_maintenance(num_term, window_term, future_period, pl_kijun) self.__update_ohlc() if self.ac.holding_side == '' and self.ac.order_side == '': #no position no order if self.prediction[0] == 1 or self.prediction[0] == 2: self.entry_market_order(self.pred_side, self.fixed_order_size) elif self.ac.holding_side != '' and self.ac.order_side == '': #holding position and no order self.entry_pl_order() elif (self.ac.holding_side == 'buy' and (self.prediction[0] == 2)) or (self.ac.holding_side == 'sell' and (self.prediction[0] == 1)): # ポジションが判定と逆の時にexit, もしplがあればキャンセル。。 if self.ac.order_status != '': self.cancel_order() #最初にキャンセルしないとexit order出せない。 self.entry_market_order(self.pred_side, self.ac.holding_size) self.entry_market_order(self.pred_side, self.fixed_order_size) #elif self.ac.holding_side != '' and self.ac.order_side != '':#sleep until next ohlc update when prediction is same as # time.sleep(1) if self.ac.holding_side != '' and zero_three_exit_when_loss and ( self.prediction[0] == 0 or self.prediction[0] == 3): pl = self.ac.holding_price - TickData.get_ltp( ) if self.ac.holding_side == 'sell' else TickData.get_ltp( ) - self.ac.holding_price if pl < -500: if self.ac.order_side != '': self.cancel_order() self.entry_market_order( 'sell' if self.ac.holding_side == 'buy' else 'buy', self.ac.holding_size) print('exit zero_three_exit_loss') LineNotification.send_error('exit zero_three_exit_loss') if self.ac.holding_side != '' and zero_three_exit_when_profit and ( self.prediction[0] == 0 or self.prediction[0] == 3): pl = self.ac.holding_price - TickData.get_ltp( ) if self.ac.holding_side == 'sell' else TickData.get_ltp( ) - self.ac.holding_price if pl > 100: if self.ac.order_side != '': self.cancel_order() self.entry_market_order( 'sell' if self.ac.holding_side == 'buy' else 'buy', self.ac.holding_size) print('exit zero_three_exit_when_profit') LineNotification.send_error( 'exit zero_three_exit_when_profit') if self.ac.order_side != '' and abs(self.ac.order_price - TickData.get_ltp()) <= 5000: res = self.ac.check_execution() if res != '': LogMaster.add_log(res, self.prediction[0], self.ac) if Trade.flg_api_limit: time.sleep(60) print('Bot sleeping for 60sec due to API access limitation') else: time.sleep(0.1)
def calc_holding_pnl(self): if self.holding_side != '': self.open_pnl = (TickData.get_ltp() - self.holding_price) * self.holding_size if self.holding_side == 'buy' else (self.holding_price - TickData.get_ltp()) * self.holding_size self.open_pnl = int(self.open_pnl)
def __update_ohlc( self): #should download ohlc soon after when it finalized if self.last_ohlc_min < datetime.now( self.JST).minute or (self.last_ohlc_min == 59 and datetime.now(self.JST).minute == 0): flg = True self.flg_loss_cut = False num_conti = 0 num_max_trial = 10 time.sleep(1) if TickData.ws_down_flg == False: omd = TickData.get_ohlc() if omd is not None: for i in range(len(omd.unix_time)): if OneMinMarketData.ohlc.unix_time[-1] < omd.unix_time[ i]: OneMinMarketData.ohlc.add_and_pop( omd.unix_time[i], omd.dt[i], omd.open[i], omd.high[i], omd.low[i], omd.close[i], omd.size[i]) flg = False LogMaster.add_log( 'updated ws ohlc at ' + str(datetime.now(self.JST)), self.prediction, self.ac) else: while flg: res, omd = CryptowatchDataGetter.get_data_after_specific_ut( OneMinMarketData.ohlc.unix_time[-1]) if res == 0 and omd is not None: if len(omd.unix_time) > 0: omd.cut_data( len(omd.unix_time) ) #remove first data to exclude after ut for i in range(len(omd.unix_time)): if OneMinMarketData.ohlc.unix_time[ -1] < omd.unix_time[i]: OneMinMarketData.ohlc.add_and_pop( omd.unix_time[i], omd.dt[i], omd.open[i], omd.high[i], omd.low[i], omd.close[i], omd.size[i]) flg = False if flg == False: print('data download dt=' + str(datetime.now(self.JST))) LogMaster.add_log( 'updated ohlc at ' + str(datetime.now(self.JST)), self.prediction, self.ac) num_conti += 1 time.sleep(1) if num_conti >= num_max_trial: print( 'data can not be downloaded from cryptowatch.') LogMaster.add_log('ohlc download error', self.prediction, self.ac) break else: TickData.ws_down_flg = False self.__overwrite_one_min_data(self.num_term, self.window_term) LogMaster.add_log('overwrite one min data', self.prediction, self.ac) print('overwrite one min data') LineNotification.send_error('overwrite one min data') if flg == False: self.last_ohlc_min = datetime.now(self.JST).minute OneMinMarketData.update_for_bot() df = OneMinMarketData.generate_df_for_bot() pred_x = self.lgb.generate_bsp_data_for_bot(df) self.prediction = self.lgb.prediction(self.model_buy, self.model_sell, pred_x, self.upper_kijun, self.lower_kijun) print('prediction=', self.prediction) self.pred_side = { 0: 'no', 1: 'buy', -1: 'sell' }[self.prediction] #self.ac.sync_position_order() self.ac.calc_holding_pnl() print('dt={}, open={},high={},low={},close={}'.format( OneMinMarketData.ohlc.dt[-1], OneMinMarketData.ohlc.open[-1], OneMinMarketData.ohlc.high[-1], OneMinMarketData.ohlc.low[-1], OneMinMarketData.ohlc.close[-1])) print( 'total_pl={}, pl per min={}, num_trade={},win_rate={},prediction={},holding_side={},holding_price={},holding_size={},ltp={}' .format(self.ac.total_pl, self.ac.total_pl_per_min, self.ac.num_trade, self.ac.win_rate, self.prediction, self.ac.holding_side, self.ac.holding_price, self.ac.holding_size, TickData.get_ltp())) print('private access per 300sec={}'.format( Trade.total_access_per_300s)) LogMaster.add_log( 'private access per 300sec = ' + str(Trade.total_access_per_300s), self.prediction, self.ac) LineNotification.send_notification( LogMaster.get_latest_performance()) while datetime.now().second >= 59: time.sleep(0.1)
async def __add_log(cls, log_message, prediction, ac): jst = pytz.timezone('Asia/Tokyo') d = '' if ac is not None: d = { 'dt': datetime.now(jst), 'message': log_message, 'prediction': prediction, 'ltp': TickData.get_ltp(), 'posi_side': ac.holding_side, 'posi_price': ac.holding_price, 'posi_size': ac.holding_size, 'pt_order_side': ac.pt_side, 'pt_order_price': ac.pt_price, 'pt_order_outstanding_size': ac.pt_outstanding_size, 'pt_order_id': ac.pt_order_id, 'total_pl': ac.total_pl, 'total_pl_per_min': ac.total_pl_per_min, 'num_trade': ac.num_trade, 'win_rate': ac.win_rate, 'execution gap': sum(ac.order_exec_price_gap) / float(len(ac.order_exec_price_gap)) } cls.latest_pl_log = d else: d = { 'dt': datetime.now(jst), 'message': log_message, 'prediction': prediction, 'ltp': TickData.get_ltp(), 'posi_side': '', 'posi_price': 0, 'posi_size': 0, 'pt_order_side': '', 'pt_order_price': 0, 'pt_order_outstanding_size': 0, 'pt_order_id': '', 'total_pl': 0, 'total_pl_per_min': 0, 'num_trade': 0, 'win_rate': 0, 'execution gap': 0 } with cls.lock: cls.log_list.append(d) if len(cls.log_list) > 1000: cls.log_list.pop(0) await cls.__add_log_to_csv()