双波振動フィルター戦略は,価格変動に基づく取引戦略である.これは,2つの異なるパラメータセットの平均波動範囲の指標を使用して,価格と波動範囲の関係を組み合わせて取引信号を生成する.この戦略は,ビットコインなどの高波動のデジタル資産に適用される.
この策略は,2つの異なる周期長さの平滑波動範囲指標を使用します. 急速波動範囲指標 ((デフォルト周期27) とゆっくり波動範囲指標 ((デフォルト周期55)). 波動範囲指標の計算式は,現在の周期の価格波動幅の指数移動平均を, (例えば1.6) の倍数で掛けます.
双波の振動フィルター戦略は,価格と2つの波動範囲の指標の関係を比較して,現在一定の振動範囲内にあるかどうかを判断する.価格が振動範囲を突破すると,取引シグナルを生成する.
具体的には,策略は,中位線を基準とし,中位線は2つの波動範囲の指標の平均値である.価格が中位線上の一つの急速波動範囲を超えると多信号が発生し,価格が中位線下の一つの急速波動範囲を下回ると空調信号が発生する.
誤報をフィルターするために,この戦略には条件が加えられている:価格が前の周期の価格と一致する時のみ,信号が生成される.例えば,価格が上昇して中値線を1つの波動範囲を超えた時のみ,多信号が生成される.
総じて,この戦略は,双波動範囲の指標を使用して,震動区間を識別し,価格が震動区間を突破する信号として取引指示を生成する.同時に,誤った信号を減らすために価格方向フィルターを追加する.
双波の振動フィルタリング戦略の利点は,
価格の波動性の特性を利用して,ビットコインなどの高波動率の資産に適応できる.双波動範囲指標は,価格の揺れ区間をより正確に特定できる.
双波動範囲の指標は,異なる時間長を含みます. 急速な指標は,短期的な突破の機会を捉えます. 遅い指標は,長期のトレンドを考慮します.
価格の方向性フィルタリング条件を追加することで,短期的な変動による誤信号を減らすことができます.
取引論理はシンプルで明快で,容易に理解できる実装で,量化取引に適しています.
双波の振動フィルタリング戦略にはいくつかのリスクがあります.
波動性の指標によって,低波動の市場では効果が悪くなることがあります.
波動範囲のパラメータは,異なる品種に対して調整して最適化する必要があります.そうしないと,取引機会が逃れ,誤った信号が生じます.
価格が変動率から離れている場合を考慮していない. 変動率が上昇し,価格が相応に上昇していない場合,誤った信号を発信することがあります.
高波動環境では,止損点の設定を調整する必要があるかもしれない.極端な止損は頻繁に止まる.
この戦略は以下の点で最適化できます.
波動範囲のパラメータをテストし,最適化して,異なる種類の異なる周期の最適なパラメータの組み合わせを見つけます.
最近の変動率の動向に応じてストップポジションを調整するメカニズムに加入し,ストップ戦略を最適化します.
価格と変動率の偏差に基づくフィルタリング条件を追加し,誤った信号を回避する.
取引量の変化などの他の指標と組み合わせて,入場確実性を高めます.
戦略に適した停止退出メカニズムをテストして加入する.
双波の振動フィルター戦略は,全体的に高波動資産に対する効果的な取引戦略である.それは価格の波動特性を正しく利用し,シンプルで明確な取引ロジックを生成する.パラメータ最適化,リスク管理などによってさらに完善され,この戦略は,量化取引システムの価値ある構成要素になることができる.それはまた,市場波動性の特性をベースにアルゴリズム取引を行うための考え方を私たちに提供する.
/*backtest
start: 2023-11-05 00:00:00
end: 2023-11-12 00:00:00
period: 30m
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/
// © colinmck, greenmask9
//@version=4
strategy(title="Twin Range Filter Algo", overlay=true)
source = input(defval=close, title="Source")
// Smooth Average Range
per1 = input(defval=27, minval=1, title="Fast period")
mult1 = input(defval=1.6, minval=0.1, title="Fast range")
per2 = input(defval=55, minval=1, title="Slow period")
mult2 = input(defval=2, minval=0.1, title="Slow range")
smoothrng(x, t, m) =>
wper = t * 2 - 1
avrng = ema(abs(x - x[1]), t)
smoothrng = ema(avrng, wper) * m
smoothrng
smrng1 = smoothrng(source, per1, mult1)
smrng2 = smoothrng(source, per2, mult2)
smrng = (smrng1 + smrng2) / 2
// Range Filter
rngfilt(x, r) =>
rngfilt = x
rngfilt := x > nz(rngfilt[1]) ? x - r < nz(rngfilt[1]) ? nz(rngfilt[1]) : x - r :
x + r > nz(rngfilt[1]) ? nz(rngfilt[1]) : x + r
rngfilt
filt = rngfilt(source, smrng)
upward = 0.0
upward := filt > filt[1] ? nz(upward[1]) + 1 : filt < filt[1] ? 0 : nz(upward[1])
downward = 0.0
downward := filt < filt[1] ? nz(downward[1]) + 1 : filt > filt[1] ? 0 : nz(downward[1])
hband = filt + smrng
lband = filt - smrng
longCond = bool(na)
shortCond = bool(na)
longCond := source > filt and source > source[1] and upward > 0 or source > filt and source < source[1] and upward > 0
shortCond := source < filt and source < source[1] and downward > 0 or source < filt and source > source[1] and downward > 0
CondIni = 0
CondIni := longCond ? 1 : shortCond ? -1 : CondIni[1]
long = longCond and CondIni[1] == -1
short = shortCond and CondIni[1] == 1
// Plotting
// Strategy
// From this part on, programmer is greenmaks9
//
Separator = input(title="Following conditions and backtest algorithm are added by @greenmask9 🎯, original script is written by @colinmck 👍. Read both of their's release notes for more info on how this script works.", type=input.bool, defval=false)
disabler = input(title="Disable greenmask9's ATR conditions", type=input.bool, defval=false)
//second
l2 = input(title="ATR1", defval=32, minval=1)
s2 = input(title="Smoothing", defval="SMA", options=["RMA", "SMA", "EMA", "WMA"])
atr2(source, l2) =>
if s2 == "SMA"
sma(source, l2)
else
if s2 == "RMA"
rma(source, l2)
else
if s2 == "EMA"
ema(source, l2)
else
wma(source, l2)
//third
l3 = input(title="ATR2", defval=64, minval=1)
s3 = input(title="Smoothing", defval="RMA", options=["RMA", "SMA", "EMA", "WMA"])
atr3(source, l3) =>
if s3 == "RMA"
rma(source, l3)
else
if s3 == "SMA"
sma(source, l3)
else
if s3 == "EMA"
ema(source, l3)
else
wma(source, l3)
atr20=atr2(tr(true), l2)
atr30=atr3(tr(true), l3)
strategy.initial_capital = 50000
ordersize=floor(strategy.initial_capital/close)
profit = input(title="Ticks profit", type=input.integer, defval=900)
stop = input(title="Ticks stoploss", type=input.integer, defval=300)
maxcandles_till_close = input(title="Time stoploss", type=input.integer, defval=17)
bull = long and (atr20<atr30 or disabler)
bear = short and (atr20<atr30 or disabler)
bullclock = barssince(bull)
bearclock = barssince(bear)
if (bull)
strategy.entry("Twin Long", strategy.long, ordersize)
strategy.exit("Exit", from_entry = "Twin Long", profit = profit, loss = stop)
if (bear)
strategy.entry("Twin Short", strategy.short, ordersize)
strategy.exit("Exit", from_entry = "Twin Short", profit = profit, loss = stop)
//time stoploss
strategy.close("Twin Long", when = bullclock == maxcandles_till_close, comment = "Timed out")
strategy.close("Twin Short", when = bearclock == maxcandles_till_close, comment = "Timed out")