Help with IIF function in a loop. Horizontal lines with labels. How to check if the code is efficient?

Hi,
This started of as an exercise to mark the highs and lows of pivots using a click of the mouse button.
Added on GUI buttons and then I am trying to plot the wicks of candles ,

Seems to be an error in the "iif" function (method of selecting if the line is plotted at the "close or the open".
image

The relevant part of the code is lines 135 and 136,

OC[j] = IIf( shapePos ==H[i] AND C[i] > O[i], C[i], O[i] OR IIf(shapePos == L[i] AND C[i] < O[i], C[i], O[i] )); //THIS SELECTS OPEN OR CLOSE
OCcolor[j] = IIf( shapePos==H[i] AND C[i] > O[i], colorBlue, colorGrey40 ) OR IIf( shapePos==L[i] AND C[i] > O[i], colorBlue,colorGrey40) ;

full code posted below,


/* 
This is with many thanks to PanoS,  GUI code used from fxshrat,
modifications by Jeetu
*/

_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates | chartHideQuoteMarker);
GraphLabelDecimals = 2;
GraphXSpace =10;
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
TC = IIf(C>Ref(C,-1),colorGreen,IIf(C<Ref(C,-1),colorRed,colorGold));
Plot( C, "Close", TC, styleNoTitle | ParamStyle("Style") | GetPriceStyle() ); 

_SECTION_END();

_SECTION_BEGIN("wicks");
RequestTimedRefresh(0.1,True);
RequestMouseMoveRefresh();

//// Start Code for GuiButtons 
numbuttons = 2; // number of toggle buttons
toggletext1 = "Disable Click,Enable Click";
toggletext2 = "Disable Remove,Remove slected";
//toggletext3 = " PROJ. ON , PROJ.OFF" ;

initial = 1;// intial toggle setting
persist = 1;// keep toggle state ON(1) / OFF(0)
ypos = 25;
width = 90;
height = 20;

// iterate number of toggle buttons         
for ( toggleID = 1; toggleID <= numbuttons; toggleID++ ) 
{  
	toggletext = VarGetText( "toggletext" + toggleID );	
	
     GuiToggle( StrExtract(toggletext, 0),  toggleID,  x =  10,    y = (toggleID-1)*(height+5) + ypos,   width, height, notifyflag = 1 );
    GuiSetColors(1,3,0,  colorWhite, colorRed, 0,   colorWhite, colorGreen, 0, colorWhite, colorGold, 0 );
	staticname = StrFormat( "GuiParamToggle_%s_%g_%g", GetDatabaseName(), GetChartID(), toggleID );
	staticget = Nz(StaticVarGet( staticname ), initial);
	GuiSetCheck(toggleID, staticget);

	togglecheck = GuiGetCheck(toggleID); 
	VarSet( "toggle" + toggleID, togglecheck );

	if ( togglecheck ) GuiSetText( StrExtract(toggletext, 1), toggleID ); 

	if ( GuiGetEvent( 0, 0 ) == toggleID && GuiGetEvent( 0, 1 ) == 1 ) {
		StaticVarSet( staticname, 1-togglecheck, persist );	
		//Say( "Toggle " + StrExtract(toggletext, 1-togglecheck) ); 
		        RequestTimedRefresh(1);
	} 
}
// END  Code for toggle buttons

//GuiTrigger for Removing All Tags
function xGuiTrigger( text1, idset, x, y, width, height, notifyflag )
{		
    local event, id,  ONOFF;    global GuiTriggerStaticName;
    GuiButton( text1, idset, x, y, width, height, notifyflag );
    id = GuiGetEvent( 0, 0 );   event = GuiGetEvent( 0, 1 );

    GuiTriggerStaticName = StrFormat( "xGuiTrigger_%g_%g",GetChartID(), idset );
    ONOFF = Nz( StaticVarGet( GuiTriggerStaticName ), 0 );

    if( id == idset && event == 1 ) {  StaticVarSet( GuiTriggerStaticName, 1 );    }
		RequestMouseMoveRefresh();
    return ONOFF;
}

