Chiến lược giao dịch định lượng dựa trên Stoch và EMA


Ngày tạo: 2023-09-15 11:31:16 sửa đổi lần cuối: 2023-09-15 11:31:16
sao chép: 0 Số nhấp chuột: 655
1
tập trung vào
1617
Người theo dõi

Trong bài viết này, chúng tôi sẽ giới thiệu chi tiết về một chiến lược giao dịch định lượng kết hợp chỉ số Stoch và đường trung bình EMA. Chiến lược này tạo ra tín hiệu giao dịch dựa trên giá trị của chỉ số Stoch và sử dụng các tín hiệu EMA ngoại trừ hướng chính thống.

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

Chiến lược này giao dịch chủ yếu thông qua các công cụ và logic sau:

  1. Tính toán chỉ số Stoch bao gồm giá trị K, giá trị D, giá trị K phản ánh biến động giá nhanh, giá trị D được xử lý trơn tru;

  2. Thiết lập các vùng mua và bán trên chỉ số Stoch để tạo ra tín hiệu giao dịch dựa trên kích thước tương đối của giá trị K, D;

  3. Tính toán đường trung bình của EMA cho một chu kỳ nhất định, để xác định xu hướng của giá;

  4. Giao dịch chỉ được thực hiện khi tín hiệu chỉ số Stoch phù hợp với đường trung bình của EMA;

  5. Xây dựng vị trí đa đầu hoặc trống theo tín hiệu và thiết lập điểm dừng lỗ.

Bằng cách này, chỉ số Stoch nắm bắt các cơ hội mua quá mức, EMA loại bỏ các tín hiệu không hợp lý, cả hai kết hợp với nhau để tạo ra chiến lược ổn định.

2 - Lợi thế chiến lược

Lợi thế lớn nhất của chiến lược này là các chỉ số bổ sung cho nhau, Stoch đánh giá quá mua quá bán, EMA đánh giá hướng chính thống, kết hợp với việc giảm giao dịch sai.

Thứ hai, giá trị K, D có thể được điều chỉnh để thích ứng với các tham số tối ưu hóa khác nhau.

Cuối cùng, các thiết lập dừng lỗ cũng làm cho mỗi giao dịch có lợi nhuận và rủi ro rõ ràng, giúp quản lý tiền.

Ba, rủi ro tiềm ẩn

Tuy nhiên, chiến lược này cũng có những vấn đề tiềm ẩn:

Đầu tiên, cả chỉ số Stoch và EMA có thể bị trễ, dẫn đến mất thời gian giao dịch tốt nhất.

Thứ hai, dừng quá nhỏ có thể tạo ra quá nhiều dừng không hiệu quả.

Cuối cùng, tối ưu hóa đa tham số đòi hỏi rất nhiều công việc để tránh quá phù hợp.

Bốn nội dung, tóm tắt

Bài viết này mô tả chi tiết một chiến lược giao dịch định lượng kết hợp Stoch và EMA. Nó có thể xác định cơ hội đảo ngược vùng mua quá mức và lọc các tín hiệu vô hiệu thông qua EMA. Chiến lược này có thể mang lại lợi nhuận ổn định thông qua tối ưu hóa tham số, nhưng cũng cần lưu ý để ngăn chặn sự xuất hiện của các vấn đề trên.

