예제 #1
0
    def run(self):
        # log initial balance
        logging.info(
            "========== [  INITIAL BALANCE  ] ========================================================"
        )
        logging.info(self.mm1.get_balance())
        logging.info(self.mm2.get_balance())

        # if not backtesting
        if not self.is_backtesting:
            while True:
                try:
                    self.execute_trade_loop()
                except Exception as e:
                    Global.send_to_slack_channel(
                        "Something happened to StatArbBot! Now it's dying from ... %s"
                        % e)
                    # stop order watcher stats thread
                    OrderWatcherStats.instance().tear_down()
                    raise e
        # if backtesting
        else:
            # collect historical data from db
            logging.info("Collecting historical data, please wait...")
            mm1_data_cursor, mm2_data_cursor = \
                self.get_data_from_db(self.mm1_data_col, self.mm2_data_col,
                                      self.start_time, self.end_time)

            # loop through history data
            for mm1_data, mm2_data in zip(mm1_data_cursor, mm2_data_cursor):
                self.execute_trade_loop(mm1_data, mm2_data)

            # log backtesting result
            self.log_common_stat(log_level=logging.CRITICAL)
예제 #2
0
def main(coin_name: str, mm1_name: str, mm2_name: str):
    Global.configure_default_root_logging(should_log_to_file=False,
                                          log_level=logging.INFO)
    SharedMongoClient.initialize(should_use_localhost_db=False)
    start_time = Global.convert_local_datetime_to_epoch("2018.08.20 09:00:00",
                                                        timezone="kr")
    end_time = Global.convert_local_datetime_to_epoch("2018.08.20 13:00:00",
                                                      timezone="kr")

    iyo_config = Global.read_iyo_setting_config(coin_name)

    # set settings // fix manually if you need to
    settings = TradeSettingConfig.get_settings(
        mm1_name=mm1_name,
        mm2_name=mm2_name,
        target_currency=coin_name,
        start_time=start_time,
        end_time=end_time,
        division=iyo_config["division"],
        depth=iyo_config["depth"],
        consecution_time=iyo_config["consecution_time"],
        is_virtual_mm=True)

    bal_factor_settings = TradeSettingConfig.get_bal_fact_settings(
        iyo_config["krw_seq_end"], iyo_config["coin_seq_end"])

    ibo_result = InitialBalanceOptimizer.run(settings, bal_factor_settings)
    print(ibo_result)
    def run_iyo(cls, settings: dict, bal_factor_settings: dict,
                factor_settings: dict, oppty_dur_dict: dict):
        db_result = []
        for trade_type in ["new", "rev"]:
            for time in oppty_dur_dict[trade_type]:
                try:
                    # clone settings, balance factor settings, factor settings with original one
                    settings_clone = copy.deepcopy(settings)
                    bal_fact_set_clone = copy.deepcopy(bal_factor_settings)
                    fact_set_clone = copy.deepcopy(factor_settings)

                    # apply each oppty duration
                    settings_clone["start_time"] = time[0]
                    settings_clone["end_time"] = time[1]

                    # convert to local time
                    st_local = Global.convert_epoch_to_local_datetime(
                        time[0], timezone="kr")
                    et_local = Global.convert_epoch_to_local_datetime(
                        time[1], timezone="kr")
                    logging.error("Now in: [%s] start_time: %s, end_time: %s" %
                                  (trade_type.upper(), st_local, et_local))

                    # initial dry run -> get new, rev oppty count
                    new_oppty_count, rev_oppty_count = super().count_oppty_num(
                        settings_clone, cls.default_initial_setting_dict)

                    # opt initial settings by oppty
                    fact_set_clone = cls.opt_factor_settings_by_oppty(
                        fact_set_clone, new_oppty_count, rev_oppty_count)
                    # opt balance_settings by oppty
                    bal_fact_set_clone = cls.opt_balance_settings_by_oppty(
                        bal_fact_set_clone, new_oppty_count, rev_oppty_count)

                    # create coin balance proportionate current exchange rate
                    bal_fact_set_clone = IBO.create_coin_bal_from_krw_bal_by_exchange_rate(
                        settings_clone, bal_fact_set_clone)

                    # add init step for balance settings and initial settings
                    cls.init_initial_step(settings_clone, bal_fact_set_clone,
                                          fact_set_clone)

                    # run recursive
                    iyo_opt_result = cls.opt_by_bal_and_init_settings_recursive(
                        settings_clone, bal_fact_set_clone, fact_set_clone,
                        settings_clone["depth"])

                    # append original oppty count to final result
                    iyo_opt_result["new_oppty_count"] = new_oppty_count
                    iyo_opt_result["rev_oppty_count"] = rev_oppty_count

                    db_result.append(iyo_opt_result)

                except Exception as e:
                    logging.error(
                        "Something went wrong while executing IYO loop!", time,
                        e)

        # finally run IYO Stat appender and return final result
        return db_result