ONOFF6 = xGuiTrigger( "Remove All", 6, 10 , 75, 90, 20,  1 );
GuiSetColors(6,6,0,  colorWhite, colorRed, 0,   colorWhite, colorDarkRed, 0, colorWhite, colorGold, 0 );
// END  Code for trigger button

// a custom GFX Function to draw lines and text together
function GfxDrawOneLine( text1, text2, x1, y1, x2, y2 , color )
{
	GfxSetBkMode(1);   
    GfxSelectPen( color );
    GfxMoveTo( x1, y1 );
    GfxLineTo( x2, y2 );
    GfxSetTextColor(Color); 
    GfxTextOut( text1, x1, y1 );
    GfxSelectFont( "Calibri", 12 );
    GfxTextOut(  text2, x2+1, y2+y2*0.001 );  
}

bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );
bis = SelectedValue( bi );
SetBarsRequired(-2,-2);


symbol = Name();
tframe = Interval();
chartID = GetChartID();  // if you like this afl to share with other charts please Disable this line
XStaticName = "X" + chartID + symbol + tframe;  
YStaticName = "Y" + chartID + symbol + tframe;

b = GetCursorMouseButtons();
//"Enable Click" button should be green
if( b & 8 ) // flag = 8 is set when window just received mouse click
{
    if( toggle1 )  
    {
        x = GetCursorXPosition( ); 
        y = GetCursorYPosition( );
        StaticVarSet( XStaticName + bis, x );  
        StaticVarSet( YStaticName + bis, y );  
    }
}

j = 0;			
dt = DateTime();
shapePos = Null;
xx = yy = Null;

for ( i = 1; i <=  lvb; i++ )
{
   x = StaticVarGet( XStaticName + i );
   y = StaticVarGet( YStaticName + i );

   if ( x == dt[i] )  
   {
       shapePos = IIf(abs(H[i]-y) < abs(L[i]-y), H[i], L[i]);   
       xx[j] = i;
       
       yy[j] = IIf(abs(H[i]-y) < abs(L[i]-y), H[i], L[i]);   
        yyColor[j] = IIf(abs(H[i]-y) < abs(L[i]-y), colorGreen, colorRed)   ; 
              
       OC[j] =    IIf( shapePos ==H[i] AND C[i] > O[i],   C[i],  O[i]  OR   IIf(shapePos == L[i] AND C[i] < O[i],  C[i],  O[i] ));     //THIS SELECTS OPEN OR CLOSE     
       OCcolor[j] =    IIf( shapePos==H[i] AND C[i] > O[i], colorBlue, colorGrey40   ) OR IIf( shapePos==L[i] AND C[i] > O[i], colorBlue,colorGrey40)  ;     
       j++;          
         }
	}
	
GfxSetOverlayMode(1);  
GfxSetCoordsMode(1); 


for( i =1; i <= j   ; i++ )
{
   
      HLletter= writeif(yyColor[i - 1]==colorgreen,"H= ", "L= " ); // Letters of H or L 
     GfxDrawOneLine(  "", StrFormat( HLletter+" %g",yy[i - 1]), xx[i - 1], yy[i - 1], BarCount - 1+5, yy[i - 1] , yyColor[i - 1] );
     /*
	 HLletter= writeif(yyColor[i - 1]==colorgreen,"H= ", "L= " ); // Letters of H or L 
     GfxDrawOneLine(  "", StrFormat( HLletter+" %g",yy[i - 1]), xx[i - 1], yy[i - 1], BarCount - 1+5, yy[i - 1] , yyColor[i - 1] );*/
     
     OCletter= writeif(OCColor[i - 1]==colorBlue,"C= ", "O= " );
    GfxDrawOneLine(  "", StrFormat( OCletter+" %g",OC[i - 1]) , xx[i - 1], OC[i - 1], BarCount - 1+5,OC[i - 1] , OCColor[i - 1] );
        
       }
   
// "Enable Click" should be green
//    "Remove Selected" should be green, To remove any one tag, first select that tag (left click on that  bar), then click the middle button

if( b & 8 ) 
{
    if( b & 4 AND Toggle2 )   
    {
        for( i = fvb ;    i < BarCount;   i++ )
        {
            x = StaticVarGet( XStaticName + i );
            y = StaticVarGet( YStaticName + i );

            if( x == dt[i] )
            {
                StaticVarRemove( XStaticName + bis);
                StaticVarRemove( YStaticName + bis  );
            }
        }
    }
}

