추세 평균을 기반으로 한 다중 반전 전략


생성 날짜: 2023-11-21 14:53:48 마지막으로 수정됨: 2023-11-21 14:53:48
복사: 0 클릭수: 601
avatar of ChaoZhang ChaoZhang
1
집중하다
1621
수행원

추세 평균을 기반으로 한 다중 반전 전략

개요

이 전략은 여러 가지 트렌드 지표를 계산하여 반전이 발생했을 때 구매 및 판매 작업을 수행합니다. 주요 트렌드 지표는 TDI, TCF, TTF 및 TII입니다. 이 전략은 거래 신호를 생성하기 위해 어떤 지표를 사용할지 설정합니다.

전략 원칙

  • ### TDI 지표

TDI 지표는 가격의 변화의 모멘텀을 기반으로 계산한다. summing 및 smoothing 기술을 통해 구성한다. TDI 방향 지표는 TDI 곡선을 통과할 때 더 많이 하고, 아래로 통과할 때 청산한다.

  • ### TCF 지표

TCF 지표는 가격의 긍정적 변화와 부정적인 변화를 계산하여 상수와 공백의 힘을 판단한다. 긍정적 변화의 힘이 부정적인 변화의 힘보다 크면 더 많이 하고, 그렇지 않으면 청산한다.

  • ### TTF 지표

TTF 지표는 높은 점과 낮은 점의 힘을 비교하여 트렌드를 판단한다. 더 많은 신호는 TTF 지표에 100을 넘어서고, 반대로 청산한다.

  • ### TII 지표

TII 지표는 평균선과 가격 범위를 결합하여 트렌드 반전을 판단한다. 그것은 단기 및 장기 트렌드를 동시에 고려한다. 다중 신호는 TII 지표 상위 80을 통과하고, 청산은 하위 80을 통과한다.

여러 평화 포지션의 로직에 들어가며, 구성된 지표에 따라 적절한 거래 신호를 선택한다.

전략적 이점

이 전략은 여러 가지 일반적인 트렌드 트레이딩 지표를 통합하여 시장 환경에 유연하게 적응할 수 있습니다. 구체적인 장점은 다음과 같습니다:

  1. 트렌드 반전 신호를 활용하여 트렌드 전환 기회를 잡을 수 있습니다.
  2. 다양한 지표들을 구성하여 타겟으로 최적화할 수 있습니다.
  3. 풍부한 지표 조합, 조합으로 신호를 확인하기 위해 사용할 수

전략적 위험

이 전략의 주요 위험은 다음과 같습니다.

  1. 트렌드 지표에서 발생하는 거래 신호가 잘못 보고되어 손실이 발생할 수 있습니다.
  2. 단일 지표는 트렌드를 완전히 판단할 수 없으며 시장 소음에 영향을 받을 수 있습니다.
  3. 잘못 구성된 지표 파라미터와 거래 파라미터로 인해 시장이 왜곡되어 잘못된 거래가 발생할 수 있습니다

위험은 다음과 같이 줄일 수 있습니다.

  1. 지표 변수를 최적화하여 최적의 변수 조합을 찾습니다.
  2. 여러 지표 신호를 조합하여 신호 품질을 향상시킵니다.
  3. 단편적 손실을 통제하기 위한 포지션 관리 전략을 조정

전략 최적화 방향

이 전략은 다음과 같은 부분에서 최적화될 수 있습니다.

  1. 다양한 시장 주기에서 최적의 지표와 변수 조합을 테스트하는 방법
  2. 지표를 추가하거나 제거하여 최적의 조합을 찾습니다.
  3. 거래 신호를 필터링하여 잘못된 신호를 제거합니다.
  4. 포지션 관리 전략의 최적화, 예를 들어, 변동 포지션, 스톱 손실 추적
  5. 기계 학습 점수 지표를 추가하여 신호 품질을 판단하는 데 도움을 줍니다.

요약하다

이 전략은 여러 가지 트렌드 반전 지표의 장점을 결합하여 지표와 매개 변수를 구성하여 최적화하여 다양한 시장 환경에 적응하여 트렌드 반전 지점에서 작동 할 수 있습니다. 핵심은 최적의 매개 변수와 매개 변수 조합을 찾고 위험을 제어하는 것입니다. 지속적인 최적화와 검증으로 안정적으로 알파를 갖는 전략을 구축 할 수 있습니다.