예제 #4
0
    def trading_mode_looper(self):

        trading_loop_count = 0
        while True:

            # check if reached settlement time
            if self.trading_mode_now_time > self._settlement_time:
                self.settlement_handler()
                break

            try:
                # update balance & time
                self.trading_mode_now_time = int(time.time())

                # run trading_mode
                trading_loop_count += 1

                self.run_trading_mode_analysis(trading_loop_count)

                # log rev ledger info
                self.log_balance_tracker()

                # sleep by Trading Mode Loop Interval
                self.trading_mode_loop_sleep_handler(self.trading_mode_now_time, int(time.time()),
                                                     self.TRADING_MODE_LOOP_INTERVAL)
            except Exception as e:
                log = "Error occured while executing Trade Streamer - Trading mode..\n" + str(e)
                logging.error(log)
                Global.send_to_slack_channel(Global.SLACK_STREAM_STATUS_URL, log)
    def log_init_mode_mctu_info(self):
        local_anal_st = Global.convert_epoch_to_local_datetime(
            self.ocat_rewind_time, timezone="kr")
        local_anal_et = Global.convert_epoch_to_local_datetime(
            self.streamer_start_time, timezone="kr")

        logging.warning("=========== [MCTU INFO] ==========")
        logging.warning("[Anal Duration]: %s - %s" %
                        (local_anal_st, local_anal_et))

        target_dict = self.rec_instance.spread_dict["init"]
        for trade_type in target_dict.keys():
            logging.warning(
                "['%s' SPREAD RECORDER]:\n%s" %
                (trade_type.upper(),
                 self.get_mctu_spread_and_frequency(target_dict[trade_type])))

        self.th_instance.NEW["normal"] = float(
            input("Decide [NEW] MCTU spread threshold: "))
        self.th_instance.NEW["royal"] = float(
            input("Decide [NEW] MCTU Royal spread: "))
        self.th_instance.REV["normal"] = float(
            input("Decide [REV] MCTU spread threshold: "))
        self.th_instance.REV["royal"] = float(
            input("Decide [REV] MCTU Royal spread: "))
예제 #6
0
    def get_factor_settings(mm1_name: str, mm2_name: str, target_currency: str,
                            max_trade_coin_end: float, threshold_end: int,
                            appx_unit_coin_price: int):

        trading_coin_limit = (1000 / appx_unit_coin_price)
        min_trading_coin = int(
            max(Global.read_min_trading_coin(mm1_name, target_currency),
                Global.read_min_trading_coin(mm2_name, target_currency)))

        return {
            "max_trading_coin": {
                "start": 0,
                "end": max_trade_coin_end,
                "step_limit": float(trading_coin_limit)
            },
            "min_trading_coin": {
                "start": min_trading_coin,
                "end": min_trading_coin,
                "step_limit": 0
            },
            "new": {
                "threshold": {
                    "start": 0,
                    "end": threshold_end,
                    "step_limit": 1
                }
            },
            "rev": {
                "threshold": {
                    "start": 0,
                    "end": threshold_end,
                    "step_limit": 1
                }
            }
        }
예제 #7
0
    def rfab2_ots_to_csv(self, mm1_db: str, mm2_db: str, mm1_fee: float,
                         mm2_fee: float, target_currency: str, start_time: int,
                         end_time: int, depth: int):
        mm1_orderbook_col = self.mongo_client[mm1_db][target_currency +
                                                      "_orderbook"]
        mm2_orderbook_col = self.mongo_client[mm2_db][target_currency +
                                                      "_orderbook"]
        mm1_orderbook_cursor = mm1_orderbook_col.find({
            "requestTime": {
                "$gte": start_time,
                "$lte": end_time
            }
        }).sort([("requestTime", 1)])
        mm2_orderbook_cursor = mm2_orderbook_col.find({
            "requestTime": {
                "$gte": start_time,
                "$lte": end_time
            }
        }).sort([("requestTime", 1)])

        csv_writer = CsvWriter(
            "stat", "%s-%s_%s_OTS_in_CSV_%d_%d_%d_max-index" %
            (mm1_db, mm2_db, target_currency, start_time, end_time, depth),
            ("requestTime", "Trade type", "Spread in unit", "Buy Price",
             "Buy Index", "Sell Price", "Sell index", "Tradable Spread",
             "Tradable Qty"))

        mm1_count = mm1_orderbook_cursor.count()
        mm2_count = mm2_orderbook_cursor.count()

        if mm1_count != mm2_count:
            Global.request_time_validation_on_cursor_count_diff(
                mm1_orderbook_cursor, mm2_orderbook_cursor)
        else:
            print("number of 'mm1 and mm2 requestTime' matched perfectly!!")

        for mm1_ob, mm2_ob in zip(mm1_orderbook_cursor, mm2_orderbook_cursor):

            requesttime = mm1_ob["requestTime"]
            (new_unit_spread, rev_unit_spread, opt_new_spread, opt_rev_spread,
             opt_new_buy_price, opt_new_buy_index, opt_new_sell_price, opt_new_sell_index, new_traded_qty,
             opt_rev_buy_price, opt_rev_buy_index, opt_rev_sell_price, opt_rev_sell_index, rev_traded_qty) = \
                BasicAnalyzer.optimized_tradable_spread_strategy(mm1_ob, mm2_ob, mm1_fee, mm2_fee, depth)

            result = [requesttime]
            if opt_new_spread >= 0:
                result.extend([
                    "NEW", new_unit_spread, opt_new_buy_price,
                    opt_new_buy_index, opt_new_sell_price, opt_new_sell_index,
                    opt_new_spread, new_traded_qty
                ])
                csv_writer.write_joinable(result)
            elif opt_rev_spread >= 0:
                result.extend([
                    "REV", rev_unit_spread, opt_rev_buy_price,
                    opt_rev_buy_index, opt_rev_sell_price, opt_rev_sell_index,
                    opt_rev_spread, rev_traded_qty
                ])
                csv_writer.write_joinable(result)
        csv_writer.close()
