Chiến lược giao dịch đường sắt kép của Oma và Apollo

Tác giả:ChaoZhang, Ngày: 2023-11-02 17:09:35
Tags:

img

Tổng quan

Chiến lược này kết hợp hai chỉ số kỹ thuật chính: chỉ số Oma và chỉ số Apollo để thực hiện giao dịch hai đường ray của các vị trí dài và ngắn. Ý tưởng cơ bản của nó là tìm cơ hội rút lui ngắn hạn khi xu hướng trung dài được đánh giá là tăng để thiết lập các vị trí dài. Khi xu hướng trung dài được đánh giá là giảm, nó tìm kiếm cơ hội trong sự phục hồi ngắn hạn để thiết lập các vị trí ngắn.

Nguyên tắc chiến lược

Chiến lược này sử dụng đường trung bình động 50 ngày và 200 ngày để xác định xu hướng trung bình dài hạn.

Tiếp theo, chiến lược sử dụng chỉ số Oma để xác định cơ hội đảo ngược giá trong ngắn hạn. Chỉ số Oma bao gồm các đường %K và %D, là kết quả của chỉ số RSI được làm mịn bằng đường trung bình động đơn giản. Khi %K phá vỡ dưới %D từ khu vực mua quá mức (trên 80), nó cho thấy giá đang chuyển từ trạng thái mua quá mức sang pullback xuống; khi %K phá vỡ trên %D từ khu vực bán quá mức (dưới 20), nó cho thấy giá đang phục hồi từ khu vực bán quá mức, tạo ra một cơ hội dài.

Ngoài ra, để lọc thêm các tín hiệu sai, chiến lược này cũng kết hợp các chỉ số Apollo. Chỉ số Apollo hiển thị các điểm cực của các giá trị %D của đường K. Khi %K hình thành một mức thấp mới, điều đó có nghĩa là sức mạnh hồi phục tương đối yếu. Khi nó hình thành một mức cao mới, nó có nghĩa là sức mạnh hồi phục tương đối mạnh. Kết hợp với các tín hiệu từ chỉ số Oma, điều này có thể cải thiện thêm độ chính xác của việc nhập.

Cụ thể, trong một xu hướng tăng, chiến lược này sẽ kiểm tra thông tin điểm cao mới cùng một lúc khi chỉ số Oma cho thấy cơ hội bên dưới khu vực mua quá mức, để xác nhận sức mạnh của sự hồi phục. Trong xu hướng giảm, khi chỉ số Oma cho thấy cơ hội ngắn vượt qua khu vực bán quá mức, chiến lược này sẽ kiểm tra thông tin điểm thấp mới cùng một lúc để xác nhận sự suy yếu của sức mạnh hồi phục.

Thông qua quy trình trên, chiến lược này tận dụng tối đa những điểm mạnh của đánh giá xu hướng trung bình dài hạn và các chỉ số đảo ngược ngắn hạn để xây dựng một hệ thống giao dịch hai đường sắt ổn định.

Ưu điểm của Chiến lược

  1. Chiến lược kết hợp giao dịch xu hướng và giao dịch đối lập bằng cách sử dụng cả đánh giá xu hướng và các chỉ số đảo ngược, tạo thành một khuôn khổ giao dịch lai ổn định.

  2. Bằng cách lọc hai chỉ báo, tỷ lệ tín hiệu sai có thể được giảm và độ tin cậy của tín hiệu được cải thiện.

  3. Các thông số chiến lược tương đối đơn giản, dễ hiểu và tối ưu hóa, phù hợp với giao dịch định lượng.

  4. Hiệu suất của chiến lược là mạnh mẽ, với tỷ lệ chiến thắng tốt và đặc điểm tỷ lệ rủi ro-lợi nhuận.

  5. Bằng cách áp dụng hai đường ray cho đường dài và đường ngắn, các cơ hội giao dịch có thể được thu được liên tục mà không bị giới hạn ở một hướng duy nhất.

Rủi ro của chiến lược

  1. Là một chiến lược đảo ngược, tổn thất liên tiếp có thể xảy ra khi xu hướng thay đổi.

  2. Chiến lược đòi hỏi sự kiểm soát cảm xúc tương đối cao từ nhà giao dịch, người cần phải chịu được một mức độ rút vốn nhất định.

  3. Một số thông số như thời gian trung bình động liên quan đến một chủ quan nhất định và cần phải được xác định thông qua kiểm tra và tối ưu hóa.

  4. Cả hai chỉ số Oma và Apollo đều có một số độ nhạy cảm với biến động bất thường và có thể thất bại trong điều kiện thị trường cực đoan.

  5. Chiến lược này phù hợp hơn với các thị trường biến động giới hạn trong phạm vi và có thể hoạt động kém hơn ở các thị trường có xu hướng mạnh.

Rủi ro có thể được giảm thiểu bằng cách điều chỉnh thích hợp thời gian trung bình động để giới thiệu lọc xu hướng và thêm dừng lỗ / lấy lợi nhuận.

