How to plot percentage change from year ago chart

How to plot percentage change from year ago e.g

@chunwai try something like this:

if (Interval() != inDaily) 
	Title = EncodeColor(colorYellow) + "You need to execute this formula ONLY using the DAILY interval.";
	yOffset = 260;
	yClose = Ref( C, -yOffset );
	YPctCh = ( C - yClose ) / yClose;

	GraphXSpace = 5;
	SetChartOptions( 2, chartShowDates, chartGridPercent | chartGridMiddle );
	_N( Title = StrFormat( "{{NAME}} - {{INTERVAL}} {{DATE}} Close %g (%.1f%%) - 1Y %% Change (%2.2f%%)", C, SelectedValue( ROC( C, 1 ) ), yPctCh * 100 ) );
	Plot( 0, "", colorAqua, styleDashed );
	Plot( yPctch * 100, "1Y % ch. ", colorWhite );
	SetBarsRequired(sbrAll, sbrAll);

To get a very similar chart to the FRED one, you need to have the same data points. For this, you may want to download a 10Y price history (as a .csv file) from their page:

FRED - S&P500 Chart/Data

Before importing the data into AmiBroker, you need to edit the file searching all the lines where, instead of a valid Close price, you'll see a dot (these days correspond to holidays).
Just fill in the previous day Close price.
Replace also the first line, with something similar to:


(I selected SP500 as the symbol to import; change to whatever is appropriate for you: be sure to use a new symbol name that is NOT already present in your database).

Save the edited file and import it using the Import Wizard. (Import only 2 fields "YMD" and "Close", skip all the others).

The offset of 260, that I used in my code snippet, seems appropriate for the FRED data file.

Probably, for other data sources, it could be set to 252 (this value, in USA markets, usually correspond to the estimated trading days un a calendar year).

Here the result:



@beppe you certainly do a comprehensive job when someone asks a question. But I just wanted to post my version for fun. If using Daily chart or daily data there are usually 252 trading days per year

OneYearPctChg = ROC(C, 252);
Plot(OneYearPctChg, "OneYearPctChg", colorAqua, styleLine);

And comparing @beppe chart and mine (I matched the lookback periods for comparison).


@portfoliobuilder, your solution is probably all @chunwai needs! :smile:

I (for fun too) spent a bit of extra time dabbling with the FRED data and wondering why the also report some trade holidays days with "empty" close price. "Padding" that missing data allowed me to draw a chart as close as possible to theirs.

In any case, the lesson I learned from this small exercise is that not all the historical data series are the same (not only for prices differences) but also for the way they handle the trade holidays that happens during regular weekdays (Mon-Fri).

Moreover, I think that for a chart like this (especially when dealing with stocks and ETFs), it is essential to know if the used prices are (or not) the "adjusted" ones (accounting for all the past corporate actions such as stock splits, dividends/distributions, and rights offerings).


Thx @beppe detailed reply. I have SP500 data from another data source. Sometimes I import other data e.g. M2 into amibroker for reference.
I have a simple afl for auto import purpose.

var AmiBroker = new ActiveXObject( "Broker.Application" );
	function Import( filename )
			AmiBroker.Import(0,filename, "yahoo1.format");
			WScript.echo( "Updating US data completed" );

1 Like
OneYearPctChg = ROC(C, 252);
Plot(OneYearPctChg, "OneYearPctChg", colorAqua, styleLine);

I also even consider to use ROC to plot this, because no of days for every year is different.
It will be difficult to plot exactly like FRED.

@chunwai, to make the matter more clear, the ROC() function is perfectly fine (and faster) for this task.

My yPctCh calculation is the same used by the default ROC () mode, just without multiplying the final result by 100.

From the documentation:

roc( ARRAY, periods = 12, absmode = False )
calculates the periods rate-of-change of ARRAY expressed as percentage.

  - if absmode = False the value returned is 100*( array - ref( array, -periods ) )/ref( array, -periods )
  - if absmode = True the value returned is 100*( array - ref( array, -periods ) )/abs( ref( array, -periods ) )

(I then multiply the result * 100, for display purposes, in the Title, and in the Plot).

I used this slower, two-step approach since to figure out what was the correct offset to use with the original FRED data series I also used an exploration to verify the yClose array values (a piece of code that I removed before posting the snippet).
But probably before posting, I should have replaced my code with ROC() too!