전략 소스 코드
/*backtest
start: 2023-11-13 00:00:00
end: 2023-11-15 03:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
//
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © kruskakli
//
// Here is a collection of Trend Indicators as defined by M.H Pee and presented
// in various articles of the "STOCKS & COMMODITIES Magazine"
//
// The actual implementation of the indicators here are made by: everget
//
// I have gather them here so that they easily can be tested.
//
// My own test was made using 15 companies from the OMXS30 list
// during the time period of 2016-2018, and I only went LONG.
//
// The result was as follows:
//
//        Average    Std.Dev
//        profit
//  TDI    3.04%      5.97
//  TTF    1.22%.     5.73
//  TII    1.07%      6.2
//  TCF    0.32%      2.68
//
strategy("M.H Pee indicators", overlay=true)


use = input(defval="TDI", title="Use Indicator", type=input.string,
             options=["TDI","TCF","TTF","TII"])

src = close


//
// TDI
//
length = input(title="Length", type=input.integer, defval=20)
mom = change(close, length)
tdi = abs(sum(mom, length)) - sum(abs(mom), length * 2) + sum(abs(mom), length)
// Direction Indicator
tdiDirection = sum(mom, length)
tdiLong = crossover(tdiDirection, tdi)
tdiXLong = crossunder(tdiDirection, tdi)

//
// TCF
//
tcflength = input(title="Length", type=input.integer, defval=35)

plusChange(src) =>
    change_1 = change(src)
    change(src) > 0 ? change_1 : 0.0
minusChange(src) =>
    change_1 = change(src)
    change(src) > 0 ? 0.0 : -change_1

plusCF = 0.0
plusChange__1 = plusChange(src)
plusCF := plusChange(src) == 0 ? 0.0 : plusChange__1 + nz(plusCF[1])

minusCF = 0.0
minusChange__1 = minusChange(src)
minusCF := minusChange(src) == 0 ? 0.0 : minusChange__1 + nz(minusCF[1])

plusTCF = sum(plusChange(src) - minusCF, tcflength)
minusTCF = sum(minusChange(src) - plusCF, tcflength)

tcfLong = plusTCF > 0 
tcfXLong = plusTCF < 0

//
// TTF
//
ttflength = input(title="Lookback Length", type=input.integer, defval=15)

hh = highest(length)
ll = lowest(length)

buyPower = hh - nz(ll[length])
sellPower = nz(hh[length]) - ll

ttf = 200 * (buyPower - sellPower) / (buyPower + sellPower)

ttfLong = crossover(ttf, 100)
ttfXLong = crossunder(ttf, -100)

//
// TII
//
majorLength = input(title="Major Length", type=input.integer, defval=60)
minorLength = input(title="Minor Length", type=input.integer, defval=30)
upperLevel = input(title="Upper Level", type=input.integer, defval=80)
lowerLevel = input(title="Lower Level", type=input.integer, defval=20)

sma = sma(src, majorLength)

positiveSum = 0.0
negativeSum = 0.0

for i = 0 to minorLength - 1 by 1
    price = nz(src[i])
    avg = nz(sma[i])
    positiveSum := positiveSum + (price > avg ? price - avg : 0)
    negativeSum := negativeSum + (price > avg ? 0 : avg - price)
    negativeSum

tii = 100 * positiveSum / (positiveSum + negativeSum)

tiiLong = crossover(tii, 80)
tiiXLong = crossunder(tii,80)

//
// LOGIC 
//
enterLong = (use == "TDI" and tdiLong) or (use == "TCF" and tcfLong) or (use == "TTF" and ttfLong) or (use == "TII" and tiiLong)
exitLong = (use == "TDI" and tdiXLong) or (use == "TCF" and tcfXLong) or (use == "TTF" and ttfXLong) or (use == "TII" and tiiXLong)


// Time range for Back Testing
btStartYear  = input(title="Back Testing Start Year",  type=input.integer, defval=2016)
btStartMonth = input(title="Back Testing Start Month", type=input.integer, defval=1)
btStartDay   = input(title="Back Testing Start Day",   type=input.integer, defval=1)
startTime = timestamp(btStartYear, btStartMonth, btStartDay, 0, 0)

btStopYear  = input(title="Back Testing Stop Year",  type=input.integer, defval=2028)
btStopMonth = input(title="Back Testing Stop Month", type=input.integer, defval=12)
btStopDay   = input(title="Back Testing Stop Day",   type=input.integer, defval=31)
stopTime  = timestamp(btStopYear, btStopMonth, btStopDay, 0, 0)

window() => time >= startTime and time <= stopTime ? true : false


riskPerc     = input(title="Max Position  %", type=input.float, defval=20, step=0.5)
maxLossPerc  = input(title="Max Loss Risk %", type=input.float, defval=5, step=0.25)

// Average True Range (ATR) measures market volatility.
// We use it for calculating position sizes.
atrLen   = input(title="ATR Length", type=input.integer, defval=14)
stopOffset = input(title="Stop Offset", type=input.float, defval=1.5, step=0.25)
limitOffset = input(title="Limit Offset", type=input.float, defval=1.0, step=0.25)
atrValue = atr(atrLen)


// Calculate position size
maxPos = floor((strategy.equity * (riskPerc/100)) / src)
// The position sizing algorithm is based on two parts:
// a certain percentage of the strategy's equity and
// the ATR in currency value.
riskEquity  = (riskPerc / 100) * strategy.equity
// Translate the ATR into the instrument's currency value.
atrCurrency = (atrValue * syminfo.pointvalue)
posSize0    = min(floor(riskEquity / atrCurrency), maxPos)
posSize     = posSize0 < 1 ? 1 : posSize0

if (window())
    strategy.entry("Long", long=true, qty=posSize0, when=enterLong)
    strategy.close_all(when=exitLong)