멀티스케일 Donqi 계단형 채널 기반 거래 전략


생성 날짜: 2024-02-27 14:57:37 마지막으로 수정됨: 2024-02-27 14:57:37
복사: 0 클릭수: 657
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

멀티스케일 Donqi 계단형 채널 기반 거래 전략

개요

이것은 여러 시간 척도를 이용한 단치 통로를 이용한 입구와 출구 지점을 판단하는 거래 전략이다. 전략의 주요 아이디어는: 더 긴 시간 척도에서 트렌드 방향을 판단하여 입구 시점을 찾는 것; 더 짧은 시간 척도에서 트렌드 반전을 판단하여 출구 시점을 찾는 것 이다.

전략 원칙

이 전략은 주로 둥지 통로의 개념을 이용한다. 둥지 통로는 통로의 상단, 하단, 중선으로 구성된다. 통로의 폭은 시간 척도에 따라 변한다. 우리는 여기서 다른 시간 척도를 사용하여 둥지 통로를 구성한다. 구체적으로:

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