CBT - Closing positions the day after intended

Hello,

My code below closes a spread Gold/Silver when there is a $3000 loss. But I am doing something wrong that it closes the spread the day after the loss. For example:

On 2020 february 21st the spread value is -$3350. I want to close the spread at the close of that day. But my code closes the spread the following day, february 24th for a loss of $4400.

c04

c05


SetTradeDelays(0,0,0,0);
stoploss = 3000;

//------------ CBT----------------

SetCustomBacktestProc("");

if (Status("action") == actionPortfolio) 
{
    bo = GetBacktesterObject();	//  Get backtester object
    bo.PreProcess();	//  Do pre-processing (always required)

    for (i = 0; i < BarCount; i++)	//  Loop through all bars
    {
        profit = 0; 
        dt = DateTime();
        _TRACE("Date: " + DateTimeToStr(dt[i], 1));
        
        //OPEN POSITIONS LOOP TO CALCULATE SPREAD PROFIT
		for ( trade = bo.GetFirstOpenPos(); trade; trade = bo.GetNextOpenPos() )  
		{
			profit  = profit + trade.GetProfit(); 			
		}
		
		//SPREAD PROFIT
		_TRACE("SpreadProfit[1] = " + NumToStr(profit,1.2) );
			
		//APPLY STOP LOSS AND CLOSE ALL OPEN POSITIONS
		if( profit[i] < -StopLoss)
		{
			for ( trade = bo.GetFirstOpenPos(); trade; trade = bo.GetNextOpenPos() )
			{
				bo.ExitTrade( i, trade.Symbol, trade.GetPrice(i,"C"), 2); 
				_TRACE("**** Stop Loss****" );				 
			}		
		}
		
		_TRACE("---------------");    
		bo.ProcessTradeSignals( i );	//  Process trades at bar (always required) 
    }         
    bo.PostProcess();	//  Do post-processing (always required)
}

c07

I have checked tradedelays and set them to 0 but that does not seem to be the issue.

Thank you!

Why use so many lines of code when you can do stop loss exit using one line ApplyStop without any CBT?

Thanks for your answer. Unfortunately I don't know how to configure ApplyStop() to get me out of the 2 legs of the spread when the combined loss is $3000. Can you help? Thanks

Your code exists THE EXACT bar that you requested. Your problem is not exit but the fact that your code uses PREVIOUS BAR profit.

You need to know that position profit is updated when you call either:

  1. bo.ProcessTradeSignals()
  2. bo.UpdateStats()

So to get profit of position at current bar you need to call either of the above BEFORE you do your calculation involving profit.

Note that depending on parameters passed to UpdateStats() you can use Open price instead of Close which will be desirable to avoid looking into the future.

2 Likes

Just for clarification:

Do you mean bo.UpdateEquity or bo.UpdateStats ?

thanks

I meant UpdateStats which updates equity, profits and many other things.

http://www.amibroker.com/guide/a_custombacktest.html

bo.UpdateStats( i, 0 ); // update equity, profits and everything with open price

Keep in mind that you are calling ProcessTradeSignals already - therefore you are using MID-level mode and you should in fact be just calling ProcessTradeSignals BEFORE your calculation and then UpdateStats will NOT be needed at all. ProcessTradeSignals does everything including updating equity and pos values.

2 Likes

With bo.ProcessTradeSignals() before the profit calculation loop works fine. Thank you very much

1 Like

Thanks @Tomasz. The CBT reference guide tells not to use UpdateStats in high and mid level positions. However, if one wanted a system that trades post-open (and makes decisions based on open prices), and wants to update equity, position values etc based on current bar open prices, would it be possible to use bo.UpdateStats(i, 0) at bar open along with a later call to bo.ProcessTradeSignals at bar end (which would take bar prices to close), hence getting advantages of both low and mid level?

When I tried to do a simple single symbol 2-bar test to evaluate the above, it looked like equity, position values, MAE/MFE were all being correctly calculated both post-open as well as post-close. I understand that calling bo.UpdateStats(i, 2) at bar end along with bo.ProcessTradeSignals is a no-no (in fact in my test, that gave double the correct value for BarsInTrade), but is calling bo.UpdateStats(i, 0) and bo.UpdateStats(i, 1) mid-bar, compatible with an end bar bo.ProcessTradeSignals call?

Maybe the right solution might be to just do everything in low-level, but would be good to know either way.

Yes you can call bo.UpdateStats( i, 0 ) even with mid-level.

2 Likes

Great @Tomasz. Are there any other major differences between updatestats(i,0) and updatestats(i, 1) internally, besides that fact that the latter updates MAE/MFE based on bar high/low?

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