Modified Square drawing to be explorable , need help

Hi All,

I try to modify the code i found here in this forum , The original code works in new amibroker .
The original code use for drawing square by pressing 'Ctrl' held down and 'Mouse left button' down sets the co-ordinates of A. While in this state of Ctrl and Mouse left button down, drag the mouse for point B. Upon releasing either Ctrl or Mouse left button, locks the co-ordinates of B.

it looks like this :

Screenshot_76

the original code :

// To convert from Bar (on X-axis) and Price (on Y-axis) to pixel co-ordinates
// Link: http://www.amibroker.com/kb/2009/03/30/how-to-convert-from-bar-value-to-pixel-co-ordinates/
Miny = Status( "axisminy" );
Maxy = Status( "axismaxy" );
lvb = Status( "lastvisiblebar" );
fvb = Status( "firstvisiblebar" );
pxchartleft = Status( "pxchartleft" );
pxchartwidth = Status( "pxchartwidth" );
pxchartbottom = Status( "pxchartbottom" );
pxchartheight = Status( "pxchartheight" );
function XtoPxX( bar ) { return pxchartleft + ( bar - fvb ) * pxchartwidth / ( lvb - fvb + 1 ); }
function YtoPxY( value ) { return pxchartbottom - floor( 0.5 + ( value - Miny ) * pxchartheight / ( Maxy - Miny + 1e-9 ) ); }

function RadToDeg( x ) {
	 pi = atan( 1 ) * 4;
	 return x * ( 180 / pi ); //Angle is calculated in radians, thus converting it to degrees
}

