Is it possible to program basic max2 strategy to utilize negative offset values AND update in real time ? It looks to be be historically accurate but real time does not change properly .
Announcement
Collapse
No announcement yet.
basic max 2 with negative offset values
Collapse
X
-
this is the max 2 strategy study
var vMA1 = null;
var vMA2 = null;
var vReturn = null;
function preMain() {
setPriceStudy(true);
setStudyTitle("MAx2");
setCursorLabelName("MA1", 0);
setCursorLabelName("MA2", 1);
setDefaultBarStyle(PS_SOLID, 0);
setDefaultBarStyle(PS_SOLID, 1);
setDefaultBarFgColor(Color.grey, 0);
setDefaultBarFgColor(Color.grey, 1);
setDefaultBarThickness(1, 0);
setDefaultBarThickness(1, 1);
setPlotType(PLOTTYPE_LINE, 0);
setPlotType(PLOTTYPE_LINE, 1);
var fp1 = new FunctionParameter("MA1Length", FunctionParameter.NUMBER);
fp1.setLowerLimit(1);
fp1.setDefault(2); //Edit this value to set a new default
var fp2 = new FunctionParameter("MA1Offset", FunctionParameter.NUMBER);
fp2.setDefault(-2); //Edit this value to set a new default
var fp3 = new FunctionParameter("MA1Source", FunctionParameter.STRING);
fp3.setName("MA1Source");
fp3.addOption("Close");
fp3.addOption("High");
fp3.addOption("Low");
fp3.addOption("Open");
fp3.addOption("HL/2");
fp3.addOption("HLC/3");
fp3.addOption("OHLC/4");
fp3.setDefault("HLC/3"); //Edit this value to set a new default
var fp4 = new FunctionParameter("MA1Type", FunctionParameter.STRING);
fp4.setName("MA1Type");
fp4.addOption("MAStudy.SIMPLE");
fp4.addOption("MAStudy.EXPONENTIAL");
fp4.addOption("MAStudy.WEIGHTED");
fp4.addOption("MAStudy.VOLUMEWEIGHTED");
fp4.setDefault("MAStudy.WEIGHTED"); //Edit this value to set a new default
var fp5 = new FunctionParameter("MA2Length", FunctionParameter.NUMBER);
fp5.setLowerLimit(1);
fp5.setDefault(6); //Edit this value to set a new default
var fp6 = new FunctionParameter("MA2Offset", FunctionParameter.NUMBER);
fp6.setDefault(-1); //Edit this value to set a new default
var fp7 = new FunctionParameter("MA2Source", FunctionParameter.STRING);
fp7.setName("MA1Source");
fp7.addOption("Close");
fp7.addOption("High");
fp7.addOption("Low");
fp7.addOption("Open");
fp7.addOption("HL/2");
fp7.addOption("HLC/3");
fp7.addOption("OHLC/4");
fp7.setDefault("HLC/3"); //Edit this value to set a new default
var fp8 = new FunctionParameter("MA2Type", FunctionParameter.STRING);
fp8.setName("MA2Type");
fp8.addOption("MAStudy.SIMPLE");
fp8.addOption("MAStudy.EXPONENTIAL");
fp8.addOption("MAStudy.WEIGHTED");
fp8.addOption("MAStudy.VOLUMEWEIGHTED");
fp8.setDefault("MAStudy.WEIGHTED"); //Edit this value to set a new default
}
function main(MA1Length,MA1Offset,MA1Source,MA1Type,MA2Leng th,MA2Offset,MA2Source,MA2Type) {
if (vMA1 == null) vMA1 = new MAStudy(MA1Length, MA1Offset, MA1Source, eval(MA1Type));
if (vMA2 == null) vMA2 = new MAStudy(MA2Length, MA2Offset, MA2Source, eval(MA2Type));
/*****************************************
Insert your code following this text block
Use vMA1.getValue(MAStudy.MA) and
vMA2.getValue(MAStudy.MA) for your code
******************************************/
if(getBarState()==BARSTATE_NEWBAR){
if(vMA1.getValue(MAStudy.MA,-1) > vMA2.getValue(MAStudy.MA,-1) && vMA1.getValue(MAStudy.MA,-2) < vMA2.getValue(MAStudy.MA,-2) && !Strategy.isLong()) {
Strategy.doLong("Crossing Up", Strategy.MARKET, Strategy.THISBAR);
}
if(vMA1.getValue(MAStudy.MA,-1) < vMA2.getValue(MAStudy.MA,-1) && vMA1.getValue(MAStudy.MA,-2) > vMA2.getValue(MAStudy.MA,-2) && !Strategy.isShort()) {
Strategy.doShort("Crossing Down", Strategy.MARKET, Strategy.THISBAR);
}
}
if(Strategy.isLong())
setPriceBarColor(Color.white);
else if(Strategy.isShort())
setPriceBarColor(Color.red);
return new Array (vMA1.getValue(MAStudy.MA),vMA2.getValue(MAStudy.M A));
vReturn = vMA.getValue(MAStudy.MA);
if (vReturn == null)
return;
if(getBarState() == BARSTATE_NEWBAR){
var nNum = 1;
}else{
var nNum = 0;
}
if(Offset < 0){
setBar(Bar.Value, Offset+nNum, vReturn);
return;
}else{
return vReturn;
}
}
It does not update in real time . You are forced to reload and even then the results are not consistent .This study is my attempt to assimilate 2 studies into 1 . The 2 studies were basic max 2(strategy) and builtin MA (offset) 2Last edited by colours; 05-25-2004, 10:30 AM.
Comment
-
First off..
You code is offsetting the MAs BACK by -1 or -2 - with the offsets. When in RT this equates to -2 and -3 as there is a new bar forming which takes up space 0.
Then you code is asking for values at -1 and -2 for comparisons of entry triggers. In RT, these values are going to be -2 and -3. Thus, some of your realtime values are "null".
You would greatly benefit from using the "debugPrintln()" function in your code so you could see what it is doing and what the values of your MAs are in RT/BT.
You will probably have to include two types of entry triggers in your main entry statements - like below...
PHP Code:if(getBarState()==BARSTATE_NEWBAR){
if (getCurrentBarIndex() != 0) {
debugPrintln(vMA1.getValue(MAStudy.MA,-1)+" : "+vMA1.getValue(MAStudy.MA,-2));
if(vMA1.getValue(MAStudy.MA,-1) > vMA2.getValue(MAStudy.MA,-1) &&
vMA1.getValue(MAStudy.MA,-2) < vMA2.getValue(MAStudy.MA,-2) &&
!Strategy.isLong()) {
Strategy.doLong("Crossing Up", Strategy.MARKET, Strategy.THISBAR);
}
if(vMA1.getValue(MAStudy.MA,-1) < vMA2.getValue(MAStudy.MA,-1) &&
vMA1.getValue(MAStudy.MA,-2) > vMA2.getValue(MAStudy.MA,-2) &&
!Strategy.isShort()) {
Strategy.doShort("Crossing Down", Strategy.MARKET, Strategy.THISBAR);
}
}
if (getCurrentBarIndex() == 0) {
debugPrintln(vMA1.getValue(MAStudy.MA,-2)+" : "+vMA1.getValue(MAStudy.MA,-3));
if(vMA1.getValue(MAStudy.MA,-2) > vMA2.getValue(MAStudy.MA,-2) &&
vMA1.getValue(MAStudy.MA,-3) < vMA2.getValue(MAStudy.MA,-3) &&
!Strategy.isLong()) {
Strategy.doLong("Crossing Up", Strategy.MARKET, Strategy.THISBAR);
}
if(vMA1.getValue(MAStudy.MA,-2) < vMA2.getValue(MAStudy.MA,-2) &&
vMA1.getValue(MAStudy.MA,-3) > vMA2.getValue(MAStudy.MA,-3) &&
!Strategy.isShort()) {
Strategy.doShort("Crossing Down", Strategy.MARKET, Strategy.THISBAR);
}
}
}
Brad Matheny
eSignal Solution Provider since 2000
Comment
-
One other thing I just thought of..
I'm not sure of this... but...
the BARSTATE_NEWBAR may be called before the MAs complete their calculations, thus, you are potentially testing for entry triggers before the MAs have completed calculating the current values. This would obviously cause a problem.
Someone from esignal could verify this better than I could.
If this is the case, then you would need to switch from BARSTATE_NEWBAR to another form of bar counter. You could use the one I use (which waits for a new bar to form, then you would run your entry conditions on the previous bar). Code example below..
PHP Code:var nLastRawTime = 0;
function main() {
if (getValue("rawtime", 0) != nLastRawTime) {
// NEW BAR FORMED
nLastRawTime = getValue("rawtime", 0);
}
}
Brad Matheny
eSignal Solution Provider since 2000
Comment
-
colours,
also if you are using this for backtest ,to get a accurate result you need to change
Strategy.doLong("Crossing Up", Strategy.MARKET, Strategy.THISBAR);
to
Strategy.doLong("Crossing Up", Strategy.MARKET, Strategy.NEXTBAR);
or
Strategy.doLong("Crossing Up", Strategy.CLOSE, Strategy.THISBAR);
also the Strategy.doShort, as the MARKET function will execute at the open price of the bar.
Comment
-
colours
You may want to see a similar efs posted in this thread.
In your case however it may end up being simpler to set the offset of the first MA to 0 and offset forward the second MA by the same amount you are currently offsetting backwards the first one.
The result is the same besides being easier to code because you now have returned values for both MAs on the current bar
Alex
Comment
Comment