xATRTrailingStop - reg

Trying to convert pinescript to AFL . Pine code is given below.

nATRPeriod = input(20, 'Period')
nATRMultip = input.float(5, 'Multiplier', minval=1, maxval=1000, step=1)

/////////////////////////////////////////////////////////////////////////////////ATR

xATR = ta.atr(nATRPeriod)
nLoss = nATRMultip * xATR
xATRTrailingStop = float(na)
iff_1 = close > nz(xATRTrailingStop[1], 0) ? close - nLoss : close + nLoss
iff_2 = close < nz(xATRTrailingStop[1], 0) and close[1] < nz(xATRTrailingStop[1], 0) ? math.min(nz(xATRTrailingStop[1]), close + nLoss) : iff_1
xATRTrailingStop := close > nz(xATRTrailingStop[1], 0) and close[1] > nz(xATRTrailingStop[1], 0) ? math.max(nz(xATRTrailingStop[1]), close - nLoss) : iff_2

pos = int(na)
iff_3 = close[1] > nz(xATRTrailingStop[1], 0) and close < nz(xATRTrailingStop[1], 0) ? -1 : nz(pos[1], 0)
pos := close[1] < nz(xATRTrailingStop[1], 0) and close > nz(xATRTrailingStop[1], 0) ? 1 : iff_3

patr = plot(xATRTrailingStop, color=color.new(color.aqua, 0), linewidth=1, title='AT', transp=0)

src = input(hlc3)
//t = time("D")
start = na(pos[1]) or pos > pos[1] or na(pos[1]) or pos < pos[1]

sumSrc = src * volume
sumVol = volume
sumSrc := start ? sumSrc : sumSrc + sumSrc[1]
sumVol := start ? sumVol : sumVol + sumVol[1]

out = sumSrc / sumVol

avg1 = math.avg(out, xATRTrailingStop)
//plot(avg1)
plot(out, color=color.new(color.aqua, 0), title='CV')
type or paste code here

The AFL is as follows but it has errors , I Request you to give the correct AFL code.


nATRPeriod = Param("ATR Period", 20, 2, 200, 1);
nATRMultip = Param("ATR Multiplier", 5, 1, 1000, 1);

xATR = ATR(nATRPeriod);
nLoss = nATRMultip * xATR;

xATRTrailingStop = nz(MA(C,nATRPeriod));

for(i = 0; i < BarCount; i++)
{
    pos = ValueWhen(Close[i] > Ref(xATRTrailingStop, -1) && Ref(Close, -1) > Ref(xATRTrailingStop, -1), 1,
             ValueWhen(Close[i] < Ref(xATRTrailingStop, -1) && Ref(Close, -1) < Ref(xATRTrailingStop, -1), -1, 0));
    if( pos == 1 )
        xATRTrailingStop = Max(xATRTrailingStop, Close[i] - nLoss);
    else if ( pos == -1 )
        xATRTrailingStop = Min(xATRTrailingStop, Close[i] + nLoss);
}

Plot(xATRTrailingStop, "XT",  colorBlue, styleLine,0,0,0,2);

src = Avg;
start = Ref(pos, -1) != pos;
sumSrc = src * Volume;
sumVol = Volume;

sumSrc = Sum(start, sumSrc, sumSrc[1]);
sumVol = Sum(start, sumVol, sumVol[1]);

out = sumSrc / sumVol;

Plot(out, "CV", colorAqua, styleLine);



You should search this forum and knowledge base as there is plenty of answers already provided (ATR Trail Stop Indicator)

3 Likes

Greetings and Thank you for your reply and suggestion. Richard,

I just wanted to take a moment to express my appreciation for Tomasz and the members of this forum.
I have been a member for a short time, but I have already seen how helpful and supportive everyone is. Their solutions was extremely helpful and made a big difference for me. I am grateful for all the time and effort that everyone puts into helping others in this community.

Keeping all that in mind, I've already done some research and tried on what you've done said , but I am still having trouble.

