Site Meter The Lawyer Trader: June 2013

Tuesday, June 18, 2013

Thinkscript: The Trend_Fuzz Indicator for Think or Swim

Here is the thinksript code for one of my favorite custom made indicators.  I've used it quite a bit over the last three or four years..now maybe you can get some use out of it as well. Here's a chart of the SPY daily chart with the indicator:


 Here's the code:

###delete this line when pasting into thing or swim###

input ThermoLookBackBars = 50;
input PlotType = {default AdaptiveMovingAverages, Standard};

def HighLowScore = 1000 * ((high - high[1]) / (high[1]) +
(low - low[1]) / low[1]);

#######ATR TrailingStop Code
input trailType = {default modified, unmodified};
input ATRPeriod = 5;
input ATRFactor = 3.5;
input firstTrade = {default long, short};

def HiLo = Min(high - low, 1.5 * Average(high - low, ATRPeriod));
def HRef = if low <= high[1]
    then high - close[1]
    else (high - close[1]) - 0.5 * (low - high[1]);
def LRef = if high >= low[1]
    then close[1] - low
    else (close[1] - low) - 0.5 * (low[1] - high);
def ATRMod = ExpAverage(Max(HiLo, Max(HRef, LRef)), 2 * ATRPeriod - 1);

def loss;
switch (trailType) {
case modified:
    loss = ATRFactor * ATRMod;
case unmodified:
    loss = ATRFactor * AvgTrueRange(high, close, low, ATRPeriod);
}

rec state = {default init, long, short};
rec trail;
switch (state[1]) {
case init:
    if (!IsNaN(loss)) {
        switch (firstTrade) {
        case long:
            state = state.long;
            trail =  close - loss;
        case short:
            state = state.short;
            trail = close + loss;
    }
    } else {
        state = state.init;
        trail = Double.NaN;
    }
case long:
    if (close > trail[1]) {
        state = state.long;
        trail = Max(trail[1], close - loss);
    }
    else {
        state = state.short;
        trail = close + loss;
    }
case short:
    if (close < trail[1]) {
        state = state.short;
        trail = Min(trail[1], close + loss);
    }
    else {
        state = state.long;
        trail =  close - loss;
    }
}

def BuySignal = Crosses(state == state.long, 0, CrossingDirection.ABOVE);
def SellSignal = Crosses(state == state.short, 0, CrossingDirection.ABOVE);

plot TrailingStop = trail;
TrailingStop.Hide();
####End ATR Trailing Stop Code

def A = Highest(high[1], ThermoLookBackBars);
def B = Lowest(low[1], ThermoLookBackBars);

def FiftyTwoWeekHigh = A;

def FiftyTwoWeekLow = B;

def FiftyTwoWeekScore = 10 * (((high
- FiftyTwoWeekHigh) / FiftyTwoWeekHigh) + 
((low - FiftyTwoWeekLow) / FiftyTwoWeekLow));

def ThermoScore = ExpAverage(HighLowScore + FiftyTwoWeekScore, ThermoLookBackBars);

input FastLengthShort = 5;
input SlowLengthShort = 15;
input EffRatioShort = 10;
input FastLengthLong = 10;
input SlowLengthLong = 25;
input EffRatioLong = 5;

def AMA = MovAvgAdaptive(ThermoScore, FastLengthShort, SlowLengthShort, EffRatioShort);
def AMA2 = MovAvgAdaptive(ThermoScore, FastLengthLong, SlowLengthLong, EffRatioLong);

plot Line1;
Line1.Hide();
plot Line2;
Line2.Hide();

switch (PlotType) {
case AdaptiveMovingAverages:
    Line1 = AMA;
    Line2 = AMA2;
case Standard:
    Line1 = ThermoScore;
    Line2 = ThermoScore;
}

def InvisibleLine = close * 0;
plot Line3 = InvisibleLine;
Line3.Hide();

def Buy = Line1 > 0 and Line2 < 0 and state == state.long;
def StrongBuy = Line1 > 0 and Line2 >= 0 and state == state.long;
def Sell = Line1 < 0 and Line2 > 0 and state == state.short;
def StrongSell = Line1 < 0 and Line2 <= 0 and state == state.short;


