Plotting trades on chart

the objective is to plot trades on chart so that it can be revieweed periodically to learn to trade better. the objective

  • is to produce a generic afl that will take in the symbol, trade dates and prices and plot on a chart.
  • support different timeframes so the plotting is still visible. daily, weekly, intraday, 5 minute/15 minute
  • ability to support position scaling as there may be multiple trade entries /exits

 

this afl needs the input in terms of static variables as follows. so you may need an adapter that will take your trades and put it to afl.


// defines if it is a stock or forex.
StaticVarSetText( "TradeType" , "Stocks" ); //Stocks|Forex
// defines the forex symbol
StaticVarSetText( "forexSymbol" , "SBUX" ); //"EUR.USD-IDEALPRO-CASH|
// defines the stock symbol
StaticVarSetText( "StockSymbol", "SBUX" ); // "YHOO"
// long or short trade.
StaticVarSetText( "ShortOrLong" , "Long" ); //"Short|Long"
// entry prices
StaticVarSetText( "EntryPrice" , "14.5,15.5" );
// exit prices
StaticVarSetText( "ExitPrice" , "14.3" );
// entry date in date number comma delimited
StaticVarSetText( "EntryDate" , "1080717,1080723" );
// exit date in date number. comma delimited
StaticVarSetText( "ExitDate", "1080725" );
// entry time in time number comma delimited
StaticVarSetText( "EntryTime", "142500,120000" );
// exit time in time number comma delimited
StaticVarSetText( "ExitTime" , "110500" );
// trade id. its an internal key for me
StaticVarSetText( "Tradeid" , "4" );
// trade strategy.
StaticVarSetText( "TradeStrategy" , "fsdfdsfds" );
// any comments on trade
StaticVarSetText( "TradeComments" , "this is the comment" );
/* sets no of entries so that the code loops when printing the number
of trdes.
if 1, then ther should be only 1 entry date/time
if there are more thatn 1 entry or exits, the number of comma delimited entries exits should match the static variable NoOfEntries and same applies for exits
*/
StaticVarSet( "NoOfEntries" , 2 );
//same as above.
StaticVarSet( "NoOfExits" , 1 );
 

 


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 ) ) ) );
Title = Title + “\n” + NumToStr( DateNum() );
Title = Title + “\n” + NumToStr( TimeNum() );
Plot( C, “Close”, ParamColor( “Color”, colorBlack ), styleNoTitle | ParamStyle( “Style” ) | GetPriceStyle() );
//_TRACE(“ABTest: test trace1 “);

//#include “C:\Program Files\AmiBroker\sharedLibrary\DateTimeToNumber.afl”

/*
#include “C:\Program Files\AmiBroker\sharedLibrary\DateTimeToNumber.afl”
StaticVarSetText( “TradeType” ,”Stocks”); //Stocks|Forex
StaticVarSetText( “forexSymbol” ,”AAPL”); //”EUR.USD-IDEALPRO-CASH|
StaticVarSetText( “StockSymbol”,”AAPL”); // “YHOO”
StaticVarSetText( “ShortOrLong” ,”Short”); //”Short|Long”
StaticVarSet( “EntryPrice” ,163.52000);
StaticVarSet( “ExitPrice” ,148.18000);
StaticVarSet( “EntryDate” ,Date_To_Num(“20080721”));
StaticVarSet( “ExitDate” ,Date_To_Num(“20080721”));
StaticVarSet( “EntryTime”,Time_To_Num(“11:01:47”) );
StaticVarSet( “ExitTime” ,Time_To_Num(“17:52:17”));

StaticVarSetText( “TradeType” , “Stocks” ); //Stocks|Forex
StaticVarSetText( “forexSymbol” , “SBUX” ); //”EUR.USD-IDEALPRO-CASH|
StaticVarSetText( “StockSymbol”, “SBUX” ); // “YHOO”
StaticVarSetText( “ShortOrLong” , “Long” ); //”Short|Long”
StaticVarSetText( “EntryPrice” , “14.5,15.5” );
StaticVarSetText( “ExitPrice” , “14.3” );
StaticVarSetText( “EntryDate” , “1080717,1080723” );
StaticVarSetText( “ExitDate”, “1080725” );
StaticVarSetText( “EntryTime”, “142500,120000” );
StaticVarSetText( “ExitTime” , “110500” );
StaticVarSetText( “Tradeid” , “4” );
StaticVarSetText( “TradeStrategy” , “fsdfdsfds” );
StaticVarSetText( “TradeComments” , “this is the comment” );

StaticVarSet( “NoOfEntries” , 2 );
StaticVarSet( “NoOfExits” , 1 );

*/

