Улучшенная стратегия рыболовных сетей
Эта стратегия улучшает классическую стратегию рыбной сети, добавляя пороги сигналов покупки/продажи и отслеживание стоп-лосса для формирования более полной системы следования тренду.
Стратегия рыбной сети оценивает рыночные тенденции, рассчитывая цену центройной силы, которая отражает взаимосвязь между ценой и объемом.
Ключ к вычислению центройной силы заключается в взаимосвязи между ценой и временем. Проще говоря, недавние изменения цен имеют больший вес в влиянии на общее суждение о тренде, в то время как более старые цены имеют меньший вес. Таким образом, при вычислении умножается вес времени. Это делает транзакции, происходящие на более высоких уровнях, более влияют на общее суждение.
Но оригинальная рыбная сеть судила только о длинном/коротком на основе направления кривой центроида, легко попадая в ловушку боковых движений.
Кроме того, улучшенная версия реализует комбинированный механизм отслеживания стоп-лосса и фиксированного стоп-лосса для выходов. После входа в тренд, отслеживание стоп-лосса может продолжать корректироваться вместе с ценовым действием, достигая динамического контроля риска. Фиксированный стоп-лосс может более надежно предотвращать потери от внезапных событий.
Конечно, индикатор центройной силы имеет ограниченные возможности на сложных рынках, и последующие остановки также могут быть проникнуты, если они установлены неправильно, поэтому трейдеры должны оставаться бдительными и своевременно оптимизировать параметры.
/*backtest start: 2023-09-04 00:00:00 end: 2023-09-11 00:00:00 period: 30m basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=3 // Copyright nilux: https://www.tradingview.com/u/nilux/ // Based on the original of dasanc: https://www.tradingview.com/u/dasanc/ strategy("FSCG-TSSL", "FSCG-TSSL Mod Backtest", default_qty_type = strategy.percent_of_equity, default_qty_value = 100, initial_capital = 100000, slippage = 5) Price = input.source(close, "Source") Length = input(20,"Period") transform = input("Inphase-Quadrature","Use Transform?",options=["Hilbert","Inphase-Quadrature","False"]) min = input(108,"Min. Period") buyTreshold = input(-2.41, title = "Buy Treshold (-)", type = float, defval=-2.0, minval = -2.50, maxval = -0.01, step = 0.01) sellTreshold = input(2.43, title = "Sell Treshold (+)", type = float, defval=2.0, minval = 0.01, maxval = 2.50, step = 0.01) // === TSSL === fixedSL = input(title="SL Activation", defval=300) trailSL = input(title="SL Trigger", defval=1) fixedTP = input(title="TP Activation", defval=150) trailTP = input(title="TP Trigger", defval=50) // === BACKTEST RANGE === FromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12) FromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31) FromYear = input(defval = 2019, title = "From Year", minval = 2015) ToMonth = input(defval = 1, title = "To Month", minval = 1, maxval = 12) ToDay = input(defval = 1, title = "To Day", minval = 1, maxval = 31) ToYear = input(defval = 9999, title = "To Year", minval = 2015) start = timestamp(FromYear, FromMonth, FromDay, 00, 00) finish = timestamp(ToYear, ToMonth, ToDay, 23, 59) window() => time >= start and time <= finish ? true : false getIQ(src,min,max) => PI = 3.14159265359 P = src - src[7] lenIQ = 0.0 lenC = 0.0 imult = 0.635 qmult = 0.338 inphase = 0.0 quadrature = 0.0 re = 0.0 im = 0.0 deltaIQ = 0.0 instIQ = 0.0 V = 0.0 inphase := 1.25*(P[4] - imult*P[2]) + imult*nz(inphase[3]) quadrature := P[2] - qmult*P + qmult*nz(quadrature[2]) re := 0.2*(inphase*inphase[1] + quadrature*quadrature[1]) + 0.8*nz(re[1]) im := 0.2*(inphase*quadrature[1] - inphase[1]*quadrature) + 0.8*nz(im[1]) if (re!= 0.0) deltaIQ := atan(im/re) for i=0 to max V := V + deltaIQ[i] if (V > 2*PI and instIQ == 0.0) instIQ := i if (instIQ == 0.0) instIQ := nz(instIQ[1]) lenIQ := 0.25*instIQ + 0.75*nz(lenIQ[1],1) length = lenIQ<min ? min : lenIQ getHT(src) => Price = src Imult = .635 Qmult = .338 PI = 3.14159 InPhase = 0.0 Quadrature = 0.0 Phase = 0.0 DeltaPhase = 0.0 InstPeriod = 0.0 Period = 0.0 Value4 = 0.0 if(n > 5) //Detrend Price Value3 = Price - Price[7] //Compute InPhase and Quadrature components InPhase := 1.25*(Value3[4] - Imult*Value3[2]) + Imult*nz(InPhase[3]) Quadrature := Value3[2] - Qmult*Value3 + Qmult*nz(Quadrature[2]) //Use ArcTangent to compute the current phase if(abs(InPhase + InPhase[1]) > 0) Phase := 180/PI * atan(abs((Quadrature + Quadrature[1]) / (InPhase + InPhase[1]))) //Resolve the ArcTangent ambiguity if(InPhase < 0 and Quadrature > 0) Phase := 180 - Phase if(InPhase < 0 and Quadrature < 0) Phase := 180 + Phase if(InPhase > 0 and Quadrature < 0) Phase := 360 - Phase //Compute a differential phase, resolve phase wraparound, and limit delta phase errors DeltaPhase := Phase[1] - Phase if(Phase[1] < 90 and Phase > 270) DeltaPhase := 360 + Phase[1] - Phase if(DeltaPhase < 1) DeltaPhase := 1 if(DeltaPhase > 60) DeltaPhase := 60 //Sum DeltaPhases to reach 360 degrees. The sum is the instantaneous period. for i = 0 to 50 Value4 := Value4 + DeltaPhase[i] if(Value4 > 360 and InstPeriod == 0) InstPeriod := i //Resolve Instantaneous Period errors and smooth if(InstPeriod == 0) InstPeriod = nz(InstPeriod[1]) Period := .25*(InstPeriod) + .75*Period[1] Period //Get highest val in period getHighest(src, len)=> H = src[len] for i=0 to len if src[i]>H H := src[i] H //Get lowest val in period getLowest(src, len)=> L = src[len] for i=0 to len if src[i]<L L := src[i] L if transform == "Hilbert" Length := round(getHT(Price)/2) if transform == "Inphase-Quadrature" Length := round(getIQ(Price,min,50)/2) if Length<min Length := min Num = 0.0 Denom = 0.0 CG = 0.0 MaxCG = 0.0 MinCG = 0.0 Value1 = 0.0 Value2 = 0.0 Value3 = 0.0 for i = 0 to Length - 1 Num := Num + (1 + i)*(Price[i]) Denom := Denom + (Price[i]) if(Denom != 0) CG := -Num/Denom + (Length + 1) / 2 MaxCG := getHighest(CG, Length) MinCG := getLowest(CG, Length) if(MaxCG != MinCG) Value1 := (CG - MinCG) / (MaxCG - MinCG) Value2 := (4*Value1 + 3*Value1[1] + 2*Value1[2] + Value1[3]) / 10 Value3 := .5*log((1+1.98*(Value2-.5))/(1-1.98*(Value2-.5))) plot(Value3, "CG",orange, linewidth=2) plot(Value3[1], "Trigger",green, linewidth=2) hline(0,color=color(black,60)) hline(2,linestyle=hline.style_solid,color=color(black,70)) hline(-2,linestyle=hline.style_solid,color=color(black,70)) sell = crossover(Value3[1],Value3) and Value3 > sellTreshold buy = crossunder(Value3[1],Value3) and Value3 < buyTreshold strategy.entry("Long", strategy.long, when= buy and window()) strategy.exit("Exit", loss=fixedSL, trail_offset=trailTP, trail_points=fixedTP) strategy.exit("Exit", when= sell) strategy.entry("Short", strategy.short, when= sell and window()) strategy.exit("Exit", loss=fixedSL, trail_offset=trailTP, trail_points=fixedTP) strategy.exit("Exit", when= buy)