convert request Dual Thrust Trading Algorithm

Viewing 15 posts - 1 through 15 (of 16 total)
  • Author
    Posts
  • #131972 quote
    Paul
    Participant
    Master

    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.

    //@version=4
    study("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
    
    //*** Inputs
    p      = 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") // 4
    nlen   = input(14,         "Lookback Window N") // 20
    k      = input(0.9,        "Coeff", step=0.01) // .7, .9
    disc   = input(0.55,       "Trending discount", step=0.01) //  .6
    use_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?")
    
    //*** Main
    O = 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/val2
        
    alpha(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 - 2
        narrow = sqrt(val1/val2)
        est = sum(pow(lr-array,2),per) / (per - 2 )
        wide = sqrt(est)
        d = dir ? 1 : -1
        band = type ? narrow : wide
        seb = lr + d * mult * band
    
    // SEE Bands
    UWB = 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 Bands
    basis = sma(close, pbb)
    dev   = multbb * stdev(close, pbb)
    upper = basis + dev
    lower = basis - dev
    plot(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 Bearish 
    uptrend = false, dntrend = false
    if rule=="Original"
        rng = C - O
        doji = rng == 0 
        uptrend := rng > 0 or doji and rng[1] > 0
        dntrend := rng < 0 or doji and rng[1] < 0
    else
        sm   = sma(C, 3)                    // #1
        em   = ema(C, 10)                   // #2
        ma5  = sma(C, 5), ma10 = sma(C, 10) // #3
        uptrend := rule=="SMA3" ? C > sm : rule=="EMA10" ? C > em : ma5 > ma10 
        dntrend := rule=="SMA3" ? C < sm : rule=="EMA10" ? C < em : ma5 < ma10  
    
    k1 = k, k2 = k
    if uptrend  // Assigned empirically. Should be optimized separately
        k1 := k1 * disc  //.2
        k2 := k2 * (1 + disc)
    if dntrend
        k1 := k1 * (1 + disc)
        k2 := k2 * disc //.2
    
    dtta1_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.0
    
        hh := 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 - ll
        
        hh := 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.0
    if algo == "Algo #1" 
        buyTrig := bt1, sellTrig := st1
    else    
        buyTrig := bt2, sellTrig := st2
    
    longCondition  = C >= buyTrig 
    shortCondition = C <= sellTrig 
    state  = 0
    state := longCondition ? 1 : shortCondition ? -1 : nz(state[1])
    long   = change(state) and state[1]==-1 
    short  = change(state) and state[1]==1
    
    plotshape(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')

     

    Screenshot-2020-05-17-at-14.53.24.jpg Screenshot-2020-05-17-at-14.53.24.jpg Screenshot-2020-05-17-at-14.53.08.jpg Screenshot-2020-05-17-at-14.53.08.jpg Screenshot-2020-05-17-at-15.22.30.jpg Screenshot-2020-05-17-at-15.22.30.jpg
    #131987 quote
    Francesco
    Participant
    Veteran

    You should also submit your request here https://www.prorealcode.com/free-code-conversion/

    Paul and swedshare thanked this post
    #133234 quote
    Paul
    Participant
    Master

    Thanks 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!

    .

    Francesco and Kovit thanked this post
    Screenshot-2020-05-25-at-21.05.02.jpg Screenshot-2020-05-25-at-21.05.02.jpg Screenshot-2020-05-25-at-21.02.42.jpg Screenshot-2020-05-25-at-21.02.42.jpg Screenshot-2020-05-25-at-21.01.55.jpg Screenshot-2020-05-25-at-21.01.55.jpg Screenshot-2020-05-25-at-21.01.21.jpg Screenshot-2020-05-25-at-21.01.21.jpg
    #133244 quote
    Francesco
    Participant
    Veteran

    Did you managed to convert it? Looks interesting, but for now i’m out from low tf systems; i would like to make some tests on higher ones if you would like to share it, from the bottom of my skills 😀

    #133267 quote
    Paul
    Participant
    Master

    yes, managed to convert the core and modified a bit. I will see how it goes. On higher timeframe it doesn’t seem to work good enough without curve-fitting.

    #133287 quote
    Francesco
    Participant
    Veteran

    I 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 🙁

    1-12.jpg 1-12.jpg
    #133313 quote
    Paul
    Participant
    Master

    That’s a problem, short didn’t work at first glance. Nice to see you got something interesting to work with!

    Francesco thanked this post
    #147084 quote
    rsagar
    Participant
    Average

    Muy 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?

    #147086 quote
    robertogozzi
    Moderator
    Master

    @rsagar

    Only 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 🙂

    #147087 quote
    robertogozzi
    Moderator
    Master

    @rsagar

    it’s not in ProRealTime language. It must be converted before you can use it with PRT.

    #147160 quote
    rsagar
    Participant
    Average

    (Sorry Roberto)

    Good Morning,

    I would need to know what application could convert me from Tradestation language to PRT please.

    (or if there is information that can help me)

    Thanks

    #172325 quote
    robertogozzi
    Moderator
    Master

    I 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):

    // Dual Thrust Strategy DAX mtf
    //
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    DEFPARAM CumulateOrders = FALSE
    Timeframe(4h,UpdateOnClose)
    //
    cTime   = OpenTime >= 050000 AND OpenTime <= 210000
    cDay    = OpenDayOfWeek >= 1 AND OpenDayOfWeek <= 5
    TradeON = cTime AND cDay
    //*********************************************************************************
    // Dual Thrust setup
    ONCE N  = 4          //4   periods
    ONCE K1 = 0.5        //0.5 K1 factor
    ONCE K2 = K1         //K2 factor same as K1
    // bands
    HH  = highest[N](high)
    HC  = highest[N](close)
    LL  = lowest[N](low)
    LC  = lowest[N](close)
    // range
    RNG = max(HH - LC,HC - LL)
    // Cap & Floor
    Cap = open + (RNG * K1)
    Flr = open - (RNG * K2)
    // ------------------------------------------------------------------------------
    // LONG  entry
    IF close CROSSES OVER Cap AND Not LongOnMarket AND TradeON THEN
    BUY 1 CONTRACT AT MARKET
    ELSIF close CROSSES UNDER Flr AND Not ShortOnMarket AND TradeON THEN
    SELLSHORT 1 CONTRACT AT MARKET
    ENDIF
    //
    SET STOP   pLOSS   100
    SET 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 operating
    trailingstart = 20  //20 trailing will start @trailinstart points profit
    trailingstep  = 5   //5  trailing step to move the "stoploss"
    distance      = 10  //10 pips distance from caurrent price (if required by the broker)
    //reset the stoploss value
    IF NOT ONMARKET THEN
    newSL=0
    ENDIF
    
    //manage long positions
    IF LONGONMARKET THEN
    //first move (breakeven)
    IF newSL=0 AND close-tradeprice(1)>=trailingstart*pipsize THEN
    newSL = tradeprice(1)+trailingstep*pipsize
    ENDIF
    //next moves
    IF newSL>0 AND close-newSL>=trailingstep*pipsize THEN
    newSL = newSL+trailingstep*pipsize
    ENDIF
    ENDIF
    
    //manage short positions
    IF SHORTONMARKET THEN
    //first move (breakeven)
    IF newSL=0 AND tradeprice(1)-close>=trailingstart*pipsize THEN
    newSL = tradeprice(1)-trailingstep*pipsize
    ENDIF
    //next moves
    IF newSL>0 AND newSL-close>=trailingstep*pipsize THEN
    newSL = newSL-trailingstep*pipsize
    ENDIF
    ENDIF
    
    //stop order to exit the positions
    IF newSL>0 THEN
    IF LongOnMarket THEN
    IF (close + distance) > newSL THEN
    SELL AT newSL STOP
    ELSIF (close - distance) < newSL THEN
    SELL AT newSL LIMIT
    ELSE
    SELL AT Market
    ENDIF
    ELSIF ShortOnmarket THEN
    IF (close + distance) < newSL THEN
    EXITSHORT AT newSL STOP
    ELSIF (close - distance) > newSL THEN
    EXITSHORT AT newSL LIMIT
    ELSE
    EXITSHORT AT Market
    ENDIF
    ENDIF
    ENDIF
    ENDIF
    //*********************************************************************************
    Paul thanked this post
    Dual-Thrust-Strategy-DAX-mtf.itf x-13.jpg x-13.jpg
    #172386 quote
    VinzentVega
    Participant
    Veteran

    Tested it with some modifications.

    Unbenannt.png Unbenannt.png
    #172400 quote
    robertogozzi
    Moderator
    Master

    Would you mind posting your code, so that everyone knows where the results come from? Thank you 🙂

    #172433 quote
    VinzentVega
    Participant
    Veteran

    Would you mind posting your code, so that everyone knows where the results come from? Thank you 🙂

    Of course. Pls find it attached.

    robertogozzi and Midlanddave thanked this post
    Dual-Thrust-Strategy-DAX-V2.itf
Viewing 15 posts - 1 through 15 (of 16 total)
  • You must be logged in to reply to this topic.

convert request Dual Thrust Trading Algorithm


ProOrder: Automated Strategies & Backtesting

New Reply
Author
author-avatar
Paul @micky75d Participant
Summary

This topic contains 15 replies,
has 3 voices, and was last updated by robertogozzi
4 years, 7 months ago.

Topic Details
Forum: ProOrder: Automated Strategies & Backtesting
Language: English
Started: 05/17/2020
Status: Active
Attachments: 12 files
Logo Logo
Loading...