Number of bars from trade entry to MFE and MAE

Hi,

As a total newie I am trying to reuse some code to calculate number of bars from trade entry to MAE and from trade entry to MFE.

I have used code posted here AmiBroker Knowledge Base » How to add MAE / MFE dates to the backtest report and was hoping to find a function NumBarsBetweenDates or something...

This is what I have now but results are wrong:

function processTrade( trade )
{
    dt = DateTime();

    SetForeign( trade.Symbol );

//	numberOfBarsFromLow = LLVBars( Low, trade.BarsInTrade + 1);
//	numberOfBarsFromHigh = HHVBars( High, trade.BarsInTrade + 1);
	numberOfBarsToLow = trade.BarsInTrade - LLVBars( Low, trade.BarsInTrade + 1);
	numberOfBarsToHigh = trade.BarsInTrade - HHVBars( High, trade.BarsInTrade + 1);
	
    llvDateTime = Lookup( Ref( dt, - LLVBars( Low, trade.BarsInTrade + 1 ) ), trade.ExitDateTime );
    hhvDateTime = Lookup( Ref( dt, - HHVBars( High, trade.BarsInTrade + 1 ) ), trade.ExitDateTime );

    if ( trade.IsLong() )
    {
        maeDateTime = llvDateTime;
        mfeDateTime = hhvDateTime;
        
        barsToMAE = numberOfBarsToLow;
        barsToMFE = numberOfBarsToHigh;
    }
    else
    {
        maeDateTime = hhvDateTime;
        mfeDateTime = llvDateTime;
        
        barsToMAE = numberOfBarsToHigh;
        barsToMFE = numberOfBarsToLow;
    }

    RestorePriceArrays();

    trade.AddCustomMetric( "MFE Date", DateTimeToStr( mfeDateTime ) );
    trade.AddCustomMetric( "MAE Date", DateTimeToStr( maeDateTime ) );
    
    // Wrong
    trade.AddCustomMetric( "Bars to MFE", NumToStr( barsToMFE, format=1.0, separator=False ) );
    trade.AddCustomMetric( "Bars to MAE", NumToStr( barsToMAE, format=1.0, separator=False ) );
        
    
    // Time to MFE and time to MAE works but these are not bars  
    trade.AddCustomMetric( "Time to MFE", NumToStr( DateTimeDiff(mfeDateTime, trade.EntryDateTime)/Interval( format=0 ), format=1.0, separator=False ) );
    trade.AddCustomMetric( "Time to MAE", NumToStr( DateTimeDiff(maeDateTime, trade.EntryDateTime)/Interval( format=0 ), format=1.0, separator=False ) );

// First newbie fail
//    trade.AddCustomMetric( "Bars to MFE", NumToStr( LastValue( Cum( trade.EntryDateTime < mfeDateTime )), format=1.0, separator=False ) );
//    trade.AddCustomMetric( "Bars to MAE", NumToStr( LastValue( Cum( trade.EntryDateTime < maeDateTime )), format=1.0, separator=False ) );
    
// Second newbie fail
//    trade.AddCustomMetric( "Bars to MFE", NumToStr( BarsSince( trade.EntryDateTime <= mfeDateTime ), format=1.0, separator=False ) );
//    trade.AddCustomMetric( "Bars to MAE", NumToStr( BarsSince( trade.EntryDateTime <= maeDateTime ), format=1.0, separator=False ) );
    
}

if ( Status( "action" ) == actionPortfolio )
{
    bo = GetBacktesterObject();

    bo.Backtest( 1 ); // run default backtest procedure

    for ( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() )
    {
      processTrade( trade );

    }

    for ( trade = bo.GetFirstOpenPos(); trade; trade = bo.GetNextOpenPos() )
    {
      processTrade( trade );
    }

    bo.ListTrades();
}

@kktrader, Welcome to this community.

I'm not a CBT expert, but I think that you can get what you are looking for by calculating your metrics starting from the 2 dates variables that you get from the original code example:

      ...
    }

	RestorePriceArrays();

    // Find bar # using lookup
	bi = BarIndex();
	maeBar = Lookup( bi, maeDate );
	mfeBar = Lookup( bi, mfeDate );
	entryBar = Lookup( bi, trade.EntryDateTime );
	exitBar = Lookup( bi, trade.ExitDateTime );


	trade.AddCustomMetric( "MAE Date", DateTimeToStr( maeDate ) );
	trade.AddCustomMetric( "MFE Date", DateTimeToStr( mfeDate ) );

	trade.AddCustomMetric( "Entry Bar", NumToStr( entryBar, 1.0 ) );
	trade.AddCustomMetric( "MAE Bar", NumtoStr( maeBar, 1.0 ) );
	trade.AddCustomMetric( "MFE Bar", NumToStr( mfeBar, 1.0 ) );
	trade.AddCustomMetric( "Exit Bar", NumtoStr( exitBar, 1.0 ) );


    
}```

(By the way, the returned bar numbers in the CBT seem to be calculated starting from the "From" date set in the dates "Range"). 
Then you can then do any additional calculations using the "bars" variables to get the " "NumBarsBetween...." values you are looking for.

Thank you very much. This indeed got me to the number of bars (from entry) to MFE and to MAE.

Now I see that calculating MFE/MAE using bar high/low is not correct/sufficient. For example, if trade exit is next bar open and if on next bar there is been a big decline from open resulting in lowest low for the trade this low of the bar will be MAE although trade was exited on the open... MAE7MFE should be calculated on trade P&L not price bar high/low...

So, the question is how to get to MAE/MFE dates of actual P&L of the trade?

I looked at https://www.amibroker.com/guide/a_custombacktest.htm and How to Compute MAE for Trades with Scale-In Entries - #3 by Greyleaf but can not figure out how to get to MAE/MFE date based on trade P&L...

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