def save_mid_vwap_mid_price(self, target_db: str, target_currency: str, start_time: int, end_time: int, depth: int): orderbook_col = self.mongo_client[target_db][target_currency + "_orderbook"] orderbook_cursor = orderbook_col.find({ "requestTime": { "$gte": start_time, "$lte": end_time } }).sort([("requestTime", 1)]) csv_writer = CsvWriter( "stat", "%s_%s_mid_vwap_%d_%d_%d_depth" % (target_db, target_currency, start_time, end_time, depth), ("request_time", "mid_price", "mid_vwap", "ask_vwap", "bid_vwap", "minask", "maxbid")) for orderbook in orderbook_cursor: request_time = int(orderbook["requestTime"]) mid_price, minask, maxbid = BasicAnalyzer.get_orderbook_mid_price( orderbook) mid_vwap, ask_vwap, bid_vwap = BasicAnalyzer.get_orderbook_mid_vwap( orderbook, depth) csv_writer.write_joinable((request_time, mid_price, mid_vwap, ask_vwap, bid_vwap, minask, maxbid)) csv_writer.close()
def update_exhaust_ctrl_target_currency(self): # retrieve latest s_iyo from MongoDB and decide b/t NEW and REV latest_s_iyo = self.streamer_db["s_iyo"].find_one( sort=[('_id', pymongo.DESCENDING)]) latest_rev_ledger = self.streamer_db["revenue_ledger"].find_one( sort=[('_id', pymongo.DESCENDING)]) mm1_mid_price, _, _ = BasicAnalyzer.get_orderbook_mid_price( self.mm1.get_orderbook( self.mm1.get_market_currency(self.target_currency))) mm2_mid_price, _, _ = BasicAnalyzer.get_orderbook_mid_price( self.mm2.get_orderbook( self.mm2.get_market_currency(self.target_currency))) mid_price = (mm1_mid_price + mm2_mid_price) / 2 # IF NEW if latest_s_iyo["new_oppty_count"] >= latest_s_iyo["rev_oppty_count"]: trade_strategy = "new" krw_to_exhaust = latest_rev_ledger["current_bal"]["krw"]["mm1"] coin_to_exhaust = latest_rev_ledger["current_bal"]["coin"][ "mm2"] * mid_price # if krw bal is larger than coin converted to krw by real exchange rate, if krw_to_exhaust >= coin_to_exhaust: self.init_exhaust_ctrl_currency_bal = latest_rev_ledger[ "initial_bal"]["coin"]["mm2"] self.cur_exhaust_ctrl_currency_bal = latest_rev_ledger[ "current_bal"]["coin"]["mm2"] # if not, else: self.init_exhaust_ctrl_currency_bal = latest_rev_ledger[ "initial_bal"]["krw"]["mm1"] self.cur_exhaust_ctrl_currency_bal = latest_rev_ledger[ "current_bal"]["krw"]["mm1"] # IF REV else: trade_strategy = "rev" krw_to_exhaust = latest_rev_ledger["current_bal"]["krw"]["mm2"] coin_to_exhaust = latest_rev_ledger["current_bal"]["coin"][ "mm1"] * mid_price # if krw bal is larger than coin converted to krw by real exchange rate, if krw_to_exhaust >= coin_to_exhaust: self.init_exhaust_ctrl_currency_bal = latest_rev_ledger[ "initial_bal"]["coin"]["mm1"] self.cur_exhaust_ctrl_currency_bal = latest_rev_ledger[ "current_bal"]["coin"]["mm1"] # if not, else: self.init_exhaust_ctrl_currency_bal = latest_rev_ledger[ "initial_bal"]["krw"]["mm2"] self.cur_exhaust_ctrl_currency_bal = latest_rev_ledger[ "current_bal"]["krw"]["mm2"] return trade_strategy
def rate_to_dict(mm1_ob: dict, mm2_ob: dict, rev_ledger: dict): # get mid price _, mm1_mb = BasicAnalyzer.get_price_of_minask_maxbid(mm1_ob) _, mm2_mb = BasicAnalyzer.get_price_of_minask_maxbid(mm2_ob) # calc remaining currency bal to exhaust further init_bal_dict = rev_ledger["initial_bal"] cur_bal_dict = rev_ledger["current_bal"] new_krw_to_exhaust = cur_bal_dict["krw"]["mm1"] new_coin_to_exhaust = cur_bal_dict["coin"]["mm2"] * mm2_mb rev_krw_to_exhaust = cur_bal_dict["krw"]["mm2"] rev_coin_to_exhaust = cur_bal_dict["coin"]["mm1"] * mm1_mb # NEW exhaust # if krw bal is larger than coin converted to krw by real exchange rate, if new_krw_to_exhaust >= new_coin_to_exhaust: new_init_bal = init_bal_dict["coin"]["mm2"] new_cur_bal = cur_bal_dict["coin"]["mm2"] else: new_init_bal = init_bal_dict["krw"]["mm1"] new_cur_bal = cur_bal_dict["krw"]["mm1"] # REV exhaust # if krw bal is larger than coin converted to krw by real exchange rate, if rev_krw_to_exhaust >= rev_coin_to_exhaust: rev_init_bal = init_bal_dict["coin"]["mm1"] rev_cur_bal = cur_bal_dict["coin"]["mm1"] else: rev_init_bal = init_bal_dict["krw"]["mm2"] rev_cur_bal = cur_bal_dict["krw"]["mm2"] # in case cur bal > init bal (in case of inflow of new investment) if new_cur_bal > new_init_bal: new_cur_bal = new_init_bal if rev_cur_bal > rev_init_bal: rev_cur_bal = rev_init_bal return { "new": round(float(1 - (new_cur_bal / new_init_bal)), 5) if not new_init_bal == 0 else 1, "rev": round(float(1 - (rev_cur_bal / rev_init_bal)), 5) if not rev_init_bal == 0 else 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 get_krw_total_balance(self): # log balance mm1_balance = self.mm1.get_balance() mm2_balance = self.mm2.get_balance() combined = BasicAnalyzer.combine_balance(mm1_balance, mm2_balance, (self.target_currency, "krw")) return combined["KRW"]["balance"]
def get_mid_price_stat(mkt_tag: str, orderbook_cur: Cursor, target_dict: dict): mid_price_list = [] for orderbook in orderbook_cur: mid_price, _, _ = BasicAnalyzer.get_orderbook_mid_price(orderbook) mid_price_list.append(mid_price) # append mid_price avg, var, st.d to inner_infos_dict IYOStatAppender.calc_avg_var_std_data( target_dict[mkt_tag]["mid_price"], mid_price_list)
def calc_krw_coin_exchange_ratio_during_oppty_dur(settings: dict): mm1_col = SharedMongoClient.get_target_col( settings["mm1"]["market_tag"], settings["target_currency"]) mm2_col = SharedMongoClient.get_target_col( settings["mm2"]["market_tag"], settings["target_currency"]) mm1_cursor, mm2_cursor = SharedMongoClient.get_data_from_db( mm1_col, mm2_col, settings["start_time"], settings["end_time"]) # get average mid exchange krw price in terms of unit coin during designated time_dur mid_price_list = [] for mm1_data, mm2_data in zip(mm1_cursor, mm2_cursor): mm1_mid_price, _, _, = BasicAnalyzer.get_orderbook_mid_price( mm1_data) mm2_mid_price, _, _, = BasicAnalyzer.get_orderbook_mid_price( mm2_data) combined_mid_price = (mm1_mid_price + mm2_mid_price) / 2 mid_price_list.append(combined_mid_price) return sum(mid_price_list) / len(mid_price_list)
def log_combined_balance(self, mm1_balance, mm2_balance): # log combined balance combined = BasicAnalyzer.combine_balance(mm1_balance, mm2_balance, (self.target_currency, "krw")) for coin_name in combined.keys(): balance = combined[coin_name] logging.info( "[TOTAL %s]: available - %.4f, trade_in_use - %.4f, balance - %.4f" % (coin_name, balance["available"], balance["trade_in_use"], balance["balance"]))
def get_spread_info(cls, mm1_orderbook: dict, mm2_orderbook: dict, mm1_taker_fee: float, mm2_taker_fee: float): # mm1 price mm1_minask_price, mm1_maxbid_price = BasicAnalyzer.get_price_of_minask_maxbid(mm1_orderbook) # mm2 price mm2_minask_price, mm2_maxbid_price = BasicAnalyzer.get_price_of_minask_maxbid(mm2_orderbook) # calc new, rev mid price new_mid_price = np.average([mm1_minask_price, mm2_maxbid_price]) rev_mid_price = np.average([mm1_maxbid_price, mm2_minask_price]) # new => buy in mm1, sell in mm2 new_unit_spread = cls.get_unit_spread_info(mm1_minask_price, mm1_taker_fee, mm2_maxbid_price, mm2_taker_fee) # rev => buy in mm2, sell in mm1 rev_unit_spread = cls.get_unit_spread_info(mm2_minask_price, mm2_taker_fee, mm1_maxbid_price, mm1_taker_fee) new_spread_ratio = new_unit_spread / new_mid_price rev_spread_ratio = rev_unit_spread / rev_mid_price return new_unit_spread, rev_unit_spread, new_spread_ratio, rev_spread_ratio, new_mid_price, rev_mid_price
def save_processed_info(self, target_db: str, target_currency: str, start_time: int, end_time: int): ticker_col = self.mongo_client[target_db][target_currency + "_ticker"] orderbook_col = self.mongo_client[target_db][target_currency + "_orderbook"] ticker_cursor = ticker_col.find({ "requestTime": { "$gte": start_time, "$lte": end_time } }).sort([("requestTime", 1)]) orderbook_cursor = orderbook_col.find({ "requestTime": { "$gte": start_time, "$lte": end_time } }).sort([("requestTime", 1)]) ticker_count = ticker_cursor.count() orderbook_count = orderbook_cursor.count() csv_writer = CsvWriter( "stat", "%s_%s_processed_%d_%d" % (target_db, target_currency, start_time, end_time), ("requestTime", "ticker", "midPrice", "minAsk", "maxBid")) if ticker_count != orderbook_count: Global.request_time_validation_on_cursor_count_diff( ticker_cursor, orderbook_cursor) for ticker, orderbook in zip(ticker_cursor, orderbook_cursor): request_time = int(ticker["requestTime"]) last = int(ticker["last"].to_decimal()) mid_price, minask, maxbid = BasicAnalyzer.get_orderbook_mid_price( orderbook) csv_writer.write_joinable( (request_time, last, mid_price, minask, maxbid)) csv_writer.close()
def log_common_stat(self, log_level: int = logging.INFO): # log trade stat trade_total = self.trade_manager.get_trade_count() trade_new = self.trade_manager.get_trade_count(TradeTag.NEW) trade_rev = self.trade_manager.get_trade_count(TradeTag.REV) try: logging.log(log_level, "[STAT] total trades: %d, new trades: %d(%.2f%%), rev trades: %d(%.2f%%)" % (trade_total, trade_new, trade_new / trade_total * 100, trade_rev, trade_rev / trade_total * 100)) except ZeroDivisionError: logging.log(log_level, "[STAT] total trades: 0, new trades: 0, rev trades: 0") # log opportunity counter logging.log(log_level, "[STAT] total oppty: %d, new oppty: %d, rev oppty: %d" % (self.new_oppty_counter + self.rev_oppty_counter, self.new_oppty_counter, self.rev_oppty_counter)) # log switch over stat last_switch_over = self.trade_manager.get_last_switch_over() logging.log(log_level, "[STAT] switch over - count: %d, average: %.2f sec, last: %.2f sec \n" % (self.trade_manager.get_switch_over_count(), self.trade_manager.get_average_switch_over_spent_time(), last_switch_over.get("spent_time") if last_switch_over is not None else 0)) # log balance mm1_balance = self.mm1.get_balance() mm2_balance = self.mm2.get_balance() logging.log(log_level, mm1_balance) logging.log(log_level, mm2_balance) # log combined balance combined = BasicAnalyzer.combine_balance(mm1_balance, mm2_balance, (self.target_currency, "krw")) for coin_name in combined.keys(): balance = combined[coin_name] logging.log(log_level, "\n[TOTAL %s]: available - %.4f, trade_in_use - %.4f, balance - %.4f" % (coin_name, balance["available"], balance["trade_in_use"], balance["balance"]))