Tag Archives: intra day testing

How to Keep Track of BuysToday and SellsToday

The Useful MP

We all know how to use the reserved word/function MarketPosition – right?  Brief summary if not – use MarketPosition to see what your current position is: -1 for short, +1 for long and 0 for flat.  MarketPosition acts like a function because you can index it to see what you position was prior to the current position – all you need to do is pass a parameter for the number of positions ago.  If you pass it a one (MarketPosition(1)) then it will return the your prior position.  If you define a variable such as MP you can store each bars MarketPosition and this can come in handy.

mp = marketPosition;

If mp[1] <> 1 and mp = 1 then buysToday = buysToday + 1;
If mp[1] <> -1 and mp = -1 then sellsToday = sellsToday + 1;
Keeping Track of Buy and Sell Entries on Daily Basis

The code compares prior bar’s MP value with the current bar’s.   If there is a change in the value, then the current market position has changed.   Going from not 1 to 1 indicates a new long position.  Going from not -1 to -1 implies a new short.  If the criteria is met, then the buysToday or sellsToday counters are incremented.  If you want to keep the number of buys or sells to a certain level, let’s say once or twice,  you can incorporate this into your code.

If  time >= startTradeTime and t < endTradeTime and 
	buysToday < 1 and 
	rsi(c,rsiLen) crosses above rsiBuyVal then buy this bar on close;
If  time >= startTradeTime and t < endTradeTime and 
	sellsToday < 1 and 
	rsi(c,rsiLen) crosses below rsiShortVal then sellShort this bar on close;
Using MP to Keep Track of BuysToday and SellsToday

This logic will work most of the time, but it depends on the robustness of the builtin MarketPosition function Look how this logic fails in the following chart:

I didn't want entries in the same direction per day!
I only wanted 1 short entry per day!

MarketPosition Failure

Failure in the sense that the algorithm shorted twice in the same day.  Notice on the first trade how the profit objective was hit on the very next bar.  The problem with MarketPosition is that it only updates at the end of the bar one bar after the entry.  So MarketPosition stays 0 during the duration of this trade.  If MarketPosition doesn’t change then my counter won’t work.  TradeStation should update MarketPosition at the end of the entry bar.  Alas it doesn’t work this way.  I figured a way around it though.  I will push the code out and explain it later in more detail.

Input: rsiLen(14),rsiBuyVal(30),rsiShortVal(70),profitObj$(250),protStop$(300),startTradeTime(940),endTradeTime(1430);

Vars: mp(0),buysToday(0),sellsToday(0),startOfDayNetProfit(0);

If d <> d[1] then
Begin
	buysToday = 0;
	sellsToday = 0;
	startOfDayNetProfit = netProfit;
end;

{mp = marketPosition;

If mp[1] <> 1 and mp = 1 then buysToday = buysToday + 1;
If mp[1] <> -1 and mp = -1 then sellsToday = sellsToday + 1;}

If entriesToday(date) > buysToday + sellsToday then 
Begin
	If marketPosition = 1 then buysToday = buysToday + 1;
	If marketPosition =-1 then sellsToday = sellsToday + 1;
	If marketPosition = 0 then
	Begin
		if netProfit > startOfDayNetProfit then
		begin
			if exitPrice(1) > entryPrice(1) then buysToday = buysToday + 1;
			If exitPrice(1) < entryPrice(1) then sellsToday = sellsToday + 1;
		end;;
		if netProfit < startOfDayNetProfit then
		Begin
			if exitPrice(1) < entryPrice(1) then buysToday = buysToday + 1;
			If exitPrice(1) > entryPrice(1) then sellsToday = sellsToday + 1;
		end;
	end;
	print(d," ",t," ",buysToday," ",sellsToday);
end;

If  time >= startTradeTime and t < endTradeTime and 
	buysToday < 1 and 
	rsi(c,rsiLen) crosses above rsiBuyVal then buy this bar on close;
If  time >= startTradeTime and t < endTradeTime and 
	sellsToday < 1 and 
	rsi(c,rsiLen) crosses below rsiShortVal then sellShort this bar on close;

SetProfittarget(profitObj$);
SetStopLoss(protStop$);

SetExitOnClose;
A Better Buy and Short Entries Counter

TradeStation does update EntriesToday at the end of the bar so you can use this keyword/function to help keep count of the different type of entries.  If MP is 0 and EntriesToday increments then you know an entry and an exit has occurred (takes care of the MarketPosition snafu) – all you need to do is determine if the entry was a buy or a sell.  NetProfit is also updated when a trade is closed.   I establish the StartOfDayNetProfit on the first bar of the day (line 9 in the code) and then examine EntriesToday and if NetProfit increased or decreased.  EntryPrice and ExitPrice are also updated at the end of the bar so I can also use them to extract the information I need.   Since MarketPosition is 0  I have to pass 1 to the EntryPrice and ExitPrice functions – prior position’s prices.  From there I can determine if a Long/Short entry occurred.  This seems like a lot of work for what you get out of it, but if you are controlling risk by limiting the number of trades (exposure) then an accurate count is so very important.

