文章声明:本内容为个人的业余研究,和任何单位,机构没有关系,文章出现的股票代码,全部只是测试例子,不做投资参考,投资有风险,代码学习使用,不做商业用途
优化1.0版本。全面检查了代码,添加了尾盘恢复仓位算法,建立底仓算法,把全部模型上线网页

根据大家的需要我重新写mini版本的,真正的实盘交易是非常复杂的


策略的原理,日线的触发比较少,可以使用日内T0模块那个触发多
一、策略概述
这是一个基于ATR指标和动态基准价格的智能化网格交易策略。策略名称为"西蒙斯ATR日线固定网格",其核心思想是通过价格波动率来自适应调整交易触发阈值,在股价波动中自动执行低买高卖的操作。
二、策略运行流程
第一步:基础参数初始化
策略启动时首先计算三个关键参数:
- ATR指标 - 平均真实波幅,衡量股票的价格波动性
- 涨跌幅阈值 - 基于ATR计算得出的交易触发边界
- 基准价格 - 作为计算涨跌幅的参考起点
这些参数构成了策略的交易框架,其中ATR值决定了网格的"宽度",波动率越大的股票,网格间距越大。
第二步:动态基准价格确定
这是策略最核心的智能部分。基准价格的确定遵循一个三级优先原则:
优先级别1:历史交易记录
- 系统首先检查是否存在该策略对该股票的过往交易记录
- 如果有记录,则采用最近一次触发交易时的价格作为新基准
- 这保证了策略的连续性,每次交易后都重新校准参考点
优先级别2:挂单状态检查
- 当没有历史交易记录时,检查当前是否有未成交的买入订单
- 如果存在买入挂单,使用挂单价格作为基准价格
- 这考虑了交易执行的时间差,避免基准价与实际情况脱节
优先级别3:默认基准价格
- 当既无历史记录也无挂单时,使用预设的基准价格计算方法
- 这通常是策略的初始启动状态
第三步:实时涨跌幅计算
基于确定的基准价格,计算当前价格的相对涨跌幅:
text
当前涨跌幅 = (当前价格 - 基准价格) / 基准价格 × 100%
这个计算是动态更新的,确保每次评估都是基于最新的市场状况。
第四步:交易条件判断
策略设置上下两个触发边界:
- 上轨阈值 = +ATR阈值(正数)
- 下轨阈值 = -ATR阈值(负数)
判断逻辑:
- 当涨跌幅 大于等于上轨阈值 → 触发卖出信号
- 当涨跌幅 小于等于下轨阈值 → 触发买入信号
- 当涨跌幅 在上下轨之间 → 保持观望状态
三、策略核心特点
1. 自适应网格宽度
传统的网格交易使用固定百分比间隔,而本策略使用ATR指标动态调整:
- 高波动性股票 → 网格宽度自动扩大 → 减少频繁交易
- 低波动性股票 → 网格宽度自动收窄 → 捕捉小幅波动
2. 动态基准调整机制
基准价格不是固定不变的,而是:
- 每次交易后自动更新为触发价格
- 确保网格始终以最新成交价为中枢
- 避免了价格大幅变动时的网格失效问题
3. 状态持续性维护
通过交易日志记录策略状态:
- 即使程序重启,也能恢复之前的交易上下文
- 确保策略执行的连贯性和一致性
- 为策略优化提供数据支持
4. 实际交易环境感知
策略考虑真实交易环境中的因素:
- 检查未成交订单的影响
- 避免在已有挂单情况下重复计算
- 提高策略的实战可行性
四、风险控制机制
波动率适配
ATR指标确保网格间距与股票特性匹配,避免:
- 在平静股票上设置过宽网格而错过机会
- 在活跃股票上设置过窄网格而频繁交易
条件严格性
策略设置明确的触发条件:
- 只在价格突破阈值时交易
- 阈值区间内不进行任何操作
- 减少不必要的交易成本和滑点
基准重置保护
每次交易后基准价格重置:
- 防止累积误差导致的策略偏移
- 确保每次交易决策的相对独立性
使用教程点击网页下载策略http://14.103.193.242:9999/xms_quants.html

http://14.103.193.242:9999/xms_quants.html

最后一个

点击会员下载,知识星球可以直接下载

下载就可以导入qmt

1设置账户

2设置建立底仓参数,默认我没有开启开个人的选择

3设置尾盘恢复仓位函数,默认我没有开启

4设置记录表格的路径,不要随便动里面的数据

5设置检测的股票池,默认支持持股,自定义股票池,默认自定义
6设置atr的参数,-3就是3天前的收盘加做为起点计算


7开启模型,是否开启参数改成是

8设置交易参数,买卖值是每一笔交易触发的金额

点击测试没有问题挂模型交易就可以

10模型交易

点击运行就可以

下单的数据


交易记录

整理全部就设置好了模型我全部上传了知识星球可以下载

