Finding median profit in a set of trade list

I understand that trade list and the backtester are second pass processing. There are times where I want to use trade list statistics to further calculate other metrics. For example, I may want to find the maximum profit, minimum profit, and median profit in a set of trade list. As far as minimum and maximum is concern, I can use 2 scalar variables and keep the min/max profit totals as each trade is processed, and swap the values if the new value is bigger/smaller. However, if I want to know the median profit, I am stuck, because I cannot create a non-scalar variable to keep track of each trade profits in the array. If I can do that, then I just use the median function on this array. So my question, is there a way to get the median profit in a trade list? Thanks.

I assume you are already using a high-level CBT. After the backtest completes, see how many trades were generated (you can get this from the Stats object) and create a Matrix of this size. Now loop through all the closed and (if desired) open trades, putting the results into the Matrix. When you're done, sort the matrix and take the value from the middle (median).

1 Like

Thanks, will try that and report back.

FYI, the method mradtke describes (storing to matrix, sorting, etc) has been posted in forum already.

4 Likes

Thank you. I am still quite new here. Appreciate all the help.

I got the median profit of a trade list to work. Thank you fxshrat. Great forum we have here.

	bo = GetBacktesterObject();
	TmpCounter = -1;
	MedianProfit = 0;

	MedianProfit = Matrix(iif(AllTradesCount == 0, 1, AllTradesCount), 1, 0);	
	
	for (trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade()){
		TmpCounter ++;
		MedianProfit = MxSetBlock( MedianProfit, TmpCounter,TmpCounter, 0, 0, trade.GetProfit() );
	}
	
	MedianProfit = MxSort(MedianProfit, -1, 1); 
	
	if (!AllTradesCount % 2 == 0)
			MedianProfit = MedianProfit[TmpCounter/2][0];
	else
			MedianProfit = (MedianProfit[TmpCounter/2][0] + MedianProfit[TmpCounter/2 + 1][0])/2;

If your variable AllTradesCount came from the Stats object, then it is the number of closed and open trades. However, you only put the Closed Trade profits into the matrix, so if there are any open trades then you will have a profit of 0 (the matrix initialization value) in the matrix for each of those open trades. That will probably throw off your median calculation.

Also, if you want to tighten up your code you could just use a simple assignment instead of calling MxSetBlock:

MedianProfit[TmpCounter][0] = trade.GetProfit();
1 Like

Wow, I am impressed with all the knowledge. Thanks for the tip in the simpler code. Yes, my AllTradesCount = stats.GetValue("AllQty"); That will throw me off because this will include open trades and closed trades. Any idea of how to get closed only trades into my calculation :). If not, I will just check the profit figure, and if zero, I won't include. Thank you!

Why do you use MxSetBlock?? Have you seen me using MxSetBlock? It should not be used that way. It's heavy.

Simply do like this

//
i = 0;
// Iterating closed trades
for (trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade()) 		
	MedianProfit[i++][0] = trade.GetProfit();
//

closed_trades = 0;
// Iterating closed trades
for (trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade()) 
	closed_trades++;

MedianProfit = Matrix(Max(1,closed_trades), 1, 0);	

Thank again fxshrat for all your help! Why did I used MxSetBlock?? rookie backtester coder that's why. This is my first time coding with the backtester. I only joined the forum about a week ago. Thank you again kindly !

I can tell you are a much experienced coder, simply because you use the line MedianProfit = Matrix(Max(1,closed_trades), 1, 0); that's a nice line ! very terse and compact line. Thanks.

FWIW, you can get number of closed trades like this also.

stats = bo.GetPerformanceStats(0);
closed_trades = stats.GetValue("AllQty") - bo.GetOpenPosQty(); 

MedianProfit = Matrix(Max(1,closed_trades), 1, 0);	
1 Like

Thank you ! great knowledge in this forum!

Thank you mradtke and fxshrat for your inputs.