How to make explore like scan result

I want an afl code to make Explore result like Scan result (Click explore, it show result like click Scan)
How to do this
Thank you!

1

You have to use AddMultiTextColumn() function.

(TextList has been created programmatically)

Version(6.2);

m = MA( Close, 20 );
Buy = Cross( Close, m ); 
Sell = Cross( m, Close );
Short = MACD() < 0;
Cover = RSI() < 30;

/// https://forum.amibroker.com/t/how-to-make-explore-like-scan-result/24856/2
TextList = "NO SIGNAL\nBuy\nSell\nBuy & Sell\nShort\nBuy & Short\n"+
			"Sell & Short\nBuy & Sell & Short\nCover\nBuy & Cover\n"+
			"Sell & Cover\nBuy & Sell & Cover\nShort & Cover\n"+
			"Buy & Short & Cover\nSell & Short & Cover\nBuy & Sell & Short & Cover";
TextSelector = 1 * Buy + 2 * Sell + 4 * Short + 8 * Cover;

fontcolor = colorWhite;
cellcolor = colorDarkGrey;

Filter = 1; 
SetOption( "NoDefaultColumns", True );
SetSortColumns( 3 );
AddTextColumn( Name(), "Symbol", 1.0, fontcolor, cellcolor, 70 );
AddMultiTextColumn( TextSelector, TextList, "Trade", 1, fontcolor, cellcolor, 200 );
AddColumn( DateTime(), "Date/Time", formatDateTime, fontcolor, cellcolor, 120 );
AddColumn(C, "Close", 1.2, fontcolor, cellcolor, 80);

22

Thank you!
I tried and see it missing something:
1

No, it is not ignored on my end.
I tried a few rules and it works here.

Post full reproducible code not pictures.
Posts showing code in pictures (and incomplete ones in addition and with inflationary use of exclamation marks) are getting ignored. Period.

22

TextSelector has 8 * Cover and Cover is at eight position in TextList (starting from zero).
Look at the output above. TextSelector is showing 8 in 4th column and Cover text is shown!

Version(6.2);

m = MA( Close, 20 );
Buy = Cross( Close, m ); 
Sell = Cross( m, Close );
Short = MACD() < 0;
Cover = MACD()>Signal();//Cross(MACD(),Signal());//MACD() > 0;

/// https://forum.amibroker.com/t/how-to-make-explore-like-scan-result/24856/2
TextList = "NO SIGNAL\nBuy\nSell\nBuy & Sell\nShort\nBuy & Short\n"+
			"Sell & Short\nBuy & Sell & Short\nCover\nBuy & Cover\n"+
			"Sell & Cover\nBuy & Sell & Cover\nShort & Cover\n"+
			"Buy & Short & Cover\nSell & Short & Cover\nBuy & Sell & Short & Cover";
TextSelector = 1 * Buy + 2 * Sell + 4 * Short + 8 * Cover;

fontcolor = colorWhite;
cellcolor = colorDarkGrey;

Filter = 1; 
SetOption( "NoDefaultColumns", True );
SetSortColumns( 3 );
AddTextColumn( Name(), "Symbol", 1.0, fontcolor, cellcolor, 70 );
AddMultiTextColumn( TextSelector, TextList, "Trade", 1, fontcolor, cellcolor, 200 );
AddColumn( DateTime(), "Date/Time", formatDateTime, fontcolor, cellcolor, 120 );
AddColumn(C, "Close", 1.2, fontcolor, cellcolor, 80);

AddColumn(TextSelector, "TextSelector", 1, fontcolor, cellcolor, 80);
AddColumn(Buy, "Buy", 1, fontcolor, cellcolor, 80);
AddColumn(Sell, "Sell", 1, fontcolor, cellcolor, 80);
AddColumn(short, "Short", 1, fontcolor, cellcolor, 80);
AddColumn(Cover, "Cover", 1, fontcolor, cellcolor, 80);

This is my problem, It miss Cover text

2

Data File: https://drive.google.com/file/d/1dOZ_5TcJNqT0MEevvhGHsYL9QZcMe1U8/view?usp=sharing

TimeFrame 20 Minute

My Code:

_SECTION_BEGIN("MACD");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));


r1 = Param( "Fast", 17, 1, 100, 1 );
r2 = Param( "Slow", 26, 1, 100, 1 );
r3 = Param( "Base", 5, 1, 100, 1 );
nTP = Param( "TP avg", 4.6, 0.1, 10, 0.2 );
nSL = Param( "SL avg", 0.5, 0.1, 10, 0.2 );


ma1 = EMA(C, r1);
ma2 = MA(C, r2);
ma3 = MA(C, r3);

Buy = Cover = Cross(ma1, ma2) AND C > ma3;
Sell = Short = Cross(ma2, ma1) AND C < ma3;