예제 #8
0
def main(target_currency: str, mm1_name: str, mm2_name: str):
    Global.configure_default_root_logging(should_log_to_file=False, log_level=logging.INFO)
    SharedMongoClient.initialize(should_use_localhost_db=True)

    mm1 = Global.get_market_manager(mm1_name)
    mm2 = Global.get_market_manager(mm2_name)

    RiskFreeArbBotV4(target_currency, mm1, mm2, is_test=True).run()
예제 #9
0
    def update_bal_seq_end_by_recent_bal_init_mode(self):

        rough_exhaust_divider = self.EXHAUST_CTRL_DIVISION
        Global.write_balance_seq_end_to_ini(
            krw_seq_end=(self.mm1_krw_bal + self.mm2_krw_bal) /
            rough_exhaust_divider,
            coin_seq_end=(self.mm1_coin_bal + self.mm2_coin_bal) /
            rough_exhaust_divider)
예제 #10
0
    def __init__(self):
        # init root logger
        Global.configure_default_root_logging()
        # set the log level for the schedule
        # in order not to display any extraneous log
        logging.getLogger("schedule").setLevel(logging.CRITICAL)

        # add SIGTERM handler
        signal.signal(signal.SIGTERM, self.handle_sigterm)
def main(target_currency: str, mm1_name: str, mm2_name: str):
    Global.configure_default_root_logging(should_log_to_file=True, log_level=logging.INFO)
    SharedMongoClient.initialize(should_use_localhost_db=True)

    mm1 = Global.get_market_manager(mm1_name)
    mm2 = Global.get_market_manager(mm2_name)

    # run TradeStreamer
    TradeStreamerV2(mm1=mm1, mm2=mm2, target_currency=target_currency, is_test=False).run()
    def settlement_handler(self):
        message = "Settlement reached!! now closing Trade Streamer!!"
        logging.warning(message)
        Global.send_to_slack_channel(Global.SLACK_STREAM_STATUS_URL, message)

        # set settle cond True
        self.cond_instance.is_settlement = True

        # command Acutal Trader to stop
        self.update_trade_commander_to_user_mongo()
    def update_trade_condition_by_mtcu_analyzer(self):
        """mtcu: Min Tradable Coin Unit
        """

        mm1_rq = Global.convert_epoch_to_local_datetime(self.mm1_ob["requestTime"], timezone="kr")
        mm2_rq = Global.convert_epoch_to_local_datetime(self.mm2_ob["requestTime"], timezone="kr")

        logging.warning("[REQUEST TIME] -- mm1: %s, mm2: %s\n" % (mm1_rq, mm2_rq))

        # analyze by MCTS
        spread_info_dict = MCTSAnalyzer.min_coin_tradable_spread_strategy(self.mm1_ob, self.mm2_ob,
                                                                          self.mm1.taker_fee,
                                                                          self.mm2.taker_fee,
                                                                          self.streamer_min_trading_coin)

        new_cond = spread_info_dict["new"].able_to_trade
        rev_cond = spread_info_dict["rev"].able_to_trade

        logging.warning("========= [OPPTY NOTIFIER] ========")
        # if there is no Oppty,
        if new_cond is False and rev_cond is False:
            self.cond_instance.NEW["is_oppty"] = False
            self.cond_instance.NEW["is_royal"] = False
            self.cond_instance.REV["is_oppty"] = False
            self.cond_instance.REV["is_royal"] = False

            logging.error("[WARNING] There is no oppty.. Waiting")
            logging.error("=> [NEW] Fail reason: %s" % spread_info_dict["new"].fail_reason)
            logging.error("=> [REV] Fail reason: %s\n" % spread_info_dict["rev"].fail_reason)
            return

        # if oppty (NEW or REV)
        for trade_type in spread_info_dict.keys():
            if not spread_info_dict[trade_type].able_to_trade:
                getattr(self.cond_instance, trade_type.upper())["is_oppty"] = False
                getattr(self.cond_instance, trade_type.upper())["is_royal"] = False
                continue

            logging.critical("[HOORAY] [%s] Oppty detected!!! now evaluating spread infos.." % trade_type.upper())
            logging.critical("[SPREAD TO TRADE]: %.4f\n" % spread_info_dict[trade_type].spread_to_trade)

            getattr(self.cond_instance, trade_type.upper())["is_oppty"] = True

            # if gte royal spread,
            if spread_info_dict[trade_type].spread_to_trade >= getattr(self.th_instance, trade_type.upper())["royal"]:
                getattr(self.cond_instance, trade_type.upper())["is_royal"] = True
                logging.critical("[!CONGRAT!] THIS WAS ROYAL SPREAD!! Now command to trade no matter what!! :D")
            else:
                getattr(self.cond_instance, trade_type.upper())["is_royal"] = False

            # get spread_to_trade list from min_trdble_coin_sprd_list
            self.rec_instance.spread_dict["trade"][trade_type].extend(
                [{"spread_to_trade": spread_info_dict[trade_type].spread_to_trade,
                  "sell_amt": spread_info_dict[trade_type].sell_order_amt,
                  "buy_amt": spread_info_dict[trade_type].buy_order_amt}])