I was wondering if it would be possible to request on the existing topics on ATR Trail Stop but my approach is different.

The link that you have provided is showing that the Trailingstop is based on LLV and HHV
but what i need is from a different approach.

Here in my approach a trailing stop loss is obtained using the calculated Stoplossdistance and compares the current Closeprice to the previous Closeprice and ATR trailing stop to determine if a long or short position should be taken, using the iff_1, iff_2, and iff_3. In that process, It checks if the current close price is greater than the previous ATR trailing stop and if the previous close price was also greater than the previous ATR trailing stop, if so it sets the ATR trailing stop to the current close price
minus the stop loss distance. If not, it checks if the current close price is less than the previous ATR trailing stop and if the previous close price was also less than the previous ATR trailing stop, if so it sets the ATR trailing stop to the minimum of the previous ATR trailing stop and the current close price plus the stop loss distance. Finally the variable "start" is used to determine if the cumulative volume
and volume sums should be reset or if they should be accumulated.

Thus I need AFL EQUIVALENT of this PINE code.

I would really appreciate any help or advice that someone might have to offer. Thank you in advance for your help.

Hi Kumar

Im not familiar with Pine code and your description is not clear to me what you are trying to achieve
You might get value spending some time understanding the difference between array processing and bar by bar processing using a for loop using individual bar values at the bar index in question. you cant mix the two or you will generate errors.

You will find all this in the tutorials and knowledge base examples and the manual.

in your afl code the atr Trail stop is just a moving average of Close using the ATRperiod is that what is intended?
Maybe others who know and understand Pine code can provide more help.

Hi, My AFL code is wrong (intended) . The pine code works fine.

So in simple terms i need that exact replica in AFL.

Wouldn't it make more sense to post an AFL code (your attempt) that is intended to be correct rather than intended to be wrong?

Hi TrendSurfer,

My apologies that my English is not good.

What i referred is the reply to Richard ... " in your afl code the atr Trail stop is just a moving average of Close using the ATRperiod is that what is intended? " ...

I don't post it intentionally wrong AFL code. The AFL code posted was my best try.

xATRTrailingStop = nz(MA(C,nATRPeriod));

I should not have added this "MA(C,nATRPeriod)" here . I simply don't know how to proceed in this step.

@kumar, here is my attempt. I never used/learned Pine script, so I only attempted to understand the original code and replicate it using loops in AFL (I imagine someone more expert will be able to greatly simplify it).