Mã nguồn chiến lược
/*backtest
start: 2023-08-15 00:00:00
end: 2023-08-26 00:00:00
period: 1h
basePeriod: 15m
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/

//@version=5
strategy(title="EMA Stoch Strategy For ProfitView", overlay=true, calc_on_every_tick=true, process_orders_on_close=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1, initial_capital=1000)

// take profit e stop loss
TakeProfitPercent = input.float(defval = 0.0, title="Take Profit (%) [0 = Disabled]",minval = 0, step=.25,group='TP / SL')
StopLossPercent = input.float(defval = 0.0, title="Stop Loss (%) [0 = Disabled]",minval = 0, step=.25,group='TP / SL')

// Stoch
smoothK = input.int(1, title="K Smoothing", minval=1,group='Stochastic')
periodD = input.int(3, title="D Smoothing", minval=1,group='Stochastic')
lenghtRSI= input.int(14, "RSI Length", minval=1) 
lenghtStoch = input.int(14, "Stochastic Length", minval=1)
src = input(close, title="RSI Source")

rsi1 = ta.rsi(src, lenghtRSI)
k = ta.sma(ta.stoch(rsi1, rsi1, rsi1, lenghtStoch), smoothK)
d = ta.sma(k, periodD)

plot(k, title="K", color=#2962FF)
plot(d, title="D", color=#FF6D00)
// bgcolor(color=color.from_gradient(k, 0, 100, color.new(#2962FF, 100), color.new(#2962FF, 95)), title="K BG")
// bgcolor(color=color.from_gradient(d, 0, 100, color.new(#FF6D00, 100), color.new(#FF6D00, 95)), title="D BG")


// ema
src1= input(close,title='Source EMA ',group='EMA')
len1= input(200,title='Length EMA ',group='EMA')
ema1= ta.ema(src1,len1)
plot(ema1,title='EMA',color= color.blue ,linewidth=2)

// signals
LongVal= input(20,title='Stoch below/cross this value for Long signals',group='Signal Options')
scegliLong= input.string('Stoch Below Value', options= ['Stoch Below Value' , 'K&D Cross Below Value' , 'Stoch CrossUp the Value'] , title='Long Signal Type')

long1=  scegliLong == 'Stoch Below Value' ?  k < LongVal and d < LongVal and close > ema1 : na
long2=  scegliLong == 'K&D Cross Below Value' ? ta.cross(k,d) and k < LongVal and d < LongVal and close > ema1 : na
long3=  scegliLong == 'Stoch CrossUp the Value' ? ta.crossover(k,LongVal) and close > ema1 : na

shortVal= input(80,title='Stoch above/cross this value for Short signals',group='Signal Options')
scegliShort= input.string('Stoch Above Value', options= ['Stoch Above Value' , 'K&D Cross Above Value' , 'Stoch CrossDown the Value'] , title='Short Signal Type' )

short1= scegliShort == 'Stoch Above Value' ? k > shortVal and d > shortVal and close < ema1 : na
short2= scegliShort == 'K&D Cross Above Value' ?  ta.cross(k,d) and k > shortVal and d > shortVal and close < ema1 : na
short3= scegliShort == 'Stoch CrossDown the Value' ?  ta.crossunder(k,shortVal) and close < ema1 : na


//  Strategy Backtest Limiting Algorithm/
i_startTime = input(defval = timestamp("01 Jan 2014 00:00 +0000"), title = "Backtesting Start Time", inline="timestart", group='Backtesting')
i_endTime = input(defval = timestamp("01 Jan 2100 23:59 +0000"), title = "Backtesting End Time", inline="timeend", group='Backtesting')
timeCond = true

pv_ex = input.string("deribit-testnet", title="Exchange", group='PV Settings')
pv_sym = input.string("btc-perpetual", title="Symbol", group='PV Settings')
pv_acc = input.string("", title="Account", group='PV Settings')
pv_alert_long = input.string("", title="PV Alert Name Longs", group='PV Settings')
pv_alert_short = input.string("", title="PV Alert Name Shorts", group='PV Settings')
pv_alert_cancel = input.string("", title="PV Alert Name TP/SL", group='PV Settings')

profit_abs = (close * (TakeProfitPercent / 100))
stop_abs = (close * (StopLossPercent / 100))

ProfitTarget = TakeProfitPercent > 0 ? profit_abs / syminfo.mintick : na
LossTarget = StopLossPercent > 0 ? stop_abs / syminfo.mintick : na

// Make sure we are within the bar range, Set up entries and exit conditions
var entryprice = 0.0
var profitprice = 0.0
var stopprice = 0.0
exsym = pv_ex == "" ? "" : "ex=" + pv_ex + ","
exsym := pv_sym == "" ? exsym : exsym + "sym=" + pv_sym

if ((long1 or long2 or long3) and timeCond and strategy.position_size <= 0)
    strategy.entry("Long", strategy.long, when=barstate.isconfirmed)
    entryprice := close
    profitprice := entryprice+profit_abs
    stopprice := entryprice-stop_abs
    
    tpsl_str = TakeProfitPercent > 0 ? ",mytp=" + str.tostring(profitprice) : ""
    tpsl_str := StopLossPercent > 0 ? tpsl_str + ",mysl=" + str.tostring(stopprice) : tpsl_str
    alert(pv_alert_long + "(" + exsym + ",acc=" + pv_acc + tpsl_str +  ")", alert.freq_once_per_bar_close)

if ((short1 or short2 or short3) and timeCond and strategy.position_size >= 0)
    strategy.entry("Short", strategy.short, when=barstate.isconfirmed)
    entryprice := close
    profitprice := entryprice-profit_abs
    stopprice := entryprice+stop_abs
    
    tpsl_str = TakeProfitPercent > 0 ? ",mytp=" + str.tostring(profitprice) : ""
    tpsl_str := StopLossPercent > 0 ? tpsl_str + ",mysl=" + str.tostring(stopprice) : tpsl_str
    alert(pv_alert_short + "(" + exsym + ",acc=" + pv_acc + tpsl_str +  ")", alert.freq_once_per_bar_close)
    
tpsl_hit_long = (strategy.position_size[1] > 0 and ((TakeProfitPercent > 0 and high > profitprice[1]) or (StopLossPercent > 0 and low < stopprice[1])))
tpsl_hit_short = (strategy.position_size[1] < 0 and ((TakeProfitPercent > 0 and low < profitprice[1]) or (StopLossPercent > 0 and high > stopprice[1])))

if (tpsl_hit_long or tpsl_hit_short)
    alert(pv_alert_cancel + "(" + exsym + ",acc=" + pv_acc + ")", alert.freq_once_per_bar)


strategy.exit("Exit Long (TP/SL)", from_entry = "Long" , profit = ProfitTarget, loss = LossTarget)
strategy.exit("Exit Short (TP/SL)", from_entry = "Short", profit = ProfitTarget, loss = LossTarget)

plot(entryprice, title="Entry Price", color=strategy.opentrades > 0 ? color.gray : color.new(color.gray, 100))
plot(profitprice, title="Profit Price", color=strategy.opentrades > 0 and TakeProfitPercent > 0 ? color.green : color.new(color.green, 100))
plot(stopprice, title="Stop Price", color=strategy.opentrades > 0 and StopLossPercent > 0? color.red : color.new(color.red, 100))