GfxMoveTo , GfxLineTo | Looking for help trying to get End Point to work

hello every1 ,

Trying to plot multiple horizontal lines using gfx in a loop from a relative high(start) to where it should end if price closes at or above that level in the future(end).

Looking for some help with this code, I'm close what am I missing here? I can get the start point to work but the endpoint is either all the way rIght or all the way Left. I got a somewhat working version where some of the lines worked but others didn't. I'll drop in a couple of images of what it should look like (approximately) and what it is mostly doing now .
thanks

Plot ( C,"",colorWHITE,styleNODRAW);
MAFH = MAFL  = count =xH =xL =yH =yL = SFH =SFL =0;
bi = BarIndex() ; 
start = FirstVisibleValue( bi ); 
end = LastVisibleValue( bi ); 
BC = END-START  ;

fH =  (Ref(H,-2) < H )   AND  ( Ref(H,-1) < H) AND ( Ref(H,1) < H ) AND ( Ref(H,2) < H ) ;
fL =  (Ref(L,-2) > L )   AND  ( Ref(L,-1) > L) AND ( Ref(L,1) > L ) AND ( Ref(L,2) > L ) ;

h0 = ValueWhen ( fh == 1, H  );
x0 = ValueWhen ( fh == 1, bi );

xEnd = Cross( C,h0) ; // C > h0 ; //IIf( C > h0 ,1,0) ;
xEndV =  ValueWhen ( xEnd  == 1, bi ); //IIf(xend==1,   bi,end );

Title = " h0 : " + h0 + "  x0 : " + x0    +  "   BC:" +bi + " true : " + xEnd + " xEndV  : " + xEndV ;

PlotShapes(shapeSmallCircle* fH,colorred,0,h,10);
PlotShapes(shapeSmallCircle* fl,colorgreen,0,L,-10);

GfxSetCoordsMode( 1 ) ; 
GfxSetOverlayMode( 1 ) ; 
 
  for( i = START; i < END; i++ ) // end
{ 

 count = COUNT+1;

 yH = IIf( fH[i]== 1 ,H[i],null) ;
 xH = ValueWhen( fH[i]== 1, i) ;
 xe = Cross(  yH[i],xEnd[i] ) ;
 x1 = ValueWhen( xEnd[i]== 1, i);
 
  
 yL = IIf( fL[i]== 1, l[i],null) ;
 xl = ValueWhen( fl[i]== 1, i) ;
 
GfxSelectPen( ColorRGB(160,10,10) );
GfxMoveTo(  xH[i], yH[i] );  //GfxMoveTo(  xH[i], yH[i] );
GfxLineTo( end,  yh[i] ); //  GfxLineTo( xEND[i],  yH[i] );
// 

//GfxSelectPen( ColorRGB(10,120,10) );
//GfxMoveTo( xL[I], yl[i] ); 
//GfxLineTo( end, yl[i] );
}

This what it looks like more or less.....
Untitled

this what it should kinda look like .......
look like this

As a general comment, it's really hard to follow your code because of the single character and abbreviated variable names.