function returnBarIndex( array )
{
indx = -1;

for ( i = 1; i < BarCount;i++ )
{

if ( array[i] == True )
{
indx = i;
}
}

return indx;
}

function returnShiftedArray( array, shift )
{

newArray = array;

for ( i = 1; i = 0 ) && ( ( shift + i ) < BarCount ) )
{

newArray[shift+i] = True;
newArray[i] = False;

}
}

return newArray;
}

if ( StrToUpper( Name() ) == StrToUpper( StaticVarGetText( “forexSymbol” ) ) OR ( StrToUpper( Name() ) == StrToUpper( StaticVarGetText( “StockSymbol” ) ) ) )

{
// get the static variables

TradeType = StaticVarGetText( “TradeType” );
forexSymbol = StaticVarGetText( “forexSymbol” );
StockSymbol = StaticVarGetText( “StockSymbol” );
ShortOrLong = StaticVarGetText( “ShortOrLong” );

if ( TradeType == “Stocks” )
{
stockname = stockSymbol;

SetOption( “FuturesMode”, False );
}
else
{
stockname = forexSymbol;
SetOption( “FuturesMode”, True );

}

for ( i = 0 ;i < StaticVarGet( “NoOfEntries” ) ;i++ )
{
VarSet( “EntryDate” + ( i ), StrToNum( StrExtract( StaticVarGetText( “EntryDate” ), ( i ) ) ) );
VarSet( “EntryPrice” + ( i ), StrToNum( StrExtract( StaticVarGetText( “EntryPrice” ), ( i ) ) ) );
VarSet( “EntryTime” + ( i ), StrToNum( StrExtract( StaticVarGetText( “EntryTime” ), ( i ) ) ) );

_TRACE( “ABTest: test 182 ” + “EntryDate” + ( i ) + NumToStr( VarGet( “EntryDate” + ( i ) ) ) );
_TRACE( “ABTest: test 182 ” + “EntryDate” + ( i ) + “string” + StrExtract( StaticVarGetText( “EntryDate” ), ( i ) ) );
}

// TESTING IF THE VARIABLES EXIST
for ( i = 0 ;i < StaticVarGet( “NoOfEntries” ) ;i++ )
{
_TRACE( “ABTest: test 182 TESTING” + “EntryDate” + ( i ) + NumToStr( VarGet( “EntryDate” + ( i ) ) ) );
_TRACE( “ABTest: test 182 TESTING timeframe” + inWeekly );
}

for ( j = 0 ;j < StaticVarGet( “NoOfExits” ) ;j++ )
{
VarSet( “ExitDate” + ( j ), StrToNum( StrExtract( StaticVarGetText( “ExitDate” ), ( j ) ) ) );
VarSet( “ExitTime” + ( j ), StrToNum( StrExtract( StaticVarGetText( “ExitTime” ), ( j ) ) ) );

VarSet( “ExitPrice” + ( j ), StrToNum( StrExtract( StaticVarGetText( “ExitPrice” ), ( j ) ) ) );
// _TRACE( “ABTest: test 182 ” + “ExitDate” + ( j ) + “string” + StrExtract( StaticVarGetText( “ExitDate” ), ( j ) ) );

}

//Buy = Sell = Short = Cover = entryPrices = exitPrices = False;

// if the symbol matches what i am looking for
dn = DateNum();

tn = TimeNum();

entryPrices = exitPrices = Buy = Sell = Short = Cover = False;

range = H – L;

switch ( Interval() )
{
// START OF SWITCH.

case inDaily:

for ( b = 0;b < BarCount;b++ )
{
// START OF DAILY

for ( i = 0 ;i dn[b] – 1 ) AND ( VarGet( “EntryDate” + i ) < dn[b] + 1 ) )
{

entryPrices[b] = VarGet( “EntryPrice” + i );
Buy[b] = Short[b] = True;
//_TRACE( “ABTest: test 182 matching price ” + NumToStr( VarGet( “EntryPrice” + i ) ) ) ;

PlotText( StaticVarGetText( “ShortOrLong” ) + ” entry ” + i + ” ” + “:” + entryPrices[b] , b, High[b] + range[b], colorBlue );
// PlotText( “entry” + VarGet( “EntryPrice” + i ) , b, EntryPrice0, colorBlue );

// _TRACE( “ABTest: test 182 MATCHED ” + NumToStr( VarGet( “EntryDate” + i ) ) + NumToStr( dn[b] ) );

}

for ( j = 0 ;j dn[b] – 1 ) AND ( VarGet( “ExitDate” + j ) < dn[b] + 1 ) )

{

exitPrices[b] = VarGet( “ExitPrice” + j );
Sell[b] = Cover[b] = True;

PlotText( StaticVarGetText( “ShortOrLong” ) + ” Exit ” + j + “:” + VarGet( “ExitPrice” + j ) , b, Low[b] – range[b], colorRed );
// _TRACE( “ABTest: test 182 MATCHED ” + NumToStr( VarGet( “ExitPrice” + j ) ) + NumToStr( dn[b] ) + NumToStr( VarGet( “ExitDate” + j )));

}

}

}

} // START OF DAILY