Hướng dẫn tối ưu hóa

  1. Kiểm tra các kết hợp tham số khác nhau để có được các cài đặt tham số tốt hơn, ví dụ như sử dụng đường trung bình di chuyển làm mịn EWMA.

  2. Thêm các chỉ số Volume hoặc BV để đánh giá sự khác biệt có thể giúp xác minh độ tin cậy của tín hiệu.

  3. Thêm các chỉ số biến động như VIX như các chỉ số giám sát, để giảm kích thước vị trí khi thị trường hoảng loạn.

  4. Tối ưu hóa các chiến lược dừng lỗ / lấy lợi nhuận, chẳng hạn như áp dụng ATR dừng lỗ năng động.

  5. Đưa ra các thuật toán học máy để tối ưu hóa các thiết lập tham số một cách năng động.

  6. Thêm các mô hình đa yếu tố để cải thiện chất lượng tín hiệu.

Tóm lại

Nhìn chung, đây là một chiến lược giao dịch định lượng ổn định và hiệu quả. Nó kết hợp các chỉ số đánh giá xu hướng và đảo ngược, và áp dụng xác minh kép bằng cách sử dụng các chỉ số Oma và Apollo, có thể phát hiện hiệu quả các cơ hội đảo ngược giá ngắn hạn. So với việc sử dụng các hệ thống xu hướng hoặc đảo ngược thuần túy, hình thức chiến lược này mạnh mẽ hơn với kiểm soát rút tiền vượt trội và là một chiến lược giao dịch định lượng được khuyến cáo. Tất nhiên, người dùng cũng cần nhận thức được rủi ro liên quan và sử dụng tối ưu hóa tham số, dừng lỗ / lấy lợi nhuận, xác định chế độ thị trường vv để kiểm soát rủi ro và đạt được hiệu suất tốt nhất.


