Ejemplo n.º 1
0
class Bot():
    def __init__(self, order_size):
        print('started bot')
        self.__nn_threshold = 0.7
        self.__nn = NN()
        self.__gene = []
        self.__nn_input_data_generator = NNInputDataGenerator()
        self.__read_genes()
        self.num_genes = len(self.__gene)
        self.bot_accounts = []
        for i in range(self.num_genes):
            self.bot_accounts.append(BotAccount(i))
        self.__pred = {}
        self.__pred_log = {}
        self.__bot_started_time = datetime.now()
        self.__bot_elapsed_time = 0
        self.__order_size = round(order_size / self.num_genes)
        self.__full_order_size = order_size
        th = threading.Thread(target=self.__bot_thread)
        th.start()

    def __initialize_combined_order_data(self):
        self.order_side_com = ''
        self.order_price_com = 0
        self.order_qty_com = 0

    def __read_genes(self):
        for f in glob.glob('./Model/*_best_weight.csv'):
            self.__gene.append(Gene(f, None, None))
        print('Identified ', len(self.__gene), ' genes.')

    '''
    毎分MarketDataに最新のデータが準備されたことを確認して、各戦略のNN計算して必要なアクションを取る。
    いずれかのBotAccountでorderがある時は約定データを取得してそれらのBotAccountに渡して約定確認・処理を行う。
    '''

    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 __nn_process(self, ohlc, index, account_id, order_data, holding_data,
                     performance_data):
        nn_input = self.__nn_input_data_generator.generate_nn_input_data_limit(
            self.__gene[account_id].num_index, ohlc, index, order_data,
            holding_data, performance_data)
        nn_outputs = self.__nn.calc_nn(nn_input, self.__gene[account_id], 0)
        self.__pred[account_id] = self.__nn.getActivatedUnitLimitMarket2(
            nn_outputs, self.__nn_threshold
        )  #{0:'no', 1: 'buy', 2:'sell', 3:'cancel'}[nn_output]
        return self.__pred[account_id]

    def __calc_combined_orders(self):
        for i in range(self.num_genes):
            od = self.self.bot_accounts[i].get_last_order_data()
Ejemplo n.º 2
0
class Sim:
    def __init__(self, bool_display):
        print('started Sim.')
        SimAccount.initialize()
        self.loop_i = 0
        self.max_amount = 1
        self.nn = NN()
        self.nn_input_data_generator = NNInputDataGenerator()
        self.gene = Gene('./Model/best_weight.csv')
        self.pred = -1
        self.pred_log = []
        self.__bool_display = bool_display  #True=display log
        th = threading.Thread(target=self.__sim_thread)
        th.start()

    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 __nn_process(self, divergence_scaled, vola_kyori_scaled):
        nn_input = self.nn_input_data_generator.generate_nn_input_data_limit_sim(
            divergence_scaled, vola_kyori_scaled)
        nn_outputs = self.nn.calc_nn(nn_input, self.gene.num_units,
                                     self.gene.weight_gene1,
                                     self.gene.weight_gene2,
                                     self.gene.bias_gene1,
                                     self.gene.bias_gene2, 1)
        self.pred = self.nn.getActivatedUnit(
            nn_outputs)  #{0:'no', 1: 'buy', 2:'sell', 3:'cancel'}[nn_output]
        self.pred_log.append(self.pred)
        #print('Sim: nn output=', self.pred, ':', {0:'no', 1: 'buy', 2:'sell', 3:'cancel'}[self.pred])

    def __generate_pl_chart(self, plog):
        if len(plog) > 2:
            df = pd.concat([
                pd.DataFrame(plog.values()),
                pd.DataFrame({'dt': plog.keys()})
            ],
                           axis=1)
            df = df.set_index('dt')
            fig, ax = plt.subplots()
            plt.plot(df.index, df['total_pl'])
            #plt.xticks(rotation=70)
            xfmt = mdates.DateFormatter("%d - %H:%M")
            ax.xaxis.set_major_formatter(xfmt)
            labels = ax.get_xticklabels()
            plt.setp(labels, rotation=45, fontsize=10)
            plt.show()
            plt.savefig('./Image/sim_pl.jpg')
            plt.close()

    def __sim_action_process(self, i, actions: ActionData, ohlc):
        for j in range(len(actions.action)):
            if actions.action[j] == 'entry':
                SimAccount.entry_order(i, actions.order_side[j],
                                       actions.order_price[j],
                                       actions.order_size[j], ohlc['dt'],
                                       actions.order_type[j],
                                       actions.order_message[j])
            elif actions.action[j] == 'cancel':
                SimAccount.cancel_all_order(i)
            elif actions.action[j] == 'update amount':
                print('update amount is not programmed !')
                pass
            elif actions.action[j] == 'update price':
                SimAccount.update_order_price(i, actions.order_serial_num[j],
                                              actions.order_price[j])
            else:
                print('Sim: Unknown strategy action !')