// Remove ALL Static Variable  --- 
if( ONOFF6 == 1 ) 
{
         StaticVarRemove( XStaticName+"*" );
        StaticVarRemove( YStaticName+"*" );
        RequestMouseMoveRefresh();
        StaticVarSet( GuiTriggerStaticName, 0 ); 
}        
_SECTION_END();


Hello
I think the you logic of iif is correct, I did-not have the time for debugging with _Trace() to find out why that happens

But if you replace those 2 lines 135 and 136,with your ones will be fine. For now

       OC[j] = IIf(abs(O[i]-y) < abs(c[i]-y), O[i], C[i]);
       OCcolor[j] =  IIf(abs(O[i]-y) < abs(C[i]-y), colorBlue, colorOrange)   ; 

Also replace the line 154

     OCletter= writeif(OCColor[i - 1]==colorBlue,"O= ", "C= " );

happy end :roll_eyes:

2 Likes

Hi,

Of course it works, once again thanks a ton.
To understand why my simple logic does not work I will also try to use the _Trace function.
I have seen _Trace function used in many posts but do not understand it, will try to learn its practical application.

I am off for a short holiday, will be back on Monday.

2 Likes

@JEETU good idea!

_TRACE () and _TRACEF () will soon be your best friends to speed up your learning and understanding of the AFL.

I use them extensively (see some usage examples) and in combination with explorations, they are the essential everyday tools to debug my code.

6 Likes

can you post the working full code again?

The one you posted is not working.

@JEETU before you move on, you should take care of some efficiency issues in your code. I won't modify your code, because I would approach many things differently. For example I wouldn't use GuiButtons - your code would be simpler and shorter without them. I would use only Ctrl + Left mouse button and Middle mouse button. In it's current form your code is very ineffcient because (among other issues):

  1. Using SetBarsRequired(-2,-2) you are forcing amiBroker to use all bars instead of only visible ones. So if for example your database has 500 000 records, and let's say only 300 are currently visible on the screen and another 300 currently invisible bars are needed to calculate properly some indicators etc., you are forcing Amibroker to do calculations on more than 499 000 unnecessary bars! Read here about the advantages of QuickAFL:

http://www.amibroker.com/kb/2008/07/03/quickafl/

If for some reason you would need your code to behave the same way as using SetBarsRequired(sbrall) when working on a subset of array instead of all bars it is also possible with the use of Status( "quickaflfirstdatabar") --> Example. This solution (which I learned from Fxshrat) was also used in the Spiral example.

  1. Using RequestTimedRefresh(0.1, True) you are forcing Amibroker to repeat all calculations 10 times per second! That's 600 times per one minute! In case of your code, there's no single reason to do that!

  2. What's more, you are additionally using RequestMouseMoveRefresh() which is also completely unnecessary in your code! This function is great if you for example want to draw an object and want to see how it changes size "live" (as it was with the logharitmic spiral example) or how it moves when you drag it. You are just plotting "static "horizontal lines, so you really don't need this function. In your case it just forces lots of unnecessary refreshes...

Your code should be working properly without any regular or additional refreshes even if you are using Gui Buttons with changing text etc. The same applies when you are removing/deleting the lines. Change the order in your code. First evaluate what lines should be plotted or removed and only then plot them or not. Not the other way around. This way you won't need any additional refreshes, but if for any reasons (which I really don't see) you would need an additional refresh after i.e. clicking something, you can enforce just one, single additional refresh this way:

if (MouseButtonClicked) RequestTimedRefresh(0.1);

If you use it this way - just one additional refresh will be applied conditionally - in this example after you click a mouse button. As a result you will get two refreshes - one regular (provided by AB) when clicking the button and after that, one additional.


If you want to get some insights how efficient your code is and how many bars it uses, I can recommend you trying two built-in functionalities:

  1. Click Tools --> Preferences --> Miscellaneous --> Display chart timing (advanced). As a result you will see some interesting readings in the bottom part of each chart:

Image%201

  1. Go to AFL Formula Editor and click Tools --> Code Check & Profile. You will see interesting summary:

