该策略基于TEMA指标的多时间框架交叉来识别市场趋势方向,并结合更低时间框架的TEMA指标交叉来寻找具体的入市和出场时机。策略可配置仅做多、仅做空或双向交易。
策略使用两个TEMA指标,一个基于5和15周期的快慢线,另一个基于用户自定义的高周期时间框架,例如日线或周线。高周期TEMA指标交叉确定总体趋势方向,当快线上穿慢线时看涨,下穿看跌;低周期TEMA指标交叉用于寻找具体的入市和出场时机。
当高周期TEMA快线上穿慢线时,低周期TEMA快线上穿慢线就可入场做多;当低周期TEMA快线下穿慢线时,就应该出场了。类似的,当高周期TEMA快线下穿慢线时,低周期TEMA快线下穿慢线就可入场做空;快线上穿慢线时就应该出场。
风险解决方法:
该策略整体概念清晰易理解,基于TEMA指标多时间框架交叉判断趋势方向,并结合低周期交叉寻找入场时机。有一定的优势,同时也存在一些改进空间。总体来说,该策略为量化交易实践提供了有价值的参考。
/*backtest
start: 2023-01-01 00:00:00
end: 2023-12-24 00:00:00
period: 1d
basePeriod: 1h
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/
// © Seltzer_
//@version=4
strategy(title="TEMA Cross +HTF Backtest", shorttitle="TEMA_X_+HTF_BT", overlay=true)
orderType = input("Longs+Shorts",title="What type of Orders", options=["Longs+Shorts","LongsOnly","ShortsOnly"])
isLong = (orderType != "ShortsOnly")
isShort = (orderType != "LongsOnly")
// Backtest Section {
// Backtest inputs
FromMonth = input(defval=1, title="From Month", minval=1, maxval=12)
FromDay = input(defval=1, title="From Day", minval=1, maxval=31)
FromYear = input(defval=2020, title="From Year", minval=2010)
ToMonth = input(defval=1, title="To Month", minval=1, maxval=12)
ToDay = input(defval=1, title="To Day", minval=1, maxval=31)
ToYear = input(defval=9999, title="To Year", minval=2017)
// Define backtest timewindow
start = timestamp(FromYear, FromMonth, FromDay, 00, 00) // backtest start window
finish = timestamp(ToYear, ToMonth, ToDay, 23, 59) // backtest finish window
window() => true
// }
//TEMA Section {
//LTF Section
xLength = input(20, minval=1, title="Fast Length")
xPrice = close
xEMA1 = ema(xPrice, xLength)
xEMA2 = ema(xEMA1, xLength)
xEMA3 = ema(xEMA2, xLength)
xnRes = (3 * xEMA1) - (3 * xEMA2) + xEMA3
xnResP = plot(xnRes, color=color.green, linewidth=2, title="TEMA1")
yLength = input(60, minval=1, title="Slow Length")
yPrice = close
yEMA1 = ema(yPrice, yLength)
yEMA2 = ema(yEMA1, yLength)
yEMA3 = ema(yEMA2, yLength)
ynRes = (3 * yEMA1) - (3 * yEMA2) + yEMA3
ynResP = plot(ynRes, color=color.red, linewidth=2, title="TEMA2")
fill(xnResP, ynResP, color=xnRes > ynRes ? color.green : color.red, transp=65, editable=true)
//HTF Section
HTFres = input(defval="D", type=input.resolution, title="HTF Resolution")
HTFxLength = input(5, minval=1, title="HTF Fast Length")
HTFxPrice = close
HTFxEMA1 = security(syminfo.tickerid, HTFres, ema(HTFxPrice, HTFxLength), barmerge.gaps_off, barmerge.lookahead_on)
HTFxEMA2 = security(syminfo.tickerid, HTFres, ema(HTFxEMA1, HTFxLength), barmerge.gaps_off, barmerge.lookahead_on)
HTFxEMA3 = security(syminfo.tickerid, HTFres, ema(HTFxEMA2, HTFxLength), barmerge.gaps_off, barmerge.lookahead_on)
HTFxnRes = (3 * HTFxEMA1) - (3 * HTFxEMA2) + HTFxEMA3
HTFxnResP = plot(HTFxnRes, color=color.yellow, linewidth=1,transp=30, title="TEMA1")
HTFyLength = input(15, minval=1, title="HTF Slow Length")
HTFyPrice = close
HTFyEMA1 = security(syminfo.tickerid, HTFres, ema(HTFyPrice, HTFyLength), barmerge.gaps_off, barmerge.lookahead_on)
HTFyEMA2 = security(syminfo.tickerid, HTFres, ema(HTFyEMA1, HTFyLength), barmerge.gaps_off, barmerge.lookahead_on)
HTFyEMA3 = security(syminfo.tickerid, HTFres, ema(HTFyEMA2, HTFyLength), barmerge.gaps_off, barmerge.lookahead_on)
HTFynRes = (3 * HTFyEMA1) - (3 * HTFyEMA2) + HTFyEMA3
HTFynResP = plot(HTFynRes, color=color.purple, linewidth=1, transp=30, title="TEMA2")
fill(HTFxnResP, HTFynResP, color=HTFxnRes > HTFynRes ? color.yellow : color.purple, transp=90, editable=true)
bgcolor(HTFxnRes > HTFynRes ? color.yellow : na, transp=90, editable=true)
bgcolor(HTFxnRes < HTFynRes ? color.purple : na, transp=90, editable=true)
// }
// Buy and Sell Triggers
LongEntryAlert = xnRes > ynRes and HTFxnRes > HTFynRes and window()
LongCloseAlert = xnRes < ynRes and window()
ShortEntryAlert = xnRes < ynRes and HTFxnRes < HTFynRes and window()
ShortCloseAlert = xnRes > ynRes
// Entry & Exit signals
if isLong
strategy.entry("Long", strategy.long, when = LongEntryAlert)
strategy.close("Long", when = LongCloseAlert)
if isShort
strategy.entry("Short", strategy.short, when = ShortEntryAlert)
strategy.close("Short", when = ShortCloseAlert)