Ichimoku Backtester với TP, SL và Cloud Confirmation

Tác giả:ChaoZhang, Ngày: 2023-11-24 17:32:47
Tags:

img

Tổng quan

Đây là một chiến lược backtesting Ichimoku với lấy lợi nhuận, dừng lỗ và xác nhận đám mây. Nó nhằm mục đích cải thiện lợi nhuận bằng cách nắm bắt chính xác xu hướng sử dụng chỉ số Ichimoku.

Chiến lược logic

Cốt lõi của chiến lược này là xây dựng các thành phần Ichimoku dựa trên các tham số đầu vào của người dùng - Tenkan-Sen, Kijun-Sen, Senkou Span A & B và Chikou Span. Nó xác định các tín hiệu tăng (dài) và giảm (ngắn) khi giá vượt qua các đường cân bằng này.

Ngoài ra, nó thực hiện dừng lỗ và lấy lợi nhuận dựa trên giá nhập để quản lý rủi ro & phần thưởng. Ngoài ra còn có tùy chọn để chờ xác nhận đám mây, tức là Senkou Span A > B cho dài và Senkou Span A < B cho ngắn. Điều này giúp tránh đột phá sai.

Ưu điểm

Những lợi thế chính của chiến lược này là ba:

  1. Ichimoku rất giỏi trong việc xác định xu hướng và động lực.

  2. Các tính năng dừng lỗ và lấy lợi nhuận tối đa hóa phần thưởng trong khi giảm thiểu rủi ro. Điều này tối ưu hóa hồ sơ rủi ro - lợi nhuận.

  3. Cloud xác nhận lọc ra các tín hiệu sai, đảm bảo khả năng nhập cao. Điều này tăng lợi nhuận.

Rủi ro

Tuy nhiên, cũng có một số rủi ro chính cần xem xét:

  1. Ichimoku có xu hướng giảm trong các thị trường không có xu hướng rõ ràng.

  2. Mây là một dấu hiệu chậm trễ.

  3. Tối ưu hóa mức dừng lỗ và lấy lợi nhuận là một thách thức và nhạy cảm.

Những cải tiến

Một số cách để cải thiện chiến lược này:

  1. Kết hợp Ichimoku với các chỉ số hàng đầu như RSI để xác nhận thêm và nhập sớm.

  2. Điều chỉnh thích nghi dừng lỗ và lấy lợi nhuận dựa trên biến động thay vì sử dụng tỷ lệ phần trăm cố định.

  3. Kiểm tra các thông số tối ưu trên các tài sản và khung thời gian khác nhau để xác định thiết lập tốt nhất cho chiến lược.

  4. Kết hợp học máy để tối ưu hóa liên tục các thông số và quy tắc chiến lược dựa trên dữ liệu cập nhật.

Kết luận

Đây là một hệ thống Ichimoku vững chắc với các tính năng nắm bắt xu hướng và quản lý rủi ro tốt. Với một số cải tiến, nó có thể là một bổ sung tuyệt vời cho cách tiếp cận giao dịch tổng thể. Nó hoạt động tốt trên các thị trường ngoại hối, hàng hóa và tiền điện tử.


