Chiến lược đảo ngược xu hướng dựa trên nhiều đường trung bình động

Tác giả:ChaoZhang, Ngày: 2023-11-21 14:53:48
Tags:

img

Tổng quan

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.

Chiến lược logic

  • Chỉ số TDI

    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

    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

    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.

  • Chỉ số TI

    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.

Ưu điểm

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.

  1. Nhận các cơ hội đảo ngược xu hướng kịp thời bằng cách sử dụng các tín hiệu đảo ngược
  2. Có thể tối ưu hóa thông qua cấu hình các chỉ số khác nhau
  3. Các kết hợp chỉ số phong phú có thể được sử dụng để xác nhận tín hiệu

Rủi ro

Những rủi ro chính mà chiến lược này phải đối mặt:

  1. Các tín hiệu chỉ số có thể có tín hiệu sai dẫn đến tổn thất
  2. Các chỉ số cá nhân không thể đánh giá đầy đủ xu hướng và dễ bị nhiễu thị trường
  3. Cấu hình không chính xác của các chỉ số và tham số giao dịch có thể hiểu sai thị trường và tạo ra các giao dịch sai

Các rủi ro có thể được giảm bằng cách:

  1. Tối ưu hóa các thông số chỉ số để tìm kết hợp tốt nhất
  2. Yêu cầu xác nhận tín hiệu chỉ số nhiều lần để cải thiện chất lượng
  3. Điều chỉnh kích thước vị trí để kiểm soát lỗ giao dịch duy nhất

Cơ hội gia tăng

Chiến lược có thể được cải thiện trong một số lĩnh vực:

  1. Kiểm tra các chỉ số và tham số tối ưu trong các chu kỳ thị trường khác nhau
  2. Thêm hoặc giảm các chỉ số để tìm kết hợp tốt nhất
  3. Chế độ lọc tín hiệu sai
  4. Tối ưu hóa các chiến lược kích thước vị trí, ví dụ như kích thước biến, dừng lỗ kéo theo
  5. Kết hợp điểm số học máy để hỗ trợ chất lượng tín hiệu

Kết luận

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)

Thêm nữa