Anyway, I also added an exploration so you can check if the steps are according to the rules (I briefly compared a last year's SPY chart, and the result seems to be not very dissimilar).

nATRPeriod = Param( "Period", 20, 5, 50, 5 );
nATRMultip = Param( "Multiplier", 5, 1, 1000, 1 );

xATR = ATR( nATRPeriod );
nLoss = nATRMultip * xATR;

iff_1 = Null;
iff_2 = Null;
iff_3 = Null;
pos = Null;
xATRTrailingStop = Null;

for( i = 1; i < BarCount; i++ )
{
    iff_1[i] = IIf( Close[i] > nz( xATRTrailingStop[i - 1], 0 ), Close[i] - nLoss[i], Close[i] + nLoss[i] );
    iff_2[i] = IIf( Close[i] < nz( xATRTrailingStop[i - 1], 0 ) AND Close[i - 1] < nz( xATRTrailingStop[i - 1], 0 ),
                    Min( nz( xATRTrailingStop[i - 1] ), Close[i] + nLoss[i] ), iff_1[i] );
    xATRTrailingStop[i] = IIf( Close[i] > nz( xATRTrailingStop[i - 1], 0 ) AND close[i - 1] > nz( xATRTrailingStop[i - 1], 0 ),
                               Max( nz( xATRTrailingStop[i - 1] ), Close[i] - nLoss[i] ), iff_2[i] );
    iff_3[i] = IIf( close[i - 1] > nz( xATRTrailingStop[i - 1], 0 ) AND Close[i] < nz( xATRTrailingStop[i - 1], 0 ), -1, nz( pos[i - 1], 0 ) );
    pos[i] = IIf( close[i - 1] < nz( xATRTrailingStop[i - 1], 0 ) AND Close[i] > nz( xATRTrailingStop[i - 1], 0 ), 1, iff_3[i] );
}
Plot( xATRTrailingStop, "ATR Stop", colorOrange, styleLine );

src = ( H + L + C ) / 3;
start = IsNull( Ref( pos, -1 ) ) OR( pos > Ref( pos, -1 ) ) OR( Pos < Ref( pos, -1 ) );
sumSrc = src * Volume;
sumVol = Volume;
for( i = 1; i < BarCount; i++ ) 
{
    sumSrc[i] = IIf( start[i], sumSrc[i], sumSrc[i] + sumSrc[i - 1] );
    sumVol[i] = iIf( start[i], sumVol[i], sumVol[i] + sumVol[i - 1] );
}
out = sumSrc / sumVol;
avg1 = MA( out, xATRTrailingStop ); // ??
Plot( out, "CV", colorGreen, styleLine | styleThick );
// Plot( avg1, "Avg1", colorRed, styleDashed ); 
Plot( sumVol, "SumV", colorBlue, styleHistogram | styleOwnScale );

// Exploration to check results
function nil( a )
{
    return IIf( a, a, Null );
}

Filter = 1;
AddColumn( Close, "Close" );
AddColumn( xATRTrailingStop, "ATR TR Stop" );
AddColumn( iff_1, "Iff_1" );
AddColumn( iff_2, "Iff_2" );
AddColumn( iff_3, "Iff_3", 1 );
AddColumn( pos, "Pos", 1 );
AddColumn( Src, "Src" );
AddColumn( nil( start ), "Start", 1, colorRed );
AddColumn( src * Volume, "Src * Volume" );
AddColumn( Volume, "Volume" );
AddColumn( sumSrc, "Cum Src * Volume" );
AddColumn( sumVol, "Cum Volume" );
AddColumn( avg1, "Avg1");
AddColumn( out, "Out" );

If it is wrong, I apologize in advance... Corrections and improvements are welcome!

2 Likes

Hi @beppe ,

Excellent. I never expected the solution this much fast. THANK YOU SO MUCH. In Tradingview we get lot of codes for free but could find it very difficult to implement in Amibroker. As far as i know that a lot of people moving to TV just because of this. Although AFL is more than a decade old, average people like me are not proficient in it. If there is code conversion tool then Amibroker can become more stronger.

Best Regards

Kumar

1 Like

@kumar Nonsense. The fact that you are not capable of something, does not mean that everyone is like you. There is nothing "easier" in Pine script. It is just half-baked attempt to copy Tradestation "Easy language" (the only thing "easy" in it was the name) and certainly shares one thing with ES - slowness.
AFL is not only faster to execute but also faster to write (since it is shorter in majority of cases, if one knows how to benefit from array processing that makes long code shorter).

And really ATR based trailing stop inAmiBroker is single line - READ THE DOCS AFL Function Reference - APPLYSTOP (so called "Chandelier stop" in the examples).

2 Likes

Hi Tomasz,

AFL is certainly faster and definitely has it own advantage. There is no minor inconvenience or whatsoever, in fact you are continuously adding more and more value to it and one of the best. My point is that there are tons of open source pine codes available and continuously pouring in everyday, i mean the quantity is really large. So I was wondering is there an unassuming way on how to convert them into AFL?.

I don't see the need to "convert" pine codes. I am yet to see anything original in those TV codes, everything is just re-write of OLD stuff, really. And you if you believe that you would take some pine script floating around and it will make you suddenly rich - it won't happen.

You have to find YOUR EDGE. Nothing publicly available offers any edge. Not to mention that you should really understand what you are trading. Using "black boxes" is really bad idea.

3 Likes