Image%202

In your case it shows, that according to the Code check & Profile you are forcing AmiBroker to use StaticvarGet() 100 000 times - (only 50 000 bars were used during this test) - so it clearly indicates, that you are definitly using StaticVars in a wrong way. You only need one or a few Static Variables, not thousands ...

I also recommend reading these articles:

https://www.amibroker.com/guide/x_performance.html
https://www.amibroker.com/guide/h_multithreading.html


Summing up - AmiBroker is an extremely fast and efficient program, but even AB might choke when feed with badly written formula :wink:

8 Likes

Take @Milosz advice very seriously. Really calling StaticVarGet 100000 times is absurd. Do NOT do that.

2 Likes

@JEETU because (in my opinion) your code seems too complicated for what it does, you can analyse my example code. It is four times shorter than yours and very light (just one static variable, no additional refreshes of any kind etc.) How to operate it:

  1. Ctrl + Left Mouse Button --> Select spots
  2. Ctrl + Middle Mouse Button --> Clear selected spots
  3. Ctrl + Middle Mouse button on the right axis (Y/Price) area --> Delete all spots

Lines2

_SECTION_BEGIN("Horizontal Lines - Mouse click");

/// @link https://forum.amibroker.com/t/help-with-iif-function-in-a-loop-how-to-check-if-the-code-is-efficient/7187/7
// By --- Miłosz Mazurkiewicz ---

Title = " Ctrl + Left Mouse Button --> Select spots    |    Ctrl + Middle Mouse Button --> Clear selected spots    |   Ctrl + Middle Mouse button on the right axis area --> Delete all spots";
LookBackPeriod = 500;
SetBarsRequired( LookBackPeriod );
IdSet = Name() + Interval() + GetChartID();
ConditionArray = Nz( StaticVarGet( "ConditionArray" + IdSet ) );
bi = BarIndex();

MouseButtonPressed = GetCursorMouseButtons();
CtrlPressed =  GetAsyncKeyState( 17 ) < 0 ;
x = GetCursorXPosition( 0 ); y = GetCursorYPosition( 0 );

if( CtrlPressed )

{
    x = LastValue( ValueWhen( x == DateTime(), bi ) );
    
    if( MouseButtonPressed & 8 )  ConditionArray[x] = 1; // LMB --> Select spots
    if( MouseButtonPressed & 4 ) ConditionArray[x] = 0; // MMB --> Delete selected spots
    if( MouseButtonPressed & 4 AND x == 0 AND IsEmpty( y ) ) ConditionArray = 0; // MMB on the right axis area --> Delete all spots
    StaticVarSet( "ConditionArray" + IdSet, ConditionArray, persist = False );
}

fvbi = Status( "firstvisiblebarindex" ); lvbi = Status( "lastvisiblebarindex" );
pxchr = Status( "pxchartright" );

GfxSetZOrder( -1 );
GfxSelectFont( "Arial Narrow", 9, 700, False );

Start = Max( 0, fvbi - LookBackPeriod ); End = Min( lvbi, BarCount - 1 );

for( i = Start; i <= End ; i++ )
{
    if( ConditionArray[i] )
    {

        if( C[i] > O[i] ) Color = colorGreen;
        else if( C[i] < O[i] ) Color = colorRed;
            else Color = colorBlue;

        Spot = C[i];
        GfxSetCoordsMode( 1 ); GfxSelectPen( Color, 2);
        GfxSelectSolidBrush( Color );
        GfxCircle( i, Spot, -5 );
        GfxMoveTo( i, Spot ); GfxLineTo( lvbi , Spot );
        GfxSetCoordsMode( 2 );
        GfxSetTextColor( Color );
        GfxTextOut( "" + Spot, pxchr + 3, Spot );
    }
}

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

_SECTION_END();

I used some ideas from my two prior posts: Post 1 and Post 2

You need to modify it according to your needs. The way in which the lines are colored is just an example. You may use Ctrl + mouse bottons clicks approach (it might require some practice) or if you don't like it, get back to Gui Buttons... Change StaticVarSet persist parameter to True or "1" if you want to retrieve the lines after AmiBroker's restart.

My objective was just to show another, simpler approach and some ideas in general so don't treat it as a finished solution.

