2005 Sep: Shorting Moving Average Pullbacks (SMAPS.efs)

ICE Data Services -

SMAPS.efs  

EFSLibrary - Discussion Board  

File Name: SMAPS.efs


Description:
This formula is based on the September 2005 article, Shorting Moving Average Pullbacks, by Steve Palmquist.

 

Formula Parameters:

  • MA Length: 35
  • MA Source: Close
  • MA Type: SIMPLE
  • Pullback Percent Envelope: 1%
  • Enable Long Positions: true
  • Enable Short Positions: true
  • Long Entry Trend Bars: 30
  • Short Entry Trend Bars: 15
  • Average Volume Filter: 200000
  • Average Volume Periods: 10
  • Price Filter: 15
  • Stochastic K Long Filter: 20
  • Stochastic K Short Filter: 80
  • Stochastic K Length: 14
  • Stochastic K Smoothing: 1
  • Stochastic D Length: 3

 

Notes:
This study is similar to Palmquist's article from the April 2005 issue, Trading Moving Average Pullbacks. As we did with the April study, MAPS.efs, we've included the logic for taking long positions as well. This logic is a combination of the rules used from the April issue as well as the specifics from the current article. The study does have the ability to leave out the long entries by setting the "Enable Long Positions" formula parameter to false through the Edit Studies options if you wish to run back tests only on short positions. There is also an option to enable/disable short positions. The study is coded as a back testing study to generate the report with the Strategy Analyzer (Tools-->Back Testing). The study also has parameters to further optimize the study based on the market and interval of the Advanced Chart. You may adjust the MA Length, MA Source, MA Type, Pullback Percent Envelope, Long Entry Trend Bars (number of bars to define long trend), Short Entry Trend Bars (number of bars to define short trend), Average Volume Filter (level for x period average volume), Average Volume Periods, Price Filter (for chart symbol), Stochastic K Long Filter, Stochastic K Short Filter, Stochastic K Length, Stochastic K Smoothing and Stochastic D Length. The related article is copyrighted material. If you are not a subscriber of Stocks & Commodities, please visit www.traders.com.

 

Download File:
SMAPS.efs



EFS Code:

/***************************************
Provided By : eSignal (c) Copyright 2005
Description:  Shorting Moving Average Pullback System - by Steve Palmquist

Version 1.0  7/8/2005

Notes:
September 2005 Issue - "Different Systems for Different Markets - 
                        Shorting Moving Average Pullbacks"

Formula Parameters:                 Defaults:
MA Length                           35
MA Source                           Close
MA Type                             SIMPLE
Pullback Percent Envelope           1%
Enable Long Positions               true
Enable Short Positions              true
Long Entry Trend Bars               30
Short Entry Trend Bars              15
Average Volume Filter               200000
Average Volume Periods              10
Price Filter                        15
Stochastic K Long Filter            20
Stochastic K Short Filter           80
Stochastic K Length                 14
Stochastic K Smoothing              1
Stochastic D Length                 3
***************************************/

