def __init__(self, custom_strategy): logger.info("[BuyThread][run] __init__") threading.Thread.__init__(self) self.custom_strategy = custom_strategy singleton_data.instance().setAllowSell(False) singleton_data.instance().setBuyThread(True) # default(20.0) * (current_quantity / max_order_quantity) # The maximum value is the default even if the quantity you have now is greater than max_order. # MAX = default(20.0) # The more bulk_net_buy orders, the higher the price. currentQty = self.custom_strategy.exchange.get_currentQty() logger.info("[BuyThread][run] MAX_ORDER_QUENTITY : " + str(settings.MAX_ORDER_QUENTITY)) self.minBuyingGap = 50.0 if abs(currentQty) >= settings.MAX_ORDER_QUENTITY: #self.minBuyingGap = self.minBuyingGap + settings.MIN_BUYING_GAP self.minBuyingGap = self.minBuyingGap else: #self.minBuyingGap = self.minBuyingGap + float(settings.MIN_BUYING_GAP) * float(abs(currentQty) / settings.MAX_ORDER_QUENTITY) self.minBuyingGap = self.minBuyingGap + float( settings.MIN_BUYING_GAP) - float( settings.MIN_BUYING_GAP) * float( abs(currentQty) / settings.MAX_ORDER_QUENTITY) logger.info("[BuyThread][run] minBuyingGap : " + str(self.minBuyingGap)) self.waiting_buy_order = {} self.wait_cnt = 0
def bulk_net_sell(custom_strategy): current_price = custom_strategy.exchange.get_instrument( )['lastPrice'] + 0.5 logger.info("[net_order][normal_sell] current_price(2) : " + str(current_price)) sell_orders = [] #order_cnt = round(settings.DEFAULT_ORDER_COUNT * 4 / 7) super_trend = custom_strategy.analysis_15m['SuperTrend'][0] order_cnt = settings.DEFAULT_ORDER_COUNT order_dist = get_order_dist(current_price, super_trend, order_cnt) default_Qty = get_qty(99, current_price + (order_cnt - 1) * order_dist) #default_Qty = settings.DEFAULT_ORDER_PRICE logger.info("[net_order][bulk_net_sell] default_Qty : " + str(default_Qty)) # manual #current_price = 9400.0 total_qty = 0 for i in range(1, order_cnt + 1): if current_price + ((i - 1) * order_dist) > super_trend: break if i == 1: sell_orders.append({ 'price': current_price - order_dist * 10, 'orderQty': default_Qty * 2, 'side': "Sell" }) sell_orders.append({ 'price': current_price + ((i - 1) * order_dist), 'orderQty': default_Qty * 2, 'side': "Sell", 'execInst': "ParticipateDoNotInitiate" }) else: sell_orders.append({ 'price': current_price + ((i - 1) * order_dist), 'orderQty': default_Qty, 'side': "Sell", 'execInst': "ParticipateDoNotInitiate" }) total_qty = total_qty + default_Qty ret = custom_strategy.converge_orders(sell_orders, []) check_caceled_order(custom_strategy, ret, 'Sell') logger.info("[net_order][bulk_net_sell] order length : " + str(len(ret))) logger.info("[net_order][bulk_net_sell] order : " + str(ret)) settings.MAX_ORDER_QUENTITY = total_qty logger.info("[net_order][bulk_net_sell] MAX_ORDER_QUENTITY : " + str(settings.MAX_ORDER_QUENTITY)) singleton_data.instance().setAllowSell(False) logger.info("[net_order][bulk_net_sell] getAllowSell() " + str(singleton_data.instance().getAllowSell()))
def setInitOHLC(self): logger.info("[OrderManager][setInitOHLC]") # 1 min bin1m_df = self.getBinData('1m') singleton_data.instance().setOHLC_1m_data(bin1m_df) # 5 mins bin5m_df = self.getBinData('5m') singleton_data.instance().setOHLC_5m_data(bin5m_df)
def check_buy_order(self, avgCostPrice): # checking whether or not it's sold ret = False buy_orders = self.custom_strategy.exchange.get_orders('Buy') logger.info("[BuyThread][check_buy_order] buy_orders : " + str(buy_orders)) if len(buy_orders) == 0: # buying complete logger.info("[BuyThread][check_buy_order] buying complete!") self.custom_strategy.exchange.cancel_all_orders('All') singleton_data.instance().setAveDownCnt(0) # expectedProfit 수정 필요 #logger.info("[BuyThread][check_buy_order] ###### profit : + " + str(self.expectedProfit) + "$ ######") #execute_logger.info("###### profit : + " + str(self.expectedProfit) + "$ ######") ret = True self.waiting_buy_order = {} elif len(buy_orders) == 1: current_price = self.custom_strategy.exchange.get_instrument( )['lastPrice'] if not float(current_price) < float(avgCostPrice) - float( self.minBuyingGap): logger.info("[BuyThread][check_buy_order] current_price(" + str(current_price) + ") < avgCostPrice(" + str(avgCostPrice) + ") - minBuyingGap(" + str(self.minBuyingGap) + ")") self.waiting_buy_order = {} self.custom_strategy.exchange.cancel_all_orders('Buy') ret = False # 3.0 move to settings elif float(current_price) - float(buy_orders[0]['price']) > 3.0: # flee away 3$ form first oder_price, amend order # reorder self.waiting_buy_order = self.make_buy_order() self.waiting_buy_order_copy = deepcopy(self.waiting_buy_order) logger.info( "[BuyThread][check_buy_order] reorder current_price + 3$ : waiting_buy_order : " + str(self.waiting_buy_order)) else: logger.info( "[BuyThread][check_buy_order] The price you ordered has not dropped by more than $ 3 from the current price." ) logger.info("[BuyThread][check_buy_order] not yet buying") return ret
def __init__(self, custom_strategy, order_type): logger.info("[OrderThread][run] __init__") threading.Thread.__init__(self) self.custom_strategy = custom_strategy self.order_type = order_type self.lastClosePrice = self.custom_strategy.analysis_15m['Close'] singleton_data.instance().setOrderThread(True) currentQty = self.custom_strategy.exchange.get_currentQty() logger.info("[OrderThread][run] currentQty : " + str(currentQty)) self.waiting_order = {}
def run() -> None: order_manager = CustomOrderManager() # Try/except just keeps ctrl-c from printing an ugly stacktrace try: order_manager.start() #order_manager.run_loop() logger.info("[CustomOrderManager][run] PLOT_RUNNING : " + str(PLOT_RUNNING)) if PLOT_RUNNING: bitmex_plot.run() except (KeyboardInterrupt, SystemExit): logger.info("[CustomOrderManager][run] except") singleton_data.instance().sendTelegram("오류로 인해 시스템 종료!!") #order_manager.stop() sys.exit()
def run(self): logger.info("[OrderThread][run]") while singleton_data.getInstance().getAllowOrder(): try: # realized profit current_price = self.custom_strategy.exchange.get_instrument( )['lastPrice'] avgCostPrice = self.custom_strategy.exchange.get_avgCostPrice() currentQty = self.custom_strategy.exchange.get_currentQty() logger.info("[OrderThread][run] current_price : " + str(current_price) + ", avgCostPrice : " + str(avgCostPrice) + ", currentQty : " + str(currentQty)) if len(self.waiting_order) == 0: # ordering condition self.waiting_order = self.make_order() logger.info("[OrderThread][run] NEW : waiting_order : " + str(self.waiting_order)) #check ordering elif len(self.waiting_order) > 0: if self.check_order(): singleton_data.getInstance().setAllowOrder(False) break else: logger.info("[OrderThread][run] len(waiting_order) : " + str(len(self.waiting_order))) logger.info("[OrderThread][run] waiting_order : " + str(self.waiting_order)) sleep(1) except Exception as ex: self.PrintException() break sleep(1) # Cancel all orders self.custom_strategy.exchange.cancel_all_orders('All') singleton_data.getInstance().setAllowOrder(True) singleton_data.getInstance().setOrderThread(False) singleton_data.instance().setSwitchMode(False)
def get_tradeBin(self, bidSize='1m'): update_required = False #logger.info("[ExchangeInterface][get_tradeBin1m]") if bidSize == '1m' or bidSize == '5m': bin_data = self.bitmex.get_trade_bin(bidSize) update_required = singleton_data.instance().appendOHLC_data( bin_data, bidSize) return update_required
def check_addtional_buy(self): #should be executed when it is in the normal state # 300.0 * 2^n p = 2 ** int(singleton_data.instance().getAveDownCnt()) self.averagingDownSize = settings.AVERAGING_DOWN_SIZE * p # check Additional buying # current_price = self.exchange.get_instrument()['lastPrice'] avg_cost_price = self.exchange.get_avgCostPrice() if avg_cost_price is None: return False logger.info("[check_addtional_buy] should be current_price(" + str(current_price) + ") + averagingDownSize(" + str(self.averagingDownSize) + ") < avgCostPrice(" + str(avg_cost_price) + ")") if float(current_price) + float(self.averagingDownSize) < float(avg_cost_price): logger.info("[check_addtional_buy] Additional buying") buy_orders = self.exchange.get_orders('Buy') if len(buy_orders) > 0: logger.info("[check_addtional_buy] Additional buying fail because remaining buy orders : " + str(buy_orders)) else : aveCnt = singleton_data.instance().getAveDownCnt() + 1 singleton_data.instance().setAveDownCnt(aveCnt) logger.info("[check_addtional_buy] aveCnt : " + str(aveCnt)) singleton_data.instance().setAllowBuy(True) return True return False
def get_analysis(getOnlyLast: object = False, bidSize: object = '1m') -> object: sec_id = None if bidSize == '1m': sec_id = singleton_data.instance().getOHLC_1m_data() elif bidSize == '5m': sec_id = singleton_data.instance().getOHLC_5m_data() elif bidSize == '15m': bin5m_data = singleton_data.instance().getOHLC_5m_data() first_idx, last_idx = trim_15m(bin5m_data) logger.info("[get_analysis] len(bin5m_data) " + str(len(bin5m_data))) temp_list = [] for i in range(first_idx, last_idx + 1): if not i % 3 == first_idx: continue temp_map = {} temp_map['trades'] = 0 temp_map['volume'] = 0 temp_map['high'] = bin5m_data['high'][i] temp_map['low'] = bin5m_data['low'][i] temp_map['timestamp'] = bin5m_data['timestamp'][i] temp_map['symbol'] = bin5m_data['symbol'][i] temp_map['open'] = bin5m_data['open'][i] temp_map['close'] = bin5m_data['close'][i + 2] for j in range(i, i + 3): if temp_map['high'] < bin5m_data['high'][j]: temp_map['high'] = bin5m_data['high'][j] if temp_map['low'] > bin5m_data['low'][j]: temp_map['low'] = bin5m_data['low'][j] temp_map[ 'trades'] = temp_map['trades'] + bin5m_data['trades'][j] temp_map['volume'] = bin5m_data['volume'][i] + bin5m_data[ 'volume'][j] temp_list.append(temp_map) cnt = int((last_idx + 1 - first_idx) / 3) df = pd.DataFrame( { 'timestamp': [temp_list[i]['timestamp'] for i in range(0, cnt)], 'symbol': [temp_list[i]['symbol'] for i in range(0, cnt)], 'open': [temp_list[i]['open'] for i in range(0, cnt)], 'high': [temp_list[i]['high'] for i in range(0, cnt)], 'low': [temp_list[i]['low'] for i in range(0, cnt)], 'close': [temp_list[i]['close'] for i in range(0, cnt)], 'trades': [temp_list[i]['trades'] for i in range(0, cnt)], 'volume': [temp_list[i]['volume'] for i in range(0, cnt)], }, index=pd.to_datetime( [temp_list[i]['timestamp'] for i in range(0, cnt)])) sec_id = df elif bidSize == '30m': bin5m_data = singleton_data.instance().getOHLC_5m_data() first_idx, last_idx = trim_30m(bin5m_data) logger.info("[get_analysis] len(bin5m_data) " + str(len(bin5m_data))) temp_list = [] for i in range(first_idx, last_idx + 1): if not i % 6 == first_idx: continue temp_map = {} temp_map['trades'] = 0 temp_map['volume'] = 0 temp_map['high'] = bin5m_data['high'][i] temp_map['low'] = bin5m_data['low'][i] temp_map['timestamp'] = bin5m_data['timestamp'][i] temp_map['symbol'] = bin5m_data['symbol'][i] temp_map['open'] = bin5m_data['open'][i] temp_map['close'] = bin5m_data['close'][i + 5] for j in range(i, i + 6): if temp_map['high'] < bin5m_data['high'][j]: temp_map['high'] = bin5m_data['high'][j] if temp_map['low'] > bin5m_data['low'][j]: temp_map['low'] = bin5m_data['low'][j] temp_map[ 'trades'] = temp_map['trades'] + bin5m_data['trades'][j] temp_map['volume'] = bin5m_data['volume'][i] + bin5m_data[ 'volume'][j] temp_list.append(temp_map) cnt = int((last_idx + 1 - first_idx) / 6) df = pd.DataFrame( { 'timestamp': [temp_list[i]['timestamp'] for i in range(0, cnt)], 'symbol': [temp_list[i]['symbol'] for i in range(0, cnt)], 'open': [temp_list[i]['open'] for i in range(0, cnt)], 'high': [temp_list[i]['high'] for i in range(0, cnt)], 'low': [temp_list[i]['low'] for i in range(0, cnt)], 'close': [temp_list[i]['close'] for i in range(0, cnt)], 'trades': [temp_list[i]['trades'] for i in range(0, cnt)], 'volume': [temp_list[i]['volume'] for i in range(0, cnt)], }, index=pd.to_datetime( [temp_list[i]['timestamp'] for i in range(0, cnt)])) sec_id = df #analysis = pd.DataFrame(index = date2num(sec_id.index)) analysis = pd.DataFrame() ret = [] analysis['timestamp'] = sec_id.timestamp analysis['Open'] = sec_id.open.to_numpy() analysis['High'] = sec_id.high.to_numpy() analysis['Low'] = sec_id.low.to_numpy() analysis['Close'] = sec_id.close.to_numpy() analysis = getSuperTrend(analysis, SUPER_TREND_F, SUPER_TREND_P) #analysis['sma_f'] = sec_id.close.rolling(SMA_FAST).mean() #analysis['sma_s'] = sec_id.close.rolling(SMA_SLOW).mean() analysis['rsi'] = ta.RSI(sec_id.close.to_numpy(), RSI_PERIOD) #analysis['sma_r'] = analysis.rsi.rolling(RSI_PERIOD).mean() #analysis['macd'], analysis['macdSignal'], analysis['macdHist'] = ta.MACD(sec_id.close.to_numpy(), fastperiod=MACD_FAST, slowperiod=MACD_SLOW, signalperiod=MACD_SIGNAL) analysis['stoch_k'], analysis['stoch_d'] = ta.STOCH( sec_id.high.to_numpy(), sec_id.low.to_numpy(), sec_id.close.to_numpy(), fastk_period=STOCH_K, slowk_period=STOCH_D, slowk_matype=0, slowd_period=3, slowd_matype=0) #slowk_period=self.STOCH_K, slowd_period=self.STOCH_D) #analysis['sma'] = np.where(analysis.sma_f > analysis.sma_s, 1, 0) ret = analysis if (getOnlyLast): ret = analysis.iloc[-1:] return ret
def run_loop(self): logger.info("[CustomOrderManager][run_loop]") self.check_current_strategy() while True: self.check_file_change() sleep(settings.LOOP_INTERVAL) # This will restart on very short downtime, but if it's longer, # the MM will crash entirely as it is unable to connect to the WS on boot. if not self.check_connection(): logger.error("Realtime data connection unexpectedly closed, restarting.") self.restart() #self.sanity_check() # Ensures health of mm - several cut-out points here #self.print_status() # Print skew, delta, etc #self.place_orders() # Creates desired orders and converges to existing orders update_1m_required = self.exchange.get_tradeBin('1m') if update_1m_required: logger.info("----------------------------------------------------------------------------") logger.info("[CustomOrderManager][run_loop] update_1m_required : " + str(update_1m_required)) update_5m_required = self.exchange.get_tradeBin('5m') #if update_5m_required and (self.user_mode == 0 or self.user_mode == 111 or self.user_mode == 222): # TEST if update_1m_required and (self.user_mode == 0 or self.user_mode == 111 or self.user_mode == 222): logger.info("[CustomOrderManager][run_loop] update_5m_required : " + str(update_5m_required)) #self.analysis_15m = analysis.get_analysis(True, '5m') self.analysis_15m = analysis.get_analysis(True, '15m') if ((self.analysis_15m['Direction'] == "Long").bool() and singleton_data.instance().getMode() == "Short")\ or ((self.analysis_15m['Direction'] == "Short").bool() and singleton_data.instance().getMode() == "Long"): singleton_data.instance().setSwitchMode(True) if (self.analysis_15m['Direction'] == "Long").bool(): singleton_data.instance().setMode("Long") singleton_data.instance().setAllowBuy(True) singleton_data.instance().setAllowSell(False) singleton_data.instance().sendTelegram("Switch from Short to Long") elif (self.analysis_15m['Direction'] == "Short").bool(): singleton_data.instance().setMode("Short") singleton_data.instance().setAllowBuy(False) singleton_data.instance().setAllowSell(True) singleton_data.instance().sendTelegram("Switch from Long to Short") else: singleton_data.instance().setSwitchMode(False) if PLOT_RUNNING: self.analysis_1m = bitmex_plot.plot_update() else : self.analysis_1m = analysis.get_analysis(True, '1m') self.check_current_strategy()
def __init__(self): super().__init__() threading.Thread.__init__(self) self.__suspend = False self.__exit = False self.analysis_1m = pd.DataFrame() self.analysis_15m = pd.DataFrame() #self.analysis_30m = pd.DataFrame() self.analysis_1m = analysis.get_analysis(True) #self.analysis_15m = analysis.get_analysis(True, '5m') self.analysis_15m = analysis.get_analysis(True, '15m') #self.analysis_30m = analysis.get_analysis(True, '30m') self.user_mode = settings.USER_MODE #self.telegram = Telegram(self) self.telegram_th = Telegram(self) self.telegram_th.daemon=True self.telegram_th.start() singleton_data.instance().setTelegramThread(self.telegram_th) position = self.exchange.get_position() currentQty = position['currentQty'] # default : 0, test : 1~n #singleton_data.instance().setAveDownCnt(1) # 1, 11, 2, 22 condtion is for Testing if self.user_mode == 0 or self.user_mode == 111 or self.user_mode == 222: if (self.analysis_15m['Direction'] == "Long").bool(): singleton_data.instance().setMode("Long") if abs(currentQty) > 0: singleton_data.instance().setAllowBuy(False) else : singleton_data.instance().setAllowBuy(True) elif (self.analysis_15m['Direction'] == "Short").bool(): singleton_data.instance().setMode("Short") if abs(currentQty) > 0: singleton_data.instance().setAllowSell(False) else : singleton_data.instance().setAllowSell(True) # Forced Buying mode elif self.user_mode == 1 or self.user_mode == 11: logger.info("[strategy] Forced Buying mode") singleton_data.instance().setMode("Long") singleton_data.instance().setAllowBuy(True) singleton_data.instance().setAllowSell(False) # Forced Selling mode elif self.user_mode == 2 or self.user_mode == 22: logger.info("[strategy] Forced Selling mode") singleton_data.instance().setMode("Short") singleton_data.instance().setAllowBuy(False) singleton_data.instance().setAllowSell(True) logger.info("[strategy][__init__] getMode() : " + str(singleton_data.instance().getMode())) logger.info("[strategy][__init__] getAllowBuy() : " + str(singleton_data.instance().getAllowBuy())) logger.info("[strategy][__init__] getAllowSell() : " + str(singleton_data.instance().getAllowSell()))
def check_current_strategy(self): current_price = self.exchange.get_instrument()['lastPrice'] avgCostPrice = self.exchange.get_avgCostPrice() currentQty = self.exchange.get_currentQty() orders = self.exchange.get_orders() TAG = "[strategy][" + str(singleton_data.instance().getMode()) + "]" logger.info(str(TAG) + " current_price : " + str(current_price) + ", avgCostPrice : " + str(avgCostPrice) + ", currentQty : " + str(currentQty)) logger.info(str(TAG) + " ['rsi'] " + str(self.analysis_1m['rsi'].values[0])[:5] + " + ['stoch_d'] " + str(self.analysis_1m['stoch_d'].values[0])[:5] + " = " + str(self.analysis_1m['rsi'].values[0] + self.analysis_1m['stoch_d'].values[0])[:5]) logger.info(str(TAG) + " getAllowBuy() " + str(singleton_data.instance().getAllowBuy()) + ", getAllowSell() : " + str(singleton_data.instance().getAllowSell()) + ", len(orders) : " + str(len(orders))) # test # Short mode -> Long mode #singleton_data.instance().setSwitchMode(True) #singleton_data.instance().setMode("Long") #singleton_data.instance().setAllowBuy(True) #singleton_data.instance().setAllowSell(False) if singleton_data.instance().getSwitchMode(): logger.info("[strategy][switch mode] getSwitchMode : True") logger.info("[strategy][switch mode] currentQty : " + str(currentQty)) if (singleton_data.instance().getMode() == "Long" and currentQty < 0) or (singleton_data.instance().getMode() == "Short" and currentQty > 0): if singleton_data.instance().isOrderThreadRun(): logger.info("[strategy][switch mode] isOrderThreadRun : True") else : self.exchange.cancel_all_orders('All') singleton_data.instance().setAllowOrder(True) order_th = None if singleton_data.instance().getMode() == "Long": order_th = OrderThread(self, 'Buy') elif singleton_data.instance().getMode() == "Short": order_th = OrderThread(self, 'Sell') order_th.daemon = True order_th.start() else : logger.info("[strategy][switch mode] getSwitchMode : True, but Keep going!") singleton_data.instance().setSwitchMode(False) # Long Mode elif singleton_data.instance().getMode() == "Long": if self.user_mode == 222: logger.info("[Long Mode] Skip Long Mode, Trading only for Short Mode") return ##### Buying Logic ##### # rsi < 30.0 & stoch_d < 20.0 if self.analysis_1m['rsi'].values[0] < settings.BASIC_DOWN_RSI or self.analysis_1m['stoch_d'].values[0] < settings.BASIC_DOWN_STOCH \ or self.analysis_1m['rsi'].values[0] + self.analysis_1m['stoch_d'].values[0] < settings.BASIC_DOWN_RSI + settings.BASIC_DOWN_STOCH \ or self.user_mode == 11: if singleton_data.instance().getAllowBuy() and len(orders) == 0: logger.info("[Long Mode][buy] rsi < " + str(settings.BASIC_DOWN_RSI) + ", stoch_d < " + str(settings.BASIC_DOWN_STOCH)) net_order.bulk_net_buy(self) else: ##### Selling Logic ##### # rsi > 70.0 & stoch_d > 80.0 if not singleton_data.instance().getAllowBuy(): ##### Check Addtional Buy #### if self.check_addtional_buy(): return if self.analysis_1m['rsi'].values[0] > settings.BASIC_UP_RSI or self.analysis_1m['stoch_d'].values[0] > settings.BASIC_UP_STOCH \ or self.analysis_1m['rsi'].values[0] + self.analysis_1m['stoch_d'].values[0] > settings.BASIC_UP_RSI + settings.BASIC_UP_STOCH: if not self.user_mode == 11: logger.info("[Long Mode][sell] rsi > " + str(settings.BASIC_UP_RSI) + ", stoch_d > " + str(settings.BASIC_UP_STOCH)) position = self.exchange.get_position() currentQty = position['currentQty'] logger.info("[Long Mode][sell] currentQty : " + str(currentQty)) logger.info("[Long Mode][sell] isSellThreadRun() : " + str(singleton_data.instance().isSellThreadRun())) if currentQty > 0 and not singleton_data.instance().isSellThreadRun(): sell_th = SellThread(self) sell_th.daemon=True sell_th.start() # even if wait for buying after ordering, it would be no quentity. # swtich to buying mode elif currentQty == 0: logger.info("[Long Mode][sell] currentQty == 0 ") logger.info("[Long Mode][sell] ### switch mode from selling to buying ###") logger.info("[Long Mode][sell] cancel all buying order") self.exchange.cancel_all_orders('All') singleton_data.instance().setAllowBuy(True) # Short Mode elif singleton_data.instance().getMode() == "Short": if self.user_mode == 111: logger.info("[Short Mode] Skip Short Mode, Trading only for Long Mode") return ##### Selling Logic ##### # rsi > 70.0 & stoch_d > 80.0 if singleton_data.instance().getAllowSell() and len(orders) == 0: if self.analysis_1m['rsi'].values[0] > settings.BASIC_UP_RSI or self.analysis_1m['stoch_d'].values[0] > settings.BASIC_UP_STOCH \ or self.analysis_1m['rsi'].values[0] + self.analysis_1m['stoch_d'].values[0] > settings.BASIC_UP_RSI + settings.BASIC_UP_STOCH \ or self.user_mode == 22: logger.info("[Short Mode][sell] rsi > " + str(settings.BASIC_UP_RSI)+", stoch_d > " + str(settings.BASIC_UP_STOCH)) net_order.bulk_net_sell(self) else : ##### Buying Logic ##### # rsi < 30.0 & stoch_d < 20.0 if not singleton_data.instance().getAllowSell(): ##### Check Addtional Sell #### if self.check_addtional_sell(): return if self.analysis_1m['rsi'].values[0] < settings.BASIC_DOWN_RSI or self.analysis_1m['stoch_d'].values[0] < settings.BASIC_DOWN_STOCH \ or self.analysis_1m['rsi'].values[0] + self.analysis_1m['stoch_d'].values[0] < settings.BASIC_DOWN_RSI + settings.BASIC_DOWN_STOCH: if not self.user_mode == 22: logger.info("[Short Mode][buy] rsi < " + str(settings.BASIC_DOWN_RSI) + ", stoch_d < " + str(settings.BASIC_DOWN_STOCH)) position = self.exchange.get_position() currentQty = position['currentQty'] logger.info("[Short Mode][buy] currentQty : " + str(currentQty)) logger.info("[Short Mode][buy] isBuyThreadRun() : " + str(singleton_data.instance().isBuyThreadRun())) if currentQty < 0 and not singleton_data.instance().isBuyThreadRun(): buy_th = BuyThread(self) buy_th.daemon=True buy_th.start() # even if wait for buying after ordering, it would be no quentity. # swtich to buying mode elif currentQty == 0: logger.info("[Short Mode][buy] currentQty == 0 ") logger.info("[Short Mode][buy] ### switch mode from buying to selling ###") logger.info("[Short Mode][buy] cancel all selling order") self.exchange.cancel_all_orders('All') singleton_data.instance().setAllowSell(True)
def mode(self, update, context): update.message.reply_text('Mode : ' + str(singleton_data.instance().getMode()))
def run(self): logger.info("[bitmex_plot][run]") sec_id = singleton_data.instance().getOHLC_data() self.sec_id_ochl = np.array( pd.DataFrame({ '0': date2num(sec_id.index), #.to_pydatetime()), '1': sec_id.open, '2': sec_id.close, '3': sec_id.high, '4': sec_id.low })) #self.analysis.Date.dt.tz_localize('UTC') self.analysis = analysis.get_analysis(False) # Prepare plot self.fig, (self.ax1, self.ax2, self.ax3, self.ax4) = plt.subplots(4, 1, sharex=True) self.ax1.set_ylabel(ticker, size=20) self.ax1.xaxis.set_major_formatter( matplotlib.dates.DateFormatter('%H:%M:%S')) #size plot self.fig.set_size_inches(15, 30) # Plot candles width=.6/(24*60) candlestick(self.ax1, self.sec_id_ochl, width=.6 / (24 * 60), colorup='g', colordown='r', alpha=1) # Draw Moving Averages self.analysis.sma_f.plot(ax=self.ax1, c='r', linewidth=self.LINE_WIDTH) self.analysis.sma_s.plot(ax=self.ax1, c='g', linewidth=self.LINE_WIDTH) handles, labels = self.ax1.get_legend_handles_labels() self.ax1.legend(handles, labels) #RSI self.ax2.set_ylabel('RSI', size=self.Y_AXIS_SIZE) self.analysis.rsi.plot(ax=self.ax2, c='g', label='Period: ' + str(self.RSI_PERIOD), linewidth=self.LINE_WIDTH) self.analysis.sma_r.plot(ax=self.ax2, c='r', label='MA: ' + str(self.RSI_AVG_PERIOD), linewidth=self.LINE_WIDTH) self.ax2.axhline(y=30, c='b', linewidth=self.LINE_WIDTH) #self.ax2.axhline(y=50, c='black', linewidth=self.LINE_WIDTH) self.ax2.axhline(y=70, c='b', linewidth=self.LINE_WIDTH) self.ax2.set_ylim([0, 100]) handles, labels = self.ax2.get_legend_handles_labels() self.ax2.legend(handles, labels) # Draw MACD computed with Talib self.ax3.set_ylabel('MACD: ' + str(self.MACD_FAST) + ', ' + str(self.MACD_SLOW) + ', ' + str(self.MACD_SIGNAL), size=self.Y_AXIS_SIZE) self.analysis.macd.plot(ax=self.ax3, color='b', label='Macd', linewidth=self.LINE_WIDTH) self.analysis.macdSignal.plot(ax=self.ax3, color='g', label='Signal', linewidth=self.LINE_WIDTH) self.analysis.macdHist.plot(ax=self.ax3, color='r', label='Hist', linewidth=self.LINE_WIDTH) self.ax3.axhline(0, lw=2, color='0', linewidth=self.LINE_WIDTH) handles, labels = self.ax3.get_legend_handles_labels() self.ax3.legend(handles, labels) # Stochastic plot self.ax4.set_ylabel('Stoch (k,d)', size=self.Y_AXIS_SIZE) self.analysis.stoch_k.plot(ax=self.ax4, label='stoch_k:' + str(self.STOCH_K), color='r', linewidth=self.LINE_WIDTH) self.analysis.stoch_d.plot(ax=self.ax4, label='stoch_d:' + str(self.STOCH_D), color='g', linewidth=self.LINE_WIDTH) handles, labels = self.ax4.get_legend_handles_labels() self.ax4.legend(handles, labels) self.ax4.axhline(y=20, c='b', linewidth=self.LINE_WIDTH) self.ax4.axhline(y=50, c='black', linewidth=self.LINE_WIDTH) self.ax4.axhline(y=80, c='b', linewidth=self.LINE_WIDTH) self.ani = animation.FuncAnimation(self.fig, self.animate, interval=5000) plt.show()
def animate(self, i): #logger.info("[plotThread][animate] self.update_flag " + str(self.update_flag)) if self.update_flag: sec_id = singleton_data.instance().getOHLC_data() sec_id_ochl = np.array( pd.DataFrame({ '0': date2num(sec_id.index), '1': sec_id.open, '2': sec_id.close, '3': sec_id.high, '4': sec_id.low })) #logger.info("[plotThread][animate] sec_id_ochl " + str(sec_id_ochl)) self.analysis = pd.DataFrame(index=sec_id.index) self.analysis['sma_f'] = sec_id.close.rolling(self.SMA_FAST).mean() self.analysis['sma_s'] = sec_id.close.rolling(self.SMA_SLOW).mean() self.analysis['rsi'] = ta.RSI(sec_id.close.to_numpy(), self.RSI_PERIOD) self.analysis['sma_r'] = self.analysis.rsi.rolling( self.RSI_PERIOD).mean() self.analysis['macd'], self.analysis['macdSignal'], self.analysis[ 'macdHist'] = ta.MACD(sec_id.close.to_numpy(), fastperiod=self.MACD_FAST, slowperiod=self.MACD_SLOW, signalperiod=self.MACD_SIGNAL) self.analysis['stoch_k'], self.analysis['stoch_d'] = ta.STOCH( sec_id.high.to_numpy(), sec_id.low.to_numpy(), sec_id.close.to_numpy(), fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, slowd_matype=0 ) #slowk_period=self.STOCH_K, slowd_period=self.STOCH_D) self.analysis['sma'] = np.where( self.analysis.sma_f > self.analysis.sma_s, 1, 0) # Plot candles width=.6/(24*60) candlestick(self.ax1, sec_id_ochl, width=.6 / (24 * 60), colorup='g', colordown='r', alpha=1) # Draw Moving Averages self.analysis['sma_f'] = sec_id.close.rolling(self.SMA_FAST).mean() self.analysis['sma_s'] = sec_id.close.rolling(self.SMA_SLOW).mean() self.analysis.sma_f.plot(ax=self.ax1, c='r', linewidth=self.LINE_WIDTH) self.analysis.sma_s.plot(ax=self.ax1, c='g', linewidth=self.LINE_WIDTH) self.analysis.rsi.plot(ax=self.ax2, c='g', label='Period: ' + str(self.RSI_PERIOD), linewidth=self.LINE_WIDTH) self.analysis.sma_r.plot(ax=self.ax2, c='r', label='MA: ' + str(self.RSI_AVG_PERIOD), linewidth=self.LINE_WIDTH) self.analysis.macd.plot(ax=self.ax3, color='b', label='Macd', linewidth=self.LINE_WIDTH) self.analysis.macdSignal.plot(ax=self.ax3, color='g', label='Signal', linewidth=self.LINE_WIDTH) self.analysis.macdHist.plot(ax=self.ax3, color='r', label='Hist', linewidth=self.LINE_WIDTH) self.analysis.stoch_k.plot(ax=self.ax4, label='stoch_k:' + str(self.STOCH_K), color='r', linewidth=self.LINE_WIDTH) self.analysis.stoch_d.plot(ax=self.ax4, label='stoch_d:' + str(self.STOCH_D), color='g', linewidth=self.LINE_WIDTH) self.update_flag = False
def restart(self): logger.info("Restarting the market maker") singleton_data.instance().sendTelegram("Restarting the market maker") os.execv(sys.executable, [sys.executable] + sys.argv)
def run(self): logger.info("[BuyThread][run]") while not singleton_data.instance().getAllowBuy(): try: # realized profit current_price = self.custom_strategy.exchange.get_instrument( )['lastPrice'] avgCostPrice = self.custom_strategy.exchange.get_avgCostPrice() avgCostPrice_copy = deepcopy(avgCostPrice) currentQty = self.custom_strategy.exchange.get_currentQty() logger.info("[BuyThread][run] [" + str(self.wait_cnt) + "] current_price : " + str(current_price) + ", avgCostPrice : " + str(avgCostPrice) + ", currentQty : " + str(currentQty)) if len(self.waiting_buy_order) == 0: # buying condition if float(current_price) < float(avgCostPrice) - float( self.minBuyingGap): logger.info("[BuyThread][run] current_price(" + str(current_price) + ") < avgCostPrice(" + str(avgCostPrice) + ") - minBuyingGap(" + str(self.minBuyingGap) + ")") self.waiting_buy_order = self.make_buy_order() self.waiting_buy_order_copy = deepcopy( self.waiting_buy_order) logger.info( "[BuyThread][run] NEW : waiting_buy_order : " + str(self.waiting_buy_order)) # waiting (default:15) secs condition else: self.wait_cnt += 1 if self.wait_cnt > settings.BUYING_WAIT: logger.info( "[BuyThread][run] stop buying thread because cnt < " + str(settings.BUYING_WAIT)) # exit buy thread break #check buying order elif len(self.waiting_buy_order) > 0: if self.check_buy_order(avgCostPrice): singleton_data.instance().setAllowSell(True) sleep(5) #report margin = self.custom_strategy.exchange.get_user_margin( ) margin_str = '수익 정리\n' margin_str += '판매가 : ' + str( self.waiting_buy_order_copy['price']) + '\n' margin_str += '평균가 : ' + str( avgCostPrice_copy) + '\n' margin_str += '수량 : ' + str( self.waiting_buy_order_copy['orderQty']) + '\n' margin_str += '실현 수익 : ' + str( margin['prevRealisedPnl'] / 100000000)[:7] + '\n' singleton_data.instance().sendTelegram(margin_str) break sleep(1) except Exception as ex: self.PrintException() break sleep(1) # Cancel all buy orders try: self.custom_strategy.exchange.cancel_all_orders('Buy') except Exception as ex: self.PrintException() finally: singleton_data.instance().setBuyThread(False)
def run(self): logger.info("[OrderThread][run]") while singleton_data.instance().getAllowOrder(): try: # realized profit current_price = self.custom_strategy.exchange.get_instrument( )['lastPrice'] avgCostPrice = self.custom_strategy.exchange.get_avgCostPrice() avgCostPrice_copy = deepcopy(avgCostPrice) currentQty = self.custom_strategy.exchange.get_currentQty() logger.info("[OrderThread][run] current_price : " + str(current_price) + ", avgCostPrice : " + str(avgCostPrice) + ", currentQty : " + str(currentQty)) if len(self.waiting_order) == 0: # ordering condition self.waiting_order = self.make_order() self.waiting_order_copy = deepcopy(self.waiting_order) logger.info("[OrderThread][run] NEW : waiting_order : " + str(self.waiting_order)) #check ordering elif len(self.waiting_order) > 0: if self.check_order(): singleton_data.instance().setAllowOrder(False) sleep(5) #report margin = self.custom_strategy.exchange.get_user_margin( ) margin_str = '포지션 강제 정리\n' margin_str += '판매가 : ' + str( self.waiting_order_copy['price']) + '\n' margin_str += '평균가 : ' + str( avgCostPrice_copy) + '\n' margin_str += '수량 : ' + str( self.waiting_order_copy['orderQty']) + '\n' margin_str += '실현 수익 : ' + str( margin['prevRealisedPnl'] / 100000000)[:7] + '\n' singleton_data.instance().sendTelegram(margin_str) break sleep(1) except Exception as ex: self.PrintException() break sleep(1) # Cancel all orders try: self.custom_strategy.exchange.cancel_all_orders('All') except Exception as ex: self.PrintException() finally: singleton_data.instance().setOrderThread(False) singleton_data.instance().setSwitchMode(False)