Ejemplo n.º 1
0
 def closeEvent(self, event):
     if not get_system_running():
         reply = QtWidgets.QMessageBox.question(self, u'警告', u'同意并继续?',
                                                QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)
         if reply == QtWidgets.QMessageBox.Yes:
             event.accept()
         else:
             sys.exit(-1)
Ejemplo n.º 2
0
    def set_default(self):
        if get_system_running():
            return

        self.cbx_exchange.setCurrentIndex(0)
        self.cbx_category.setCurrentIndex(0)
        self.cbx_period.setCurrentIndex(3)
        self.txt_ema_fast.setText('7')
        self.txt_ema_slow.setText('30')
        self.txt_open_offset.setText('20')
        self.txt_open_interval.setText('0')
        self.txt_stop_earning_offset.setText('100')
        self.txt_stop_loss_offset.setText('0')
        self.txt_level_rate.setText('10')
        self.txt_max_num.setText('3')
        self.btn_switch.setText('开始')
Ejemplo n.º 3
0
    def run(self):
        # self._signal.emit('hello');  # 可以在这里写信号焕发
        count = 0
        while get_system_running():
            set_buniness_enabled(True)
            if count % 60 == 0:
                try:
                    logging.debug("running count={0}".format(int(count / 60)))
                    run_business(self.period, self.ma_fast, self.ma_slow,
                                 self.open_offset, self.open_interval,
                                 self.stop_offset, self.level_rate,
                                 self.max_open_number)
                except Exception as e:
                    ret = get_g_ret()
                    logging.debug("running count={0} ret={1}".format(
                        int(count / 60), pformat(ret)))
                    logging.debug("running count={0} exception={1}".format(
                        int(count / 60), e))

            count += 1
            time.sleep(1)

        logging.debug("stop trading")
        set_buniness_enabled(False)
Ejemplo n.º 4
0
    def btn_switch_click(self):
        if not get_system_running():
            exchange = self.cbx_exchange.currentText()
            category = self.cbx_category.currentText()
            period = self.cbx_period.currentText()
            ema_slow = self.txt_ema_slow.toPlainText()
            ema_fast = self.txt_ema_fast.toPlainText()
            open_offset = self.txt_open_offset.toPlainText()
            open_interval = self.txt_open_interval.toPlainText()
            stop_earning_offset = self.txt_stop_earning_offset.toPlainText()
            stop_loss_offset = self.txt_stop_loss_offset.toPlainText()
            level_rate = self.txt_level_rate.toPlainText()
            max_number = self.txt_max_num.toPlainText()

            ema_fast_good = True
            ema_slow_good = True
            if not self.is_number(ema_fast) or int(ema_fast) < 0:
                ema_fast_good = False
                self.txt_ema_fast.setText('请输入大于0的整数')
                self.txt_ema_fast.setFocus()
                return
            if not self.is_number(ema_slow) or int(ema_slow) < 0:
                ema_slow_good = False
                self.txt_ema_slow.setText('请输入大于0的整数')
                self.txt_ema_slow.setFocus()
                return
            if ema_fast_good and ema_slow_good and int(ema_fast) >= int(
                    ema_slow):
                self.txt_ema_slow.setText('慢线需大于快线')
                self.txt_ema_slow.setFocus()
                return

            if open_offset and not self.is_number(open_offset):
                self.txt_open_offset.setText('请输入整数')
                self.txt_open_offset.setFocus()
                return
            if open_interval and not self.is_number(open_interval):
                self.txt_open_interval.setText('请输入整数')
                self.txt_open_interval.setFocus()
                return

            if not self.is_number(stop_earning_offset):
                self.txt_stop_earning_offset.setText('请输入大于0的整数')
                self.txt_stop_earning_offset.setFocus()
                return
            if not self.is_number(stop_loss_offset):
                self.txt_stop_loss_offset.setText('请输入大于0的整数')
                self.txt_stop_loss_offset.setFocus()
                return

            if not self.is_number(level_rate):
                self.txt_level_rate.setText('请输入大于0的整数')
                self.txt_level_rate.setFocus()
                return
            if not self.is_number(max_number):
                self.txt_max_num.setText('请输入大于0的整数')
                self.txt_max_num.setFocus()
                return
            global g_config
            if int(max_number) > 30 and not g_config._max_open_number_limit:
                self.txt_max_num.setText('最大只支持30张')
                self.txt_max_num.setFocus()
                return

            self.btn_switch.setText('停止')
            set_system_running(True)
            self.set_all_enabled(False)
            self.run_business_thread(True, period, ema_fast, ema_slow,
                                     open_offset, open_interval,
                                     stop_earning_offset, level_rate,
                                     max_number)
            self.set_params()
        else:
            self.btn_switch.setText('开始')
            set_system_running(False)
            self.run_business_thread(False)
            # self.run_reading_thread(False)
            self.set_all_enabled(True)
