Modulo logic với chiến lược lọc EMA

Tác giả:ChaoZhang, Ngày: 2023-12-13 15:55:07
Tags:

img

Tổng quan

Chiến lược này kết hợp các hoạt động toán học mô-đun và trung bình động theo hàm số nhân để tạo ra một bộ lọc ngẫu nhiên mạnh mẽ để xác định hướng vị trí. Nó đầu tiên tính phần còn lại của giá chia cho một số được đặt ra, và một tín hiệu giao dịch được tạo ra nếu phần còn lại là 0. Nếu tín hiệu này nằm dưới đường EMA, đi ngắn; nếu trên, đi dài. Chiến lược này tích hợp sự ngẫu nhiên của các hoạt động toán học và xu hướng phán đoán của các chỉ số kỹ thuật, sử dụng xác thực chéo giữa các chỉ số của các chu kỳ khác nhau để lọc hiệu quả một số tiếng ồn thị trường.

Chiến lược logic

  1. Đặt giá trị đầu vào giá a để đóng, có thể sửa đổi; đặt số chia b là 4, có thể sửa đổi.
  2. Tính toán phần còn lại modulo của a chia cho b, xác định nếu modulo bằng 0.
  3. Đặt chiều dài của EMA (MALen) thành 70 giai đoạn theo mặc định như một chỉ số cho xu hướng trung và dài hạn.
  4. Khi modulo bằng 0, một tín hiệu giao dịch số lẻ được tạo ra. Kết hợp với mối quan hệ EMA, nó xác định hướng. Khi giá vượt qua EMA, một tín hiệu BUY được tạo ra; khi giá vượt qua dưới EMA, một tín hiệu SELL được tạo ra.
  5. Các mục giao dịch được mở dài hoặc ngắn dựa trên hướng tín hiệu. Chiến lược có thể hạn chế vị trí mở ngược để kiểm soát số lượng giao dịch.
  6. Các điều kiện dừng lỗ được thiết lập dựa trên 3 tùy chọn: dừng lỗ cố định, dừng lỗ ATR, dừng lỗ dao động giá.
  7. Trailing stop có thể được kích hoạt để khóa trong lợi nhuận nhiều hơn, vô hiệu hóa theo mặc định.

Phân tích lợi thế

  1. Sự ngẫu nhiên của toán học modulo tránh tác động của biến động giá, kết hợp với phán đoán xu hướng của đường trung bình động, nó có thể lọc hiệu quả các tín hiệu không hợp lệ.
  2. EMA như một thước đo cho xu hướng trung bình đến dài hạn kết hợp với tín hiệu modulo ngắn hạn thực hiện xác minh nhiều lớp và tránh các tín hiệu sai.
  3. Các tham số có thể tùy chỉnh rất linh hoạt, có thể được điều chỉnh cho các thị trường khác nhau để tìm kết hợp tham số tối ưu.
  4. Tích hợp nhiều phương pháp dừng lỗ để kiểm soát rủi ro.
  5. Hỗ trợ mở ngược trực tiếp các vị trí để chuyển hướng liền mạch.

Phân tích rủi ro

  1. Cài đặt tham số không chính xác có thể tạo ra quá nhiều tín hiệu giao dịch, làm tăng tần suất giao dịch và chi phí trượt.
  2. EMA là chỉ số đánh giá xu hướng duy nhất có thể chậm lại, thiếu thời điểm đảo ngược giá.
  3. Phương pháp dừng lỗ cố định có thể quá cơ học, không thể điều chỉnh cho biến động thị trường.
  4. Mở ngược trực tiếp làm tăng tần suất điều chỉnh vị trí, tăng chi phí và rủi ro.

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

  1. Kiểm tra các đường trung bình động khác thay vì EMA, hoặc kết hợp EMA với các MAs khác, để xem liệu tỷ lệ lợi nhuận có thể được cải thiện hay không.
  2. Hãy thử kết hợp bộ lọc modulo với các chiến lược khác như Bollinger Bands, mô hình nến vv để tạo ra các bộ lọc ổn định hơn.
  3. Nghiên cứu các phương pháp dừng lỗ thích nghi dựa trên mức độ biến động thị trường để điều chỉnh khoảng cách dừng.
  4. Đặt giới hạn về số lượng giao dịch hoặc ngưỡng lợi nhuận/mất để hạn chế tần suất mở ngược trực tiếp.

