MAPS.efs
EFSLibrary - Discussion Board
File Name: MAPS.efs
Description:
This formula is based on the April 2005 article, Success Amid Risk - Trading Moving Average Pullbacks, by Steve Palmquist.
Formula Parameters:
- MA Length: 30
- MA Source: Close
- MA Type: SIMPLE
- Pullback Percent Envelope: 1%
- Trend Bars: 30
Notes:
This study is back testing compatiblle for the Strategy Analyzer. The related article is copyrighted material. If you are not a subscriber of Stocks & Commodities, please visit www.traders.com.
Download File:
MAPS.efs
EFS Code:
/*************************************** Provided By : eSignal (c) Copyright 2005 Description: Moving Average Pullback System - by Steve Palmquist Version 1.0 2/10/2005 Notes: April 2005 Issue - "Success Amid Risk - Trading Moving Average Pullbacks" Formula Parameters: Defaults: MA Length 30 MA Source Close MA Type SIMPLE Pullback Percent Envelope 1% Trend Bars 30 ***************************************/ function preMain() { setPriceStudy(true); setStudyTitle("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.red, 1); setDefaultBarFgColor(Color.blue, 2); setDefaultBarFgColor(Color.grey, 3); var fp1 = new FunctionParameter("nLength", FunctionParameter.NUMBER); fp1.setName("MA Length"); fp1.setDefault(30); 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("VOLUMEWEIGHTED"); 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("nTrendBars", FunctionParameter.NUMBER); fp5.setName("Number of Bars for Trend"); fp5.setDefault(30); fp5.setLowerLimit(1); } var study = null; 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, nTrendBars) { var nState = getBarState(); if (nState == BARSTATE_ALLBARS || bInit == true) { study = new MAStudy(nLength, 0, sSource, eval("MAStudy." + type)); if (close(0) > vMA) sSide = 1; else sSide = -1; setCursorLabelName("+" + nPBpercent + "\%", 0); setCursorLabelName("-" + nPBpercent + "\%", 2); bt = true; bInit = false; } var vMA = study.getValue(MAStudy.MA); var vMA1 = study.getValue(MAStudy.MA, -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 (nTrendCntr1 >= nTrendBars) { if (sSide1 == 1 && vPosition != 1) { if ( Math.abs((low(-1) - vMA1)/vMA1) <= (nPBpercent/100) ) { bLongTrigger = true; nTriggerIndex = getCurrentBarIndex(); } } else if (sSide1 == -1 && vPosition != -1) { if ( Math.abs((vMA1 - high(-1))/vMA1) <= (nPBpercent/100) ) { bShortTrigger = true; nTriggerIndex = getCurrentBarIndex(); } } } } // Position Exit if (vPosition != 0 && nBarCount == 3) { if (vPosition == 1) { longExit(); } else if (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) nTrendCntr = 0; // reset trend return new Array(((nPBpercent/100)*vMA)+vMA, vMA, vMA-((nPBpercent/100)*vMA), nTrendCntr+""); } /***** Support Functions *****/ 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); return; } function shortExit() { vPosition = 0; if (bt == true) Strategy.doCover("Short Stop", Strategy.MARKET, Strategy.THISBAR); return; }