An alternative is to test on a higher resolution of data – say 1 minute bars.  In doing this you give a buffer to the MarketPosition function – more bars to catch up.

 

Don’t Fool Yourself – Limitations of Back Testing with Daily Data [EasyLanguage]

Which equity curve do you like best? (created with EasyLanguage script) This one…

Or this one?

Obviously the first one.  Even though it had a substantial draw down late in the test.  What if I told you that the exact same system logic generated both curves?  Here is the EasyLanguage code for this simple system.

Buy next bar at open of next bar + .25 *avgTrueRange(10) stop;
Sellshort next bar at open of next bar - .25*avgTrueRange(10) stop;

setStopLoss(500);
setProfitTarget(1000);
Open Range Break Out with Profit and Loss Objective

This algorithm relies heavily on needing to know which occurred first: the high or the low of the day.   The second chart tells the true story because it looks inside the daily bar to see what really happened.  The first chart uses an algorithm to try to determine which happened first and applies this to the trades.  In some instances,  the market looks like it opens then has a slight pull back and then goes up all day.  As a result the system buys and holds the trade through the close and onto the next day, but in reality the market opens, goes up and triggers a long entry, then retraces and you get stopped out.  What was a nice winner turns into a bad loss.  Here is an example of what might have happened during a few trades:

Nice flow – sold, bought, sold, bought, sold again and finally a nice profit.  But this is what really happened:

Sold, bought, reversed short on same day and stopped out on same day.  Then sold and reversed long on same day and finally sold and took profit.   TradeStation’s Look Inside Bar feature helps out when your system needs to know the exact path the market made during the day.  In many cases, simply clicking this feature to on will take care of most of your testing needs.  However, this simple algorithm needs to place or replace orders based on what happens during the course of the day.  With daily bars you are sitting on the close of the prior day spouting off orders.  So once the new day starts all of your orders are set.  You can’t see this initially on the surface, because it seems the algorithm is so simple.   Here is another consequence of day bar testing when the intra-day market movement is paramount:

Here the computer is doing exactly what you told it!  Sell short and then take a profit and sell short 25% of the ATR below the open.  Well once the system exited the short it realized it was well below the sell entry point so it immediately goes short at the exact same price (remember TS doesn’t allow stop limit orders).  You told the computer that you wanted to be short if the market moves a certain amount below the open.  These were the orders that were place on yesterday’s close  This may not be exactly what you wanted, right?  You probably wanted to take the profit and then wait for the next day to enter a new trade.  Even if you did want to still be short after the profit level was obtained you wouldn’t want to exit and then reenter at the same price (practically impossible) and be levied a round-turn slip and commission.   You could fiddle around with the code and try to make it work, but I guarantee you that a system like this can only be tested properly on intra-day data.  Let’s drop down to a lower time frame, program the system and see what the real results look like:

Looks very similar to the daily bar chart with Look Inside Bar turned on.  However, it is different.  If you wan’t to gauge a systems potential with a quick program, then go ahead and test on daily bars with LIB turned on.  If it shows promise, then invest the time and program the intra-day version just to validate your results.  What do you mean spend the time?  Can’t you simply turn your chart from daily bars to five minute bars and be done with it.  Unfortunately no!  You have to switch paradigms and this requires quite a bit more programming.  Here is our simple system now in EasyLanguage:

Vars:stb(0),sts(0),atr(0),icnt(0);
Vars:buysToday(0),sellsToday(0),mp(0);

{Use highD() and XXXXD(0)  functions to capture the highs, lows, and closes for the past 10 days.  
 I could have just used a daily bar as data2.  
 I am looking at five minute bars so we know how the market flows through the day.
}

{This loop kicks out a warning message, but seems to work
 Just do this once at the beginning of the day - faster}

{remember true range is either the higher of todays high
 Or yesterdays close minus the lower of todays low or 
 yesterdays close}

{ tradeStation time stamps at the close of the bar so
 we capture the opening of the open time plus the bar interval - 
 in this case 5 minute - so at 1800 + 5 (1805) I capture the open
 of the day}

if time = sess1StartTime + barInterval then  
begin
	Value1 = 0.0;
	for icnt = 1 to 10
	begin
		Value1 = value1 + maxList(closeD(icnt-1),highD(icnt)) - minList(closeD(icnt-1),lowD(icnt));
	end;
	atr = value1/10.0;
	stb = open + .25* atr;
	sts = open - .25* atr;
	buysToday = 0;
	sellsToday = 0;
end;

mp = marketPosition; {The ole mp trick}

If mp = 1 and mp[1] <> 1 then buysToday = buysToday + 1;
If mp =-1 and mp[1] <> -1 then sellsToday = sellsToday + 1;

if buysToday = 0  and time < sess1EndTime and close <= stb then buy next bar at stb stop;
if sellsToday = 0 and time < sess1EndTime and close >= sts then sellshort next bar at sts stop;

setStopLoss(500);
setProfitTarget(1000);
Open Range Break Out Utilizing Five Minute Bars

Here is a validation that Look Inside Bar does work:

This is the trade from June 1st.  Scroll back up to the second chart where LIB is turned on.