15 Likes

Samething using only ctrl + left mouse

/// @link https://forum.amibroker.com/t/help-with-iif-function-in-a-loop-how-to-check-if-the-code-is-efficient/7187/7
// By --- Milosz Mazurkiewicz ---
// minor changes by Anderson Wilson

Title = " Ctrl + Left Mouse Button on chart --> Select/Clear selected spots    |   Ctrl + Left Mouse Button on the right axis area --> Delete all spots";
LookBackPeriod = 500;
SetBarsRequired( LookBackPeriod );
IdSet = Name() + Interval() + GetChartID();
ConditionArray = Nz( StaticVarGet( "ConditionArray" + IdSet ) );
bi = BarIndex();

MouseButtonPressed = GetCursorMouseButtons();
CtrlPressed =  GetAsyncKeyState( 17 ) < 0 ;
x = GetCursorXPosition( 0 );
y = GetCursorYPosition( 0 );

if( CtrlPressed )
{
    x = LastValue( ValueWhen( x == DateTime(), bi ) );
    
    if( MouseButtonPressed & 8 )  // LMB --> Select spots
	{
		if( x == 0 AND IsEmpty( y ) )
			ConditionArray = 0;
		if( ConditionArray[x] )
			ConditionArray[x] = 0;
		else
			ConditionArray[x] = 1;
		StaticVarSet( "ConditionArray" + IdSet, ConditionArray, persist = False );
	}
}

fvbi = Status( "firstvisiblebarindex" );
lvbi = Status( "lastvisiblebarindex" );
pxchr = Status( "pxchartright" );

GfxSetZOrder( -1 );
GfxSelectFont( "Arial Narrow", 9, 700, False );

Start = Max( 0, fvbi - LookBackPeriod );
End = Min( lvbi, BarCount - 1 );

for( i = Start; i <= End ; i++ )
{
    if( ConditionArray[i] )
    {

        if( C[i] > O[i] ) Color = colorGreen;
        else
            if( C[i] < O[i] ) Color = colorRed;
            else Color = colorBlue;

        Spot = C[i];
        GfxSetCoordsMode( 1 );
        GfxSelectPen( Color, 2 );
        GfxSelectSolidBrush( Color );
        GfxCircle( i, Spot, -5 );
        GfxMoveTo( i, Spot );
        GfxLineTo( lvbi , Spot );
        GfxSetCoordsMode( 2 );
        GfxSetTextColor( Color );
        GfxTextOut( "" + Spot, pxchr + 3, Spot );
    }
}

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

6 Likes

Yes, of course I agree with you @awilson. I don't know why I have decided to additionally use Middle Mouse Button in this case :thinking: Using only Left mouse button is a simpler and better choice...

Thanks :slight_smile:

4 Likes

missed else if , corrected

/// @link https://forum.amibroker.com/t/help-with-iif-function-in-a-loop-how-to-check-if-the-code-is-efficient/7187/7
// By --- Milosz Mazurkiewicz ---
// minor changes by Anderson Wilson

Title = " Ctrl + Left Mouse Button on chart --> Select/Clear selected spots    |   Ctrl + Left Mouse Button on the right axis area --> Delete all spots";
LookBackPeriod = 500;
SetBarsRequired( LookBackPeriod );
IdSet = Name() + Interval() + GetChartID();
ConditionArray = Nz( StaticVarGet( "ConditionArray" + IdSet ) );
bi = BarIndex();

MouseButtonPressed = GetCursorMouseButtons();
CtrlPressed =  GetAsyncKeyState( 17 ) < 0 ;
x = GetCursorXPosition( 0 );
y = GetCursorYPosition( 0 );

if( CtrlPressed )
{
    x = LastValue( ValueWhen( x == DateTime(), bi ) );
    
    if( MouseButtonPressed & 8 )  // LMB --> Select spots
	{
		if( x == 0 AND IsEmpty( y ) )
			ConditionArray = 0;
		else if( ConditionArray[x] )
			ConditionArray[x] = 0;
		else
			ConditionArray[x] = 1;
		StaticVarSet( "ConditionArray" + IdSet, ConditionArray, persist = False );
	}
}

