First off, thanks for reading this thread. :) I have a problem with NinjaTrader which bugs me allot, and I was hoping some of the experts here could give me an suggestion as how to proceed.
I'm trying to output all the trades which were made during an backtest to an external text file, so that these can be imported into R. This works like a charm, however, I have trouble exporting the MAE and MFE of each trade to the file.
The problem lies in the fact that NinjaTrader doesn't supply these metrics on a per trade basis. So, these have to be manually calculated, and I cant seem to succeed in this. Why? I dont know, the logic of the C# code (see below) seems consistent with the definition of MFE and MAE. Even more weird is that roughly 80-90% of the outputted values are correct, yet the different (read: wrong) values dont have consistent properties (i.e. the wrong values happen in long trades, short trades, trades with few bars, trades with long bars, profitable trades, losing trades, etc).
The following code gives the right Bar position of an trades:
Print("Trade#: " + (t.TradeNumber + 1) + " TimeOfExit: " + Time[(Count - t.ExitExecution.BarIndex) - 1] + " tradeDuration: " + ((t.ExitExecution.BarIndex - t.EntryExecution.BarIndex) + 1)); However, when I try to incorporate this ExitBarIndex minus EntryBarIndex + 1, I get the wrong results for the MAE and MFE values:
foreach (Trade t in Performance.AllTrades)
{
if (t.Entry.MarketPosition == MarketPosition.Long)
{
bestPriceReached = MAX(High, ((t.ExitExecution.BarIndex + 1) - t.EntryExecution.BarIndex))[(Count - 1) - (t.ExitExecution.BarIndex - 1)];
worstPriceReached = MIN(Low, ((t.ExitExecution.BarIndex + 1) - t.EntryExecution.BarIndex))[(Count - 1) - (t.ExitExecution.BarIndex - 1)];
}
else if (t.Entry.MarketPosition == MarketPosition.Short)
{
bestPriceReached = MIN(Low, ((t.ExitExecution.BarIndex + 1) - t.EntryExecution.BarIndex))[(Count - 1) - (t.ExitExecution.BarIndex - 1)];
worstPriceReached = MAX(High, ((t.ExitExecution.BarIndex + 1) - t.EntryExecution.BarIndex))[(Count - 1) - (t.ExitExecution.BarIndex - 1)]; ;
}
maeTrade = Math.Abs(worstPriceReached - t.Entry.Price);
mfeTrade = Math.Abs(bestPriceReached - t.Entry.Price);
etdTrade = Math.Abs(mfeTrade - t.ProfitCurrency);
}
Ive tried every variant I could think of to calculate the MAE and MFE per trade, but didnt succeeded. What am I overlooking?
******
Edit: Because most of the values are correct, I'm examining each situation where the values are off, and I noticed that this happens when the trade is of a short duration (i.e. lasts only a few bars) (see attachment for an graphic representation). With the following code I tried to work around this problem, yet that didn't succeed:
foreach (Trade t in Performance.AllTrades)
{
double entryPrice, exitPrice;
int entryBarIndex, exitBarIndex, lengthOfTrade;
double bestPriceReached, worstPriceReached;
double maeTrade, mfeTrade;
if (t.Entry.MarketPosition == MarketPosition.Long)
{
// what's the entry price?
entryPrice = t.Entry.Price;
// on which bar did that happen?
entryBarIndex = (Count - 1) - t.EntryExecution.BarIndex;
// what's the exit price?
exitPrice = t.Exit.Price;
// on which bar did that happen?
exitBarIndex = (Count - 1) - t.ExitExecution.BarIndex;
// so, how long did the trade lasted?
lengthOfTrade = (entryBarIndex - exitBarIndex) + 1;
// so, what's the best price for an long trade that happend during this time period?
bestPriceReached = MAX(High, lengthOfTrade)[exitBarIndex];