Backtest Performance from end of year

I am trying to run a backtest to see performance Year to Date, but when I enter 12/31/2022 vs 12/30/2022 I get different results. 12/31/2022 is a weekend so performance does not start until 1/3/2023. Is there a way to have Amibroker use previous value for start of calculating performance?
When you enter 12/31/2022 and this is a Saturday it skips the performance on 1/3/2023. I would like to have it show the performance Year to date when I enter 12/31/2022. I am guessing this is happening any time a date is enter that is a weekend or holiday?

I provided this simple code as a test.

Buy=Sell=Short=Cover=0;
movAvg= MA(C,100);
Buy=C>MovAvg;
Sell=!Buy;

Obviously you would get different results if you start trade on 12/30 as compared to 1/3/2023.

Also it does NOT skip performance on 1/3/2023. Set it to trade on OPEN (Buy price set to open) in the Settings and you will get movement from 1/3 INCLUDED in performance results.

Of course it would NOT include intra-bar movement from December to January.

If you want to have GAP between December close to January open included in the result, you have to use starting point in DECEMBER in last TRADING day.

If you want to use weekends as starting point, you have to use View->Pad non trading days

If you put start date of 12/31/2022 you are actually getting performance from 1/3/2023 end of day forward, so the entire performance of 1/3/2023 is being omitted using the backtest. Setting Trade on Open does not really work as an option because I am trading on a closing basis and would need to change to Open only for first trade.

If start date in Analysis Window is not a market day it seems it should use previous day, is it possible for me to make this happen through AFL or setting.

No, you are mistaken.
The backtest does not omit anything.

YOU are doing that.

If you are trading on CLOSING basis, then YOU skip first bar, because YOU decided to trade on close.

It has nothing to do with AmiBroker. It is YOUR decision that you skip first day because you choose NOT to use Open->Close movement.

Ok thank you! how might I show first trade as "OpenLong"? if the trade starts on 12/15/22 and stays long into January and I run backtest report for 12/31/22 begin date can I show first trade as "OpenLong"?

Selecting VIEW->Pad Non Trading Days does work, so far seems like best solution I guess? Can I turn this setting on in the afl?

Is it possible to create a warning message if first date of Backtest is a weekend?

Thanks again for the help, always amazing what you can do with Amibroker.

What do you mean Open->Close movement? Does this imply that I can change first trade to be on Open and remaining trades to be on Close?

However this still gives different results no? The buy occurred on 12/15/22 but I was running performance for YTD so I entered 12/31/22 and if it buys on Open of 1/3/23 this would be different than close of previous market day?

View pad seems to work, but I do not want to view my charts this way, is they another way that I can accomplish this?

Thank you.

If you want to see YTD performance of an ongoing strategy, why not just start the backtest on a reasonable date (like when you (hypothetically) started trading the strategy) and then use the Profit Table in the Report Charts to see monthly, annual, and YTD performance?

Thanks mradtke!

Yes this could work, I need to check if it is truly YTD and not on a monthly basis, but it still does not solve situation if you choose to look at some period from 3/31/2000 to 6/30/2008 or something like this. I am just randomly picking these dates, but what if you wanted to see this performance and one of those dates is a weekend, you performance report will not reflect actual performance. I am not saying there is anything wrong with Amibroker I am just saying the performance report does not reflect true performance if one of the dates is a weekend. Setting view-> pad weekends works , but it does change the moving averages. There must be some clever way or I can create a warning to change date or make Amibroker look at predecessor rather than successor for first equity value.

Something like this should work to provide you with a warning:

rangeFromDate = Status("RangeFromDate");
firstDateInRange = LastValue(ValueWhen(Status("firstBarInRange"), DateNum()));
if (rangeFromDate != firstDateInRange)
{
	Error("Warning! First date of analysis range is not a trading day");
}
2 Likes

Super mradtke!

This will at least let me know what I am doing! Thanks again!

Give this a look. I wrote this back in 2019 after scouring the forum. TrendXplorer and Amarjit provided clear guidance. I just re-packaged into a simple to read file. Use it with #INCLUDE to provide easy access to the variables.

/*
GH Period Begin End Variables.afl

By: Greg Hanson
2019-02-15

http://forum.amibroker.com/t/gtaa-timing-model-rotational-stragegy/4090/8		// AmiBroker implementation by TrendXplorer
http://www.amibroker.com/members/library/detail.php?id=1478&hilite=DayOfWeek

AmiBroker AFL code to determine periods beginning and ending weekly, monthly, etc. 
*/

// --- initialize variables for use in period calculations
curDow = DayOfWeek();
curMonth = Month();
curYear = Year();

// --- detect beginning of period ---
weekBegin 		= curDow < Ref( curDow, -1);
monthBegin 		= curMonth != Ref( curMonth, -1);
biMonthBeg 		= (curMonth%2 == 1) AND monthBegin;
quarterBegin 	= (curMonth%3 == 1) AND monthBegin;
yearBegin 		= curYear != Ref( curYear, -1);

// --- detect end of period ---
weekEnd			= curDow > Ref( curDow, 1);
monthEnd    	= curMonth != Ref( curMonth, 1 );
biMonthEnd  	= (curMonth%2  == 0) AND monthEnd;
quarterEnd  	= (curMonth%3  == 0) AND monthEnd;
yearEnd     	= curYear != Ref( curYear, 1);
1 Like

mradtke,

Even though startdate is market day I get the warning when I select parameters. Any suggestions? Is this best solution?

if(Status("actionex") != actionExAAParameters)
{
	rangeFromDate = Status("RangeFromDate");
        firstDateInRange = LastValue(ValueWhen(Status("firstBarInRange"), DateNum()));
       if (rangeFromDate != firstDateInRange)
      {
	        Error("Warning! First date of analysis range is not a trading day");
      }
}
action  = Status( "actionex" );
if( action != actionExAAParameters AND action != actionExEditVerifyFormula )
{
    rangeFromDate = DateTimeConvert(2, Status("RangeFromDate"));   

    if( IsNull(Lookup(C,rangeFromDate, 0)) )
    {
        Error( "Warning! First date of analysis range is not a trading day" );
    }
}

fxshrat,

Thanks for such a quick response. Could you please give an explanation for your reasoning for this code? Why is it better to use Lookup in this scenario? I hope if can understand the reasoning I can make better choices in the future.

Thanks Again for your and everyone who contributes here.

Well, Lookup looks up some element at specific datetime.
And if it does not exist then it returns Null (mode zero). That's all.

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