第一次接触量化交易的朋友可能会觉得"自动化交易"听起来很高大上,但其实用QMT平台配合通达信代码就能轻松实现。我自己从2018年开始用这套方案,已经稳定运行了6年多。简单来说,这个系统的工作原理就像个24小时值班的交易员:通达信负责监控市场发出预警信号,QMT平台则自动执行买卖操作。
最让我惊喜的是,这种方案对新手特别友好。不需要自己写复杂的策略逻辑,直接利用通达信成熟的预警功能,把选股结果传给QMT执行就行。我统计过身边朋友的使用情况,从零基础到能跑通第一个自动化策略,平均只需要3天时间。下面这张表格对比了传统手动交易和自动化交易的区别:
| 对比维度 | 手动交易 | QMT+通达信自动化 |
|---|---|---|
| 执行速度 | 分钟级 | 秒级响应 |
| 工作时间 | 盯盘4小时 | 24小时运行 |
| 情绪影响 | 容易受干扰 | 完全机械执行 |
| 学习成本 | 低 | 中等(需基础编程) |
先来看最关键的初始化部分。我建议新手直接复制这个模板,修改几个参数就能用:
python复制text = {
"账户": "55003243",
"账户类型": "STOCK", # STOCK/CREDIT
"通达信路径": "E:/tdx/T0002/blocknew",
"自选股板块": "XGTDXYJ",
"固定交易金额": 1000,
"持股限制": 20
}
def init(c):
c.account = text['账户']
c.account_type = text['账户类型']
c.path = text['通达信路径']
c.name = text['自选股板块']
# 设置定时任务
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")
这里有个实用技巧:用text字典管理参数比直接写死在代码里方便得多。去年我帮一个朋友排查问题时就发现,他每次修改参数都要重新部署整个策略,而用这种配置化的方式,只需要改text字典里的值就行。
这个xg_tdx类是我经过多次迭代优化的成果,主要解决三个痛点:
python复制class xg_tdx:
def __init__(self, path='E:/tdx/T0002/blocknew'):
self.path = path
def read_tdx_stock(self, name):
try:
with open(f"{self.path}/{name}.blk", 'r', encoding='gbk') as f:
codes = [line.strip() for line in f]
return pd.DataFrame({'证券代码': codes})
except Exception as e:
print(f"读取{name}板块失败:", e)
return pd.DataFrame()
实际使用中我发现,通达信的板块文件有时会被其他程序占用导致读取失败。后来我增加了重试机制,最多尝试3次读取,这个问题就再没出现过。
买入逻辑的核心是"三重过滤"机制,这是我经过多次实盘测试总结出来的:
python复制def get_buy_stock(c):
# 第一层过滤:交易时间
if not check_is_trader_date_1():
return pd.DataFrame()
# 第二层过滤:标的类型
df = c.xg_tdx.read_tdx_stock(name=c.name)
df['品种'] = df['证券代码'].apply(select_data_type)
df = df[df['品种'].isin(text['交易品种'])]
# 第三层过滤:持仓检查
hold_stock = get_position(c, c.account, c.account_type)
buy_list = [s for s in df['证券代码'] if s not in hold_stock['证券代码']]
return buy_list[:text['持股限制'] - len(hold_stock)]
有个坑要特别注意:通达信的预警股票代码格式是"1600031"这样的7位数字,需要先转换成"600031.SH"的标准格式。我曾在实盘中出现过因格式错误导致下单失败的情况,现在代码里已经内置了自动转换功能。
卖出模块我设计了两种触发方式:
python复制def run_sell_func(c):
# 主动卖出逻辑
sell_df = get_sell_stock(c)
for stock, avail in zip(sell_df['证券代码'], sell_df['可用数量']):
if avail >= 10:
passorder(c.sell_code, 1101, c.account, stock, 5, 0, avail, '系统自动卖出')
# 被动风控逻辑
hold_stock = get_position(c, c.account, c.account_type)
for stock in hold_stock[hold_stock['浮动盈亏率'] < -10]['证券代码']:
passorder(c.sell_code, 1101, c.account, stock, 5, 0, avail, '止损卖出')
这里有个实用建议:对于卖出操作,我习惯设置"可用数量>=10"的条件,避免对刚买入的股票立即卖出(A股是T+1制度)。这个阈值可以根据账户资金规模调整,我的经验值是保证每笔交易金额不低于5000元。
在Windows服务器部署时,遇到过三个典型问题:
这是我现在的标准部署流程:
很多新手会忽略交易时段控制,这里分享我的时间管理方案:
python复制def check_is_trader_date_1():
now = datetime.now()
# 排除非交易日期
if now.weekday() >= 5:
return False
# 交易时段控制
start = time(9, 30)
end = time(11, 30)
return start <= now.time() <= end
特别注意:如果要做科创板股票,需要单独处理盘后固定价格交易时段(15:05-15:30)。我专门写了个is_kcb_trade_time()函数来处理这种特殊情况。
完善的日志系统能节省大量排查时间。我的日志模块包含:
python复制def log_trade(action, stock, price, amount):
msg = f"{datetime.now()} {action} {stock} 价格{price} 数量{amount}"
print(msg)
with open('trade.log', 'a') as f:
f.write(msg + '\n')
if action == '买入' and amount * price > 100000:
send_alert_mail(f"大额交易预警:{msg}")
最近我还增加了企业微信机器人通知功能,交易异常时会直接推送到手机,实测响应速度比邮件快很多。