이 전략은 TDI, TCF, TTF 및 TII를 포함한 여러 트렌드 지표의 반전을 기반으로 구매 및 판매 신호를 생성합니다. 이 전략은 입시 및 출시에 사용되는 지표 신호를 선택할 수 있습니다.
TDI 지표는 집계 및 평평화 기술을 사용하여 가격 동력을 사용하여 구성됩니다. TDI 방향이 TDI 라인 위에 넘어가면 길어지고 아래로 넘어가면 빠져 나갑니다.
TCF 지표는 상승세와 하락세 세력을 측정하기 위해 긍정적이고 부정적인 가격 변화를 측정합니다. 긍정적 인 변화가 부정적인 변화보다 크면 길어집니다. 그렇지 않으면 종료됩니다.
TTF 지표는 트렌드를 결정하기 위해 최고와 최저 가격의 힘을 비교합니다. 긴 신호는 TTF가 100을 넘을 때이며 출구는 -100을 넘을 때입니다.
TII는 트렌드 반전을 식별하기 위해 이동 평균과 가격 대역을 결합합니다. 단기 및 장기 트렌드를 모두 고려합니다. 긴 신호는 80 이상이고 출구는 80 이하입니다.
엔트리 길고 가까운 로직은 구성된 지표에 기초하여 적절한 신호를 선택합니다.
이 전략은 일반적으로 사용되는 트렌드 거래 지표를 통합하여 변화하는 시장 조건에 적응 할 수있는 유연성을 제공합니다.
이 전략의 주요 위험은 다음과 같습니다.
위험은 다음과 같이 감소 할 수 있습니다.
이 전략은 몇 가지 분야에서 강화될 수 있습니다.
여러 트렌드 역전 지표와 최적화 구성을 결합함으로써,이 전략은 트렌드 전환점에 작동하기 위해 다양한 시장 환경에 적응 할 수 있습니다. 핵심은 위험을 제어하는 동시에 최적의 매개 변수와 지표를 찾는 것입니다. 지속적인 최적화와 검증은 안정적인 알파 전략을 구축 할 수 있습니다.
/*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)