A trend following investment strategy buys an asset that has risen recently and sells it when it has stopped rising. A common way to define"has risen" is to see if the last price exceeds the moving average of closing prices over the last N days. An R script to test such strategies for various exchange-traded funds (ETFs) and a translation to Fortran largely done by ChatGPT o3-mini (given the R script and its output) are at
The Fortran program output is
prices_file: prices.csv
Symbol First_Date Last_Date Days
SPY 1993-01-29 2025-03-28 8097
EFA 2001-08-27 2025-03-28 5932
EEM 2003-04-14 2025-03-28 5526
EMB 2007-12-19 2025-03-28 4346
HYG 2007-04-11 2025-03-28 4522
LQD 2002-07-30 2025-03-28 5704
Unconditional returns and volatility
Symbol Ann_Ret Ann_Vol
SPY 9.72 18.61
EFA 5.43 20.97
EEM 8.10 27.26
EMB 4.17 11.05
HYG 4.67 11.15
LQD 4.52 8.44
Returns and volatility conditional on the price being above or below the moving average
Symbol MA_Length Ann_Ret_Above Ann_Vol_Above Fraction_Above Ann_Ret_Below Ann_Vol_Below Fraction_Below
SPY 100.00 8.39 13.52 0.73 13.48 28.35 0.27
SPY 200.00 10.33 13.92 0.77 7.78 29.65 0.23
EFA 100.00 8.13 14.78 0.65 2.05 29.08 0.35
EFA 200.00 7.93 14.79 0.69 1.66 30.87 0.31
EEM 100.00 10.34 20.46 0.61 1.14 35.53 0.39
EEM 200.00 4.37 20.56 0.64 8.65 36.97 0.36
EMB 100.00 6.05 8.48 0.66 0.38 15.13 0.34
EMB 200.00 5.23 7.98 0.71 3.60 16.39 0.29
HYG 100.00 5.45 7.47 0.74 3.20 17.95 0.26
HYG 200.00 5.57 6.72 0.76 2.82 19.70 0.24
LQD 100.00 5.31 6.28 0.68 1.95 11.89 0.32
LQD 200.00 4.66 6.40 0.72 2.07 12.42 0.28
Looking at the lines
Returns and volatility conditional on the price being above or below the moving average
Symbol MA_Length Ann_Ret_Above Ann_Vol_Above Fraction_Above Ann_Ret_Below Ann_Vol_Below Fraction_Below
SPY 100.00 8.39 13.52 0.73 13.48 28.35 0.27
SPY 200.00 10.33 13.92 0.77 7.78 29.65 0.23
One sees that since 1993, U.S. annualized stock returns have been higher, 10.33% vs. 7.78%, with a much lower annualized standard deviation (volatility), 13.92% vs. 29.65%, after SPY (which tracks the S&P 500 index) has closed above rather than below its 200-day moving average. For the 100-day moving average the volatility pattern is the same, but returns are higher when the price is below the moving average. Higher stock market volatility after declines than rises has been modelled by asymmetric GARCH models, implemented in the NAG library and by me in Fortran (WIP).
The Fortran code was largely auto-generated and is not pretty. I would write a cleaner program using my dataframe type and the statistics functions in that repo. The price data can be obtained from an R script using the quantmod package.