
이 전략은 여러 가지 트렌드 지표를 계산하여 반전이 발생했을 때 구매 및 판매 작업을 수행합니다. 주요 트렌드 지표는 TDI, TCF, TTF 및 TII입니다. 이 전략은 거래 신호를 생성하기 위해 어떤 지표를 사용할지 설정합니다.
TDI 지표는 가격의 변화의 모멘텀을 기반으로 계산한다. summing 및 smoothing 기술을 통해 구성한다. TDI 방향 지표는 TDI 곡선을 통과할 때 더 많이 하고, 아래로 통과할 때 청산한다.
TCF 지표는 가격의 긍정적 변화와 부정적인 변화를 계산하여 상수와 공백의 힘을 판단한다. 긍정적 변화의 힘이 부정적인 변화의 힘보다 크면 더 많이 하고, 그렇지 않으면 청산한다.
TTF 지표는 높은 점과 낮은 점의 힘을 비교하여 트렌드를 판단한다. 더 많은 신호는 TTF 지표에 100을 넘어서고, 반대로 청산한다.
TII 지표는 평균선과 가격 범위를 결합하여 트렌드 반전을 판단한다. 그것은 단기 및 장기 트렌드를 동시에 고려한다. 다중 신호는 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)