Buy = ExRem( Buy, Sell);
Sell = ExRem(Sell, Buy);
Cover = ExRem(Cover, Short);
Short = ExRem(Short, Cover);

Plot(ma1,"MA1", colorAqua);
Plot(ma2,"MA2", colorRed);
Plot(ma3,"MA3", colorBlue);


Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle()); 

PlotShapes( Buy * shapeUpArrow + Sell * shapeDownArrow, IIf( Buy, colorGreen , colorRed) ); 

Filter = Buy or Sell or Short or Cover;

ApplyStop(stopTypeProfit,stopModePercent,nTP,True);
ApplyStop(stopTypeLoss,stopModePercent,nSL,True);


Equity( 1, 0 ); // evaluate stops, all quotes


////////////////////////////////////////////////////////////////////////////////////////////////
/// https://forum.amibroker.com/t/how-to-make-explore-like-scan-result/24856/2
TextList = "NO SIGNAL\nBuy\nSell\nBuy & Sell\nShort\nBuy & Short\n"+
			"Sell & Short\nBuy & Sell & Short\nCover\nBuy & Cover\n"+
			"Sell & Cover\nBuy & Sell & Cover\nShort & Cover\n"+
			"Buy & Short & Cover\nSell & Short & Cover\nBuy & Sell & Short & Cover";
TextSelector = 1 * Buy + 2 * Sell + 4 * Short + 8 * Cover;

fontcolor = colorWhite;
cellcolor = colorDarkGrey;

Filter = 1; 
SetOption( "NoDefaultColumns", True );
SetSortColumns( 3 );
AddTextColumn( Name(), "Symbol", 1.0, fontcolor, cellcolor, 70 );
AddMultiTextColumn( TextSelector, TextList, "Trade", 1, fontcolor, cellcolor, 200 );
AddColumn( DateTime(), "Date/Time", formatDateTime, fontcolor, cellcolor, 120 );
AddColumn(C, "Close", 1.2, fontcolor, cellcolor, 80);

AddColumn(TextSelector, "TextSelector", 1, fontcolor, cellcolor, 80);
AddColumn(Buy, "Buy", 1, fontcolor, cellcolor, 80);
AddColumn(Sell, "Sell", 1, fontcolor, cellcolor, 80);
AddColumn(short, "Short", 1, fontcolor, cellcolor, 80);
AddColumn(Cover, "Cover", 1, fontcolor, cellcolor, 80);


_SECTION_END();

The code is pointless. Use "SCAN" button instead and it will display Buy/Sell/Short/Cover automatically WITHOUT ANY CODING.

There is NO POINT in re-inventing the wheel and doing it wrongly.

Remove everything after

Equity( 1, 0 )

call and run SCAN.

Your code does not work because exit signals may be different than 0 and 1. If exit signal was generated by STOP then Equity() writes back value different than 1, see:

http://www.amibroker.com/kb/2014/09/24/how-to-identify-which-signal-triggers/

To make it work you would need to write:

TextSelector = 1 * Buy + 2 * ( Sell != 0 ) + 4 * Short + 8 * ( Cover != 0 );
2 Likes

@dungla2011,

That's why you should not post just pictures but complete code.

You are using ApplyStop function.

The TextSelector I posted expects all signals to return ONE ( 1 ) .
ApplyStop (if triggered) makes Sell And Cover to return other values greater one.
E.g. if short stop loss would be triggered then Cover would return 2, if short profit stop would be triggered then Cover would return 3.

See ApplyStop documentation.

So in order to make Cover and Sell returning 1 again you have to add additional Cover Sell after Equity() function.

// Return 1 again (also if stops are triggered)
Cover = Cover > 0;// Includes Regular Exit and Stops
Sell = Sell > 0;// Includes Regular Exit and Stops

Why do we need to do that (making Cover and Sell returning 1)?

Because otherwise you would have to modify TextSelector and TextList if you would want to output stop text separately.

e.g. TextSelector would have to be like this for example

CoverSL = Cover == 2;// If Cover stop loss triggered
CoverTP = Cover == 3;// If Cover take profit triggered

SellSL = Sell == 2;// If Sell stop loss triggered
SellTP = Sell == 3;// If Sell take profit triggered

TextSelector = 1*Buy + 2*Sell + 4*Short + 8*Cover + 16*SellSL + 32*SellTP + 64*CoverSL + 128*CoverTP;

TextList string would become even longer.


Anyway this one should work now with original code of 2nd post.

_SECTION_BEGIN("MACD");
r1 = Param( "Fast", 17, 1, 100, 1 );
r2 = Param( "Slow", 26, 1, 100, 1 );
r3 = Param( "Base", 5, 1, 100, 1 );
nTP = Param( "TP avg", 4.6, 0.1, 10, 0.2 );
nSL = Param( "SL avg", 0.5, 0.1, 10, 0.2 );

