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)
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('开始')
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)
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)
def close_all_contract(self): if get_system_running(): QMessageBox.information(self, '提示', '该功能只能在停止运行后使用') else: close_all_contract()
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
def closeEvent(self, event): # 函数名固定不可变 if get_system_running(): QMessageBox.information(self, '提示', '请先停止软件运行,再关闭') event.ignore() else: instance.delete_lok_file()