本策略的核心思想是结合多空指标与基础移动平均线,实现趋势跟踪与趋势反转交易。当价格与指标同向时,采取趋势跟踪;当价格与指标异向时,采取逆转交易。
该策略主要基于三个自定义指标:
多空指标(Trend):计算价格与超买超卖通道的关系,判断多头和空头趋势,返回 1、0、-1 三种状态。
超买超卖通道(Tsl):参考ATR计算上轨和下轨,价格突破上轨视为超买,突破下轨视为超卖。
基础移动平均线(MA):计算20周期的收盘价简单移动平均线。
具体来说,策略根据多空指标值判断价格处于多头、震荡还是空头状态。当多空指标为1时,代表处于多头状态;当多空指标为-1时,代表空头状态。这时如果价格与指标方向一致,则采取趋势跟踪策略,在点位符合情况下做多做空。如果价格与指标方向相反,如指标显示多头而价格下跌突破下轨,则采取逆转策略,做空截获利润。
此外,价格突破移动平均线也作为辅助信号指导交易方向。价格上穿平均线时进多,下穿平均线时进空。
具体的多头交易策略如下:
多空指标 > 0,价格上涨突破上轨,属于趋势追踪情况,做多。
多空指标 < 0,价格下跌突破下轨,属于趋势反转情况,做空。
收盘价 > 开盘价 > 中枢点位,视为突破中枢做多机会,做多。
收盘价突破上轨,且收盘价 > 移动平均线,做多。
空头交易策略如下:
多空指标 < 0,价格下跌突破下轨,属于趋势追踪情况,做空。
多空指标 > 0,价格上涨突破上轨,属于趋势反转情况,做多。
开盘价 > 收盘价 < 中枢点位,视为突破中枢做空机会,做空。
收盘价突破下轨,且收盘价 < 移动平均线,做空。
平仓策略比较简单,通过价格重新突破超买超卖通道止损。
该策略具有以下优势:
多空指标可以准确判断市场走势,是策略的核心指标。
超买超卖通道与指标配合,可以发现潜在的反转机会。
基础移动平均线可作为辅助过滤信号,避免假突破。
中枢点位结合多空指标,形成高概率交易点位。
兼具趋势跟踪与逆转交易能力,收益机会更丰富。
超买超卖通道止损清晰简洁,有利于风险控制。
该策略也存在以下风险:
多空指标可能发出错误信号,需要组合其他指标过滤。
突破交易容易被套,需要严格止损。
移动平均线周期设置不当,可能错过趋势或产生假信号。
中枢点位需要回测验证概率可靠性。
超买超卖通道需要优化参数,以适应不同品种。
指标参数不匹配,可能导致交易频繁。
针对这些风险,可以采取以下措施:
结合其他指标如K线、成交量验证多空指标信号。
严格遵守超买超卖通道止损策略,快速止损。
测试不同移动平均线周期参数,找到最佳参数。
充分回测验证中枢点位策略概率。
优化通道参数,找到各品种最佳参数组合。
调整指标参数,使整体系统稳定运行。
该策略还可以从以下几个方面进行优化:
增加机器学习算法,利用大数据训练多空指标。可以提高指标准确性,减少错误信号。
增加自适应通道,根据市场波动率自动调整通道参数。可以提高突破的准确率。
利用深度学习提取更多变化指标,组成指标集优化 entry 和 exit 策略。
增加高级止损算法,能够跟踪趋势止损。避免被反转止损。
进行参数优化和组合测试,提高整体策略稳定性。
添加资金管理模块,使风险控制更科学化。
本策略通过多空指标判断市场结构,以及通道、移动平均线生成交易信号,实现了趋势跟踪与趋势反转的有机结合。具有指标效果好、交易机会丰富、止损清晰的优点。同时也存在一定的风险,需要进一步优化以提高稳定性。整体来说,该策略充分融合了趋势交易和反转交易的思想,值得进一步研究与应用。
/*backtest
start: 2023-08-25 00:00:00
end: 2023-09-24 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © amysojexson
//@version=3
strategy(title="Pivots strategy", overlay=true)
// Input settings
// Create a pull-down menu for the pivot type
pivotType = input(title="Pivot Type",
options=["Daily", "Intraday", "Weekly"], defval="Daily")
// Make toggles for pivot level options
plotPP = input(title="Plot PP", type=bool, defval=true)
plotS1R1 = input(title="Plot S1 and R1", type=bool, defval=true)
plotS2R2 = input(title="Plot S2 and R2", type=bool, defval=true)
plotS3R3 = input(title="Plot S3 and R3", type=bool, defval=true)
plotTCBC = input(title="Plot S3 and R3", type=bool, defval=true)
// Configure session options
sessRange = input(title="Trading Session", defval="0800-1600")
showSess = input(title="Highlight Session?", type=bool, defval=false)
// Enable or disable pivot labels
showLabels = input(title="Show Labels?", type=bool, defval=false)
// Step 2. Calculate indicator values
// Create a function to fetch daily and weekly data
GetData(res, data) =>
security(syminfo.tickerid, res, data[1],
lookahead=barmerge.lookahead_on)
// Fetch daily and weekly price data
dailyHigh = GetData("D", high)
dailyLow = GetData("D", low)
dailyClose = GetData("D", close)
weeklyHigh = GetData("W", high)
weeklyLow = GetData("W", low)
weeklyClose = GetData("W", close)
// Determine session pivot data
// First see how the price bar relates to
// the session time range
inSession = not na(time(timeframe.period, sessRange)[1])
sessStart = inSession and not inSession[1]
sessEnd = not inSession and inSession[1]
// Determine session price data
sessHigh = 0.0
sessLow = 0.0
sessClose = 0.0
sessHigh := sessStart ? high :
inSession ? max(high, sessHigh[1]) : na
sessLow := sessStart ? low :
inSession ? min(low, sessLow[1]) : na
sessClose := sessEnd ? close[1] : na
// Compute high, low, close from previous intra-day session
highPrevSess = 0.0
lowPrevSess = 0.0
closePrevSess = 0.0
highPrevSess := sessEnd ? fixnan(sessHigh) : highPrevSess[1]
lowPrevSess := sessEnd ? fixnan(sessLow) : lowPrevSess[1]
closePrevSess := sessEnd ? fixnan(sessClose) : closePrevSess[1]
// Now figure out which kind of price data
// to use for the pivot calculation
theHigh = if (pivotType == "Daily")
dailyHigh
else
if (pivotType == "Intraday")
highPrevSess
else
weeklyHigh
theLow = if (pivotType == "Daily")
dailyLow
else
if (pivotType == "Intraday")
lowPrevSess
else
weeklyLow
theClose = if (pivotType == "Daily")
dailyClose
else
if (pivotType == "Intraday")
closePrevSess
else
weeklyClose
// Finally calculate the pivot levels
pp = (theHigh + theLow + theClose) / 3
bc= (theHigh + theLow)/2
tc= (pp-bc)+pp
r1 = pp+(.382*(theHigh-theLow))
s1 = pp-(.382*(theHigh-theLow))
r2 = pp +(.618*(theHigh-theLow))
s2 = pp -(.618*(theHigh-theLow))
r3 = pp +(1*(theHigh-theLow))
s3 = pp -(1*(theHigh-theLow))
// Step 3. Output indicator data
// Plot the various pivot levels
plot(series=plotS3R3 ? r3 : na, title="R3",
style=circles, linewidth=1, color=#0023FF)
plot(series=plotS2R2 ? r2 : na, title="R2",
style=circles, linewidth=1, color=#1E90FF)
plot(series=plotS1R1 ? r1 : na, title="R1",
style=circles, linewidth=1, color=#09E0F3)
plot(series=plotTCBC ? tc : na, title="TC",
style=circles, linewidth=.75, color=#FF00D1)
plot(series=plotPP ? pp : na, title="PP",
style=circles, linewidth=1, color=#000000)
plot(series=plotTCBC ? bc : na, title="BC",
style=circles, linewidth=.75, color=#FF00D1)
plot(series=plotS1R1 ? s1 : na, title="S1",
style=circles, linewidth=1, color=#09E0F3)
plot(series=plotS2R2 ? s2 : na, title="S2",
style=circles, linewidth=1, color=#1E90FF)
plot(series=plotS3R3 ? s3 : na, title="S3",
style=circles, linewidth=1, color=#0023FF)
// Display the pivot names on the chart, if applicable
newPivots = (showLabels == false) ? false :
(pivotType == "Intraday") ? sessEnd :
(pivotType == "Daily") ? dayofmonth != dayofmonth[1] :
dayofweek == monday and dayofmonth != dayofmonth[1]
plotchar(series=newPivots and plotS3R3 ? r3 : na,
char='', text="R3", offset=1,
location=location.absolute,
color=#0023FF, title="R3 label")
plotchar(series=newPivots and plotS2R2 ? r2 : na,
char='', text="R2", offset=1,
location=location.absolute,
color=#1E90FF, title="R2 label")
plotchar(series=newPivots and plotS1R1 ? r1 : na,
char='', text="R1", offset=1,
location=location.absolute,
color=#09E0F3, title="R1 label")
plotchar(series=newPivots and plotTCBC ? r1 : na,
char='', text="TC", offset=1,
location=location.absolute,
color=#FF00D1, title="TC label")
plotchar(series=newPivots and plotTCBC ? r1 : na,
char='', text="BC", offset=1,
location=location.absolute,
color=#FF00D1, title="BC label")
plotchar(series=newPivots and plotS1R1 ? s1 : na,
char='', text="S1", offset=1,
location=location.absolute,
color=#09E0F3, title="S1 label")
plotchar(series=newPivots and plotS2R2 ? s2 : na,
char='', text="S2", offset=1,
location=location.absolute,
color=#1E90FF, title="S2 label")
plotchar(series=newPivots and plotS3R3 ? s3 : na,
char='', text="S3", offset=1,
location=location.absolute,
color=#0023FF, title="S3 label")
// Highlight the intra-day price data session on the chart
bgcolor(color=showSess and inSession and (pivotType == "Intraday") ?
orange : na, transp=95)
// Step 4. Create indicator alerts
alertcondition(condition=cross(close, s3),
title="Pivot S3 Cross",
message="Prices crossed Pivot S3 level")
alertcondition(condition=cross(close, s2),
title="Pivot S2 Cross",
message="Prices crossed Pivot S2 level")
alertcondition(condition=cross(close, s1),
title="Pivot S1 Cross",
message="Prices crossed Pivot S1 level")
alertcondition(condition=cross(close, tc),
title="Pivot TC Cross",
message="Prices crossed Pivot TC level")
alertcondition(condition=cross(close, pp),
title="Pivot PP Cross",
message="Prices crossed the main Pivot Point level")
alertcondition(condition=cross(close, bc),
title="Pivot BC Cross",
message="Prices crossed Pivot BC level")
alertcondition(condition=cross(close, r1),
title="Pivot R1 Cross",
message="Prices crossed Pivot R1 level")
alertcondition(condition=cross(close, r2),
title="Pivot R2 Cross",
message="Prices crossed Pivot R2 level")
alertcondition(condition=cross(close, r3),
title="Pivot R3 Cross",
message="Prices crossed Pivot R3 level")
MA = sma(close, 20)
plot(MA, color=red)
Factor = input(2, type=float)
Pd = input(10, minval=1,maxval = 100)
Up = hl2-(Factor*atr(Pd))
Dn = hl2+(Factor*atr(Pd))
TrendUp = 0.0
TrendUp := close[1]>TrendUp[1]? max(Up,TrendUp[1]) : Up
TrendDown = 0.0
TrendDown := close[1]<TrendDown[1]? min(Dn,TrendDown[1]) : Dn
Trend = 0.0
Trend := close > TrendDown[1] ? 1: close< TrendUp[1]? -1: nz(Trend[1],1)
Tsl = Trend==1? TrendUp: TrendDown
plot(Tsl, color=blue)
if close>open
if open<pp
if close>pp
if close>MA
strategy.entry("long", true)
if close<open
if open>pp
if close<pp
if close<MA
strategy.entry("short", false)
strategy.close("long", when = open<Tsl)
strategy.close("short", when = open>Tsl)