FRAMA Part III: Avoiding Countertrend Trading — A First Attempt

[This article was first published on QuantStrat TradeR » R, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

This post will begin to experiment with long-term directional detection using relationships between two FRAMA indicators. By observing the relationship between two differently parametrized FRAMAs and the relationship by virtue of the ATR, it will be possible to avoid counter-trend trading on both sides. We will see this example later:

As with TVI, when the signals and rules were swapped for the short end, the equity curve was an unmitigated disaster. Unlike the flat-during-bull-runs-and-permanently-popping-up equity curve of ETFHQ, this equity curve was a disaster. For those that read the final TVI post, the equity curve looked almost identical to that–just a monotonous drawdown until the crisis, at which point the gains aren’t made up, and then the losses continue. In short, there’s no need to go into depth of those statistics.

As the link to ETFHQ suggests, we will use a longer-term FRAMA (the n=252, FC=40, SC=252 version). The market will be in an uptrend when the fast FRAMA (the FRAMA from the previous post) is above this slower FRAMA, and vice versa. Furthermore, in order to avoid some whipsaws, the fast FRAMA will have to be ascending (or descending, during a downtrend), and the entry signal will be when the price crosses over (under) the faster FRAMA, with the exit being the reverse.

In the interest of brevity, since the sample period was an uptrend, then a great deal of strategies will look good on the upside. The question is whether or not the strategy does well on the short side, as the litmus test in testing a confirming indicator is whether or not it can create a positive expectation in a strategy that is counter-trend to the dominant trend in the sample data. As this is a replication of an implied idea by ETFHQ (rather than my own particular idea), let’s look at the code for the strategy. In this instance, both the long and short end of this symmetric strategy are included, and in RStudio, commenting or uncommenting one half or the other is as simple as highlight+ctrl+shift+C.

Here’s the code.

require(DSTrading)
require(IKTrading)
require(quantstrat)
require(PerformanceAnalytics)

initDate="1990-01-01"
from="2003-01-01"
to="2010-12-31"
options(width=70)

#to rerun the strategy, rerun everything below this line
source("demoData.R") #contains all of the data-related boilerplate.

#trade sizing and initial equity settings
tradeSize <- 10000
initEq <- tradeSize*length(symbols)

strategy.st <- portfolio.st <- account.st <- "FRAMA_II"
rm.strat(portfolio.st)
rm.strat(strategy.st)
initPortf(portfolio.st, symbols=symbols, initDate=initDate, currency='USD')
initAcct(account.st, portfolios=portfolio.st, initDate=initDate, currency='USD',initEq=initEq)
initOrders(portfolio.st, initDate=initDate)
strategy(strategy.st, store=TRUE)

#parameters

FCfast=4
SCfast=300
nFast=126
fastTriggerLag=1

FCslow=40
SCslow=252
nSlow=252
slowTriggerLag=1

period=10
pctATR=.02

#indicators
#Have to add in this function first, since the word 'slow' gets picked up
#by the HLC function as "low", which causes issues.
add.indicator(strategy.st, name="lagATR", 
              arguments=list(HLC=quote(HLC(mktdata)), n=period), 
              label="atrX")


add.indicator(strategy.st, name="FRAMA", 
              arguments=list(HLC=quote(HLC(mktdata)), n=nFast, FC=FCfast, 
                             SC=SCfast, triggerLag=fastTriggerLag),
              label="fast")


add.indicator(strategy.st, name="FRAMA", 
              arguments=list(HLC=quote(HLC(mktdata)), n=nSlow, FC=FCslow, 
                             SC=SCslow, triggerLag=slowTriggerLag),
              label="slow")

# #long signals
# 
# #condition 1: our fast FRAMA is above our slow FRAMA
# add.signal(strategy.st, name="sigComparison",
#            arguments=list(columns=c("FRAMA.fast", "FRAMA.slow"), relationship="gt"),
#            label="fastFRAMAaboveSlow")
# 
# #condition 2: our fast FRAMA is rising
# add.signal(strategy.st, name="sigComparison",
#            arguments=list(columns=c("FRAMA.fast", "trigger.fast"), relationship="gt"),
#            label="fastFRAMArising")
# 
# #setup: price crosses above the fast FRAMA
# add.signal(strategy.st, name="sigComparison",
#            arguments=list(columns=c("Close", "FRAMA.fast"), relationship="gte"),
#            label="CloseGteFastFRAMA")
# 
# #wrap our conditions and our setup into one entry signal
# add.signal(strategy.st, name="sigAND",
#            arguments=list(columns=c("fastFRAMAaboveSlow", "fastFRAMArising", "CloseGteFastFRAMA"), cross=TRUE),
#            label="longEntry")
# 
# #our old exit signal
# add.signal(strategy.st, name="sigCrossover",
#            arguments=list(columns=c("Close", "FRAMA.fast"), relationship="lt"),
#            label="longExit")

# #long rules

# add.rule(strategy.st, name="ruleSignal", 
#          arguments=list(sigcol="longEntry", sigval=TRUE, ordertype="market", 
#                         orderside="long", replace=FALSE, prefer="Open", osFUN=osDollarATR,
#                         tradeSize=tradeSize, pctATR=pctATR, atrMod="X"), 
#          type="enter", path.dep=TRUE)
# 
# add.rule(strategy.st, name="ruleSignal", 
#          arguments=list(sigcol="longExit", sigval=TRUE, orderqty="all", ordertype="market", 
#                         orderside="long", replace=FALSE, prefer="Open"), 
#          type="exit", path.dep=TRUE)



#short signals
add.signal(strategy.st, name="sigComparison",
           arguments=list(columns=c("FRAMA.fast", "FRAMA.slow"), relationship="lt"),
           label="fastFRAMAbelowSlow")

#condition 2: our fast FRAMA is falling
add.signal(strategy.st, name="sigComparison",
           arguments=list(columns=c("FRAMA.fast", "trigger.fast"), relationship="lt"),
           label="fastFRAMAfalling")


#setup: price crosses below the fast FRAMA
add.signal(strategy.st, name="sigCrossover",
           arguments=list(columns=c("Close", "FRAMA.fast"), relationship="lt"),
           label="CloseLtFastFRAMA")

#wrap our conditions and our setup into one entry signal
add.signal(strategy.st, name="sigAND",
           arguments=list(columns=c("fastFRAMAbelowSlow", "fastFRAMAfalling", "CloseLtFastFRAMA"), cross=TRUE),
           label="shortEntry")

#our old exit signal
add.signal(strategy.st, name="sigCrossover",
           arguments=list(columns=c("Close", "FRAMA.fast"), relationship="gt"),
           label="shortExit")

#short rules
add.rule(strategy.st, name="ruleSignal", 
         arguments=list(sigcol="shortEntry", sigval=TRUE, ordertype="market", 
                        orderside="short", replace=FALSE, prefer="Open", osFUN=osDollarATR,
                        tradeSize=-tradeSize, pctATR=pctATR, atrMod="X"), 
         type="enter", path.dep=TRUE)
add.rule(strategy.st, name="ruleSignal", 
         arguments=list(sigcol="shortExit", sigval=TRUE, orderqty="all", ordertype="market", 
                        orderside="short", replace=FALSE, prefer="Open"), 
         type="exit", path.dep=TRUE)


#apply strategy
t1 <- Sys.time()
out <- applyStrategy(strategy=strategy.st,portfolios=portfolio.st)
t2 <- Sys.time()
print(t2-t1)


#set up analytics
updatePortf(portfolio.st)
dateRange <- time(getPortfolio(portfolio.st)$summary)[-1]
updateAcct(portfolio.st,dateRange)
updateEndEq(account.st)

First, a quick little side-note: since many indicators look for the word “low”, my usage of the label “slow” would cause a bug if I added the lagATR indicator after that point. So try to avoid labels such as “high”, “low”, “open”, and “close” in your indicators, or at least declare all indicators that would look for the word “low” before declaring the indicator you label in part as “slow”, if you must go this route. Low is probably the easiest one for which to overlook this, since “slow” has so many applications to confirmatory indicators. (EG: SMA fast vs. SMA slow, etc.)

Again, to reiterate, the system will take a long position when price crosses over (under) a rising (falling) fast FRAMA that’s higher (lower) than the slow FRAMA, and exit that position when the price crosses back under (over) the fast FRAMA. The cross must happen when the other two conditions are intact, as opposed to a trade being entered when all three conditions come together, which may be in the middle of a trend.

As the majority of the sample data was in an uptrend (and the fact that the Andreas Clenow-inspired ATR order-sizing function pays enormous dividends in protecting for a limited time in a counter-trend), I decided to put the (slightly modified–with the one condition of rising in an uptrend or falling in a downtrend) system to the test by testing it on the non-dominant trend in the sample–that is, to see if the system can stay out at all points aside from the crisis.

Here are the (not-so-flattering) results:

Trade statistics:

                        EFA      EPP      EWA      EWC      EWG
Num.Txns              88.00    80.00    84.00    60.00    70.00
Num.Trades            43.00    40.00    40.00    30.00    35.00
Net.Trading.PL     -1393.99 -1585.91   981.89   875.47  -810.83
Avg.Trade.PL         -32.42   -39.65    24.55    29.18   -23.17
Med.Trade.PL        -106.64   -70.14     1.79   -74.83   -46.21
Largest.Winner      1238.56   775.14  1106.59  2195.51   449.23
Largest.Loser       -661.04  -466.95  -552.10  -565.80  -547.09
Gross.Profits       4211.42  3301.63  3677.16  3856.57  2719.33
Gross.Losses       -5605.42 -4887.54 -2695.27 -2981.10 -3530.16
Std.Dev.Trade.PL     344.67   284.29   263.92   462.93   226.75
Percent.Positive      32.56    30.00    50.00    26.67    48.57
Percent.Negative      67.44    70.00    50.00    73.33    51.43
Profit.Factor          0.75     0.68     1.36     1.29     0.77
Avg.Win.Trade        300.82   275.14   183.86   482.07   159.96
Med.Win.Trade         73.89   172.89    56.79   245.71   121.09
Avg.Losing.Trade    -193.29  -174.55  -134.76  -135.50  -196.12
Med.Losing.Trade    -156.80  -141.04   -88.56  -108.19  -187.47
Avg.Daily.PL         -33.19   -39.65    24.55    29.18   -23.17
Med.Daily.PL        -103.99   -70.14     1.79   -74.83   -46.21
Std.Dev.Daily.PL     337.33   284.29   263.92   462.93   226.75
Ann.Sharpe            -1.56    -2.21     1.48     1.00    -1.62
Max.Drawdown       -4696.67 -3090.61 -2193.20 -2032.07 -1990.83
Profit.To.Max.Draw    -0.30    -0.51     0.45     0.43    -0.41
Avg.WinLoss.Ratio      1.56     1.58     1.36     3.56     0.82
Med.WinLoss.Ratio      0.47     1.23     0.64     2.27     0.65
Max.Equity           560.75   355.13  2236.74  1567.71  1030.36
Min.Equity         -4135.91 -2881.48 -1702.76 -2019.64  -960.47
End.Equity         -1393.99 -1585.91   981.89   875.47  -810.83

                        EWH      EWJ      EWS      EWT      EWU
Num.Txns              48.00   102.00    74.00    56.00    82.00
Num.Trades            23.00    51.00    35.00    27.00    41.00
Net.Trading.PL      -420.23  -951.54  1424.73   292.07 -1756.36
Avg.Trade.PL         -18.27   -18.66    40.71    10.82   -42.84
Med.Trade.PL         -42.63   -54.18   -15.44     3.83   -46.42
Largest.Winner       309.93  1704.54  1165.10   437.42   664.06
Largest.Loser       -341.09  -460.39  -424.29  -367.22  -367.18
Gross.Profits        996.32  5137.50  4424.92  2072.64  2461.62
Gross.Losses       -1416.55 -6089.05 -3000.19 -1780.57 -4217.98
Std.Dev.Trade.PL     135.68   358.27   328.50   180.94   227.57
Percent.Positive      39.13    39.22    42.86    51.85    34.15
Percent.Negative      60.87    60.78    57.14    48.15    65.85
Profit.Factor          0.70     0.84     1.47     1.16     0.58
Avg.Win.Trade        110.70   256.88   294.99   148.05   175.83
Med.Win.Trade         91.25    80.40    84.30   100.73    66.50
Avg.Losing.Trade    -101.18  -196.42  -150.01  -136.97  -156.22
Med.Losing.Trade     -92.50  -173.06  -141.06  -144.50  -146.70
Avg.Daily.PL         -18.27   -18.66    40.71    10.82   -42.84
Med.Daily.PL         -42.63   -54.18   -15.44     3.83   -46.42
Std.Dev.Daily.PL     135.68   358.27   328.50   180.94   227.57
Ann.Sharpe            -2.14    -0.83     1.97     0.95    -2.99
Max.Drawdown       -1330.17 -3187.00 -1855.03 -1440.36 -3674.50
Profit.To.Max.Draw    -0.32    -0.30     0.77     0.20    -0.48
Avg.WinLoss.Ratio      1.09     1.31     1.97     1.08     1.13
Med.WinLoss.Ratio      0.99     0.46     0.60     0.70     0.45
Max.Equity           791.29  2235.46  2100.37   919.22   280.39
Min.Equity          -974.85 -2116.00 -1230.08  -885.33 -3394.12
End.Equity          -420.23  -951.54  1424.73   292.07 -1756.36

                        EWY      EWZ      EZU      IEF      IGE
Num.Txns              82.00    58.00    90.00    47.00    96.00
Num.Trades            41.00    29.00    45.00    24.00    48.00
Net.Trading.PL      2644.53   434.29 -1639.77 -1071.52 -1826.08
Avg.Trade.PL          64.50    14.98   -36.44   -44.65   -38.04
Med.Trade.PL         -36.18   -89.69   -70.13   -56.73   -79.30
Largest.Winner      2447.28  2495.03  1222.50   908.54  2146.42
Largest.Loser       -392.38  -382.20  -455.60  -717.52  -297.67
Gross.Profits       5519.58  3649.15  3231.22  2332.00  3162.60
Gross.Losses       -2875.04 -3214.86 -4870.99 -3403.52 -4988.68
Std.Dev.Trade.PL     441.24   521.49   282.42   339.58   349.80
Percent.Positive      48.78    24.14    37.78    41.67    20.83
Percent.Negative      51.22    75.86    62.22    58.33    79.17
Profit.Factor          1.92     1.14     0.66     0.69     0.63
Avg.Win.Trade        275.98   521.31   190.07   233.20   316.26
Med.Win.Trade        119.21    91.01    54.82    81.98    82.87
Avg.Losing.Trade    -136.91  -146.13  -173.96  -243.11  -131.28
Med.Losing.Trade     -97.92  -109.64  -155.51  -230.79  -113.58
Avg.Daily.PL          64.50    14.98   -36.44   -74.70   -38.04
Med.Daily.PL         -36.18   -89.69   -70.13   -71.76   -79.30
Std.Dev.Daily.PL     441.24   521.49   282.42   312.88   349.80
Ann.Sharpe             2.32     0.46    -2.05    -3.79    -1.73
Max.Drawdown       -1779.21 -3253.19 -3402.61 -3204.56 -3455.82
Profit.To.Max.Draw     1.49     0.13    -0.48    -0.33    -0.53
Avg.WinLoss.Ratio      2.02     3.57     1.09     0.96     2.41
Med.WinLoss.Ratio      1.22     0.83     0.35     0.36     0.73
Max.Equity          3319.81  2235.92   291.74  1170.92   255.57
Min.Equity         -1779.21 -1280.22 -3110.88 -2033.64 -3200.25
End.Equity          2644.53   434.29 -1639.77 -1071.52 -1826.08

                        IYR      IYZ      LQD      RWR      SHY
Num.Txns             106.00   108.00    43.00   114.00    33.00
Num.Trades            53.00    54.00    21.00    56.00    17.00
Net.Trading.PL     -3809.10 -3010.91  1863.94 -3690.62 -3715.43
Avg.Trade.PL         -71.87   -55.76    88.76   -65.90  -218.55
Med.Trade.PL        -107.50   -94.91   -14.30   -95.48  -165.13
Largest.Winner      1714.13  2673.04  1618.71  1455.78    23.93
Largest.Loser       -745.50  -463.08  -236.13  -476.51  -870.37
Gross.Profits       3465.76  3941.01  3050.21  2877.22    44.39
Gross.Losses       -7274.86 -6951.92 -1186.26 -6567.84 -3759.82
Std.Dev.Trade.PL     316.10   412.75   387.67   256.76   226.14
Percent.Positive      22.64    22.22    47.62    19.64    11.76
Percent.Negative      77.36    77.78    52.38    80.36    88.24
Profit.Factor          0.48     0.57     2.57     0.44     0.01
Avg.Win.Trade        288.81   328.42   305.02   261.57    22.19
Med.Win.Trade        125.96    52.77   178.87   144.25    22.19
Avg.Losing.Trade    -177.44  -165.52  -107.84  -145.95  -250.65
Med.Losing.Trade    -151.10  -150.12   -97.91  -134.83  -210.93
Avg.Daily.PL         -71.87   -55.76    80.29   -65.90  -223.39
Med.Daily.PL        -107.50   -94.91   -33.90   -95.48  -188.03
Std.Dev.Daily.PL     316.10   412.75   395.74   256.76   232.64
Ann.Sharpe            -3.61    -2.14     3.22    -4.07   -15.24
Max.Drawdown       -4518.57 -4628.68 -1075.56 -4511.52 -4429.88
Profit.To.Max.Draw    -0.84    -0.65     1.73    -0.82    -0.84
Avg.WinLoss.Ratio      1.63     1.98     2.83     1.79     0.09
Med.WinLoss.Ratio      0.83     0.35     1.83     1.07     0.11
Max.Equity           709.48   561.64  2649.32   820.90   714.45
Min.Equity         -3809.10 -4067.04  -318.88 -3690.62 -3715.43
End.Equity         -3809.10 -3010.91  1863.94 -3690.62 -3715.43

                        TLT      XLB      XLE      XLF      XLI
Num.Txns              73.00    72.00    82.00   104.00   106.00
Num.Trades            37.00    36.00    41.00    52.00    53.00
Net.Trading.PL     -2881.18    75.64  -738.57  -705.52 -1281.19
Avg.Trade.PL         -77.87     2.10   -18.01   -13.57   -24.17
Med.Trade.PL        -147.94   -45.01   -94.63   -71.06   -77.50
Largest.Winner      1425.91  1831.45  2087.67  1058.03  1218.87
Largest.Loser       -486.72  -423.07  -299.82  -711.69  -480.88
Gross.Profits       3086.09  3723.24  3173.04  5277.71  4948.54
Gross.Losses       -5967.27 -3647.61 -3911.61 -5983.23 -6229.73
Std.Dev.Trade.PL     338.67   369.57   371.02   313.49   307.17
Percent.Positive      24.32    36.11    14.63    34.62    30.19
Percent.Negative      75.68    63.89    85.37    65.38    69.81
Profit.Factor          0.52     1.02     0.81     0.88     0.79
Avg.Win.Trade        342.90   286.40   528.84   293.21   309.28
Med.Win.Trade        151.67   158.38   237.83   139.29   204.28
Avg.Losing.Trade    -213.12  -158.59  -111.76  -175.98  -168.37
Med.Losing.Trade    -195.66  -128.42   -96.70  -144.43  -147.64
Avg.Daily.PL         -86.21     2.10   -18.01   -13.57   -24.17
Med.Daily.PL        -149.61   -45.01   -94.63   -71.06   -77.50
Std.Dev.Daily.PL     339.60   369.57   371.02   313.49   307.17
Ann.Sharpe            -4.03     0.09    -0.77    -0.69    -1.25
Max.Drawdown       -3946.88 -2772.07 -2742.16 -2243.85 -2727.83
Profit.To.Max.Draw    -0.73     0.03    -0.27    -0.31    -0.47
Avg.WinLoss.Ratio      1.61     1.81     4.73     1.67     1.84
Med.WinLoss.Ratio      0.78     1.23     2.46     0.96     1.38
Max.Equity           139.90  1411.59   335.20  1066.45   848.83
Min.Equity         -3806.97 -1978.82 -2742.16 -1573.88 -2028.21
End.Equity         -2881.18    75.64  -738.57  -705.52 -1281.19

                        XLK      XLP      XLU      XLV      XLY
Num.Txns              94.00    84.00    86.00    62.00    66.00
Num.Trades            47.00    41.00    42.00    31.00    33.00
Net.Trading.PL     -1651.16 -3264.51 -4665.83 -2093.02   507.06
Avg.Trade.PL         -35.13   -79.62  -111.09   -67.52    15.37
Med.Trade.PL         -99.55  -129.52   -90.84   -80.14  -100.97
Largest.Winner      2403.16  1008.09   174.64  1447.68  2090.68
Largest.Loser       -526.85  -460.10  -419.92  -533.05  -352.17
Gross.Profits       4484.79  2660.58   600.44  2419.62  4101.12
Gross.Losses       -6135.95 -5925.09 -5266.27 -4512.64 -3594.06
Std.Dev.Trade.PL     419.01   287.43   134.66   364.01   430.90
Percent.Positive      31.91    19.51    21.43    16.13    30.30
Percent.Negative      68.09    80.49    78.57    83.87    69.70
Profit.Factor          0.73     0.45     0.11     0.54     1.14
Avg.Win.Trade        298.99   332.57    66.72   483.92   410.11
Med.Win.Trade        106.63    84.26    46.23    86.14   202.57
Avg.Losing.Trade    -191.75  -179.55  -159.58  -173.56  -156.26
Med.Losing.Trade    -168.10  -161.95  -152.33  -128.20  -151.78
Avg.Daily.PL         -35.13   -79.62  -111.09   -67.52    15.37
Med.Daily.PL         -99.55  -129.52   -90.84   -80.14  -100.97
Std.Dev.Daily.PL     419.01   287.43   134.66   364.01   430.90
Ann.Sharpe            -1.33    -4.40   -13.10    -2.94     0.57
Max.Drawdown       -4435.53 -5189.24 -4665.83 -3779.96 -2264.20
Profit.To.Max.Draw    -0.37    -0.63    -1.00    -0.55     0.22
Avg.WinLoss.Ratio      1.56     1.85     0.42     2.79     2.62
Med.WinLoss.Ratio      0.63     0.52     0.30     0.67     1.33
Max.Equity           861.83  1156.76     0.00  1686.94  2771.26
Min.Equity         -3573.71 -4032.47 -4665.83 -2093.02  -613.72
End.Equity         -1651.16 -3264.51 -4665.83 -2093.02   507.06


> (aggPF <- sum(tStats$Gross.Profits)/-sum(tStats$Gross.Losses))
[1] 0.7443694
> (aggCorrect <- mean(tStats$Percent.Positive))
[1] 31.708
> (numTrades <- sum(tStats$Num.Trades))
[1] 1166
> (meanAvgWLR <- mean(tStats$Avg.WinLoss.Ratio))
[1] 1.824333

In other words, we can already see that the proposed confirmatory indicator is a dud. To display the raw instrument daily stats at this point would also be uninteresting, so we’ll move past that.

Duration statistics:

durStats <- durationStatistics(Portfolio=portfolio.st, Symbols=sort(symbols))
print(t(durStats))
      EFA EPP EWA EWC EWG EWH EWJ EWS EWT EWU EWY EWZ EZU IEF IGE IYR
Min     1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
Q1      2   1   1   4   1   2   1   3   1   1   1   1   2   2   1   1
Med     4   4   4   8   5   4   4   5   5   4   3   5   4   5   5   3
Mean   10   8   9  13  10   7   9  11  13   8  10  11   8  10   9   7
Q3      7   8   7  16  10   6   8  10  10  10   7   8   7   8   8   7
Max    83  72  79  74  77  55  98  76  79  72 105  71  83  66  90  59
WMin    1   1   1   7   1   1   1   1   1   1   1   1   1   1   6   1
WQ1     3   2   1  14   1   3   1   4   2   1   1   4   2   7   8   6
WMed   10   6   6  23   5   6   2  10  10   4   3   8   4   8  18   9
WMean  21  14  13  26  13  11  13  18  22  13  16  24  11  20  26  15
WQ3    26  14   9  29  13   7   9  26  21  15  14  41   7  39  30  17
WMax   83  72  79  74  77  55  98  76  79  72 105  71  83  66  90  59
LMin    1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1
LQ1     2   1   1   4   2   2   2   3   1   2   1   1   2   1   1   1
LMed    4   3   4   6   4   3   4   4   4   4   1   4   5   2   3   3
LMean   4   5   6   9   6   4   6   5   4   6   3   7   6   4   4   4
LQ3     6   6   6  12   8   6   8   5   5   7   3   7   7   6   6   5
LMax   21  23  22  33  21  14  25  32   8  29  12  68  26  10  14  36

      IYZ LQD RWR SHY TLT XLB XLE XLF XLI XLK XLP XLU XLV XLY
Min     1   1   1   1   1   1   1   1   1   1   1   1   1   1
Q1      1   1   1   4   2   2   1   2   2   2   2   2   2   2
Med     5   3   3   6   4   6   4   5   4   3   4   4   5   5
Mean    9   9   6   9   8  12  10  13   9   9   8   6   8  14
Q3      7   5   6  12   7  14   7  18  11  10   7   6   8  11
Max   105  91  67  29  55  82  97  91  55  67  67  34  35 100
WMin    1   1   1   3   1   2   7   1   1   1   1   1   3   2
WQ1     3   3   8   4   2   7   9   3   3   2   4   1   7   7
WMed    8   5  10   6   6  17  22  20  10  15  15   4  17  26
WMean  21  17  18   6  18  23  40  26  17  20  22   9  19  35
WQ3    28  18  24   7  32  22  69  34  26  26  32  13  35  56
WMax  105  91  67   8  55  82  97  91  55  67  67  34  35 100
LMin    1   1   1   1   1   1   1   1   1   1   1   1   1   1
LQ1     1   1   1   4   2   2   1   2   2   1   1   2   1   1
LMed    4   1   2   6   4   3   3   4   4   3   3   4   4   4
LMean   5   2   3   9   5   6   5   6   6   4   4   4   6   4
LQ3     7   3   5  12   7   8   6   8  10   5   6   5   7   6
LMax   29   7  15  29  19  29  40  21  19  21  20  16  30  13

Basically, we can see that there are some really long trades that win, but between this table and the previous trade stats output, that is more than swamped by the legions of losers. Here is the market exposure:


#market exposure
tmp <- list()
length(tmp) <- length(symbols)
for(i in 1:nrow(dStats)) {
  totalDays <- nrow(get(rownames(dStats)[i]))
  mktExposure <- dStats$Total.Days[i]/totalDays
  tmp[[i]] <- c(rownames(dStats)[i], round(mktExposure, 3))
}
mktExposure <- data.frame(do.call(rbind, tmp))
colnames(mktExposure) <- c("Symbol","MktExposure")
print(mktExposure)

   Symbol MktExposure
1     EFA       0.168
2     EPP       0.125
3     EWA       0.149
4     EWC        0.15
5     EWG       0.133
6     EWH       0.063
7     EWJ       0.176
8     EWS       0.145
9     EWT       0.133
10    EWU       0.135
11    EWY       0.152
12    EWZ       0.126
13    EZU       0.147
14    IEF       0.102
15    IGE       0.168
16    IYR       0.152
17    IYZ       0.186
18    LQD       0.083
19    RWR       0.149
20    SHY       0.052
21    TLT       0.126
22    XLB       0.168
23    XLE        0.16
24    XLF       0.249
25    XLI       0.196
26    XLK       0.168
27    XLP       0.129
28    XLU       0.101
29    XLV         0.1
30    XLY       0.168

In other words, even though the market exposure is rather small, the system still manages to hemorrhage a great deal during those small exposures, which does not sing many praises for the proposed system.

Here is the code for a cash sharpe and the equity curve comparisons:

#portfolio cash PL
portString <- paste0("portfolio.", portfolio.st)
portPL <- .blotter[[portString]]$summary$Net.Trading.PL

#Cash Sharpe
(SharpeRatio.annualized(portPL, geometric=FALSE))

#Portfolio comparisons to SPY
instRets <- PortfReturns(account.st)

#Correlations
instCors <- cor(instRets)
diag(instRets) <- NA
corMeans <- rowMeans(instCors, na.rm=TRUE)
names(corMeans) <- gsub(".DailyEndEq", "", names(corMeans))
print(round(corMeans,3))
mean(corMeans)

portfRets <- xts(rowMeans(instRets)*ncol(instRets), order.by=index(instRets))
portfRets <- portfRets[!is.na(portfRets)]
cumPortfRets <- cumprod(1+portfRets)
firstNonZeroDay <- as.character(index(portfRets)[min(which(portfRets!=0))])
getSymbols("SPY", from=firstNonZeroDay, to=to)
SPYrets <- diff(log(Cl(SPY)))[-1]
cumSPYrets <- cumprod(1+SPYrets)
comparison <- cbind(cumPortfRets, cumSPYrets)
colnames(comparison)  <- c("strategy", "SPY")
chart.TimeSeries(comparison, legend.loc = "topleft",
                 colors=c("green","red"))

Which gives us the following results:

(SharpeRatio.annualized(portPL, geometric=FALSE))
                                Net.Trading.PL
Annualized Sharpe Ratio (Rf=0%)     -0.2687879

In short, the idea of using a “slower” FRAMA does not seem to hold much water. And here are the portfolio statistics to confirm it:

> SharpeRatio.annualized(portfRets)
                                      [,1]
Annualized Sharpe Ratio (Rf=0%) -0.2950648
> Return.annualized(portfRets)
                         [,1]
Annualized Return -0.01560975
> maxDrawdown(portfRets)
[1] 0.1551006

But why?

For that, we’ll look at a picture of the equity curve of an individual instrument, complete with overlaid indicators.

chart.Posn(portfolio.st, "XLF")
tmp <- FRAMA(HLC(XLF), n=nFast, FC=FCfast, SC=SCfast, triggerLag=fastTriggerLag)
add_TA(tmp$FRAMA, on=1, col="purple", lwd=3)
add_TA(tmp$trigger, on=1, col="blue", lwd=0.5)
tmp2 <- FRAMA(HLC(XLF), n=nSlow, FC=FCslow, SC=SCslow, triggerLag=slowTriggerLag)
add_TA(tmp2$FRAMA, on=1, col="orange", lwd=3)
tmp2 <- lagATR(HLC=HLC(XLF), n=period)
add_TA(tmp2$atr, col="purple", lwd=2)

Which produces the following plot:

The primary indicator is in purple, while the confirmatory indicator is in orange. And now we see the reason why: because although the FRAMA (n=252, FC=40, SC=252) is a seemingly fine parametrization in and of itself, as a “big-picture/long-term-trend/greater smoothing” indicator, it does not seem like the best choice, at least in the conventional sense as using something such as the SMA200, ROC200 > 0, or RS Rank (see this post from SystemTraderSuccess).

Why? Because from my intuition, adaptive moving average indicators all aim to do the same thing–they aim to be a more accurate way of aggregating lots of data in order to tell you what is happening to as close as current time as they can get. That is, if you look at the presentation by Dr. John Ehlers (see this link), you’ll notice how similar all of the indicators are. All of them effectively aim to maximize near-term smoothness and eliminate as much lag as possible. That is, if you’re looking to make short-term momentum trades that last five days, if your indicator has a five-day lag (EG a 10-day running median), well, your indicator isn’t of much use in that case, because by the time you receive the signal, the opportunity is over!

However, while eliminating lag is usually desirable, in one case, it isn’t. To go off on a tangent, the Japanese trading system called Ichimoku Kinko Hyo (which may be investigated in the future), created by Goichi Hosoda, deliberately makes use of lagging current price action to create a cloud. That is, if you want a confirmatory indicator, you want something robust (especially to the heightened volatility during corrections, bear markets, downtrends, etc.), and something that *has* a bit of lag to it, to confirm the relationship between the more up-to-date indicator (E.G. an adaptive moving average, a short-term oscillator such as RSI2, etc.), and the overarching, long-term trend.

The failure to do so in this case results in problematic counter-trend trades before the financial crisis. While the trading during the financial crisis had a very choppy equity curve during the height of the crisis itself, this was for an individual instrument, and note, that by the end of the crisis, the strategy had indeed made money. The greater problem was that due to the similarities in kind of the confirmatory indicator with the one used for entries and exits, then occasionally, the confirmatory indicator would overtake the indicator it was supposed to confirm, even in a sideways or upwards market, which resulted in several disastrous trades.

And while the indicator used for entries and exits should be as up-to-date as possible so as to get in and out in as timely a fashion as possible, a confirmatory indicator, first and foremost, should not reverse the entire system’s understanding of the market mode on a whim, and secondly, should try to be more backward looking, so as to better do its job of confirmation. Thus, in my opinion, the recommendation of this “slower” FRAMA to be used as a confirmatory indicator by ETFHQ was rather ill-advised. Thus, the investigation will continue into finding a more suitable confirmatory indicator.

Thanks for reading.


To leave a comment for the author, please follow the link and comment on their blog: QuantStrat TradeR » R.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)