Get Updates:
Email
Twitter
RSS

Many of you asked for a method to backtest this study. It is a relatively simple matter to construct a thinkScript strategy from a study. Most of the code from any study can be copied straight across into your strategy. You will need to declare the strategy mode with a declare statement with one of the following arguments:

LONG_ENTRY; LONG_EXIT; SHORT_ENTRY; SHORT_EXIT

Since you can’t plot anything from a strategy, all plot statements for variables that will be part of the strategy logic should be converted to def statements and their formatting commands removed. Other non-essential plot statements and associated formatting can be removed entirely. Your entire goal when creating a strategy is to define a binary condition that will trigger a trade. In this particular case we are looking for a moving average cross. I had already coded that into the study for use with the signal dots:

def buySignal = if TypicalPriceZeroLagTEMA > HeikinAshiZeroLagTEMA and TypicalPriceZeroLagTEMA[1] <= HeikinAshiZeroLagTEMA[1] then 1 else 0;

With this condition we can now add the other essential piece of code for strategies – the addOrder(condition,price) command:

addOrder(buySignal,open[-1]);

Here you see the binary condition buySignal entered as the trigger argument and the price is the next bar’s open, hence the [-1] indexing.

Strategies only work in pairs. You can have a Long Entry and Long Exit pair or a Long Entry and Short Entry pair etc. In this case I used a daily chart with six months of data to run the backtest. With proper money and stop management to minimize drawdowns this looks to be a viable strategy. Profit was $7400 on a single ES contract over the preceding six month period. Full results here.

Vervoort Crossover Strategy Analysis

Vervoort Crossover Strategy Analysis

The Long Entry Code:


declare LONG_ENTRY;

input period = 55;
def price = (high+low+close)/3;

def TMA1 = 3 * ExpAverage(price, period)
- 3 * ExpAverage(ExpAverage(price, period), period)
+ ExpAverage(ExpAverage(ExpAverage(price, period), period), period);

def TMA2 = 3 * ExpAverage(TMA1, period)
- 3 * ExpAverage(ExpAverage(TMA1, period), period)
+ ExpAverage(ExpAverage(ExpAverage(TMA1, period), period), period);

def difference = TMA1 - TMA2;
def TypicalPriceZeroLagTEMA = TMA1 + difference;

rec haopen = compoundValue(1, ((open[1] + high[1] + low[1] + close[1]) / 4
+ haopen[1]) / 2, hl2);
def haclose = ((open + high + low + close) / 4 + haopen + Max(high, haopen)
+ Min(low, haopen)) / 4;

def HATMA1 = 3 * ExpAverage(haclose, period)
- 3 * ExpAverage(ExpAverage(haclose, period), period)
+ ExpAverage(ExpAverage(ExpAverage(haclose, period), period), period);

def HATMA2 = 3 * ExpAverage(HATMA1, period)
- 3 * ExpAverage(ExpAverage(HATMA1, period), period)
+ ExpAverage(ExpAverage(ExpAverage(HATMA1, period), period), period);

def HAdifference = HATMA1 - HATMA2;
def HeikinAshiZeroLagTEMA = HATMA1 + HAdifference;

def buySignal = if TypicalPriceZeroLagTEMA > HeikinAshiZeroLagTEMA
and TypicalPriceZeroLagTEMA[1] <= HeikinAshiZeroLagTEMA[1] then 1 else 0;

addOrder(buySignal,open[-1]);
setColor(color.green);

The Short Entry Code:


declare SHORT_ENTRY;

input period = 55;
def price = (high+low+close)/3;

def TMA1 = 3 * ExpAverage(price, period)
- 3 * ExpAverage(ExpAverage(price, period), period)
+ ExpAverage(ExpAverage(ExpAverage(price, period), period), period);

def TMA2 = 3 * ExpAverage(TMA1, period)
- 3 * ExpAverage(ExpAverage(TMA1, period), period)
+ ExpAverage(ExpAverage(ExpAverage(TMA1, period), period), period);

def difference = TMA1 - TMA2;
def TypicalPriceZeroLagTEMA = TMA1 + difference;

rec haopen = compoundValue(1, ((open[1] + high[1] + low[1] + close[1]) / 4
+ haopen[1]) / 2, hl2);
def haclose = ((open + high + low + close) / 4 + haopen + Max(high, haopen)
+ Min(low, haopen)) / 4;

def HATMA1 = 3 * ExpAverage(haclose, period)
- 3 * ExpAverage(ExpAverage(haclose, period), period)
+ ExpAverage(ExpAverage(ExpAverage(haclose, period), period), period);

def HATMA2 = 3 * ExpAverage(HATMA1, period)
- 3 * ExpAverage(ExpAverage(HATMA1, period), period)
+ ExpAverage(ExpAverage(ExpAverage(HATMA1, period), period), period);

def HAdifference = HATMA1 - HATMA2;
def HeikinAshiZeroLagTEMA = HATMA1 + HAdifference;

def sellSignal = if TypicalPriceZeroLagTEMA < HeikinAshiZeroLagTEMA
and TypicalPriceZeroLagTEMA[1] >= HeikinAshiZeroLagTEMA[1] then 1 else 0;

addOrder(sellSignal, open[-1]);
setColor(color.red);