예제 #14
0
 def send_result_nicely_to_slack(cls, final_sorted_list: list,
                                 start_date: str, end_date: str):
     to_be_sent = str("[OTC start date: %s, end date: %s]\n" %
                      (start_date, end_date))
     for result in final_sorted_list:
         new_percent = (result["new"] / cls.time_dur_to_anal) * 100
         rev_percent = (result["rev"] / cls.time_dur_to_anal) * 100
         to_be_sent += ("[%s]\n NEW: %.2f%%, REV: %.2f%%\n" %
                        (result["combination"], new_percent, rev_percent))
     Global.send_to_slack_channel(Global.SLACK_OTC_SCHEDUELR_URL,
                                  to_be_sent)
예제 #15
0
    def get_oppty_dur_human_time(oppty_dur_dict: dict, timezone: str):
        final_dict = dict()
        for key in ["new", "rev"]:
            result_list = []
            for time_dur in oppty_dur_dict[key]:
                human_st = Global.convert_epoch_to_local_datetime(time_dur[0], timezone=timezone)
                human_et = Global.convert_epoch_to_local_datetime(time_dur[1], timezone=timezone)
                result_list.append([human_st, human_et])
            final_dict[key] = result_list

        return final_dict
예제 #16
0
    def run(self):
        # do nothing if the market of order is not watchable
        if not self.is_watchable(self.order):
            return

        # add in order watcher stats
        OrderWatcherStats.started(self.order.order_id)

        # log initial time
        initial_time = time.time()

        try:
            while (self.order.status is not OrderStatus.FILLED) and (
                    self.order.status is not OrderStatus.CANCELLED):
                start_time = time.time()
                self.do_interval()
                end_time = time.time()

                # if current time has exceeded the max_wait_sec
                if not self.is_delayed:
                    time_check = end_time - initial_time
                    if time_check > self.delayed_flag_sec:
                        self.is_delayed = True
                        OrderWatcherStats.delayed(self.order.order_id)
                        message = "Order %s has exceeded delayed flag time! " \
                                  "Counter measures are expected to be executed manually!" % self.order.order_id
                        logging.critical(message)
                        Global.send_to_slack_channel(
                            Global.SLACK_BOT_STATUS_URL, message)

                # wait for the target interval
                wait_time = self.interval_sec - (end_time - start_time)
                if wait_time > 0:
                    time.sleep(wait_time)

            # if it is filled
            if self.order.status is OrderStatus.FILLED:
                OrderWatcherStats.done(self.order.order_id)
                # if sell, krw as fee
                # if buy, coin as fee
                if self.order.is_sell_order():
                    GlobalFeeAccumulator.add_fee_expenditure(
                        self.order.market, "krw", self.order.fee)
                else:
                    GlobalFeeAccumulator.add_fee_expenditure(
                        self.order.market, self.order.currency.name.lower(),
                        self.order.fee)
            elif self.order.status is OrderStatus.CANCELLED:
                OrderWatcherStats.cancelled(self.order.order_id)

        except Exception as e:
            # if there was any error for some unexpected reasons
            OrderWatcherStats.error(self.order.order_id)
            logging.error(e)
    def log_trading_mode_mtcu_info(self, anal_start_time: int, anal_end_time: int):
        local_anal_st = Global.convert_epoch_to_local_datetime(anal_start_time, timezone="kr")
        local_anal_et = Global.convert_epoch_to_local_datetime(anal_end_time, timezone="kr")

        logging.warning("=========== [MCTU INFO] ==========")
        logging.warning("[Anal Duration]: %s - %s" % (local_anal_st, local_anal_et))

        target_dict = self.rec_instance.spread_dict["trade"]
        for trade_type in target_dict.keys():
            logging.warning("\n\n[ '%s' SPREAD RECORDER]:\n%s"
                            % (trade_type.upper(),
                               self.get_mtcu_spread_and_frequency(target_dict[trade_type])))
