//@Name:TSI //@Description:Draws the True Strength Index (TSI). A variant of the RSI, the TSI's overbought/oversold levels are usually 25/-25. // 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, ShareScope Support var longPeriod=25; var shortPeriod=13; var signal=7; var overbought = 25; var oversold = -25; //var MAList = ["Simple","Exponential","Weighted","Triangular","VariableVHF","VariableCMO","Vidya"]; var colour1=11862016; var colour2=11862016; var colour3=255; var width1=0; var width2=0; var width3=0; var pen1=0; var pen2=2; var pen3=0; //var MAType=0; function init(status) { if (status == Loading || status == Editing) { var temp = restore(storage.getAt(0),[[pen1,0,4],[pen2,0,4],[pen3,0,4]]); pen1 = temp[0][0]; pen2 = temp[1][0]; pen3 = temp[2][0]; var temp = restore(storage.getAt(1),[[width1,0,7],[width2,0,7],[signal,2,999]]); width1 = temp[0][0]; width2 = temp[1][0]; signal = temp[2][0]; var temp = restore(storage.getAt(2),[[longPeriod,2,999],[shortPeriod,2,999],[width3,0,7]]); longPeriod = temp[0][0]; shortPeriod = temp[1][0]; width3 = temp[2][0]; colour1 = storage.getAt(3); colour2 = storage.getAt(4); colour3 = storage.getAt(5); var temp = restore(storage.getAt(6),[[overbought,-100,100],[oversold,-100,100]]); overbought = temp[0][0]; oversold = temp[1][0]; } if (status == Adding || status == Editing) { var dlg = new Dialog("Stochastic Oscilator", 285, 100); dlg.addOkButton(); dlg.addCancelButton(); dlg.addGroupBox(5,5,220,30,"Smoothing periods"); dlg.addIntEdit("INT1",8,15,-1,-1, "","1st smoothing",longPeriod,2,999); dlg.addColLinePicker("INT3",90,15,-1,-1,"","",colour1,pen1,width1); dlg.addIntEdit("INT2",185,15,-1,-1, "2nd smoothing","",shortPeriod,2,999); dlg.addGroupBox(5,35,220,30,"Signal period"); dlg.addIntEdit("INT4",8,45,-1,-1, "","Signal",signal,2,999); dlg.addColLinePicker("INT5",90,45,-1,-1,"","",colour2,pen2,width2); //dlg.addDropList("INT6",150,45,-1,-1, MAList, "Method","",MAType); dlg.addGroupBox(5,65,220,30,"Horizontal Lines"); dlg.addIntEdit("INT7",8,75,-1,-1, "","Overbought level",overbought,-100,100); dlg.addIntEdit("INT8",105,75,-1,-1, "","Oversold level",oversold,-100,100); dlg.addColLinePicker("INT9",185,75,-1,-1,"","",colour3,pen3,width3); if (dlg.show() == Dialog.Cancel) return false; longPeriod = dlg.getValue("INT1"); shortPeriod = dlg.getValue("INT2"); signal = dlg.getValue("INT4"); overbought = dlg.getValue("INT7"); oversold = dlg.getValue("INT8"); //MAType=dlg.getValue("INT6"); colour1 = dlg.getValue("INT3").colour; pen1 = dlg.getValue("INT3").pen; width1 = dlg.getValue("INT3").width; colour2 = dlg.getValue("INT5").colour; pen2 = dlg.getValue("INT5").pen; width2 = dlg.getValue("INT5").width; colour3 = dlg.getValue("INT9").colour; pen3 = dlg.getValue("INT9").pen; width3 = dlg.getValue("INT9").width; storage.setAt(0, compress([[pen1,0,4],[pen2,0,4],[pen3,0,4]])); storage.setAt(1, compress([[width1,0,7],[width2,0,7],[signal,2,999]])); storage.setAt(2, compress([[longPeriod,2,999],[shortPeriod,2,999],[width3,0,7]])); storage.setAt(3, colour1); storage.setAt(4, colour2); storage.setAt(5, colour3); storage.setAt(6, compress([[overbought,-100,100],[oversold,-100,100]])); } setTitle("TSI ("+longPeriod+", "+shortPeriod+", "+signal+")"); setSeriesColour(0, colour1); setSeriesLineStyle(0, pen1, width1); setSeriesColour(1, colour2); setSeriesLineStyle(1, pen2, width2); setSeriesColour(2, colour3); setSeriesLineStyle(2, pen3, width3); setSeriesColour(3, colour3); setSeriesLineStyle(3, pen3, width3); //setRange(Range.MinMax,-100,100); setHorizontalLine(0); } function getGraph(share, data) { var ma1 = new MA(longPeriod,MA.Exponential); var ma2 = new MA(shortPeriod,MA.Exponential); var ma3 = new MA(longPeriod,MA.Exponential); var ma4 = new MA(shortPeriod,MA.Exponential); var ma5 = new MA(signal,MA.Exponential); var TSI = []; var sigLine = [] var TSI = []; var OutputOB = []; var OutputOS = []; for (var i=1;i8388608) print("Too much data for single storage space") return output } //restore from compression algorithm //storage is the compress function output and data is the same as compress function input. //individual values in "data" aren't important (those get overwritten), but min and max values are function restore(storage, data) { var remainder = storage var rangeTot = 1 for (var i=0;i=0;i--) { if (i