def __check_bid_ask_diff(side, ori_bidask, diff_kijun): if side == 'buy': ask = TickData.get_ask_price() return False if ask - ori_bidask >= diff_kijun else True else: bid = TickData.get_bid_price() return False if ori_bidask - bid >= diff_kijun else True
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 market_order_wait_till_execution3(cls, side, total_size): size = [] price = [] max_wait = 10 num = 0 bid = TickData.get_bid_price() ask = TickData.get_ask_price() try: cls.num_private_access += 1 order_id = cls.bf.create_order( symbol='BTC/JPY', type='market', side=side, amount=total_size, params={'product_code': 'FX_BTC_JPY'}) except Exception as e: print('market order failed! ' + str(e)) LogMaster.add_log('market order failed! ' + str(e), None) LineNotification.send_error('market order failed! ' + str(e)) cls.check_exception(e) return -1, 0, 0, '' order_id = order_id['info']['child_order_acceptance_id'] print('waiting for market order execution...') start = time.time() while sum(size) < total_size: exe_data = TickData.get_exe_data()[-100:] if time.time() - start > max_wait: exe_data = cls.get_executions() exe_data = TickData.get_exe_data()[-100:] for exec in exe_data: if exec[side + "_child_order_acceptance_id"] == order_id: size.append(exec["size"]) price.append(exec["price"]) if time.time() - start > max_wait: print( 'can not complete Trade - check_and_wait_till_all_execution!' ) LogMaster.add_log( 'can not complete Trade - check_and_wait_till_all_execution!', None) LineNotification.send_error( 'can not complete Trade - check_and_wait_till_all_execution!' ) return -1, sum(size), round( sum(price[i] * size[i] for i in range(len(price))) / sum(size)), order_id num += 1 ave_p = round( sum(price[i] * size[i] for i in range(len(price))) / sum(size)) print('market order has been successfully executed.' + 'side=' + side + ', ave price=' + str(ave_p) + ', size=' + str(round(sum(size), 2))) sp = ask - ave_p if side == 'buy' else ave_p - bid print('market order spread loss/profit = ' + str(sp)) cls.spread_loss_profit += sp cls.spread_loss_profit_log.append(sp) return 0, round(sum(size), 2), ave_p, order_id
def __check_bid_ask_diff( side, ori_bidask, diff_kijun ): #True:diff is within diff_kijun, False:diff is larger than diff_kijun if side == 'buy': ask = TickData.get_ask_price() return False if ask - ori_bidask >= diff_kijun else True else: bid = TickData.get_bid_price() return False if ori_bidask - bid >= diff_kijun else True
def calc_opt_pl(self): if TickData.get_1m_std() > 10000: newpl = self.pl_kijun * math.log( (TickData.get_1m_std() / 100000)) + 5 print('changed opt pl kijun to ' + str(newpl)) LogMaster.add_log( 'action_message - changed opt pl kijun to ' + str(newpl), self.prediction[0], self.ac) LineNotification.send_error('changed opt pl kijun to ' + str(newpl)) return newpl else: return self.pl_kijun
def __check_system_maintenance(self, num_term, window_term): if (datetime.now(tz=self.JST).hour == 3 and datetime.now(tz=self.JST).minute >= 59): print('sleep waiting for system maintenance') #TickData.stop(30,30) LineNotification.send_error('sleep waiting for system maintenance') if self.ac.order_side != '': self.cancel_order() time.sleep(720) # wait for daily system maintenace TickData.initialize() CryptowatchDataGetter.get_and_add_to_csv() OneMinMarketData.initialize_for_bot(num_term, window_term) LineNotification.send_error('resumed from maintenance time sleep') print('resumed from maintenance time sleep')
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 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 opt_price_wait_till_execution(cls, side, total_size): exec_size = [] exec_price = [] max_wait = 2.1 loop_sec = 0.01 bid = TickData.get_bid_price() ask = TickData.get_ask_price() try: price = TickData.get_bid_price() if side =='buy' else TickData.get_ask_price() cls.num_private_access += 1 order_id = cls.bf.create_order( symbol='BTC/JPY', type='limit', side=side, price=price, amount=total_size, params={'product_code': 'FX_BTC_JPY', 'minute_to_expire': 1} # 期限切れまでの時間(分)(省略した場合は30日) ) except Exception as e: print('opt price order failed! ' + str(e)) LogMaster.add_log('opt price order failed! ' + str(e), 0, None) LineNotification.send_error('opt price order failed! ' + str(e)) cls.check_exception(e) return -1, 0, 0, '' order_id = order_id['info']['child_order_acceptance_id'] print('waiting for opt price order execution...') num = 0 ave_p = 0 while sum(exec_size) < total_size: executions = cls.get_executions() for exec in executions: if exec["child_order_acceptance_id"] == order_id: exec_size.append(exec["size"]) exec_price.append(exec["price"]) time.sleep(loop_sec) num += 1 if max_wait < loop_sec * num: cls.cancel_order(order_id) if sum(exec_size) > 0: ave_p = round(sum(exec_price[i] * exec_size[i] for i in range(len(exec_price))) / sum(exec_size)) print('opt price order has been failed.' + 'side=' + side + ', ave price=' + str(ave_p) + ', size=' + str(round(sum(exec_size), 2))) return -1, round(sum(exec_size), 2), ave_p, order_id ave_p = round(sum(exec_price[i] * exec_size[i] for i in range(len(exec_price))) / sum(exec_size)) print('opt price order has been successfully executed.' + 'side=' + side + ', ave price=' + str(ave_p) + ', size=' + str(round(sum(exec_size), 2))) return 0, round(sum(exec_size), 2), ave_p, order_id
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 __check_execution_ws(order_id): exec_size = [] exec_price = [] exe_data = TickData.get_exe_data()[-30:] for exec in exe_data: if exec[side + '_child_order_acceptance_id'] == order_id and exec[ 'id'] not in checked_exec_id: exec_size.append(exec['size']) exec_price.append(exec['price']) checked_exec_id.append(exec['id']) return exec_size, exec_price
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 account_thread(self): mid_check_flg = False #flg for 約30秒ごとに一回API経由で約定履歴・注文一覧 i = 0 while SystemFlg.get_system_flg(): if i > 10: i = 0 #30秒ごとに一回API経由で約定履歴を取得して、order idを確認 self.exec_data.add_executions(Trade.get_executions()) #30秒ごとに一回API経由で注文一覧を取得して、order id登録から1分経過したものをcancelとして処理 self.check_order_cancellation() self.exec_data.add_executions(TickData.get_latest_exec_data()) self.check_order_execution() i += 1 time.sleep(3)
def check_pt_order_exeution(self): executions = None if datetime.now().second >=57: executions = Trade.get_executions() else: executions = TickData.get_exe_data()[-30:] if self.pt_order_id != '': for i in range(len(executions)): if executions[i]['child_order_acceptance_id'] == self.pt_order_id and executions[i]['id'] not in self.pt_checked_exec_id: side = executions[i]['side'].ilower() price = executions[i]['price'] size = executions[i]['size'] self.pt_checked_exec_id.append(executions[i]['id']) self.executions_hist_log.append(executions[i]) self.calc_pl(executions[i]) self.update_holding(side, price, size) self.pt_outstanding_size -= size if self.pt_outstanding_size <= 0: print('pt order has been fully executed!') self.initialize_pt_order()
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)
TickData.get_ltp() * 1.0 / self.leverage, 2) return size def calc_opt_pl(self): if TickData.get_1m_std() > 10000: newpl = self.pl_kijun * math.log( (TickData.get_1m_std() / 100000)) + 5 print('changed opt pl kijun to ' + str(newpl)) LogMaster.add_log( 'action_message - changed opt pl kijun to ' + str(newpl), self.prediction[0], self.ac) LineNotification.send_error('changed opt pl kijun to ' + str(newpl)) return newpl else: return self.pl_kijun if __name__ == '__main__': SystemFlg.initialize() TickData.initialize(30, 30) Trade.initialize() LogMaster.initialize() LineNotification.initialize() fb = FlyerBot() fb.start_flyer_bot( 150, 2, 2500, 5, False, True ) #num_term, window_term, pl_kijun, future_period, zero_three_exit_when_loss, zero_three_exit_when_profit #'JRF20190526-142616-930215' #JRF20190526-143431-187560
if len(status) > 0: if status[0]['child_order_state'] == 'ACTIVE' or status[0][ 'child_order_state'] == 'COMPLETED': print('confirmed the order has been boarded') return status[0] n += 1 if n > 30: print('6 sec was passed but order boarding was not confirmed!') LineNotification.send_error( '6 sec was passed but order boarding was not confirmed!') time.sleep(0.2) if __name__ == '__main__': SystemFlg.initialize() TickData.initialize() time.sleep(5) LogMaster.initialize() Trade.initialize() s = time.time() oid = Trade.order('buy', 1000000, 0.01, 'limit', 1) print(Trade.get_orders()) Trade.cancel_order(oid) time.sleep(1) Trade.cancel_order(oid) #print(Trade.price_tracing_order('sell', 0.05)) print('done') #executions =Trade.get_executions() ##print(executions) #print(len(executions)) #print(time.time() - s)
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 opt_price_wait_till_execution2(cls, side, total_size): def __check_execution( order_id ): #should use only 1 time for final check to avoid double count of same exec data exec_size = [] exec_price = [] executions = cls.get_executions() for exec in executions: if exec['child_order_acceptance_id'] in order_id: exec_size.append(exec['size']) exec_price.append(exec['price']) return exec_size, exec_price checked_exec_id = [] def __check_execution_ws(order_id): exec_size = [] exec_price = [] exe_data = TickData.get_exe_data()[-30:] for exec in exe_data: if exec[side + '_child_order_acceptance_id'] == order_id and exec[ 'id'] not in checked_exec_id: exec_size.append(exec['size']) exec_price.append(exec['price']) checked_exec_id.append(exec['id']) return exec_size, exec_price def __calc_price_move(): executions = TickData.get_exe_data()[-3:] change = executions[-1]['price'] - executions[0]['price'] return change def __check_bid_ask_diff( side, ori_bidask, diff_kijun ): #True:diff is within diff_kijun, False:diff is larger than diff_kijun if side == 'buy': ask = TickData.get_ask_price() return False if ask - ori_bidask >= diff_kijun else True else: bid = TickData.get_bid_price() return False if ori_bidask - bid >= diff_kijun else True remaining_size = total_size order_id = '' exec_size = [] exec_price = [] s = time.time() while total_size > sum(exec_size) and remaining_size >= 0.01: exec_size = [] exec_price = [] change = __calc_price_move() entry_price = 0 if side == 'buy': if change > 0: entry_price = TickData.get_ask_price() else: entry_price = TickData.get_bid_price() + 1 if side == 'sell': if change > 0: entry_price = TickData.get_ask_price() - 1 else: entry_price = TickData.get_bid_price() try: cls.num_private_access += 1 order_id = cls.bf.create_order( symbol='BTC/JPY', type='limit', side=side, price=entry_price, amount=remaining_size, params={'product_code': 'FX_BTC_JPY'}) except Exception as e: print('market order failed! ' + str(e)) LogMaster.add_log('market order failed! ' + str(e), None) LineNotification.send_error('market order failed! ' + str(e)) cls.check_exception(e) return -1, 0, 0, '' time.sleep(1) while __check_bid_ask_diff(side, entry_price, 300) == True and remaining_size >= 0.01: esize, eprice = __check_execution_ws(order_id) exec_size.extend(esize) exec_price.extend(eprice) remaining_size = round(total_size - sum(exec_size), 2) time.sleep(1) completion_status = cls.cancel_and_wait_completion( order_id) #cancel order if price diff > 300 if len(completion_status) > 0: s, p = __check_execution(order_id) remaining_size -= s remaining_size = round(total_size - sum(exec_size), 2) ave_p = round( sum(exec_price[i] * exec_size[i] for i in range(len(exec_price))) / sum(exec_size)) print('opt price order has been successfully executed.' + 'time elapsed=' + str(time.time() - s) + 'side=' + side + ', ave price=' + str(ave_p) + ', size=' + str(round(sum(exec_size), 2))) return 0, round(sum(exec_size), 2), ave_p, order_id
def __calc_price_move(): executions = TickData.get_exe_data()[-3:] change = executions[-1]['price'] - executions[0]['price'] return change
def opt_entry_limit_order(cls, side, total_size): def __check_execution(order_id): exec_size = [] exec_price = [] executions = cls.get_executions() for exec in executions: if exec['child_order_acceptance_id'] in order_id: exec_size.append(exec['size']) exec_price.append(exec['price']) return exec_size, exec_price checked_exec_id = [] def __check_execution_ws(order_id): exec_size = [] exec_price = [] exe_data = TickData.get_exe_data()[-30:] for exec in exe_data: if exec[side + '_child_order_acceptance_id'] == order_id and exec[ 'id'] not in checked_exec_id: exec_size.append(exec['size']) exec_price.append(exec['price']) checked_exec_id.append(exec['id']) return exec_size, exec_price order_id = '' try: entry_price = TickData.get_bid_price( ) + 1 if side == 'buy' else TickData.get_ask_price() - 1 cls.num_private_access += 1 order_id = cls.bf.create_order( symbol='BTC/JPY', type='limit', side=side, price=entry_price, amount=total_size, params={ 'product_code': 'FX_BTC_JPY', 'minute_to_expire': 1 } # 期限切れまでの時間(分)(省略した場合は30日) )['info']['child_order_acceptance_id'] except Exception as e: print('opt entry limit order failed! ' + str(e)) LogMaster.add_log('opt entry limit order failed! ' + str(e), 0, None) LineNotification.send_error('opt entry limit order failed! ' + str(e)) cls.check_exception(e) return -1, 0, 0, '' exec_size = [] exec_price = [] print('oid=', order_id) while datetime.now().second <= 56 and sum(exec_size) < total_size: es, ep = __check_execution_ws(order_id) exec_size.extend(es) exec_price.extend(ep) time.sleep(0.5) cls.cancel_order(order_id) if sum(exec_size ) < total_size: #final check using execution history from API es, ep = __check_execution(order_id) if sum(es) > sum(exec_size): exec_size = es exec_price = ep if sum(exec_size) > 0: ave_p = round( sum(exec_price[i] * exec_size[i] for i in range(len(exec_price))) / sum(exec_size)) print('opt entry limit order has been successfully executed.' + 'side=' + side + ', ave price=' + str(ave_p) + ', size=' + str(round(sum(exec_size), 2))) return 0, round(sum(exec_size), 2), ave_p, order_id else: ave_p = 0 print('opt entry limit order timed out.' + 'side=' + side + ', ave price=0' + ', size=0') return -1, 0, 0, order_id
def price_tracing_order(cls, side, total_size): def __check_bid_ask_diff( side, ori_bidask, diff_kijun ): #True:diff is within diff_kijun, False:diff is larger than diff_kijun if side == 'buy': ask = TickData.get_ask_price() return False if ask - ori_bidask >= diff_kijun else True else: bid = TickData.get_bid_price() return False if ori_bidask - bid >= diff_kijun else True checked_exec_id = [] def __check_execution_ws(order_id): exec_size = [] exec_price = [] exe_data = TickData.get_exe_data()[-30:] for exec in exe_data: if exec[side + '_child_order_acceptance_id'] == order_id and exec[ 'id'] not in checked_exec_id: exec_size.append(exec['size']) exec_price.append(exec['price']) checked_exec_id.append(exec['id']) return exec_size, exec_price exec_size = [] exec_price = [] order_ids = [] order_sizes = [] outstanding_size = total_size while sum(exec_size) < total_size and outstanding_size >= 0.01: try: entry_price = TickData.get_bid_price( ) + 1 if side == 'buy' else TickData.get_ask_price() - 1 cls.num_private_access += 1 order_id = cls.bf.create_order( symbol='BTC/JPY', type='limit', side=side, price=entry_price, amount=outstanding_size, params={ 'product_code': 'FX_BTC_JPY', 'minute_to_expire': 1 } # 期限切れまでの時間(分)(省略した場合は30日) )['info']['child_order_acceptance_id'] order_ids.append(order_id) order_sizes.append(outstanding_size) except Exception as e: print('price tracing order failed! ' + str(e)) LogMaster.add_log('price tracing order failed! ' + str(e), 0, None) LineNotification.send_error('price tracing order failed! ' + str(e)) cls.check_exception(e) ave_p = round( sum(exec_price[i] * exec_size[i] for i in range(len(exec_price))) / sum(exec_size)) return -1, order_sizes, ave_p, order_ids, sum(exec_size) while __check_bid_ask_diff(side, entry_price, 300) and sum(exec_size) < total_size: es, ep = __check_execution_ws(order_id) if sum(es) > 0: exec_size.extend(es) exec_price.extend(ep) outstanding_size = round(total_size - sum(exec_size), 2) time.sleep(0.1) cls.cancel_order(order_id) ave_p = round( sum(exec_price[i] * exec_size[i] for i in range(len(exec_price))) / sum(exec_size)) print('price tracing order has been successfully executed.' + 'side=' + side + ', ave price=' + str(ave_p) + ', size=' + str(round(sum(exec_size), 2))) return 0, order_sizes, ave_p, order_ids, sum(exec_size)
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()
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)