break;

case inWeekly:

for ( b = 1;b < BarCount – 1;b++ )
{
// START OF weekly

for ( i = 0 ;i 0)
PreviousBar=b-1;
NextBar=b;
if(b= dn[b] ) AND ( VarGet( “EntryDate” + i ) < dn[b+1] ) )
{

entryPrices[b] = VarGet( “EntryPrice” + i );
Buy[b] = Short[b] = True;
_TRACE( “ABTest: test 182 matching price entry ” + NumToStr( VarGet( “EntryPrice” + i ) ) ) ;

PlotText( StaticVarGetText( “ShortOrLong” ) + ” entry” + i + ” ” + “:” + entryPrices[b] , b, High[b] + range[b], colorBlue );
// PlotText( “entry” + VarGet( “EntryPrice” + i ) , b, EntryPrice0, colorBlue );

// //( “ABTest: test 182 MATCHED ” + NumToStr( VarGet( “EntryDate” + i ) ) + NumToStr( dn[b] ) );

}

for ( j = 0 ;j = dn[b-1] ) AND (VarGet( “EntryDate” + i )= dn[b] ) AND ( VarGet( “ExitDate” + j ) < dn[b+1] ) )

{

exitPrices[b] = VarGet( “ExitPrice” + j );
Sell[b] = Cover[b] = True;

PlotText( StaticVarGetText( “ShortOrLong” ) + ” Exit” + j + “:” + VarGet( “ExitPrice” + j ) , b, Low[b] – range[b], colorRed );
// _TRACE( “ABTest: test 182 MATCHED ” + NumToStr( VarGet( “ExitPrice” + j ) ) + NumToStr( dn[b] ) + NumToStr( VarGet( “ExitDate” + j )));

}

}

}

} // START OF weekly

break;

//_TRACE(“ABTest: test 182 ” +”getting to break”);

case in1Minute:

