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()))
Example #3
0
    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
Example #5
0
    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 = {}
Example #6
0
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()
Example #7
0
    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)
Example #8
0
    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
Example #9
0
    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
Example #11
0
    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()
Example #12
0
    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()))
Example #13
0
    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
Example #17
0
 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)
Example #19
0
    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)