예제 #18
0
def main(target_currency: str, mm1: MarketManager, mm2: MarketManager,
         mm1_name: str, mm2_name: str, mm1_krw_bal: float, mm1_coin_bal: float,
         mm2_krw_bal: float, mm2_coin_bal: float):
    Global.configure_default_root_logging(should_log_to_file=False,
                                          log_level=logging.WARNING)
    SharedMongoClient.initialize(should_use_localhost_db=False)

    trade_streamer = TestTradeStreamer(target_currency, mm1, mm2, mm1_name,
                                       mm2_name, mm1_krw_bal, mm1_coin_bal,
                                       mm2_krw_bal, mm2_coin_bal)

    trade_streamer.real_time_streamer()
예제 #19
0
    def settlement_handler(self):
        logging.critical("Settlement Reached! Stopping RFAB Actual Trader")
        logging.warning(
            "========== [ SETTLEMENT BALANCE ] ========================================================")
        logging.warning(self.mm1.get_balance())
        logging.warning(self.mm2.get_balance())

        # send to Slack
        Global.send_to_slack_channel(Global.SLACK_BOT_STATUS_URL,
                                     "Settlement Reached! Stopping RFAB Actual Trader")

        # teardown OrderWatcher
        OrderWatcherStats.instance().tear_down()
예제 #20
0
    def update_bal_seq_end_by_recent_bal_and_exhaust_ctrl(self):

        # update exhaust_ctrl_currency
        trade_strategy = self.update_exhaust_ctrl_target_currency()

        # update exhaust_ctrl_stage
        self.update_exhaust_stage_and_iyo_config()

        # evaluate current exhaust rate and decide whether to boost or inhibit
        current_exhaust_rate = 1 - (self.cur_exhaust_ctrl_currency_bal /
                                    self.init_exhaust_ctrl_currency_bal)

        if current_exhaust_rate <= self.cur_exhaust_ctrl_stage / self.EXHAUST_CTRL_DIVISION:
            exhaust_rate_divider = self.EXHAUST_CTRL_DIVISION / self.EXHAUST_CTRL_BOOSTER
        else:
            exhaust_rate_divider = self.EXHAUST_CTRL_DIVISION / self.EXHAUST_CTRL_INHIBITOR

        # finally, create seq with initial bal and evaluated divider
        latest_rev_ledger = self.streamer_db["revenue_ledger"].find_one(
            sort=[('_id', pymongo.DESCENDING)])
        if trade_strategy == "new":
            current_krw_be_traded = latest_rev_ledger["current_bal"]["krw"][
                "mm1"]
            current_coin_be_traded = latest_rev_ledger["current_bal"]["coin"][
                "mm2"]

        elif trade_strategy == "rev":
            current_krw_be_traded = latest_rev_ledger["current_bal"]["krw"][
                "mm2"]
            current_coin_be_traded = latest_rev_ledger["current_bal"]["coin"][
                "mm1"]
        else:
            raise Exception(
                "Invalid type of trade strategy injected.. should be one of NEW or REV"
            )

        krw_seq_end = current_krw_be_traded / exhaust_rate_divider
        coin_seq_end = current_coin_be_traded / exhaust_rate_divider

        # update Balance seq end accordingly
        Global.write_balance_seq_end_to_ini(krw_seq_end=krw_seq_end,
                                            coin_seq_end=coin_seq_end)

        # log its result in order to analyze deeper
        logging.warning("\n========= [EXHAUSTION INFO Report] =========")
        logging.warning("Current Exhst rate: %.4f" % current_exhaust_rate)
        logging.warning("Current Exhst Ctrl Stage: %d" %
                        self.cur_exhaust_ctrl_stage)
        logging.warning("[KRW] seq end: %.5f" % krw_seq_end)
        logging.warning("[%s] seq end: %.5f\n" %
                        (self.target_currency.upper(), coin_seq_end))