ma1 = EMA(C, r1);
ma2 = MA(C, r2);
ma3 = MA(C, r3);

Buy = Cover = Cross(ma1, ma2) AND C > ma3;
Sell = Short = Cross(ma2, ma1) AND C < ma3;

ApplyStop(stopTypeProfit,stopModePercent,nTP,True);
ApplyStop(stopTypeLoss,stopModePercent,nSL,True);

Equity( 1, 0 ); // evaluate stops, all quotes


// Return 1 again (also if stops are triggered)
Cover = Cover > 0;// Includes Regular Exit and Stops
Sell = Sell > 0;// Includes Regular Exit and Stops


SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));

Plot(ma1,"MA1", colorAqua);
Plot(ma2,"MA2", colorRed);
Plot(ma3,"MA3", colorBlue);

Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle()); 
PlotShapes( Buy * shapeUpArrow + Sell * shapeDownArrow, IIf( Buy, colorGreen , colorRed) ); 


////////////////////////////////////////////////////////////////////////////////////////////////
/// https://forum.amibroker.com/t/how-to-make-explore-like-scan-result/24856/2
TextList = "NO SIGNAL\nBuy\nSell\nBuy & Sell\nShort\nBuy & Short\n"+
			"Sell & Short\nBuy & Sell & Short\nCover\nBuy & Cover\n"+
			"Sell & Cover\nBuy & Sell & Cover\nShort & Cover\n"+
			"Buy & Short & Cover\nSell & Short & Cover\nBuy & Sell & Short & Cover";
TextSelector = 1 * Buy + 2 * Sell + 4 * Short + 8 * Cover;

fontcolor = colorWhite;
cellcolor = colorDarkGrey;

Filter = Buy or Sell or Short or Cover;
SetOption( "NoDefaultColumns", True );
SetSortColumns( 3 );
AddTextColumn( Name(), "Symbol", 1.0, fontcolor, cellcolor, 70 );
AddMultiTextColumn( TextSelector, TextList, "Trade", 1, fontcolor, cellcolor, 200 );
AddColumn( DateTime(), "Date/Time", formatDateTime, fontcolor, cellcolor, 120 );
AddColumn(C, "Close", 1.2, fontcolor, cellcolor, 80);
_SECTION_END();

BTW, I don't see how it would be pointless if he wants to add additional columns to exploration.
We don't know.
Scan can not have addtional colunms. In Exploration you can do add them since it is advanced scan.

1 Like

... zero (FALSE (0)) or one (TRUE (1)).

// Return 0 or 1 again (also if stops are triggered)

Thanks for your helps!

@Tomasz : I need do this to understand how AFL work, to control it, it's really difficult to understand, I'm programmer more than 10 year, I use pine script first, and pine seem very easy to understand and easy to find document and example...)

After some nightmare, I have good result:

image


_SECTION_BEGIN("MACD");
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle()); 

ma1 = MA(C,10);
ma2 = EMA(C,10);
Buy = Cross(ma2,ma1);
Sell = 0;

Plot(ma1,"MA1", colorBlue);
Plot(ma2,"MA2", colorRed);
//Plot shape at default position
//PlotShapes( Buy * shapeUpArrow, colorBlue); 

//Plot shape at Low, easy see
PlotShapes( Buy, colorBlue, 0, Low);

//Take profit: 2%
ApplyStop(stopTypeProfit,stopModePercent,2,True);
//Stop lost: 1%
ApplyStop(stopTypeLoss,stopModePercent,1,True);

//Must have this line, to show true Buy/Sell Point
Equity( 1, 0 );

InTrade = Flip(Buy,Sell);
stopline = IIf( InTrade, ma1, Null );
Plot( stopline, "Max stop line", colorBlack, styleThick );
tpline = IIf( InTrade, ma1, Null );
Plot( tpline, "Max TP line", colorBlue, styleThick );

////For explore ///

//Show Buy/SellOnly
Filter= (Buy != 0) OR (Sell != 0);
//Show All
//Filter = 1;

AddColumn(Buy,"Buy");
AddColumn(Sell,"Sell");
AddColumn(IIf(Buy,Asc("B"),IIf(Sell,Asc("S"),Null)),"Buy/Sell",formatChar,colorDefault,IIf(Buy,colorGreen,IIf(Sell,colorOrange,colorDefault)));
AddColumn(C,"Close");
AddColumn(InTrade,"InTrade");
AddColumn(IIf(InTrade,Asc("x") ,null),"InTrade1",formatChar,colorDefault,IIf(InTrade,colorGreen,IIf(Sell,colorOrange,colorDefault)));
AddMultiTextColumn((InTrade > 0), "NotIntrade\nIntrade", "Intrade2", 1.0, IIf( InTrade > 0, colorGreen, colorRed ), colorDefault, 100 );

_SECTION_END(); 


