Chiến lược giao dịch trung bình chuyển động quang phổ dao động

Tác giả:ChaoZhang
Tags:

img

Tổng quan

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

Chiến lược này sử dụng một hàm trung bình động biến thể có thể tạo ra 12 loại trung bình động khác nhau. Nguyên tắc cơ bản là tính toán hai đường trung bình động, đường nhanh (Close MA) và đường chậm (Open MA). Khi đường nhanh vượt qua đường chậm, một tín hiệu mua được tạo ra. Khi đường nhanh vượt qua đường chậm, một tín hiệu bán được tạo ra. Các thông số dừng lỗ và lấy lợi nhuận cũng được thiết lập để đạt được dừng lỗ tự động và lấy lợi nhuận.

Lý thuyết chính là tạo ra hai đường trung bình động thông qua hàm biến thể:closeSeries = variant(basisType, close, basisLen, offsetSigma, offsetALMA)openSeries = variant(basisType, open, basisLen, offsetSigma, offsetALMA)Chức năng biến thể bao gồm các phương pháp tính toán cho 12 loại trung bình động khác nhau. Người dùng có thể tự do chọn loại thông qua tham số baseType. Điều này thực hiện sự kết hợp giữa các trung bình động phổ.

Logic cơ bản để tạo ra tín hiệu giao dịch là:longCond = xlongshortCond = xshort

Phân tích lợi thế

Một lợi thế khác là logic chiến lược đơn giản và rõ ràng, nhưng cung cấp chức năng mạnh mẽ. Nó dễ dàng cho người dùng hiểu và sử dụng chiến lược này. Đồng thời, các thông số đầu vào phong phú cũng cung cấp đủ không gian tối ưu hóa cho người dùng tiên tiến.

Phân tích rủi ro

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

Các hướng tối ưu hóa chính cho chiến lược này bao gồm:

  1. Kiểm tra nhiều loại kết hợp trung bình động hơn để tìm kết hợp tốt nhất
  2. Thêm các bộ lọc để tránh các tín hiệu sai, chẳng hạn như kết hợp các chỉ số khối lượng giao dịch, v.v.
  3. Tối ưu hóa kích thước vị trí, dừng lỗ và lấy lợi nhuận tham số

Tóm lại