AssignPriceColor(if Buy then Color.DARK_GREEN else if StrongBuy then Color.GREEN else if Sell then Color.DARK_RED else if StrongSell then Color.RED else Color.BLUE);

AddLabel(yes, Concat("Current Reading is ", (if Buy then "Up Trend" else if StrongBuy then "Strong Up Trend" else if Sell then "Down Trend" else if StrongSell then "Strong Down Trend" else "Neutral")),  if Buy then Color.DARK_GREEN else if StrongBuy then Color.GREEN else if Sell then Color.DARK_RED else if StrongSell then Color.RED else Color.GRAY);

#######Stochastic Code

declare upper;

input over_bought = 80;
input over_sold = 20;
input KPeriod = 10;
input DPeriod = 10;
input priceH = high;
input priceL = low;
input priceC = close;
input slowing_period = 3;
input smoothingType = {default SMA, EMA};

def lowest_k = Lowest(priceL, KPeriod);
def c1 = priceC - lowest_k;
def c2 = Highest(priceH, KPeriod) - lowest_k;
def FastK = if c2 != 0 then c1 / c2 * 100 else 0;

def FullK;
def FullD;

switch (smoothingType) {
case SMA:
    FullK = Average(FastK, slowing_period);
    FullD = Average(FullK, DPeriod);
case EMA:
    FullK = ExpAverage(FastK, slowing_period);
    FullD = ExpAverage(FullK, DPeriod);
}

def pricefilterup = if close > close[50] then 1 else 0;
def pricefilterdown = if close < close [50] then 1 else 0;

def OverBoughtAdd = if FullK < over_bought and FullK[1] >= over_bought then 1 else 0;
def OverSoldAdd = if FullK > over_sold and FullK[1] <= over_sold then 1 else 0;

def na = Double.NaN;

#Plot arrows
plot up = if StrongBuy and OverSoldAdd  and pricefilterup then low - (3 * TickSize()) else na;
plot down = if StrongSell and OverBoughtAdd and pricefilterdown then high + (3 * TickSize()) else na;
up.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
down.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);

###delete this line when pasting into think or swim###

Take care,

TLT

Monday, June 3, 2013

Equity Curve Analysis: Can Prediction Beef Up an Edge?

I've been doing lots of research lately on trading systems and analysis of trading system results.  Equity curve analysis is not necessarily a new idea, however, it is something that I've not spent much time on until now.  So how does it work and what can it tell you?  Well, I'll share what I've done.  Surely there are some great methods that have been discovered and refined by others, however, I just started from scratch and started tinkering with some math that made sense to me.  Sometimes you can get some good results with doing that..other times you spin your wheels but you generally end up learning something.  The following breakdown is my version of equity curve analysis and I share this not to necessarily say it works and that you should copy it, but to possibly share some ideas that others can build on.

First, I started off with a mechanical day trading system that I created.  The system itself doesn't really matter, I'll just say that it's a fairly decent performing momentum strategy that makes about one trade a day on average.  I took a few years worth of daily returns and plugged them into a spread sheet.  This creates a time series out of the daily returns and the great thing about having this is that you can line it up in a column next to other pieces of data or indicators and look for patterns in what is useful.

Second, I took several other pieces of data like:  1, 3, and 5 period daily ATR (average true range) readings, volume, prior day return, 2 Period RSI and a few other pieces of data, and I lined up the indicator data with the returns.  Then I shifted the return row (moved it down/forward one day) so that the end of day data that I had could be used to try to predict the return of the system for the next day.  This exercise alone was very interesting.  To determine what factors (indicators/data) were useful, I ran regression analysis on the various factors and looked for significant R Squared and P-Value readings to tell me what factors were actually predictive and what factors/indicators were more random and not useful.

Third, after determining a handful of factors that regression analysis said was useful, I normalized the data by taking all of the factors and then divided them by that day's close.  This way, an ATR would be useful whether the instrument being traded was currently traded at $10 a share or $100 a share.  I also took a five period moving average of the data and then divided each factor's data point by it's trailing 5 day average.  This is particularly useful for volume because an instrument might trade an average of 50k shares a day for a while and then bump up to 300K shares a year later.  I wanted to isolate above average and below average conditions relative to the instrument's recent trading history and then compare those reading to values from several years before.

