マルチスケールドンキステップワイズチャネルに基づく取引戦略


作成日: 2024-02-27 14:57:37 最終変更日: 2024-02-27 14:57:37
コピー: 0 クリック数: 657
1
フォロー
1617
フォロワー

マルチスケールドンキステップワイズチャネルに基づく取引戦略

概要

これは,複数の時間尺度で唐津通路を使って入場と出場の点を判断する取引戦略である.戦略の主な考えは:より長い時間尺度でトレンドの方向を判断して入場のタイミングを見つけること.より短い時間尺度でトレンドの逆転を判断して出場のタイミングを見つけることである.

戦略原則

この戦略は,主にトンチ通路の概念を利用している.トンチ通路は,通路の上沿線,下沿線,中沿線で構成されている.通路の幅は時間尺度によって変化している.ここでは,異なる時間尺度でトンチ通路を構成している.具体的には:

  1. 52周期を使ってより長い時間尺度の唐津通路を構成し,通路の上沿,下沿,中沿線が得られる
  2. 12周期を使ってより短い時間尺度の唐津通路を構成し,通路の上沿,下沿,中沿線が得られる

入場論理: 価格がより長い時間尺度通路の上沿いを突破したときに,多頭入場のタイミングとして判断する.偽の突破を避けるために,我々は,最近3つのK線のうち少なくとも1つのK線の閉盘価格が,そのK線の通路の上沿いに高くなることを要求する.これは,短期的な過度の拡張による偽の突破を防ぐことができる.

出口論理: 価格がより短い時間尺の通路の下沿いを破るときは,平仓の出口のタイミングであると判断する。我々はまた,最近3つのK線のうち少なくとも1つのK線の閉盘価格が,そのK線の通路の下沿いに低いことを要求する.この方法で,突破の有効性を確認し,被套を避けることができる。

戦略的優位性

  1. この戦略は,トレンド追跡と反転取引の優位性を融合している.長い時間尺はトレンドの方向を判断し,短い時間尺は局所的な反転を判断し,両者は組み合わせてトレンドの中で局所的な波動を捉えることができる.

  2. 多時間尺度分析を用いて,偽突破の問題をよりうまく処理し,入場と出場をより明確に有効にすることができる.

  3. パラメータを最適化することで,異なる品種と市場環境に対応できる.

リスクと解決

  1. この戦略はパラメータに敏感であり,異なるパラメータはまったく異なる結果が得られる可能性がある.最適なパラメータの組み合わせを見つけるために十分なテスト・最適化が必要である.

  2. 震動的な状況では,戦略は大量取引信号を生じ,過剰取引を引き起こす可能性がある. 単一損失を制御するには,ストップを配置する.

  3. 策略は,大レベルのトレンド判断の論理を考慮していないため,牛と熊の転換点で失敗する可能性があります.他の指標と組み合わせて大レベルの動きを判断することができます.

最適化の方向

  1. パラメータ最適化を行い,最適なパラメータの組み合わせを見つけます.最適化サイクル長さ,通路タイプなどのパラメータです.

  2. ストップロジックの追加. 合理的な移動ストップを配置し,単一損失を制御する.

  3. 他の指標と組み合わせて大レベルのトレンドを判断する.例えばEMA,K線通路,マック指標など.重要な転換点での失敗を避ける.

要約する

この戦略は,全体として典型的な多時間尺度チャネルブレイク戦略である.これは,トレンド追跡と反転取引の優位性をよく融合し,異なる時間尺度チャネル判断によってトレンドにおける局所的な変動の効果を捉えるための効果である.パラメータが最適化されている場合,トレンドが顕著な市場で効果は優れている.しかし,戦略自体は比較的脆弱であり,パラメータと全体的な動きの判断に敏感である.

