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)
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
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: "))
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 } } }
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()
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()
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)
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}])
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)
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
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])))
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()
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()
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))
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
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)
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))
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)
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
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()
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]
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 }