/*backtest
start: 2023-01-18 00:00:00
end: 2024-01-24 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
//

strategy(title="Long/Short", shorttitle="Banana Maker", overlay=true, pyramiding=0, default_qty_type=strategy.percent_of_equity, default_qty_value=100, calc_on_every_tick=false)



// === INPUTS ===
useRes = input(defval=true, title="Use Alternate Resolution?")
intRes = input(defval=7, title="Multiplier for Alernate Resolution")
stratRes = timeframe.ismonthly ? tostring(timeframe.multiplier * intRes, "###M") : 
   timeframe.isweekly ? tostring(timeframe.multiplier * intRes, "###W") : 
   timeframe.isdaily ? tostring(timeframe.multiplier * intRes, "###D") : 
   timeframe.isintraday ? tostring(timeframe.multiplier * intRes, "####") : '60'
basisType = input(defval="DEMA", title="MA Type: ", options=["SMA", "EMA", "DEMA", "TEMA", "WMA", "VWMA", "SMMA", "HullMA", "LSMA", "ALMA", "SSMA", "TMA"])
basisLen = input(defval=8, title="MA Period", minval=1)
offsetSigma = input(defval=6, title="Offset for LSMA / Sigma for ALMA", minval=0)
offsetALMA = input(defval=0.85, title="Offset for ALMA", minval=0, step=0.01)
scolor = input(false, title="Show coloured Bars to indicate Trend?")
delayOffset = input(defval=0, title="Delay Open/Close MA (Forces Non-Repainting)", minval=0, step=1)
tradeType = input("BOTH", title="What trades should be taken : ", options=["LONG", "SHORT", "BOTH", "NONE"])
// === /INPUTS ===

// Constants colours that include fully non-transparent option.
green100 = #008000FF
lime100 = #6ad279
red100 = #FF0000FF
blue100 = #0000FFFF
aqua100 = #00FFFFFF
darkred100 = #8B0000FF
gray100 = #808080FF

// === BASE FUNCTIONS ===
variant(type, src, len, offSig, offALMA) =>
    v1 = sma(src, len)  // Simple
    v2 = ema(src, len)  // Exponential
    v3 = 2 * v2 - ema(v2, len)  // Double Exponential
    v4 = 3 * (v2 - ema(v2, len)) + ema(ema(v2, len), len)  // Triple Exponential
    v5 = wma(src, len)  // Weighted
    v6 = vwma(src, len)  // Volume Weighted
    v7 = 0.0
    sma_1 = sma(src, len)  // Smoothed
    v7 := na(v7[1]) ? sma_1 : (v7[1] * (len - 1) + src) / len
    v8 = wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len)))  // Hull
    v9 = linreg(src, len, offSig)  // Least Squares
    v10 = alma(src, len, offALMA, offSig)  // Arnaud Legoux
    v11 = sma(v1, len)  // Triangular (extreme smooth)
    // SuperSmoother filter
    // © 2013  John F. Ehlers
    a1 = exp(-1.414 * 3.14159 / len)
    b1 = 2 * a1 * cos(1.414 * 3.14159 / len)
    c2 = b1
    c3 = -a1 * a1
    c1 = 1 - c2 - c3
    v12 = 0.0
    v12 := c1 * (src + nz(src[1])) / 2 + c2 * nz(v12[1]) + c3 * nz(v12[2])
    type == "EMA" ? v2 : type == "DEMA" ? v3 : 
       type == "TEMA" ? v4 : type == "WMA" ? v5 : type == "VWMA" ? v6 : 
       type == "SMMA" ? v7 : type == "HullMA" ? v8 : type == "LSMA" ? v9 : 
       type == "ALMA" ? v10 : type == "TMA" ? v11 : type == "SSMA" ? v12 : v1

// security wrapper for repeat calls* NEEDS REFINEMENT- backtesting this shows repaint. need new wrapper
reso(exp, use, res) =>
    security_1 = security(syminfo.tickerid, res, exp, gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_on)
    use ? security_1 : exp



// === /BASE FUNCTIONS ===

// === SERIES SETUP ===
closeSeries = variant(basisType, close[delayOffset], basisLen, offsetSigma, offsetALMA)
openSeries = variant(basisType, open[delayOffset], basisLen, offsetSigma, offsetALMA)
// === /SERIES ===

// === PLOTTING ===

// alt resulution 
closeSeriesAlt = reso(closeSeries, useRes, stratRes)
openSeriesAlt = reso(openSeries, useRes, stratRes)
//
trendColour = closeSeriesAlt > openSeriesAlt ? color.green : color.red
bcolour = closeSeries > openSeriesAlt ? lime100 : red100
barcolor(scolor ? bcolour : na, title="Bar Colours")
closeP = plot(closeSeriesAlt, title="Close Series", color=trendColour, linewidth=0, style=plot.style_line, transp=1)
openP = plot(openSeriesAlt, title="Open Series", color=trendColour, linewidth=0, style=plot.style_line, transp=1)
fill(closeP, openP, color=trendColour, transp=80)

// === /PLOTTING ===
//

//
// === ALERT conditions

xlong = crossover(closeSeriesAlt, openSeriesAlt)
xshort = crossunder(closeSeriesAlt, openSeriesAlt)
longCond = xlong  // alternative: longCond[1]? false : (xlong or xlong[1]) and close>closeSeriesAlt and close>=open
shortCond = xshort  // alternative: shortCond[1]? false : (xshort or xshort[1]) and close<closeSeriesAlt and close<=open


// === /ALERT conditions. needs work in study mode. the banana maker is the study script. 
// Create alert for cross, shunt back 1 if source is not 'open', this should prevent repaint issue.
//shunt = RSIsrc == open ? 0 : 1
//shunt = 0
//c_alert = (buy[shunt]==1 or sell[shunt]==1)
//alertcondition(c_alert, title="QQECROSS Alert", message="QQECROSS Alert")
// show only when alert condition is met and bar closed.
//plotshape(c_alert,title= "Alert Indicator Closed", location=location.bottom, color=sell[shunt]==1?red:green, transp=0, style=shape.circle)

//Repaint city, study mode will help but wont trigger the alerts


// === STRATEGY ===
// stop loss
slPoints = input(defval=0, title="Initial Stop Loss Points (zero to disable)", minval=0)
tpPoints = input(defval=0, title="Initial Target Profit Points (zero for disable)", minval=0)
// Include bar limiting algorithm
ebar = input(defval=1000, title="Number of Bars for Back Testing", minval=0)
dummy = input(false, title="- SET to ZERO for Daily or Longer Timeframes")
//
// Calculate how many mars since last bar
tdays = (timenow - time) / 60000.0  // number of minutes since last bar
tdays := timeframe.ismonthly ? tdays / 1440.0 / 5.0 / 4.3 / timeframe.multiplier : 
   timeframe.isweekly ? tdays / 1440.0 / 5.0 / timeframe.multiplier : 
   timeframe.isdaily ? tdays / 1440.0 / timeframe.multiplier : 
   tdays / timeframe.multiplier  // number of bars since last bar
//
//set up exit parameters
TP = tpPoints > 0 ? tpPoints : na
SL = slPoints > 0 ? slPoints : na

// Make sure we are within the bar range, Set up entries and exit conditions
if (ebar == 0 or tdays <= ebar) and tradeType != "NONE"
    strategy.entry("long", strategy.long, when=longCond == true and tradeType != "SHORT")
    strategy.entry("short", strategy.short, when=shortCond == true and tradeType != "LONG")
    strategy.close("long", when=shortCond == true and tradeType == "LONG")
    strategy.close("short", when=longCond == true and tradeType == "SHORT")
    strategy.exit("XL", from_entry="long", profit=TP, loss=SL)
    strategy.exit("XS", from_entry="short", profit=TP, loss=SL)



// === /STRATEGY ===
// eof


Thêm nữa