# 聚宽-QMT跟单系统 **Repository Path**: sh18gao/mini-qmt-nanny-level-tutorial ## Basic Information - **Project Name**: 聚宽-QMT跟单系统 - **Description**: 通过QMT读取聚宽策略信号、下单交易,解决聚宽无法实盘的问题,从而实现自动化交易。 - **Primary Language**: Python - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 3 - **Created**: 2025-04-08 - **Last Updated**: 2025-04-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 大 QMT 聚宽跟单系统 ### 系统简介 通过QMT读取聚宽的交易信号,实现自动交易,解决聚宽无法实盘、手动下单的问题,同时继承了聚宽的策略因子,省去了策略重写、因子重构的繁琐工作。 ### 主要功能 策略实时同步 :每3秒读取一次聚宽的信号,当有信号时自动下单 灵活跟单模式 :支持成交模式、持股模式、1比1模式等多种跟单方式 因子继承:通过读取信号的方式,无需重构因子 风险管控功能 :设置止损、止盈等参数,控制交易风险,保护收益。 多账户管理 :管理多个交易账户,方便资金和风险管控。 ### 优势特点 提升效率 :自动化减少人工操作,提升效率和准确性。 降低门槛 :无需专业编程和量化知识,简单易用,且不需要重写策略代码。 丰富策略 :聚宽丰富策略供选择,增加投资多样性。 个性化配置 :可根据需求调整参数,适应不同市场环境。 ### 准备工作 找管理员(量化交易汤姆猫): 1、开通QMT账户 2、领取聚宽跟单系统.rzrk 策略文件 3、注册授权码password,每个策略注册一个,区分大小写、不能重复。 ### 使用教程 **1、将这串代码复制到策略代码开头** **2、注册的授权码替换代码中的password** ![输入图片说明](%E6%95%99%E7%A8%8B1.png) ``` ''' 《QMT-聚宽跟单系统》使用说明 原理替代,继承聚宽的交易函数类 读取下单类的函数参数,把交易数据发送到服务器 把下面的全部源代码复制到聚宽策略的开头就可以 使用前先模拟盘测试一下数据 把下面的内容全部复制到策略的开头就可以 管理员:量化交易汤姆猫 微信:quant0808 ''' import requests import json import pandas as pd from jqdata import * url='http://101.34.65.108' port=8888 #自定义服务器编码 url_code='63d85b6189e42cba63feea36381da615c31ad8e36ae420ed67f60f3598efc9ad' #找管理员注册,每个策略一个,不能重复,且区分大小写,务必和注册时一致 password='Alex1' class joinquant_trader: def __init__(self,url='http://101.34.65.108', port=8888, url_code='63d85b6189e42cba63feea36381da615c31ad8e36ae420ed67f60f3598efc9ad', password='123456'): ''' 获取服务器数据 ''' self.url=url self.port=port self.url_code=url_code self.password=password def get_user_data(self,data_type='用户信息'): ''' 获取使用的数据 data_type='用户信息','实时数据',历史数据','清空实时数据','清空历史数据' ''' url='{}:{}/_dash-update-component'.format(self.url,self.port) headers={'Content-Type':'application/json'} data={"output":"joinquant_trader_table.data@{}".format(self.url_code), "outputs":{"id":"joinquant_trader_table","property":"data@{}".format(self.url_code)}, "inputs":[{"id":"joinquant_trader_password","property":"value","value":self.password}, {"id":"joinquant_trader_data_type","property":"value","value":data_type}, {"id":"joinquant_trader_text","property":"value","value":"\n {'状态': 'held', '订单添加时间': 'datetime.datetime(2024, 4, 23, 9, 30)', '买卖': 'False', '下单数量': '9400', '已经成交': '9400', '股票代码': '001.XSHE', '订单ID': '1732208241', '平均成交价格': '10.5', '持仓成本': '10.59', '多空': 'long', '交易费用': '128.31'}\n "}, {"id":"joinquant_trader_run","property":"value","value":"运行"}, {"id":"joinquant_trader_down_data","property":"value","value":"不下载数据"}], "changedPropIds":["joinquant_trader_run.value"],"parsedChangedPropsIds":["joinquant_trader_run.value"]} res=requests.post(url=url,data=json.dumps(data),headers=headers) text=res.json() df=pd.DataFrame(text['response']['joinquant_trader_table']['data']) return df def send_order(self,result): ''' 发送交易数据 ''' url='{}:{}/_dash-update-component'.format(self.url,self.port) headers={'Content-Type':'application/json'} data={"output":"joinquant_trader_table.data@{}".format(self.url_code), "outputs":{"id":"joinquant_trader_table","property":"data@{}".format(self.url_code)}, "inputs":[{"id":"joinquant_trader_password","property":"value","value":self.password}, {"id":"joinquant_trader_data_type","property":"value","value":'实时数据'}, {"id":"joinquant_trader_text","property":"value","value":result}, {"id":"joinquant_trader_run","property":"value","value":"运行"}, {"id":"joinquant_trader_down_data","property":"value","value":"不下载数据"}], "changedPropIds":["joinquant_trader_run.value"],"parsedChangedPropsIds":["joinquant_trader_run.value"]} res=requests.post(url=url,data=json.dumps(data),headers=headers) text=res.json() df=pd.DataFrame(text['response']['joinquant_trader_table']['data']) return df #继承类 xg_data=joinquant_trader(url=url,port=port,password=password,url_code=url_code) def send_order(result): ''' 发送函数 status: 状态, 一个OrderStatus值 add_time: 订单添加时间, [datetime.datetime]对象 is_buy: bool值, 买还是卖,对于期货: 开多/平空 -> 买 开空/平多 -> 卖 amount: 下单数量, 不管是买还是卖, 都是正数 filled: 已经成交的股票数量, 正数 security: 股票代码 order_id: 订单ID price: 平均成交价格, 已经成交的股票的平均成交价格(一个订单可能分多次成交) avg_cost: 卖出时表示下卖单前的此股票的持仓成本, 用来计算此次卖出的收益. 买入时表示此次买入的均价(等同于price). side: 多/空,'long'/'short' action: 开/平, 'open'/'close' commission交易费用(佣金、税费等) ''' data={} data['状态']=str(result.status) data['订单添加时间']=str(result.add_time) data['买卖']=str(result.is_buy) data['下单数量']=str(result.amount) data['已经成交']=str(result.filled) data['股票代码']=str(result.security) data['订单ID']=str(result.order_id) data['平均成交价格']=str(result.price) data['持仓成本']=str(result.avg_cost) data['多空']=str(result.side) data['交易费用']=str(result.commission) result=str(data) xg_data.send_order(result) return data def xg_order(func): ''' 继承order对象 数据交易函数 ''' def wrapper(*args, **kwargs): result = func(*args, **kwargs) if result == None: return send_order(result) return result return wrapper def xg_order_target(func): ''' 继承order_target对象 百分比 ''' def wrapper(*args, **kwargs): result = func(*args, **kwargs) if result == None: return send_order(result) return result return wrapper def xg_order_value(func): ''' 继承order_value对象 数量 ''' def wrapper(*args, **kwargs): result = func(*args, **kwargs) if result == None: return send_order(result) return result return wrapper def xg_order_target_value(func): ''' 继承order_target_value对象 数量 ''' def wrapper(*args, **kwargs): result = func(*args, **kwargs) if result == None: return send_order(result) return result return wrapper order = xg_order(order) order_target = xg_order_target(order_target) order_value = xg_order_value(order_value) order_target_value = xg_order_target_value(order_target_value) ``` **3、将策略挂到聚宽进行模拟交易** ![输入图片说明](8.png) **4、在QMT启动策略脚本** 登录大QMT,导入聚宽跟单系统.rzrk ![输入图片说明](%E6%95%99%E7%A8%8B2.png) **5、填写参数、编译、保存、运行、完成** ![输入图片说明](3.png) 至此,设置完成,当策略发出交易信号后,程序自动读取并且下单。 ### 信号检验 **1、进入服务器网址(有点慢,多等一会)** http://101.34.65.108:8888/ **2、输入授权码、选择运行,查看各种信息** _查看用户注册信息_ ![输入图片说明](4.png) _查看历史数据_ ![输入图片说明](6.png) _查看实时数据_ ![输入图片说明](5.png) _和聚宽平台信号对比,完全一致_ ### 参数说明 ``` 一、参数说明及示例(注意是在72行的text变量中修改): 1、实盘时间设置 "交易时间段":4, #一周交易五天, "交易开始时间":9, #9:00:00开是 "交易结束时间":14, #14:59:59结束 2、测试时间设置 "时间设置":"时间设置********", "交易时间段":8, "交易开始时间":0, "交易结束时间":24, "是否参加集合竞价":"否", "开始交易分钟":0, 3、实盘需要把txet中的参数‘是否测试’改成‘否’ "是否开启测试":"否", 4、该参数测试的时候改成否,实盘改成是 "是否开启临时id记录":"是" "是"用于实盘,"否"用于测试 4、模式选择 高频使用循环模式,每3秒刷新一次,获取一次交易信号 低频使用定时模式,固定时间点获取信号 5、数值 描述 -1 无效(只对于algo_passorder起作用) 0 卖5价 1 卖4价 2 卖3价 3 卖2价 4 卖1价 5 最新价 6 买1价 7 买2价(组合不支持) 8 买3价(组合不支持) 9 买4价(组合不支持) 10 买5价(组合不支持) 6、详细参数说明 text={ "账户":"", #这里填写自己的资金账户 "账户支持融资融券":"账户支持融资融券,账户类型STOCK/CREDIT", "账户类型":"STOCK", "买入价格编码":5, #最新价 "卖出价格编码":5, #最新价 "黑名单说明":"黑名单里面的标的,不会买入也不会卖出", "黑名单":['600031.SH','600111.SH','513100.SH'], "聚宽跟单":"跟单原理", "服务器设置":"服务器跟单设置", "服务器":"http://101.34.65.108", "端口":"8888", "服务器编码":"63d85b6189e42cba63feea36381da615c31ad8e36ae420ed67f60f3598efc9ad", "测试说明":"开启测试就是选择历史交易不开启就是选择今天的数据", "是否开启测试":"否", # “是”表示开启测试,“否”表示不开启 "测试数量":200, #当开启测试时,下单的股数 "跟单设置":"跟单设置***********", "账户跟单比例":0.5, #账户总资产(持仓+现金)的0.5倍资金用于跟单,可以自己修改,如0.5、0.6、0.8等 "多策略用逗号隔开":"多策略用逗号隔开********", "组合名称":["Alex1号组合"], #随便写,用于自己记录 "组合授权码":["Alex1"], #找管理员注册,每个策略用一个,不能重复,区分大小写 "组合跟单比例":[1], #聚宽下单的1倍数量,如聚宽下单100股,QMT下单100股,可以修改,如2倍,则QMT下单200股 "不同策略间隔更新时间":0, "下单默认说明":"默认/金额/数量", #默认表示聚宽下单多少,QMT下单多少, 金额模式则“下单值”列单元是元, 数量模式“下单值”列单元是股 "下单模式":"默认", "下单值":1000, "时间设置":"时间设置********", "交易时间段":8, "交易开始时间":0, "交易结束时间":24, "是否参加集合竞价":"否", "开始交易分钟":0, "是否开启临时id记录":"是" } ``` ### 资料领取 源代码、资料已整理,需要找我 微信:quant0808