ドンチェイン・チャネルベースの取引戦略

作者: リン・ハーンチャオチャン,日付: 2024-02-27 14:57:37
タグ:

img

概要

ドンチェイン (Donchain) は,複数のタイムフレームでドンチェインチャネルを利用してエントリー・エグジットポイントを決定する取引戦略である. 基本的なアイデアは,エントリー・シグナルのより長いタイムフレームでトレンド方向を判断し,エグジット・シグナルのより短いタイムフレームでトレンド逆転を探すことである.

戦略の論理

この戦略は主に,チャネルトップ,ボトム,ミッドラインで構成されるDonchainチャネルの概念を活用しています.チャネル幅は異なる時間枠で異なります.特に,私たちは2つの時間スケールでDonchainチャネルを構築します:

  1. 長期のドンチェインチャネルを構成し 上,下,中間線を得るために52つの周期を使用します

  2. 短期のドンチェインチャネルを構成し,上,下,中線を得ます.

エントリーロジック: 価格が長期チャネル上位を突破すると,我々はそれをロングエントリー信号として決定する. 偽のブレイクアウトを避けるために,我々は最近3の少なくとも1個のキャンドルがチャネル上位を閉じる必要があります.

エグジットロジック: 価格が短期チャネル底を下に突破したとき,我々はそれをロングポジションを閉じる出口信号として決定する.同様に,我々は,破綻の有効性を確認するために,最近の3つのチャネル底を下に閉じた少なくとも1個のキャンドルを必要とする.

利点

  1. この戦略は,トレンドフォローと平均逆転取引の両方のメリットを組み合わせます.より長いタイムフレームはトレンドを判断し,より短いタイムフレームはトレンド内のローカル逆転を捉えます.

  2. 複数のタイムフレームの分析を使用することで,偽のブレイクに関する問題を解決し,エントリー/出口を有効にします.

  3. パラメータは,異なる製品と市場制度に最適化できます.

リスク と 解決策

  1. 戦略はパラメータに敏感である.異なるパラメータは劇的に異なる結果をもたらす可能性がある.最適なパラメータセットを見つけるには十分なテストと最適化が必要である.

  2. ストップ・ロスは,単一の取引損失を制御するために使用されるべきです.

  3. 一般的な市場体制を考慮しない.主要なトレンド逆転点では失敗する可能性があります.主要なトレンドを評価するために他の指標を使用する必要があります.

オプティマイゼーションの方向性

  1. 最適なパラメータ,チャネル期間,チャネルタイプなどを見つけるためにパラメータ最適化を行います.

  2. 損失を制御するために,合理的なトラッキングストップとストップ・ロジックを組み込む.

  3. EMA,ケルトナーチャネル,MACDなど,主要なトレンドを決定するために他の指標を組み合わせ,重要なターニングポイントで失敗を避ける.

結論

概要すると,これは典型的なマルチタイムフレームドンチェインチャネルブレイクアウト戦略である.トレンド内のローカル逆転を把握するために,トレンドフォローと平均逆転の両方を巧みに統合する.最適化されたパラメータにより,トレンド市場では非常にうまく機能することができる.しかし,戦略自体は脆弱であり,パラメータや全体的な市場体制に敏感である.より強力な結果を達成するために,他の戦略または指標と組み合わせることを推奨する.


/*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()



もっと