Эта торговая стратегия сочетает в себе несколько скользящих средних и индикаторов импульса для определения направления и силы тенденций, установления позиций на ранней стадии в развивающихся тенденциях, а затем оптимизации управления прибылью и рисками с использованием остановок и получения прибыли.
Для создания быстрых и медленных линий создаются два набора скользящих средних с различными параметрами:
Когда быстрая линия пересекает медленную линию, это сигнализирует о том, что краткосрочный тренд набирает силу по сравнению со среднесрочным трендом, и представляет собой сигнал входа.
Встроен фильтр RSI, принимающий записи только при минимумах RSI (для длинных) и максимумах RSI (для коротких), чтобы избежать ложных прорывов.
После ввода, последующая остановка используется для минимизации потерь, в то время как получение прибыли блокирует прибыль.
Когда быстрая линия пересекает медленную линию, это сигнализирует об изменении тренда, что приводит к выходу через стоп-лосс или прибыль.
Эта стратегия объединяет скользящие средние и индикаторы импульса для выявления и установления ранних входов во время появляющихся тенденций, управляя при этом риском и вознаграждением через своевременные остановки и получение прибыли.
/*backtest start: 2023-10-06 00:00:00 end: 2023-11-05 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=3 strategy(title="[WAI GUA]", shorttitle="[EOS] 1.0", overlay=true) //study(title="[WAI GUA]", shorttitle="[EOS] 1.0", overlay=true) // // Use Alternate Anchor TF for MAs uRenko = input(true, title="IS This a RENKO Chart") // anchor = input(0,minval=0,maxval=1440,title="Alternate TimeFrame Multiplier (0=none)") // src = close //input(close, title="EMA Source") showRibbons = input(false,title="Show Coloured MA Ribbons") showAvgs = input(false,title="Show Ribbon Median MA Lines") // // Fast Ribbon MAs // Lower MA - type, length typeF1 = input(defval="EMA", title="FAST MA Ribbon Type: ", options=["SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "LAGMA", "HullMA", "ZEMA", "TMA", "SSMA"]) lenF1 = input(defval=5, title="FAST Ribbon Lower MA Length", minval=1) gammaF1 = 0.33 //input(defval=0.33,title="Fast MA - Gamma for LAGMA") // Upper MA - type, length typeF11 = typeF1 //input(defval="WMA", title="FAST Ribbon Upper MA Type: ", options=["SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "LAGMA", "HullMA", "ZEMA", "TMA", "SSMA"]) lenF11 = input(defval=25, title="FAST Ribbon Upper Length", minval=2) gammaF11 = 0.77 //input(defval=0.77,title="Slow MA - Gamma for LAGMA") // Slow Ribbon MAs // Lower MA - type, length typeS1 = input(defval="EMA", title="SLOW MA Ribbon Type: ", options=["SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "LAGMA", "HullMA", "ZEMA", "TMA", "SSMA"]) lenS1 = input(defval=28, title="SLOW Ribbon Lower MA Length", minval=1) gammaS1 = 0.33 //input(defval=0.33,title="Fast MA - Gamma for LAGMA") // Upper MA - type, length typeS16 = typeS1 //input(defval="WMA", title="SLOW Ribbon Upper MA Type: ", options=["SMA", "EMA", "WMA", "VWMA", "SMMA", "DEMA", "TEMA", "LAGMA", "HullMA", "ZEMA", "TMA", "SSMA"]) lenS16 = input(defval=72, title="SLOW Ribbon Upper Length", minval=2) gammaS16 = 0.77 //input(defval=0.77,title="Slow MA - Gamma for LAGMA") // - Constants gold = #FFD700 // - FUNCTIONS // - variant(type, src, len, gamma) // 返回MA输入选择变量,默认为SMA,如果空白或键入。 // SuperSmoother filter variant_supersmoother(src,len) => 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 v9 = 0.0 v9 := c1*(src + nz(src[1])) / 2 + c2*nz(v9[1]) + c3*nz(v9[2]) v9 variant_smoothed(src,len) => v5 = 0.0 v5 := na(v5[1]) ? sma(src, len) : (v5[1] * (len - 1) + src) / len v5 variant_zerolagema(src,len) => ema1 = ema(src, len) ema2 = ema(ema1, len) v10 = ema1+(ema1-ema2) v10 variant_doubleema(src,len) => v2 = ema(src, len) v6 = 2 * v2 - ema(v2, len) v6 variant_tripleema(src,len) => v2 = ema(src, len) v7 = 3 * (v2 - ema(v2, len)) + ema(ema(v2, len), len) // Triple Exponential v7 //calc Laguerre variant_lag(p,g) => L0 = 0.0 L1 = 0.0 L2 = 0.0 L3 = 0.0 L0 := (1 - g)*p+g*nz(L0[1]) L1 := -g*L0+nz(L0[1])+g*nz(L1[1]) L2 := -g*L1+nz(L1[1])+g*nz(L2[1]) L3 := -g*L2+nz(L2[1])+g*nz(L3[1]) f = (L0 + 2*L1 + 2*L2 + L3)/6 f // return variant, defaults to SMA variant(type, src, len, g) => type=="EMA" ? ema(src,len) : type=="WMA" ? wma(src,len): type=="VWMA" ? vwma(src,len) : type=="SMMA" ? variant_smoothed(src,len) : type=="DEMA" ? variant_doubleema(src,len): type=="TEMA" ? variant_tripleema(src,len): type=="LAGMA" ? variant_lag(src,g) : type=="HullMA"? wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len))) : type=="SSMA" ? variant_supersmoother(src,len) : type=="ZEMA" ? variant_zerolagema(src,len) : type=="TMA" ? sma(sma(src,len),len) : sma(src,len) // - /variant // If have anchor specified, calculate the base multiplier. //mult = isintraday ? anchor==0 or interval<=0 or interval>=anchor or anchor>1440? 1 : round(anchor/interval) : 1 //mult := isdwm? 1 : mult // Only available Daily or less mult = anchor>0 ? anchor : 1 // high_ = uRenko? max(close,open) : high low_ = uRenko? min(close,open) : low //用锚乘器调整MA长度 //Fast MA Ribbon emaF1 = variant(typeF1, src, lenF1*mult, gammaF1) emaF11 = variant(typeF11, src, lenF11*mult,gammaF11) emafast = (emaF1+emaF11)/2 // Average of Upper and Lower MAs // //Slow MA Ribbon emaS1 = variant(typeS1,src, lenS1*mult,gammaS1) emaS16 = variant(typeS16, src, lenS16*mult, gammaS16) emaslow = (emaS1+emaS16)/2 // Average of Upper and Lower MAs // // Count crossover candles xup = 0 xdn = 0 fup = 0 fdn = 0 sup = 0 sdn = 0 // xup := (emafast-emaslow)>0 and (emafast-emaslow)>(emafast[1]-emaslow[1]) ? nz(xup[1])+1 : 0 xdn := (emafast-emaslow)<0 and (emafast-emaslow)<(emafast[1]-emaslow[1]) ? nz(xdn[1])+1 : 0 fup := (emaF1-emaF11)>0 and (emaF1-emaF11)>(emaF1[1]-emaF11[1]) ? nz(fup[1])+1 : 0 fdn := (emaF1-emaF11)<0 and (emaF1-emaF11)<(emaF1[1]-emaF11[1]) ? nz(fdn[1])+1 : 0 sup := (emaS1-emaS16)>0 and (emaS1-emaS16)>(emaS1[1]-emaS16[1]) ? nz(sup[1])+1 : 0 sdn := (emaS1-emaS16)<0 and (emaS1-emaS16)<(emaS1[1]-emaS16[1]) ? nz(sdn[1])+1 : 0 //Fast EMA Final Color Rules colFinal = fup>=2 ? aqua : fdn>=2 ? blue : gray //Slow EMA Final Color Rules colFinal2 = sup>=2 ? lime : sdn>=2 ? red : gray //Fast EMA Plots p1=plot(showRibbons?emaF1:na, title="Fast Ribbon Lower MA", style=line, linewidth=1, color=colFinal,transp=10) p2=plot(showRibbons?emaF11:na, title="Fast Ribbon Upper MA", style=line, linewidth=1, color=colFinal,transp=10) plot(showAvgs?emafast:na, title="Fast Ribbon Avg MA", style=circles,join=true, linewidth=1, color=gold,transp=10) // //fill(p1,p2,color=colFinal, transp=90) //Slow EMA Plots p3=plot(showRibbons?emaS1:na, title="Slow Ribbon Lower MA", style=line, linewidth=1, color=colFinal2,transp=10) p4=plot(showRibbons?emaS16:na, title="Slow Ribbon Upper MA", style=line, linewidth=1, color=colFinal2,transp=10) plot(showAvgs?emaslow:na, title="Slow Ribbon Avg MA", style=circles,join=true, linewidth=1, color=fuchsia,transp=10) // //fill(p3,p4, color=colFinal2, transp=90) // Generate Buy Sell signals, buy = 0 sell=0 // buy := xup>=2 and sup>=2 and fup>=2 ? nz(buy[1])>0?buy[1]+1 :1 : 0 sell := xdn>=2 and sdn>=2 and fdn>=2 ? nz(sell[1])>0?sell[1]+1 :1 : 0 //////////////////////// //* 反测试周期选择器 *// //////////////////////// testStartYear = input(2018, "Backtest Start Year",minval=1980) testStartMonth = input(1, "Backtest Start Month",minval=1,maxval=12) testStartDay = input(1, "Backtest Start Day",minval=1,maxval=31) testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0) testStopYear = 9999 //input(9999, "Backtest Stop Year",minval=1980) testStopMonth = 12 // input(12, "Backtest Stop Month",minval=1,maxval=12) testStopDay = 31 //input(31, "Backtest Stop Day",minval=1,maxval=31) testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,0,0) testPeriod() => time >= testPeriodStart and time <= testPeriodStop ? true : false /////////////// //* RSI策略 *// /////////////// //指示器 1 lowerpc = lowest(low, 21) upperpc = highest(high, 21) midpc = avg(upperpc, lowerpc) //指示器 2 ma = sma(close, 50) petd = ema(close,13) rangema = ema(tr, 50) upperkc = ma + rangema * 0.25 lowerkc = ma - rangema * 0.25 //指示器 3 up = rma(max(change(close), 0), 5) down = rma(-min(change(close), 0), 5) rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down)) // PET-D petdcolor = close > petd ? green : red barcolor (petdcolor) //Slope SlopeL = midpc > midpc[5] SlopeS = midpc < midpc[5] //条件 CL = SlopeL == 1 and close > lowerkc and close < midpc and rsi < 35 CS = SlopeS == 1 and close < upperkc and close > midpc and rsi > 65 //Setup RsiSL = CL == 1 and CL[1] != 1 RsiSS = CS == 1 and CS[1] != 1 ///////////////////// //* RSA抛物线指标 *// ///////////////////// start = input(0.02) increment = input(0.02) maximum = input(0.2) psar = sar(start, increment, maximum) RSALE = false RSASE = false if (psar > high) RSALE = true else RSALE = false if (psar < low) RSASE = true else RSASE = false //////////////// //* 策略组件 *// //////////////// AQUA = #00FFFFFF BLUE = #0000FFFF RED = #FF0000FF LIME = #00FF00FF GRAY = #808080FF DARKRED = #8B0000FF DARKGREEN = #006400FF // fastExit = input(false,title="Use Opposite Trade as a Close Signal") clrBars = input(true,title="Colour Candles to Trade Order state") orderType = input("Longs+Shorts",title="What type of Orders", options=["Longs+Shorts","LongsOnly","ShortsOnly","Flip"]) // isLong = (orderType != "ShortsOnly") isShort = (orderType != "LongsOnly") ////////////////////////// //* 贸易状态引擎 *// ////////////////////////// // 追踪当前贸易状态 longClose = false, longClose := nz(longClose[1],false) shortClose = false, shortClose := nz(shortClose[1],false) tradeState = 0, tradeState := nz(tradeState[1]) tradeState := tradeState==0 ? buy==1 and (barstate.isconfirmed or barstate.ishistory) and isLong and not longClose and not shortClose? 1 : sell==1 and (barstate.isconfirmed or barstate.ishistory) and isShort and not longClose and not shortClose? -1 : tradeState : tradeState //////////////////////////////////// //* 在这里设置入口和特殊出口条件 *// //////////////////////////////////// //进入状态,当状态改变方向时。 longCondition = false shortCondition = false //longCondition := longCondition != true ? change(tradeState) and tradeState==1 : true //shortCondition := shortCondition != true ? change(tradeState) and tradeState==-1 : true longCondition := change(tradeState) and tradeState==1 shortCondition := change(tradeState) and tradeState==-1 if orderType=="Flip" temp = longCondition longCondition := shortCondition shortCondition := temp //end if // 卖出信号退出 longExitC = (emafast[1]<emaslow[1] and open<emaslow[1]) ? 1 : 0 shortExitC = (emafast[1]>emaslow[1] and open>emaslow[1]) ? 1 : 0 // change退出条件。 longExit = change(longExitC) and longExitC==1 and tradeState==1 shortExit = change(shortExitC) and shortExitC==1 and tradeState==-1 // -- debugs //plotchar(tradeState,"tradeState at Event",location=location.bottom, color=#FF0000FF) //plotchar(longCondition, title="longCondition",color=#FF0000FF) //plotchar(shortCondition, title="shortCondition",color=#FF0000FF) //plotchar(tradeState, title="tradeState",color=#006400FF) // -- /debugs //////////////////////////////// //======[ 交易入门价格 ]======// //////////////////////////////// last_open_longCondition = na last_open_shortCondition = na last_open_longCondition := longCondition ? close : nz(last_open_longCondition[1]) last_open_shortCondition := shortCondition ? close : nz(last_open_shortCondition[1]) //////////////////////////// //======[ 位置状态 ]======// //////////////////////////// in_longCondition = tradeState == 1 in_shortCondition = tradeState == -1 //////////////////////// //======[ 尾停 ]======// //////////////////////// isTS = input(true, "Trailing Stop") ts = input(3.0, "Trailing Stop (%)", minval=0,step=0.1, type=float) /100 last_high = na last_low = na last_high_short = na last_low_long = na last_high := not in_longCondition ? na : in_longCondition and (na(last_high[1]) or high_ > nz(last_high[1])) ? high_ : nz(last_high[1]) last_high_short := not in_shortCondition ? na : in_shortCondition and (na(last_high[1]) or high_ > nz(last_high[1])) ? high_ : nz(last_high[1]) last_low := not in_shortCondition ? na : in_shortCondition and (na(last_low[1]) or low_ < nz(last_low[1])) ? low_ : nz(last_low[1]) last_low_long := not in_longCondition ? na : in_longCondition and (na(last_low[1]) or low_ < nz(last_low[1])) ? low_ : nz(last_low[1]) long_ts = isTS and in_longCondition and not na(last_high) and (low_ <= last_high - last_high * ts) //and (last_high >= last_open_longCondition + last_open_longCondition * tsi) short_ts = isTS and in_shortCondition and not na(last_low) and (high_ >= last_low + last_low * ts) //and (last_low <= last_open_shortCondition - last_open_shortCondition * tsi) //////////////////////// //======[ 获利 ]======// //////////////////////// isTP = input(true, "Take Profit") tp = input(3.0, "Take Profit (%)",minval=0,step=0.1,type=float) / 100 ttp = input(1.0, "Trailing Profit (%)",minval=0,step=0.1,type=float) / 100 ttp := ttp>tp ? tp : ttp long_tp = isTP and in_longCondition and (last_high >= last_open_longCondition + last_open_longCondition * tp) and (low_ <= last_high - last_high * ttp) short_tp = isTP and in_shortCondition and (last_low <= last_open_shortCondition - last_open_shortCondition * tp) and (high_ >= last_low + last_low * ttp) //////////////////////////// //======[ 停止损耗 ]======// //////////////////////////// isSL = input(false, "Stop Loss") sl = input(3.0, "Stop Loss (%)", minval=0,step=0.1, type=float) / 100 long_sl = isSL and in_longCondition and (low_ <= last_open_longCondition - last_open_longCondition * sl) short_sl = isSL and in_shortCondition and (high_ >= last_open_shortCondition + last_open_shortCondition * sl) //////////////////////// //======[ 对峙 ]======// //////////////////////// //注:短出口信号不重漆,无需用力,如果锥体继续进行。 long_sos = (fastExit or (not isTS and not isSL)) and longExit and in_longCondition short_sos = (fastExit or (not isTS and not isSL)) and shortExit and in_shortCondition //////////////////////////// //======[ 关闭信号 ]======// //////////////////////////// // 为所有不同的关闭条件创建一个单独的关闭,这里的所有条件都不重漆。 longClose := isLong and (long_tp or long_sl or long_ts or long_sos) and not longCondition shortClose := isShort and (short_tp or short_sl or short_ts or short_sos) and not shortCondition //////////////////////////// //======[ 情节色彩 ]======// //////////////////////////// longCloseCol = na shortCloseCol = na longCloseCol := long_tp ? green : long_sl ? maroon : long_ts ? purple : long_sos ? orange :longCloseCol[1] shortCloseCol := short_tp ? green : short_sl ? maroon : short_ts ? purple : short_sos ? orange : shortCloseCol[1] // tpColor = isTP and in_longCondition ? lime : isTP and in_shortCondition ? lime : na slColor = isSL and in_longCondition ? red : isSL and in_shortCondition ? red : na ////////////////////////////////// //======[ 策略图 ]======// ////////////////////////////////// plot(isTS and in_longCondition? last_high - last_high * ts : na, "Long Trailing", fuchsia, style=2, linewidth=2,offset=1) plot(isTP and in_longCondition and last_high < last_open_longCondition + last_open_longCondition * tp ? last_open_longCondition + last_open_longCondition * tp : na, "Long TP Active", tpColor, style=3,join=false, linewidth=2,offset=1) plot(isTP and in_longCondition and last_high >= last_open_longCondition + last_open_longCondition * tp ? last_high - last_high * ttp : na, "Long Trailing", black, style=2, linewidth=2,offset=1) plot(isSL and in_longCondition and last_low_long > last_open_longCondition - last_open_longCondition * sl ? last_open_longCondition - last_open_longCondition * sl : na, "Long SL", slColor, style=3,join=false, linewidth=2,offset=1) plot(isTS and in_shortCondition? last_low + last_low * ts : na, "Short Trailing", fuchsia, style=2, linewidth=2,offset=1) plot(isTP and in_shortCondition and last_low > last_open_shortCondition - last_open_shortCondition * tp ? last_open_shortCondition - last_open_shortCondition * tp : na, "Short TP Active", tpColor, style=3,join=false, linewidth=2,offset=1) plot(isTP and in_shortCondition and last_low <= last_open_shortCondition - last_open_shortCondition * tp ? last_low + last_low * ttp : na, "Short Trailing", black, style=2, linewidth=2,offset=1) plot(isSL and in_shortCondition and last_high_short < last_open_shortCondition + last_open_shortCondition * sl ? last_open_shortCondition + last_open_shortCondition * sl : na, "Short SL", slColor, style=3,join=false, linewidth=2,offset=1) bclr = not clrBars ? na : tradeState==0 ? GRAY : in_longCondition ? close<last_open_longCondition? DARKGREEN : LIME : in_shortCondition ? close>last_open_shortCondition? DARKRED : RED : GRAY barcolor(bclr,title="Trade State Bar Colouring") ////////////////////////////////// //======[ 战略进入与退出 ]======// ////////////////////////////////// if testPeriod() and isLong strategy.entry("Long", 1, when=longCondition) strategy.close("Long", when=longClose ) if testPeriod() and isShort strategy.entry("Short", 0, when=shortCondition) strategy.close("Short", when=shortClose ) // --- Debugs //plotchar(longExit,title="longExit",location=location.bottom,color=na) //plotchar(longCondition,title="longCondition",location=location.bottom,color=na) //plotchar(in_longCondition,title="in_longCondition",location=location.bottom,color=na) //plotchar(longClose,title="longClose",location=location.bottom,color=na,color=na) //plotchar(buy,title="buy",location=location.bottom,color=na) // --- /Debugs //开单时改变背景 bgcolor( in_longCondition ? lime : na, transp=90) bgcolor( in_shortCondition ? red : na, transp=90) //////////////////////////// //======[ 重置变量 ]======// //////////////////////////// if longClose or not in_longCondition last_high := na last_high_short := na if shortClose or not in_shortCondition last_low := na last_low_long := na if longClose or shortClose tradeState := 0 in_longCondition := false in_shortCondition := false //plotchar(tradeState,"tradeState at EOF",location=location.bottom, color=na) // EOF