介绍 文章链接
小果大QMT通达信预警板块交易系统介绍 小果大QMT通达信预警板块交易系统是一种创新的量化交易解决方案,它通过QMT(Quick Money Trading)平台实时读取通达信软件的预警内容,并自动执行交易操作。该系统将通达信强大的技术分析预警功能与QMT的高效交易执行能力完美结合,为投资者提供了一个自动化、智能化的交易工具4。
系统核心功能 实时预警监控
系统持续监控通达信软件生成的预警信息,包括价格突破、技术指标信号、成交量异动等多种预警类型4
采用高效的文件监控机制,确保预警信息能够被即时捕获和处理
自动交易执行
通过QMT平台的xtquant库连接券商交易接口,实现毫秒级的交易响应4
支持多种委托类型:限价单、最优五档、对手方最优价、本方最优价等4
灵活的策略配置
用户可通过图形界面(GUI)设置交易参数,包括账户信息、交易品种、资金分配、风险控制等4
支持多种交易策略的快速切换和组合
全面的风险管理
内置多重风险控制机制,包括单笔金额限制、总金额限制、价格波动幅度限制等4
自动止损止盈功能,保护投资者资金安全
实时监控与日志记录
提供直观的交易监控界面,实时显示交易状态和账户情况4
完整的操作日志记录,便于事后分析和策略优化
系统架构与技术实现 小果大QMT通达信预警板块交易系统采用模块化设计,主要由以下几个核心组件构成:
预警监控模块
负责实时读取通达信预警文件内容
采用高效的文件变化检测算法,确保预警信号的及时捕获
配置流程
设置通达信预警输出路径和格式
配置QMT交易账户和接口参数
设定交易策略参数和风险控制规则4
运行模式
支持模拟交易和实盘交易两种模式
可设置交易时间段,避免非计划时段的误操作4
小果大QMT通达信预警板块交易系统通过将技术分析预警与自动化交易执行无缝结合,为投资者提供了一个高效、可靠的量化交易工具,特别适合那些希望将通达信技术分析能力转化为实际交易优势的用户群体。
安装教程
直接导入大qmt就可以
使用说明
一打开大qmt
打开qmt登录不选择独立默认进入大qmt
二导入策略
点击右键,选择导入策略
导入策略
三通达信预警设置
打开通达信客户端,证券公司的版本也可以
点击通达信预警设置,功能下面
设置预警的条件,预警的公式等自己建立设置
点击其他设置,设置通达信预警保持数据的板块,也支持文本输出,这个是我miniqmt的模式,参考我的设置就可以
选择预警保持的板块
四通达信板块的建立
点击通达信设置可以建立板块
五qmt通达信板块设置
点击qmt的文件编辑,输入账户
设置通达信的板块路径,预警保存的板块名称
通达信路径的获取,终于文件夹路径向左边 点击通达信客户端点击属性
点击打开文件位置,点击0002文件夹
点击new文件夹
通达信的全部板块文件就是在这个文件夹 点击一个文件点击属性就有文件路径
路径
E:\tdx\T0002\blocknew
线改写向左边的
设置通达信板块名称,支持卖出,大写的中文
还有很多参数,后面我给视频说明
text={
"账户":"440018483",
"账户支持融资融券":"账户支持融资融券,账户类型STOCK/CREDIT",
"账户类型":"STOCK",
"交易品种说明":"stock/fund/bond",
"交易品种":['stock','fund','bond'],
"是否测试说明":"测试会读取板块的数据分析,不测试直接清空自选股数据,等待最新的数据",
"是否测试":"否",
"是否开启临时id记录":"是",
"通达信路径":"E:/tdx/T0002/blocknew",
"自选股板块":"XGTDXYJ",
"剔除预警标开头":['688','300'],
"通达信卖出板块":"SELL",
"交易模式说明":"金额/数量",
"交易模式":"金额",
"固定交易金额":1000,
"固定交易数量":100,
"特殊交易标的设置":"特殊交易标的设置",
"特殊交易标的":[],
"特殊交易标的固定交易金额":15000,
"特殊交易标的固定交易数量":100,
"持股限制":20,
"时间设置":"时间设置********",
"交易时间段":8,
"交易开始时间":0,
"交易结束时间":24,
"是否参加集合竞价":"否",
"开始交易分钟":0,
}
六模型测试
点击测试模型,点击运行
实盘设置
点击模型交易模型挂实盘
7启动通达信预警
qmt运行
启动通达信预警
qmt读取预警下单的结果
qmt的下单分析的结果
下单的信号
委托
八源代码,部分,后面完善了全部开源,加入自定义买入算法
encoding:gbk
'''
小果通达信预警板块交易系统
原理读取通达信预警写入板块的数据,没有在持股的标的买入
支持自定义板块卖出
作者:小果
微信:15117320079
'''
import pandas as pd
import numpy as np
import talib
import os
import time
from datetime import datetime
text={
"账户":"40018483",
"账户支持融资融券":"账户支持融资融券,账户类型STOCK/CREDIT",
"账户类型":"STOCK",
"交易品种说明":"stock/fund/bond",
"交易品种":['stock','fund','bond'],
"是否测试说明":"测试会读取板块的数据分析,不测试直接清空自选股数据,等待最新的数据",
"是否测试":"否",
"是否开启临时id记录":"是",
"通达信路径":"E:/tdx/T0002/blocknew",
"自选股板块":"XGTDXYJ",
"剔除预警标开头":['688','300'],
"通达信卖出板块":"SELL",
"交易模式说明":"金额/数量",
"交易模式":"金额",
"固定交易金额":1000,
"固定交易数量":100,
"特殊交易标的设置":"特殊交易标的设置",
"特殊交易标的":[],
"特殊交易标的固定交易金额":15000,
"特殊交易标的固定交易数量":100,
"持股限制":20,
"时间设置":"时间设置********",
"交易时间段":8,
"交易开始时间":0,
"交易结束时间":24,
"是否参加集合竞价":"否",
"开始交易分钟":0,
}
class a:
pass
a.buy_id_list=[]
def init(c):
#账户
c.account=text['账户']
#账户类型
c.account_type=text['账户类型']
if c.account_type=='stock' or c.account_type=='STOCK':
c.buy_code=23
c.sell_code=24
else:
#融资融券
c.buy_code=33
c.sell_code=34
c.path=text['通达信路径']
c.name=text['自选股板块']
c.is_open=text['是否开启临时id记录']
c.xg_tdx=xg_tdx(path=r'{}'.format(c.path))
test=text['是否测试']
if test=='是':
print('开启测试模型,实盘记得关闭')
else:
del_all_tdx_stock(c)
print(get_account(c,c.account,c.account_type))
print(get_position(c,c.account,c.account_type))
#循环模式3秒
c.run_time("run_buy_func","1nSecond","2024-07-25 13:20:00")
c.run_time("run_sell_func","2nSecond","2024-07-25 13:20:00")
#定时清空数据
c.run_time("del_all_tdx_stock","1nDay","2024-07-25 09:10:00")
c.run_time("del_all_tdx_stock","1nDay","2024-07-25 15:10:00")
run_sell_func(c)
def handlebar(c):
pass
def del_all_tdx_stock(c):
'''
运行程序前清空通达信预警的数据
'''
name=text['自选股板块']
sell_name=text['通达信卖出板块']
c.xg_tdx.del_all_tdx_stock(name=name)
print(name,'数据清空成功')
c.xg_tdx.del_all_tdx_stock(name=sell_name)
print(sell_name,'数据清空成功')
def get_price(c,stock):
'''
获取最新价格
'''
tick=c.get_full_tick(stock_code=[stock])
tick=tick[stock]
price=tick['lastPrice']
return price
def select_data_type(stock='600031'):
'''
选择数据类型
'''
stock=str(stock)
if stock[:2] in ['11','12'] or stock[:3] in ['123','110','113','123','127','128','118','132','120']:
return 'bond'
elif stock[:2] in ['51','15','50','16','18','52']:
return 'fund'
else:
return 'stock'
def adjust_stock(stock='600031.SH'):
'''
调整代码
'''
if stock[-2:]=='SH' or stock[-2:]=='SZ' or stock[-2:]=='sh' or stock[-2:]=='sz':
stock=stock.upper()
else:
if stock[:3] in ['600','601','603','605','688','689',
] or stock[:2] in ['11','51','58']:
stock=stock+'.SH'
else:
stock=stock+'.SZ'
return stock
def get_buy_stock(c):
'''
获取买入股票池数据
'''
if check_is_trader_date_1():
tarder_type=text['交易品种']
del_list=text['剔除预警标开头']
hold_limit=text['持股限制']
#读取持股
hold_stock=get_position(c,c.account,c.account_type)
if hold_stock.shape[0]>0:
hold_stock=hold_stock[hold_stock['持仓量']>=10]
if hold_stock.shape[0]>0:
hold_stock['品种']=hold_stock['证券代码'].apply(lambda x:select_data_type(x))
hold_stock['选择']=hold_stock['品种'].apply(lambda x:'是' if x in tarder_type else '不是')
hold_stock=hold_stock[hold_stock['品种']=='是']
if hold_stock.shape[0]>0:
hold_stock_list=hold_stock['证券代码'].tolist()
hold_stock_amount=len(hold_stock_list)
else:
hold_stock_list=[]
hold_stock_amount=0
else:
hold_stock_list=[]
hold_stock_amount=0
else:
hold_stock_list=[]
hold_stock_amount=0
#读取通达信自选股
df=c.xg_tdx.read_tdx_stock(name=c.name)
print(df)
if df.shape[0]>0:
df['证券代码']=df['证券代码'].apply(lambda x: str(x)[1:])
df['证券代码']=df['证券代码'].apply(lambda x:adjust_stock(x))
df['品种']=df['证券代码'].apply(lambda x:select_data_type(x))
df['选择']=df['品种'].apply(lambda x:'是' if x in tarder_type else '不是')
df=df[df['选择']=='是']
df['剔除']=df['证券代码'].apply(lambda x: '是' if x in del_list else '不是')
if df.shape[0]>0:
df=df[df['剔除']=='不是']
if df.shape[0]>0:
tdx_stock_list=df['证券代码'].tolist()
tdx_stock_amount=len(tdx_stock_list)
else:
tdx_stock_list=[]
tdx_stock_amount=0
else:
tdx_stock_list=[]
tdx_stock_amount=0
else:
tdx_stock_list=[]
tdx_stock_amount=0
#检查委托买入没有成交的也计算在持股里面
order=get_order(c,c.account,c.account_type)
if order.shape[0]>0:
#操作类型48买入
order=order[order['操作类型']==48]
'''
ENTRUST_STATUS_WAIT_REPORTING 49 待报
ENTRUST_STATUS_REPORTED 50 已报(已报出到柜台,待成交)
ENTRUST_STATUS_REPORTED_CANCEL 51 已报待撤(对已报状态的委托撤单吗,等待柜台处理撤单请求)
ENTRUST_STATUS_PARTSUCC_CANCEL 52 部成待撤(已报到柜台,已有部分成交,已发出对剩余部分的撤单,待柜台处理撤单请求)
ENTRUST_STATUS_PART_CANCEL 53 部撤(已报到柜台,已有部分成交,剩余部分已撤)
ENTRUST_STATUS_CANCELED 54 已撤
ENTRUST_STATUS_PART_SUCC 55 部成(已报到柜台,已有部分成交)
ENTRUST_STATUS_SUCCEEDED 56 已成
ENTRUST_STATUS_JUNK 57 废单(不符合报单条件,委托被打回,相关信息再委托的废单原因字段查看)
'''
#可以撤销没有成交的类型
#52,53自己考虑有没有添加
cacal_list=[49,50,51]
if order.shape[0]>0:
order['未成交']=order['委托状态'].apply(lambda x:'是' if x in cacal_list else '不是')
order=order[order['未成交']=='是']
if order.shape[0]>0:
order_stock_list=order['证券代码'].tolist()
else:
order_stock_list=[]
else:
order_stock_list=[]
else:
order_stock_list=[]
for stock in order_stock_list:
hold_stock_list.append(stock)
hold_stock_amount=len(hold_stock_list)
#买入股票列表
buy_stock_list=[]
for stock in tdx_stock_list:
if stock not in hold_stock_list:
print('通达信预警{}没有在持股买入'.format(stock))
buy_stock_list.append(stock)
else:
print('通达信预警{}持股不买入'.format(stock))
buy_df=pd.DataFrame()
buy_df['证券代码']=buy_stock_list
buy_amount=hold_limit-hold_stock_amount
if buy_amount>0:
buy_amount=buy_amount
else:
print('超过持股限制{}不买入'.format(hold_limit))
buy_df=buy_df[:buy_amount]
print('买入股票池*******************')
print(buy_df)
return buy_df
else:
print('{} 目前不是交易时间'.format(datetime.now()))
buy_df=pd.DataFrame()
return buy_df
def run_buy_func(c):
'''
运行买入函数
'''
print('********************************************************')
print('********************************************************')
print('********************************************************')
trader_models=text['交易模式']
fix_value=text['固定交易金额']
fix_amount=text['固定交易金额']
sep_fix_value=text['特殊交易标的固定交易金额']
sep_fix_amount=text['特殊交易标的固定交易数量']
sep_stock_list=text['特殊交易标的']
if check_is_trader_date_1():
#先卖在买入
buy_df=get_buy_stock(c)
#买入
if buy_df.shape[0]>0:
for stock in buy_df['证券代码'].tolist():
if stock in sep_stock_list:
print('{}在特殊标的里面*********'.format(stock))
fix_value=sep_fix_value
volume=sep_fix_amount
else:
fix_value=text['固定交易金额']
volume=fix_amount
print(stock,fix_value)
if trader_models=='金额':
print('{}金额交易模式*******'.format(stock))
tader_type,amount,price=order_stock_value(c,c.account,c.account_type,stock,fix_value,'buy')
print(tader_type,amount,price)
if tader_type=='buy' and amount>=10 :
if c.is_open=='是':
if stock not in a.buy_id_list:
passorder(c.buy_code, 1101, c.account, str(stock), 5, 0, amount, '买入小果通达信预警板块交易系统',1,'小果通达信预警板块交易系统',c)
#passorder(23, 1101, c.account, str('513100.SH'), 5, 0, 100, '',1,'',c)
print('{} 最新价格 买入{} 元'.format(stock,fix_value))
a.buy_id_list.append(stock)
else:
print(stock,'在临时买入id里面不买入')
else:
passorder(c.buy_code, 1101, c.account, str(stock), 5, 0, amount, '买入小果通达信预警板块交易系统',1,'小果通达信预警板块交易系统',c)
#passorder(23, 1101, c.account, str('513100.SH'), 5, 0, 100, '',1,'',c)
print('{} 最新价格 买入{} 元'.format(stock,fix_value))
a.buy_id_list.append(stock)
else:
print('{}金额交易模式买入不了*******'.format(stock))
else:
if c.is_open=='是':
if stock not in a.buy_id_list:
print('{}数量交易模式*******'.format(stock))
passorder(c.buy_code, 1101, c.account, str(stock), 5, 0, volume, '买入小果通达信预警板块交易系统',1,'小果通达信预警板块交易系统',c)
print('{} 最新价格 买入{} 数量'.format(stock,volume))
else:
print(stock,'在临时买入id里面不买入')
else:
print('{}数量交易模式*******'.format(stock))
passorder(c.buy_code, 1101, c.account, str(stock), 5, 0, volume, '买入小果通达信预警板块交易系统',1,'小果通达信预警板块交易系统',c)
print('{} 最新价格 买入{} 数量'.format(stock,volume))
else:
print('没有买入数据')
else:
print('{} 目前不少交易时间'.format(datetime.now()))
def get_sell_stock(c):
'''
获取卖出股票池数据
'''
name=text['通达信卖出板块']
tarder_type=text['交易品种']
df=c.xg_tdx.read_tdx_stock(name=name)
if df.shape[0]>0:
df['证券代码']=df['证券代码'].apply(lambda x: str(x)[1:])
df['证券代码']=df['证券代码'].apply(lambda x:adjust_stock(x))
tdx_stock_list=df['证券代码'].tolist()
tdx_stock_amount=len(tdx_stock_list)
else:
tdx_stock_list=[]
tdx_stock_amount=0
hold_stock=get_position(c,c.account,c.account_type)
if hold_stock.shape[0]>0:
hold_stock=hold_stock[hold_stock['可用数量']>=10]
if hold_stock.shape[0]>0:
hold_stock['品种']=hold_stock['证券代码'].apply(lambda x:select_data_type(x))
hold_stock['选择']=hold_stock['品种'].apply(lambda x:'是' if x in tarder_type else '不是')
hold_stock['卖出']=hold_stock['证券代码'].apply(lambda x:'是' if x in tdx_stock_list else '不是')
sell_df=hold_stock[hold_stock['卖出']=='是']
else:
sell_df=pd.DataFrame()
else:
sell_df=pd.DataFrame()
return sell_df
def run_sell_func(c):
'''
运行卖出函数
'''
print('********************************************************')
print('********************************************************')
print('********************************************************')
trader_models=text['交易模式']
fix_value=text['固定交易金额']
fix_amount=text['固定交易金额']
sep_fix_value=text['特殊交易标的固定交易金额']
sep_fix_amount=text['特殊交易标的固定交易数量']
sep_stock_list=text['特殊交易标的']
if check_is_trader_date_1():
sell_df=get_sell_stock(c)
if sell_df.shape[0]>0:
for stock,hold_amount,av_amount in zip(sell_df['证券代码'],sell_df['持仓量'],sell_df['可用数量']):
try:
if av_amount>=10:
print('{} 持有数量{} 可以数量{}大于0 卖出数量{}'.format(stock,hold_amount,av_amount,av_amount))
passorder(c.sell_code, 1101,c.account, stock, 5, 0, av_amount, '卖出小果通达信预警板块交易系统',1,'小果通达信预警板块交易系统',c)
else:
print('{} 持有数量{} 可以数量{}等于0 卖出数量{} 不交易'.format(stock,hold_amount,av_amount,av_amount))
except:
print('{}卖出有问题'.format(stock))
else:
print('没有卖出的数据')
class xg_tdx:
'''
小果通达信自选股操作模型
作者微信15117320079
'''
def __init__(self,path=r'E:\tdx\T0002\blocknew'):
'''
小果通达信自选股操作模型
'''
self.path=path
def read_all_tdx_stock(self):
'''
读取全部的通达信板块
'''
try:
all_path=os.listdir(r'{}'.format(self.path))
except Exception as e:
print(e,'通达信板块文件不存在')
all_path=[]
return all_path
def creat_tdx_user_def_stock(self,name='CS_1'):
'''
建立通达信自定义自选股模块
'''
name_1='{}.blk'.format(name)
path="{}\{}.blk".format(self.path,name)
all_path=self.read_all_tdx_stock()
if name_1 in all_path:
print('{} 通达信自选股模块已经存在不建立'.format(name))
else:
with open(path, 'w', encoding='gbk') as file:
file.writelines('')
print('{} 通达信自选股板块建立成功'.format(name))
def del_tdx_user_def_stock(self,name='CS'):
'''
删除自定义股票池板块
'''
name_1='{}.blk'.format(name)
path="{}\{}.blk".format(self.path,name)
all_path=self.read_all_tdx_stock()
if name_1 in all_path:
os.remove(path=path)
print('自定义模块{}删除成功'.format(name))
else:
print(name_1,'不存在')
def adjust_stock(self,stock='600031.SH'):
'''
调整代码
'''
if stock[:3] in ['600','601','603','605','688','689',
] or stock[:2] in ['11','51','58']:
stock="1{}".format(stock)
else:
stock="0{}".format(stock)
return stock