Ejemplo n.º 5
0
 def close_all_contract(self):
     if get_system_running():
         QMessageBox.information(self, '提示', '该功能只能在停止运行后使用')
     else:
         close_all_contract()
Ejemplo n.º 6
0
def run():
    """
    * 如果趋势发生变化,撤销所有的限价挂单以及委托挂单
    * 如果有逆势持仓,则平掉所有逆势持仓
    * 如果有逆势限价挂单,则撤销所有逆势限价挂单
    * 如果没有顺势持仓,则(如果没有限价挂单,则按最优价格挂单;如果有限价挂单,检查价位是否合理,如果不合理则撤销重新挂单)
    * 如果有顺势持仓,则只挂止盈委托挂单,在慢速ema价格上设置止盈点
    """
    global g_ret
    g_ret = qds_test_registration()
    if not g_ret:
        logging.debug("Error, software is not correctly registered. Please contact [email protected] to register")
        return False

    global period
    global ma_fast
    global ma_slow
    global open_offset
    global open_interval
    global stop_offset
    global level_rate
    global max_open_number
    global trend_history
    global_data = Organized()

    logging.debug("qds params: period={0}, ma_fast={1}, ma_slow={2}, open_offset={3}, open_interval={4}, "
                  "stop_offset={5}, level_rate={6}, max_open_number={7}".format(
        period, ma_fast, ma_slow, open_offset, open_interval, stop_offset, level_rate, max_open_number))

    if not get_system_running(): return False
    g_ret = dm.get_contract_kline(symbol=symbol_period, period=period, size=300)
    if not ru.is_ok(g_ret):
        logging.debug("get_contract_kline failed, ret={0}".format(pformat(g_ret)))
        return False
    global_data = KLineAdapterHuobi.ParseData(g_ret['data'])

    close_list = global_data._close_list
    ma_fast_list = talib.EMA(np.array(close_list), timeperiod=ma_fast)
    ma_slow_list = talib.EMA(np.array(close_list), timeperiod=ma_slow)

    global_data._ema_list[ma_fast] = ma_fast_list
    global_data._ema_list[ma_slow] = ma_slow_list

    # debug_ema(global_data)

    last_index = global_data.GetLen() - 2
    last_ema_fast = global_data.ema_list[ma_fast][last_index]
    last_ema_slow = global_data.ema_list[ma_slow][last_index]
    ts = global_data._timestamp[last_index]

    # 多空决策
    trend = None
    if last_ema_fast > last_ema_slow:
        trend = 'long'
    elif last_ema_fast < last_ema_slow:
        trend = 'short'
    else:  # 趋势不变
        if trend_history:
            trend = trend_history
        else:
            trend = 'long'

    # 趋势发生变化,撤销所有的限价挂单以及委托挂单
    logging.debug("ts:{0} ma{1}:{2}, ma{3}:{4}".format(ts, ma_fast, last_ema_fast, ma_slow, last_ema_slow))
    if trend_history != trend:
        logging.debug(
            "trend={5} last: {4} ma{0}:{1}, ma{2}:{3}".format(ma_fast, last_ema_fast, ma_slow, last_ema_slow, ts,
                                                              trend))
        if not get_system_running(): return False
        g_ret = dm.cancel_all_contract_order(symbol_type)
        if ru.is_ok(g_ret):
            logging.debug("cancel_all_contract_order successfully at trend changed")
        else:
            if ru.is_no_order(g_ret):
                logging.debug("cancel_all_contract_order no orders")
            else:
                logging.debug("cancel_all_contract_order failed at trend changed, ret={0}".format(pformat(g_ret)))
                return False

        if not get_system_running(): return False
        g_ret = dm.cancel_all_contract_trigger(symbol_type)
        if ru.is_ok(g_ret):
            logging.debug("cancel_all_contract_trigger successfully at trend changed")
        else:
            if ru.is_no_order(g_ret):
                logging.debug("cancel_all_contract_trigger no orders")
            else:
                logging.debug("cancel_all_contract_trigger failed at trend changed, ret={0}".format(pformat(g_ret)))
                return False

        # 确保撤单成功再修改趋势,否则下次会再次执行撤单操作
        trend_history = trend

    if not get_system_running(): return False
    g_ret = dm.get_contract_account_position_info(symbol_type)
    if ru.is_ok(g_ret):
        available = g_ret['data'][0]['margin_available']
        balance = g_ret['data'][0]['margin_balance']
        logging.debug("margin_available={0}, margin_balance={1}".format(available, balance))
        set_margin(available, balance)
        if available == 0.0 and balance == 0.0:
            logging.debug("no available margin {0}, {1}".format(available, balance))
            return False

    # 获取当前持仓多单数量,空单数量,价格
    if not get_system_running(): return False
    g_ret = dm.get_contract_position_info(symbol_type)
    if not ru.is_ok(g_ret):
        logging.debug("get_contract_position_info failed, ret={0}".format(pformat(g_ret)))
        return False
    cpi_helper.log_all_orders("buy", g_ret)
    cpi_helper.log_all_orders('sell', g_ret)
    limit_holding_buy_count = cpi_helper.get_orders_count('buy', g_ret)
    limit_holding_buy_price = cpi_helper.get_price('buy', g_ret)
    limit_holding_sell_count = cpi_helper.get_orders_count('sell', g_ret)
    limit_holding_sell_price = cpi_helper.get_price('sell', g_ret)

    # 获取当前限价挂单的方向以及价格
    if not get_system_running(): return False
    g_ret = dm.get_contract_open_orders(symbol_type)
    if not ru.is_ok(g_ret):
        logging.debug("get_contract_open_orders failed, ret={0}".format(pformat(g_ret)))
        return False
    coo_helper.log_all_orders('buy', g_ret)
    coo_helper.log_all_orders('sell', g_ret)
    limit_pending_buy_count = coo_helper.get_orders_count('buy', 'open', g_ret)  # 开仓
    limit_pending_close_sell_count = coo_helper.get_orders_count('sell', 'close', g_ret)  # 平仓
    limit_pending_sell_count = coo_helper.get_orders_count('sell', 'open', g_ret)
    limit_pending_close_buy_count = coo_helper.get_orders_count('buy', 'close', g_ret)
    limit_pending_buy_price_list = coo_helper.get_price('buy', 'open', g_ret)
    limit_pending_sell_price_list = coo_helper.get_price('sell', 'open', g_ret)

    # 获取当前委托挂单多单数量,空单数量
    if not get_system_running(): return False
    g_ret = dm.get_contract_trigger_openorders(symbol_type)
    if not ru.is_ok(g_ret):
        logging.debug("get_contract_trigger_openorders failed, ret={0}".format(pformat(g_ret)))
        return False
    ctoo_helper.log_all_orders('buy', g_ret)
    ctoo_helper.log_all_orders('sell', g_ret)
    trigger_holding_buy_count = ctoo_helper.get_orders_count('buy', 'close', g_ret)
    trigger_holding_sell_count = ctoo_helper.get_orders_count('sell', 'close', g_ret)
    # 获取当前委托挂单方向以及价格
    trigger_holding_buy_order_price = round(ctoo_helper.get_order_price('buy', g_ret))
    trigger_holding_sell_order_price = round(ctoo_helper.get_order_price('sell', g_ret))

    # 设置最大允许操作数量(挂单数量+持仓数量)
    max_on_trend_count = max_open_number

    # 计算当前是否有逆势持仓
    limit_holding_against_trend_count = 0
    limit_holding_against_trend_close_direction = ''
    limit_holding_price = 0
    trigger_holding_against_trend_count = 0
    # 止盈止损
    stop_earning_trigger_type = ''
    stop_earning_trigger_price = 0
    stop_earning_order_price = 0
    stop_earning_direction = ''
    limit_pending_on_trend_count = 0
    limit_pending_close_on_trend_count = 0
    limit_pending_against_trend_count = 0
    limit_pending_on_trend_price_list = []
    trigger_holding_on_trend_order_price = 0
    base_open_point = 0
    if trend == 'long':
        base_open_point = last_ema_slow - open_offset
        limit_holding_against_trend_count = limit_holding_sell_count
        limit_holding_against_trend_close_direction = 'buy'
        trigger_holding_against_trend_count = trigger_holding_sell_count
        trigger_holding_on_trend_count = trigger_holding_sell_count
        trigger_holding_on_trend_order_price = trigger_holding_sell_order_price

        limit_pending_on_trend_open_direction = 'buy'
        limit_pending_on_trend_count = limit_pending_buy_count
        limit_pending_close_on_trend_count = limit_pending_close_sell_count
        limit_pending_against_trend_count = limit_pending_sell_count
        limit_pending_on_trend_price_list = limit_pending_buy_price_list

        limit_holding_on_trend_count = limit_holding_buy_count
        limit_holding_price = limit_holding_buy_price
        stop_earning_trigger_type = 'ge'
        stop_earning_order_price = round(last_ema_slow + stop_offset)
        stop_earning_trigger_price = round(stop_earning_order_price - 10)
        stop_earning_direction = 'sell'
    else:
        base_open_point = last_ema_slow + open_offset
        limit_holding_against_trend_count = limit_holding_buy_count
        limit_holding_against_trend_close_direction = 'sell'
        trigger_holding_against_trend_count = trigger_holding_buy_count
        trigger_holding_on_trend_count = trigger_holding_buy_count
        trigger_holding_on_trend_order_price = trigger_holding_buy_order_price

        limit_pending_on_trend_open_direction = 'sell'
        limit_pending_on_trend_count = limit_pending_sell_count
        limit_pending_close_on_trend_count = limit_pending_close_buy_count
        limit_pending_against_trend_count = limit_pending_buy_count
        limit_pending_on_trend_price_list = limit_pending_sell_price_list

        limit_holding_on_trend_count = limit_holding_sell_count
        limit_holding_price = limit_holding_sell_price
        stop_earning_trigger_type = 'le'
        stop_earning_order_price = round(last_ema_slow - stop_offset)
        stop_earning_trigger_price = round(stop_earning_order_price + 10)
        stop_earning_direction = 'buy'

    # 最优限价挂单价格
    limit_best_price = [
        round(base_open_point - open_interval),
        round(base_open_point),
        round(base_open_point + open_interval)
    ]
    logging.debug("limit_best_price={0}, {1}, {2}".format(limit_best_price[0], limit_best_price[1], limit_best_price[2]))
    # 执行交易
    # 平掉所有逆势持仓
    if limit_holding_against_trend_count > 0:
        logging.debug("limit_holding_against_trend_count={0}".format(limit_holding_against_trend_count))
        if not get_system_running(): return False
        g_ret = dm.send_lightning_close_position(symbol_type, contract_type_period, '',
                                               int(limit_holding_against_trend_count),
                                               limit_holding_against_trend_close_direction,
                                               '', None)
        if ru.is_ok(g_ret):
            limit_holding_against_trend_count = 0
            logging.debug("send_lightning_close_position successfully, direction={0}, volume={1}".format(
                limit_holding_against_trend_close_direction, limit_holding_against_trend_count))
        else:
            logging.debug("send_lightning_close_position failed, ret={0}".format(pformat(g_ret)))
            return False

    # 撤销所有逆势限价挂单,简化操作,只要逆势挂单就撤销所有限价挂单
    if limit_pending_against_trend_count > 0:
        logging.debug("limit_pending_against_trend_count={0}".format(limit_pending_against_trend_count))
        if not get_system_running(): return False
        g_ret = dm.cancel_all_contract_order(symbol_type)
        if ru.is_ok(g_ret):
            limit_pending_on_trend_count = 0
            limit_pending_against_trend_count = 0
            logging.debug("cancel_all_contract_order successfully")
        else:
            logging.debug("cancel_all_contract_order failed, ret={0}".format(pformat(g_ret)))
            return False

    # 如果没有顺势持仓,则(如果没有限价挂单,则按最优价格挂单;如果有限价挂单,检查价位是否合理,如果不合理则撤销重新挂单)
    if limit_holding_on_trend_count == 0:
        if limit_pending_on_trend_count == 0:
            available_limit_pending_on_trend_count = max_on_trend_count
            logging.debug("available_limit_pending_on_trend_count={0}".format(available_limit_pending_on_trend_count))
            if available_limit_pending_on_trend_count > 0:
                available_limit_pending_on_trend_count_each = [
                    round(available_limit_pending_on_trend_count / 3),
                    round(available_limit_pending_on_trend_count / 3),
                    max_on_trend_count - round(available_limit_pending_on_trend_count / 3) * 2
                ]
                for i in range(0, len(available_limit_pending_on_trend_count_each)):
                    if limit_holding_on_trend_count < max_on_trend_count:
                        price = round(limit_best_price[i])
                        volume = available_limit_pending_on_trend_count_each[i]
                        if volume > available_limit_pending_on_trend_count:
                            volume = available_limit_pending_on_trend_count
                        direction = limit_pending_on_trend_open_direction
                        if price > 0 and volume > 0:
                            if not get_system_running(): return False
                            g_ret = dm.send_contract_order(symbol=symbol_type, contract_type=contract_type_period, contract_code='',
                                                         client_order_id='', price=price, volume=int(volume),
                                                         direction=direction, offset='open', lever_rate=level_rate,
                                                         order_price_type='limit')
                            if ru.is_ok(g_ret):
                                available_limit_pending_on_trend_count -= volume
                                logging.debug(
                                    "send_contract_order successfully, price={0} volume={1} direction={2}".format(
                                        price, int(volume), direction))
                            else:
                                logging.debug("send_contract_order failed, ret={0}".format(pformat(g_ret)))
                                return False
        elif limit_pending_on_trend_count != max_on_trend_count:
            global g_fix_race_check_one_more_time
            if limit_pending_on_trend_count < max_on_trend_count and not g_fix_race_check_one_more_time:
                logging.debug(
                    "Fix race issue: limit_pending_on_trend_count {0} is smaller than max_on_trend_count {1}, "
                    "need to check one more time".format(limit_pending_on_trend_count, max_on_trend_count))
                g_fix_race_check_one_more_time = True
            else:
                g_fix_race_check_one_more_time = False
                if not get_system_running(): return False
                g_ret = dm.cancel_all_contract_order(symbol_type)
                if ru.is_ok(g_ret):
                    logging.debug(
                        "cancel_all_contract_order successfully, limit_pending_on_trend_count {0} not match with "
                        "max_on_trend_count {1}".format(limit_pending_on_trend_count, max_on_trend_count))
                else:
                    logging.debug("cancel_all_contract_order failed, ret={0}".format(pformat(g_ret)))
                    return False
        else:
            logging.debug("limit_pending_on_trend_count={0}".format(limit_pending_on_trend_count))
            for i in range(0, len(limit_pending_on_trend_price_list)):
                price = limit_pending_on_trend_price_list[i]
                # 如果限价挂单价格不是最优价格,则撤销重新挂单
                is_best_limit_price = False
                for j in range(0, len(limit_best_price)):
                    if price == limit_best_price[j]:
                        is_best_limit_price = True
                if not is_best_limit_price:
                    if not get_system_running(): return False
                    g_ret = dm.cancel_all_contract_order(symbol_type)
                    if ru.is_ok(g_ret):
                        logging.debug(
                            "cancel_all_contract_order successfully, price={0} is not one of limit_best_price".format(
                                price))
                    else:
                        logging.debug("cancel_all_contract_order failed, ret={0}".format(pformat(g_ret)))
                        return False
                    break

    # 如果有顺势持仓,则只挂止盈委托挂单,在持仓的价格上设置止盈点
    # 在只有限价单持仓的情况下,才能设置止盈委托挂单,否则会容易交易失败,而且不合逻辑
    available_trigger_pending_on_trend_count = limit_holding_on_trend_count - \
                                               limit_pending_close_on_trend_count - trigger_holding_on_trend_count
    if available_trigger_pending_on_trend_count > 0:
        logging.debug("available_trigger_pending_on_trend_count={0}".format(available_trigger_pending_on_trend_count))
        if not get_system_running(): return False
        g_ret = dm.send_contract_trigger_order(symbol=symbol_type, contract_type=contract_type_period,
                                             contract_code=None,
                                             trigger_type=stop_earning_trigger_type,
                                             trigger_price=round(stop_earning_trigger_price),
                                             order_price=round(stop_earning_order_price),
                                             order_price_type='limit',
                                             volume=int(available_trigger_pending_on_trend_count),
                                             direction=stop_earning_direction,
                                             offset='close',
                                             lever_rate=level_rate)
        if ru.is_ok(g_ret):
            logging.debug("send_contract_trigger_order successfully, {0} {1} {2} {3} {4}".format(
                stop_earning_trigger_type, round(stop_earning_trigger_price), round(stop_earning_order_price),
                int(available_trigger_pending_on_trend_count), stop_earning_direction))
        else:
            logging.debug("send_contract_trigger_order failed, ret={0}".format(pformat(g_ret)))
            return False
Ejemplo n.º 7
0
 def closeEvent(self, event):  # 函数名固定不可变
     if get_system_running():
         QMessageBox.information(self, '提示', '请先停止软件运行,再关闭')
         event.ignore()
     else:
         instance.delete_lok_file()