def __calc_ohlc_thread(cls): while cls.flg_ohlc_loop: target_min = -1 next_min = -1 while SystemFlg.get_system_flg(): data = cls.get_tmp_exec_data() if len(data) > 0: target_min = int(data[-1]['timestamp'].split('T')[1].split(':')[1]) #計算開始の基準minuteを決定 target_min = target_min +1 if target_min +1 < 60 else 0 next_min = target_min +1 if target_min +1 < 60 else 0 break time.sleep(0.1) while SystemFlg.get_system_flg(): data = cls.get_tmp_exec_data() if len(data) > 0 and int(data[-1]['timestamp'].split('T')[1].split(':')[1]) == next_min or (datetime.now().minute == next_min and datetime.now().second > 2): #次の分のデータが入り出したらohlc計算する next_data = [] target_data = [] for d in data: minut = int(d['timestamp'].split('T')[1].split(':')[1]) #if (next_min != 0 and minut >= next_min) or (next_min == 0 and minut >= 0): if minut == next_min: next_data.append(d) #次回の分のデータは次に回す elif minut == target_min: target_data.append(d) if len(next_data) > 0: cls.add_tmp_exec_data(next_data) if len(target_data) == 0: print('RealtimeWSAPI: target data len is 0 !') LineNotification.send_error('RealtimeWSAPI: target data len is 0 !') #ここに来たら、計算開始の基準minuteを決定まで戻ったほうがいい。 #reset target min cls.flg_ohlc_loop = False break #if len(data) > 0: # target_min = int(data[-1]['timestamp'].split('T')[1].split(':')[1]) # target_min = target_min + 1 if target_min + 1 < 60 else 0 # next_min = target_min + 1 if target_min + 1 < 60 else 0 #else: # print('RealtimeWSAPI: data len is 0 !') # LineNotification.send_error('RealtimeWSAPI: data len is 0 !') else: p = [d.get('price') for d in target_data] size = [d.get('size') for d in target_data] dt = dateutil.parser.parse(target_data[-1]['timestamp']) OneMinMarketData.add_tmp_ohlc(dt.timestamp(), dt, p[0], max(p), min(p), p[-1], sum(size)) #print(datetime.now()) #print('RealtimeWSAPI: ', dt.timestamp(), p[0], max(p), min(p), p[-1], sum(size)) target_min = target_min + 1 if target_min + 1 < 60 else 0 next_min = target_min + 1 if target_min + 1 < 60 else 0 else: cls.add_tmp_exec_data(data) time.sleep(1) if cls.flg_ohlc_loop == False: cls.restart_thread()
def __init__(self): SystemFlg.initialize() self.margin_rate = 120.0 self.leverage = 15.0 self.ac = BotAccount() self.JST = pytz.timezone('Asia/Tokyo') self.last_ohlc_min = -1 self.last_sync_ut = datetime.now(self.JST).timestamp() self.model = None self.cbm = None self.bst = None self.prediction = [0] self.pred_side = ''
def __display_thread(cls): while SystemFlg.get_system_flg(): print('pl=', cls.total_pl, 'num_trade=', cls.num_trade, 'win_rate=', cls.win_rate, 'pl_per_min=', cls.pl_per_min, 'total_fee=', cls.total_fee) print(cls.get_order_data()) print('holding_side=', cls.holding_side, 'holding_price', cls.holding_price, 'holding_qty=', cls.holding_qty) #LineNotification.send_message('holding_side:'+cls.holding_side+', holding_price:'+str(cls.holding_price)+', holding_qty:'+str(cls.holding_qty)) order_data = cls.get_order_data() LineNotification.send_message('pl=' + str(cls.total_pl) + ', num_trade=' + str(cls.num_trade) + ', win_rate=' + str(cls.win_rate) + '\n' + '********Holding********\n' + cls.holding_side + ' @' + str(cls.holding_price) + ' x ' + str(cls.holding_qty) + '\n' + '********Order********\n' + str(order_data['side']) + ' @' + str(order_data['price']) + ' x ' + str(order_data['leaves_qty'])) LogMaster.add_account_log(datetime.datetime.now(), Trade.get_bid_ask()[0], cls.total_pl, cls.total_fee, cls.num_trade, cls.win_rate) #loop = asyncio.new_event_loop() #loop.run_until_complete(cls.__generate_and_send_pl_image()) if cls.image_sending_flg >= 60: cls.__generate_and_send_pl_image() cls.image_sending_flg = 0 else: cls.image_sending_flg += 1 time.sleep(60)
def start_flyer_bot(self, num_term, window_term, pl, ls, upper_kijun, lower_kijun): self.__bot_initializer(num_term, window_term, pl, ls, upper_kijun, lower_kijun) self.start_time = time.time() self.fixed_order_size = 0.05 while SystemFlg.get_system_flg(): self.__check_system_maintenance(num_term, window_term) self.__update_ohlc() if self.ac.holding_side == '' and self.ac.pt_side == '' and self.flg_loss_cut == False: #no position no pt order if self.prediction == 1 or self.prediction == -1: self.entry_price_tracing_order(self.pred_side, self.fixed_order_size) elif self.ac.holding_side != '' and self.ac.pt_side == '' and self.flg_loss_cut == False: #holding position and no order self.entry_pt_order() elif (self.ac.holding_side == 'buy' and self.prediction == 2) or (self.ac.holding_side == 'sell' and self.prediction == 1): # ポジションが判定と逆の時にexit, もしplがあればキャンセル。。 self.cancel_pt_order() self.exit_order() self.entry_price_tracing_order(self.pred_side, self.fixed_order_size) elif self.ac.holding_side == '' and self.ac.pt_side != '': #unexpected situation, no holding position but pt order exist print('no position but pt order exist!') LogMaster.add_log('no position but pt order exist!', self.prediction, self.ac) LineNotification.send_error('no position but pt order exist!') self.cancel_pt_order() self.check_and_do_lc() #check and do loss cut if Trade.flg_api_limit: time.sleep(60) print('Bot sleeping for 60sec due to API access limitation') else: time.sleep(0.1)
def __account_thread(self): while SystemFlg.get_system_flg(): for oid in self.order_ids_active: ltp = TickData.get_ltp() #check if execution of limit order is possible if ltp <= self.order_price[oid] and (self.order_side[oid] == 'Buy' or ltp >= self.order_price[oid]) and self.order_side[oid] == 'Sell' and self.order_type[oid] == 'Limit': self.__check_execution(oid) time.sleep(1)
def __init__(self): SystemFlg.initialize() LineNotification.initialize() Trade.initialize() LogMaster.initialize() while True: print('Please select program mode.') print('1: OHLCV data update') print('2: Mark3etData test') print('3: Bot test') print('4: Sim') print('5: WS Test') print('6: Trade Test') select = str(input()) if select == '1': print('1: OHLCV data update') dmd = DownloadMarketData() dmd.download_all_targets_async(2017, 1, 2) dmd.update_ohlcv() RestAPI.update_onemin_data() break elif select == '2': print('2: MarketData test') term_list = list(range(10, 1000, 100)) MarketData.initialize_for_bot(term_list, True) break elif select == '3': print('3: Bot test') term_list = list(range(10, 1000, 100)) MarketData.initialize_for_bot(term_list, False) bot = Bot(100) break elif select == '4': print('4: Sim') pass break elif select == '5': print('5: WS Test') pass break elif select == '6': print('6: Trade Test') Trade.test_trade() break else: pass
def __init__(self): SystemFlg.initialize() self.ac = BotAccount() self.margin_rate = 120.0 self.leverage = 4.0 self.JST = pytz.timezone('Asia/Tokyo') self.last_ohlc_min = -1 self.lgb = LgbModel() self.model_buy = None self.model_sell = None self.upper_kijun = 0 self.lower_kijun = 0 self.pl = 0 self.ls = 0 self.prediction = 0 self.pred_side = '' self.flg_loss_cut = False #prohibit re-entry after losscut within 1m
def main_thread(self): ini_data_flg = False #flg for market data initialization while SystemFlg.get_system_flg(): while ini_data_flg is False: #wait for initial update of the market data if len(OneMinMarketData.ohlc.dt) > 0: ini_data_flg = True time.sleep(0.5) if OneMinMarketData.get_flg_ohlc_update(): df = OneMinMarketData.get_df() if df is not None: if True in df.isnull().any(): print('null is in df!') LineNotification.send_error('LgbModel:' + 'null is in df!') self.set_pred("null") else: if self.pred_method == 0: prediction = self.bpsp_prediction( self.model, df, self.upper_kijun) elif self.pred_method == 1: prediction = self.bpsp_prediction2(self.model, df) elif self.pred_method == 2: prediction = self.bpsp_prediction2_kai( self.model, df) elif self.pred_method == 3: prediction = self.bpsp_prediction3( self.model, df, self.upper_kijun) elif self.pred_method == 4: prediction = self.bpsp_prediction4(self.model, df) else: print('invalid pred_method!', self.pred_method) LineNotification.send_error( 'LgbModel:' + 'invalid pred_method!' + str(self.pred_method)) if len(prediction) > 0: self.set_pred({ 0: 'buy_large', 1: 'buy_small', 2: 'sell_large', 3: 'sell_small', -1: 'no' }[prediction[-1]]) else: print('prediction length==0!', prediction) LineNotification.send_error( 'LgbModel:' + 'prediction length==0!') print(df) OneMinMarketData.set_flg_ohlc_update(False) print('prediction = ', self.pred) self.write_df_pred(df, self.pred) else: print('df is None after completed generation!') LineNotification.send_error( 'LgbModel:' + 'df is None after completed generation!') time.sleep(1) print('Lgb main thread ended.')
def __ohlc_thread(cls): print('started Account.ohlc_thread') cls.start_ts = time.time() while SystemFlg.get_system_flg(): cls.__check_order_status_API() cls.__calc_total_pl() cls.pl_per_min = round( (cls.total_pl / ((time.time() - cls.start_ts) / 60.0)), 4) time.sleep(10)
def monitor_api(cls): pre_private_access = 0 pre_public_access = 0 cls.access_log = [] cls.total_access_per_300s = 0 while SystemFlg.get_system_flg(): cls.access_log.append(cls.num_private_access + cls.num_public_access - pre_private_access - pre_public_access) pre_private_access =cls.num_private_access pre_public_access = cls.num_public_access if len(cls.access_log) >= 300: cls.total_access_per_300s = sum(cls.access_log[-300:]) cls.access_log.pop(0) time.sleep(1)
def order(cls, side, price, type, amount): for i in range(cls.error_trial): cls.num_private_access += 1 order_info = '' error_message = '' try: if type == 'Limit' or type == 'limit': order_info = cls.bb.createOrder( 'BTC/USD', 'limit', side, str(amount), str(price), {'time_in_force': 'GoodTillCancel'}) elif type == 'Market' or type == 'market': order_info = cls.bb.createOrder( 'BTC/USD', 'market', side, str(amount), str(price), {'time_in_force': 'GoodTillCancel'}) except Exception as e: error_message = str(e) print('Trade-order error!, ' + str(e)) print('side=', side, ', price=', price, ', type', type, ', amount', amount) print('error in order! ' + '\r\n' + order_info + '\r\n' + str(e)) LineNotification.send_message('Trade-order error!, ' + str(e)) cls.initialize() time.sleep(1) finally: if 'error' not in error_message: return order_info elif 'expire' in error_message: print('API key expired!') print('Force finish all processes!') LineNotification.send_message('API key expired!') SystemFlg.set_system_flg(False) return None else: time.sleep(cls.rest_interval) print('Order finally failed.') LineNotification.send_message('Order finally failed.') return None
def __ohlc_thread(cls): t = datetime.datetime.now().timestamp() cls.kijun_timestamp = int( t - (t - (t // 60.0) * 60.0)) + 60 #timestampの秒を次の分の0に修正 while SystemFlg.get_system_flg(): if cls.kijun_timestamp <= datetime.datetime.now().timestamp(): #download last 1m ohlc df = cls.get_ohlc(1, cls.kijun_timestamp - 60) print(datetime.datetime.now()) print(df) cls.kijun_timestamp += 60 else: time.sleep(1)
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 __onemin_data_download_thread(cls): while SystemFlg.get_system_flg(): if datetime.now().second == 0: time.sleep(1) df = cls.download_latest_ohlc() if df is not None: cls.set_ohlc(df[0], df[1], df[2], df[3], df[4], df[5], df[6]) #print(cls.initial_data_download(), cls.ohlc_dt, cls.ohlc_open, cls.ohlc_high, cls.ohlc_low, cls.ohlc_close, cls.ohlc_volume) else: print( 'failed download ohlc in __onemin_data_download_thread !' ) time.sleep(0.1)
def __ohlc_thread(cls): print('started MarketData.ohlc_thread') t = datetime.datetime.now().timestamp() kijun_timestamp = int( t - (t - (t // 60.0) * 60.0)) + 60 # timestampの秒を次の分の0に修正 while SystemFlg.get_system_flg(): if kijun_timestamp + 1 <= datetime.datetime.now().timestamp(): downloaded_df = RestAPI.get_ohlc( 1, cls.df['timestamp'].iloc[-1] - 60) cls.add_df(downloaded_df) print(cls.get_df().iloc[-10:]) cls.set_model_data(cls.generate_data_for_model(cls.get_df())) cls.__calc_prediction() kijun_timestamp += 60 else: time.sleep(1) print('stopped MarketData.ohlc_thread!')
def __account_thread(self): while SystemFlg.get_system_flg(): for oid in self.order_ids: order_data = PrivateWSData.get_order_data(oid) exec_data = PrivateWSData.get_exec_data(oid) if order_data is not None and oid not in self.removed_order_ids: if order_data['ordStatus'] == 'New' and self.order_status[oid] == 'Sent': self.__confirm_order(oid, order_data['side'],order_data['price'],order_data['orderQty'],order_data['ordType']) elif exec_data['ordStatus'] == 'PartiallyFilled' and order_data['ordStatus'] == 'PartiallyFilled': self.__execute_order(order_data['orderID'], exec_data['execID'], order_data['side'], order_data['price'], self.order_size[oid] - order_data['leavesQty'], order_data['prdStatus']) elif order_data['ordStatus'] == 'Filled' or order_data['ordStatus'] == 'Canceled': time.sleep(1) trades = Trade.get_trades(10) api_exec_data = list(map(lambda x: x['info'] if x['info']['orderID'] == oid and str(x['info']['execComm']) != 'None' else {}, trades)) api_exec_data = [x for x in api_exec_data if x != {}] self.__calc_fee(oid, list(map(lambda x: x['execComm'], api_exec_data))) if order_data['ordStatus'] == 'Filled' and order_data['leavesQty'] > 0: print('status is Filled but leavesQty is not 0!', order_data) self.__execute_order(oid, '', self.order_side[oid], order_data['avgPx'], self.order_size[oid] - order_data['leavesQty'], order_data['ordStatus']) else: print('Unknown order status!', order_data['ordStatus'])
def __ohlc_thread(cls): print('started MarketData.ohlc_thread') t = datetime.datetime.now().timestamp() kijun_timestamp = int( t - (t - (t // 60.0) * 60.0)) + 60 # timestampの秒を次の分の0に修正 while SystemFlg.get_system_flg(): if kijun_timestamp + 1 <= datetime.datetime.now().timestamp(): downloaded_df = RestAPI.get_ohlcv_update(cls.md.datetime[-1]) #downloaded_df = RestAPI.get_ohlc(1, cls.md.timestamp[-1] - 60) cls.__add_ohlc_data(downloaded_df) print(cls.md.get_ohlc().iloc[-1:]) kijun_timestamp += 60 if cls.test_flg: print( '*******************MarketData OHLCV*******************' ) print(cls.md.get_ohlc()) print( '*******************MarketData index*******************' ) print(cls.md.get_index()) else: time.sleep(1) print('stopped MarketData.ohlc_thread!')
def lgbmaster_thread(self): while SystemFlg.get_system_flg(): if datetime.now().minute is 0: pass time.sleep(1)
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
def __sim_thread(self): while SystemFlg.get_system_flg(): if MarketData.ohlc_sim_flg == True: #毎分MarketDataでohlc / indexが更新されたことを確認 ohlc = MarketData.get_latest_ohlc( 0 ) #{'dt', 'open', 'high', 'low', 'close', 'divergence_scaled', 'vola_kyori_scaled} #SimAccountのpl / holding periodなどを更新 SimAccount.ohlc_update(self.loop_i, ohlc) #check invalid ac situation if SimAccount.getNumOrders() > 1: print('Sim: # of order is more than 1 !') #nnの計算を行い、strategyで必要なアクションを計算 self.__nn_process(ohlc['divergence_scaled'], ohlc['vola_kyori_scaled']) #SimAccountのorderを更新する。 actions = Strategy.sim_ga_limit_strategy( self.pred, 1, self.max_amount, ohlc) self.__sim_action_process(self.loop_i, actions, ohlc) #Log LogMaster.add_sim_holding_log(ohlc['dt'], SimAccount.get_holding_data()) LogMaster.add_sim_order_log(ohlc['dt'], SimAccount.get_order_data()) LogMaster.add_sim_performance_log( ohlc['dt'], SimAccount.get_performance_data()) LogMaster.add_sim_trade_log(ohlc['dt'], SimAccount.get_latest_trade_log()) #Display if self.__bool_display: print('') print( '**************************************************************************************************' ) print('i=', self.loop_i) del ohlc['divergence_scaled'] del ohlc['vola_kyori_scaled'] del ohlc['vol_ma_divergence_scaled'] print(ohlc) print('nn ouput=', { 0: 'no', 1: 'buy', 2: 'sell', 3: 'cancel' }[self.pred_log[-1]]) performance_log = SimAccount.get_performance_data() print( '----------------------------------------Performance Data--------------------------------------------' ) print(performance_log) print( '-------------------------------------------Holding Data---------------------------------------------' ) print(SimAccount.get_holding_data()) print( '--------------------------------------------Order Data----------------------------------------------' ) print(SimAccount.get_order_data()) print( '--------------------------------------------Trade Log-----------------------------------------------' ) print(SimAccount.get_latest_trade_log()) print( '**************************************************************************************************' ) #create pl chart plog = LogMaster.get_sim_performance_log() self.__generate_pl_chart(plog) #send message LineNotification.send_performance(performance_log) LineNotification.send_holding( SimAccount.get_holding_data()) if os.path.isfile('./Image/sim_pl.jpg'): LineNotification.send_image( open('./Image/sim_pl.jpg', 'rb')) self.loop_i += 1 time.sleep(1)
def order(cls, side, price, size, type, expire_m) -> str: # min size is 0.01 if cls.flg_api_limit == False: order_id = '' if size >= 0.01: try: if type == 'limit': cls.num_private_access += 1 order_id = cls.bf.create_order( symbol='BTC/JPY', type='limit', side=side, price=price, amount=size, params={'product_code': 'FX_BTC_JPY', 'minute_to_expire': expire_m} # 期限切れまでの時間(分)(省略した場合は30日) ) elif type == 'market': cls.num_private_access += 1 order_id = cls.bf.create_order( symbol='BTC/JPY', type='market', side=side, amount=size, params={'product_code': 'FX_BTC_JPY'} ) else: print('Trade - order: invalid order type!') LogMaster.add_log('api_error - Trade - order: invalid order type!',0,None) LineNotification.send_error('Trade - order: invalid order type!') return '' except Exception as e: if 'Margin amount is insufficient' in str(e): size -= 0.01 size = round(size,2) if size >= 0.01: print('margin amount is insufficient! - decrease order size to '+str(size)) return cls.order(side,price,size, type, expire_m) else: print('margin amount can not be less than 0.01! - decrease order size to 0.01') LogMaster.add_log('api_error - Trade - order:margin amount can not be less than 0.01!',0,None) LineNotification.send_error('Trade - order:margin amount can not be less than 0.01!') return '' elif 'Market state is closed.' in str(e): print(str(datetime.now())+': market state is closed.') time.sleep(10) return cls.order(side, price, size, type, expire_m) else: print(e) LogMaster.add_log('action_message - Trade-order error! ' + str(e),0,None) cls.conti_order_error += 1 if cls.check_exception(e) == 'ok': if cls.conti_order_error > 15: SystemFlg.set_system_flg(False) LogMaster.add_log('api_error - continuous order error more than 15times System Finished.',0,None) print('continuous order error more than 15times System Finished.') return '' else: #connection reset by peer error return '' order_id = order_id['info']['child_order_acceptance_id'] cls.conti_order_error = 0 print('ok order - ' + str(order_id)) return order_id else: # in case order size is smaller than 0.01 if size >0: positions = Trade.get_positions() ide = '' size = 0 price = 0 for s in positions: side = s['side'].lower() size += float(s['size']) price += float(s['price']) * float(s['size']) price = round(price / size) order_id = cls.bf.create_order( symbol='BTC/JPY', type='market', side='buy' if side =='sell' else 'sell', amount=size, params={'product_code': 'FX_BTC_JPY'} ) print('order size ' + str(size) + ' is too small. minimum order size is 0.01!') LineNotification.send_error('order size ' + str(size) + ' is too small. minimum order size is 0.01!') LogMaster.add_log('order size ' + str(size) + ' is too small. minimum order size is 0.01!',0,None) return order_id else: print('order size =0 is not valid!') LineNotification.send_error('order size =0 is not valid!') return '' else: print('order is temporary exhibited due to API access limitation!') return ''
def __bot_thread(self): loop_num = 0 while SystemFlg.get_system_flg(): #毎分のデータ更新時の処理 if MarketData.get_ohlc_flg() == True: ohlc = MarketData.get_ohlc() index = MarketData.get_index() for i in range(self.num_genes ): #各戦略毎に新しい行動を計算して、実際に発注等する。結果をBotAccountに入力 order_data = self.bot_accounts[i].get_last_order_data() holding_data = self.bot_accounts[i].get_holding_data() performance_data = self.bot_accounts[ i].get_performance_data() nn_output = self.__nn_process(ohlc, index, i, order_data, holding_data, performance_data) actions = Strategy.ga_limit_market_strategy( nn_output, self.__order_size, self.__order_size, order_data, holding_data, i) print('#', i, ' - pred=', nn_output[0]) for j in range(len(actions.action)): if actions.action[j] == 'entry': res = Trade.order(actions.order_side[j], actions.order_price[j], actions.order_type[j], actions.order_size[j]) if res != None: self.bot_accounts[i].entry_order( res['info']['order_id'], res['info']['side'], res['info']['price'], res['info']['qty'], res['info']['order_type'], actions.order_message[j]) elif actions.action[ j] == 'cancel' and order_data['side'] != '': res = Trade.cancel_order(order_data['id']) if res != None: self.bot_accounts[i].cancel_order( order_data['id']) elif actions.action[j] == 'update amount': res = Trade.update_order_amount( actions.order_serial_num[j], actions.order_size[j]) if res != None: self.bot_accounts[i].update_order_amount( order_data['id'], actions.order_size[j]) elif actions.action[j] == 'update price': res = Trade.update_order_price( actions.order_serial_num[j], actions.order_price[j]) if res != None: self.bot_accounts[i].update_order_price( order_data['id'], actions.order_price[j]) else: print('Unknown strategy action-', actions.action[j]) self.bot_accounts[i].move_to_next(ohlc['datetime'], loop_num, ohlc, self.__order_size) loop_num += 1 #次のデータ更新まで未約定orderがある時に約定確認処理を継続する order_remaining_flg = True while MarketData.get_ohlc_flg() == False and order_remaining_flg: order_remaining_flg = False for i in range(self.num_genes): #未約定注文有無の確認 if len(self.bot_accounts[i].order_id) > 0: order_remaining_flg = True if order_remaining_flg == False: #未約定注文がなければ確認処理を停止 break else: exec_list = Trade.get_executions() if exec_list != None: #datetime unmatched errorで取得できないことがある。 for i in range(self.num_genes): if len(self.bot_accounts[i].order_id) > 0: self.bot_accounts[i].check_execution( exec_list) #未約定注文があるBotAccountに約定データを渡す time.sleep(3) time.sleep(1) print('Exited Bot thread loop !') LineNotification.send_message('Exited Bot thread loop !')
def __onemin_thread(self): while SystemFlg.get_system_flg(): time.sleep(60) self.__calc_pnl()
def __bot_sub_thread(self): num_bot_main_loop = 0 while SystemFlg.get_system_flg(): time.sleep(60) print('') print('') print('*********************************************') print('num_bot_loop:', num_bot_main_loop, ' : ', datetime.now()) print('*********************************************') print('') print('---------------------sim---------------------') self.sim_ac.onemine_process(TickData.get_ltp(), datetime.now()) print('sim_posi_side:', self.sim_ac.holding_side, ', sim_posi_price:', self.sim_ac.holding_price, ', sim_posi_size:', self.sim_ac.holding_size) for oid in self.sim_ac.order_serial_list: print('sim_order_side:', self.sim_ac.order_side[oid], ', sim_order_price:', self.sim_ac.order_price[oid], ', sim_order_size:', self.sim_ac.order_size[oid], ', sim_order_type:', self.sim_ac.order_type[oid]) print('sim_total_pl:', self.sim_ac.total_pl, 'sim_total_fee:', self.sim_ac.total_fee, 'sim_num_trade:', self.sim_ac.num_trade, 'sim_win_rate:', self.sim_ac.win_rate) if self.real_trade is False: LineNotification.send_free_message( '\r\n' + 'sim_total_pl:' + str(self.sim_ac.total_pl) + ', sim_total_fee:' + str(self.sim_ac.total_fee) + ', sim_num_trade:' + str(self.sim_ac.num_trade) + ', sim_win_rate:' + str(self.sim_ac.win_rate) + '\r\n' + 'pred=' + self.lgb_model.get_pred() + ', sim_posi_side:' + self.sim_ac.holding_side + ', sim_posi_price:' + str(self.sim_ac.holding_price) + ', sim_posi_size:' + str(self.sim_ac.holding_size)) self.__write_sim_log() if self.real_trade: print('') print('---------------------bot---------------------') #print('BOT: performance') performance = self.ac.get_performance() print('BOT Performance:', performance) #print('BOT: Position') posi = self.ac.get_position() print('BOT Position:', 'bot_posi_side:', posi['side'], ', bot_posi_price:', posi['price'], ', bot_posi_size:', posi['size']) #print('BOT: Orders') order_side, order_price, order_size, order_type, order_dt = self.ac.get_orders( ) for oid in order_side: print('BOT Order:', 'bot_order_side:', order_side[oid], ', bot_order_price:', order_price[oid], ', bot_order_size:', order_size[oid], ', bot_order_type:', order_type[oid]) LineNotification.send_free_message( '\r\n' + 'total_pl:' + str(performance['total_pl']) + ', total_fee:' + str(performance['total_fee']) + ', num_trade:' + str(performance['num_trade']) + ', win_rate:' + str(performance['win_rate']) + '\r\n' + 'pred=' + self.lgb_model.get_pred() + ', posi_side:' + posi['side'] + ', posi_price:' + str(posi['price']) + ', posi_size:' + str(posi['size'])) num_bot_main_loop += 1 print('exited from bot sub-loop')
def __bot_thread(self): while TickData.get_ltp() <= 0: time.sleep(1) next_min = datetime.now( ).minute + 1 if datetime.now().minute + 1 < 60 else 0 flg = False pre_order_side = '' pre_order_size = 0 #for detection of pt execution while SystemFlg.get_system_flg(): pred = self.lgb_model.get_pred() self.sim_ac = self.sim.sim_model_pred_onemin( pred, self.pt_ratio, self.lc_ratio, self.amount, TickData.get_ltp(), self.sim_ac, OneMinMarketData.ohlc) #self.sim_ac = self.sim.sim_model_pred_onemin_avert(pred, self.pt_ratio, self.lc_ratio, self.amount, TickData.get_ltp(), self.sim_ac, self.sim_ac2, self.avert_period_kijun, self.avert_val_kijun, OneMinMarketData.ohlc) #self.sim_ac = self.sim.sim_model_pred_onemin_avert_limit_entry(pred, self.pt_ratio, self.lc_ratio, self.amount, TickData.get_ltp(), self.sim_ac, self.sim_ac2, self.avert_period_kijun, self.avert_val_kijun, OneMinMarketData.ohlc) if self.real_trade: posi = self.ac.get_position() bot_order = self.ac.get_latest_order() sim_order = self.sim_ac.get_latest_order() ''' if len(order_side) > 1: print('bot order len is bigger than 1!') print(order_side) if len(self.sim_ac.order_side) > 1: print('sim_ac order len is bigger than 1!') print(order_side) ''' #market entry if bot_order['side'] == '' and sim_order[ 'side'] != '' and pre_order_side != '' and pre_order_size > 0: #pt exec check in bot print( 'BOT: pt completion was detected and process sim_ac execution from bot.' ) self.sim_ac.bot_procedss_execution(sim_order['side'], sim_order['price'], sim_order['size'], 'Limit', datetime.now()) elif posi[ 'side'] != self.sim_ac.holding_side: #to have same position side (botで先にpt約定完了してno posiになった時はsimに合わせるべきではない、botでpt約定を感知したらsim_acにも反映させるべき) size = self.sim_ac.holding_size if posi[ 'side'] == '' else self.sim_ac.holding_size + posi[ 'size'] order_info = Trade.order(self.sim_ac.holding_side, self.sim_ac.holding_price, 'Market', size) if order_info is not None: print('BOT: entry order', order_info['info']['side'], order_info['info']['price'], order_info['info']['orderQty'], order_info['info']['ordType'], order_info['info']['orderID']) LineNotification.send_free_message( 'BOT: entry order' + '\r\n' + order_info['info']['side'] + '\r\n' + str(order_info['info']['price']) + '\r\n' + str(order_info['info']['orderQty']) + '\r\n' + order_info['info']['ordType'] + '\r\n' + order_info['info']['orderID']) self.ac.add_order(order_info['info']['orderID'], order_info['info']['side'], order_info['info']['price'], order_info['info']['orderQty'], order_info['info']['ordType']) else: print('BOT: entry order failed!') LineNotification.send_error('BOT: entry order failed!') elif bot_order['side'] != sim_order['side'] and posi[ 'side'] == self.sim_ac.holding_side: #position side is matched but order side in unmatch for oid in self.ac.order_ids_active: Trade.cancel_order(oid) print('BOT: cancel order', oid) self.ac.bot_cancel_order(oid) order_info = Trade.order(sim_order['side'], sim_order['price'], sim_order['type'], self.amount) if order_info is not None: print('BOT: pt order', order_info['info']['side'], order_info['info']['price'], order_info['info']['orderQty'], order_info['info']['ordType'], order_info['info']['orderID']) LineNotification.send_free_message( 'BOT: pt order' + '\r\n' + order_info['info']['side'] + '\r\n' + str(order_info['info']['price']) + '\r\n' + str(order_info['info']['orderQty']) + '\r\n' + order_info['info']['ordType'] + '\r\n' + order_info['info']['orderID']) self.ac.add_order(order_info['info']['orderID'], order_info['info']['side'], order_info['info']['price'], order_info['info']['orderQty'], order_info['info']['ordType']) else: print('BOT: pt order failed!') LineNotification.send_error('BOT: pt order failed!') #Limit entry ''' if bot_order['side'] == '' and sim_order['side'] != '' and pre_order_side != '' and pre_order_size > 0: # pt exec check in bot print('BOT: pt completion was detected and process sim_ac execution from bot.') self.sim_ac.bot_procedss_execution(sim_order['side'], sim_order['price'], sim_order['size'], 'Limit', datetime.now()) elif posi['side'] != self.sim_ac.holding_side and : # to have same position side (botで先にpt約定完了してno posiになった時はsimに合わせるべきではない、botでpt約定を感知したらsim_acにも反映させるべき) size = self.sim_ac.holding_size if posi['side'] == '' else self.sim_ac.holding_size + posi['size'] order_info = Trade.order(self.sim_ac.holding_side, self.sim_ac.holding_price, 'Limit', size) if order_info is not None: print('BOT: entry order', order_info['info']['side'], order_info['info']['price'], order_info['info']['orderQty'], order_info['info']['ordType'], order_info['info']['orderID']) LineNotification.send_free_message('BOT: entry order' + '\r\n' + order_info['info']['side'] + '\r\n' + str(order_info['info']['price']) + '\r\n' + str(order_info['info']['orderQty']) + '\r\n' + order_info['info']['ordType'] + '\r\n' + order_info['info']['orderID']) self.ac.add_order(order_info['info']['orderID'], order_info['info']['side'], order_info['info']['price'], order_info['info']['orderQty'], order_info['info']['ordType']) else: print('BOT: entry order failed!') LineNotification.send_error('BOT: entry order failed!') elif bot_order['side'] != sim_order['side'] and posi['side'] == self.sim_ac.holding_side: # position side is matched but order side in unmatch for oid in self.ac.order_ids_active: Trade.cancel_order(oid) print('BOT: cancel order', oid) self.ac.bot_cancel_order(oid) order_info = Trade.order(sim_order['side'], sim_order['price'], sim_order['type'], self.amount) if order_info is not None: print('BOT: pt order', order_info['info']['side'], order_info['info']['price'], order_info['info']['orderQty'], order_info['info']['ordType'], order_info['info']['orderID']) LineNotification.send_free_message('BOT: pt order' + '\r\n' + order_info['info']['side'] + '\r\n' + str(order_info['info']['price']) + '\r\n' + str(order_info['info']['orderQty']) + '\r\n' + order_info['info']['ordType'] + '\r\n' + order_info['info']['orderID']) self.ac.add_order(order_info['info']['orderID'], order_info['info']['side'], order_info['info']['price'], order_info['info']['orderQty'], order_info['info']['ordType']) else: print('BOT: pt order failed!') LineNotification.send_error('BOT: pt order failed!') pre_order_side = bot_order['side'] pre_order_size = bot_order['size'] ''' time.sleep(3) # simをsleep無しで回し続けるとtickdataがlockされてltp取れなくなる print('exited from bot main loop')