_SECTION_BEGIN( "Square off a Trendline" );
	 SetChartOptions( 1, chartShowDates );
	 
	 bi = BarIndex();
	 ChartId = Name() + GetChartId();
	 
	 //////////////////////////////////////////////////////////////
	 ///////////// Capturing co-ordinates of A and B //////////////
	 //////////////////////////////////////////////////////////////
	 LeftMsBtnJustClkd = GetCursorMouseButtons() & 8;
	 LeftMsBtnDownRlsd = GetCursorMouseButtons() & 9;
	 MsMiddleBtnClkd = GetCursorMouseButtons() & 4;
	 
	 x = GetCursorXPosition( 0 );
	 y = GetCursorYPosition( 0 );

	 CtrlPressed = GetAsyncKeyState( 17 ) < 0;
	 if( CtrlPressed ) {
		 if( LeftMsBtnJustClkd ) {
			 StaticVarSet( "Ax" + ChartId, x, 0, False );
			 StaticVarSet( "Ay" + ChartId, y, 0, False );
		 }	
		 if( LeftMsBtnDownRlsd ) {
			 StaticVarSet( "Bx" + ChartId, x, 0, False );
			 StaticVarSet( "By" + ChartId, y, 0, False );
		 }	
		 if( MsMiddleBtnClkd ) {
			 StaticVarRemove( "Ax" + ChartId );
			 StaticVarRemove( "Ay" + ChartId );
			 StaticVarRemove( "Bx" + ChartId );
			 StaticVarRemove( "By" + ChartId );
		 }
	 }
	 //////////////////////////////////////////////////////////////
	 
	 GfxSetZOrder( 0 );
	 GfxSetCoordsMode( 0 );
	 GfxSetBkMode( 1 );
	 GfxSelectFont( "Arial", 8, 400 );
	 GfxSetTextColor( colorLavender );
	 GfxSelectPen( colorBlueGrey, 1, 0 );
	 
	 _Ax = XtoPxX( Lookup( bi, StaticVarGet( "Ax" + ChartId ) ) );
	 _Ay = YtoPxY( StaticVarGet( "Ay" + ChartId ) );
	 _Bx = XtoPxX( Lookup( bi, StaticVarGet( "Bx" + ChartId ) ) );
	 _By = YtoPxY( StaticVarGet( "By" + ChartId ) );
	 
	 
	 if( _Ax > 0 && _Bx > 0 ) {
		 
		 //Finding co-ordinates of C and D (ABCD being a square)
		  dX = _Bx - _Ax;	 		 dY = _By - _Ay;
		 _Cx = _Bx - dY;			_Cy = _By + dx;
		 _Dx = _Ax - dY;			_Dy = _Ay + dx;
		 
		 
		 // Drawing square ABCD
		 GfxMoveTo( _Ax, _Ay );		GfxLineTo( _Bx, _By );
		 GfxMoveTo( _Bx, _By );		GfxLineTo( _Cx, _Cy );
		 GfxMoveTo( _Ax, _Ay );		GfxLineTo( _Dx, _Dy );
		 GfxMoveTo( _Cx, _Cy );		GfxLineTo( _Dx, _Dy );		 
		 
		 // Drawing diagonals of the square ABCD
		 GfxMoveTo( _Ax, _Ay );		GfxLineTo( _Cx, _Cy );
		 GfxMoveTo( _Bx, _By );		GfxLineTo( _Dx, _Dy );
		 
		 // Finding mid-points of the sides of ABCD
		 Px = ( _Ax + _Bx ) / 2;	Py = ( _Ay + _By ) / 2;
		 Qx = ( _Bx + _Cx ) / 2;	Qy = ( _By + _Cy ) / 2;
		 Rx = ( _Cx + _Dx ) / 2;	Ry = ( _Cy + _Dy ) / 2;
		 Sx = ( _Ax + _Dx ) / 2;	Sy = ( _Ay + _Dy ) / 2;
		 
		 // Drawing a square PQRS
		 GfxMoveTo( Px, Py );		GfxLineTo( Qx, Qy );
		 GfxMoveTo( Qx, Qy );		GfxLineTo( Rx, Ry );
		 GfxMoveTo( Rx, Ry );		GfxLineTo( Sx, Sy );
		 GfxMoveTo( Sx, Sy );		GfxLineTo( Px, Py );
		 
		 // Text for co-ordinates
		 GfxTextOut( "A", _Ax, _Ay ); 	GfxTextOut( "B", _Bx, _By );	GfxTextOut( "C", _Cx, _Cy ); 	GfxTextOut( "D", _Dx, _Dy );
		 GfxTextOut( "P", Px, Py ); 	GfxTextOut( "Q", Qx, Qy ); 		GfxTextOut( "R", Rx, Ry ); 		GfxTextOut( "S", Sx, Sy );
		 
		 //////////////////////////////////////////////////////////////
		 /////////////// Proving that ABCD is a square ////////////////
		 //////////////////////////////////////////////////////////////		 
		 // Measuring length of the sides using Distance formula (in pixels)
		 AB = sqrt( dX ^ 2 + dY ^ 2 );
		 BC = sqrt( ( _Cx - _Bx ) ^ 2 + ( _Cy - _By ) ^ 2 );
		 CD = sqrt( ( _Dx - _Cx ) ^ 2 + ( _Dy - _Cy ) ^ 2 );
		 DA = sqrt( ( _Dx - _Ax ) ^ 2 + ( _Dy - _Ay ) ^ 2 );
		 
		 //Finding angle of the vertices of ABCD
		 CAD = atan( CD / DA );		CAB = atan( BC / AB );		/*Hence,*/ DAB = RadToDeg( CAD + CAB );
		 DBA = atan( DA / AB );		DBC = atan( CD / BC );		/*Hence,*/ ABC = RadToDeg( DBA + DBC );
		 ACB = atan( AB / BC );		ACD = atan( DA / CD );		/*Hence,*/ BCD = RadToDeg( ACB + ACD );
		 BDC = atan( BC / CD );		BDA = atan( AB / DA );		/*Hence,*/ CDA = RadToDeg( BDC + BDA );
		 
		 Title =
		 "Proof 1: All sides of ABCD are equal (in pixels)" +
		 StrFormat( "\nAB = %1.2f, BC = %1.2f, CD = %1.2f, DA = %1.2f", AB, BC, CD, DA ) +
		 "\nAB = BC = CD = DA = " + WriteIf( AB == BC && BC == CD && CD == DA, "True", "False" ) +
		 "\n\nProof 2: All vertices of ABCD are of 90°" +
		 StrFormat( "\nDAB = %1.0f°, ABC = %1.0f°, BCD = %1.0f°, CDA = %1.0f°", DAB, ABC, BCD, CDA ) +
		 "\nAngle A = B = C = D = " + WriteIf( DAB == ABC && ABC == BCD && BCD == CDA, "True", "False" )
		 ;
		 
		 
		 Cen1 = (_Ax + _Cx)/2 ; Cen2 = (_Ay + _Cy)/2 ; 
		 rad = sqrt( dX ^ 2 + dY ^ 2 )/2; 
		 r = (sqrt( ( _Cx - _Bx ) ^ 2 + ( _Cy - _By ) ^ 2 ))/1.41;
		 GfxSelectStockObject( 5 ); 
		 GfxCircle(Cen1,Cen2,rad);
		 GfxCircle(Cen1, Cen2,r);
		 
		 //////////////////////////////////////////////////////////////
	 }
	 
	 

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

