//@Name:Cross Finder //@Description:Identifies a number of classic technical crosses. Can be used both in a column or as an alarm. //@Returns:Number //@Width:90 //@Env:Production //@Update:Periodic,30 //@StandardAlarmOutput:Yes // Care has been taken in preparing this code but it is provided without guarantee. // You are welcome to modify and extend it. Please add your name as a modifier if you distribute it. //Coded by: Richard Chiesa, ShareScript Support //************************************************************** //****** How to expand the script ****** //************************************************************** //* Follow these steps to add further cross types to the script //* //* 1. Add a unique identifier to 'cross'. Try using the same //* naming convention adopted up to now and remember that //* all even identifiers are treated as crosses 'above' //* and all odd identifiers as crosses 'below' //* //* 2. Add the corresponding menu item to 'crossList'. //* Remember that its position in the list needs to match //* the value assigned to it in 'cross' //* //* 3. Set which type of dialog box will be called. If none //* of the existing ones can be used, create a new one //* following the same style as the others //* //* 4. Set the title that will appear on the column heading //* //* 5. Add the objects that are used to calculate the two //* lines. If you define them as indicator1 and indicator2, //* OHLCVindicator1 and OHLCVindicator2 you can recycle the //* calculation code in the 'for' loop later on: the former //* is treated as an indicator that takes close prices, //* while the latter takes full OHLCV data as input. //* This is also the point at which you might need to create //* an indicator object if you aren't using one of the //* existing ShareScript ones. Look at the PercB prototype //* further down the script for an example of how to code a //* single-input single-output indicator (like MA or RSI) or //* look at the BollBand prototype for a single-input multi-output //* indicator (like MACD or Stoch.Osc) //* //* 6. Add the code to calculate the values of line1 and line2. //* You might be able to simply add the new cross types to //* some existing calculation code if the indicators are of the //* same style as existing ones. Otherwise just append the new options //* //* 7. If the new cross is in the "price crossing something" format, you'll //* need to add the options to the first two lines of the four lines //* that actually calculate if the cross, in any other case //* you won't need to do anything as, by default, CrossFinder treats //* any cross type with a even number Id as "line1 crossing //* above line2" and any type with an odd Id as "line1 crossing //* below line2" //* //* 8. Test, test, test, test and then test some more. //* var var1 = 13; var var2 = 26; var var3 = 9; var var4 = 3; var crossType = 0; var MAtype1 = 0; var MAtype2 = 0; var dataSource = 15; var maList = ["Simple","Exponential","Weighted","Triangular","VariableVHF","VariableCMO","VIDYA","Hull","TEMA","VWAP"]; var maTitleList = ["SMA","EMA","WMA","TMA","VVHF","VCMO","VIDYA","HMA","TEMA","VWAP"]; var dataList = ["1m","2m","2.5m","3m","4m","5m","6m","10m","15m","20m","30m","1h","2h","3h","4h","Daily","Weekly","Monthly"]; var useIntra = false; var cross = { PRICE_ABOVE_MA: 0, PRICE_BELOW_MA: 1, GOLDEN_CROSS: 2, DEAD_CROSS: 3, MACD_ABOVE_SIGNAL: 4, MACD_BELOW_SIGNAL: 5, STOCHASTIC_OSCILLATOR_ABOVE_SIGNAL: 6, STOCHASTIC_OSCILLATOR_BELOW_SIGNAL: 7, STOCHASTIC_OSCILLATOR_ABOVE_LEVEL: 8, STOCHASTIC_OSCILLATOR_BELOW_LEVEL: 9, PDI_ABOVE_NDI: 10, PDI_BELOW_NDI: 11, MOMENTUM_ABOVE_LEVEL: 12, MOMENTUM_BELOW_LEVEL: 13, ADX_ABOVE_LEVEL: 14, ADX_BELOW_LEVEL: 15, RSI_ABOVE_LEVEL: 16, RSI_BELOW_LEVEL: 17, RSI_ABOVE_RSI: 18, RSI_BELOW_RSI: 19, POSITIVE_VOL_INDEX_ABOVE_SIGNAL: 20, POSITIVE_VOL_INDEX_BELOW_SIGNAL: 21, NEGATIVE_VOL_INDEX_ABOVE_SIGNAL: 22, NEGATIVE_VOL_INDEX_BELOW_SIGNAL: 23, PERCENTB_ABOVE_LEVEL: 24, PERCENTB_BELOW_LEVEL: 25, ZLTCD_ABOVE_SIGNAL: 26, ZLTCD_BELOW_SIGNAL: 27, MACD_ABOVE_ZERO: 28, MACD_BELOW_ZERO: 29, MFI_ABOVE_MFI: 30, MFI_BELOW_MFI: 31, CCI_ABOVE_LEVEL: 32, CCI_BELOW_LEVEL: 33, WILLIAMS_AD_ABOVE_SIGNAL: 34, WILLIAMS_AD_BELOW_SIGNAL: 35, PDI_ABOVE_LEVEL: 36, PDI_BELOW_LEVEL: 37, NDI_ABOVE_LEVEL: 38, NDI_BELOW_LEVEL: 39, PRICE_ABOVE_TOP_BB: 40, PRICE_BELOW_TOP_BB: 41, PRICE_ABOVE_BOTTOM_BB: 42, PRICE_BELOW_BOTTOM_BB: 43, ZERO_LAG_STUDY_BUY: 44, ZERO_LAG_STUDY_SELL: 45, AROON_UP_ABOVE_DOWN: 46, AROON_UP_BELOW_DOWN: 47 } var crossList = [ "Price above MA", //0 "Price below MA", //1 "Golden Cross", //2 "Dead Cross", //3 "MACD above Signal", //4 "MACD below Signal", //5 "Stoch.Osc. above Signal", //6 "Stoch.Osc. below Signal", //7 "Stoch.Osc. above Level", //8 "Stoch.Osc. below Level", //9 "DI+ above DI-", //10 "DI+ below DI-", //11 "Momentum above level", //12 "Momentum below level", //13 "ADX above level", //14 "ADX below level", //15 "RSI above level", //16 "RSI below level", //17 "RSI above RSI", //18 "RSI below RSI", //19 "PosVolIndex above Signal", //20 "PosVolIndex below signal", //21 "NegVolIndex above Signal", //22 "NegVolIndex below signal", //23 "%b above level", //24 "%b below level", //25 "ZLTCD above Signal", //26 "ZLTCD below Signal", //27 "MACD above Zero", //28 "MACD below Zero", //29 "MFI above MFI", //30 "MFI below MFI", //31 "CCI above level", //32 "CCI below level", //33 "WilliamsA/D above Signal", //34 "WilliamsA/D below Signal", //35 "DI+ above level", //36 "DI+ below level", //37 "DI- above level", //38 "DI- below level", //39 "Price above top BBand", //40 "Price below top BBand", //41 "Price above bottom BBand", //42 "Price above bottom BBand", //43 "Zero Lag Study Buy", //44 "Zero Lag Study Sell", //45 "Aroon Up above Down", //46 "Aroon Up below Down" //47 ]; function init(status) { if (status == Loading || status == Editing) { var store1 = restore(storage.getAt(0),[[crossType,0,crossList.length-1],[dataSource,0,dataList.length-1],[useIntra,0,1]]); MAtype1 = storage.getAt(1); MAtype2 = storage.getAt(2); //dataSource = storage.getAt(3); var4 = storage.getAt(3); var1 = storage.getAt(4); var2 = storage.getAt(5); var3 = storage.getAt(6); crossType = store1[0][0]; dataSource = store1[1][0]; useIntra = store1[2][0]; //useIntra = storage.getAt(7); } if (status == Adding || status == Editing) { // creates the first dialog where the type of cross and the time period are chosen dlg = new Dialog("Select Cross Type", 180, 75); dlg.addOkButton(-1,-1,-1,-1,"Next >"); dlg.addCancelButton(); dlg.addDropList("DL1",8,-1,100,-1,crossList,"","",crossType); dlg.addDropList("DL3",8,-1,100,-1,dataList,"","",dataSource); dlg.addTickBox("TB1",8,50,150,-1,"Include intraday data",useIntra) if (dlg.show()==Dialog.Cancel) return false; crossType = dlg.getValue("DL1"); //storage.setAt(0, crossType); dataSource = dlg.getValue("DL3"); //storage.setAt(3, dataSource); useIntra = dlg.getValue("TB1"); //storage.setAt(7, useIntra); storage.setAt(0, compress([[crossType,0,crossList.length-1],[dataSource,0,dataList.length-1],[useIntra,0,1]])); // creates the second dialog where the periods are set switch (crossType) { case cross.PRICE_ABOVE_MA: dialog1(status);break; case cross.PRICE_BELOW_MA: dialog1(status);break; case cross.GOLDEN_CROSS: dialog2(status);break; case cross.DEAD_CROSS: dialog2(status);break; case cross.MACD_ABOVE_SIGNAL: dialog3(status);break; case cross.MACD_BELOW_SIGNAL: dialog3(status);break; case cross.STOCHASTIC_OSCILLATOR_ABOVE_SIGNAL: dialog4(status);break; case cross.STOCHASTIC_OSCILLATOR_BELOW_SIGNAL: dialog4(status);break; case cross.STOCHASTIC_OSCILLATOR_ABOVE_LEVEL: dialog9(status);break; case cross.STOCHASTIC_OSCILLATOR_BELOW_LEVEL: dialog9(status);break; case cross.PDI_ABOVE_NDI: dialog5(status);break; case cross.PDI_BELOW_NDI: dialog5(status);break; case cross.MOMENTUM_ABOVE_LEVEL: dialog6(status);break; case cross.MOMENTUM_BELOW_LEVEL: dialog6(status);break; case cross.ADX_ABOVE_LEVEL: dialog6(status);break; case cross.ADX_BELOW_LEVEL: dialog6(status);break; case cross.RSI_ABOVE_LEVEL: dialog6(status);break; case cross.RSI_BELOW_LEVEL: dialog6(status);break; case cross.RSI_ABOVE_RSI: dialog10(status);break; case cross.RSI_BELOW_RSI: dialog10(status);break; case cross.POSITIVE_VOL_INDEX_ABOVE_SIGNAL: dialog5(status);break; case cross.POSITIVE_VOL_INDEX_BELOW_SIGNAL: dialog5(status);break; case cross.NEGATIVE_VOL_INDEX_ABOVE_SIGNAL: dialog5(status);break; case cross.NEGATIVE_VOL_INDEX_BELOW_SIGNAL: dialog5(status);break; case cross.PERCENTB_ABOVE_LEVEL: dialog7(status);break; case cross.PERCENTB_BELOW_LEVEL: dialog7(status);break; case cross.ZLTCD_ABOVE_SIGNAL: dialog8(status);break; case cross.ZLTCD_BELOW_SIGNAL: dialog8(status);break; case cross.MACD_ABOVE_ZERO: dialog3(status);break; case cross.MACD_BELOW_ZERO: dialog3(status);break; case cross.MFI_ABOVE_MFI: dialog10(status);break; case cross.MFI_BELOW_MFI: dialog10(status);break; case cross.CCI_ABOVE_LEVEL: dialog6(status);break; case cross.CCI_BELOW_LEVEL: dialog6(status);break; case cross.WILLIAMS_AD_ABOVE_SIGNAL: dialog5(status);break; case cross.WILLIAMS_AD_BELOW_SIGNAL: dialog5(status);break; case cross.PDI_ABOVE_LEVEL: dialog6(status);break; case cross:PDI_BELOW_LEVEL: dialog6(status);break; case cross.NDI_ABOVE_LEVEL: dialog6(status);break; case cross.NDI_BELOW_LEVEL: dialog6(status);break; case cross.PRICE_ABOVE_TOP_BB: dialog11(status);break; case cross.PRICE_BELOW_TOP_BB: dialog11(status);break; case cross.PRICE_ABOVE_BOTTOM_BB: dialog11(status);break; case cross.PRICE_BELOW_BOTTOM_BB: dialog11(status);break; case cross.ZERO_LAG_STUDY_BUY: dialog12(status);break; case cross.ZERO_LAG_STUDY_SELL: dialog12(status);break; case cross.AROON_UP_ABOVE_DOWN: dialog5(status);break; case cross.AROON_UP_BELOW_DOWN: dialog5(status);break; } storage.setAt(1, MAtype1); storage.setAt(2, MAtype2); storage.setAt(3, var4); storage.setAt(4, var1); storage.setAt(5, var2); storage.setAt(6, var3); } var inputList = ["(O)","(H)","(L)",""] // sets the title of the column switch (crossType) { case cross.PRICE_ABOVE_MA: setTitle("CrossFinder: Price above "+var1+" "+maTitleList[MAtype1]+" "+inputList[var3]+" "+dataList[dataSource]); break; case cross.PRICE_BELOW_MA: setTitle("CrossFinder: Price below "+var1+" "+maTitleList[MAtype1]+" "+inputList[var3]+" "+dataList[dataSource]); break; case cross.GOLDEN_CROSS: setTitle("CrossFinder: Golden Cross "+var1+" "+maTitleList[MAtype1]+" "+var2+" "+maTitleList[MAtype2]+" "+dataList[dataSource]); break; case cross.DEAD_CROSS: setTitle("CrossFinder: Dead Cross "+var1+" "+maTitleList[MAtype1]+" "+var2+" "+maTitleList[MAtype2]+" "+dataList[dataSource]); break; case cross.MACD_ABOVE_SIGNAL: setTitle("CrossFinder: "+var1+" "+var2+" MACD above "+var3+" signal"+" "+dataList[dataSource]); break; case cross.MACD_BELOW_SIGNAL: setTitle("CrossFinder: "+var1+" "+var2+" MACD below "+var3+" signal"+" "+dataList[dataSource]); break; case cross.STOCHASTIC_OSCILLATOR_ABOVE_SIGNAL: setTitle("CrossFinder: "+var1+" "+var2+" Stoch.Osc. above "+var3+" signal"+" "+dataList[dataSource]); break; case cross.STOCHASTIC_OSCILLATOR_BELOW_SIGNAL: setTitle("CrossFinder: "+var1+" "+var2+" Stoch.Osc. below "+var3+" signal"+" "+dataList[dataSource]); break; case cross.STOCHASTIC_OSCILLATOR_ABOVE_LEVEL: setTitle("CrossFinder: "+var1+" "+var2+" Stoch.Osc. above "+var3+" level"+" "+dataList[dataSource]); break; case cross.STOCHASTIC_OSCILLATOR_BELOW_LEVEL: setTitle("CrossFinder: "+var1+" "+var2+" Stoch.Osc. below "+var3+" level"+" "+dataList[dataSource]); break; case cross.PDI_ABOVE_NDI: setTitle("CrossFinder: "+var1+" ADX DI+ above DI-"+" "+dataList[dataSource]); break; case cross.PDI_BELOW_NDI: setTitle("CrossFinder: "+var1+" ADX DI+ below DI-"+" "+dataList[dataSource]); break; case cross.MOMENTUM_ABOVE_LEVEL: setTitle("CrossFinder: "+var1+" Momentum above "+var2+" level"+" "+dataList[dataSource]); break; case cross.MOMENTUM_BELOW_LEVEL: setTitle("CrossFinder: "+var1+" Momentum below "+var2+" level"+" "+dataList[dataSource]); break; case cross.ADX_ABOVE_LEVEL: setTitle("CrossFinder: "+var1+" ADX above "+var2+" level"+" "+dataList[dataSource]); break; case cross.ADX_BELOW_LEVEL: setTitle("CrossFinder: "+var1+" ADX below "+var2+" level"+" "+dataList[dataSource]); break; case cross.RSI_ABOVE_LEVEL: setTitle("CrossFinder: "+var1+" RSI above "+var2+" level"+" "+dataList[dataSource]); break; case cross.RSI_BELOW_LEVEL: setTitle("CrossFinder: "+var1+" RSI below "+var2+" level"+" "+dataList[dataSource]); break; case cross.RSI_ABOVE_RSI: setTitle("CrossFinder: "+var1+" RSI above "+var2+" RSI "+dataList[dataSource]); break; case cross.RSI_BELOW_RSI: setTitle("CrossFinder: "+var1+" RSI below "+var2+" RSI "+dataList[dataSource]); break; case cross.POSITIVE_VOL_INDEX_ABOVE_SIGNAL: setTitle("CrossFinder: PosVolIndex above "+var1+" signal "+dataList[dataSource]); break; case cross.POSITIVE_VOL_INDEX_BELOW_SIGNAL: setTitle("CrossFinder: PosVolIndex below "+var1+" signal "+dataList[dataSource]); break; case cross.NEGATIVE_VOL_INDEX_ABOVE_SIGNAL: setTitle("CrossFinder: NegVolIndex above "+var1+" signal "+dataList[dataSource]); break; case cross.NEGATIVE_VOL_INDEX_BELOW_SIGNAL: setTitle("CrossFinder: NegVolIndex below "+var1+" signal "+dataList[dataSource]); break; case cross.PERCENTB_ABOVE_LEVEL: setTitle("CrossFinder: %b ("+var1+" "+maTitleList[MAtype1]+", "+var3+" dev) above "+var2+" ("+dataList[dataSource]+")"); break; case cross.PERCENTB_BELOW_LEVEL: setTitle("CrossFinder: %b ("+var1+" "+maTitleList[MAtype1]+", "+var3+" dev) below "+var2+" ("+dataList[dataSource]+")"); break; case cross.ZLTCD_ABOVE_SIGNAL: setTitle("CrossFinder: "+var1+" ZLTCD above "+var3+" signal "+dataList[dataSource]); break; case cross.ZLTCD_BELOW_SIGNAL: setTitle("CrossFinder: "+var1+" ZLTCD below "+var3+" signal "+dataList[dataSource]); break; case cross.MACD_ABOVE_ZERO: setTitle("CrossFinder: "+var1+" "+var2+" MACD above Zero "+dataList[dataSource]); break; case cross.MACD_BELOW_ZERO: setTitle("CrossFinder: "+var1+" "+var2+" MACD below Zero "+dataList[dataSource]); break; case cross.MFI_ABOVE_MFI: setTitle("CrossFinder: "+var1+" MFI above "+var2+" MFI "+dataList[dataSource]); break; case cross.MFI_BELOW_MFI: setTitle("CrossFinder: "+var1+" MFI below "+var2+" MFI "+dataList[dataSource]); break; case cross.CCI_ABOVE_LEVEL: setTitle("CrossFinder: "+var1+" CCI above "+var2+" level "+dataList[dataSource]); break; case cross.CCI_BELOW_LEVEL: setTitle("CrossFinder: "+var1+" CCI below "+var2+" level "+dataList[dataSource]); break; case cross.WILLIAMS_AD_ABOVE_SIGNAL: setTitle("CrossFinder: WillAD above "+var1+" signal "+dataList[dataSource]); break; case cross.WILLIAMS_AD_BELOW_SIGNAL: setTitle("CrossFinder: WillAD below "+var1+" signal "+dataList[dataSource]); break; case cross.PDI_ABOVE_LEVEL: setTitle("CrossFinder: "+var1+" DI+ above "+var2+" level"+" "+dataList[dataSource]); break; case cross:PDI_BELOW_LEVEL: setTitle("CrossFinder: "+var1+" DI+ below "+var2+" level"+" "+dataList[dataSource]); break; case cross.NDI_ABOVE_LEVEL: setTitle("CrossFinder: "+var1+" DI- above "+var2+" level"+" "+dataList[dataSource]); break; case cross.NDI_BELOW_LEVEL: setTitle("CrossFinder: "+var1+" DI- below "+var2+" level"+" "+dataList[dataSource]); break; case cross.PRICE_ABOVE_TOP_BB: setTitle("CrossFinder: Price above "+var1+" "+maTitleList[MAtype1]+" "+var3+" dev top BB "+dataList[dataSource]); break; case cross.PRICE_BELOW_TOP_BB: setTitle("CrossFinder: Price below "+var1+" "+maTitleList[MAtype1]+" "+var3+" dev bottom BB "+dataList[dataSource]); break; case cross.PRICE_ABOVE_BOTTOM_BB: setTitle("CrossFinder: Price above "+var1+" "+maTitleList[MAtype1]+" "+var3+" dev top BB "+dataList[dataSource]); break; case cross.PRICE_BELOW_BOTTOM_BB: setTitle("CrossFinder: Price below "+var1+" "+maTitleList[MAtype1]+" "+var3+" dev bottom BB "+dataList[dataSource]); break; case cross.ZERO_LAG_STUDY_BUY: setTitle("CrossFinder: ZeroLag Buy "+var1+" "+var2+" "+dataList[dataSource]); break; case cross.ZERO_LAG_STUDY_SELL: setTitle("CrossFinder: ZeroLag Sell "+var1+" "+var2+" "+dataList[dataSource]); break; case cross.AROON_UP_ABOVE_DOWN: setTitle("CrossFinder: "+var1+" Aroon Up above Aroon Down "+dataList[dataSource]); break; case cross.AROON_UP_BELOW_DOWN: setTitle("CrossFinder: "+var1+" Aroon Up below Aroon Down "+dataList[dataSource]); break; } } function getVal(share) { var data = getData(share,dataSource,useIntra,Math.max(var1,var2)*10) if (data.length<2) return; //create the objects needed to calculate the cross switch(crossType) { case cross.MACD_ABOVE_SIGNAL: case cross.MACD_BELOW_SIGNAL: case cross.MACD_ABOVE_ZERO: case cross.MACD_BELOW_ZERO: var macd1 = new MACD(var1,var2,var3);break; case cross.STOCHASTIC_OSCILLATOR_ABOVE_SIGNAL: case cross.STOCHASTIC_OSCILLATOR_BELOW_SIGNAL: var ohlcvIndicator = new StochOsc(var1,var2,var3,MAtype2);break; case cross.STOCHASTIC_OSCILLATOR_ABOVE_LEVEL: case cross.STOCHASTIC_OSCILLATOR_BELOW_LEVEL: var ohlcvIndicator = new StochOsc(var1,var2,2,MA.Simple);break; case cross.PDI_ABOVE_NDI: case cross.PDI_BELOW_NDI: case cross.ADX_ABOVE_LEVEL: case cross.ADX_BELOW_LEVEL: case cross.PDI_ABOVE_LEVEL: case cross.PDI_BELOW_LEVEL: case cross.NDI_ABOVE_LEVEL: case cross.NDI_BELOW_LEVEL: var adx1 = new ADX(var1);break; case cross.MOMENTUM_ABOVE_LEVEL: case cross.MOMENTUM_BELOW_LEVEL: var indicator1 = new Momentum(var1);break; case cross.RSI_ABOVE_LEVEL: case cross.RSI_BELOW_LEVEL: case cross.RSI_ABOVE_RSI: case cross.RSI_BELOW_RSI: var indicator1 = new RSI(var1); var indicator2 = new RSI(var2); break; case cross.POSITIVE_VOL_INDEX_ABOVE_SIGNAL: case cross.POSITIVE_VOL_INDEX_BELOW_SIGNAL: var ohlcvIndicator = new PVI(var1);break; case cross.NEGATIVE_VOL_INDEX_ABOVE_SIGNAL: case cross.NEGATIVE_VOL_INDEX_BELOW_SIGNAL: var ohlcvIndicator = new NVI(var1);break; case cross.PERCENTB_ABOVE_LEVEL: case cross.PERCENTB_BELOW_LEVEL: var indicator1 = new PercB(var1,MAtype1,var3);break; case cross.ZLTCD_ABOVE_SIGNAL: case cross.ZLTCD_BELOW_SIGNAL: var ohlcvIndicator = new ZLTCD(var1,var3);break; case cross.MFI_ABOVE_MFI: case cross.MFI_BELOW_MFI: var indicator1 = new MFI(var1); var indicator2 = new MFI(var2); break; case cross.CCI_ABOVE_LEVEL: case cross.CCI_BELOW_LEVEL: var indicator1 = new CCI(var1);break; case cross.WILLIAMS_AD_ABOVE_SIGNAL: case cross.WILLIAMS_AD_BELOW_SIGNAL: var ohlcvIndicator = new WillADSig(var1);break; case cross.PRICE_ABOVE_TOP_BB: case cross.PRICE_BELOW_TOP_BB: case cross.PRICE_ABOVE_BOTTOM_BB: case cross.PRICE_BELOW_BOTTOM_BB: var indicator1 = new BollBand(var1,MAtype1,var3);break; case cross.ZERO_LAG_STUDY_BUY: case cross.ZERO_LAG_STUDY_SELL: var indicator1 = new ZeroLagStudy(var1,var2);break; case cross.AROON_UP_ABOVE_DOWN: case cross.AROON_UP_BELOW_DOWN: var indicator1 = new Aroon(var1); default: if (MAtype1 == 8) //TEMA { var ma1 = new TEMA(var1); } else if (MAtype1 == 9) //VWAP { var ma1 = new MA(var1); var ma3 = new MA(var1); } else //all other MAs { var ma1 = new MA(var1,MAtype1); } if (MAtype2 == 8) //TEMA { var ma2 = new TEMA(var2); } else if (MAtype2 == 9) //VWAP { var ma2 = new MA(var2); var ma4 = new MA(var2); } else //all other MAs { var ma2 = new MA(var2,MAtype2); } } var line1 = new Array(); var line2 = new Array(); var output = 0; // the necessary indicators are calculated for (var i=0;iline1[a]?1:0; else if (crossType==cross.PRICE_BELOW_MA || crossType==cross.PRICE_BELOW_TOP_BB || crossType==cross.PRICE_BELOW_BOTTOM_BB) output = data[b].close>line1[b]&&data[a].closeline2[a]?1:0; else output = line1[b]>line2[b]&&line1[a]3?3:var3); if (dlg2.show()==Dialog.Cancel) return false; MAtype1 = dlg2.getValue("DL2"); var1 = dlg2.getValue("INT1"); var3 = dlg2.getValue("DL3"); } function dialog2(status) //ma crossing ma { dlg2 = new Dialog("Settings...",160,100); dlg2.addOkButton(); dlg2.addCancelButton(); dlg2.addDropList("DL2",8,-1,80,-1,maList,"","",MAtype1); dlg2.addIntEdit("INT1",8,-1,-1,-1,"","Short period",var1,2,1000); dlg2.addDropList("DL4",8,-1,40,-1,["Open","High","Low","Close"],"","Data source",var3>3?3:var3); dlg2.addDropList("DL3",8,-1,80,-1,maList,"","",MAtype2); dlg2.addIntEdit("INT2",8,-1,-1,-1,"","Long period",var2,3,1000); dlg2.addDropList("DL5",8,-1,40,-1,["Open","High","Low","Close"],"","Data source",var4); if (dlg2.show()==Dialog.Cancel) return false; MAtype1 = dlg2.getValue("DL2"); var1 = dlg2.getValue("INT1"); MAtype2 = dlg2.getValue("DL3"); var2 = dlg2.getValue("INT2"); var3 = dlg2.getValue("DL4"); //PH - new data choices var4 = dlg2.getValue("DL5"); } function dialog3(status) //macd cross { dlg2 = new Dialog("Settings...",160,75); dlg2.addOkButton(); dlg2.addCancelButton(); dlg2.addIntEdit("INT1",8,-1,-1,-1,"","Short period",var1,2,1000); dlg2.addIntEdit("INT2",8,-1,-1,-1,"","Long period",var2,3,1000); dlg2.addIntEdit("INT3",8,-1,-1,-1,"","Signal period",var3,2,1000); if (dlg2.show()==Dialog.Cancel) return false; var1 = dlg2.getValue("INT1"); var2 = dlg2.getValue("INT2"); var3 = dlg2.getValue("INT3"); } function dialog4(status) //stochastic cross { dlg2 = new Dialog("Settings...",160,75); dlg2.addOkButton(); dlg2.addCancelButton(); dlg2.addIntEdit("INT1",8,-1,-1,-1,"","Period",(status==Adding?20:var1),2,1000); dlg2.addIntEdit("INT2",8,-1,-1,-1,"","Slowing",(status==Adding?2:var2),1,1000); dlg2.addDropList("DL3",8,-1,80,-1,maList,"","",MAtype2); dlg2.addIntEdit("INT3",8,-1,-1,-1,"","Signal period",var3,2,1000); if (dlg2.show()==Dialog.Cancel) return false; var1 = dlg2.getValue("INT1"); MAtype2 = dlg2.getValue("DL3"); var2 = dlg2.getValue("INT2"); var3 = dlg2.getValue("INT3"); } function dialog5(status) //di+ crossing di-, pos and neg volume index crossing signal & Williams A/D crossing signal, Aroon Cross { dlg2 = new Dialog("Settings...",160,75); dlg2.addOkButton(); dlg2.addCancelButton(); dlg2.addIntEdit("INT1",8,-1,-1,-1,"","Period",(status==Adding?14:var1),2,1000); if (dlg2.show()==Dialog.Cancel) return false; var1 = dlg2.getValue("INT1"); } function dialog6(status) //momentum, rsi, CCI and ADX crossing level { dlg2 = new Dialog("Settings...",160,75); dlg2.addOkButton(); dlg2.addCancelButton(); dlg2.addIntEdit("INT1",8,-1,-1,-1,"","Period",(status==Adding?14:var1),2,1000); dlg2.addNumEdit("NUM1",8,-1,-1,-1,"","Level",(status==Adding?30:var2),-400,400); if (dlg2.show()==Dialog.Cancel) return false; var1 = dlg2.getValue("INT1"); var2 = dlg2.getValue("NUM1"); } function dialog7(status) //%b crossing level { dlg2 = new Dialog("Settings...",160,75); dlg2.addOkButton(); dlg2.addCancelButton(); dlg2.addDropList("DL2",8,-1,80,-1,maList,"","",MAtype1); dlg2.addIntEdit("INT1",8,-1,-1,-1,"","Period",(status==Adding?20:var1),2,1000); dlg2.addNumEdit("NUM1",8,-1,-1,-1,"","St. Deviations",(status==Adding?1.5:var3),0.1,5); dlg2.addNumEdit("NUM2",8,-1,-1,-1,"","Level",(status==Adding?0:var2),-5,5); if (dlg2.show()==Dialog.Cancel) return false; MAtype1 = dlg2.getValue("DL2"); var1 = dlg2.getValue("INT1"); var3 = dlg2.getValue("NUM1"); var2 = dlg2.getValue("NUM2"); } function dialog8(status) //ZLTCD crossing signal { dlg2 = new Dialog("Settings...",160,75); dlg2.addOkButton(); dlg2.addCancelButton(); dlg2.addIntEdit("INT1",8,-1,-1,-1,"","Period",(status==Adding?10:var1),2,1000); dlg2.addIntEdit("INT2",8,-1,-1,-1,"","Signal",(status==Adding?5:var3),2,1000); if (dlg2.show()==Dialog.Cancel) return false; var1 = dlg2.getValue("INT1"); var3 = dlg2.getValue("INT2"); } function dialog9(status) //stochastic crossing level { dlg2 = new Dialog("Settings...",160,75); dlg2.addOkButton(); dlg2.addCancelButton(); dlg2.addIntEdit("INT1",8,-1,-1,-1,"","Period",(status==Adding?20:var1),2,1000); dlg2.addIntEdit("INT2",8,-1,-1,-1,"","Slowing",(status==Adding?2:var2),1,1000); dlg2.addIntEdit("INT3",8,-1,-1,-1,"","Level",(status==Adding?20:var3),0,100); if (dlg2.show()==Dialog.Cancel) return false; var1 = dlg2.getValue("INT1"); var2 = dlg2.getValue("INT2"); var3 = dlg2.getValue("INT3"); } function dialog10(status) //Money Flow Index crossing Money Flow Index, RSI crossing RSI { dlg2 = new Dialog("Settings...",160,75); dlg2.addOkButton(); dlg2.addCancelButton(); dlg2.addIntEdit("INT1",8,-1,-1,-1,"","Short period",(status==Adding?10:var1),2,1000); dlg2.addIntEdit("INT2",8,-1,-1,-1,"","Long period",(status==Adding?20:var2),3,1000); if (dlg2.show()==Dialog.Cancel) return false; var1 = dlg2.getValue("INT1"); var2 = dlg2.getValue("INT2"); } function dialog11(status) //price crossing bollinger band { dlg2 = new Dialog("Settings...",160,75); dlg2.addOkButton(); dlg2.addCancelButton(); dlg2.addDropList("DL2",8,-1,80,-1,maList,"","",MAtype1); dlg2.addIntEdit("INT1",8,-1,-1,-1,"","Period",(status==Adding?20:var1),2,1000); dlg2.addNumEdit("NUM1",8,-1,-1,-1,"","St. Deviations",(status==Adding?1.5:var3),0.1,5); if (dlg2.show()==Dialog.Cancel) return false; MAtype1 = dlg2.getValue("DL2"); var1 = dlg2.getValue("INT1"); var3 = dlg2.getValue("NUM1"); } function dialog12(status) //zero lag study { dlg2 = new Dialog("Settings...",160,75); dlg2.addOkButton(); dlg2.addCancelButton(); dlg2.addIntEdit("INT1",8,-1,-1,-1,"","Period",(status==Adding?32:var1),2,1000); dlg2.addIntEdit("INT2",8,-1,-1,-1,"","Gain Limit",(status==Adding?22:var2),3,1000); if (dlg2.show()==Dialog.Cancel) return false; var1 = dlg2.getValue("INT1"); var2 = dlg2.getValue("INT2"); } function TEMA(p) { this.period = p; this.emaVal1; this.emaVal2; this.emaVal3; } TEMA.prototype.getNext = function (price) { var ma1 = new MA(this.period, MA.Exponential); var ma2 = new MA(this.period, MA.Exponential); var ma3 = new MA(this.period, MA.Exponential) if (this.emaVal1 != undefined) this.emaVal1 = ma1.getNext(this.emaVal1); this.emaVal1 = ma1.getNext((price.high+price.low+price.close)/3); if (this.emaVal2 != undefined) this.emaVal2 = ma2.getNext(this.emaVal2); this.emaVal2 = ma2.getNext(this.emaVal1); if (this.emaVal3 != undefined) this.emaVal3 = ma3.getNext(this.emaVal3); this.emaVal3 = ma3.getNext(this.emaVal2); var tema = 3*this.emaVal1-3*this.emaVal2+this.emaVal3; return tema; } //Negative Volume Index function function NVI(p) { this.nviValue; this.ma1 = new MA(p); this.signal; this.prevVol; this.prevC; } NVI.prototype.next = function (price) { if (price.isOHLCV) { if (this.nviValue==undefined) { this.nviValue = price.close; } else if (price.volumethis.prevVol) { this.pviValue = this.pviValue+(price.close/this.prevC-1)*this.pviValue; } this.signal = this.ma1.getNext(this.pviValue); this.prevVol = price.volume; this.prevC = price.close; } } PVI.prototype.getMain = function () { return this.pviValue; } PVI.prototype.getSignal = function () { return this.signal; } //%b indicator function function PercB(p,t,d) { this.period = p; this.ma1 = new MA(p,t); this.devs = d; this.priceArray = []; } PercB.prototype.getNext = function (price) { var av1 = this.ma1.getNext(price); //Close price MA this.priceArray[this.priceArray.length] = price; if (this.priceArray.lengththis.period) this.priceArray.shift(); var y1 = 0; //Bollinger band calculations for (var i=0;ithis.period) this.priceArray.shift(); var y1 = 0; //Bollinger band calculations for (var i=0;i=this.period+1) { var pmf = 0; var nmf = 0; for (var i=1;i<=this.period;i++) { if (this.typ[this.typ.length-i]>this.typ[this.typ.length-i-1]) pmf += this.mf[this.mf.length-i]; else if (this.typ[this.typ.length-i]=0;i--) { tempData = share.getIBarArray(i,dataPeriod*60); if (tempData==undefined || tempData.length<1) continue; data = data.concat(share.getIBarArray(i,dataPeriod*60)); } if (data==undefined || data[0]==undefined || data.length<2) return []; } else if (dataType==15 && useIntra==0) var data = share.getPriceArray(); else if (dataType==16 && useIntra==0) var data = share.getWeeklyBarArray(); else if (dataType==17 && useIntra==0) var data = share.getMonthlyBarArray(); //daily else if (dataType==15 && useIntra==1) { var data = share.getPriceArray(); if (data.length<2) return []; var idata = share.getIBarArray(0,86400); if (idata!=undefined && idata.length==1 && new Date().getDate()==idata[0].date.getDate() && new Date().getDate()!=data[data.length-1].date.getDate()) { data[data.length]={ open:idata[0].open, high:idata[0].high, low:idata[0].low, close:(share.getIClose()==null?share.getIMid():share.getIClose()), volume:idata[0].volume, dateNum:idata[0].dateNum, date:idata[0].date}; } } //weekly else if (dataType==16 && useIntra==1) { var data = share.getWeeklyBarArray(); if (data.length<2) return []; var idata = share.getIBarArray(0,86400); if (idata!=undefined && idata.length==1 && new Date().getDate()==idata[0].date.getDate() && new Date().getDate()!=data[data.length-1].date.getDate()) { if (idata[0].date.getDay()data[data.length-1].high?idata[0].high:data[data.length-1].high), low:(idata[0].lowdata[data.length-1].high?idata[0].high:data[data.length-1].high), low:(idata[0].lowtempData[tempData.length-1].high?idata[0].high:tempData[tempData.length-1].high), low:(idata[0].lowdata[data.length-1].high?tempData[i].high:data[data.length-1].high), low:(tempData[i].low8388608) print("Too much data for single storage space") return output } function restore(storage, data) { var remainder = storage var rangeTot = 1 for (var i=0;i=0;i--) { if (i