예제 #21
0
    def iyo_result_to_mongo_db(coin_name: str, start_time: int, end_time: int):
        Global.configure_default_root_logging(should_log_to_file=False,
                                              log_level=logging.CRITICAL)
        SharedMongoClient.initialize(should_use_localhost_db=True)
        db_client = SharedMongoClient.instance()

        # convert epoch time to local_time and log
        local_st = Global.convert_epoch_to_local_datetime(start_time,
                                                          timezone="kr")
        local_et = Global.convert_epoch_to_local_datetime(end_time,
                                                          timezone="kr")

        # create combination of coin that is injected by validating if the exchange has that coin
        rfab_combi_list = Global.get_rfab_combination_tuples(coin_name)

        for _combi in rfab_combi_list:
            logging.critical(
                "[%s-%s-%s] IYO conducting -> start_time: %s, end_time: %s" %
                (coin_name.upper(), str(_combi[0]).upper(), str(
                    _combi[1]).upper(), local_st, local_et))

            # draw iyo_config for bal & factor_setting
            iyo_config = Global.read_iyo_setting_config(coin_name)

            settings = TradeSettingConfig.get_settings(
                mm1_name=_combi[0],
                mm2_name=_combi[1],
                target_currency=coin_name,
                start_time=start_time,
                end_time=end_time,
                division=iyo_config["division"],
                depth=iyo_config["depth"],
                consecution_time=iyo_config["consecution_time"],
                is_virtual_mm=True)
            # todo
            bal_factor_settings = TradeSettingConfig.get_bal_fact_settings(
                iyo_config["krw_seq_end"], iyo_config["coin_seq_end"])

            factor_settings = TradeSettingConfig.get_factor_settings(
                _combi[0], _combi[1], coin_name,
                iyo_config["max_trade_coin_end"], iyo_config["threshold_end"],
                iyo_config["appx_unit_coin_price"])

            try:
                iyo_result = IntegratedYieldOptimizer.run(
                    settings, bal_factor_settings, factor_settings)

                # finally save to mongoDB
                if len(iyo_result) > 0:
                    db_client["statistics"]["iyo"].insert_many(iyo_result)
                else:
                    logging.critical(
                        "There was no oppty!! Skipping to next combination!")
                    continue

            except TypeError as e:
                Global.send_to_slack_channel(
                    Global.SLACK_BOT_STATUS_URL,
                    "Something went wrong in IYO Schduler! >> %s" % e)
                pass
예제 #22
0
def main(coin_name: str, mm1_name: str, mm2_name: str, start_time: str,
         end_time: str, slicing_interval: int):
    Global.configure_default_root_logging(should_log_to_file=False,
                                          log_level=logging.INFO)
    SharedMongoClient.initialize(should_use_localhost_db=False)

    logging.warning("Nohup conducting -> start_time: %s, end_time: %s" %
                    (start_time, end_time))
    # Global.send_to_slack_channel("IYO Initiated!! start_time: %s, end_time: %s" % (prev_time, cur_time))

    start_time = Global.convert_local_datetime_to_epoch(start_time,
                                                        timezone="kr")
    end_time = Global.convert_local_datetime_to_epoch(end_time, timezone="kr")

    # draw iyo_config for bal & factor_setting
    iyo_config = Global.read_sliced_iyo_setting_config(coin_name)

    logging.critical(
        "[%s-%s-%s] IYO conducting -> start_time: %s, end_time: %s" %
        (coin_name.upper(), mm1_name.upper(), mm2_name.upper(), start_time,
         end_time))

    # set settings, bal_fact_settings, factor_settings
    settings = TradeSettingConfig.get_settings(
        mm1_name=mm1_name,
        mm2_name=mm2_name,
        target_currency=coin_name,
        start_time=start_time,
        end_time=end_time,
        division=iyo_config["division"],
        depth=iyo_config["depth"],
        consecution_time=iyo_config["consecution_time"],
        is_virtual_mm=True)

    bal_factor_settings = TradeSettingConfig.get_bal_fact_settings(
        iyo_config["krw_seq_end"], iyo_config["coin_seq_end"])

    factor_settings = TradeSettingConfig.get_factor_settings(
        mm1_name, mm2_name, coin_name, iyo_config["max_trade_coin_end"],
        iyo_config["threshold_end"], iyo_config["appx_unit_coin_price"])

    iyo_result = IntegratedYieldOptimizer.run(
        settings,
        bal_factor_settings,
        factor_settings,
        is_stat_appender=False,
        is_slicing_dur=True,
        slicing_interval=slicing_interval)
    logging.critical("Final IYO result: %s" % iyo_result)
    return iyo_result
def main(target_currency: str, mm1_name: str, mm2_name: str, st_local: str,
         et_local: str):
    Global.configure_default_root_logging(should_log_to_file=False)
    SharedMongoClient.initialize(should_use_localhost_db=False)

    start_time = Global.convert_local_datetime_to_epoch(st_local,
                                                        timezone="kr")
    end_time = Global.convert_local_datetime_to_epoch(et_local, timezone="kr")

    mm1_taker_fee = Global.read_market_fee(mm1_name, True)
    mm1_maker_fee = Global.read_market_fee(mm1_name, False)
    mm2_taker_fee = Global.read_market_fee(mm2_name, True)
    mm2_maker_fee = Global.read_market_fee(mm2_name, False)

    mm1_market = getattr(Market, "VIRTUAL_%s" % mm1_name.upper())
    mm2_market = getattr(Market, "VIRTUAL_%s" % mm2_name.upper())

    bal_setting = {
        'mm1': {
            'krw_balance': 0,
            'coin_balance': 0.04475666666666667
        },
        'mm2': {
            'krw_balance': 333333.3333333333,
            'coin_balance': 0.0
        }
    }

    initial_setting_dict = {
        'max_trading_coin': 0.005,
        'min_trading_coin': 0,
        'new': {
            'threshold': 0,
            'factor': 1
        },
        'rev': {
            'threshold': 0,
            'factor': 1
        }
    }

    mm1 = VirtualMarketManager(mm1_market, mm1_taker_fee, mm1_maker_fee,
                               bal_setting["mm1"]["krw_balance"],
                               bal_setting["mm1"]["coin_balance"],
                               target_currency, True)
    mm2 = VirtualMarketManager(mm2_market, mm2_taker_fee, mm2_maker_fee,
                               bal_setting["mm2"]["krw_balance"],
                               bal_setting["mm2"]["coin_balance"],
                               target_currency, True)
    mm1_col = SharedMongoClient.get_target_col(mm1_market, target_currency)
    mm2_col = SharedMongoClient.get_target_col(mm2_market, target_currency)

    mm1_data_cursor, mm2_data_cursor = SharedMongoClient.get_data_from_db(
        mm1_col, mm2_col, start_time, end_time)
    RfabBacktester(mm1, mm2,
                   target_currency).run(mm1_data_cursor,
                                        mm2_data_cursor,
                                        initial_setting_dict,
                                        is_running_in_optimizer=False)
