다중 이동 평균에 기초한 트렌드 역전 전략

저자:차오장, 날짜: 2023-11-21 14:53:48
태그:

img

전반적인 설명

이 전략은 TDI, TCF, TTF 및 TII를 포함한 여러 트렌드 지표의 반전을 기반으로 구매 및 판매 신호를 생성합니다. 이 전략은 입시 및 출시에 사용되는 지표 신호를 선택할 수 있습니다.

전략 논리

  • TDI 지표

    TDI 지표는 집계 및 평평화 기술을 사용하여 가격 동력을 사용하여 구성됩니다. TDI 방향이 TDI 라인 위에 넘어가면 길어지고 아래로 넘어가면 빠져 나갑니다.

  • TCF 지표

    TCF 지표는 상승세와 하락세 세력을 측정하기 위해 긍정적이고 부정적인 가격 변화를 측정합니다. 긍정적 인 변화가 부정적인 변화보다 크면 길어집니다. 그렇지 않으면 종료됩니다.

  • TTF 표시기

    TTF 지표는 트렌드를 결정하기 위해 최고와 최저 가격의 힘을 비교합니다. 긴 신호는 TTF가 100을 넘을 때이며 출구는 -100을 넘을 때입니다.

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

더 많은