/*backtest
start: 2023-10-25 00:00:00
end: 2023-10-28 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © PtGambler

//@version=5
strategy("2 EMA + Stoch RSI + ATR [Pt]", shorttitle = "2EMA+Stoch+ATR", overlay=true, initial_capital = 10000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, calc_on_order_fills = false, max_bars_back = 500)

// ********************************** Trade Period / Strategy Setting **************************************
startY = input(title='Start Year', defval=2011, group = "Backtesting window")
startM = input.int(title='Start Month', defval=1, minval=1, maxval=12, group = "Backtesting window")
startD = input.int(title='Start Day', defval=1, minval=1, maxval=31, group = "Backtesting window")
finishY = input(title='Finish Year', defval=2050, group = "Backtesting window")
finishM = input.int(title='Finish Month', defval=12, minval=1, maxval=12, group = "Backtesting window")
finishD = input.int(title='Finish Day', defval=31, minval=1, maxval=31, group = "Backtesting window")
timestart = timestamp(startY, startM, startD, 00, 00)
timefinish = timestamp(finishY, finishM, finishD, 23, 59)

// ******************************************************************************************

group_ema = "EMA"
group_stoch = "Stochastic RSI"
group_atr = "ATR Stoploss Finder"

// ----------------------------------------- 2 EMA -------------------------------------

ema1_len = input.int(50, "EMA Length 1", group = group_ema)
ema2_len = input.int(200, "EMA Length 2", group = group_ema)

ema1 = ta.ema(close, ema1_len)
ema2 = ta.ema(close, ema2_len)

plot(ema1, "ema1", color.white, linewidth = 2)
plot(ema2, "ema2", color.orange, linewidth = 2)

ema_bull = ema1 > ema2
ema_bear = ema1 < ema2


// -------------------------------------- Stochastic RSI -----------------------------

smoothK = input.int(3, "K", minval=1, group = group_stoch)
smoothD = input.int(3, "D", minval=1, group = group_stoch)
lengthRSI = input.int(14, "RSI Length", minval=1, group = group_stoch)
lengthStoch = input.int(14, "Stochastic Length", minval=1, group = group_stoch)
src = close
rsi1 = ta.rsi(src, lengthRSI)
k = ta.sma(ta.stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = ta.sma(k, smoothD)

var trigger_stoch_OB = k > 80
var trigger_stoch_OS = k < 20

stoch_crossdown = ta.crossunder(k, d)
stoch_crossup = ta.crossover(k, d)

P_hi = ta.pivothigh(k,1,1)
P_lo = ta.pivotlow(k,1,1)

previous_high = ta.valuewhen(P_hi, k, 1)
previous_low = ta.valuewhen(P_lo, k, 1)
recent_high = ta.valuewhen(P_hi, k, 0)
recent_low = ta.valuewhen(P_lo, k, 0)

// --------------------------------------- ATR stop loss finder ------------------------

length = input.int(title='Length', defval=14, minval=1, group = group_atr)
smoothing = input.string(title='Smoothing', defval='EMA', options=['RMA', 'SMA', 'EMA', 'WMA'], group = group_atr)
m = input.float(0.7, 'Multiplier', step = 0.1, group = group_atr)
src1 = input(high, "Source for upper band", group = group_atr)
src2 = input(low, "Source for lower band", group = group_atr)

showatr = input.bool(true, 'Show ATR Bands', group = group_atr)
collong = input.color(color.purple, 'Long ATR SL', inline='1', group = group_atr)
colshort = input.color(color.purple, 'Short ATR SL', inline='2', group = group_atr)

ma_function(source, length) =>
    if smoothing == 'RMA'
        ta.rma(source, length)
    else
        if smoothing == 'SMA'
            ta.sma(source, length)
        else
            if smoothing == 'EMA'
                ta.ema(source, length)
            else
                ta.wma(source, length)

a = ma_function(ta.tr(true), length) * m
up = ma_function(ta.tr(true), length) * m + src1
down = src2 - ma_function(ta.tr(true), length) * m

p1 = plot(showatr ? up : na, title='ATR Short Stop Loss', color=colshort)
p2 = plot(showatr ? down : na, title='ATR Long Stop Loss', color=collong)

// ******************************* Profit Target / Stop Loss *********************************************

RR = input.float(2.0, "Reward to Risk ratio (X times SL)", step = 0.1, group = "Profit Target")

var L_PT = 0.0
var S_PT = 0.0
var L_SL = 0.0
var S_SL = 0.0

BSLE = ta.barssince(strategy.opentrades.entry_bar_index(0) == bar_index)

if strategy.position_size > 0 and BSLE == 1
    L_PT := close + (close-down)*RR
    L_SL := L_SL[1]
    S_PT := close - (up - close)*RR
    S_SL := up
else if strategy.position_size < 0 and BSLE == 1
    S_PT := close - (up - close)*RR
    S_SL := S_SL[1]
    L_PT := close + (close-down)*RR
    L_SL := down
else if strategy.position_size != 0
    L_PT := L_PT[1] 
    S_PT := S_PT[1]
else
    L_PT := close + (close-down)*RR
    L_SL := down
    S_PT := close - (up - close)*RR
    S_SL := up

entry_line = plot(strategy.position_size != 0 ? strategy.opentrades.entry_price(0) : na, "Entry Price", color.white, linewidth = 1, style = plot.style_linebr)

L_PT_line = plot(strategy.position_size > 0 and BSLE > 0 ? L_PT : na, "L PT", color.green, linewidth = 2, style = plot.style_linebr)
S_PT_line = plot(strategy.position_size < 0 and BSLE > 0 ? S_PT : na, "S PT", color.green, linewidth = 2, style = plot.style_linebr)

L_SL_line = plot(strategy.position_size > 0 and BSLE > 0 ? L_SL : na, "L SL", color.red, linewidth = 2, style = plot.style_linebr)
S_SL_line = plot(strategy.position_size < 0 and BSLE > 0 ? S_SL : na, "S SL", color.red, linewidth = 2, style = plot.style_linebr)

fill(L_PT_line, entry_line, color = color.new(color.green,90))
fill(S_PT_line, entry_line, color = color.new(color.green,90))
fill(L_SL_line, entry_line, color = color.new(color.red,90))
fill(S_SL_line, entry_line, color = color.new(color.red,90))


// ---------------------------------- strategy setup ------------------------------------------------------

var L_entry_trigger1 = false
var S_entry_trigger1 = false

L_entry_trigger1 := ema_bull and close < ema1 and k < 20 and strategy.position_size == 0
S_entry_trigger1 := ema_bear and close > ema1 and k > 80 and strategy.position_size == 0

L_entry1 = L_entry_trigger1[1] and stoch_crossup and recent_low > previous_low
S_entry1 = S_entry_trigger1[1] and stoch_crossdown and recent_high < previous_high

//debugging
plot(L_entry_trigger1[1]?1:0, "L Entry Trigger")
plot(stoch_crossup?1:0, "Stoch Cross Up")
plot(recent_low > previous_low?1:0, "Higher low")

plot(S_entry_trigger1[1]?1:0, "S Entry Trigger")
plot(stoch_crossdown?1:0, "Stoch Cross down")
plot(recent_high < previous_high?1:0, "Lower high")

if L_entry1
    strategy.entry("Long", strategy.long)

if S_entry1
    strategy.entry("Short", strategy.short)

strategy.exit("Exit Long", "Long", limit = L_PT, stop = L_SL, comment_profit = "Exit Long, PT hit", comment_loss = "Exit Long, SL hit")
strategy.exit("Exit Short", "Short", limit = S_PT, stop = S_SL, comment_profit = "Exit Short, PT hit", comment_loss = "Exit Short, SL hit")

//resetting triggers
L_entry_trigger1 := L_entry_trigger1[1] ? L_entry1 or ema_bear or S_entry1 ? false : true : L_entry_trigger1
S_entry_trigger1 := S_entry_trigger1[1] ? S_entry1 or ema_bull or L_entry1 ? false : true : S_entry_trigger1

//Trigger zones
bgcolor(L_entry_trigger1 ? color.new(color.green ,90) : na)
bgcolor(S_entry_trigger1 ? color.new(color.red,90) : na)

Thêm nữa