fvbi = Status( "firstvisiblebarindex" );
lvbi = Status( "lastvisiblebarindex" );
pxchr = Status( "pxchartright" );

GfxSetZOrder( -1 );
GfxSelectFont( "Arial Narrow", 9, 700, False );

Start = Max( 0, fvbi - LookBackPeriod );
End = Min( lvbi, BarCount - 1 );

for( i = Start; i <= End ; i++ )
{
    if( ConditionArray[i] )
    {

        if( C[i] > O[i] ) Color = colorGreen;
        else
            if( C[i] < O[i] ) Color = colorRed;
            else Color = colorBlue;

        Spot = C[i];
        GfxSetCoordsMode( 1 );
        GfxSelectPen( Color, 2 );
        GfxSelectSolidBrush( Color );
        GfxCircle( i, Spot, -5 );
        GfxMoveTo( i, Spot );
        GfxLineTo( lvbi , Spot );
        GfxSetCoordsMode( 2 );
        GfxSetTextColor( Color );
        GfxTextOut( "" + Spot, pxchr + 3, Spot );
    }
}

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


6 Likes

Hi,

Trying to get back home! Can not because the road is blocked!

Looks like the whole mountain has come down due to rain, the locals say that it is like this in many places!
So an extended holiday, but that is another topic.

YOU GUYS ARE GREAT OR WHAT !!! So much to learn, for the time I am just going to click "like this post"
for all , more when I am back home !!

2 Likes

Hi,

Thanks a lot for your guidance.
It is another step in my learning curve - will go though the steps you have mentioned and hopefully progress
to writing more efficient codes.

Trying to learn and with no programme writing experience a bit of a stuggle, slowly will get there.

Hi,

Have copied your code and tried it - no clue as to the AFL used to effectively use only the left button -
very interesting - will have to try and understand the method of coding.
Thanks a lot for sharing.

Hello
Jeetu in the afl that milosz and awilson provide you must use it by pressing the control CTRL button in the keyboard and then left mouse click.

I know for your final project you need about 20 buttons, as you have 20 different cases.
For ALL in ONE afl you cannot use only the CTRL + left click, but also you need toggle buttons to control every individual case differently. Also without buttons you are going to lost, if was me I will not remember what job of witch X keyboard key + left click is doing

I really agree with Milosz that is nice to keep one thread to ask your question as it is about “about clicking” -> store a value to staticvar or matrix -> do the calculation and print the results to the chart
This will be nice thread also for new users without any coding background to read and learn.

@Milosz and @awilson I really enjoy your team work.... I may join on this.
And as I am talking for team work I can see one line of the code that I don’t understand why you did not use SelectedValue(bi) ?

   // x = LastValue( ValueWhen( x == DateTime(), bi ) );
    x = SelectedValue(bi);

have a nice day

1 Like

hi
I just comment the lines that i don’t think we need

if( CtrlPressed )
{
   // x = LastValue( ValueWhen( x == DateTime(), bi ) );
    x = SelectedValue(bi);
    
    if( MouseButtonPressed & 8 )  // LMB --> Select spots
	{
		//if( x == 0 AND IsEmpty( y ) )
		//	ConditionArray = 0; 
		//else 
		
		if( ConditionArray[x] )
			ConditionArray[x] = 0;  
		else
			ConditionArray[x] = 1; 
		StaticVarSet( "ConditionArray" + IdSet, ConditionArray, persist = False );
	}
}
1 Like

@Panos, did you check your version carefully? It doesn't seem to be working properly for two reasons:

  1. You can not remove all lines at once clicking on the right axis area
  2. Using SelectedValue() is a less robust solution comparing to GetCursorXPosition() because it doesn't work as expected when the line selector disappears (which sometimes happen - when you for example click twice, click between bars etc.) GetCursorXPosition() works allways as expected. It returns x coordinates either in screen pixels or in DateTime(). For this reason I have used this line:
x = LastValue( ValueWhen( x == DateTime(), bi ) );

I will get back to this tomorrow, because currently it is 1:45 a.m. in Poland ...

3 Likes

Hi,

This reply is addressed to all, apart from me = who is only asking questions !!!
Great to see the masters discussing a topic, newbies like me will definitely learn from your discussions.

