圧縮モメンタム指標に基づくトレンドフォロー戦略


作成日: 2023-11-13 17:46:01 最終変更日: 2023-11-13 17:46:01
コピー: 0 クリック数: 883
1
フォロー
1617
フォロワー

圧縮モメンタム指標に基づくトレンドフォロー戦略

概要

この戦略は,LazyBearの圧縮動量指標をベースに,ブリン帯とKeltnerチャネルを組み合わせて,価格突破チャネルが形成した圧縮と拡大の形状を識別し,株価の潜在的トレンド方向を判断し,トレンド追跡方法を採用して,開設方向を決定する.戦略の優点は,潜在的トレンドを識別する動量指標の能力を充分利用し,取引信号の質を制御するために複数の条件フィルターを設定することで,不確実な取引信号を効果的にフィルタリングすることができ,振動盤全体で過度に頻繁な取引を避ける.

戦略原則

  1. ブリン帯の中軌,上軌,下軌を計算する. 中軌はn日の閉盘価格の単純移動平均で,上軌は中軌のm倍加減のn日の閉盘価格の標準差である.

  2. ケルトナー通路の中線,上線,下線を計算する. 中線は,n日の閉盘価格の単純移動平均,上線は,n日の真波幅の単純移動平均を,中線に,m倍加減算する.

  3. 価格がブリン帯とケルトナー通路の上下軌道を破ったかどうかを判断する圧縮と拡張の形態である.価格が上から下軌道を破ったときに圧縮の形態であり,価格が下から上軌道を破ったときに拡張の形態である.

  4. 動力の指標として,線形回帰曲線の数値を計算する.動力の線の上を0穿越すると買の信号で,下を0穿越すると売の信号である.

  5. 圧縮拡大形,動向指標方向,平均値フィルターなどの複数の条件を組み合わせて最終取引信号を判断する.すべての条件を満たすのみで取引信号が生成され,誤った取引を避ける.

戦略的優位性

  1. ブリン帯とケルトナー通路の二重フィルタリングを使用して,高品質の圧縮と拡張形態を識別する.

  2. 動量指標は,価格トレンドの逆転をタイムリーに捉え,通路指標と互補を形成する.

  3. オンラインショップは,オンラインショップをオープンにすることで,

  4. 複数の条件の判断により,地震の時に頻繁にポジションを開くのを避ける.

  5. 各技術指標のパラメータは,異なる品種とパラメータの組み合わせに対応してカスタマイズできます.

  6. 測量時間帯を設定して,特定の時間周期に対して最適化テストを行う.

戦略リスク

  1. トレンドフォロー戦略は,トレンドが逆転したときに損失を伴うものです.

  2. パラメータを正しく設定しない場合,取引頻度が高くなり,信号の質が悪くなる可能性があります.

  3. 過去のデータテストを頼りにして,将来の復帰が安定する保証はありません.

  4. 市場が急激に変動し,物価が急激に変動する事態に 対応できない.

  5. 検知時間ウィンドウの設定が不適切で,過適合を引き起こす可能性があります.

戦略最適化の方向性

  1. ブリン帯とケルトナー通路のパラメータを最適化して,最適な組み合わせを見つける.

  2. 単一取引の最大損失を制御するために移動停止を加えるテスト.

  3. 特定の品種と周期の組み合わせでさらに最適化しようとします.

  4. 機械学習のモデルを導入し,トレンドの逆転を判断する.

  5. 異なる入場順序とポジション管理戦略をテストする.

  6. 逆転信号を認識し,その時に止めてしまう方法を研究する.

要約する

この戦略は,価格トレンドの方向を判断する複数の技術指標を融合し,トレンドを追跡し,強い適応性を持っています.パラメータのカスタマイズと複数の条件のフィルタリングにより,取引頻度を効果的に制御し,信号の質を向上させることができます.しかし,逆転取引と突発事件は,トレンドの逆転信号とリスク制御機構の最適化のために,戦略をより堅牢にするための警戒が必要です.

