convert request Dual Thrust Trading Algorithm
Forums › ProRealTime English forum › ProOrder support › convert request Dual Thrust Trading Algorithm
- This topic has 15 replies, 3 voices, and was last updated 3 years ago by robertogozzi.
-
-
05/17/2020 at 2:31 PM #131972
Hi Nicolas,
a request to convert this tradingsystem. I hope there’s interest in this!
Thank you.
The first 2 pics are probably from tradestation.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169//@version=4study("Dual Thrust Trading Algorithm (ps4)", overlay=true)// author: capissimo// This is an PS4 update to the Dual Thrust trading algorithm developed by Michael Chalek.// It has been commonly used in futures, forex and equity markets.// The idea of Dual Thrust is similar to a typical breakout system,// however dual thrust uses the historical price to construct update the look back period -// theoretically making it more stable in any given period.// see: https://www.quantconnect.com/tutorials/strategy-library/dual-thrust-trading-algorithm//*** Inputsp = input(20, "Lookback Window", minval=1)mult = input(2.0, "Multiplier", minval=0.001, maxval=50)rule = input("Original", "Trend Identification Rule", options=["Original","SMA3","EMA10","SMA5/SMA10"])algo = input("Algo #1", "Algorithm used:", options=["Algo #1", "Algo #2"])mlen = input(5, "Lookback Window M") // 4nlen = input(14, "Lookback Window N") // 20k = input(0.9, "Coeff", step=0.01) // .7, .9disc = input(0.55, "Trending discount", step=0.01) // .6use_bb = input(false, "Bollinger? (alt. Standard Error) Bands")pbb = input(20, "Lookback Window", minval=1)sdeg = input(3, "Smoothing Factor", minval=1)multbb = input(2.0, "Bands Multiplier", minval=0.001, maxval=50)repnt = input(true, "Repaint?")//*** MainO = security(syminfo.tickerid, tostring(timeframe.multiplier), repnt ? open : open[1], barmerge.gaps_off, barmerge.lookahead_on)H = security(syminfo.tickerid, tostring(timeframe.multiplier), repnt ? high : high[1], barmerge.gaps_off, barmerge.lookahead_on)L = security(syminfo.tickerid, tostring(timeframe.multiplier), repnt ? low : low[1], barmerge.gaps_off, barmerge.lookahead_on)C = security(syminfo.tickerid, tostring(timeframe.multiplier), repnt ? close : close[1], barmerge.gaps_off, barmerge.lookahead_on)// ==Bands==//// Standard Error of the Estimate (SEE) Bands are constructed around a linear regression curve and// based on two standard errors above and below this regression line.// The error bands measure the standard error of the estimate around the linear re-gression line.// Therefore, as a price series follows the course of the regression line the bands will narrow,// showing little error in the estimate. As the market gets noisy and random,// the error will be greater resulting in wider bands.beta(array,per) =>val1 = sum(bar_index*array,per)-(per*sma(bar_index,per)*sma(array,per))val2 = sum(pow(bar_index,2),per)-(per*pow(sma(bar_index,per),2))calcB = val1/val2alpha(array,per) =>calcA = sma(array,per)-(beta(array,per)*sma(bar_index,per))see(array,per,mult,dir,type) =>lr = linreg(array,per,0)val1 = (sum(pow(array,2),per))-((alpha(array,per)*sum(array,per)))-((beta(array,per)*sum(bar_index*array,per)))val2 = per - 2narrow = sqrt(val1/val2)est = sum(pow(lr-array,2),per) / (per - 2 )wide = sqrt(est)d = dir ? 1 : -1band = type ? narrow : wideseb = lr + d * mult * band// SEE BandsUWB = plot(use_bb ? na: sma(see(close, pbb, 2.1, true, false), sdeg), color=color.blue, transp=90)UNB = plot(use_bb ? na: sma(see(close, pbb, 2, true, true), sdeg), color=color.blue, transp=90)plot(use_bb ? na: sma(linreg(close, pbb, 0), sdeg), color=color.orange, transp=0)BNB = plot(use_bb ? na: sma(see(close, pbb, 2, false, true), sdeg), color=color.blue, transp=90)BWB = plot(use_bb ? na: sma(see(close, pbb, 2.1, false, false), sdeg), color=color.blue, transp=90)fill(UWB, BWB, title="WideSEE", color=color.blue)fill(UNB, BNB, title="NarrowSEE", color=color.blue)// Bollinger Bandsbasis = sma(close, pbb)dev = multbb * stdev(close, pbb)upper = basis + devlower = basis - devplot(use_bb ? basis : na, color=color.orange, linewidth=2, transp=0)fill(plot(use_bb ? upper : na, transp=65), plot(use_bb ? lower : na, transp=65), color=color.blue, transp=90)// ==Dual Thrust Trading Algorithm==// At the close of the day, calculate two values:// the highest price - the closing price, and// the closing price - the lowest price.// Then take the two larger ones, multiply the k values. The results are called trig-ger values.// On the second day, the opening price is recorded,// and then immediately after the price exceeds (opening + trigger value),// or the price is lower than the (opening - trigger value), the short selling immedi-ately.// This is an inversion system without a single stop? i.e. the reverse signal is also the unwinding signal.// K1 and K2 are the parameters.// When K1 is greater than K2, it is much easier to trigger the long signal and vice versa.// For demonstration, here we choose K1 = K2 = 0.5.// In live trading, we can still use historical data to optimize those parameters or// adjust the parameters according to the market trend.// K1 should be small than k2 if you are bullish on the market and k1 should be much bigger if you are bearish on the market.// Trend Identification - Bullish or Bearishuptrend = false, dntrend = falseif rule=="Original"rng = C - Odoji = rng == 0uptrend := rng > 0 or doji and rng[1] > 0dntrend := rng < 0 or doji and rng[1] < 0elsesm = sma(C, 3) // #1em = ema(C, 10) // #2ma5 = sma(C, 5), ma10 = sma(C, 10) // #3uptrend := rule=="SMA3" ? C > sm : rule=="EMA10" ? C > em : ma5 > ma10dntrend := rule=="SMA3" ? C < sm : rule=="EMA10" ? C < em : ma5 < ma10k1 = k, k2 = kif uptrend // Assigned empirically. Should be optimized separatelyk1 := k1 * disc //.2k2 := k2 * (1 + disc)if dntrendk1 := k1 * (1 + disc)k2 := k2 * disc //.2dtta1_algo(k1, k2, len) =>hh = highest(H, len)[1]hc = highest(C, len)[1]lc = lowest(C, len)[1]ll = lowest(L, len)[1]// The range is calculated based on the close, high and low over the most recent N-periods.// A position is opened when the market moves a certain range from the opening price.range = max(hh - lc, hc - ll)[O + k1 * range, O - k2 * range]dtta2_algo(k1, k2, ml, nl) =>hh = 0.0, ll = 0.0, hc = 0.0, lc = 0.0hh := highest(H, ml)[1]hc := highest(C, ml)[1]lc := lowest(C, ml)[1]ll := lowest(L, ml)[1]sellRange = (hh - lc) >= (hc - ll) ? hh - lc : hc - llhh := highest(H, nl)[1]hc := highest(C, nl)[1]lc := lowest(C, nl)[1]ll := lowest(L, nl)[1]buyRange = (hh - lc) >= (hc - ll) ? hh - lc : hc - ll[O + k1 * buyRange, O - k2 * sellRange][bt1, st1] = dtta1_algo(k1, k2, mlen)[bt2, st2] = dtta2_algo(k1, k2, mlen, nlen)buyTrig = 0.0, sellTrig = 0.0if algo == "Algo #1"buyTrig := bt1, sellTrig := st1elsebuyTrig := bt2, sellTrig := st2longCondition = C >= buyTrigshortCondition = C <= sellTrigstate = 0state := longCondition ? 1 : shortCondition ? -1 : nz(state[1])long = change(state) and state[1]==-1short = change(state) and state[1]==1plotshape(uptrend and long ? low : na, location=location.belowbar, style=shape.labelup, color=color.green, size=size.tiny, text="B", textcolor=color.white, transp=0)plotshape(dntrend and short ? high : na, location=location.abovebar, style=shape.labeldown, color=color.red, size=size.tiny, text="S", textcolor=color.white, transp=0)alertcondition(long, title='Buy', message='go long')alertcondition(short, title='Sell', message='go short')05/17/2020 at 3:38 PM #131987You should also submit your request here https://www.prorealcode.com/free-code-conversion/
05/25/2020 at 8:42 PM #133234Thanks Francesco
I never submitted it that way.
there’s not enough interest which is too bad because it’s a good concept, although it has been around a long time.
I just want to point out that it’s interesting on a fast timeframe, maybe also a slower one and is a great base to experiment and build upon.
Created a code for long and that’a a new one, that works for now, on wallstreet, ftse, us russel2000, dax, sweden30, with the exact same parameters, with the correct spread, on the same timeframe and/or a timeframe close to it.
Most likely a lucky moment in time. It might however give someone new inspiration!
.
05/25/2020 at 9:41 PM #13324405/26/2020 at 4:46 AM #13326705/26/2020 at 10:28 AM #133287I managed to convert it also (don’t know if good) and seems very promising, this is a first interaction with the DOW with any kind of optimization and with a random timeframe
But i think i also have your same problem, it only works on long 🙁
05/26/2020 at 1:07 PM #13331310/11/2020 at 11:58 PM #147084Muy buenas,Desconozco porqué pero este indicador lo he copiado y pegado pero no me funciona. Me da errores de compilación.Alguna persona me puede ayudar, por favor?Very good, I do not know why but this indicator I have copied and pasted but it does not work for me. It gives me compilation errors. Can someone help me please?
10/12/2020 at 12:34 AM #147086Only post in the language of the forum that you are posting in. For example English only in the English speaking forums and French only in the French speaking forums.
Thank you 🙂
10/12/2020 at 12:36 AM #14708710/12/2020 at 12:52 PM #14716006/24/2021 at 5:09 PM #172325I don’t know that language properly so couldn’t convert it, but I used the formula found on the internet to code an indicator (https://www.prorealcode.com/prorealtime-indicators/dual-thrust-strategy-indicator/) and this MTF strategy that simply enters a LONG position when the price crosses over the CAP and a SHORT position when it crosses under the FLOOR.
As suggested by the author, Stop & Reverse is the suggested way to close positions, but I added also fixed SL and TP (written and tested on DAX, 5min TF):
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697// Dual Thrust Strategy DAX mtf/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////DEFPARAM CumulateOrders = FALSETimeframe(4h,UpdateOnClose)//cTime = OpenTime >= 050000 AND OpenTime <= 210000cDay = OpenDayOfWeek >= 1 AND OpenDayOfWeek <= 5TradeON = cTime AND cDay//*********************************************************************************// Dual Thrust setupONCE N = 4 //4 periodsONCE K1 = 0.5 //0.5 K1 factorONCE K2 = K1 //K2 factor same as K1// bandsHH = highest[N](high)HC = highest[N](close)LL = lowest[N](low)LC = lowest[N](close)// rangeRNG = max(HH - LC,HC - LL)// Cap & FloorCap = open + (RNG * K1)Flr = open - (RNG * K2)// ------------------------------------------------------------------------------// LONG entryIF close CROSSES OVER Cap AND Not LongOnMarket AND TradeON THENBUY 1 CONTRACT AT MARKETELSIF close CROSSES UNDER Flr AND Not ShortOnMarket AND TradeON THENSELLSHORT 1 CONTRACT AT MARKETENDIF//SET STOP pLOSS 100SET TARGET pPROFIT 200//Timeframe(default)//*********************************************************************************// https://www.prorealcode.com/blog/trading/complete-trailing-stop-code-function/// (righe 17- 56)//// trailing stop function by Nicolas (with the addition of DISTANCE and delayed start of N bars)//IF (BarIndex - TradeIndex) >= 0 THEN //0 bars dealy to start operatingtrailingstart = 20 //20 trailing will start @trailinstart points profittrailingstep = 5 //5 trailing step to move the "stoploss"distance = 10 //10 pips distance from caurrent price (if required by the broker)//reset the stoploss valueIF NOT ONMARKET THENnewSL=0ENDIF//manage long positionsIF LONGONMARKET THEN//first move (breakeven)IF newSL=0 AND close-tradeprice(1)>=trailingstart*pipsize THENnewSL = tradeprice(1)+trailingstep*pipsizeENDIF//next movesIF newSL>0 AND close-newSL>=trailingstep*pipsize THENnewSL = newSL+trailingstep*pipsizeENDIFENDIF//manage short positionsIF SHORTONMARKET THEN//first move (breakeven)IF newSL=0 AND tradeprice(1)-close>=trailingstart*pipsize THENnewSL = tradeprice(1)-trailingstep*pipsizeENDIF//next movesIF newSL>0 AND newSL-close>=trailingstep*pipsize THENnewSL = newSL-trailingstep*pipsizeENDIFENDIF//stop order to exit the positionsIF newSL>0 THENIF LongOnMarket THENIF (close + distance) > newSL THENSELL AT newSL STOPELSIF (close - distance) < newSL THENSELL AT newSL LIMITELSESELL AT MarketENDIFELSIF ShortOnmarket THENIF (close + distance) < newSL THENEXITSHORT AT newSL STOPELSIF (close - distance) > newSL THENEXITSHORT AT newSL LIMITELSEEXITSHORT AT MarketENDIFENDIFENDIFENDIF//*********************************************************************************1 user thanked author for this post.
06/25/2021 at 7:16 AM #172386Tested it with some modifications.
06/25/2021 at 9:54 AM #172400Would you mind posting your code, so that everyone knows where the results come from? Thank you 🙂
06/25/2021 at 3:28 PM #172433Would you mind posting your code, so that everyone knows where the results come from? Thank you 🙂
Of course. Pls find it attached.
3 users thanked author for this post.
-
AuthorPosts
Find exclusive trading pro-tools on