//@LibraryID:197,4 //@Name:Alarm:ASO Cross //@Description:An alarm that triggers when the Adaptive Stochastic Oscillator crosses the set trigger level //@Update:Periodic, 60 //@Env:Production //@Returns:Text //@Width:120 // 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 var dataList = ["Daily","Weekly","Monthly"]; var dataType = 0; var minPeriod = 7; var maxPeriod = 28; var slowPeriod = 2; var topTrigger = 80; var bottomTrigger = 20; var crossType = 0; function init(status) { if (status == Loading || status == Editing) { dataType = storage.getAt(0); minPeriod = storage.getAt(1); maxPeriod = storage.getAt(2); slowPeriod = storage.getAt(3); topTrigger = storage.getAt(4); bottomTrigger = storage.getAt(5); crossType = storage.getAt(6); } if (status == Adding || status == Editing) { dlg = new Dialog("ASO Alarm",160,175); dlg.addOkButton(); dlg.addCancelButton(); dlg.addDropList("DL1",8,-1,80,-1,dataList,"","",dataType); dlg.addIntEdit("INT1",8,-1,-1,-1,"","Min Period",minPeriod,2,1000); dlg.addIntEdit("INT2",8,-1,-1,-1,"","Max Period",maxPeriod,2,1000); dlg.addIntEdit("INT3",8,-1,-1,-1,"","Slowing Periods",slowPeriod,2,1000); dlg.addNumEdit("NUM1",8,-1,-1,-1,"","Top Trigger",topTrigger,0,100.0); dlg.addNumEdit("NUM2",8,-1,-1,-1,"","Bottom Trigger",bottomTrigger,0,100.0); dlg.addDropList("DL2",8,-1,80,-1,["Inside to Outside","Outside to Inside"],"","",crossType); dlg.addText(8,120,134,50,"\"Inside to Outside\" will trigger the alarm when the ASO moves from inside the"+ " trigger levels (i.e. between 80 and 20) to outside (i.e. above 80 or below 20). "+ "\"Outside to Inside\" triggeres when the opposite occurs."); if (dlg.show()==Dialog.Cancel) return false; dataType = dlg.getValue("DL1"); minPeriod = dlg.getValue("INT1"); maxPeriod = dlg.getValue("INT2"); slowPeriod = dlg.getValue("INT3"); topTrigger = dlg.getValue("NUM1"); bottomTrigger = dlg.getValue("NUM2"); crossType = dlg.getValue("DL2"); storage.setAt(0, dataType); storage.setAt(1, minPeriod); storage.setAt(2, maxPeriod); storage.setAt(3, slowPeriod); storage.setAt(4, topTrigger); storage.setAt(5, bottomTrigger); storage.setAt(6, crossType); } } function getVal(share) { if (dataType == 0) { var data = share.getPriceArray(maxPeriod*4); if (data.length < maxPeriod*4) return; var iPrice = share.getIBarArray(0, 86400); if (iPrice != undefined && iPrice.length == 1 && share.getIDate() > data[data.length-1].date) data[data.length] = iPrice[0]; } if (dataType == 1) var data = share.getWeeklyBarArray(maxPeriod*4); if (dataType == 2) var data = share.getMonthlyBarArray(maxPeriod*4); var aso = new AdaptiveStochOsc(minPeriod, maxPeriod, slowPeriod, 9); aso.next(data); var aso0 = aso.getMain(); data.length--; aso = new AdaptiveStochOsc(minPeriod, maxPeriod, slowPeriod, 9); aso.next(data); var aso1 = aso.getMain(); var oldAlarm = getValueForShare(share); var alarmText; if (oldAlarm == undefined || !isAlarmContext) { if ((!crossType && aso1topTrigger) || (crossType && aso1>topTrigger && aso0bottomTrigger && aso0bottomTrigger)) { setValueForShare(share, -1); if (!crossType) alarmText = minPeriod+","+maxPeriod+","+slowPeriod+", ASO crossed outside "+bottomTrigger; else alarmText = minPeriod+","+maxPeriod+","+slowPeriod+", ASO crossed inside "+bottomTrigger; } } else { if ((!crossType && aso0bottomTrigger) || (crossType && (aso0>topTrigger || aso0