20 Responses to “Vervoort Crossover Strategy and Analysis”

  1. Bill Smith says:

    Thanks Eric. No wonder I couldn’t figure it out. I thought there was a way to call a study from within the strategy, so I was trying to do that.

    This is very helpful.

    bill

  2. thinkscripter says:

    That would be nice….but alas, not yet.

  3. Chris says:

    Dude, you rock – your explantion has opened my eyes greatly – keep it going. Thanks Much

  4. Dennis says:

    Outstanding….wish I would have scrolled down enough the see the code snip ;) That said your explanation was good enough to port the study over to a strategy and learned allot along the way…now if I only knew how to tweak my draws.

    This is great stuff!!

  5. manatrader says:

    Thanks for this, I’ve been working with strategies a lot to cross check results from metatrader, finding plenty of variance, trust TOS results more. Wish it could handle stops, haven’t found any way for exit rules to reference entry price :\

  6. Bill Smith says:

    Eric,

    Check this out. I pulled out some old strategy code and I thought I remembered that you could indeed reference a study from inside a strategy. I remember writing to TOS help and getting the answer. I’ve pasted the whole code here (forgive my simplicity… I’m a trader, not a programmer), and the key word is “reference”. I was able to pull values from the ADX_DMI studies without having to bring the actual code it. This is what I was trying to do with your studies and could’t make work, but I think I just wasn’t passing the required parameters properly.

    Bill

    declare LONG_ENTRY;

    input DMI = 13;
    input ADX_length = 8;
    input ADX_signal = 25;
    input Price_Breakout_Length = 30;
    input DMI_Breakout_Length = 20;

    def dmiPlus = reference diplus(length = DMI);
    def dmiMinus = reference diminus(length = DMI);
    def adxLine = reference adx(length = ADX_length);

    def condition = adxLine > ADX_signal AND
    High > Highest( High[1], Price_Breakout_Length ) AND
    dmiPlus > Highest(dmiPlus[1],DMI_Breakout_Length);

    addOrder(condition);

  7. Prospectus says:

    @Bill Smith: You can’t call a user-defined study inside of a strategy. But you can replicate the study in the code and use it in your strategy.

    @manatrader: When I make strategies with trailing stops, I replicate the entire entry logic inside of the trailing stop strategy. This way, the trailing stop logic knows where to begin trailing and has the entry price available.

  8. [...] two recent posts, ThinkScripter (a great new blog that features studies and strategies coded for the thinkScript language used on [...]

  9. neutral says:

    Can anyone tell me what I’m doing wrong?
    When I cut the code from above and paste it into the source box for a new study, I get three sections highlighted in red:
    line 1: “LONG_ENTRY” is highlighted in red
    line 34: “addOrder” is highlighted in red
    line35: “setColor” is highlighted in red

    Beneath that in the next box (under the link for thinkScript Manual) are the notations:
    No such function: addOrder at 34:1
    No such function: setColor at 35:1
    Unexpected declare: Long_Entry at 1:9
    At least one plot should be defined
    ________________________________________________
    Thanks in advance for any assistance

    • neutral,
      These are not studies but strategies. You need to cut and paste each one into a new TOS strategy. One will be the long side of the strategy and the other will be the short side. Together they work to create an always in trading approach going from long to short and back again.
      Eric

  10. JB says:

    Hi Eric – Just ran in to your website, you have done some amazing things with the TOS scripting. Can you tell me if there is a way to exit EOD in the script while backtesting? Also, can there be alerts generated based on an EMA crossover strategy?
    Thanks much,

    JB

    • JB,
      You can create exit strategies using the TOS time functions such as getSecondsTill(time). You will need both a long and short exit strategy with the time function to create a binary exit signal. Yes, EMA crossovers are easy to create into strategies almost identical to the Vervoot crossover.

  11. jomo says:

    Hello Think Scripter,

    I wanted to know if it is possible to add off set orders with a limit and/or stop amount? Also is it possible to turn the Fisher Transform Signal to a Strategie? I’ve tried bt with no luck!

  12. Mark says:

    Thanks for your great work on scripting for the TOS charts. I appreciate it.

    Have you noticed that on some charts the entries and exits don’t always correspond to the dots painted by the VerVoortCrossover study? I’m still trying to figure out why but haven’t discovered why. I thought it’s may be only happening on a tick chart but I’ve also seen it happen on time charts too.

    • Mark,
      I have always noted strange behavior from strategies. Perhaps it is my lack of skill in coding them but I have seen inconsistent results on occasion as well as strategies that act different in real-time as opposed to historically. Often times merely resetting a chart period will cause different results from a strategy. For this reason, I only use TOS strategies as a crude backtest of a study/trading method. I never use them real-time to trade with.
      Eric

  13. Craig says:

    Eric,

    Please post a brief step-by-step on how to backtest a strategy like this one in TOS. Thanks again for your excellent work.

    Craig
    Gold Member

  14. Craig says:

    Eric,

    Also, have you also created and posted Long_Exit and Short_Exit strategies on your site for the pairs required for testing the above Vervoot entry strategies?

    Thanks again,
    Craig
    Gold Member

  15. Felix says:

    I would say that the main advantage of the strategy in the fact that one strategy may combine more completely different studies. Of course, provided that you do not exaggerate in order to get signals. It is in fact a combination of study and determining the number of adjustable parameters with the greatest skill of creating good strategy as opposed to studies that are sufficient for themselves.

Leave a Reply