Data file:

[https://drive.google.com/file/d/1ZNkzx06l3BNNsq_B-92ZweO5WBDXA96x/view]

@Tomasz : why I need do this, you can see, In scan, have not show TakeProfit/StopLost, only show Buy/Sell
But with explore, I can see exactly TakeProfit/StopLost

AFL is among the easiest and more concise languages around. Thanks to array processing properly written formulas in AFL are much shorter than written in any other language. Want a proof, see S&C Traders' Tips examples (AFL codes are almost always the shortest).

All you need to do is to DROP your assumptions & habits from other languages (such as Pine) that do not feature array processing and adopt array-wise thinking.

2 Likes

I feel like a lot of people will be coming to AMI from Pine since Trading View is so popular. It might be good to do a post for people to know which functions to use and common differences.

I might do this at some point...

2 Likes

I don't think that learning by "differences" is the way to go. You won't learn new paradigm of thinking if the language you are comparing to simply has no equivalent concepts.
From my observations, AFL is better understood by people without much programming experience. They come with fresh mind and no assumptions. That is correct way to approach new language.
I once met a dentist who had no previous programming experience and within a week become brilliant AFL programmer.

The worst case are people who expect AFL to work exactly the same way as their XYZ language. People who don't really want any change. If they love XYZ so much, let them continue use old tools. If you want new, you have to open your mind.

4 Likes

(Not to hijack this thread any further, but private messaging is turned off so I must)

While the code style may be different, the needs remain the same. I came to AMI from a coding background. The biggest hurdle for me was figuring out what all the equivalent functions are named and how to search for them.
Admittedly self referencing variables was a challenge. There are still certain things that I can't figure out how to code the "AFL way" without using a loop. Such as a Laguerre filter.

Personally the big problem I seem to notice is people coming here with no coding background, copy pasting someone else's work in any language they can find, and have no desire to even learn. Frankly I don't even know why they are using AMI Broker. In my opinion AMI is most useful for people who code (or at least want to)!

Unfortunately it seems most just want to use someone else's code to make money. Not only do they not care about how it's made with AFL, but they don't even care about what the indicator is actually measuring. It's just a line with a name. The real coders here all know that won't work out well in the end.

1 Like

I think it is sign of times that everyone wants everything quickly without effort.

As for Laguerre filter it does not look terribly complicated (based on Ehlers TS code):

// AFL implementation TJ 2021
alpha = 0.2;

price = (H+L+C)/3;

p0 = price[0];

l0 = AMA2( alpha * price, 1, 1-alpha );
l1 = AMA2( -(1 - alpha)*l0 + Nz( Ref( l0, -1 ), p0 ), 1, 1 - alpha );
l2 = AMA2( -(1 - alpha)*l1 + Nz( Ref( l1, -1 ), p0 ), 1, 1 - alpha );
l3 = AMA2( -(1 - alpha)*l2 + Nz( Ref( l2, -1 ), p0 ), 1, 1 - alpha );


Plot( C, "Price", colorDefault, styleCandle );

Plot( ( l0 + 2*l1 + 2*l2 + l3) / 6, "Laguerre Filter", colorGreen );

coeff[ 0 ] = coeff[ 3 ] = 1/6;
coeff[ 1 ] = coeff[ 2 ] = 2/6;

Plot( FIR( price, coeff, 4 ), "FIR", colorRed );`
4 Likes

I came out with even shorter and cleaner code for Laguerre filter thanks to AmiBroker's built-in general-purpose IIR function:

// Laguerre filter AFL implementation TJ 2021 (shorter)
alpha = 0.2;

price = (H+L+C)/3;

l0 = IIR( price, alpha, 1 - alpha );
l1 = IIR( l0, alpha - 1, 1 - alpha, 1 );
l2 = IIR( l1, alpha - 1, 1 - alpha, 1 );
l3 = IIR( l2, alpha - 1, 1 - alpha, 1 );

Plot( C, "Price", colorDefault, styleCandle );

Plot( ( l0 + 2*l1 + 2*l2 + l3) / 6, "Laguerre Filter", colorGreen );

coeff[ 0 ] = coeff[ 3 ] = 1/6;
coeff[ 1 ] = coeff[ 2 ] = 2/6;

Plot( FIR( price, coeff, 4 ), "FIR", colorRed );
4 Likes

Wow I did not expect this type of reply, but it was very welcome :rofl:

I knew AMA was very close to what I needed, but didn't know AMA2 existed! Maybe have whoever works on the guide update AMA by adding AMA2 + IIR to the "see also" section.

I would have never thought of the IIR method. Thanks very much for providing these two examples. Very informative.

2 Likes

Majority of smoothing filters are either IIR or FIR or combination of them. If you see Ehlers work you can bet with 99% probability that you can implement it using IIR or FIR function.

3 Likes

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.