Kết luận

Chiến lược này kết hợp hiệu quả sự ngẫu nhiên của các hoạt động mô-đun và đánh giá xu hướng của các đường trung bình động thông qua các điều chỉnh tham số linh hoạt phục vụ cho các môi trường thị trường khác nhau, dẫn đến các tín hiệu giao dịch đáng tin cậy. Nó cũng tích hợp các cơ chế dừng khác nhau để kiểm soát rủi ro cũng như lấy lợi nhuận và dừng lại để khóa lợi nhuận.


/*backtest
start: 2023-11-12 00:00:00
end: 2023-12-12 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/
// © tweakerID

// To understand this strategy first we need to look into the Modulo (%) operator. The modulo returns the remainder numerator 
// of a division's quotient (the result). If we do 5 / 3, we get 1 and 2/3 as a result, where the remainder is 2 (two thirds, in this case). This can be
// used for many things, for example to determine when a number divides evenly into another number. If we divide 3/3, our result is 1,
// with no remainder numerator, hence our modulo result is 0. In this strategy, we compare a given number (divisor, user defined) with the
// the closing price of every candle (dividend, modifiable from the inputs panel) to determine if the result between their division is an even number. 
// If the answer is true, we have an entry signal. If this signal occurs below the EMA (length is defined by the user) we go short and
// viceversa for longs. This logic can be reversed. In this case, the modulo works as a random-like filter for a moving average strategy
// that usually struggles when the market is ranging.

//@version=4

//@version=4
strategy("Modulo Logic + EMA Strat", 
     overlay=true, 
     default_qty_type=strategy.percent_of_equity, 
     default_qty_value=100, 
     initial_capital=10000, 
     commission_value=0.04, 
     calc_on_every_tick=false, 
     slippage=0)

direction = input(0, title = "Strategy Direction", type=input.integer, minval=-1, maxval=1)
strategy.risk.allow_entry_in(direction == 0 ? strategy.direction.all : (direction < 0 ? strategy.direction.short : strategy.direction.long))

/////////////////////// STRATEGY INPUTS ////////////////////////////////////////
title1=input(true, "-----------------Strategy Inputs-------------------")  

a=input(close, title="Dividend")
b=input(4, title="Divisor")
usemod=input(true, title="Use Modulo Logic")
MALen=input(70, title="EMA Length")

/////////////////////// BACKTESTER /////////////////////////////////////////////
title2=input(true, "-----------------General Inputs-------------------")  

// Backtester General Inputs
i_SL=input(true, title="Use Stop Loss and Take Profit")
i_SLType=input(defval="ATR Stop", title="Type Of Stop", options=["Strategy Stop", "Swing Lo/Hi", "ATR Stop"])
i_SPL=input(defval=10, title="Swing Point Lookback")
i_PercIncrement=input(defval=3, step=.1, title="Swing Point SL Perc Increment")*0.01
i_ATR = input(14, title="ATR Length")
i_ATRMult = input(4, step=.1, title="ATR Multiple")
i_TPRRR = input(1, step=.1, title="Take Profit Risk Reward Ratio")
TS=input(false, title="Trailing Stop")

// Bought and Sold Boolean Signal
bought = strategy.position_size > strategy.position_size[1] 
 or strategy.position_size < strategy.position_size[1]

// Price Action Stop and Take Profit
LL=(lowest(i_SPL))*(1-i_PercIncrement)
HH=(highest(i_SPL))*(1+i_PercIncrement)
LL_price = valuewhen(bought, LL, 0)
HH_price = valuewhen(bought, HH, 0)
entry_LL_price = strategy.position_size > 0 ? LL_price : na 
entry_HH_price = strategy.position_size < 0 ? HH_price : na 
tp=strategy.position_avg_price + (strategy.position_avg_price - entry_LL_price)*i_TPRRR
stp=strategy.position_avg_price - (entry_HH_price - strategy.position_avg_price)*i_TPRRR

// ATR Stop
ATR=atr(i_ATR)*i_ATRMult
ATRLong = ohlc4 - ATR
ATRShort = ohlc4 + ATR
ATRLongStop = valuewhen(bought, ATRLong, 0)
ATRShortStop = valuewhen(bought, ATRShort, 0)
LongSL_ATR_price = strategy.position_size > 0 ? ATRLongStop : na 
ShortSL_ATR_price = strategy.position_size < 0 ? ATRShortStop : na 
ATRtp=strategy.position_avg_price + (strategy.position_avg_price - LongSL_ATR_price)*i_TPRRR
ATRstp=strategy.position_avg_price - (ShortSL_ATR_price - strategy.position_avg_price)*i_TPRRR


// Strategy Stop

float LongStop = na
float ShortStop = na
float StratTP = na
float StratSTP = na

/////////////////////// STRATEGY LOGIC /////////////////////////////////////////

modulo=a%b
evennumber=modulo==0
MA=ema(close, MALen)
plot(MA)

BUY=usemod ? evennumber and close > MA : close > MA
SELL=usemod ? evennumber and close < MA : close < MA

//Trading Inputs
DPR=input(true, "Allow Direct Position Reverse")
reverse=input(false, "Reverse Trades")

// Entries
if reverse
    if not DPR
        strategy.entry("long", strategy.long, when=SELL and strategy.position_size == 0)
        strategy.entry("short", strategy.short, when=BUY and strategy.position_size == 0)
    else     
        strategy.entry("long", strategy.long, when=SELL)
        strategy.entry("short", strategy.short, when=BUY)
else
    if not DPR 
        strategy.entry("long", strategy.long, when=BUY and strategy.position_size == 0)
        strategy.entry("short", strategy.short, when=SELL and strategy.position_size == 0)
    else
        strategy.entry("long", strategy.long, when=BUY)
        strategy.entry("short", strategy.short, when=SELL)


SL= i_SLType == "Swing Lo/Hi" ? entry_LL_price : i_SLType == "ATR Stop" ? LongSL_ATR_price : LongStop
SSL= i_SLType == "Swing Lo/Hi" ? entry_HH_price : i_SLType == "ATR Stop" ? ShortSL_ATR_price : ShortStop
TP= i_SLType == "Swing Lo/Hi" ? tp : i_SLType == "ATR Stop" ? ATRtp : StratTP
STP= i_SLType == "Swing Lo/Hi" ? stp : i_SLType == "ATR Stop" ? ATRstp : StratSTP

//TrailingStop
dif=(valuewhen(strategy.position_size>0 and strategy.position_size[1]<=0, high,0))
 -strategy.position_avg_price
trailOffset     = strategy.position_avg_price - SL
var tstop = float(na)
if strategy.position_size > 0
    tstop := high- trailOffset - dif
    if tstop<tstop[1]
        tstop:=tstop[1]
else
    tstop := na
StrailOffset     = SSL - strategy.position_avg_price
var Ststop = float(na)
Sdif=strategy.position_avg_price-(valuewhen(strategy.position_size<0 
 and strategy.position_size[1]>=0, low,0))
if strategy.position_size < 0
    Ststop := low+ StrailOffset + Sdif
    if Ststop>Ststop[1]
        Ststop:=Ststop[1]
else
    Ststop := na

strategy.exit("TP & SL", "long", limit=TP, stop=TS? tstop : SL, when=i_SL)
strategy.exit("TP & SL", "short", limit=STP, stop=TS? Ststop : SSL, when=i_SL)

/////////////////////// PLOTS //////////////////////////////////////////////////

plot(i_SL and strategy.position_size > 0 and not TS ? SL : i_SL and strategy.position_size > 0 and TS ? tstop : na , title='SL', style=plot.style_cross, color=color.red)
plot(i_SL and strategy.position_size < 0 and not TS ? SSL : i_SL and strategy.position_size < 0 and TS ? Ststop : na , title='SSL', style=plot.style_cross, color=color.red)
plot(i_SL and strategy.position_size > 0 ? TP : na, title='TP', style=plot.style_cross, color=color.green)
plot(i_SL and strategy.position_size < 0 ? STP : na, title='STP', style=plot.style_cross, color=color.green)
// Draw price action setup arrows
plotshape(BUY ? 1 : na, style=shape.triangleup, location=location.belowbar, 
 color=color.green, title="Bullish Setup", size=size.auto)
plotshape(SELL ? 1 : na, style=shape.triangledown, location=location.abovebar, 
 color=color.red, title="Bearish Setup", size=size.auto)
 




Thêm nữa