What I have noticed is your GfxLineTo ( end ... uses the variable end = LastVisibleValue( bi ) which means that all lines will go to the last visible value hence they will all go to the r.h.s of the screen rather than any crossing of the chart.

Hope that helps.

Sorry my entire response to your message got erased , i dunno what happened.
gonna try to rewrite quickly hopefully it works

Thanks
Going to rewrite to make easier to understand shortly....

**xEndV** =  ValueWhen ( xEnd  == 1, bi,-1 ); //IIf(xend==1,   bi,end );

xEndV kinda works, it shows the value true and correct outside the array here the results on Pic

pic1
pic 2

The value changes when scrolled and not sure how to access outside the visible range without using all the candles which I don't want to do. I think I need something more static. I did try to add bars to the start or subtract from the end but the results get wonky.

Any suggestions appreciated,

thank you

Do you mean to change xEndV and then in your GfxLineTo, replace end with xEndV? Can you post the full snippet of what you mean by "xEndV kinda works" if you want to get help debugging your code.

Also, the willingness of ppl to take time to debug your code is likely linearly correlated to how readable your code is.

At this point, I would suggest if you have the starting point of a line, and you want to find the bar at which this line intersects with a candle, then what you're looking for is:

function endOfLine(startingBar, startingPrice) {
  for (i = startingBar; i < BarCount; i++) {
    if ( startingPrice >= Low[i] && startingPrice <= High[i]) break;
  }
  return i;
}

You can prolly find simpler ways of expressing the above but that seems to be the gist of what you're trying to achieve.

I re-wrote the code to make it more clear hopefully.
thanks for all your time...

I am trying to define the 2nd "x" value. The 1st X / Y value is the Barcount / "High" value of the bar the fractal is true. So (X0,Y0) and Y1(horizontal line) is good to go. I am having great difficulty trying to define X1 in the array. That Value should be when the Y0 Value which is a relative high gets touched again in the future. X1 = when Y1 (Price) >= the initial Y0( H) that should define the second barcount value (X1) . So the horizontal line would be from the High of the fractal til it ends when price touches it again or continues if price doesn't reach it. The 2nd pic from top shows a hand drawn version which is closest to what it should look like although I missed drawing a line from a relative high and to the right at around ~29.32.

Plot ( C,"",colorWHITE,styleCandle);
count =0 ; ll = 0 ;
bi = BarIndex() ; 
FVV = BeginValue(bi )  ;   // FirstVisibleValue( bi ); 
LVV = LastValue(bi ) ; //  LastVisibleValue( bi ); 
BC = lvv - fvv ;

Fractal_High =  (Ref(H,-2) < H )   AND  ( Ref(H,-1) < H) AND ( Ref(H,1) < H ) AND ( Ref(H,2) < H ) ; // general High Rejection
Fractal_Low  =  (Ref(L,-2) > L )   AND  ( Ref(L,-1) > L) AND ( Ref(L,1) > L ) AND ( Ref(L,2) > L ) ; // general Low Rejection

Y_END_Value = Cross( C,Fractal_High) ; 
X_END_Value = BarsSince(Fractal_High) ;
//Title = " h0 : " + h0 + "  x0 : " + x0    +  "   BC: " +bi + " true : " + xEnd + " xEndV  : " + xEndV ;

PlotShapes(shapeSmallCircle* Fractal_High,colorred,0,h,10);
PlotShapes(shapeSmallCircle* Fractal_Low,colorgreen,0,L,-10);

GfxSetCoordsMode( 1 ) ; 
GfxSetOverlayMode( 1 ) ;
 
  for( i = LVV; i > lvv-200; i-- )
    
{
 count = COUNT+1;
if( i > count) 
{

 X0 = ValueWhen( Fractal_High[i]== 1, i);
 Y0 = IIf( Fractal_High[i] == 1 ,H[i],null) ; 
 X1 =   x0[i] +   ValueWhen( y0[i] > C[i-count] , count)    ;
 Y1 = y0[i];
 
GfxSelectPen( ColorRGB(200,10,10) );
GfxMoveTo(  X0[i], Y0[i] );
GfxLineTo( x1[i],  y0[i]);

}
}

It is recommended to read first this
https://www.amibroker.com/guide/h_understandafl.html

In your code you are using array functions incorrectly (inside loop and with scalar input).

For example this:

ValueWhen( Fractal_High[i]== 1, i);

is wrong because both inputs are scalars (single value). With scalar value there is no "history". ValueWhen works with arrays.

See:

and this:

You should start using debugger and use Watch window to display variable types and values, use advice given here: How do I debug my formula?

I copy/pasted your code onto my chart and got no lines.

Your for loop and if condition is weird. You're counting down from LVV and up from count. I don't know if this is intentional but for arguments' sake, let's say LVV is 300.

  for( i = LVV; i > lvv-200; i-- )
    
{
 count = COUNT+1;
if( i > count) 

-- becomes

  for( i = 300; i > 100; i-- )
    
{
 count = COUNT+1; // count starts at 0
if( i > count) 
{

-- becomes 

for ( i = 150 ; i > 100 ; i-- )

-- ie, this has the same effect without the if condition

for ( i = (LVV - count) / 2 ; i > LVV - 200; i-- )

The debugger is a great tool for newbies to understand what it is that you're creating and looping through. I spent 2 weeks just stepping through functions and matching it to the charts to understand exactly what was happening.

As Thomaz pointed out, you're doing array operations in a loop, not sure if that's the intention, it could well be because you're iterating down the value at a bar, but even that loop seems strange.

Lastly, LVV is the LastValue, which is the price, but you're using it to reference Fractal_High which is a boolean array of the bar at which a high/low is found. So there's a lot in that code that does not make any sense. Prolly best for you to debug this step by step, look at the variables you're creating and confirm they are in fact what you expect.

G'luck!

I read the array article and have a basic understanding of the difference between the array and the individual element but implementing it is where my lack of programming skill really stands out. I think the debugging is where I need to explore ( Ty Ty for the link) as I use the title / selected value , as a simpleton’s debugger outside the array but inside have no clue the actual movements of what’s going on. I’ll study that a bit and hopefully come up with a better understanding and solution soon. And thank you for making the best charting program in the world . I started using it back around y2k for a couple years then took about 18 years off and picked it up again . A lot more squinting nowadays but chugging along.
Thank you for the help.

I tried running the array from left to right and right to left , tried adding and subtracting elements and values from and to the x0 , x1 and something fundamental I’m just not getting. I used the lastvalue with (+ … -) references . With some stuff happening but all a little wonky. I should be able to read up on the debugging later today and Try to figure out what that endofline function does. It was really late and my brain was spent. A lot of the code examples I try to understand, and many times I just accept parts for what they are and the results they give, as my ability of programming is not so good.
There is a lot from you and tomasz I need to reread study and hopefully soon have a clearer understanding.
Thankyou for your precious time.

There is a lot to understand with Amibroker and AFL. I would suggest having that script of yours with the debugger window open side by side on the watch tab, watch all your variables, have breakpoints set on each line and just confirm what you expect to happen is actually happening on each line.

It took me a while to get, and it's slow going at first, but once I understood it, it was much easier to make Amibroker do what I wanted. Array programming was actually trivial, the only complexity was in my head. The debugger was a great help to me.

1 Like

Hi, I went threw the debug part 1 and was wondering in the above quote are you referring to the Exploration widow or is there an additional debug widow that can be used?

I did a debug set up with the help from the articles Tomasz linked and it was extremely helpful and hope my code is improving . I did get more positive results even though not complete. I believe the next step will be adding another step in the loop to draw the starting point to the far right if the ending line isn't triggered which is the case many times . I'm just not to sure if there is some obvious simple 1 or 2 line code or loop or something that can be added. This is the 1st time I am doing an array in array but having multiple start signals and less end signals made it difficult for me to work around that with my limited capacities in programming.
Here's an update on the code and a couple pics. thanks for all the help

Plot ( C,"",colorWHITE,styleCandle);
Fractal_High =  (Ref(H,-2) < H )   AND  ( Ref(H,-1) < H) AND ( Ref(H,1) < H ) AND ( Ref(H,2) < H ) ; // general High Rejection
Fractal_Low  =  (Ref(L,-2) > L )   AND  ( Ref(L,-1) > L) AND ( Ref(L,1) > L ) AND ( Ref(L,2) > L ) ; // general Low Rejection
PlotShapes(shapeSmallCircle* Fractal_High,colorred,0,h,10);
PlotShapes(shapeSmallCircle* Fractal_Low,colorgreen,0,L,-10);

bi = BarIndex() ; 
FV = FirstVisibleValue( bi ); 
LV = LastVisibleValue ( bi ); 

cond_Start = Fractal_High ==1;
BarCount_Start = ValueWhen( cond_Start ==1, bi,1) ;
Price_Start = ValueWhen( cond_Start ==1, H,1) ;

Cond_END = Cross(  H, Price_Start );
BarCount_END = ValueWhen( Cond_END ==1,BI,1) ;  
Price_END = ValueWhen( Cond_END==1 , H,1) ;

GfxSetCoordsMode( 1 ) ; 
GfxSetOverlayMode( 1 ) ;
GfxSelectPen( ColorRGB(200,10,10) );
 
  for( i = FV; i < LV; i++ )   
{

Move_to_Start = cond_Start[i];
y0 = Price_Start[i] ;
x0 = BarCount_Start[i] ;

	if( Move_to_start==1 )
	{
		GfxMoveTo( x0 , y0 );

				for( j = i; j < LV; j++ )
				{

					Move_to_End = cond_End[j];
					
					if( Move_to_End ==1 )
					{
					y1 = Price_END[j] ;
					x1 =  BarCount_End[j] ;
					GfxLineTo( x1 ,  y0[j] );
					break;
					}
		
					
				}
			
	}
} 
 
 
 



 
 
 
 
 
 Filter = 1; // show all bars

bi = BarIndex();
Fractal_High =  (Ref(H,-2) < H )   AND  ( Ref(H,-1) < H) AND ( Ref(H,1) < H ) AND ( Ref(H,2) < H ) ; // general High Rejection
Fractal_Low  =  (Ref(L,-2) > L )   AND  ( Ref(L,-1) > L) AND ( Ref(L,1) > L ) AND ( Ref(L,2) > L ) ; // general Low Rejection



cond_Start = Fractal_High ==1;
BarCount_Start = ValueWhen( cond_Start ==1, bi) ;
Price_Start = ValueWhen( cond_Start ==1, H) ;

Cond_END = Cross(  H, Price_Start );
BarCount_END = ValueWhen( Cond_END ==1,BI) ;  
Price_END = ValueWhen( Cond_END==1 , H) ;


//
AddColumn( bi, "BarIndex" );
AddColumn( C, "Close" );

AddColumn( cond_Start, "Start Value true ?" );
AddColumn( BarCount_Start, "BarCount @ Start");
AddColumn( Price_Start, "Price High @ Start");

AddColumn( cond_END, " End Value true ?");
AddColumn( BarCount_END, "BarCount @ END");
AddColumn( Price_END, "Price High @ END");

Pic 4-1
4-2

There is working code already

@ak47 I'm not talking about Scan, Explore or Backtest in your Analysis Window.

In your formula editor, you can set breakpoints, then start debugging which steps through your code. Using the Window -> Watch window, you can watch how your variables change as you execute each line of code.

Please refer to Tomasz's link above about how do I debug my formula, specifically step 6, How to use AFL debugger

image

Thanks , that looks super helpful. ty much !

The code is at another level ! TY sir. I'll need a few weeks to process that and all the all the information from every1 . ( And I though I was close to finishing ) lol.

thank you all

HI, I just wanted to thank every1 for the help and fxshrat for the absolutely amazing code from "plot horizontal line until crossed" Just as a side note as my understanding of the code is highly limited I was able to modify it to work with upper limits. Here is a working version of Upper limit horizontal line til crossed. Hope someone finds this useful in the future , I struggled with the concept for few months .

function fxMxStopLinesUpper(sig, targetarray) {
Version(6.0);
// by fxshrat@gmail.com  <==== GOD programmer lives amongst us mere mortals , modded to work on Upper targets by ak
// Initialize variables
// Only consider bars that are currently visible on the chart
bir = Status("barvisible"); // chart area array
// Get cumulative sum of sig array where bir is true, and last visible value
cums = Cum(IIf(bir, sig, 0));
lastcum = LastVisibleValue(cums);
// Initialize stop_mat matrix with 3 rows (start bar, end bar, level) and maximum of 1 or lastcum columns
stop_mat = Matrix(3, Max(1, lastcum), 0);
colnum = MxGetSize(stop_mat, 1);

// Loop through all bars
for (i = 0, n = 0; i < BarCount; i++) {
if (bir[i]) {
// If sig[i] is true, add line to stop_mat
if (sig[i]) {
if (n < colnum) {
stop_mat[0][n] = i; // start bar
stop_mat[1][n] = BarCount - 1; // end bar
stop_mat[2][n] = targetarray[i]; // level
// Find first bar where High value crosses the line
for (j = i; j < BarCount; j++) {
if (H[j] > stop_mat[2][n]) {
stop_mat[1][n] = j; // end bar
break;
}
}
}
n++;
}
}
}

printf( "#lines: %g, BarCount: %g", colnum, BarCount );
	//GfxSelectPen( colorgreen, 1, 0 );	
	for ( n = 0; n < colnum; n++ ) {
		GfxMoveTo(x1 = stop_mat[0][n], y = stop_mat[2][n] );
		GfxLineTo(x2 = stop_mat[1][n], y ); 
		//GfxTextOut(StrFormat("%g", y), x2+0.25, y ); 
		//GfxTextOut(StrFormat("%g bars", x2-x1), x2+0.25, y );    
	}
	return stop_mat;
}

Hope the comments help and are correct(?). This is my limited take on whats going on, feel free to make corrections .

I used for the target array targetarray_L = LLV(L,1); and the HHV equivalent for the upper. the signal is whatever you want like a Cross etc.

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