예제 #24
0
    def run(self):
        model = TopkNet(self.cfg).to(Global.DEVICE)
        Global.load_weight(model, self.W_PATH)
        model.eval()

        future_coords_offsets_pd = []
        timestamps = []
        agent_ids = []
        confs = []

        with torch.no_grad():
            dataiter = tqdm(self.test_dataloader)

            for data in dataiter:
                inputs = data["image"].to(Global.DEVICE)
                images = []
                samples_means, means, mixture_weights = model(inputs)

                fit_outputs = torch.stack([mean for mean in means], dim=1)

                fit_confidences = torch.stack(
                    [mixture_weight for mixture_weight in mixture_weights],
                    dim=1).squeeze()
                outputs = torch.zeros(fit_outputs.size(0), fit_outputs.size(1),
                                      fit_outputs.size(2), 2).to(Global.DEVICE)

                conf = []
                one_hot_el = torch.eye(3, 3)
                for i in range(fit_confidences.size(0)):
                    idx = torch.argmax(fit_confidences[i]).item()
                    conf.append(one_hot_el[idx])

                outputs[:, 0] = Utils.map_writer_from_image_to_world(
                    data, fit_outputs[:, 0, :, :], self.cfg)
                outputs[:, 1] = Utils.map_writer_from_image_to_world(
                    data, fit_outputs[:, 1, :, :], self.cfg)
                outputs[:, 2] = Utils.map_writer_from_image_to_world(
                    data, fit_outputs[:, 2, :, :], self.cfg)

                future_coords_offsets_pd.append(outputs.cpu().numpy().copy())
                timestamps.append(data["timestamp"].numpy().copy())
                agent_ids.append(data["track_id"].numpy().copy())
                confs.append(fit_confidences.cpu().numpy().copy())
                if (len(confs) == 10): break
        write_pred_csv(f'{Global.MULTI_MODE_SUBMISSION}',
                       timestamps=np.concatenate(timestamps),
                       track_ids=np.concatenate(agent_ids),
                       coords=np.concatenate(future_coords_offsets_pd),
                       confs=np.concatenate(confs))
예제 #25
0
    def __init__(self, market_tag: Market, market_api: MarketApi):
        self.market_tag = market_tag
        self.market_api = market_api
        self.taker_fee = Global.read_market_fee(
            exchange_name=self.market_tag.name, is_taker_fee=True)
        self.maker_fee = Global.read_market_fee(
            exchange_name=self.market_tag.name, is_taker_fee=False)

        # init fee accumulator
        GlobalFeeAccumulator.initialize_market(self.market_tag)

        # Note that updating balance is already included in initialization phase
        self.balance = Balance(self.get_market_name())
        self.update_balance()
        self.min_trading_coin_dict = dict()
    def set_initial_trade_setting(self):
        # set streamer_min_trading_coin
        self.MIN_TRDBLE_COIN_MULTIPLIER = float(input("Please indicate Min Tradable Coin Multiplier (gte 1.0): "))
        self.streamer_min_trading_coin \
            = max(Global.read_min_trading_coin(self.mm1_name, self.target_currency),
                  Global.read_min_trading_coin(self.mm2_name, self.target_currency)) * self.MIN_TRDBLE_COIN_MULTIPLIER

        # set settlement related var
        settle_hour = int(input("Please type settlement hour (int only): "))
        settle_min = int(input("Please type settlement minute (int only): "))
        anal_rewind_hr = int(input("Please type [Initiation Mode] Rewind hour (int only): "))
        self.TIME_DUR_OF_SETTLEMENT = settle_hour * 60 * 60 + settle_min * 60

        # set rewind time for MCTU anal init mode
        self.ocat_rewind_time = int(self.streamer_start_time - anal_rewind_hr * 60 * 60)