function preMain() {
    setPriceStudy(true);
    setStudyTitle("Short Moving Average Pullback System ");
    setShowTitleParameters(false);
    setCursorLabelName("+1\%", 0);
    setCursorLabelName("MA", 1);
    setCursorLabelName("-1\%", 2); 
    setCursorLabelName("Trend Count", 3);
    setDefaultBarFgColor(Color.blue, 0);
    setDefaultBarFgColor(Color.maroon, 1);
    setDefaultBarFgColor(Color.blue, 2);
    setDefaultBarFgColor(Color.grey, 3);
    
    var fp1 = new FunctionParameter("nLength", FunctionParameter.NUMBER);
        fp1.setName("MA Length");
        fp1.setDefault(35);
        fp1.setLowerLimit(1);
    var fp2 = new FunctionParameter("sSource", FunctionParameter.STRING);
        fp2.setName("MA Source");
        fp2.setDefault("Close");
        fp2.addOption("Open");
        fp2.addOption("High");
        fp2.addOption("Low");
        fp2.addOption("Close");
        fp2.addOption("HL/2");
        fp2.addOption("HLC/3");
        fp2.addOption("OHLC/4");
    var fp3  = new FunctionParameter("type", FunctionParameter.STRING);
        fp3.setName("MA Type");
        fp3.setDefault("Simple");
        fp3.addOption("Simple");
        fp3.addOption("Exponential");
        fp3.addOption("Weighted");
        fp3.addOption("Volume Weighted");
    var fp4 = new FunctionParameter("nPBpercent", FunctionParameter.NUMBER);
        fp4.setName("Pullback Percent Envelope");
        fp4.setDefault(1);
        fp4.setLowerLimit(0);
        fp4.setUpperLimit(100);
    var fp5 = new FunctionParameter("bLong", FunctionParameter.STRING);
        fp5.setName("Enable Long Positions");
        fp5.setDefault("true");
        fp5.addOption("true");
        fp5.addOption("false");
    var fp6 = new FunctionParameter("bShort", FunctionParameter.STRING);
        fp6.setName("Enable Short Positions");
        fp6.setDefault("true");
        fp6.addOption("true");
        fp6.addOption("false");
    var fp7 = new FunctionParameter("nLTrendBars", FunctionParameter.NUMBER);
        fp7.setName("Number of Bars for Long Trend");
        fp7.setDefault(30);
        fp7.setLowerLimit(1);
    var fp8 = new FunctionParameter("nSTrendBars", FunctionParameter.NUMBER);
        fp8.setName("Number of Bars for Short Trend");
        fp8.setDefault(15);
        fp8.setLowerLimit(1);
    var fp9 = new FunctionParameter("nVFilter", FunctionParameter.NUMBER);
        fp9.setName("Average Volume Filter");
        fp9.setDefault(200000);
        fp9.setLowerLimit(0);
    var fp10 = new FunctionParameter("nAvgVolLen", FunctionParameter.NUMBER);
        fp10.setName("Average Volume Periods");
        fp10.setDefault(10);
        fp10.setLowerLimit(1);
    var fp11 = new FunctionParameter("nPFilter", FunctionParameter.NUMBER);
        fp11.setName("Price Filter");
        fp11.setDefault(15);
        fp11.setLowerLimit(0);
    var fp12 = new FunctionParameter("nStochKLFilter", FunctionParameter.NUMBER);
        fp12.setName("Stochastic K Long Filter");
        fp12.setDefault(20);
        fp12.setLowerLimit(0);
    var fp13 = new FunctionParameter("nStochKSFilter", FunctionParameter.NUMBER);
        fp13.setName("Stochastic K Short Filter");
        fp13.setDefault(80);
        fp13.setLowerLimit(0);
    var fp14 = new FunctionParameter("nStochKLen", FunctionParameter.NUMBER);
        fp14.setName("Stochastic K Length");
        fp14.setDefault(14);
        fp14.setLowerLimit(1);
    var fp15 = new FunctionParameter("nStochKSmooth", FunctionParameter.NUMBER);
        fp15.setName("Stochastic K Smoothing");
        fp15.setDefault(1);
        fp15.setLowerLimit(1);
    var fp16 = new FunctionParameter("nStochDLen", FunctionParameter.NUMBER);
        fp16.setName("Stochastic D Length");
        fp16.setDefault(3);
        fp16.setLowerLimit(1);
}

var bVersion = null;
var study = null;   // MA
var study2 = null;  // Daily Avg Volume
var study3 = null;  // StochK
var bt = true;      // back testing on
var nTrendCntr = 0;
var nTrendCntr1 = 0;// previous bar's nTrendCntr
var sSide = 0;      // 1 = obove MA, -1 = below MA
var sSide1 = 0;     // previous bar's sSide
var bInit = true;   // initialization routine.
var bLongTrigger = false;
var bShortTrigger = false;
var vPosition = 0;  // 0 = no position, 1 = long, -1 = short
var nTriggerIndex = null;
var nBarCount = 0;  // bar counter for exit strategy