ストラテジーソースコード
/*backtest
start: 2023-02-20 00:00:00
end: 2024-02-26 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/
// © venkyrocker7777

//@version=5

strategy('Donchain channel based investment strategy', shorttitle='Donchain channel strategy', overlay=true)

Length = input.int(21, minval=1)
xPrice = close
xvnoise = math.abs(xPrice - xPrice[1])
nAMA = 0.0
nfastend = 0.666
nslowend = 0.0645
nsignal = math.abs(xPrice - xPrice[Length])
nnoise = math.sum(xvnoise, Length)
nefratio = nnoise != 0 ? nsignal / nnoise : 0
nsmooth = math.pow(nefratio * (nfastend - nslowend) + nslowend, 2)
nAMA := nz(nAMA[1]) + nsmooth * (xPrice - nz(nAMA[1]))
plot(nAMA, color=color.new(color.blue, 0), title='KAMA')

// Function to get Lower Channel, Upper Channel, Middle Channel for a period length
getLCUCMC(PeriodLength) =>
    lowestValueInThePeriod = ta.lowest(PeriodLength)  // LC
    highestValueInThePeriod = ta.highest(PeriodLength)  // UC
    middleChannelInTheperiod = math.avg(highestValueInThePeriod, lowestValueInThePeriod)  // MC
    // Returns Lower Channel, Upper Channel, Middle Channel for a period length
    [lowestValueInThePeriod, highestValueInThePeriod, middleChannelInTheperiod]

// Longer time frame for entry
longerPeriod = 52

// Shorter time frame for exit
shorterPeriod = 12

if timeframe.period == 'D'
    // Longer time frame for entry
    longerPeriod := 52 * 5

    // Shorter time frame for exit
    shorterPeriod := 12 * 5
    shorterPeriod

if timeframe.period == 'M'
    // Longer time frame for entry
    longerPeriod := 12

    // Shorter time frame for exit
    shorterPeriod := 3
    shorterPeriod

// Get Lower Channel, Upper Channel, Middle Channel for longerPeriod, shorterPeriod
[lowestValueInTheLongerPeriodLength, highestValueInTheLongerPeriodLength, middleChannelInLongerperiod] = getLCUCMC(longerPeriod)
[lowestValueInTheShorterPeriodLength, highestValueInTheShorterPeriodLength, middleChannelInShorterperiod] = getLCUCMC(shorterPeriod)


// Plot Upper Channel of longerPeriod in dark green
plot(highestValueInTheLongerPeriodLength, 'highestValueInTheLongerPeriodLength', color=color.new(color.green, 0))

// Plot Lower Channel of shorterPeriod in dark red
plot(lowestValueInTheShorterPeriodLength, 'lowestValueInTheShorterPeriodLength', color=color.new(color.red, 0))

// Entry Plan
// Will start to see if we can enter when high crosses up longer period high (high >= highestValueInTheLongerPeriodLength)
// Check if any of the three past candles and enter when any of the 3 past candles satisfy
// 1) high of that candle >= highestValueInTheLongerPeriodLength of that candle (high[i] >= highestValueInTheLongerPeriodLength[i])
// 2) close of entry point consideration candle is above close of that candle (close > close[i])
isThisPointAnEntry() =>
// Check last 3 bars
    isThisPointAnEntry = false
    offset = 0
    for i = 1 to 3 by 1
        isCurrentCandleALongerPeriodHigh = high >= highestValueInTheLongerPeriodLength
        isCurrentCandleCloseGreaterThanPreiousIthOne = close > close[i]
        isPreviousIthCandleAlsoALongerPeriodHigh = high[i] >= highestValueInTheLongerPeriodLength[i]
        isThisPointAnEntry := isCurrentCandleALongerPeriodHigh and isCurrentCandleCloseGreaterThanPreiousIthOne and isPreviousIthCandleAlsoALongerPeriodHigh
        if isThisPointAnEntry
            offset := -i
            break
    [isThisPointAnEntry, offset]

// Exit Plan - same as entry plan, with things reversed and also on a shorter time frame
// Will start to see if we should exit when low crosses down longer period low (low <= lowestValueInTheShorterPeriodLength)
// Check if any of the three past candles and exit when any of the 3 past candles satisfy
// 1) low of that candle <= highestValueInTheLongerPeriodLength of that candle (low[i] <= lowestValueInTheShorterPeriodLength[i])
// 2) close of exit point consideration candle is below close of that candle (close < close[i])
isThisPointAnExit() =>
// Check last 3 bars
    isThisPointAnExit = false
    for i = 1 to 3 by 1
        isCurrentCandleAShorterPeriodLow = low <= lowestValueInTheShorterPeriodLength
        isCurrentCandleCloseLesserThanPreiousIthOne = close < close[i]
        isPreviousIthCandleAlsoAShorterPeriodLow = low[i] <= lowestValueInTheShorterPeriodLength[i]
        isThisPointAnExit := isCurrentCandleAShorterPeriodLow and isCurrentCandleCloseLesserThanPreiousIthOne and isPreviousIthCandleAlsoAShorterPeriodLow
        break
    isThisPointAnExit

[isEntry, offset] = isThisPointAnEntry()


if isEntry
    strategy.entry('Buy', strategy.long)

strategy.close_all(when=isThisPointAnExit() == true)

if year(timenow) == year(time) and month(timenow) == month(time) and dayofmonth(timenow) - 2 == dayofmonth(time)
    strategy.close_all()