예제 #27
0
    def launch_oppty_sliced_iyo(self, anal_start_time: int,
                                rewinded_time: int):
        st_local = Global.convert_epoch_to_local_datetime(rewinded_time,
                                                          timezone="kr")
        et_local = Global.convert_epoch_to_local_datetime(anal_start_time,
                                                          timezone="kr")
        logging.critical(
            "[%s-%s-%s] Sliced IYO conducting -> , start_time: %s, end_time: %s"
            % (self.target_currency.upper(), self.mm1_name.upper(),
               self.mm2_name.upper(), st_local, et_local))

        # draw iyo_config for bal & factor_setting
        sliced_iyo_config = Global.read_sliced_iyo_setting_config(
            self.target_currency)
        # set settings, bal_fact_settings, factor_settings
        settings = TradeSettingConfig.get_settings(
            mm1_name=self.mm1_name,
            mm2_name=self.mm2_name,
            target_currency=self.target_currency,
            start_time=rewinded_time,
            end_time=anal_start_time,
            division=sliced_iyo_config["division"],
            depth=sliced_iyo_config["depth"],
            consecution_time=sliced_iyo_config["consecution_time"],
            is_virtual_mm=True)

        bal_factor_settings = TradeSettingConfig.get_bal_fact_settings(
            sliced_iyo_config["krw_seq_end"],
            sliced_iyo_config["coin_seq_end"])

        factor_settings = TradeSettingConfig.get_factor_settings(
            self.mm1_name, self.mm2_name, self.target_currency,
            sliced_iyo_config["max_trade_coin_end"],
            sliced_iyo_config["threshold_end"],
            sliced_iyo_config["appx_unit_coin_price"])
        try:
            slicied_iyo_result = IntegratedYieldOptimizer.run(
                settings,
                bal_factor_settings,
                factor_settings,
                is_stat_appender=False,
                is_slicing_dur=True,
                slicing_interval=sliced_iyo_config["slicing_interval"])
        # FIXME: type error는 커서 에러때문에...
        except IndexError or TypeError:
            slicied_iyo_result = None

        return slicied_iyo_result
예제 #28
0
    def execute_trade_loop(self, mm1_data=None, mm2_data=None):
        if not self.is_backtesting:
            self.trade_loop_start()

        # refresh cur_trade
        self.cur_trade = None

        try:
            self.actual_trade_loop(mm1_data, mm2_data)
        except Exception as e:
            log = "Error occured while executing trade loop.." + str(e)
            logging.error(log)
            Global.send_to_slack_channel(Global.SLACK_BOT_STATUS_URL, log)

        if not self.is_backtesting:
            self.trade_loop_end()
예제 #29
0
    def sort_exhaust_rate_opt_fti_result_by_min_avg_trade_interval(
            final_opted_fti_iyo_list: list):
        # if len(final_opted_fti_iyo_list) =! 1, then choose the best one
        if len(final_opted_fti_iyo_list) > 1:

            min_ti_sorted_fti_iyo_list = []
            min_trade_interval = None
            for fti_iyo_dict in final_opted_fti_iyo_list:

                # calc avg trade_interval of current iyo_dict
                avg_trade_interval = 0
                for iyo in fti_iyo_dict["fti_iyo_list"]:
                    avg_trade_interval += iyo["fti"]

                # sort by minimum
                if min_trade_interval is None:
                    min_trade_interval = avg_trade_interval
                    min_ti_sorted_fti_iyo_list.append(fti_iyo_dict)
                    continue
                if min_trade_interval > avg_trade_interval:
                    min_trade_interval = avg_trade_interval
                    min_ti_sorted_fti_iyo_list.clear()
                    min_ti_sorted_fti_iyo_list.append(fti_iyo_dict)
                if min_trade_interval == avg_trade_interval:
                    min_ti_sorted_fti_iyo_list.append(fti_iyo_dict)
                else:
                    continue
            return Global.find_middle_of_list(min_ti_sorted_fti_iyo_list)
        else:
            return final_opted_fti_iyo_list[0]
예제 #30
0
    def get_order_info(self, currency: GopaxCurrency, order: Order):
        path = "/orders/" + order.order_id
        headers = self.get_auth_headers("GET", path)
        res = self._session.get(self.BASE_URL + path, headers=headers)
        res_json = self.filter_successful_response(res)

        # note that if res_json is empty it will return empty
        # gopax api is currently removing the order entry when the order is completed or cancelled, which is very wrong.
        if res_json is None:
            return None

        fee_rate = Global.read_market_fee("gopax", is_taker_fee=True)

        order_amount = float(res_json["amount"])
        remain_amount = float(res_json["remaining"])
        filled_amount = order_amount - remain_amount
        avg_filled_price = int(float(res_json["price"]))

        if res_json["side"] == "buy":
            fee = filled_amount * fee_rate
        elif res_json["side"] == "sell":
            fee = avg_filled_price * filled_amount * fee_rate
        else:
            fee = "null"

        return {
            "status": OrderStatus.get(res_json["status"]),
            "avg_filled_price": avg_filled_price,
            "order_amount": order_amount,
            "filled_amount": filled_amount,
            "remain_amount": remain_amount,
            "fee": fee
        }