case in5Minute:

case in15Minute:

case inHourly:

for ( b = 1;b < BarCount – 1;b++ )
{
// START OF intraday

for ( i = 0 ;i = tn[b] ) AND ( VarGet( “EntryTime” + i ) < tn[b+1] ) )
{

entryPrices[b] = VarGet( “EntryPrice” + i );
Buy[b] = Short[b] = True;
_TRACE( “ABTest: test 182 matching price entry ” + NumToStr( VarGet( “EntryPrice” + i ) ) ) ;

PlotText( StaticVarGetText( “ShortOrLong” ) + ” entry” + i + ” ” + “:” + entryPrices[b] , b, High[b] + range[b], colorBlue );
// PlotText( “entry” + VarGet( “EntryPrice” + i ) , b, EntryPrice0, colorBlue );

// //( “ABTest: test 182 MATCHED ” + NumToStr( VarGet( “EntryDate” + i ) ) + NumToStr( dn[b] ) );

}

for ( j = 0 ;j = dn[b-1] ) AND (VarGet( “EntryDate” + i )= tn[b] ) AND ( VarGet( “ExitTime” + j ) < tn[b+1] ) )

{

exitPrices[b] = VarGet( “ExitPrice” + j );
Sell[b] = Cover[b] = True;

PlotText( StaticVarGetText( “ShortOrLong” ) + ” Exit” + j + “:” + VarGet( “ExitPrice” + j ) , b, Low[b] – range[b], colorRed );
// _TRACE( “ABTest: test 182 MATCHED ” + NumToStr( VarGet( “ExitPrice” + j ) ) + NumToStr( dn[b] ) + NumToStr( VarGet( “ExitDate” + j )));

}

}

}

} // end of intraday

break;

//_TRACE(“ABTest: test 182 ” +”getting to break”);

}// end of switch.

PlotShapes( IIf( Buy OR Short, shapeSmallCircle, shapeNone ), colorBrightGreen, 0, EntryPrices, 0 );

PlotShapes( IIf( Sell OR Cover, shapeSmallCircle, shapeNone ), colorRed, 0 , ExitPrices, 0 );

Miny = Status( “axisminy” );

Maxy = Status( “axismaxy” );

pxheight = Status( “pxheight” );

y = ( GetCursorYPosition() – Miny ) / ( Maxy – Miny );

y = ( 1 – y ) * pxheight;

y = y – 20;

x = 10;

GfxSelectPen( colorRed, 1 );

GfxSelectSolidBrush( colorCustom1 );

//GfxRectangle( 2, y-100, 270, y ) ;

GfxSelectFont( “Tahoma”, 8, 700 );

GfxSetBkMode( 1 );

GfxSetTextColor( colorGreen );

GfxTextOut( Name() + ” Tradeid= ” + StaticVarGetText( “Tradeid” ) , x, y ) ;

GfxTextOut( ” Strategy= ” + StaticVarGetText( “TradeStrategy” ) , x, y + 10 ) ;

GfxTextOut( ” Comments= ” + StaticVarGetText( “TradeComments” ) , x, y + 20 ) ;

} // // if the symbol matches what i am looking for

Date and Time to Number Conversions

Code developed and kindly donated by Murthy Suresh.

{
    dd_ StrToNumStrRightaaaammdd) );    //printf(WriteVal(dd_) + " "  );
    mm_ StrToNumStrMidaaaammdd4) );    //printf(WriteVal(mm_) + " "  );
    aa_ StrToNumStrLeftaaaammdd) );    //printf(WriteVal(aa_) + " " + "\n" );
    Date_Num = ( 10000 * ( aa_ 1900 ) ) + ( 100 mm_ ) + dd_;
    RESULT Date_Num;
    return RESULT;
}