不懂的问我就可以,加我备注入群可以加入量化群

底层的简单算法
class user_def_trader_func:
def __init__(self,c,stock='512480.SH',tick='',hist='',other_data=''):
'''
自定义交易函数
'''
self.tick=tick
self.hist=hist
self.other_data=other_data
self.log=pd.read_excel(r'{}'.format(c.path))
self.trader_date=str(datetime.now())[:10]
self.now_date=datetime.now()
self.stock=stock
if self.log.shape[0]>0:
self.log=self.log[['证券代码','模块名称','交易日','触发时间','交易类型','交易数量','触发价格','投资备注','交易状态']]
self.log=self.log.sort_values(by='触发时间',ascending=True)
#self.log=self.log[self.log['交易日']==self.trader_date]
else:
self.log=pd.DataFrame()
self.c=c
def conditional_single_time_sharing_grid(self,
name='西蒙斯ATR日线固定网格'):
tick=self.tick
stock=self.stock
atr,zdf=cacal_atr(self.c,stock=stock)
x1=zdf
x2=-zdf
base_price=get_base_price(self.c,stock=stock)
price=tick['lastPrice']
if self.log.shape[0]>0:
self.log['证券代码']=self.log['证券代码'].astype(str)
log=self.log[self.log['模块名称']==name]
log=log[log['证券代码']==stock]
if log.shape[0]>0:
pre_price=log['触发价格'].tolist()[-1]
zdf=((price-pre_price)/pre_price)*100
else:
order_stats,order_price=check_buy_order(self.c,stock=stock)
if order_stats==True:
base_price=order_price
else:
base_price=base_price
zdf=((price-base_price)/base_price)*100
else:
order_stats,order_price=check_buy_order(self.c,stock=stock)
if order_stats==True:
base_price=order_price
else:
base_price=base_price
zdf=((price-base_price)/base_price)*100
if zdf>=x1:
print('{} 模块{} 卖出{} 目前涨跌幅{} 大于目前标涨跌幅{} atr {}'.format(self.now_date,name,stock,zdf,x1,atr))
return 'sell'
elif zdf<=x2:
print('{} 模块{} 买入{} 目前涨跌幅{} 小于目前标涨跌幅{} atr {}'.format(self.now_date,name,stock,zdf,x2,atr))
return 'buy'
else:
print('{} 模块{} 不符合交易{} 目前涨跌幅{} 在{}到{}期间 atr {}'.format(self.now_date,name,stock,zdf,x2,x1,atr))
return ''
def symmetric_grid_trading(self,
name='西蒙斯ATR日线对称网格'):
'''
西蒙斯ATR日线对称网格
'''
tick=self.tick
stock=self.stock
atr,zdf=cacal_atr(self.c,stock=stock)
x1=zdf
x2=-zdf
base_price=get_base_price(self.c,stock=stock)
price=tick['lastPrice']
if self.log.shape[0]>0:
self.log['证券代码']=self.log['证券代码'].astype(str)
log=self.log[self.log['模块名称']==name]
log=log[log['证券代码']==stock]
if log.shape[0]>0:
pre_price=log['触发价格'].tolist()[-1]
zdf=((price-pre_price)/pre_price)*100
shift_trader_type=log['交易类型'].tolist()[-1]
else:
order_stats,order_price=check_buy_order(self.c,stock=stock)
if order_stats==True:
base_price=order_price
else:
base_price=base_price
zdf=((price-base_price)/base_price)*100
shift_trader_type=''
else:
order_stats,order_price=check_buy_order(self.c,stock=stock)
if order_stats==True:
base_price=order_price
else:
base_price=base_price
zdf=((price-base_price)/base_price)*100
shift_trader_type=''
if zdf>=x1 and shift_trader_type=='buy':
print('{} 上一笔买入模块{} 卖出{} 目前涨跌幅{} 大于目前标涨跌幅{} atr {} '.format(self.now_date,name,stock,zdf,x1,atr))
return 'sell'
elif zdf<=x2 and shift_trader_type=='sell':
print('{}上一笔卖出 模块{} 买入{} 目前涨跌幅{} 小于目前标涨跌幅{} atr {}'.format(self.now_date,name,stock,zdf,x2,atr))
return 'buy'
if zdf>=x1 :
print('{}上一笔没有买入委托 模块{} 卖出{} 目前涨跌幅{} 大于目前标涨跌幅{} atr {}'.format(self.now_date,name,stock,zdf,x1,atr))
return 'sell'
elif zdf<=x2 :
print('{} 上一笔没有卖出委托模块{} 买入{} 目前涨跌幅{} 小于目前标涨跌幅{} atr {}'.format(self.now_date,name,stock,zdf,x2,atr))
return 'buy'
else:
print('{} 模块{} 不符合交易{} 目前涨跌幅{} 在{}到{}期间 atr {}'.format(self.now_date,name,stock,zdf,x2,x1,atr))
return ''