Chiến lược này tạo ra tín hiệu mua và bán dựa trên sự đảo ngược của nhiều chỉ số xu hướng bao gồm TDI, TCF, TTF và TII. Chiến lược cho phép chọn tín hiệu chỉ số nào để sử dụng cho các bước vào và ra.
Chỉ số TDI được xây dựng bằng cách sử dụng động lực giá với các kỹ thuật tổng hợp và làm mịn. Nó đi dài khi hướng TDI vượt qua trên đường TDI và thoát khi vượt qua bên dưới.
Chỉ số TCF đo lường sự thay đổi giá tích cực và tiêu cực để đánh giá các lực tăng và giảm. Nó đi dài khi sự thay đổi tích cực lớn hơn sự thay đổi tiêu cực, nếu không nó sẽ ra.
Chỉ số TTF so sánh sức mạnh của giá cao nhất và thấp nhất để xác định xu hướng.
TII kết hợp các dải giá và đường trung bình động để xác định sự đảo ngược xu hướng. Nó xem xét cả xu hướng ngắn hạn và dài hạn.
Logic đầu vào dài và gần chọn các tín hiệu phù hợp dựa trên chỉ số được cấu hình.
Chiến lược này kết hợp một số chỉ số giao dịch xu hướng được sử dụng phổ biến, cho phép linh hoạt để thích nghi với các điều kiện thị trường thay đổi.
Những rủi ro chính mà chiến lược này phải đối mặt:
Các rủi ro có thể được giảm bằng cách:
Chiến lược có thể được cải thiện trong một số lĩnh vực:
Bằng cách kết hợp nhiều chỉ số đảo ngược xu hướng và tối ưu hóa cấu hình, chiến lược này có thể thích nghi với các môi trường thị trường khác nhau để hoạt động tại các điểm chuyển hướng xu hướng.
/*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)