function Time_To_NumstrTime // format for time is hh:mm:ss
{
    /*
    //do something to raise alert  if length does not match
    ????PopupWindow("Current time is: " + Now(),"Alert", 2,
    640*mtRandom(), 480*mtRandom());
    */
    hh_t StrToNumStrLeftstrTime) );    //printf(WriteVal( hh_t ) + " "  );
    mm_t StrToNumStrMidstrTime3) );    //printf(WriteVal( mm_t ) + " "  );
    ss_t StrToNumStrRightstrTime) );    //printf(WriteVal( ss_t ) + " "  + "\n"  );
    Time_Num 10000 hh_t 100 mm_t ss_t;
    RESULT Time_Num;
    return RESULT;

Popup Window: Preventing pile-ups

By Dennis Brown

The popup window is a great tool in debugging and can help you to keep track of what your code is doing or it can be used to alert you to special situations in your normally running formula. A common problem is that if you call PopupWindow() from a loop or if one gets generated on every AFL pass, you can get hundreds or even thousands of pop-ups piling up on your screen. Tomasz posted a simple work-around on the AmiBroker Feedback Center that took care of the problem in some cases (Suggestion 1528):

The following is a more complete version of this solution that adds a popupID to keep track of each individual popup window and re-enable the popup after its specified timeout period, or if any of the displayed text changes:

function GetSecondNum()
{
    Time Now);
    Seconds intTime 100 );
    Minutes intTime 100 100 );
    Hours intTime 10000 100 );
    SecondNum intHours 60 60 Minutes 60 Seconds );
    return SecondNum;
}

function PopupWindowExpopupIDbodytextcaptiontexttimeoutlefttop )
{
    displayText bodytext captiontext;
    if ( ( StaticVarGetText"prevPopup" popupID ) != displayText) OR ( StaticVarGet"prevPopupTime" popupID ) < GetSecondNum() ) )
    {
        StaticVarSetText"prevPopup" popupIDdisplayText);
        StaticVarSet"prevPopupTime" popupIDGetSecondNum() + timeout );
        PopupWindowbodytextCaptiontext popupIDtimeoutLefttop );
    }
}

PopupWindowEx"ID:1""testing""test alert "5, -1, -);
PopupWindowEx"ID:2""testing""test alert "50);

WordPress upgrade

Due to vulnerability found in previous version of WordPress (2.2) and attack attempts this site experienced and the compatibility issues with Windows Live Writer that surfaced after quick security fix was applied, I was forced to perform upgrade to newest version of WordPress.
This results in old Table-of-content plugin not working anymore and the need for rewrite. The new version produces ill-formatted output. Please be patient when TOC plugin is under rewrite.

Also note that although read experience does not change (the site looks identical from reader perspective), the author control panel has changed and looks different. It requires some time to adjust to new design, but after a while I think it is better. I am sorry about this mess but it was not caused by me.

Pattern Recognition Across Timeframes

TEMPORARY DRAFT

Two classical bullish patterns in daily bars.

PR001

Timeframe shifted to weekly.

Selector line moved to highlight the former Pivot Lo value.

PR002

Timeframe shifted to Monthly.

Selector line moved to highlight the former Pivot Lo value.

PR003

 

Note that the 2nd and third Pivot Lo’s (not marked on the charts) are not significant in the monthly timeframe i.e. the monthly chart does not truly represent the underlying waves (cycles) of the daily chart (which I claim is the natural rhythm of the market notwithstanding that the intra-day charts tell us as much, if not more, about the behaviour of market participants).

 

Bonus Commentary

Comparing perfect equity with a buy&hold strategy for three weeks (using an earlier section of the above chart).

The charts are linked and in different timeframes.

 

Perfect trades are an approximation of Pivot Hi to Pivot Lo marked in colour with corresponding % change obtained via the AB studies tooltips.

For the sake of the exercise I cheated a little on the perfect swings.

For convenience I ignored inside and outside days (not counted as a swing) -annoying little things those ID’s and OD’s – messing up my perfect theories like that.

 

PR005

 

PR004