Hi, I am trying to backtest a moving average crossover strategy. The fast moving average is the Hull Moving average, while the slow moving average is the simple moving average. I am facing issues when trying to use the call function for accessing the Hull Moving average. Can someone help me ?
Code for the Strategy
var bInit = false;
function preMain() {
setPriceStudy(true);
setStudyTitle("Moving Average Crossover");
setColorPriceBars(true);
setDefaultPriceBarColor(Color.black);
setPlotType(PLOTTYPE_LINE,0);
setDefaultBarFgColor(Color.red, 0);
setPlotType(PLOTTYPE_LINE,1);
setDefaultBarFgColor(Color.blue, 1);
}
var xSMAFast = null;
var xSMASlow = null;
function main() {
var nBarState = getBarState();
var nSMAFast = 0;
var nSMASlow = 0;
if (bInit == false) {
xSMAFast = call("HullMA2.efs")
xSMASlow = sma(20)
bInit = true;
}
nSMAFast = xSMAFast.getValue(-1);
nSMASlow = xSMASlow.getValue(-1);
if(nSMAFast == null || nSMASlow == null) return;
if (getCurrentBarIndex() == 0) return;
if(nSMAFast >= nSMASlow && !Strategy.isLong())
Strategy.doLong("Crossing Up", Strategy.MARKET, Strategy.THISBAR);
if(nSMAFast < nSMASlow && !Strategy.isShort())
Strategy.doShort("Crossing Down", Strategy.MARKET, Strategy.THISBAR);
if(Strategy.isLong())
setPriceBarColor(Color.lime);
else if(Strategy.isShort())
setPriceBarColor(Color.red);
return new Array(nSMAFast, nSMASlow);
}
HullMA2.efs
var fpArray = new Array();
function preMain() {
setPriceStudy(true);
setStudyTitle("Hull MA");
setCursorLabelName("HMA", 0);
setDefaultBarStyle(PS_SOLID, 0);
setDefaultBarFgColor(Color.blue, 0);
setPlotType(PLOTTYPE_LINE, 0);
setDefaultBarThickness(1, 0);
var x=0;
fpArray[x] = new FunctionParameter("Length", FunctionParameter.NUMBER);
with(fpArray[x++]){
setLowerLimit(1);
setDefault(15);
}
fpArray[x] = new FunctionParameter("Source", FunctionParameter.STRING);
with(fpArray[x++]){
addOption("open");
addOption("high");
addOption("low");
addOption("close");
addOption("hl2");
addOption("hlc3");
addOption("ohlc4");
setDefault("close");
}
fpArray[x] = new FunctionParameter("Symbol", FunctionParameter.STRING);
with(fpArray[x++]){
setDefault();
}
fpArray[x] = new FunctionParameter("Interval", FunctionParameter.STRING);
with(fpArray[x++]){
setDefault();
}
fpArray[x] = new FunctionParameter("Offset", FunctionParameter.NUMBER);
with(fpArray[x++]){
setDefault(0);
}
fpArray[x] = new FunctionParameter("Params", FunctionParameter.BOOLEAN);
with(fpArray[x++]){
setName("Show Parameters");
setDefault(false);
}
}
var bInit = false;
var vSymbol = null;
var vSource = null;
var xHMA = null;
function main(Length,Source,Symbol,Interval,Offset,Params) {
if(getCurrentBarCount()<Length*2) return;
if(bInit == false){
if(Symbol == null) Symbol = getSymbol();
if(Interval == null) Interval = getInterval();
vSymbol = Symbol+","+Interval;
vSource = eval(Source);
xHMA = getSeries(wma(Math.round(Math.sqrt(Length)),efsInt ernal("calcHMA",Length,Offset,vSource(sym(vSymbol) ))));
setShowTitleParameters(eval(Params));
bInit = true;
}
return xHMA;
}
var xAvg1 = null;
var xAvg2 = null;
function calcHMA(length,offset,source){
if(xAvg1==null) xAvg1 = offsetSeries(wma(length/2,source),offset);
if(xAvg2==null) xAvg2 = offsetSeries(wma(length,source),offset);
var Avg1 = xAvg1.getValue(0);
var Avg2 = xAvg2.getValue(0);
if(Avg1 == null || Avg2 == null) return;
return (2*Avg1)-Avg2;
}
Code for the Strategy
var bInit = false;
function preMain() {
setPriceStudy(true);
setStudyTitle("Moving Average Crossover");
setColorPriceBars(true);
setDefaultPriceBarColor(Color.black);
setPlotType(PLOTTYPE_LINE,0);
setDefaultBarFgColor(Color.red, 0);
setPlotType(PLOTTYPE_LINE,1);
setDefaultBarFgColor(Color.blue, 1);
}
var xSMAFast = null;
var xSMASlow = null;
function main() {
var nBarState = getBarState();
var nSMAFast = 0;
var nSMASlow = 0;
if (bInit == false) {
xSMAFast = call("HullMA2.efs")
xSMASlow = sma(20)
bInit = true;
}
nSMAFast = xSMAFast.getValue(-1);
nSMASlow = xSMASlow.getValue(-1);
if(nSMAFast == null || nSMASlow == null) return;
if (getCurrentBarIndex() == 0) return;
if(nSMAFast >= nSMASlow && !Strategy.isLong())
Strategy.doLong("Crossing Up", Strategy.MARKET, Strategy.THISBAR);
if(nSMAFast < nSMASlow && !Strategy.isShort())
Strategy.doShort("Crossing Down", Strategy.MARKET, Strategy.THISBAR);
if(Strategy.isLong())
setPriceBarColor(Color.lime);
else if(Strategy.isShort())
setPriceBarColor(Color.red);
return new Array(nSMAFast, nSMASlow);
}
HullMA2.efs
var fpArray = new Array();
function preMain() {
setPriceStudy(true);
setStudyTitle("Hull MA");
setCursorLabelName("HMA", 0);
setDefaultBarStyle(PS_SOLID, 0);
setDefaultBarFgColor(Color.blue, 0);
setPlotType(PLOTTYPE_LINE, 0);
setDefaultBarThickness(1, 0);
var x=0;
fpArray[x] = new FunctionParameter("Length", FunctionParameter.NUMBER);
with(fpArray[x++]){
setLowerLimit(1);
setDefault(15);
}
fpArray[x] = new FunctionParameter("Source", FunctionParameter.STRING);
with(fpArray[x++]){
addOption("open");
addOption("high");
addOption("low");
addOption("close");
addOption("hl2");
addOption("hlc3");
addOption("ohlc4");
setDefault("close");
}
fpArray[x] = new FunctionParameter("Symbol", FunctionParameter.STRING);
with(fpArray[x++]){
setDefault();
}
fpArray[x] = new FunctionParameter("Interval", FunctionParameter.STRING);
with(fpArray[x++]){
setDefault();
}
fpArray[x] = new FunctionParameter("Offset", FunctionParameter.NUMBER);
with(fpArray[x++]){
setDefault(0);
}
fpArray[x] = new FunctionParameter("Params", FunctionParameter.BOOLEAN);
with(fpArray[x++]){
setName("Show Parameters");
setDefault(false);
}
}
var bInit = false;
var vSymbol = null;
var vSource = null;
var xHMA = null;
function main(Length,Source,Symbol,Interval,Offset,Params) {
if(getCurrentBarCount()<Length*2) return;
if(bInit == false){
if(Symbol == null) Symbol = getSymbol();
if(Interval == null) Interval = getInterval();
vSymbol = Symbol+","+Interval;
vSource = eval(Source);
xHMA = getSeries(wma(Math.round(Math.sqrt(Length)),efsInt ernal("calcHMA",Length,Offset,vSource(sym(vSymbol) ))));
setShowTitleParameters(eval(Params));
bInit = true;
}
return xHMA;
}
var xAvg1 = null;
var xAvg2 = null;
function calcHMA(length,offset,source){
if(xAvg1==null) xAvg1 = offsetSeries(wma(length/2,source),offset);
if(xAvg2==null) xAvg2 = offsetSeries(wma(length,source),offset);
var Avg1 = xAvg1.getValue(0);
var Avg2 = xAvg2.getValue(0);
if(Avg1 == null || Avg2 == null) return;
return (2*Avg1)-Avg2;
}
Comment