function main(nLength, sSource, type, nPBpercent, bLong, bShort, 
              nLTrendBars, nSTrendBars, nVFilter, nAvgVolLen, nPFilter,
              nStochKLFilter, nStochKSFilter, nStochKLen, nStochKSmooth, nStochDLen) {    

    if (bVersion == null) bVersion = verify();
    if (bVersion == false) return;    

    var nState = getBarState();

    if (nState == BARSTATE_ALLBARS || bInit == true) {
        var xSource = close();
        switch (sSource) {
            case "Open" :       xSource = open(); break;
            case "High" :       xSource = high(); break;
            case "Low" :        xSource = low(); break;
            case "Close" :      xSource = close(); break;
            case "HL/2" :       xSource = hl2(); break;
            case "HLC/3" :      xSource = hlc3(); break;
            case "OHLC/4" :     xSource = ohlc4(); break;
            default :           xSource = close();
        }
        switch (type) {
            case "Simple" :             study = sma(nLength, xSource); break;
            case "Exponential" :        study = ema(nLength, xSource); break;
            case "Weighted" :           study = wma(nLength, xSource); break;
            case "Volume Weighted" :    study = vwma(nLength, xSource); break;
            default :                   study = sma(nLength, xSource);
        }
        study2 = sma(nAvgVolLen, volume());
        study3 = stochK(nStochKLen, nStochKSmooth, nStochDLen);
        if (close(0) > study.getValue(0)) sSide = 1;
        else sSide = -1;
        setCursorLabelName("+" + nPBpercent + "\%", 0);
        setCursorLabelName("-" + nPBpercent + "\%", 2);
        bt = true;
        bInit = false;
    }
    
    var bL = eval(bLong);
    var bS = eval(bShort);
    var vMA = study.getValue(0);
    var vMA1 = study.getValue(-1);
    if (vMA == null || vMA1 == null) return;
    
    if (nState == BARSTATE_NEWBAR) {
        nTrendCntr1 = nTrendCntr;
        nTrendCntr += 1;
        sSide1 = sSide;
        nBarCount += 1;
        if (getCurrentBarIndex() < 0) bt = true;
        else bt = false;
    }
    
    if (sSide == 1 && low(-1) < vMA1) sSide = -1;
    else if (sSide == -1 && high(-1) > vMA1) sSide = 1;
    
    if (nState == BARSTATE_NEWBAR && bLongTrigger == false && bShortTrigger == false) {
        if (study2.getValue(0) > nVFilter && close(0) >= nPFilter) {
            if (bL && nTrendCntr1 >= nLTrendBars && sSide1 == 1 && vPosition != 1
                    && study3.getValue(0) > nStochKLFilter) {
                if ( Math.abs((close(-1) - vMA1)/vMA1) <= (nPBpercent/100) ) {
                    bLongTrigger = true;
                    nTriggerIndex = getCurrentBarIndex();
                }
            } else if (bS && nTrendCntr1 >= nSTrendBars && sSide1 == -1 && vPosition != -1 
                    && study3.getValue(0) < nStochKSFilter) {
                if ( Math.abs((vMA1 - close(-1))/vMA1) <= (nPBpercent/100) ) {
                    bShortTrigger = true;
                    nTriggerIndex = getCurrentBarIndex();
                }
            }
        }
    }
    
    // Position Exit
    if (vPosition != 0 && nBarCount == 3) {
        if (bL && vPosition == 1) {
            longExit();
        } else if (bS && vPosition == -1) {
            shortExit();
        }
    }
    
    // Position Entry
    if (getCurrentBarIndex() == nTriggerIndex) {
        if (bLongTrigger == true) {
            if (high(0) > high(-1)) longEntry();
        } else if (bShortTrigger == true) {
            if (low(0) < low(-1)) shortEntry();
        }
    } else {
        bLongTrigger = false;
        bShortTrigger = false;
    }

    if (vPosition == 1) setBarBgColor(Color.green);
    if (vPosition == -1) setBarBgColor(Color.red); 
    
    if (sSide1 != sSide) {  // reset trend
        nTrendCntr = 0;  
        //nSTrendCntr = 0;  
    }
    
    return new Array(((nPBpercent/100)*vMA)+vMA, vMA, vMA-((nPBpercent/100)*vMA), nTrendCntr+"");
}

/***** Support Functions *****/

function verify() {
    var b = false;
    if (getBuildNumber() < 700) {
        drawTextAbsolute(5, 35, "This study requires version 7.9 or later.", 
            Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
            null, 13, "error");
        drawTextAbsolute(5, 20, "Click HERE to upgrade.@URL=http://www.esignal.com/download/default.asp", 
            Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
            null, 13, "upgrade");
        return b;
    } else {
        b = true;
    }
    
    return b;
}

function longEntry() {
    bLongTrigger = false;
    vPosition = 1;
    setBarBgColor(Color.green);
    var nEntryPrice = high(-1);
    if (open(0) > nEntryPrice) nEntryPrice = open(0);
    if (bt == true) {
        Strategy.doLong("Buy", Strategy.LIMIT, Strategy.THISBAR, null, nEntryPrice);
    }
    nBarCount = 0;
    return;
}

function shortEntry() {
    bShortTrigger = false;
    vPosition = -1
    setBarBgColor(Color.red);
    var nEntryPrice = low(-1);
    if (open(0) < nEntryPrice) nEntryPrice = open(0);
    if (bt == true) {
        Strategy.doShort("Short", Strategy.LIMIT, Strategy.THISBAR, null, nEntryPrice);
    }
    nBarCount = 0;
    return;
}

function longExit() {
    vPosition = 0;
    //if (bt == true) Strategy.doSell("Long Stop", Strategy.MARKET, Strategy.THISBAR);
    if (bt == true) Strategy.doSell("Long Stop", Strategy.CLOSE, Strategy.THISBAR);
    return;
}

function shortExit() {
    vPosition = 0;
    //if (bt == true) Strategy.doCover("Short Stop", Strategy.MARKET, Strategy.THISBAR);
    if (bt == true) Strategy.doCover("Short Stop", Strategy.CLOSE, Strategy.THISBAR);
    return;
}