CBT Monthly Closed Trade Counter

Hello guys. I am trying to understand how program a loop that keeps track of how many trades are closed in the current month. I am tracing what i am doing, but just can not figure out the logic how to properly do it.
My attempt :

                closed_trades = 0;
		newMonth = Month() != Ref( Month(), -1 );

			for(trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() ) 
			{				
				if(!newMonth[i])
				{
					closed_trades++;
				}
				
				if (newMonth[i])
				{					
					closed_trades = 0;					
					closed_trades++;				
				}				
			}
   _TRACE("closed_trades        " + closed_trades +  "          " + DateTimeToStr(dt[i]) );


Of course i am not doing something right, but at my programing level, i can not figure it out.
Appreciate any help.
Thank you.

Here's one way to do it - without the need for a bar loop.

MA1 	= MA(C, 5);
MA2 	= MA(C, 20);
Buy 	= Cross(MA1, MA2);
Sell 	= Cross(MA2, MA1);

SetCustomBacktestProc(""); 
if( Status("action") == actionPortfolio ) 
{ 
    bo = GetBacktesterObject(); 
    bo.Backtest(); // run default backtest procedure 

	dt = DateTime();
	MonthStart = LastValue(ValueWhen(ROC(Month(), 1) != 0, dt)); // Calc DateTime value of first trading day this month

    TradesClosedThisMonth = 0;
    for (trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade())
    {
        if (trade.ExitDateTime >= MonthStart) // Trade Exit date was in this current month
			TradesClosedThisMonth++;
    }
    
    bo.AddCustomMetric("Trades Closed This Month", TradesClosedThisMonth, Null, Null, 0);
}

Metric then shows at foot of Statistics page of the backtest report:

image

3 Likes

Thank you for the reply @MacAllan. Much appreciated. :hugs:
My bad for not being more specific. The idea is to use this variable TradesClosedThisMonth++ to keep a counter with witch to decide if new trades can be taken or not, based on how many trades were closed this month. To do that i would add the Trade.GetpercentProfit method along with this closed trades variable and could use it to say : do not take any more trades this month if for ex i already have 5 closed losing trades.
Not that there is any merit to the idea, i'm just trying different things and looking at the outcomes, all while improving my understanding of the logic and proper use of Amibroker.
I have tried your method and using _Trace function in a low level CBT and do not have any increment in the variable. When using it the way you posted( high Level) it works, it keeps track of closed trades, but as you say, only in the Statistics of the backtest report, and can not use it in trade decision.
Sorry for not being more explicit. If you still want to help, I appreciate it.
Thank you again for your reply and the example you posted . :hugs:

1 Like

You can still use the same approach, but just move it down from the high-level to the mid-level CBT, inside a bar loop. You can then loop through the closed trade list on each bar, capture the number of exits this month, before then processing the signals for that bar and conditionally preventing new entries based on the result of the trade looping. Eg

SetCustomBacktestProc("");
if (Status("action") == actionPortfolio) 
{
    bo = GetBacktesterObject();	//  Get backtester object
    bo.PreProcess();	//  Do pre-processing (always required)
    
	DetailedLog = GetOption("PortfolioReportMode") == 1;
    dt = DateTime();    
    
    NewMonth = ROC(Month(), 1) != 0;
    MonthStart = dt[0]; // Initialise month start to first bar
    
    MaxClosedTradesPerMonth = 5;

    for (i = 0; i < BarCount; i++)	//  Loop through all bars
    {
		if (DetailedLog) bo.RawTextOutput(DateTimeToStr( dt[i] ));   // Show bar date in Detailed Log 
		
		if (NewMonth[i]) MonthStart = dt[i]; // Update month start when new month
		
		// Loop through all trades closed up to this point in the bar loop
		TradesClosedThisMonth = 0;
		for (trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade())
		{
			if (trade.ExitDateTime >= MonthStart) // Trade Exit date was in this current month
				TradesClosedThisMonth++;
		}	
		if (DetailedLog) bo.RawTextOutput("\tTrades Closed This Month: " + 	TradesClosedThisMonth);
			
        // Process signals for this bar
        for (sig = bo.GetFirstSignal( i ); sig; sig = bo.GetNextSignal( i ) )
        {	
            // Prevent new entries if exit trade limit has been reached this month
            if (TradesClosedThisMonth >= MaxClosedTradesPerMonth AND sig.IsEntry())
            {
				sig.Price = -1; // Ignore entry signal
				if (DetailedLog) bo.RawTextOutput("\t" + sig.Symbol + " entry ignored");
			}
        }	
        
        bo.ProcessTradeSignals( i );	//  Process trades at bar (always required)
    }	  
      
    bo.PostProcess();	//  Do post-processing (always required)
}

If you turn on the Detailed Log, you'll see the output generated on each bar.

image

1 Like

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