Right now , i want to modify the code to be exploreable ; by automatic finding valley value ( as point A ) and top value ( as point B ) for determined parameter days , after that generate square chart with point C and D . Filter for point C (in X axis ) if Valley occur first. Filter for point D ( in X axis ) if Top occur first.

it should look like this

Square 1

Square 2

The code i modify is this

Miny = Status( "axisminy" );
Maxy = Status( "axismaxy" );

function GfxConvertValueToPixelY( Value ) 
{ 
 local Miny, Maxy, pxchartbottom, pxchartheight; 

 Miny = Status("axisminy"); 
 Maxy = Status("axismaxy"); 

 pxchartbottom = Status("pxchartbottom"); 
 pxchartheight = Status("pxchartheight"); 
 
 m_m = valueWhen( Maxy - Miny == 0 , 1 );
 return pxchartbottom - floor( 0.5 + ( Value - Miny ) * pxchartheight/  m_m   );
} 

function GfxConvertBarToPixelX( bar ) 
{ 
 lvb = Status("lastvisiblebar"); 
 fvb = Status("firstvisiblebar"); 
 pxchartleft = Status("pxchartleft"); 
 pxchartwidth = Status("pxchartwidth"); 
 
 return pxchartleft + (bar  * pxchartwidth / ( Lvb - fvb + 1 )); 
 } 

bi = Cum(1); 

Bars = Param("Strength",5,2,15,1);

//Find Top
Top = H == HHV(H,2*bars) AND Ref(HHV(H,bars),bars) < H;
Top = Top AND LastValue(bi)-ValueWhen(Top,bi) > bars;
Top_Y = ValueWhen(Top , H );
Top_X = ValueWhen(Top , bi );

//Find Valley
Valley = L == LLV(L,2*bars) AND Ref(LLV(L,bars),bars) > L;
Valley = Valley AND LastValue(bi)-ValueWhen(Valley,bi) > bars;
Valley_Y = ValueWhen (Valley, L );
Valley_X = ValueWhen(Valley , bi );

Ax = IIf( Valley_X < Top_X   , Valley_X , Top_X );
Bx = IIf( Valley_X < Top_X , Top_X  , Valley_X  );
Ay = IIf( Valley_X < Top_X , Valley_Y   , Top_Y );
BY = IIf( Valley_X < Top_X , Top_Y , Valley_Y );

_Ax = Lastvalue(GfxConvertBarToPixelX(Ax))  ;
_Bx = LastValue(GfxConvertBarToPixelX(Bx))  ;
_Ay = LastValue(GfxConvertValueToPixelY(Ay)) ;
_By = Lastvalue(GfxConvertValueToPixelY(Ay)) ;

// Finding co-ordinates of C and D (ABCD being a square)
dX = _Bx - _Ax;	 		 dY = _By - _Ay;
_Cx = _Bx - dY;			_Cy = _By + dx;
_Dx = _Ax - dY;			_Dy = _Ay + dx;
	
// Drawing square ABCD
GfxMoveTo( _Ax, _Ay );		GfxLineTo( _Bx, _By );
GfxMoveTo( _Bx, _By );		GfxLineTo( _Cx, _Cy );
GfxMoveTo( _Ax, _Ay );		GfxLineTo( _Dx, _Dy );
GfxMoveTo( _Cx, _Cy );		GfxLineTo( _Dx, _Dy );		 

// Text for co-ordinates
GfxTextOut( "A", _Ax, _Ay ); 	GfxTextOut( "B", _Bx, _By );	GfxTextOut( "C", _Cx, _Cy ); 	GfxTextOut( "D", _Dx, _Dy );

Filter = IIf ( Valley_X < Top_X , round(_Cx) , round(_Dx) ) ;

I work on it for several weeks but not working.

Can somebody help me to configure what is wrong with it ?

Thanks in advance

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