Now to the point made by @Milosz and @Tomasz w.r.t. the in-efficiency of the AFL code , I will definitely
give it the due attention. But for now I am more inclined to go ahead and work towards my goal, unless the
AFL code I use really - VISUALLY - slows the execution.

The point made by @PanoS is correct, thinking about the "range" selections required - I am inclined to go with
with a total of 10 ranges (3=internal retracements(6 clicks) , 3=external retracements(6 clicks) / extensions and 4=projections ( 4 x 3 =12clicks) ; total = 24clicks !!

Really mind boggling for me .

Did some work with the code from @beppe, basically just changed the visual look, added 23.6% for internal retracement .

List of TO DO TASKS---
/[1]. TO DO = I SHOULD BE ABLE TO DECIDE WHAT ANY SELECTED RANGE (2 BARS=INTRET OR EXRET // 3 BARS = PROJECTION)
PLOTS . AT PRESENT WHAT I SELECT WITH PARAMTOGGLE IS PLOTTED FOR ALL RANGE SELECTIONS,ie. IF I SELECT
"intret" WITH PARAMTOGGLE AND USE 3 RANGES THEN ALL 3 WILL PLOT ONLY "inret". I SHOULD BE ABLE TO DECIDE
WHAT PLOTS (intret / exret or projection) FOR EACH RANGE . use GUI or AFL? INCREASE RANGE SELECTION FROM PRESENT "3"
/

/* [2]. TO DO = DELETE ANY SELECTED RANGE (intret, exret or projection). use GUI or AFL?. */

/* [3]. TO DO = REQUIRE "ONLY" CLEAR ALL STUDIES FROM THIS CHART SO REMOVE
"CLEARALL" paramToggle*/

/* 4]. TO DO = START WORKING WITH TIME / BARS --- X-AXIS === HOW TO PLOT AT DIFFERENT "Y-AXIS LEVELS,
FOR Lo to Hi PLOT ABOVE PRICE & FOR Hi to Lo PLOT BELOW PRICE, START WITH 3 STUDIES (3DIFFERENT LEVELS)
FOR EACH */
2 screen capture to clarify point [1] ;

image

image

Once again, thanks to all of you!

@JEETU this is actually my code (modified by @awilson) which I have prepared to show you that the results you were trying to accomplish can be achieved in a simple and effective way. @awilson has very logically noticed (:+1:), that in this case there is no need to use additionally middle mouse button to remove the lines and modified the lines which are responsible for handling mouse clicks. When preparing this code I simply used some parts from my other code where I was also using the middle mouse button and didn't change it - although I should have - because it was very logical. Simplest solutions are usually the best.

The whole idea behind this code is very simple. It uses just one Static variable --> ConditionArray to identify which bars have been selected via Ctrl + LMB click. Initially all array ellements equals 0 (zero). When you select some bar, array element at this place changes it's value to 1 (one). If you click one more time, it changes it's value back to zero.

In the next part of the code, it iterates through all visible bars (plus the lookback period to allow displaying all the lines when the chart is zoomed in or scrolled to the right). If it finds an array element which equals 1 (one) it plots the line and the label. As you can see, the idea is really simple and the code could be even more simplified.

I understand that, but believe me - if you had based your solution on your initial code and started adding next functionalities, you would have shortly hit the wall and start asking on the forum: why my code is getting so slow (or even worse: why Amibroker is so slow :wink: ) or why am I getting strange errors every few minutes? Your code performs a really simple task and does it in a very inefficient way. I pay special attention to the efficiency of my codes and I couldn't accept, that in one code you used SetBarsRequired(sbrall,sbrall) + RequestTimedRefresh(0.1) + RequestMouseMoveRefresh() without a single reason to do so and additionally you were calling even hundreds of thousands Static Variables (when one is enough)!

Whether you are going to use some ideas from this code, or not - is up to you. As I said, I just wanted to show an alternative and much more efficient approach to save you from troubles.

Regards.

3 Likes

Panagioti, I'm not a specialist in Elliott, Fibo, different kind of retracements etc. - I don't use them that often, besides I won't have much free time in the upcoming days, so don't count me in. I'm afraid, I'm not going to embark on this project ...

Best :slight_smile:

1 Like