用DolphinScript实现趋势跟踪与ATR止损的交易策略
本页为一篇文章页面,包含标题信息,并展示作者署名与发布日期等文章元信息。
Source: https://dolphindb.cn/blogs/189
What this page covers
- 数据分析准备:建库建表、分区与数据导入。
- 示例数据说明:标的、时间范围与字段示意。
- 趋势跟踪信号规则与对应脚本实现。
- Kelly公式的定义、参数与计算实现思路。
- ATR止盈止损、仓位管理与交易指令触发条件。
- 策略绩效度量:年化收益率与最大回撤计算结果。
技能认证特训营第二期正式开启(限时报名)
页面顶部包含活动报名促销信息,并提供链接入口。
- 活动“技能认证特训营第二期”处于正式开启状态。
- 页面提供“限时报名”入口信息。
- 报名入口包含可点击的链接地址。
用DolphinScript实现趋势跟踪与ATR止损的交易策略(作者与日期)
该部分呈现文章标题,并给出作者署名与发布日期信息。
- 文章标题为“用DolphinScript实现趋势跟踪与ATR止损的交易策略”。
- 页面显示作者署名信息。
- 页面显示文章发布日期信息。
目录
该部分列出文章的章节与小节结构,用于导航。
- 目录包含多个章节级标题条目。
- 目录包含多个小节级标题条目。
- 目录区域与正文之间存在分隔元素。
数据分析的准备工作:建库建表与导入数据
本节说明按日期分区并使用TSDB引擎创建数据库与表,并通过loadTextEx从CSV导入数据。
- stockDB数据库使用TSDB(时间序列数据库)引擎。
- stockDB按日期值分区,设置为每天一个分区。
- 使用loadTextEx从CSV文件导入数据。
- 导入数据会按分区规则分布到不同分区。
stockTB表数据示例(浦发银行600000,前复权日线)
本节给出示例数据的标的、时间范围与字段示意说明。
- 示例数据标的为“浦发银行 600000”。
- 示例数据时间范围为2024-04-01至2025-04-01(日线数据)。
- 示例数据进行前复权处理以减少分红配股造成的价格变化影响。
趋势跟踪交易策略:策略介绍与信号规则
本节描述基于价格突破的趋势信号规则,给出DolphinScript实现,并说明交易信号开始月份设置原因。
- 策略类型为基于价格突破的趋势跟踪交易策略。
- 策略结合凯利公式进行仓位管理。
- 收盘价低于过去15日最低价(不含当日)触发买入信号。
- 收盘价高于过去5日最高价(不含当日)触发卖出信号。
- 交易信号从2024年8月开始产生以提供Kelly估计所需历史数据。
Kelly公式:定义、参数与计算实现思路
本节介绍Kelly公式的含义与参数,说明胜率/败率与平均盈利的历史计算方法,并给出实现与结果解读及半Kelly用法。
- Kelly公式用于确定最优投资比例,以最大化长期资本增长并避免破产风险。
- 参数f表示最优投入比例;正值代表多头,负值代表空头。
- 参数Pwin表示做多胜率;Ploss表示做多败率。
- 关系式为Ploss = 1 - Pwin。
- Pwin/Ploss可通过每日价格在历史序列中的排名与累加得到。
- 平均盈利可通过潜在做多/做空盈利序列累加并除以胜利次数得到。
- 从2024年8月开始,Kelly值在图示解读中稳定在0.7~0.8之间。
- 仓位管理使用半Kelly值以降低激进程度。
融入ATR跟踪止损策略:ATR计算、仓位管理与交易指令触发条件
本节定义ATR与止盈止损倍数,给出仓位计算方式,并列出开仓、调仓、反转、平仓及冷静期等触发条件。
- ATR取三个波动值的最大值并做15日移动平均。
- 止盈倍数为3.5,止损倍数为1.8。
- 止盈触发条件为“止盈倍数×ATR 大于单次投资盈利”。
- 止损触发条件为“止损倍数×ATR 大于单次投资亏损”。
- 仓位比例公式为(趋势信号方向×Kelly值)/ 2。
- 交易指令类型包括open、adjust、reverse、close(否则为hold)。
- 平仓后设置冷静期:接下来5天忽略趋势信号并保持空仓。
策略实现代码:tradeRecord函数流程与回测交易记录示例
本节给出tradeRecord函数流程,包括变量初始化、下单指令判定、仓位与资产更新、ATR信号生成与记录表输出,并展示示例说明。
- 回测初始资金(cash[0])设置为100000.0。
- 交易周期中会根据条件生成open/adjust/reverse/close/hold等指令。
- 当指令为open/adjust/reverse时,Position按capital、Signal与Kelly等计算。
- costPrice在open/reverse时取当日Close,在adjust时按加权平均更新。
- cash与capital按持仓变动与当日Close进行更新。
- atrSignal在无持仓时为NULL;满足止盈或止损条件时生成信号。
度量策略表现:年化收益率与最大回撤公式及计算结果
本节通过年化收益率与回撤指标评估策略,给出筛选区间条件,并展示最终的数值结果。
- 绩效计算输出包含date、returnRate与drawdown字段。
- returnRate使用log(capital/capital[0])与时间差计算年化值。
- 绩效计算筛选条件为month(date) >= 2024.08M。
- 策略表现结果给出年化收益率为6.48%。
- 策略表现结果给出最大回撤为1.56%。
完整脚本代码
本节汇总从数据准备到回测与绩效计算的完整DolphinScript脚本。
- 脚本包含建库建表与数据导入相关代码。
- 脚本包含趋势信号、Kelly计算与ATR信号相关代码。
- 脚本包含回测记录与绩效指标计算相关代码。
Facts Index
| Entity | Attribute | Value | Confidence |
|---|---|---|---|
| 技能认证特训营第二期 | 状态 | 正式开启(限时报名,享专属福利优惠) | medium |
| 限时报名链接 | url | https://www.qingsuyun.com/h5/e/217471/5/ | high |
| 文章发布日期 | date | 2025-05-23 | high |
| 作者署名 | name | 海豚_325754868 | high |
| stockDB数据库分区 | partitioning | 按日期值分区,每天一个分区(VALUE(2024.04.01..2025.04.01);按date列分区) | high |
| stockDB数据库存储引擎 | engine | TSDB(时间序列数据库)引擎 | high |
| TSDB引擎 | capability | 支持高效的时间范围查询和聚合操作(针对时间序列数据优化) | medium |
| 数据导入函数 | function | 使用loadTextEx从CSV文件导入数据,并按分区规则分布到不同分区 | high |
| stockTB表结构 | columns | date(DATE), Open(DOUBLE), High(DOUBLE), Low(DOUBLE), Close(DOUBLE), Volume(INT) | high |
| stockTB表设置 | sortColumns | sortColumns=[`date] | high |
| stockTB表设置 | keepDuplicates | keepDuplicates=ALL | high |
| 示例数据标的 | security | 浦发银行 600000 | high |
| 示例数据时间范围 | range | 2024-04-01 至 2025-04-01(日线数据) | high |
| 示例数据价格处理 | adjustment | 前复权处理,避免分红配股导致的股价变化 | high |
| 趋势跟踪策略类型 | strategy | 基于价格突破的趋势跟踪交易策略,结合凯利公式进行仓位管理 | high |
| 买入信号条件(文中描述) | rule | 当收盘价低于过去15日最低价(不包括当日)触发买入信号 | high |
| 卖出信号条件(文中描述) | rule | 当收盘价高于过去5日最高价(不包括当日)触发卖出信号 | high |
| 交易信号开始时间 | constraint | 从2024年8月开始产生交易信号(为Kelly公式估计提供足够历史数据) | high |
| trendSignal函数 | output | 返回包含date、Open、High、Low、Close及Signal列的表 | high |
| Signal取值含义(代码) | mapping | 卖出信号为-1;买入信号为1 | high |
| 买入信号条件(代码) | rule | Close < Low.prev().mmin(15).bfill!() 且 month(date) >= 2024.08M → Signal=1 | high |
| 卖出信号条件(代码) | rule | Close > High.prev().mmax(5).bfill!() 且 month(date) >= 2024.08M → Signal=-1 | high |
| 单次投资盈亏公式 | formula | (当前价格 - 平均成本价格)x sgn(仓位) | high |
| Kelly公式用途 | purpose | 确定最优投注或投资比例,旨在最大化长期资本增长并避免破产风险 | medium |
| Kelly公式参数f | definition | 投入资产占当前总资产的最优比例;正值代表多头,负值代表空头;不允许杠杆时绝对值应小于1 | high |
| Kelly公式参数Pwin | definition | 做多胜率 | high |
| Kelly公式参数Ploss | definition | 做多败率,也是做空胜率 | high |
| Kelly公式参数rw | definition | 每次做多胜利时的平均盈利 | high |
| Kelly公式参数rl | definition | 每次做空胜利时的平均盈利 | high |
| Pwin/Ploss计算思路 | method | 通过每天价格在历史序列中的排名与累加得到做多/做空胜利总次数,再计算胜率与败率 | medium |
| 历史胜率与败率关系 | formula | Ploss = 1 - Pwin | high |
| 平均盈利计算思路 | method | long_profit(v)/short_profit(v) 计算每时刻潜在做多/做空盈利;累加得到总盈利并除以胜利次数得到平均盈利 | medium |
| Kelly(v)实现 | components | 使用cumrank与cumsum得到累计多头/空头计数;计算long_rate与short_rate;计算累计利润与平均利润并代入公式 | high |
| Kelly值回测结果区间(图示解读) | range | 从2024年8月开始Kelly值稳定在0.7~0.8之间 | medium |
| 仓位管理中的Kelly用法 | rule | 由于Kelly偏激进,策略采用半Kelly值用于仓位管理 | high |
| ATR定义(文中描述) | formula | 取以下三个值的最大值并做15日移动平均:当日最高-最低;当日最高-次日收盘绝对值;次日收盘-当日最低绝对值 | high |
| ATR止盈触发 | condition | 止盈倍数 × ATR值 > 单次投资的盈利时触发止盈信号 | high |
| ATR止损触发 | condition | 止损倍数 × ATR值 > 单次投资的亏损时触发止损信号 | high |
| 止盈倍数 | value | 3.5 | high |
| 止损倍数 | value | 1.8 | high |
| ATR代码实现 | expression | matrix(High-Low, abs(High-Close.next()), abs(Close.next()-Low)).rowMax().mavg(15) | high |
| 仓位比例公式 | formula | 仓位比例 = (趋势信号方向 × Kelly值) / 2 | high |
| 持仓量公式 | formula | 持仓量 = 仓位比例 × 本金 / 当日股价(当日交易价格取当日收盘价) | high |
| 趋势信号方向取值 | mapping | 1代表买入信号,-1代表卖出信号 | high |
| 仓位符号说明 | rule | 若卖出信号为负且Kelly值为负,则实际仓位为正,代表多头头寸 | high |
| 交易周期指令类型 | set | open、adjust、reverse、close(其他情况为hold) | high |
| 开仓触发条件 | conditions | Position[i-1]==0.0 且 atrSignal[(i-5):i].isValid().sum()==0 且 trendSignalTB[Signal][i-1].isValid() | high |
| 调仓触发条件 | conditions | Position[i-1]*trendSignalTB[Signal][i-1]>0 且 atrSignal[(i-5):i].isValid().sum()==0 且 trendSignalTB[Signal][i-1].isValid() | high |
| 多空转换触发条件 | conditions | Position[i-1]*trendSignalTB[Signal][i-1]<0 且 atrSignal[(i-5):i].isValid().sum()==0 且 trendSignalTB[Signal][i-1].isValid() | high |
| 平仓触发条件 | conditions | atrSignal[i-1].isValid(),之后清空持仓;并设置冷静期:接下来5天忽略趋势信号,保持空仓 | high |
| 回测初始资金 | cash[0] | 100000.0 | high |
| 持仓数量Position计算(实现) | formula | 当order为open/adjust/reverse时:Position[i]=(capital[i-1]*Signal[i-1]*Kelly(Close)[i]/2)/Close[i];close时为0;否则沿用 | high |
| 平均成本价costPrice计算(实现) | rule | open/reverse取当日Close;adjust按加权平均公式;close置0;否则沿用 | high |
| 资产更新(实现) | formulas | cash[i]=cash[i-1]+(Position[i-1]-Position[i])*Close[i];capital[i]=cash[i]+Position[i]*Close[i] | high |
| ATR信号生成(实现) | conditions | 无持仓(costPrice==0)为NULL;3.5*ATR < (Close-costPrice)*signum(Position) 为止盈信号;-1.8*ATR > (Close-costPrice)*signum(Position) 为止损信号;否则NULL | high |
| performMetrics函数输出 | fields | date、returnRate(log(capital/capital[0])*365/(date-date[0]))、drawdown(capital.cummdd()) | high |
| 绩效计算筛选条件 | where | where month(date) >= 2024.08M | high |
| 策略表现结果 | annualized_return | 6.48% | high |
| 策略表现结果 | max_drawdown | 1.56% | high |