Fourth, I took a neural net program and several years worth of data and trained the neural net with the data..this is straight data mining at this point.  The most important part of it was knowing that I'd likely used relevant factors (b/c of the regression analysis) and I'd used normalized data so the neural net would learn on apples-apples data.  After I had a fairly decent neural net that was trained with a significant amount of good data..it was time to start predicting.

Fifth, I had the neural net predict the system's returns for a couple of years of out of sample data.  One problem with neural net predictions, at least the one that I've been using, is that it's often decent at catching turning points but it's not great at predicting magnitude i.e. how large the move is.  So I took the daily change of the neural net prediction (for example if yesterday's prediction was +1% and today's is +.5%, the reading would actually be a -.5%) and this helps actually gauge whether the system will likely make more or less money tomorrow.  

Sixth, I made the output binary and had the data transformed into 0s and 1s.  A zero merely meant the system would likely lose money and a 1 merely means it will likely make money for the day.  Now it's time to throw in some money management or position size rules based on whether the prediction for the system would likely make money or lose money.  The initial results for the plus day/minus day readings are about 60%..meaning that sixty percent of the time the prediction was correct.  This is not a huge edge but it seems to be a little better than random.

Seventh, I tested a basic money management rule based on the predicted profitability of the following trading day.  If the prediction said that the system would make money the following day, a double sized position was taken on the trades for that day.  And if the prediction was that the system would lose money, a half position was taken for the trades of that day.

And the results please...

It appears that there's some merit to this.  Below is a chart of the returns of the predicted money management system along side the normal system without the money management rules.  Also, there is a line of random money management rules too just to see what a random result would look like.  The random line was developed by having a random 0 or 1 drawn from a random number generator and then applying the money management rule based on the random drawing..kind of a control group.  The fourth line of the graph is the difference between the prediction money management system and the straight returns of the system.  Here's the chart:


As you can see, the prediction money management system outperformed the non money management system by about 80% (the horizontal axis is the cumulative returns, just in a non percentage format..so 1.0 is 100% and 2.6 is actually 260% etc.) over 489 trading days.  Furthermore, the random money management system was actually in the middle of the predicted and straight returns.  Another interesting aspect is that the difference from the predicted money management and the regular returns levels off and stays flat..this could be indicative that the further the neural net gets from the training data, the less accurate it's predictions become.

The results indicate that the predictions on the profitable trading days tend to maximize gains and minimize losses over time.  It's obviously not perfect, but what is in finance and trading.  The prediction seems to add to the edge that this system has and it helps provide a fairly linear equity curve.  The analogy that I've used to explain this concept is that it's like counting cards in black jack.  Keeping up the count doesn't give you a huge edge, but it gives you enough of an edge to tell you when to bet more or less which allows a good black jack player to slowly grind out a profit.  Also, the count doesn't necessarily tell you to play the cards different from basic strategy (ok, it does some but for examples sake we can say it doesn't).  The predicted money management rules tell me nothing about the buy and sell signals from the system, it just says to dial up or dial down the position size..much like the count in black jack.

So where to go from here?  A little more testing wouldn't hurt.  Also, there's some work that can be done with the actual money management rules as well..i.e. something a little more complex than bet half or double for any given day.  I could easily run a solver program to optimize the position strategy, but that type of curve fitting is getting a little ahead of yourself if you're just testing to see if there is an edge to begin with.  Also, I could test the actual buying a selling rules based on the predictions..such as, let trades run longer on profitable days and cut losses quicker on predicted negative days.  I might dabble with some of these extensions, however, the more rules you add to it, the more curve fitting and the less robust the actual system will be.

For now, I have a fairly decent result showing me there's an edge with running and applying this type of analysis.  Hopefully this all made sense and maybe it will spark some ideas for some that are out there testing the same types of concepts.

One last thing to note..the use of a neural net was not particularly important with the example.  For those unfamiliar with them, they are really just another type of forecasting tool.  One could easily come up with something similar using linear regression, polynomial regression, arima, garch..etc.  Any type of forecasting can be used and combinations of these different methods can be used as well.  Just didn't want anyone to think that if you're not knowledgeable about A.I. and neural nets that it's not worth bothering...that is not the case at all.

Take care and good luck with your trading endeavors.

TLT