ストラテジーソースコード
/*backtest
start: 2022-11-06 00:00:00
end: 2023-11-12 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=3
//Strategy based on LazyBear Squeeze Momentum Indicator
//I added some custom feature and filters
//
// @author LazyBear
// List of all my indicators:
// https://docs.google.com/document/d/15AGCufJZ8CIUvwFJ9W-IKns88gkWOKBCvByMEvm5MLo/edit?usp=sharing
// v2 - fixed a typo, where BB multipler was always stuck at 1.5. [Thanks @ucsgears]
//
strategy(shorttitle = "SQZMOM_LB", title="Strategy for Squeeze Momentum Indicator [LazyBear]", overlay=false, calc_on_every_tick=true, pyramiding=0,default_qty_type=strategy.percent_of_equity,default_qty_value=100,currency=currency.USD)

length = input(14, title="BB Length")
mult = input(2.0,title="BB MultFactor")
lengthKC=input(16, title="KC Length")
multKC = input(1.5, title="KC MultFactor")
 
useTrueRange = input(true, title="Use TrueRange (KC)", type=bool)

//FILTERS
useExtremeOrders  = input(false, title="Early entry on momentum change", type=bool)
useMomAverage = input(false, title="Filter for Momenutum value", type=bool)
MomentumMin = input(20, title="Min for momentum")

// Calculate BB
src = close
basis = sma(src, length)
dev = mult * stdev(src, length)
upperBB = basis + dev
lowerBB = basis - dev
 
// Calculate KC
ma = sma(src, lengthKC)
range = useTrueRange ? tr : (high - low)
rangema = sma(range, lengthKC)
upperKC = ma + rangema * multKC
lowerKC = ma - rangema * multKC
 
sqzOn  = (lowerBB > lowerKC) and (upperBB < upperKC)
sqzOff = (lowerBB < lowerKC) and (upperBB > upperKC)
noSqz  = (sqzOn == false) and (sqzOff == false)
 
val = linreg(src  -  avg(avg(highest(high, lengthKC), lowest(low, lengthKC)),sma(close,lengthKC)), lengthKC,0)
 
bcolor = iff( val > 0,            iff( val > nz(val[1]), lime, green),            iff( val < nz(val[1]), red, maroon))
scolor = noSqz ? blue : sqzOn ? black : aqua
plot(val, color=bcolor, style=histogram, linewidth=4)
plot(0, color=scolor, style=cross, linewidth=2)

//LOGIC
//momentum filter
filterMom=useMomAverage?abs(val)>(MomentumMin/100000)?true:false:true

//standard condition
longCondition = scolor[1]!=aqua and scolor==aqua and bcolor==lime and filterMom
exitLongCondition = bcolor==green and not useExtremeOrders
shortCondition = scolor[1]!=aqua and scolor==aqua and bcolor==red and filterMom
exitShortCondition = bcolor==maroon and not useExtremeOrders

//early entry
extremeLong= useExtremeOrders and scolor==aqua and bcolor==maroon and bcolor[1]!=bcolor[0] and filterMom
exitExtLong = scolor==black or bcolor==red
extremeShort = useExtremeOrders and scolor==aqua and bcolor==green and bcolor[1]!=bcolor[0] and filterMom
exitExtShort = scolor==black or bcolor==lime

//STRATEGY

strategy.entry("SQ_Long", strategy.long, when = longCondition)
strategy.close("SQ_Long",when = exitLongCondition )

strategy.entry("SQ_Long_Ext", strategy.long, when = extremeLong)
strategy.close("SQ_Long_Ext",when = exitExtLong)
//strategy.exit("exit Long", "SQ_Long", when = exitLongCondition)

strategy.entry("SQ_Short", strategy.short, when = shortCondition)
strategy.close("SQ_Short",when = exitShortCondition)

strategy.entry("SQ_Short_Ext", strategy.short, when = extremeShort)
strategy.close("SQ_Short_Ext",when = exitExtShort)
//strategy.exit("exit Short", "SQ_Short", when = exitShortCondition)



// // === Backtesting Dates === thanks to Trost

// testPeriodSwitch = input(true, "Custom Backtesting Dates")
// testStartYear = input(2018, "Backtest Start Year")
// testStartMonth = input(1, "Backtest Start Month")
// testStartDay = input(1, "Backtest Start Day")
// testStartHour = input(0, "Backtest Start Hour")
// testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,testStartHour,0)
// testStopYear = input(2018, "Backtest Stop Year")
// testStopMonth = input(12, "Backtest Stop Month")
// testStopDay = input(14, "Backtest Stop Day")
// testStopHour = input(23, "Backtest Stop Hour")
// testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,testStopHour,0)
// testPeriod() =>
//     time >= testPeriodStart and time <= testPeriodStop ? true : false
// isPeriod = testPeriodSwitch == true ? testPeriod() : true
// // === /END

// if not isPeriod
//     strategy.cancel_all()
//     strategy.close_all()