/*backtest
start: 2022-11-17 00:00:00
end: 2023-11-23 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

strategy("Ichimoku Backtester with TP and SL", overlay=true, 
     currency = currency.USD, default_qty_type = strategy.percent_of_equity, 
     default_qty_value = 95)
//@version=4

//Inputs
ts_bars = input(9, minval=1, title="Tenkan-Sen Bars")
ks_bars = input(26, minval=1, title="Kijun-Sen Bars")
ssb_bars = input(52, minval=1, title="Senkou-Span B Bars")
cs_offset = input(26, minval=1, title="Chikou-Span Offset")
ss_offset = input(26, minval=1, title="Senkou-Span Offset")
long_entry = input(true, title="Long Entry")
short_entry = input(true, title="Short Entry")

wait_for_cloud = input(true, title="Wait for Cloud Confirmation")

use_short_stop_loss = input(true, title="Use Short Stop Loss")
short_stop_loss = input(title="Short Stop Loss (%)", type=input.float, minval=0.0, step=0.1, 
     defval=5) * 0.01
use_long_stop_loss = input(true, title="Use Long Stop Loss")
long_stop_loss = input(title="Long Stop Loss (%)", type=input.float, minval=0.0, step=0.1, 
     defval=5) * 0.01
     
use_short_take_profit = input(true, title="Use Short Take Profit")
short_take_profit = input(title="Short Take Profit (%)", type=input.float, minval=0.0, step=0.1,
     defval = 20) * .01
use_long_take_profit = input(true, title="Use Long Take Profit")
long_take_profit = input(title="Long Take Profit (%)", type=input.float, minval=0.0, step=0.1,
     defval = 20) * .01

// === INPUT SHOW PLOT ===
showDate  = input(defval = false, title = "Show Date Range", type = input.bool)

// === INPUT BACKTEST RANGE ===
fromMonth = input(defval = 1,    title = "From Month",      type = input.integer, minval = 1, maxval = 12)
fromDay   = input(defval = 1,    title = "From Day",        type = input.integer, minval = 1, maxval = 31)
fromYear  = input(defval = 2020, title = "From Year",       type = input.integer, minval = 1970)
thruMonth = input(defval = 1,    title = "Thru Month",      type = input.integer, minval = 1, maxval = 12)
thruDay   = input(defval = 1,    title = "Thru Day",        type = input.integer, minval = 1, maxval = 31)
thruYear  = input(defval = 2112, title = "Thru Year",       type = input.integer, minval = 1970)



// === FUNCTION EXAMPLE ===
start     = timestamp(fromYear, fromMonth, fromDay, 00, 00)        // backtest start window
finish    = timestamp(thruYear, thruMonth, thruDay, 23, 59)        // backtest finish window
window()  => time >= start and time <= finish ? true : false       // create function "within window of time"

middle(len) => avg(lowest(len), highest(len))

// Ichimoku Components
tenkan = middle(ts_bars)
kijun = middle(ks_bars)
senkouA = avg(tenkan, kijun)
senkouB = middle(ssb_bars)

bgcolor(color = showDate and window() ? color.gray : na, transp = 90)  // plot within time window

// Plot Ichimoku Kinko Hyo
plot(tenkan, color=#0496ff, title="Tenkan-Sen")
plot(kijun, color=#991515, title="Kijun-Sen")
plot(close, offset=-cs_offset+1, color=#459915, title="Chikou-Span")
sa=plot(senkouA, offset=ss_offset-1, color=color.green, title="Senkou-Span A")
sb=plot(senkouB, offset=ss_offset-1, color=color.red, title="Senkou-Span B")
fill(sa, sb, color = senkouA > senkouB ? color.green : color.red, title="Cloud color")

ss_high = max(senkouA[ss_offset-1], senkouB[ss_offset-1])
ss_low = min(senkouA[ss_offset-1], senkouB[ss_offset-1])

// Entry/Exit Signals
tk_cross_bull = tenkan > kijun
tk_cross_bear = tenkan < kijun
cs_cross_bull = mom(close, cs_offset-1) > 0
cs_cross_bear = mom(close, cs_offset-1) < 0
price_above_kumo = close > ss_high
price_below_kumo = close < ss_low
senkou_green = senkouA > senkouB ? true : false

bullish = tk_cross_bull and cs_cross_bull and price_above_kumo
bearish = tk_cross_bear and cs_cross_bear and price_below_kumo

if (wait_for_cloud)
    bullish := bullish and senkou_green
    bearish := bearish and not senkou_green

longStopPrice  = strategy.position_avg_price * (1 - long_stop_loss)
shortStopPrice = strategy.position_avg_price * (1 + short_stop_loss)
longLimitPrice = strategy.position_avg_price * (1 + long_take_profit)
shortLimitPrice = strategy.position_avg_price * (1 - short_take_profit)

in_long = false
in_long := in_long[1]


open_long = bullish and not in_long
open_short = bearish and in_long


if (open_long)
    in_long := true
if (open_short)
    in_long := false

strategy.entry("Long", strategy.long, when=open_long and long_entry and  (showDate ? window() : true))
strategy.entry("Short", strategy.short ,when=open_short and short_entry and (showDate ? window() : true))

if (strategy.position_size > 0.0)
    if (use_long_stop_loss and not use_long_take_profit)
        strategy.exit("Long", stop = longStopPrice)
    if (use_long_take_profit and not use_long_stop_loss)
        strategy.exit("Long", limit = longLimitPrice)
    if (use_long_take_profit and use_long_stop_loss)
        strategy.exit("Long", stop = longStopPrice, limit=longLimitPrice)
if (strategy.position_size < 0.0)
    if (use_short_stop_loss and not use_short_take_profit)
        strategy.exit("Short", stop = shortStopPrice)
    if (use_short_take_profit and not use_short_stop_loss)
        strategy.exit("Short", limit = shortLimitPrice)
    if (use_short_take_profit and use_short_stop_loss)
        strategy.exit("Short", stop = shortStopPrice, limit = shortLimitPrice)

strategy.close("Long", when=bearish and not short_entry and (showDate ? window() : true))
strategy.close("Short", when=bullish and not long_entry and (showDate ? window() : true))


Thêm nữa