indicators-all.src.js 340 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680
  1. /**
  2. * @license Highstock JS v8.2.0 (2020-08-20)
  3. *
  4. * All technical indicators for Highstock
  5. *
  6. * (c) 2010-2019 Pawel Fus
  7. *
  8. * License: www.highcharts.com/license
  9. */
  10. 'use strict';
  11. (function (factory) {
  12. if (typeof module === 'object' && module.exports) {
  13. factory['default'] = factory;
  14. module.exports = factory;
  15. } else if (typeof define === 'function' && define.amd) {
  16. define('highcharts/indicators/indicators-all', ['highcharts', 'highcharts/modules/stock'], function (Highcharts) {
  17. factory(Highcharts);
  18. factory.Highcharts = Highcharts;
  19. return factory;
  20. });
  21. } else {
  22. factory(typeof Highcharts !== 'undefined' ? Highcharts : undefined);
  23. }
  24. }(function (Highcharts) {
  25. var _modules = Highcharts ? Highcharts._modules : {};
  26. function _registerModule(obj, path, args, fn) {
  27. if (!obj.hasOwnProperty(path)) {
  28. obj[path] = fn.apply(null, args);
  29. }
  30. }
  31. _registerModule(_modules, 'Mixins/IndicatorRequired.js', [_modules['Core/Utilities.js']], function (U) {
  32. /**
  33. *
  34. * (c) 2010-2020 Daniel Studencki
  35. *
  36. * License: www.highcharts.com/license
  37. *
  38. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  39. *
  40. * */
  41. var error = U.error;
  42. /* eslint-disable no-invalid-this, valid-jsdoc */
  43. var requiredIndicatorMixin = {
  44. /**
  45. * Check whether given indicator is loaded,
  46. else throw error.
  47. * @private
  48. * @param {Highcharts.Indicator} indicator
  49. * Indicator constructor function.
  50. * @param {string} requiredIndicator
  51. * Required indicator type.
  52. * @param {string} type
  53. * Type of indicator where function was called (parent).
  54. * @param {Highcharts.IndicatorCallbackFunction} callback
  55. * Callback which is triggered if the given indicator is loaded.
  56. * Takes indicator as an argument.
  57. * @param {string} errMessage
  58. * Error message that will be logged in console.
  59. * @return {boolean}
  60. * Returns false when there is no required indicator loaded.
  61. */
  62. isParentLoaded: function (indicator,
  63. requiredIndicator,
  64. type,
  65. callback,
  66. errMessage) {
  67. if (indicator) {
  68. return callback ? callback(indicator) : true;
  69. }
  70. error(errMessage || this.generateMessage(type, requiredIndicator));
  71. return false;
  72. },
  73. /**
  74. * @private
  75. * @param {string} indicatorType
  76. * Indicator type
  77. * @param {string} required
  78. * Required indicator
  79. * @return {string}
  80. * Error message
  81. */
  82. generateMessage: function (indicatorType, required) {
  83. return 'Error: "' + indicatorType +
  84. '" indicator type requires "' + required +
  85. '" indicator loaded before. Please read docs: ' +
  86. 'https://api.highcharts.com/highstock/plotOptions.' +
  87. indicatorType;
  88. }
  89. };
  90. return requiredIndicatorMixin;
  91. });
  92. _registerModule(_modules, 'Stock/Indicators/Indicators.js', [_modules['Core/Globals.js'], _modules['Mixins/IndicatorRequired.js'], _modules['Core/Utilities.js']], function (H, requiredIndicator, U) {
  93. /* *
  94. *
  95. * License: www.highcharts.com/license
  96. *
  97. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  98. *
  99. * */
  100. var addEvent = U.addEvent,
  101. error = U.error,
  102. extend = U.extend,
  103. isArray = U.isArray,
  104. pick = U.pick,
  105. seriesType = U.seriesType,
  106. splat = U.splat;
  107. var Series = H.Series,
  108. seriesTypes = H.seriesTypes,
  109. ohlcProto = H.seriesTypes.ohlc.prototype,
  110. generateMessage = requiredIndicator.generateMessage;
  111. /**
  112. * The parameter allows setting line series type and use OHLC indicators. Data
  113. * in OHLC format is required.
  114. *
  115. * @sample {highstock} stock/indicators/use-ohlc-data
  116. * Plot line on Y axis
  117. *
  118. * @type {boolean}
  119. * @product highstock
  120. * @apioption plotOptions.line.useOhlcData
  121. */
  122. /* eslint-disable no-invalid-this */
  123. addEvent(H.Series, 'init', function (eventOptions) {
  124. var series = this,
  125. options = eventOptions.options;
  126. if (options.useOhlcData &&
  127. options.id !== 'highcharts-navigator-series') {
  128. extend(series, {
  129. pointValKey: ohlcProto.pointValKey,
  130. keys: ohlcProto.keys,
  131. pointArrayMap: ohlcProto.pointArrayMap,
  132. toYData: ohlcProto.toYData
  133. });
  134. }
  135. });
  136. addEvent(Series, 'afterSetOptions', function (e) {
  137. var options = e.options,
  138. dataGrouping = options.dataGrouping;
  139. if (dataGrouping &&
  140. options.useOhlcData &&
  141. options.id !== 'highcharts-navigator-series') {
  142. dataGrouping.approximation = 'ohlc';
  143. }
  144. });
  145. /* eslint-enable no-invalid-this */
  146. /**
  147. * The SMA series type.
  148. *
  149. * @private
  150. * @class
  151. * @name Highcharts.seriesTypes.sma
  152. *
  153. * @augments Highcharts.Series
  154. */
  155. seriesType('sma', 'line',
  156. /**
  157. * Simple moving average indicator (SMA). This series requires `linkedTo`
  158. * option to be set.
  159. *
  160. * @sample stock/indicators/sma
  161. * Simple moving average indicator
  162. *
  163. * @extends plotOptions.line
  164. * @since 6.0.0
  165. * @excluding allAreas, colorAxis, dragDrop, joinBy, keys,
  166. * navigatorOptions, pointInterval, pointIntervalUnit,
  167. * pointPlacement, pointRange, pointStart, showInNavigator,
  168. * stacking, useOhlcData
  169. * @product highstock
  170. * @requires stock/indicators/indicators
  171. * @optionparent plotOptions.sma
  172. */
  173. {
  174. /**
  175. * The name of the series as shown in the legend, tooltip etc. If not
  176. * set, it will be based on a technical indicator type and default
  177. * params.
  178. *
  179. * @type {string}
  180. */
  181. name: void 0,
  182. tooltip: {
  183. /**
  184. * Number of decimals in indicator series.
  185. */
  186. valueDecimals: 4
  187. },
  188. /**
  189. * The main series ID that indicator will be based on. Required for this
  190. * indicator.
  191. *
  192. * @type {string}
  193. */
  194. linkedTo: void 0,
  195. /**
  196. * Whether to compare indicator to the main series values
  197. * or indicator values.
  198. *
  199. * @sample {highstock} stock/plotoptions/series-comparetomain/
  200. * Difference between comparing SMA values to the main series
  201. * and its own values.
  202. *
  203. * @type {boolean}
  204. */
  205. compareToMain: false,
  206. /**
  207. * Paramters used in calculation of regression series' points.
  208. */
  209. params: {
  210. /**
  211. * The point index which indicator calculations will base. For
  212. * example using OHLC data, index=2 means the indicator will be
  213. * calculated using Low values.
  214. */
  215. index: 0,
  216. /**
  217. * The base period for indicator calculations. This is the number of
  218. * data points which are taken into account for the indicator
  219. * calculations.
  220. */
  221. period: 14
  222. }
  223. },
  224. /**
  225. * @lends Highcharts.Series.prototype
  226. */
  227. {
  228. processData: function () {
  229. var series = this,
  230. compareToMain = series.options.compareToMain,
  231. linkedParent = series.linkedParent;
  232. Series.prototype.processData.apply(series, arguments);
  233. if (linkedParent && linkedParent.compareValue && compareToMain) {
  234. series.compareValue = linkedParent.compareValue;
  235. }
  236. return;
  237. },
  238. bindTo: {
  239. series: true,
  240. eventName: 'updatedData'
  241. },
  242. hasDerivedData: true,
  243. useCommonDataGrouping: true,
  244. nameComponents: ['period'],
  245. nameSuffixes: [],
  246. calculateOn: 'init',
  247. // Defines on which other indicators is this indicator based on.
  248. requiredIndicators: [],
  249. requireIndicators: function () {
  250. var obj = {
  251. allLoaded: true
  252. };
  253. // Check whether all required indicators are loaded, else return
  254. // the object with missing indicator's name.
  255. this.requiredIndicators.forEach(function (indicator) {
  256. if (seriesTypes[indicator]) {
  257. seriesTypes[indicator].prototype.requireIndicators();
  258. }
  259. else {
  260. obj.allLoaded = false;
  261. obj.needed = indicator;
  262. }
  263. });
  264. return obj;
  265. },
  266. init: function (chart, options) {
  267. var indicator = this,
  268. requiredIndicators = indicator.requireIndicators();
  269. // Check whether all required indicators are loaded.
  270. if (!requiredIndicators.allLoaded) {
  271. return error(generateMessage(indicator.type, requiredIndicators.needed));
  272. }
  273. Series.prototype.init.call(indicator, chart, options);
  274. // Make sure we find series which is a base for an indicator
  275. chart.linkSeries();
  276. indicator.dataEventsToUnbind = [];
  277. /**
  278. * @private
  279. * @return {void}
  280. */
  281. function recalculateValues() {
  282. var oldData = indicator.points || [],
  283. oldDataLength = (indicator.xData || []).length,
  284. processedData = indicator.getValues(indicator.linkedParent,
  285. indicator.options.params) || {
  286. values: [],
  287. xData: [],
  288. yData: []
  289. },
  290. croppedDataValues = [],
  291. overwriteData = true,
  292. oldFirstPointIndex,
  293. oldLastPointIndex,
  294. croppedData,
  295. min,
  296. max,
  297. i;
  298. // We need to update points to reflect changes in all,
  299. // x and y's, values. However, do it only for non-grouped
  300. // data - grouping does it for us (#8572)
  301. if (oldDataLength &&
  302. !indicator.hasGroupedData &&
  303. indicator.visible &&
  304. indicator.points) {
  305. // When data is cropped update only avaliable points (#9493)
  306. if (indicator.cropped) {
  307. if (indicator.xAxis) {
  308. min = indicator.xAxis.min;
  309. max = indicator.xAxis.max;
  310. }
  311. croppedData = indicator.cropData(processedData.xData, processedData.yData, min, max);
  312. for (i = 0; i < croppedData.xData.length; i++) {
  313. // (#10774)
  314. croppedDataValues.push([
  315. croppedData.xData[i]
  316. ].concat(splat(croppedData.yData[i])));
  317. }
  318. oldFirstPointIndex = processedData.xData.indexOf(indicator.xData[0]);
  319. oldLastPointIndex = processedData.xData.indexOf(indicator.xData[indicator.xData.length - 1]);
  320. // Check if indicator points should be shifted (#8572)
  321. if (oldFirstPointIndex === -1 &&
  322. oldLastPointIndex === processedData.xData.length - 2) {
  323. if (croppedDataValues[0][0] === oldData[0].x) {
  324. croppedDataValues.shift();
  325. }
  326. }
  327. indicator.updateData(croppedDataValues);
  328. // Omit addPoint() and removePoint() cases
  329. }
  330. else if (processedData.xData.length !== oldDataLength - 1 &&
  331. processedData.xData.length !== oldDataLength + 1) {
  332. overwriteData = false;
  333. indicator.updateData(processedData.values);
  334. }
  335. }
  336. if (overwriteData) {
  337. indicator.xData = processedData.xData;
  338. indicator.yData = processedData.yData;
  339. indicator.options.data = processedData.values;
  340. }
  341. // Removal of processedXData property is required because on
  342. // first translate processedXData array is empty
  343. if (indicator.bindTo.series === false) {
  344. delete indicator.processedXData;
  345. indicator.isDirty = true;
  346. indicator.redraw();
  347. }
  348. indicator.isDirtyData = false;
  349. }
  350. if (!indicator.linkedParent) {
  351. return error('Series ' +
  352. indicator.options.linkedTo +
  353. ' not found! Check `linkedTo`.', false, chart);
  354. }
  355. indicator.dataEventsToUnbind.push(addEvent(indicator.bindTo.series ?
  356. indicator.linkedParent : indicator.linkedParent.xAxis, indicator.bindTo.eventName, recalculateValues));
  357. if (indicator.calculateOn === 'init') {
  358. recalculateValues();
  359. }
  360. else {
  361. var unbinder = addEvent(indicator.chart,
  362. indicator.calculateOn,
  363. function () {
  364. recalculateValues();
  365. // Call this just once, on init
  366. unbinder();
  367. });
  368. }
  369. return indicator;
  370. },
  371. getName: function () {
  372. var name = this.name,
  373. params = [];
  374. if (!name) {
  375. (this.nameComponents || []).forEach(function (component, index) {
  376. params.push(this.options.params[component] +
  377. pick(this.nameSuffixes[index], ''));
  378. }, this);
  379. name = (this.nameBase || this.type.toUpperCase()) +
  380. (this.nameComponents ? ' (' + params.join(', ') + ')' : '');
  381. }
  382. return name;
  383. },
  384. getValues: function (series, params) {
  385. var period = params.period,
  386. xVal = series.xData,
  387. yVal = series.yData,
  388. yValLen = yVal.length,
  389. range = 0,
  390. sum = 0,
  391. SMA = [],
  392. xData = [],
  393. yData = [],
  394. index = -1,
  395. i,
  396. SMAPoint;
  397. if (xVal.length < period) {
  398. return;
  399. }
  400. // Switch index for OHLC / Candlestick / Arearange
  401. if (isArray(yVal[0])) {
  402. index = params.index ? params.index : 0;
  403. }
  404. // Accumulate first N-points
  405. while (range < period - 1) {
  406. sum += index < 0 ? yVal[range] : yVal[range][index];
  407. range++;
  408. }
  409. // Calculate value one-by-one for each period in visible data
  410. for (i = range; i < yValLen; i++) {
  411. sum += index < 0 ? yVal[i] : yVal[i][index];
  412. SMAPoint = [xVal[i], sum / period];
  413. SMA.push(SMAPoint);
  414. xData.push(SMAPoint[0]);
  415. yData.push(SMAPoint[1]);
  416. sum -= (index < 0 ?
  417. yVal[i - range] :
  418. yVal[i - range][index]);
  419. }
  420. return {
  421. values: SMA,
  422. xData: xData,
  423. yData: yData
  424. };
  425. },
  426. destroy: function () {
  427. this.dataEventsToUnbind.forEach(function (unbinder) {
  428. unbinder();
  429. });
  430. Series.prototype.destroy.apply(this, arguments);
  431. }
  432. });
  433. /**
  434. * A `SMA` series. If the [type](#series.sma.type) option is not specified, it
  435. * is inherited from [chart.type](#chart.type).
  436. *
  437. * @extends series,plotOptions.sma
  438. * @since 6.0.0
  439. * @product highstock
  440. * @excluding dataParser, dataURL, useOhlcData
  441. * @requires stock/indicators/indicators
  442. * @apioption series.sma
  443. */
  444. ''; // adds doclet above to the transpiled file
  445. });
  446. _registerModule(_modules, 'Stock/Indicators/ADIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  447. /* *
  448. *
  449. * License: www.highcharts.com/license
  450. *
  451. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  452. * */
  453. var error = U.error,
  454. seriesType = U.seriesType;
  455. /* eslint-disable valid-jsdoc */
  456. // Utils:
  457. /**
  458. * @private
  459. */
  460. function populateAverage(xVal, yVal, yValVolume, i) {
  461. var high = yVal[i][1],
  462. low = yVal[i][2],
  463. close = yVal[i][3],
  464. volume = yValVolume[i],
  465. adY = close === high && close === low || high === low ?
  466. 0 :
  467. ((2 * close - low - high) / (high - low)) * volume,
  468. adX = xVal[i];
  469. return [adX, adY];
  470. }
  471. /* eslint-enable valid-jsdoc */
  472. /**
  473. * The AD series type.
  474. *
  475. * @private
  476. * @class
  477. * @name Highcharts.seriesTypes.ad
  478. *
  479. * @augments Highcharts.Series
  480. */
  481. seriesType('ad', 'sma',
  482. /**
  483. * Accumulation Distribution (AD). This series requires `linkedTo` option to
  484. * be set.
  485. *
  486. * @sample stock/indicators/accumulation-distribution
  487. * Accumulation/Distribution indicator
  488. *
  489. * @extends plotOptions.sma
  490. * @since 6.0.0
  491. * @product highstock
  492. * @requires stock/indicators/indicators
  493. * @requires stock/indicators/accumulation-distribution
  494. * @optionparent plotOptions.ad
  495. */
  496. {
  497. params: {
  498. /**
  499. * The id of volume series which is mandatory.
  500. * For example using OHLC data, volumeSeriesID='volume' means
  501. * the indicator will be calculated using OHLC and volume values.
  502. *
  503. * @since 6.0.0
  504. */
  505. volumeSeriesID: 'volume'
  506. }
  507. },
  508. /**
  509. * @lends Highcharts.Series#
  510. */
  511. {
  512. nameComponents: false,
  513. nameBase: 'Accumulation/Distribution',
  514. getValues: function (series, params) {
  515. var period = params.period,
  516. xVal = series.xData,
  517. yVal = series.yData,
  518. volumeSeriesID = params.volumeSeriesID,
  519. volumeSeries = series.chart.get(volumeSeriesID),
  520. yValVolume = volumeSeries && volumeSeries.yData,
  521. yValLen = yVal ? yVal.length : 0,
  522. AD = [],
  523. xData = [],
  524. yData = [],
  525. len,
  526. i,
  527. ADPoint;
  528. if (xVal.length <= period &&
  529. yValLen &&
  530. yVal[0].length !== 4) {
  531. return;
  532. }
  533. if (!volumeSeries) {
  534. error('Series ' +
  535. volumeSeriesID +
  536. ' not found! Check `volumeSeriesID`.', true, series.chart);
  537. return;
  538. }
  539. // i = period <-- skip first N-points
  540. // Calculate value one-by-one for each period in visible data
  541. for (i = period; i < yValLen; i++) {
  542. len = AD.length;
  543. ADPoint = populateAverage(xVal, yVal, yValVolume, i, period);
  544. if (len > 0) {
  545. ADPoint[1] += AD[len - 1][1];
  546. }
  547. AD.push(ADPoint);
  548. xData.push(ADPoint[0]);
  549. yData.push(ADPoint[1]);
  550. }
  551. return {
  552. values: AD,
  553. xData: xData,
  554. yData: yData
  555. };
  556. }
  557. });
  558. /**
  559. * A `AD` series. If the [type](#series.ad.type) option is not
  560. * specified, it is inherited from [chart.type](#chart.type).
  561. *
  562. * @extends series,plotOptions.ad
  563. * @since 6.0.0
  564. * @excluding dataParser, dataURL
  565. * @product highstock
  566. * @requires stock/indicators/indicators
  567. * @requires stock/indicators/accumulation-distribution
  568. * @apioption series.ad
  569. */
  570. ''; // add doclet above to transpiled file
  571. });
  572. _registerModule(_modules, 'Stock/Indicators/AOIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
  573. /* *
  574. *
  575. * License: www.highcharts.com/license
  576. *
  577. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  578. *
  579. * */
  580. var correctFloat = U.correctFloat,
  581. isArray = U.isArray,
  582. seriesType = U.seriesType;
  583. var noop = H.noop;
  584. /**
  585. * The AO series type
  586. *
  587. * @private
  588. * @class
  589. * @name Highcharts.seriesTypes.ao
  590. *
  591. * @augments Highcharts.Series
  592. */
  593. seriesType('ao', 'sma',
  594. /**
  595. * Awesome Oscillator. This series requires the `linkedTo` option to
  596. * be set and should be loaded after the `stock/indicators/indicators.js`
  597. *
  598. * @sample {highstock} stock/indicators/ao
  599. * Awesome
  600. *
  601. * @extends plotOptions.sma
  602. * @since 7.0.0
  603. * @product highstock
  604. * @excluding allAreas, colorAxis, joinBy, keys, navigatorOptions,
  605. * params, pointInterval, pointIntervalUnit, pointPlacement,
  606. * pointRange, pointStart, showInNavigator, stacking
  607. * @requires stock/indicators/indicators
  608. * @requires stock/indicators/ao
  609. * @optionparent plotOptions.ao
  610. */
  611. {
  612. /**
  613. * Color of the Awesome oscillator series bar that is greater than the
  614. * previous one. Note that if a `color` is defined, the `color`
  615. * takes precedence and the `greaterBarColor` is ignored.
  616. *
  617. * @sample {highstock} stock/indicators/ao/
  618. * greaterBarColor
  619. *
  620. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  621. * @since 7.0.0
  622. */
  623. greaterBarColor: '#06B535',
  624. /**
  625. * Color of the Awesome oscillator series bar that is lower than the
  626. * previous one. Note that if a `color` is defined, the `color`
  627. * takes precedence and the `lowerBarColor` is ignored.
  628. *
  629. * @sample {highstock} stock/indicators/ao/
  630. * lowerBarColor
  631. *
  632. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  633. * @since 7.0.0
  634. */
  635. lowerBarColor: '#F21313',
  636. threshold: 0,
  637. groupPadding: 0.2,
  638. pointPadding: 0.2,
  639. crisp: false,
  640. states: {
  641. hover: {
  642. halo: {
  643. size: 0
  644. }
  645. }
  646. }
  647. },
  648. /**
  649. * @lends Highcharts.Series#
  650. */
  651. {
  652. nameBase: 'AO',
  653. nameComponents: false,
  654. // Columns support:
  655. markerAttribs: noop,
  656. getColumnMetrics: H.seriesTypes.column.prototype.getColumnMetrics,
  657. crispCol: H.seriesTypes.column.prototype.crispCol,
  658. translate: H.seriesTypes.column.prototype.translate,
  659. drawPoints: H.seriesTypes.column.prototype.drawPoints,
  660. drawGraph: function () {
  661. var indicator = this,
  662. options = indicator.options,
  663. points = indicator.points,
  664. userColor = indicator.userOptions.color,
  665. positiveColor = options.greaterBarColor,
  666. negativeColor = options.lowerBarColor,
  667. firstPoint = points[0],
  668. i;
  669. if (!userColor && firstPoint) {
  670. firstPoint.color = positiveColor;
  671. for (i = 1; i < points.length; i++) {
  672. if (points[i].y > points[i - 1].y) {
  673. points[i].color = positiveColor;
  674. }
  675. else if (points[i].y < points[i - 1].y) {
  676. points[i].color = negativeColor;
  677. }
  678. else {
  679. points[i].color = points[i - 1].color;
  680. }
  681. }
  682. }
  683. },
  684. getValues: function (series) {
  685. var shortPeriod = 5,
  686. longPeriod = 34,
  687. xVal = series.xData || [],
  688. yVal = series.yData || [],
  689. yValLen = yVal.length,
  690. AO = [], // 0- date, 1- Awesome Oscillator
  691. xData = [],
  692. yData = [],
  693. high = 1,
  694. low = 2,
  695. shortSum = 0,
  696. longSum = 0,
  697. shortSMA, // Shorter Period SMA
  698. longSMA, // Longer Period SMA
  699. awesome,
  700. shortLastIndex,
  701. longLastIndex,
  702. price,
  703. i,
  704. j;
  705. if (xVal.length <= longPeriod ||
  706. !isArray(yVal[0]) ||
  707. yVal[0].length !== 4) {
  708. return;
  709. }
  710. for (i = 0; i < longPeriod - 1; i++) {
  711. price = (yVal[i][high] + yVal[i][low]) / 2;
  712. if (i >= longPeriod - shortPeriod) {
  713. shortSum = correctFloat(shortSum + price);
  714. }
  715. longSum = correctFloat(longSum + price);
  716. }
  717. for (j = longPeriod - 1; j < yValLen; j++) {
  718. price = (yVal[j][high] + yVal[j][low]) / 2;
  719. shortSum = correctFloat(shortSum + price);
  720. longSum = correctFloat(longSum + price);
  721. shortSMA = shortSum / shortPeriod;
  722. longSMA = longSum / longPeriod;
  723. awesome = correctFloat(shortSMA - longSMA);
  724. AO.push([xVal[j], awesome]);
  725. xData.push(xVal[j]);
  726. yData.push(awesome);
  727. shortLastIndex = j + 1 - shortPeriod;
  728. longLastIndex = j + 1 - longPeriod;
  729. shortSum = correctFloat(shortSum -
  730. (yVal[shortLastIndex][high] +
  731. yVal[shortLastIndex][low]) / 2);
  732. longSum = correctFloat(longSum -
  733. (yVal[longLastIndex][high] +
  734. yVal[longLastIndex][low]) / 2);
  735. }
  736. return {
  737. values: AO,
  738. xData: xData,
  739. yData: yData
  740. };
  741. }
  742. });
  743. /**
  744. * An `AO` series. If the [type](#series.ao.type)
  745. * option is not specified, it is inherited from [chart.type](#chart.type).
  746. *
  747. * @extends series,plotOptions.ao
  748. * @since 7.0.0
  749. * @product highstock
  750. * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
  751. * navigatorOptions, pointInterval, pointIntervalUnit,
  752. * pointPlacement, pointRange, pointStart, showInNavigator, stacking
  753. * @requires stock/indicators/indicators
  754. * @requires stock/indicators/ao
  755. * @apioption series.ao
  756. */
  757. ''; // for including the above in the doclets
  758. });
  759. _registerModule(_modules, 'Mixins/MultipleLines.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
  760. /**
  761. *
  762. * (c) 2010-2020 Wojciech Chmiel
  763. *
  764. * License: www.highcharts.com/license
  765. *
  766. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  767. *
  768. * */
  769. var defined = U.defined,
  770. error = U.error,
  771. merge = U.merge;
  772. var SMA = H.seriesTypes.sma;
  773. /**
  774. * Mixin useful for all indicators that have more than one line.
  775. * Merge it with your implementation where you will provide
  776. * getValues method appropriate to your indicator and pointArrayMap,
  777. * pointValKey, linesApiNames properites. Notice that pointArrayMap
  778. * should be consistent with amount of lines calculated in getValues method.
  779. *
  780. * @private
  781. * @mixin multipleLinesMixin
  782. */
  783. var multipleLinesMixin = {
  784. /* eslint-disable valid-jsdoc */
  785. /**
  786. * Lines ids. Required to plot appropriate amount of lines.
  787. * Notice that pointArrayMap should have more elements than
  788. * linesApiNames, because it contains main line and additional lines ids.
  789. * Also it should be consistent with amount of lines calculated in
  790. * getValues method from your implementation.
  791. *
  792. * @private
  793. * @name multipleLinesMixin.pointArrayMap
  794. * @type {Array<string>}
  795. */
  796. pointArrayMap: ['top', 'bottom'],
  797. /**
  798. * Main line id.
  799. *
  800. * @private
  801. * @name multipleLinesMixin.pointValKey
  802. * @type {string}
  803. */
  804. pointValKey: 'top',
  805. /**
  806. * Additional lines DOCS names. Elements of linesApiNames array should
  807. * be consistent with DOCS line names defined in your implementation.
  808. * Notice that linesApiNames should have decreased amount of elements
  809. * relative to pointArrayMap (without pointValKey).
  810. *
  811. * @private
  812. * @name multipleLinesMixin.linesApiNames
  813. * @type {Array<string>}
  814. */
  815. linesApiNames: ['bottomLine'],
  816. /**
  817. * Create translatedLines Collection based on pointArrayMap.
  818. *
  819. * @private
  820. * @function multipleLinesMixin.getTranslatedLinesNames
  821. * @param {string} [excludedValue]
  822. * Main line id
  823. * @return {Array<string>}
  824. * Returns translated lines names without excluded value.
  825. */
  826. getTranslatedLinesNames: function (excludedValue) {
  827. var translatedLines = [];
  828. (this.pointArrayMap || []).forEach(function (propertyName) {
  829. if (propertyName !== excludedValue) {
  830. translatedLines.push('plot' +
  831. propertyName.charAt(0).toUpperCase() +
  832. propertyName.slice(1));
  833. }
  834. });
  835. return translatedLines;
  836. },
  837. /**
  838. * @private
  839. * @function multipleLinesMixin.toYData
  840. * @param {Highcharts.Point} point
  841. * Indicator point
  842. * @return {Array<number>}
  843. * Returns point Y value for all lines
  844. */
  845. toYData: function (point) {
  846. var pointColl = [];
  847. (this.pointArrayMap || []).forEach(function (propertyName) {
  848. pointColl.push(point[propertyName]);
  849. });
  850. return pointColl;
  851. },
  852. /**
  853. * Add lines plot pixel values.
  854. *
  855. * @private
  856. * @function multipleLinesMixin.translate
  857. * @return {void}
  858. */
  859. translate: function () {
  860. var indicator = this,
  861. pointArrayMap = indicator.pointArrayMap,
  862. LinesNames = [],
  863. value;
  864. LinesNames = indicator.getTranslatedLinesNames();
  865. SMA.prototype.translate.apply(indicator, arguments);
  866. indicator.points.forEach(function (point) {
  867. pointArrayMap.forEach(function (propertyName, i) {
  868. value = point[propertyName];
  869. if (value !== null) {
  870. point[LinesNames[i]] = indicator.yAxis.toPixels(value, true);
  871. }
  872. });
  873. });
  874. },
  875. /**
  876. * Draw main and additional lines.
  877. *
  878. * @private
  879. * @function multipleLinesMixin.drawGraph
  880. * @return {void}
  881. */
  882. drawGraph: function () {
  883. var indicator = this,
  884. pointValKey = indicator.pointValKey,
  885. linesApiNames = indicator.linesApiNames,
  886. mainLinePoints = indicator.points,
  887. pointsLength = mainLinePoints.length,
  888. mainLineOptions = indicator.options,
  889. mainLinePath = indicator.graph,
  890. gappedExtend = {
  891. options: {
  892. gapSize: mainLineOptions.gapSize
  893. }
  894. },
  895. // additional lines point place holders:
  896. secondaryLines = [],
  897. secondaryLinesNames = indicator.getTranslatedLinesNames(pointValKey),
  898. point;
  899. // Generate points for additional lines:
  900. secondaryLinesNames.forEach(function (plotLine, index) {
  901. // create additional lines point place holders
  902. secondaryLines[index] = [];
  903. while (pointsLength--) {
  904. point = mainLinePoints[pointsLength];
  905. secondaryLines[index].push({
  906. x: point.x,
  907. plotX: point.plotX,
  908. plotY: point[plotLine],
  909. isNull: !defined(point[plotLine])
  910. });
  911. }
  912. pointsLength = mainLinePoints.length;
  913. });
  914. // Modify options and generate additional lines:
  915. linesApiNames.forEach(function (lineName, i) {
  916. if (secondaryLines[i]) {
  917. indicator.points = secondaryLines[i];
  918. if (mainLineOptions[lineName]) {
  919. indicator.options = merge(mainLineOptions[lineName].styles, gappedExtend);
  920. }
  921. else {
  922. error('Error: "There is no ' + lineName +
  923. ' in DOCS options declared. Check if linesApiNames' +
  924. ' are consistent with your DOCS line names."' +
  925. ' at mixin/multiple-line.js:34');
  926. }
  927. indicator.graph = indicator['graph' + lineName];
  928. SMA.prototype.drawGraph.call(indicator);
  929. // Now save lines:
  930. indicator['graph' + lineName] = indicator.graph;
  931. }
  932. else {
  933. error('Error: "' + lineName + ' doesn\'t have equivalent ' +
  934. 'in pointArrayMap. To many elements in linesApiNames ' +
  935. 'relative to pointArrayMap."');
  936. }
  937. });
  938. // Restore options and draw a main line:
  939. indicator.points = mainLinePoints;
  940. indicator.options = mainLineOptions;
  941. indicator.graph = mainLinePath;
  942. SMA.prototype.drawGraph.call(indicator);
  943. }
  944. };
  945. return multipleLinesMixin;
  946. });
  947. _registerModule(_modules, 'Stock/Indicators/AroonIndicator.js', [_modules['Core/Utilities.js'], _modules['Mixins/MultipleLines.js']], function (U, multipleLinesMixin) {
  948. /* *
  949. *
  950. * License: www.highcharts.com/license
  951. *
  952. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  953. *
  954. * */
  955. var merge = U.merge,
  956. pick = U.pick,
  957. seriesType = U.seriesType;
  958. /* eslint-disable valid-jsdoc */
  959. // Utils
  960. // Index of element with extreme value from array (min or max)
  961. /**
  962. * @private
  963. */
  964. function getExtremeIndexInArray(arr, extreme) {
  965. var extremeValue = arr[0],
  966. valueIndex = 0,
  967. i;
  968. for (i = 1; i < arr.length; i++) {
  969. if (extreme === 'max' && arr[i] >= extremeValue ||
  970. extreme === 'min' && arr[i] <= extremeValue) {
  971. extremeValue = arr[i];
  972. valueIndex = i;
  973. }
  974. }
  975. return valueIndex;
  976. }
  977. /* eslint-enable valid-jsdoc */
  978. /**
  979. * The Aroon series type.
  980. *
  981. * @private
  982. * @class
  983. * @name Highcharts.seriesTypes.aroon
  984. *
  985. * @augments Highcharts.Series
  986. */
  987. seriesType('aroon', 'sma',
  988. /**
  989. * Aroon. This series requires the `linkedTo` option to be
  990. * set and should be loaded after the `stock/indicators/indicators.js`.
  991. *
  992. * @sample {highstock} stock/indicators/aroon
  993. * Aroon
  994. *
  995. * @extends plotOptions.sma
  996. * @since 7.0.0
  997. * @product highstock
  998. * @excluding allAreas, colorAxis, compare, compareBase, joinBy, keys,
  999. * navigatorOptions, pointInterval, pointIntervalUnit,
  1000. * pointPlacement, pointRange, pointStart, showInNavigator,
  1001. * stacking
  1002. * @requires stock/indicators/indicators
  1003. * @requires stock/indicators/aroon
  1004. * @optionparent plotOptions.aroon
  1005. */
  1006. {
  1007. /**
  1008. * Paramters used in calculation of aroon series points.
  1009. *
  1010. * @excluding periods, index
  1011. */
  1012. params: {
  1013. /**
  1014. * Period for Aroon indicator
  1015. */
  1016. period: 25
  1017. },
  1018. marker: {
  1019. enabled: false
  1020. },
  1021. tooltip: {
  1022. pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>Aroon Up: {point.y}<br/>Aroon Down: {point.aroonDown}<br/>'
  1023. },
  1024. /**
  1025. * aroonDown line options.
  1026. */
  1027. aroonDown: {
  1028. /**
  1029. * Styles for an aroonDown line.
  1030. */
  1031. styles: {
  1032. /**
  1033. * Pixel width of the line.
  1034. */
  1035. lineWidth: 1,
  1036. /**
  1037. * Color of the line. If not set, it's inherited from
  1038. * [plotOptions.aroon.color](#plotOptions.aroon.color).
  1039. *
  1040. * @type {Highcharts.ColorString}
  1041. */
  1042. lineColor: void 0
  1043. }
  1044. },
  1045. dataGrouping: {
  1046. approximation: 'averages'
  1047. }
  1048. },
  1049. /**
  1050. * @lends Highcharts.Series#
  1051. */
  1052. merge(multipleLinesMixin, {
  1053. nameBase: 'Aroon',
  1054. pointArrayMap: ['y', 'aroonDown'],
  1055. pointValKey: 'y',
  1056. linesApiNames: ['aroonDown'],
  1057. getValues: function (series, params) {
  1058. var period = params.period,
  1059. xVal = series.xData,
  1060. yVal = series.yData,
  1061. yValLen = yVal ? yVal.length : 0,
  1062. // 0- date, 1- Aroon Up, 2- Aroon Down
  1063. AR = [],
  1064. xData = [],
  1065. yData = [],
  1066. slicedY,
  1067. low = 2,
  1068. high = 1,
  1069. aroonUp,
  1070. aroonDown,
  1071. xLow,
  1072. xHigh,
  1073. i;
  1074. // For a N-period, we start from N-1 point, to calculate Nth point
  1075. // That is why we later need to comprehend slice() elements list
  1076. // with (+1)
  1077. for (i = period - 1; i < yValLen; i++) {
  1078. slicedY = yVal.slice(i - period + 1, i + 2);
  1079. xLow = getExtremeIndexInArray(slicedY.map(function (elem) {
  1080. return pick(elem[low], elem);
  1081. }), 'min');
  1082. xHigh = getExtremeIndexInArray(slicedY.map(function (elem) {
  1083. return pick(elem[high], elem);
  1084. }), 'max');
  1085. aroonUp = (xHigh / period) * 100;
  1086. aroonDown = (xLow / period) * 100;
  1087. if (xVal[i + 1]) {
  1088. AR.push([xVal[i + 1], aroonUp, aroonDown]);
  1089. xData.push(xVal[i + 1]);
  1090. yData.push([aroonUp, aroonDown]);
  1091. }
  1092. }
  1093. return {
  1094. values: AR,
  1095. xData: xData,
  1096. yData: yData
  1097. };
  1098. }
  1099. }));
  1100. /**
  1101. * A Aroon indicator. If the [type](#series.aroon.type) option is not
  1102. * specified, it is inherited from [chart.type](#chart.type).
  1103. *
  1104. * @extends series,plotOptions.aroon
  1105. * @since 7.0.0
  1106. * @product highstock
  1107. * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
  1108. * joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
  1109. * pointPlacement, pointRange, pointStart, showInNavigator, stacking
  1110. * @requires stock/indicators/indicators
  1111. * @requires stock/indicators/aroon
  1112. * @apioption series.aroon
  1113. */
  1114. ''; // to avoid removal of the above jsdoc
  1115. });
  1116. _registerModule(_modules, 'Stock/Indicators/AroonOscillatorIndicator.js', [_modules['Core/Globals.js'], _modules['Mixins/MultipleLines.js'], _modules['Mixins/IndicatorRequired.js'], _modules['Core/Utilities.js']], function (H, multipleLinesMixin, requiredIndicator, U) {
  1117. /* *
  1118. *
  1119. * License: www.highcharts.com/license
  1120. *
  1121. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  1122. *
  1123. * */
  1124. var merge = U.merge,
  1125. seriesType = U.seriesType;
  1126. var AROON = H.seriesTypes.aroon;
  1127. /**
  1128. * The Aroon Oscillator series type.
  1129. *
  1130. * @private
  1131. * @class
  1132. * @name Highcharts.seriesTypes.aroonoscillator
  1133. *
  1134. * @augments Highcharts.Series
  1135. */
  1136. seriesType('aroonoscillator', 'aroon',
  1137. /**
  1138. * Aroon Oscillator. This series requires the `linkedTo` option to be set
  1139. * and should be loaded after the `stock/indicators/indicators.js` and
  1140. * `stock/indicators/aroon.js`.
  1141. *
  1142. * @sample {highstock} stock/indicators/aroon-oscillator
  1143. * Aroon Oscillator
  1144. *
  1145. * @extends plotOptions.aroon
  1146. * @since 7.0.0
  1147. * @product highstock
  1148. * @excluding allAreas, aroonDown, colorAxis, compare, compareBase,
  1149. * joinBy, keys, navigatorOptions, pointInterval,
  1150. * pointIntervalUnit, pointPlacement, pointRange, pointStart,
  1151. * showInNavigator, stacking
  1152. * @requires stock/indicators/indicators
  1153. * @requires stock/indicators/aroon
  1154. * @requires stock/indicators/aroon-oscillator
  1155. * @optionparent plotOptions.aroonoscillator
  1156. */
  1157. {
  1158. /**
  1159. * Paramters used in calculation of aroon oscillator series points.
  1160. *
  1161. * @excluding periods, index
  1162. */
  1163. params: {
  1164. /**
  1165. * Period for Aroon Oscillator
  1166. *
  1167. * @since 7.0.0
  1168. * @product highstock
  1169. */
  1170. period: 25
  1171. },
  1172. tooltip: {
  1173. pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b>: {point.y}'
  1174. }
  1175. },
  1176. /**
  1177. * @lends Highcharts.Series#
  1178. */
  1179. merge(multipleLinesMixin, {
  1180. nameBase: 'Aroon Oscillator',
  1181. pointArrayMap: ['y'],
  1182. pointValKey: 'y',
  1183. linesApiNames: [],
  1184. init: function () {
  1185. var args = arguments,
  1186. ctx = this;
  1187. requiredIndicator.isParentLoaded(AROON, 'aroon', ctx.type, function (indicator) {
  1188. indicator.prototype.init.apply(ctx, args);
  1189. return;
  1190. });
  1191. },
  1192. getValues: function (series, params) {
  1193. // 0- date, 1- Aroon Oscillator
  1194. var ARO = [],
  1195. xData = [],
  1196. yData = [],
  1197. aroon,
  1198. aroonUp,
  1199. aroonDown,
  1200. oscillator,
  1201. i;
  1202. aroon = AROON.prototype.getValues.call(this, series, params);
  1203. for (i = 0; i < aroon.yData.length; i++) {
  1204. aroonUp = aroon.yData[i][0];
  1205. aroonDown = aroon.yData[i][1];
  1206. oscillator = aroonUp - aroonDown;
  1207. ARO.push([aroon.xData[i], oscillator]);
  1208. xData.push(aroon.xData[i]);
  1209. yData.push(oscillator);
  1210. }
  1211. return {
  1212. values: ARO,
  1213. xData: xData,
  1214. yData: yData
  1215. };
  1216. }
  1217. }));
  1218. /**
  1219. * An `Aroon Oscillator` series. If the [type](#series.aroonoscillator.type)
  1220. * option is not specified, it is inherited from [chart.type](#chart.type).
  1221. *
  1222. * @extends series,plotOptions.aroonoscillator
  1223. * @since 7.0.0
  1224. * @product highstock
  1225. * @excluding allAreas, aroonDown, colorAxis, compare, compareBase, dataParser,
  1226. * dataURL, joinBy, keys, navigatorOptions, pointInterval,
  1227. * pointIntervalUnit, pointPlacement, pointRange, pointStart,
  1228. * showInNavigator, stacking
  1229. * @requires stock/indicators/indicators
  1230. * @requires stock/indicators/aroon
  1231. * @requires stock/indicators/aroon-oscillator
  1232. * @apioption series.aroonoscillator
  1233. */
  1234. ''; // adds doclet above to the transpiled file
  1235. });
  1236. _registerModule(_modules, 'Stock/Indicators/ATRIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  1237. /* *
  1238. *
  1239. * License: www.highcharts.com/license
  1240. *
  1241. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  1242. *
  1243. * */
  1244. var isArray = U.isArray,
  1245. seriesType = U.seriesType;
  1246. var UNDEFINED;
  1247. /* eslint-disable valid-jsdoc */
  1248. // Utils:
  1249. /**
  1250. * @private
  1251. */
  1252. function accumulateAverage(points, xVal, yVal, i) {
  1253. var xValue = xVal[i],
  1254. yValue = yVal[i];
  1255. points.push([xValue, yValue]);
  1256. }
  1257. /**
  1258. * @private
  1259. */
  1260. function getTR(currentPoint, prevPoint) {
  1261. var pointY = currentPoint,
  1262. prevY = prevPoint,
  1263. HL = pointY[1] - pointY[2],
  1264. HCp = prevY === UNDEFINED ? 0 : Math.abs(pointY[1] - prevY[3]),
  1265. LCp = prevY === UNDEFINED ? 0 : Math.abs(pointY[2] - prevY[3]),
  1266. TR = Math.max(HL,
  1267. HCp,
  1268. LCp);
  1269. return TR;
  1270. }
  1271. /**
  1272. * @private
  1273. */
  1274. function populateAverage(points, xVal, yVal, i, period, prevATR) {
  1275. var x = xVal[i - 1],
  1276. TR = getTR(yVal[i - 1],
  1277. yVal[i - 2]),
  1278. y;
  1279. y = (((prevATR * (period - 1)) + TR) / period);
  1280. return [x, y];
  1281. }
  1282. /* eslint-enable valid-jsdoc */
  1283. /**
  1284. * The ATR series type.
  1285. *
  1286. * @private
  1287. * @class
  1288. * @name Highcharts.seriesTypes.atr
  1289. *
  1290. * @augments Highcharts.Series
  1291. */
  1292. seriesType('atr', 'sma',
  1293. /**
  1294. * Average true range indicator (ATR). This series requires `linkedTo`
  1295. * option to be set.
  1296. *
  1297. * @sample stock/indicators/atr
  1298. * ATR indicator
  1299. *
  1300. * @extends plotOptions.sma
  1301. * @since 6.0.0
  1302. * @product highstock
  1303. * @requires stock/indicators/indicators
  1304. * @requires stock/indicators/atr
  1305. * @optionparent plotOptions.atr
  1306. */
  1307. {
  1308. params: {
  1309. period: 14
  1310. }
  1311. },
  1312. /**
  1313. * @lends Highcharts.Series#
  1314. */
  1315. {
  1316. getValues: function (series, params) {
  1317. var period = params.period,
  1318. xVal = series.xData,
  1319. yVal = series.yData,
  1320. yValLen = yVal ? yVal.length : 0,
  1321. xValue = xVal[0],
  1322. yValue = yVal[0],
  1323. range = 1,
  1324. prevATR = 0,
  1325. TR = 0,
  1326. ATR = [],
  1327. xData = [],
  1328. yData = [],
  1329. point,
  1330. i,
  1331. points;
  1332. points = [[xValue, yValue]];
  1333. if ((xVal.length <= period) ||
  1334. !isArray(yVal[0]) ||
  1335. yVal[0].length !== 4) {
  1336. return;
  1337. }
  1338. for (i = 1; i <= yValLen; i++) {
  1339. accumulateAverage(points, xVal, yVal, i);
  1340. if (period < range) {
  1341. point = populateAverage(points, xVal, yVal, i, period, prevATR);
  1342. prevATR = point[1];
  1343. ATR.push(point);
  1344. xData.push(point[0]);
  1345. yData.push(point[1]);
  1346. }
  1347. else if (period === range) {
  1348. prevATR = TR / (i - 1);
  1349. ATR.push([xVal[i - 1], prevATR]);
  1350. xData.push(xVal[i - 1]);
  1351. yData.push(prevATR);
  1352. range++;
  1353. }
  1354. else {
  1355. TR += getTR(yVal[i - 1], yVal[i - 2]);
  1356. range++;
  1357. }
  1358. }
  1359. return {
  1360. values: ATR,
  1361. xData: xData,
  1362. yData: yData
  1363. };
  1364. }
  1365. });
  1366. /**
  1367. * A `ATR` series. If the [type](#series.atr.type) option is not specified, it
  1368. * is inherited from [chart.type](#chart.type).
  1369. *
  1370. * @extends series,plotOptions.atr
  1371. * @since 6.0.0
  1372. * @product highstock
  1373. * @excluding dataParser, dataURL
  1374. * @requires stock/indicators/indicators
  1375. * @requires stock/indicators/atr
  1376. * @apioption series.atr
  1377. */
  1378. ''; // to include the above in the js output
  1379. });
  1380. _registerModule(_modules, 'Stock/Indicators/BBIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Mixins/MultipleLines.js']], function (H, U, multipleLinesMixin) {
  1381. /**
  1382. *
  1383. * License: www.highcharts.com/license
  1384. *
  1385. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  1386. *
  1387. * */
  1388. var isArray = U.isArray,
  1389. merge = U.merge,
  1390. seriesType = U.seriesType;
  1391. var SMA = H.seriesTypes.sma;
  1392. /* eslint-disable valid-jsdoc */
  1393. // Utils:
  1394. /**
  1395. * @private
  1396. */
  1397. function getStandardDeviation(arr, index, isOHLC, mean) {
  1398. var variance = 0,
  1399. arrLen = arr.length,
  1400. std = 0,
  1401. i = 0,
  1402. value;
  1403. for (; i < arrLen; i++) {
  1404. value = (isOHLC ? arr[i][index] : arr[i]) - mean;
  1405. variance += value * value;
  1406. }
  1407. variance = variance / (arrLen - 1);
  1408. std = Math.sqrt(variance);
  1409. return std;
  1410. }
  1411. /* eslint-enable valid-jsdoc */
  1412. /**
  1413. * Bollinger Bands series type.
  1414. *
  1415. * @private
  1416. * @class
  1417. * @name Highcharts.seriesTypes.bb
  1418. *
  1419. * @augments Highcharts.Series
  1420. */
  1421. seriesType('bb', 'sma',
  1422. /**
  1423. * Bollinger bands (BB). This series requires the `linkedTo` option to be
  1424. * set and should be loaded after the `stock/indicators/indicators.js` file.
  1425. *
  1426. * @sample stock/indicators/bollinger-bands
  1427. * Bollinger bands
  1428. *
  1429. * @extends plotOptions.sma
  1430. * @since 6.0.0
  1431. * @product highstock
  1432. * @requires stock/indicators/indicators
  1433. * @requires stock/indicators/bollinger-bands
  1434. * @optionparent plotOptions.bb
  1435. */
  1436. {
  1437. params: {
  1438. period: 20,
  1439. /**
  1440. * Standard deviation for top and bottom bands.
  1441. */
  1442. standardDeviation: 2,
  1443. index: 3
  1444. },
  1445. /**
  1446. * Bottom line options.
  1447. */
  1448. bottomLine: {
  1449. /**
  1450. * Styles for a bottom line.
  1451. */
  1452. styles: {
  1453. /**
  1454. * Pixel width of the line.
  1455. */
  1456. lineWidth: 1,
  1457. /**
  1458. * Color of the line. If not set, it's inherited from
  1459. * [plotOptions.bb.color](#plotOptions.bb.color).
  1460. *
  1461. * @type {Highcharts.ColorString}
  1462. */
  1463. lineColor: void 0
  1464. }
  1465. },
  1466. /**
  1467. * Top line options.
  1468. *
  1469. * @extends plotOptions.bb.bottomLine
  1470. */
  1471. topLine: {
  1472. styles: {
  1473. lineWidth: 1,
  1474. /**
  1475. * @type {Highcharts.ColorString}
  1476. */
  1477. lineColor: void 0
  1478. }
  1479. },
  1480. tooltip: {
  1481. pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>Top: {point.top}<br/>Middle: {point.middle}<br/>Bottom: {point.bottom}<br/>'
  1482. },
  1483. marker: {
  1484. enabled: false
  1485. },
  1486. dataGrouping: {
  1487. approximation: 'averages'
  1488. }
  1489. },
  1490. /**
  1491. * @lends Highcharts.Series#
  1492. */
  1493. merge(multipleLinesMixin, {
  1494. pointArrayMap: ['top', 'middle', 'bottom'],
  1495. pointValKey: 'middle',
  1496. nameComponents: ['period', 'standardDeviation'],
  1497. linesApiNames: ['topLine', 'bottomLine'],
  1498. init: function () {
  1499. SMA.prototype.init.apply(this, arguments);
  1500. // Set default color for lines:
  1501. this.options = merge({
  1502. topLine: {
  1503. styles: {
  1504. lineColor: this.color
  1505. }
  1506. },
  1507. bottomLine: {
  1508. styles: {
  1509. lineColor: this.color
  1510. }
  1511. }
  1512. }, this.options);
  1513. },
  1514. getValues: function (series, params) {
  1515. var period = params.period,
  1516. standardDeviation = params.standardDeviation,
  1517. xVal = series.xData,
  1518. yVal = series.yData,
  1519. yValLen = yVal ? yVal.length : 0,
  1520. // 0- date, 1-middle line, 2-top line, 3-bottom line
  1521. BB = [],
  1522. // middle line, top line and bottom line
  1523. ML,
  1524. TL,
  1525. BL,
  1526. date,
  1527. xData = [],
  1528. yData = [],
  1529. slicedX,
  1530. slicedY,
  1531. stdDev,
  1532. isOHLC,
  1533. point,
  1534. i;
  1535. if (xVal.length < period) {
  1536. return;
  1537. }
  1538. isOHLC = isArray(yVal[0]);
  1539. for (i = period; i <= yValLen; i++) {
  1540. slicedX = xVal.slice(i - period, i);
  1541. slicedY = yVal.slice(i - period, i);
  1542. point = SMA.prototype.getValues.call(this, {
  1543. xData: slicedX,
  1544. yData: slicedY
  1545. }, params);
  1546. date = point.xData[0];
  1547. ML = point.yData[0];
  1548. stdDev = getStandardDeviation(slicedY, params.index, isOHLC, ML);
  1549. TL = ML + standardDeviation * stdDev;
  1550. BL = ML - standardDeviation * stdDev;
  1551. BB.push([date, TL, ML, BL]);
  1552. xData.push(date);
  1553. yData.push([TL, ML, BL]);
  1554. }
  1555. return {
  1556. values: BB,
  1557. xData: xData,
  1558. yData: yData
  1559. };
  1560. }
  1561. }));
  1562. /**
  1563. * A bollinger bands indicator. If the [type](#series.bb.type) option is not
  1564. * specified, it is inherited from [chart.type](#chart.type).
  1565. *
  1566. * @extends series,plotOptions.bb
  1567. * @since 6.0.0
  1568. * @excluding dataParser, dataURL
  1569. * @product highstock
  1570. * @requires stock/indicators/indicators
  1571. * @requires stock/indicators/bollinger-bands
  1572. * @apioption series.bb
  1573. */
  1574. ''; // to include the above in the js output
  1575. });
  1576. _registerModule(_modules, 'Stock/Indicators/CCIIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  1577. /* *
  1578. *
  1579. * License: www.highcharts.com/license
  1580. *
  1581. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  1582. * */
  1583. var isArray = U.isArray,
  1584. seriesType = U.seriesType;
  1585. /* eslint-disable valid-jsdoc */
  1586. // Utils:
  1587. /**
  1588. * @private
  1589. */
  1590. function sumArray(array) {
  1591. return array.reduce(function (prev, cur) {
  1592. return prev + cur;
  1593. }, 0);
  1594. }
  1595. /**
  1596. * @private
  1597. */
  1598. function meanDeviation(arr, sma) {
  1599. var len = arr.length,
  1600. sum = 0,
  1601. i;
  1602. for (i = 0; i < len; i++) {
  1603. sum += Math.abs(sma - (arr[i]));
  1604. }
  1605. return sum;
  1606. }
  1607. /* eslint-enable valid-jsdoc */
  1608. /**
  1609. * The CCI series type.
  1610. *
  1611. * @private
  1612. * @class
  1613. * @name Highcharts.seriesTypes.cci
  1614. *
  1615. * @augments Highcharts.Series
  1616. */
  1617. seriesType('cci', 'sma',
  1618. /**
  1619. * Commodity Channel Index (CCI). This series requires `linkedTo` option to
  1620. * be set.
  1621. *
  1622. * @sample stock/indicators/cci
  1623. * CCI indicator
  1624. *
  1625. * @extends plotOptions.sma
  1626. * @since 6.0.0
  1627. * @product highstock
  1628. * @requires stock/indicators/indicators
  1629. * @requires stock/indicators/cci
  1630. * @optionparent plotOptions.cci
  1631. */
  1632. {
  1633. params: {
  1634. period: 14
  1635. }
  1636. },
  1637. /**
  1638. * @lends Highcharts.Series#
  1639. */
  1640. {
  1641. getValues: function (series, params) {
  1642. var period = params.period,
  1643. xVal = series.xData,
  1644. yVal = series.yData,
  1645. yValLen = yVal ? yVal.length : 0,
  1646. TP = [],
  1647. periodTP = [],
  1648. range = 1,
  1649. CCI = [],
  1650. xData = [],
  1651. yData = [],
  1652. CCIPoint,
  1653. p,
  1654. len,
  1655. smaTP,
  1656. TPtemp,
  1657. meanDev,
  1658. i;
  1659. // CCI requires close value
  1660. if (xVal.length <= period ||
  1661. !isArray(yVal[0]) ||
  1662. yVal[0].length !== 4) {
  1663. return;
  1664. }
  1665. // accumulate first N-points
  1666. while (range < period) {
  1667. p = yVal[range - 1];
  1668. TP.push((p[1] + p[2] + p[3]) / 3);
  1669. range++;
  1670. }
  1671. for (i = period; i <= yValLen; i++) {
  1672. p = yVal[i - 1];
  1673. TPtemp = (p[1] + p[2] + p[3]) / 3;
  1674. len = TP.push(TPtemp);
  1675. periodTP = TP.slice(len - period);
  1676. smaTP = sumArray(periodTP) / period;
  1677. meanDev = meanDeviation(periodTP, smaTP) / period;
  1678. CCIPoint = ((TPtemp - smaTP) / (0.015 * meanDev));
  1679. CCI.push([xVal[i - 1], CCIPoint]);
  1680. xData.push(xVal[i - 1]);
  1681. yData.push(CCIPoint);
  1682. }
  1683. return {
  1684. values: CCI,
  1685. xData: xData,
  1686. yData: yData
  1687. };
  1688. }
  1689. });
  1690. /**
  1691. * A `CCI` series. If the [type](#series.cci.type) option is not
  1692. * specified, it is inherited from [chart.type](#chart.type).
  1693. *
  1694. * @extends series,plotOptions.cci
  1695. * @since 6.0.0
  1696. * @excluding dataParser, dataURL
  1697. * @product highstock
  1698. * @requires stock/indicators/indicators
  1699. * @requires stock/indicators/cci
  1700. * @apioption series.cci
  1701. */
  1702. ''; // to include the above in the js output
  1703. });
  1704. _registerModule(_modules, 'Stock/Indicators/CMFIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  1705. /* *
  1706. *
  1707. * (c) 2010-2020 Highsoft AS
  1708. *
  1709. * Author: Sebastian Domas
  1710. *
  1711. * Chaikin Money Flow indicator for Highstock
  1712. *
  1713. * License: www.highcharts.com/license
  1714. *
  1715. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  1716. *
  1717. * */
  1718. var seriesType = U.seriesType;
  1719. /**
  1720. * The CMF series type.
  1721. *
  1722. * @private
  1723. * @class
  1724. * @name Highcharts.seriesTypes.cmf
  1725. *
  1726. * @augments Highcharts.Series
  1727. */
  1728. seriesType('cmf', 'sma',
  1729. /**
  1730. * Chaikin Money Flow indicator (cmf).
  1731. *
  1732. * @sample stock/indicators/cmf/
  1733. * Chaikin Money Flow indicator
  1734. *
  1735. * @extends plotOptions.sma
  1736. * @since 6.0.0
  1737. * @excluding animationLimit
  1738. * @product highstock
  1739. * @requires stock/indicators/indicators
  1740. * @requires stock/indicators/cmf
  1741. * @optionparent plotOptions.cmf
  1742. */
  1743. {
  1744. params: {
  1745. period: 14,
  1746. /**
  1747. * The id of another series to use its data as volume data for the
  1748. * indiator calculation.
  1749. */
  1750. volumeSeriesID: 'volume'
  1751. }
  1752. },
  1753. /**
  1754. * @lends Highcharts.Series#
  1755. */
  1756. {
  1757. nameBase: 'Chaikin Money Flow',
  1758. /**
  1759. * Checks if the series and volumeSeries are accessible, number of
  1760. * points.x is longer than period, is series has OHLC data
  1761. * @private
  1762. * @param {Highcharts.CMFIndicator} this indicator to use.
  1763. * @return {boolean} True if series is valid and can be computed,
  1764. * otherwise false.
  1765. */
  1766. isValid: function () {
  1767. var chart = this.chart,
  1768. options = this.options,
  1769. series = this.linkedParent,
  1770. volumeSeries = (this.volumeSeries ||
  1771. (this.volumeSeries =
  1772. chart.get(options.params.volumeSeriesID))),
  1773. isSeriesOHLC = (series &&
  1774. series.yData &&
  1775. series.yData[0].length === 4);
  1776. /**
  1777. * @private
  1778. * @param {Highcharts.Series} serie to check length validity on.
  1779. * @return {boolean|undefined} true if length is valid.
  1780. */
  1781. function isLengthValid(serie) {
  1782. return serie.xData &&
  1783. serie.xData.length >= options.params.period;
  1784. }
  1785. return !!(series &&
  1786. volumeSeries &&
  1787. isLengthValid(series) &&
  1788. isLengthValid(volumeSeries) && isSeriesOHLC);
  1789. },
  1790. /**
  1791. * Returns indicator's data.
  1792. * @private
  1793. * @param {Highcharts.CMFIndicator} this indicator to use.
  1794. * @param {Highcharts.Series} series to calculate values from
  1795. * @param {Highcharts.CMFIndicatorParamsOptions} params to pass
  1796. * @return {boolean|Highcharts.IndicatorNullableValuesObject} Returns false if the
  1797. * indicator is not valid, otherwise returns Values object.
  1798. */
  1799. getValues: function (series, params) {
  1800. if (!this.isValid()) {
  1801. return;
  1802. }
  1803. return this.getMoneyFlow(series.xData, series.yData, this.volumeSeries.yData, params.period);
  1804. },
  1805. /**
  1806. * @private
  1807. * @param {Array<number>} xData - x timestamp values
  1808. * @param {Array<number>} seriesYData - yData of basic series
  1809. * @param {Array<number>} volumeSeriesYData - yData of volume series
  1810. * @param {number} period - indicator's param
  1811. * @return {Highcharts.IndicatorNullableValuesObject} object containing computed money
  1812. * flow data
  1813. */
  1814. getMoneyFlow: function (xData, seriesYData, volumeSeriesYData, period) {
  1815. var len = seriesYData.length,
  1816. moneyFlowVolume = [],
  1817. sumVolume = 0,
  1818. sumMoneyFlowVolume = 0,
  1819. moneyFlowXData = [],
  1820. moneyFlowYData = [],
  1821. values = [],
  1822. i,
  1823. point,
  1824. nullIndex = -1;
  1825. /**
  1826. * Calculates money flow volume, changes i, nullIndex vars from
  1827. * upper scope!
  1828. * @private
  1829. * @param {Array<number>} ohlc - OHLC point
  1830. * @param {number} volume - Volume point's y value
  1831. * @return {number|null} - volume * moneyFlowMultiplier
  1832. **/
  1833. function getMoneyFlowVolume(ohlc, volume) {
  1834. var high = ohlc[1],
  1835. low = ohlc[2],
  1836. close = ohlc[3],
  1837. isValid = volume !== null &&
  1838. high !== null &&
  1839. low !== null &&
  1840. close !== null &&
  1841. high !== low;
  1842. /**
  1843. * @private
  1844. * @param {number} h - High value
  1845. * @param {number} l - Low value
  1846. * @param {number} c - Close value
  1847. * @return {number} calculated multiplier for the point
  1848. **/
  1849. function getMoneyFlowMultiplier(h, l, c) {
  1850. return ((c - l) - (h - c)) / (h - l);
  1851. }
  1852. return isValid ?
  1853. getMoneyFlowMultiplier(high, low, close) * volume :
  1854. ((nullIndex = i), null);
  1855. }
  1856. if (period > 0 && period <= len) {
  1857. for (i = 0; i < period; i++) {
  1858. moneyFlowVolume[i] = getMoneyFlowVolume(seriesYData[i], volumeSeriesYData[i]);
  1859. sumVolume += volumeSeriesYData[i];
  1860. sumMoneyFlowVolume += moneyFlowVolume[i];
  1861. }
  1862. moneyFlowXData.push(xData[i - 1]);
  1863. moneyFlowYData.push(i - nullIndex >= period && sumVolume !== 0 ?
  1864. sumMoneyFlowVolume / sumVolume :
  1865. null);
  1866. values.push([moneyFlowXData[0], moneyFlowYData[0]]);
  1867. for (; i < len; i++) {
  1868. moneyFlowVolume[i] = getMoneyFlowVolume(seriesYData[i], volumeSeriesYData[i]);
  1869. sumVolume -= volumeSeriesYData[i - period];
  1870. sumVolume += volumeSeriesYData[i];
  1871. sumMoneyFlowVolume -= moneyFlowVolume[i - period];
  1872. sumMoneyFlowVolume += moneyFlowVolume[i];
  1873. point = [
  1874. xData[i],
  1875. i - nullIndex >= period ?
  1876. sumMoneyFlowVolume / sumVolume :
  1877. null
  1878. ];
  1879. moneyFlowXData.push(point[0]);
  1880. moneyFlowYData.push(point[1]);
  1881. values.push([point[0], point[1]]);
  1882. }
  1883. }
  1884. return {
  1885. values: values,
  1886. xData: moneyFlowXData,
  1887. yData: moneyFlowYData
  1888. };
  1889. }
  1890. });
  1891. /**
  1892. * A `CMF` series. If the [type](#series.cmf.type) option is not
  1893. * specified, it is inherited from [chart.type](#chart.type).
  1894. *
  1895. * @extends series,plotOptions.cmf
  1896. * @since 6.0.0
  1897. * @product highstock
  1898. * @excluding dataParser, dataURL
  1899. * @requires stock/indicators/indicators
  1900. * @requires stock/indicators/cmf
  1901. * @apioption series.cmf
  1902. */
  1903. ''; // adds doclet above to the transpiled file
  1904. });
  1905. _registerModule(_modules, 'Stock/Indicators/DPOIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  1906. /* *
  1907. *
  1908. * License: www.highcharts.com/license
  1909. *
  1910. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  1911. *
  1912. * */
  1913. var correctFloat = U.correctFloat,
  1914. pick = U.pick,
  1915. seriesType = U.seriesType;
  1916. /* eslint-disable valid-jsdoc */
  1917. // Utils
  1918. /**
  1919. * @private
  1920. */
  1921. function accumulatePoints(sum, yVal, i, index, subtract) {
  1922. var price = pick(yVal[i][index],
  1923. yVal[i]);
  1924. if (subtract) {
  1925. return correctFloat(sum - price);
  1926. }
  1927. return correctFloat(sum + price);
  1928. }
  1929. /* eslint-enable valid-jsdoc */
  1930. /**
  1931. * The DPO series type.
  1932. *
  1933. * @private
  1934. * @class
  1935. * @name Highcharts.seriesTypes.dpo
  1936. *
  1937. * @augments Highcharts.Series
  1938. */
  1939. seriesType('dpo', 'sma',
  1940. /**
  1941. * Detrended Price Oscillator. This series requires the `linkedTo` option to
  1942. * be set and should be loaded after the `stock/indicators/indicators.js`.
  1943. *
  1944. * @sample {highstock} stock/indicators/dpo
  1945. * Detrended Price Oscillator
  1946. *
  1947. * @extends plotOptions.sma
  1948. * @since 7.0.0
  1949. * @product highstock
  1950. * @excluding allAreas, colorAxis, compare, compareBase, joinBy, keys,
  1951. * navigatorOptions, pointInterval, pointIntervalUnit,
  1952. * pointPlacement, pointRange, pointStart, showInNavigator,
  1953. * stacking
  1954. * @requires stock/indicators/indicators
  1955. * @requires stock/indicators/dpo
  1956. * @optionparent plotOptions.dpo
  1957. */
  1958. {
  1959. /**
  1960. * Parameters used in calculation of Detrended Price Oscillator series
  1961. * points.
  1962. */
  1963. params: {
  1964. /**
  1965. * Period for Detrended Price Oscillator
  1966. */
  1967. period: 21
  1968. }
  1969. },
  1970. /**
  1971. * @lends Highcharts.Series#
  1972. */
  1973. {
  1974. nameBase: 'DPO',
  1975. getValues: function (series, params) {
  1976. var period = params.period,
  1977. index = params.index,
  1978. offset = Math.floor(period / 2 + 1),
  1979. range = period + offset,
  1980. xVal = series.xData || [],
  1981. yVal = series.yData || [],
  1982. yValLen = yVal.length,
  1983. // 0- date, 1- Detrended Price Oscillator
  1984. DPO = [],
  1985. xData = [],
  1986. yData = [],
  1987. sum = 0,
  1988. oscillator,
  1989. periodIndex,
  1990. rangeIndex,
  1991. price,
  1992. i,
  1993. j;
  1994. if (xVal.length <= range) {
  1995. return;
  1996. }
  1997. // Accumulate first N-points for SMA
  1998. for (i = 0; i < period - 1; i++) {
  1999. sum = accumulatePoints(sum, yVal, i, index);
  2000. }
  2001. // Detrended Price Oscillator formula:
  2002. // DPO = Price - Simple moving average [from (n / 2 + 1) days ago]
  2003. for (j = 0; j <= yValLen - range; j++) {
  2004. periodIndex = j + period - 1;
  2005. rangeIndex = j + range - 1;
  2006. // adding the last period point
  2007. sum = accumulatePoints(sum, yVal, periodIndex, index);
  2008. price = pick(yVal[rangeIndex][index], yVal[rangeIndex]);
  2009. oscillator = price - sum / period;
  2010. // substracting the first period point
  2011. sum = accumulatePoints(sum, yVal, j, index, true);
  2012. DPO.push([xVal[rangeIndex], oscillator]);
  2013. xData.push(xVal[rangeIndex]);
  2014. yData.push(oscillator);
  2015. }
  2016. return {
  2017. values: DPO,
  2018. xData: xData,
  2019. yData: yData
  2020. };
  2021. }
  2022. });
  2023. /**
  2024. * A Detrended Price Oscillator. If the [type](#series.dpo.type) option is not
  2025. * specified, it is inherited from [chart.type](#chart.type).
  2026. *
  2027. * @extends series,plotOptions.dpo
  2028. * @since 7.0.0
  2029. * @product highstock
  2030. * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
  2031. * joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
  2032. * pointPlacement, pointRange, pointStart, showInNavigator, stacking
  2033. * @requires stock/indicators/indicators
  2034. * @requires stock/indicators/dpo
  2035. * @apioption series.dpo
  2036. */
  2037. ''; // to include the above in the js output'
  2038. });
  2039. _registerModule(_modules, 'Stock/Indicators/EMAIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  2040. /* *
  2041. *
  2042. * License: www.highcharts.com/license
  2043. *
  2044. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2045. *
  2046. * */
  2047. var correctFloat = U.correctFloat,
  2048. isArray = U.isArray,
  2049. seriesType = U.seriesType;
  2050. /**
  2051. * The EMA series type.
  2052. *
  2053. * @private
  2054. * @class
  2055. * @name Highcharts.seriesTypes.ema
  2056. *
  2057. * @augments Highcharts.Series
  2058. */
  2059. seriesType('ema', 'sma',
  2060. /**
  2061. * Exponential moving average indicator (EMA). This series requires the
  2062. * `linkedTo` option to be set.
  2063. *
  2064. * @sample stock/indicators/ema
  2065. * Exponential moving average indicator
  2066. *
  2067. * @extends plotOptions.sma
  2068. * @since 6.0.0
  2069. * @product highstock
  2070. * @requires stock/indicators/indicators
  2071. * @requires stock/indicators/ema
  2072. * @optionparent plotOptions.ema
  2073. */
  2074. {
  2075. params: {
  2076. /**
  2077. * The point index which indicator calculations will base. For
  2078. * example using OHLC data, index=2 means the indicator will be
  2079. * calculated using Low values.
  2080. *
  2081. * By default index value used to be set to 0. Since Highstock 7
  2082. * by default index is set to 3 which means that the ema
  2083. * indicator will be calculated using Close values.
  2084. */
  2085. index: 3,
  2086. period: 9 // @merge 14 in v6.2
  2087. }
  2088. },
  2089. /**
  2090. * @lends Highcharts.Series#
  2091. */
  2092. {
  2093. accumulatePeriodPoints: function (period, index, yVal) {
  2094. var sum = 0,
  2095. i = 0,
  2096. y = 0;
  2097. while (i < period) {
  2098. y = index < 0 ? yVal[i] : yVal[i][index];
  2099. sum = sum + y;
  2100. i++;
  2101. }
  2102. return sum;
  2103. },
  2104. calculateEma: function (xVal, yVal, i, EMApercent, calEMA, index, SMA) {
  2105. var x = xVal[i - 1],
  2106. yValue = index < 0 ?
  2107. yVal[i - 1] :
  2108. yVal[i - 1][index],
  2109. y;
  2110. y = typeof calEMA === 'undefined' ?
  2111. SMA : correctFloat((yValue * EMApercent) +
  2112. (calEMA * (1 - EMApercent)));
  2113. return [x, y];
  2114. },
  2115. getValues: function (series, params) {
  2116. var period = params.period,
  2117. xVal = series.xData,
  2118. yVal = series.yData,
  2119. yValLen = yVal ? yVal.length : 0,
  2120. EMApercent = 2 / (period + 1),
  2121. sum = 0,
  2122. EMA = [],
  2123. xData = [],
  2124. yData = [],
  2125. index = -1,
  2126. SMA = 0,
  2127. calEMA,
  2128. EMAPoint,
  2129. i;
  2130. // Check period, if bigger than points length, skip
  2131. if (yValLen < period) {
  2132. return;
  2133. }
  2134. // Switch index for OHLC / Candlestick / Arearange
  2135. if (isArray(yVal[0])) {
  2136. index = params.index ? params.index : 0;
  2137. }
  2138. // Accumulate first N-points
  2139. sum = this.accumulatePeriodPoints(period, index, yVal);
  2140. // first point
  2141. SMA = sum / period;
  2142. // Calculate value one-by-one for each period in visible data
  2143. for (i = period; i < yValLen + 1; i++) {
  2144. EMAPoint = this.calculateEma(xVal, yVal, i, EMApercent, calEMA, index, SMA);
  2145. EMA.push(EMAPoint);
  2146. xData.push(EMAPoint[0]);
  2147. yData.push(EMAPoint[1]);
  2148. calEMA = EMAPoint[1];
  2149. }
  2150. return {
  2151. values: EMA,
  2152. xData: xData,
  2153. yData: yData
  2154. };
  2155. }
  2156. });
  2157. /**
  2158. * A `EMA` series. If the [type](#series.ema.type) option is not
  2159. * specified, it is inherited from [chart.type](#chart.type).
  2160. *
  2161. * @extends series,plotOptions.ema
  2162. * @since 6.0.0
  2163. * @product highstock
  2164. * @excluding dataParser, dataURL
  2165. * @requires stock/indicators/indicators
  2166. * @requires stock/indicators/ema
  2167. * @apioption series.ema
  2168. */
  2169. ''; // adds doclet above to the transpiled file
  2170. });
  2171. _registerModule(_modules, 'Stock/Indicators/ChaikinIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Mixins/IndicatorRequired.js']], function (H, U, requiredIndicator) {
  2172. /* *
  2173. *
  2174. * License: www.highcharts.com/license
  2175. *
  2176. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2177. *
  2178. * */
  2179. var correctFloat = U.correctFloat,
  2180. error = U.error,
  2181. seriesType = U.seriesType;
  2182. var EMA = H.seriesTypes.ema,
  2183. AD = H.seriesTypes.ad;
  2184. /**
  2185. * The Chaikin series type.
  2186. *
  2187. * @private
  2188. * @class
  2189. * @name Highcharts.seriesTypes.chaikin
  2190. *
  2191. * @augments Highcharts.Series
  2192. */
  2193. seriesType('chaikin', 'ema',
  2194. /**
  2195. * Chaikin Oscillator. This series requires the `linkedTo` option to
  2196. * be set and should be loaded after the `stock/indicators/indicators.js`
  2197. * and `stock/indicators/ema.js`.
  2198. *
  2199. * @sample {highstock} stock/indicators/chaikin
  2200. * Chaikin Oscillator
  2201. *
  2202. * @extends plotOptions.ema
  2203. * @since 7.0.0
  2204. * @product highstock
  2205. * @excluding allAreas, colorAxis, joinBy, keys, navigatorOptions,
  2206. * pointInterval, pointIntervalUnit, pointPlacement,
  2207. * pointRange, pointStart, showInNavigator, stacking
  2208. * @requires stock/indicators/indicators
  2209. * @requires stock/indicators/ema
  2210. * @requires stock/indicators/chaikin
  2211. * @optionparent plotOptions.chaikin
  2212. */
  2213. {
  2214. /**
  2215. * Paramters used in calculation of Chaikin Oscillator
  2216. * series points.
  2217. *
  2218. * @excluding index, period
  2219. */
  2220. params: {
  2221. /**
  2222. * The id of volume series which is mandatory.
  2223. * For example using OHLC data, volumeSeriesID='volume' means
  2224. * the indicator will be calculated using OHLC and volume values.
  2225. */
  2226. volumeSeriesID: 'volume',
  2227. /**
  2228. * Periods for Chaikin Oscillator calculations.
  2229. *
  2230. * @type {Array<number>}
  2231. * @default [3, 10]
  2232. */
  2233. periods: [3, 10]
  2234. }
  2235. },
  2236. /**
  2237. * @lends Highcharts.Series#
  2238. */
  2239. {
  2240. nameBase: 'Chaikin Osc',
  2241. nameComponents: ['periods'],
  2242. init: function () {
  2243. var args = arguments,
  2244. ctx = this;
  2245. requiredIndicator.isParentLoaded(EMA, 'ema', ctx.type, function (indicator) {
  2246. indicator.prototype.init.apply(ctx, args);
  2247. return;
  2248. });
  2249. },
  2250. getValues: function (series, params) {
  2251. var periods = params.periods,
  2252. period = params.period,
  2253. // Accumulation Distribution Line data
  2254. ADL,
  2255. // 0- date, 1- Chaikin Oscillator
  2256. CHA = [],
  2257. xData = [],
  2258. yData = [],
  2259. periodsOffset,
  2260. // Shorter Period EMA
  2261. SPE,
  2262. // Longer Period EMA
  2263. LPE,
  2264. oscillator,
  2265. i;
  2266. // Check if periods are correct
  2267. if (periods.length !== 2 || periods[1] <= periods[0]) {
  2268. error('Error: "Chaikin requires two periods. Notice, first ' +
  2269. 'period should be lower than the second one."');
  2270. return;
  2271. }
  2272. ADL = AD.prototype.getValues.call(this, series, {
  2273. volumeSeriesID: params.volumeSeriesID,
  2274. period: period
  2275. });
  2276. // Check if adl is calculated properly, if not skip
  2277. if (!ADL) {
  2278. return;
  2279. }
  2280. SPE = EMA.prototype.getValues.call(this, ADL, {
  2281. period: periods[0]
  2282. });
  2283. LPE = EMA.prototype.getValues.call(this, ADL, {
  2284. period: periods[1]
  2285. });
  2286. // Check if ema is calculated properly, if not skip
  2287. if (!SPE || !LPE) {
  2288. return;
  2289. }
  2290. periodsOffset = periods[1] - periods[0];
  2291. for (i = 0; i < LPE.yData.length; i++) {
  2292. oscillator = correctFloat(SPE.yData[i + periodsOffset] -
  2293. LPE.yData[i]);
  2294. CHA.push([LPE.xData[i], oscillator]);
  2295. xData.push(LPE.xData[i]);
  2296. yData.push(oscillator);
  2297. }
  2298. return {
  2299. values: CHA,
  2300. xData: xData,
  2301. yData: yData
  2302. };
  2303. }
  2304. });
  2305. /**
  2306. * A `Chaikin Oscillator` series. If the [type](#series.chaikin.type)
  2307. * option is not specified, it is inherited from [chart.type](#chart.type).
  2308. *
  2309. * @extends series,plotOptions.chaikin
  2310. * @since 7.0.0
  2311. * @product highstock
  2312. * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
  2313. * navigatorOptions, pointInterval, pointIntervalUnit,
  2314. * pointPlacement, pointRange, pointStart, stacking, showInNavigator
  2315. * @requires stock/indicators/indicators
  2316. * @requires stock/indicators/ema
  2317. * @requires stock/indicators/chaikin
  2318. * @apioption series.chaikin
  2319. */
  2320. ''; // to include the above in the js output
  2321. });
  2322. _registerModule(_modules, 'Stock/Indicators/DEMAIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Mixins/IndicatorRequired.js']], function (H, U, requiredIndicator) {
  2323. /* *
  2324. *
  2325. * License: www.highcharts.com/license
  2326. *
  2327. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2328. *
  2329. * */
  2330. var correctFloat = U.correctFloat,
  2331. isArray = U.isArray,
  2332. seriesType = U.seriesType;
  2333. var EMAindicator = H.seriesTypes.ema;
  2334. /**
  2335. * The DEMA series Type
  2336. *
  2337. * @private
  2338. * @class
  2339. * @name Highcharts.seriesTypes.dema
  2340. *
  2341. * @augments Highcharts.Series
  2342. */
  2343. seriesType('dema', 'ema',
  2344. /**
  2345. * Double exponential moving average (DEMA) indicator. This series requires
  2346. * `linkedTo` option to be set and should be loaded after the
  2347. * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
  2348. *
  2349. * @sample {highstock} stock/indicators/dema
  2350. * DEMA indicator
  2351. *
  2352. * @extends plotOptions.ema
  2353. * @since 7.0.0
  2354. * @product highstock
  2355. * @excluding allAreas, colorAxis, compare, compareBase, joinBy, keys,
  2356. * navigatorOptions, pointInterval, pointIntervalUnit,
  2357. * pointPlacement, pointRange, pointStart, showInNavigator,
  2358. * stacking
  2359. * @requires stock/indicators/indicators
  2360. * @requires stock/indicators/ema
  2361. * @requires stock/indicators/dema
  2362. * @optionparent plotOptions.dema
  2363. */
  2364. {},
  2365. /**
  2366. * @lends Highcharts.Series#
  2367. */
  2368. {
  2369. init: function () {
  2370. var args = arguments,
  2371. ctx = this;
  2372. requiredIndicator.isParentLoaded(EMAindicator, 'ema', ctx.type, function (indicator) {
  2373. indicator.prototype.init.apply(ctx, args);
  2374. return;
  2375. });
  2376. },
  2377. getEMA: function (yVal, prevEMA, SMA, index, i, xVal) {
  2378. return EMAindicator.prototype.calculateEma(xVal || [], yVal, typeof i === 'undefined' ? 1 : i, this.chart.series[0].EMApercent, prevEMA, typeof index === 'undefined' ? -1 : index, SMA);
  2379. },
  2380. getValues: function (series, params) {
  2381. var period = params.period,
  2382. doubledPeriod = 2 * period,
  2383. xVal = series.xData,
  2384. yVal = series.yData,
  2385. yValLen = yVal ? yVal.length : 0,
  2386. index = -1,
  2387. accumulatePeriodPoints = 0,
  2388. SMA = 0,
  2389. DEMA = [],
  2390. xDataDema = [],
  2391. yDataDema = [],
  2392. EMA = 0,
  2393. // EMA(EMA)
  2394. EMAlevel2,
  2395. // EMA of previous point
  2396. prevEMA,
  2397. prevEMAlevel2,
  2398. // EMA values array
  2399. EMAvalues = [],
  2400. i,
  2401. DEMAPoint;
  2402. series.EMApercent = (2 / (period + 1));
  2403. // Check period, if bigger than EMA points length, skip
  2404. if (yValLen < 2 * period - 1) {
  2405. return;
  2406. }
  2407. // Switch index for OHLC / Candlestick / Arearange
  2408. if (isArray(yVal[0])) {
  2409. index = params.index ? params.index : 0;
  2410. }
  2411. // Accumulate first N-points
  2412. accumulatePeriodPoints =
  2413. EMAindicator.prototype.accumulatePeriodPoints(period, index, yVal);
  2414. // first point
  2415. SMA = accumulatePeriodPoints / period;
  2416. accumulatePeriodPoints = 0;
  2417. // Calculate value one-by-one for each period in visible data
  2418. for (i = period; i < yValLen + 2; i++) {
  2419. if (i < yValLen + 1) {
  2420. EMA = this.getEMA(yVal, prevEMA, SMA, index, i)[1];
  2421. EMAvalues.push(EMA);
  2422. }
  2423. prevEMA = EMA;
  2424. // Summing first period points for EMA(EMA)
  2425. if (i < doubledPeriod) {
  2426. accumulatePeriodPoints += EMA;
  2427. }
  2428. else {
  2429. // Calculate DEMA
  2430. // First DEMA point
  2431. if (i === doubledPeriod) {
  2432. SMA = accumulatePeriodPoints / period;
  2433. }
  2434. EMA = EMAvalues[i - period - 1];
  2435. EMAlevel2 = this.getEMA([EMA], prevEMAlevel2, SMA)[1];
  2436. DEMAPoint = [
  2437. xVal[i - 2],
  2438. correctFloat(2 * EMA - EMAlevel2)
  2439. ];
  2440. DEMA.push(DEMAPoint);
  2441. xDataDema.push(DEMAPoint[0]);
  2442. yDataDema.push(DEMAPoint[1]);
  2443. prevEMAlevel2 = EMAlevel2;
  2444. }
  2445. }
  2446. return {
  2447. values: DEMA,
  2448. xData: xDataDema,
  2449. yData: yDataDema
  2450. };
  2451. }
  2452. });
  2453. /**
  2454. * A `DEMA` series. If the [type](#series.ema.type) option is not
  2455. * specified, it is inherited from [chart.type](#chart.type).
  2456. *
  2457. * @extends series,plotOptions.ema
  2458. * @since 7.0.0
  2459. * @product highstock
  2460. * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
  2461. * joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
  2462. * pointPlacement, pointRange, pointStart, showInNavigator, stacking
  2463. * @requires stock/indicators/indicators
  2464. * @requires stock/indicators/ema
  2465. * @requires stock/indicators/dema
  2466. * @apioption series.dema
  2467. */
  2468. ''; // adds doclet above to the transpiled file
  2469. });
  2470. _registerModule(_modules, 'Stock/Indicators/TEMAIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Mixins/IndicatorRequired.js']], function (H, U, requiredIndicator) {
  2471. /* *
  2472. *
  2473. * License: www.highcharts.com/license
  2474. *
  2475. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2476. *
  2477. * */
  2478. var correctFloat = U.correctFloat,
  2479. isArray = U.isArray,
  2480. seriesType = U.seriesType;
  2481. var EMAindicator = H.seriesTypes.ema;
  2482. /**
  2483. * The TEMA series type.
  2484. *
  2485. * @private
  2486. * @class
  2487. * @name Highcharts.seriesTypes.tema
  2488. *
  2489. * @augments Highcharts.Series
  2490. */
  2491. seriesType('tema', 'ema',
  2492. /**
  2493. * Triple exponential moving average (TEMA) indicator. This series requires
  2494. * `linkedTo` option to be set and should be loaded after the
  2495. * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
  2496. *
  2497. * @sample {highstock} stock/indicators/tema
  2498. * TEMA indicator
  2499. *
  2500. * @extends plotOptions.ema
  2501. * @since 7.0.0
  2502. * @product highstock
  2503. * @excluding allAreas, colorAxis, compare, compareBase, joinBy, keys,
  2504. * navigatorOptions, pointInterval, pointIntervalUnit,
  2505. * pointPlacement, pointRange, pointStart, showInNavigator,
  2506. * stacking
  2507. * @requires stock/indicators/indicators
  2508. * @requires stock/indicators/ema
  2509. * @requires stock/indicators/tema
  2510. * @optionparent plotOptions.tema
  2511. */
  2512. {},
  2513. /**
  2514. * @lends Highcharts.Series#
  2515. */
  2516. {
  2517. init: function () {
  2518. var args = arguments,
  2519. ctx = this;
  2520. requiredIndicator.isParentLoaded(EMAindicator, 'ema', ctx.type, function (indicator) {
  2521. indicator.prototype.init.apply(ctx, args);
  2522. return;
  2523. });
  2524. },
  2525. getEMA: function (yVal, prevEMA, SMA, index, i, xVal) {
  2526. return EMAindicator.prototype.calculateEma(xVal || [], yVal, typeof i === 'undefined' ? 1 : i, this.chart.series[0].EMApercent, prevEMA, typeof index === 'undefined' ? -1 : index, SMA);
  2527. },
  2528. getTemaPoint: function (xVal, tripledPeriod, EMAlevels, i) {
  2529. var TEMAPoint = [
  2530. xVal[i - 3],
  2531. correctFloat(3 * EMAlevels.level1 -
  2532. 3 * EMAlevels.level2 + EMAlevels.level3)
  2533. ];
  2534. return TEMAPoint;
  2535. },
  2536. getValues: function (series, params) {
  2537. var period = params.period,
  2538. doubledPeriod = 2 * period,
  2539. tripledPeriod = 3 * period,
  2540. xVal = series.xData,
  2541. yVal = series.yData,
  2542. yValLen = yVal ? yVal.length : 0,
  2543. index = -1,
  2544. accumulatePeriodPoints = 0,
  2545. SMA = 0,
  2546. TEMA = [],
  2547. xDataTema = [],
  2548. yDataTema = [],
  2549. // EMA of previous point
  2550. prevEMA,
  2551. prevEMAlevel2,
  2552. // EMA values array
  2553. EMAvalues = [],
  2554. EMAlevel2values = [],
  2555. i,
  2556. TEMAPoint,
  2557. // This object contains all EMA EMAlevels calculated like below
  2558. // EMA = level1
  2559. // EMA(EMA) = level2,
  2560. // EMA(EMA(EMA)) = level3,
  2561. EMAlevels = {};
  2562. series.EMApercent = (2 / (period + 1));
  2563. // Check period, if bigger than EMA points length, skip
  2564. if (yValLen < 3 * period - 2) {
  2565. return;
  2566. }
  2567. // Switch index for OHLC / Candlestick / Arearange
  2568. if (isArray(yVal[0])) {
  2569. index = params.index ? params.index : 0;
  2570. }
  2571. // Accumulate first N-points
  2572. accumulatePeriodPoints =
  2573. EMAindicator.prototype.accumulatePeriodPoints(period, index, yVal);
  2574. // first point
  2575. SMA = accumulatePeriodPoints / period;
  2576. accumulatePeriodPoints = 0;
  2577. // Calculate value one-by-one for each period in visible data
  2578. for (i = period; i < yValLen + 3; i++) {
  2579. if (i < yValLen + 1) {
  2580. EMAlevels.level1 = this.getEMA(yVal, prevEMA, SMA, index, i)[1];
  2581. EMAvalues.push(EMAlevels.level1);
  2582. }
  2583. prevEMA = EMAlevels.level1;
  2584. // Summing first period points for ema(ema)
  2585. if (i < doubledPeriod) {
  2586. accumulatePeriodPoints += EMAlevels.level1;
  2587. }
  2588. else {
  2589. // Calculate dema
  2590. // First dema point
  2591. if (i === doubledPeriod) {
  2592. SMA = accumulatePeriodPoints / period;
  2593. accumulatePeriodPoints = 0;
  2594. }
  2595. EMAlevels.level1 = EMAvalues[i - period - 1];
  2596. EMAlevels.level2 = this.getEMA([EMAlevels.level1], prevEMAlevel2, SMA)[1];
  2597. EMAlevel2values.push(EMAlevels.level2);
  2598. prevEMAlevel2 = EMAlevels.level2;
  2599. // Summing first period points for ema(ema(ema))
  2600. if (i < tripledPeriod) {
  2601. accumulatePeriodPoints += EMAlevels.level2;
  2602. }
  2603. else {
  2604. // Calculate tema
  2605. // First tema point
  2606. if (i === tripledPeriod) {
  2607. SMA = accumulatePeriodPoints / period;
  2608. }
  2609. if (i === yValLen + 1) {
  2610. // Calculate the last ema and emaEMA points
  2611. EMAlevels.level1 = EMAvalues[i - period - 1];
  2612. EMAlevels.level2 = this.getEMA([EMAlevels.level1], prevEMAlevel2, SMA)[1];
  2613. EMAlevel2values.push(EMAlevels.level2);
  2614. }
  2615. EMAlevels.level1 = EMAvalues[i - period - 2];
  2616. EMAlevels.level2 = EMAlevel2values[i - 2 * period - 1];
  2617. EMAlevels.level3 = this.getEMA([EMAlevels.level2], EMAlevels.prevLevel3, SMA)[1];
  2618. TEMAPoint = this.getTemaPoint(xVal, tripledPeriod, EMAlevels, i);
  2619. // Make sure that point exists (for TRIX oscillator)
  2620. if (TEMAPoint) {
  2621. TEMA.push(TEMAPoint);
  2622. xDataTema.push(TEMAPoint[0]);
  2623. yDataTema.push(TEMAPoint[1]);
  2624. }
  2625. EMAlevels.prevLevel3 = EMAlevels.level3;
  2626. }
  2627. }
  2628. }
  2629. return {
  2630. values: TEMA,
  2631. xData: xDataTema,
  2632. yData: yDataTema
  2633. };
  2634. }
  2635. });
  2636. /**
  2637. * A `TEMA` series. If the [type](#series.ema.type) option is not
  2638. * specified, it is inherited from [chart.type](#chart.type).
  2639. *
  2640. * @extends series,plotOptions.ema
  2641. * @since 7.0.0
  2642. * @product highstock
  2643. * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
  2644. * joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
  2645. * pointPlacement, pointRange, pointStart, showInNavigator, stacking
  2646. * @requires stock/indicators/indicators
  2647. * @requires stock/indicators/ema
  2648. * @requires stock/indicators/tema
  2649. * @apioption series.tema
  2650. */
  2651. ''; // to include the above in the js output
  2652. });
  2653. _registerModule(_modules, 'Stock/Indicators/TRIXIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Mixins/IndicatorRequired.js']], function (H, U, requiredIndicator) {
  2654. /* *
  2655. *
  2656. * License: www.highcharts.com/license
  2657. *
  2658. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2659. *
  2660. * */
  2661. var correctFloat = U.correctFloat,
  2662. seriesType = U.seriesType;
  2663. var TEMA = H.seriesTypes.tema;
  2664. /**
  2665. * The TRIX series type.
  2666. *
  2667. * @private
  2668. * @class
  2669. * @name Highcharts.seriesTypes.trix
  2670. *
  2671. * @augments Highcharts.Series
  2672. */
  2673. seriesType('trix', 'tema',
  2674. /**
  2675. * Triple exponential average (TRIX) oscillator. This series requires
  2676. * `linkedTo` option to be set.
  2677. *
  2678. * Requires https://code.highcharts.com/stock/indicators/ema.js
  2679. * and https://code.highcharts.com/stock/indicators/tema.js.
  2680. *
  2681. * @sample {highstock} stock/indicators/trix
  2682. * TRIX indicator
  2683. *
  2684. * @extends plotOptions.tema
  2685. * @since 7.0.0
  2686. * @product highstock
  2687. * @excluding allAreas, colorAxis, compare, compareBase, joinBy, keys,
  2688. * navigatorOptions, pointInterval, pointIntervalUnit,
  2689. * pointPlacement, pointRange, pointStart, showInNavigator,
  2690. * stacking
  2691. * @optionparent plotOptions.trix
  2692. */
  2693. {},
  2694. /**
  2695. * @lends Highcharts.Series#
  2696. */
  2697. {
  2698. init: function () {
  2699. var args = arguments,
  2700. ctx = this;
  2701. requiredIndicator.isParentLoaded(TEMA, 'tema', ctx.type, function (indicator) {
  2702. indicator.prototype.init.apply(ctx, args);
  2703. return;
  2704. });
  2705. },
  2706. // TRIX is calculated using TEMA so we just extend getTemaPoint method.
  2707. getTemaPoint: function (xVal, tripledPeriod, EMAlevels, i) {
  2708. if (i > tripledPeriod) {
  2709. var TRIXPoint = [
  2710. xVal[i - 3],
  2711. EMAlevels.prevLevel3 !== 0 ?
  2712. correctFloat(EMAlevels.level3 - EMAlevels.prevLevel3) /
  2713. EMAlevels.prevLevel3 * 100 : null
  2714. ];
  2715. }
  2716. return TRIXPoint;
  2717. }
  2718. });
  2719. /**
  2720. * A `TRIX` series. If the [type](#series.tema.type) option is not specified, it
  2721. * is inherited from [chart.type](#chart.type).
  2722. *
  2723. * @extends series,plotOptions.tema
  2724. * @since 7.0.0
  2725. * @product highstock
  2726. * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
  2727. * joinBy, keys, navigatorOptions, pointInterval, pointIntervalUnit,
  2728. * pointPlacement, pointRange, pointStart, showInNavigator, stacking
  2729. * @apioption series.trix
  2730. */
  2731. ''; // to include the above in the js output
  2732. });
  2733. _registerModule(_modules, 'Stock/Indicators/APOIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Mixins/IndicatorRequired.js']], function (H, U, requiredIndicator) {
  2734. /* *
  2735. *
  2736. * License: www.highcharts.com/license
  2737. *
  2738. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2739. *
  2740. * */
  2741. var error = U.error,
  2742. seriesType = U.seriesType;
  2743. var EMA = H.seriesTypes.ema;
  2744. /**
  2745. * The APO series type.
  2746. *
  2747. * @private
  2748. * @class
  2749. * @name Highcharts.seriesTypes.apo
  2750. *
  2751. * @augments Highcharts.Series
  2752. */
  2753. seriesType('apo', 'ema',
  2754. /**
  2755. * Absolute Price Oscillator. This series requires the `linkedTo` option to
  2756. * be set and should be loaded after the `stock/indicators/indicators.js`
  2757. * and `stock/indicators/ema.js`.
  2758. *
  2759. * @sample {highstock} stock/indicators/apo
  2760. * Absolute Price Oscillator
  2761. *
  2762. * @extends plotOptions.ema
  2763. * @since 7.0.0
  2764. * @product highstock
  2765. * @excluding allAreas, colorAxis, joinBy, keys, navigatorOptions,
  2766. * pointInterval, pointIntervalUnit, pointPlacement,
  2767. * pointRange, pointStart, showInNavigator, stacking
  2768. * @requires stock/indicators/indicators
  2769. * @requires stock/indicators/ema
  2770. * @requires stock/indicators/apo
  2771. * @optionparent plotOptions.apo
  2772. */
  2773. {
  2774. /**
  2775. * Paramters used in calculation of Absolute Price Oscillator
  2776. * series points.
  2777. *
  2778. * @excluding period
  2779. */
  2780. params: {
  2781. /**
  2782. * Periods for Absolute Price Oscillator calculations.
  2783. *
  2784. * @type {Array<number>}
  2785. * @default [10, 20]
  2786. * @since 7.0.0
  2787. */
  2788. periods: [10, 20]
  2789. }
  2790. },
  2791. /**
  2792. * @lends Highcharts.Series.prototype
  2793. */
  2794. {
  2795. nameBase: 'APO',
  2796. nameComponents: ['periods'],
  2797. init: function () {
  2798. var args = arguments,
  2799. ctx = this;
  2800. requiredIndicator.isParentLoaded(EMA, 'ema', ctx.type, function (indicator) {
  2801. indicator.prototype.init.apply(ctx, args);
  2802. return;
  2803. });
  2804. },
  2805. getValues: function (series, params) {
  2806. var periods = params.periods,
  2807. index = params.index,
  2808. // 0- date, 1- Absolute price oscillator
  2809. APO = [],
  2810. xData = [],
  2811. yData = [],
  2812. periodsOffset,
  2813. // Shorter Period EMA
  2814. SPE,
  2815. // Longer Period EMA
  2816. LPE,
  2817. oscillator,
  2818. i;
  2819. // Check if periods are correct
  2820. if (periods.length !== 2 || periods[1] <= periods[0]) {
  2821. error('Error: "APO requires two periods. Notice, first period ' +
  2822. 'should be lower than the second one."');
  2823. return;
  2824. }
  2825. SPE = EMA.prototype.getValues.call(this, series, {
  2826. index: index,
  2827. period: periods[0]
  2828. });
  2829. LPE = EMA.prototype.getValues.call(this, series, {
  2830. index: index,
  2831. period: periods[1]
  2832. });
  2833. // Check if ema is calculated properly, if not skip
  2834. if (!SPE || !LPE) {
  2835. return;
  2836. }
  2837. periodsOffset = periods[1] - periods[0];
  2838. for (i = 0; i < LPE.yData.length; i++) {
  2839. oscillator = (SPE.yData[i + periodsOffset] -
  2840. LPE.yData[i]);
  2841. APO.push([LPE.xData[i], oscillator]);
  2842. xData.push(LPE.xData[i]);
  2843. yData.push(oscillator);
  2844. }
  2845. return {
  2846. values: APO,
  2847. xData: xData,
  2848. yData: yData
  2849. };
  2850. }
  2851. });
  2852. /**
  2853. * An `Absolute Price Oscillator` series. If the [type](#series.apo.type) option
  2854. * is not specified, it is inherited from [chart.type](#chart.type).
  2855. *
  2856. * @extends series,plotOptions.apo
  2857. * @since 7.0.0
  2858. * @product highstock
  2859. * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
  2860. * navigatorOptions, pointInterval, pointIntervalUnit,
  2861. * pointPlacement, pointRange, pointStart, showInNavigator, stacking
  2862. * @requires stock/indicators/indicators
  2863. * @requires stock/indicators/ema
  2864. * @requires stock/indicators/apo
  2865. * @apioption series.apo
  2866. */
  2867. ''; // to include the above in the js output
  2868. });
  2869. _registerModule(_modules, 'Stock/Indicators/IKHIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Color.js'], _modules['Core/Utilities.js']], function (H, Color, U) {
  2870. /* *
  2871. *
  2872. * License: www.highcharts.com/license
  2873. *
  2874. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  2875. *
  2876. * */
  2877. /* eslint-enable @typescript-eslint/interface-name-prefix */
  2878. var color = Color.parse;
  2879. var defined = U.defined,
  2880. isArray = U.isArray,
  2881. merge = U.merge,
  2882. objectEach = U.objectEach,
  2883. seriesType = U.seriesType;
  2884. var UNDEFINED,
  2885. SMA = H.seriesTypes.sma;
  2886. /* eslint-disable require-jsdoc */
  2887. // Utils:
  2888. function maxHigh(arr) {
  2889. return arr.reduce(function (max, res) {
  2890. return Math.max(max, res[1]);
  2891. }, -Infinity);
  2892. }
  2893. function minLow(arr) {
  2894. return arr.reduce(function (min, res) {
  2895. return Math.min(min, res[2]);
  2896. }, Infinity);
  2897. }
  2898. function highlowLevel(arr) {
  2899. return {
  2900. high: maxHigh(arr),
  2901. low: minLow(arr)
  2902. };
  2903. }
  2904. function getClosestPointRange(axis) {
  2905. var closestDataRange,
  2906. loopLength,
  2907. distance,
  2908. xData,
  2909. i;
  2910. axis.series.forEach(function (series) {
  2911. if (series.xData) {
  2912. xData = series.xData;
  2913. loopLength = series.xIncrement ? 1 : xData.length - 1;
  2914. for (i = loopLength; i > 0; i--) {
  2915. distance = xData[i] - xData[i - 1];
  2916. if (closestDataRange === UNDEFINED ||
  2917. distance < closestDataRange) {
  2918. closestDataRange = distance;
  2919. }
  2920. }
  2921. }
  2922. });
  2923. return closestDataRange;
  2924. }
  2925. // Check two lines intersection (line a1-a2 and b1-b2)
  2926. // Source: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
  2927. function checkLineIntersection(a1, a2, b1, b2) {
  2928. if (a1 && a2 && b1 && b2) {
  2929. var saX = a2.plotX - a1.plotX, // Auxiliary section a2-a1 X
  2930. saY = a2.plotY - a1.plotY, // Auxiliary section a2-a1 Y
  2931. sbX = b2.plotX - b1.plotX, // Auxiliary section b2-b1 X
  2932. sbY = b2.plotY - b1.plotY, // Auxiliary section b2-b1 Y
  2933. sabX = a1.plotX - b1.plotX, // Auxiliary section a1-b1 X
  2934. sabY = a1.plotY - b1.plotY, // Auxiliary section a1-b1 Y
  2935. // First degree Bézier parameters
  2936. u,
  2937. t;
  2938. u = (-saY * sabX + saX * sabY) / (-sbX * saY + saX * sbY);
  2939. t = (sbX * sabY - sbY * sabX) / (-sbX * saY + saX * sbY);
  2940. if (u >= 0 && u <= 1 && t >= 0 && t <= 1) {
  2941. return {
  2942. plotX: a1.plotX + (t * saX),
  2943. plotY: a1.plotY + (t * saY)
  2944. };
  2945. }
  2946. }
  2947. return false;
  2948. }
  2949. // Parameter opt (indicator options object) include indicator, points,
  2950. // nextPoints, color, options, gappedExtend and graph properties
  2951. function drawSenkouSpan(opt) {
  2952. var indicator = opt.indicator;
  2953. indicator.points = opt.points;
  2954. indicator.nextPoints = opt.nextPoints;
  2955. indicator.color = opt.color;
  2956. indicator.options = merge(opt.options.senkouSpan.styles, opt.gap);
  2957. indicator.graph = opt.graph;
  2958. indicator.fillGraph = true;
  2959. SMA.prototype.drawGraph.call(indicator);
  2960. }
  2961. // Data integrity in Ichimoku is different than default "averages":
  2962. // Point: [undefined, value, value, ...] is correct
  2963. // Point: [undefined, undefined, undefined, ...] is incorrect
  2964. H.approximations['ichimoku-averages'] = function () {
  2965. var ret = [],
  2966. isEmptyRange;
  2967. [].forEach.call(arguments, function (arr, i) {
  2968. ret.push(H.approximations.average(arr));
  2969. isEmptyRange = !isEmptyRange && typeof ret[i] === 'undefined';
  2970. });
  2971. // Return undefined when first elem. is undefined and let
  2972. // sum method handle null (#7377)
  2973. return isEmptyRange ? void 0 : ret;
  2974. };
  2975. /* eslint-enable require-jsdoc */
  2976. /**
  2977. * The IKH series type.
  2978. *
  2979. * @private
  2980. * @class
  2981. * @name Highcharts.seriesTypes.ikh
  2982. *
  2983. * @augments Highcharts.Series
  2984. */
  2985. seriesType('ikh', 'sma',
  2986. /**
  2987. * Ichimoku Kinko Hyo (IKH). This series requires `linkedTo` option to be
  2988. * set.
  2989. *
  2990. * @sample stock/indicators/ichimoku-kinko-hyo
  2991. * Ichimoku Kinko Hyo indicator
  2992. *
  2993. * @extends plotOptions.sma
  2994. * @since 6.0.0
  2995. * @excluding allAreas, colorAxis, compare, compareBase, joinBy, keys,
  2996. * navigatorOptions, pointInterval, pointIntervalUnit,
  2997. * pointPlacement, pointRange, pointStart, showInNavigator,
  2998. * stacking
  2999. * @product highstock
  3000. * @requires stock/indicators/indicators
  3001. * @requires stock/indicators/ichimoku-kinko-hyo
  3002. * @optionparent plotOptions.ikh
  3003. */
  3004. {
  3005. params: {
  3006. period: 26,
  3007. /**
  3008. * The base period for Tenkan calculations.
  3009. */
  3010. periodTenkan: 9,
  3011. /**
  3012. * The base period for Senkou Span B calculations
  3013. */
  3014. periodSenkouSpanB: 52
  3015. },
  3016. marker: {
  3017. enabled: false
  3018. },
  3019. tooltip: {
  3020. pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> {series.name}</b><br/>' +
  3021. 'TENKAN SEN: {point.tenkanSen:.3f}<br/>' +
  3022. 'KIJUN SEN: {point.kijunSen:.3f}<br/>' +
  3023. 'CHIKOU SPAN: {point.chikouSpan:.3f}<br/>' +
  3024. 'SENKOU SPAN A: {point.senkouSpanA:.3f}<br/>' +
  3025. 'SENKOU SPAN B: {point.senkouSpanB:.3f}<br/>'
  3026. },
  3027. /**
  3028. * The styles for Tenkan line
  3029. */
  3030. tenkanLine: {
  3031. styles: {
  3032. /**
  3033. * Pixel width of the line.
  3034. */
  3035. lineWidth: 1,
  3036. /**
  3037. * Color of the line.
  3038. *
  3039. * @type {Highcharts.ColorString}
  3040. */
  3041. lineColor: void 0
  3042. }
  3043. },
  3044. /**
  3045. * The styles for Kijun line
  3046. */
  3047. kijunLine: {
  3048. styles: {
  3049. /**
  3050. * Pixel width of the line.
  3051. */
  3052. lineWidth: 1,
  3053. /**
  3054. * Color of the line.
  3055. *
  3056. * @type {Highcharts.ColorString}
  3057. */
  3058. lineColor: void 0
  3059. }
  3060. },
  3061. /**
  3062. * The styles for Chikou line
  3063. */
  3064. chikouLine: {
  3065. styles: {
  3066. /**
  3067. * Pixel width of the line.
  3068. */
  3069. lineWidth: 1,
  3070. /**
  3071. * Color of the line.
  3072. *
  3073. * @type {Highcharts.ColorString}
  3074. */
  3075. lineColor: void 0
  3076. }
  3077. },
  3078. /**
  3079. * The styles for Senkou Span A line
  3080. */
  3081. senkouSpanA: {
  3082. styles: {
  3083. /**
  3084. * Pixel width of the line.
  3085. */
  3086. lineWidth: 1,
  3087. /**
  3088. * Color of the line.
  3089. *
  3090. * @type {Highcharts.ColorString}
  3091. */
  3092. lineColor: void 0
  3093. }
  3094. },
  3095. /**
  3096. * The styles for Senkou Span B line
  3097. */
  3098. senkouSpanB: {
  3099. styles: {
  3100. /**
  3101. * Pixel width of the line.
  3102. */
  3103. lineWidth: 1,
  3104. /**
  3105. * Color of the line.
  3106. *
  3107. * @type {Highcharts.ColorString}
  3108. */
  3109. lineColor: void 0
  3110. }
  3111. },
  3112. /**
  3113. * The styles for area between Senkou Span A and B.
  3114. */
  3115. senkouSpan: {
  3116. /**
  3117. * Color of the area between Senkou Span A and B,
  3118. * when Senkou Span A is above Senkou Span B. Note that if
  3119. * a `style.fill` is defined, the `color` takes precedence and
  3120. * the `style.fill` is ignored.
  3121. *
  3122. * @see [senkouSpan.styles.fill](#series.ikh.senkouSpan.styles.fill)
  3123. *
  3124. * @sample stock/indicators/ichimoku-kinko-hyo
  3125. * Ichimoku Kinko Hyo color
  3126. *
  3127. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  3128. * @since 7.0.0
  3129. * @apioption plotOptions.ikh.senkouSpan.color
  3130. */
  3131. /**
  3132. * Color of the area between Senkou Span A and B,
  3133. * when Senkou Span A is under Senkou Span B.
  3134. *
  3135. * @sample stock/indicators/ikh-negative-color
  3136. * Ichimoku Kinko Hyo negativeColor
  3137. *
  3138. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  3139. * @since 7.0.0
  3140. * @apioption plotOptions.ikh.senkouSpan.negativeColor
  3141. */
  3142. styles: {
  3143. /**
  3144. * Color of the area between Senkou Span A and B.
  3145. *
  3146. * @deprecated
  3147. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  3148. */
  3149. fill: 'rgba(255, 0, 0, 0.5)'
  3150. }
  3151. },
  3152. dataGrouping: {
  3153. approximation: 'ichimoku-averages'
  3154. }
  3155. },
  3156. /**
  3157. * @lends Highcharts.Series#
  3158. */
  3159. {
  3160. pointArrayMap: [
  3161. 'tenkanSen',
  3162. 'kijunSen',
  3163. 'chikouSpan',
  3164. 'senkouSpanA',
  3165. 'senkouSpanB'
  3166. ],
  3167. pointValKey: 'tenkanSen',
  3168. nameComponents: ['periodSenkouSpanB', 'period', 'periodTenkan'],
  3169. init: function () {
  3170. SMA.prototype.init.apply(this, arguments);
  3171. // Set default color for lines:
  3172. this.options = merge({
  3173. tenkanLine: {
  3174. styles: {
  3175. lineColor: this.color
  3176. }
  3177. },
  3178. kijunLine: {
  3179. styles: {
  3180. lineColor: this.color
  3181. }
  3182. },
  3183. chikouLine: {
  3184. styles: {
  3185. lineColor: this.color
  3186. }
  3187. },
  3188. senkouSpanA: {
  3189. styles: {
  3190. lineColor: this.color,
  3191. fill: color(this.color).setOpacity(0.5).get()
  3192. }
  3193. },
  3194. senkouSpanB: {
  3195. styles: {
  3196. lineColor: this.color,
  3197. fill: color(this.color).setOpacity(0.5).get()
  3198. }
  3199. },
  3200. senkouSpan: {
  3201. styles: {
  3202. fill: color(this.color).setOpacity(0.2).get()
  3203. }
  3204. }
  3205. }, this.options);
  3206. },
  3207. toYData: function (point) {
  3208. return [
  3209. point.tenkanSen,
  3210. point.kijunSen,
  3211. point.chikouSpan,
  3212. point.senkouSpanA,
  3213. point.senkouSpanB
  3214. ];
  3215. },
  3216. translate: function () {
  3217. var indicator = this;
  3218. SMA.prototype.translate.apply(indicator);
  3219. indicator.points.forEach(function (point) {
  3220. indicator.pointArrayMap.forEach(function (value) {
  3221. if (defined(point[value])) {
  3222. point['plot' + value] =
  3223. indicator.yAxis.toPixels(point[value], true);
  3224. // Add extra parameters for support tooltip in moved
  3225. // lines
  3226. point.plotY = point['plot' + value];
  3227. point.tooltipPos = [
  3228. point.plotX,
  3229. point['plot' + value]
  3230. ];
  3231. point.isNull = false;
  3232. }
  3233. });
  3234. });
  3235. },
  3236. // One does not simply
  3237. // Render five linesZ
  3238. // And an arearange
  3239. // In just one series..
  3240. drawGraph: function () {
  3241. var indicator = this,
  3242. mainLinePoints = (indicator.points),
  3243. pointsLength = mainLinePoints.length,
  3244. mainLineOptions = (indicator.options),
  3245. mainLinePath = (indicator.graph),
  3246. mainColor = indicator.color,
  3247. gappedExtend = {
  3248. options: {
  3249. gapSize: mainLineOptions.gapSize
  3250. }
  3251. },
  3252. pointArrayMapLength = indicator.pointArrayMap.length,
  3253. allIchimokuPoints = [[],
  3254. [],
  3255. [],
  3256. [],
  3257. [],
  3258. []],
  3259. ikhMap = {
  3260. tenkanLine: allIchimokuPoints[0],
  3261. kijunLine: allIchimokuPoints[1],
  3262. chikouLine: allIchimokuPoints[2],
  3263. senkouSpanA: allIchimokuPoints[3],
  3264. senkouSpanB: allIchimokuPoints[4],
  3265. senkouSpan: allIchimokuPoints[5]
  3266. },
  3267. intersectIndexColl = [],
  3268. senkouSpanOptions = indicator.options.senkouSpan,
  3269. color = (senkouSpanOptions.color ||
  3270. senkouSpanOptions.styles.fill),
  3271. negativeColor = (senkouSpanOptions.negativeColor),
  3272. // Points to create color and negativeColor senkouSpan
  3273. points = [
  3274. [],
  3275. [] // Points negative color
  3276. ],
  3277. // For span, we need an access to the next points, used in
  3278. // getGraphPath()
  3279. nextPoints = [
  3280. [],
  3281. [] // NextPoints negative color
  3282. ],
  3283. lineIndex = 0,
  3284. position,
  3285. point,
  3286. i,
  3287. startIntersect,
  3288. endIntersect,
  3289. sectionPoints,
  3290. sectionNextPoints,
  3291. pointsPlotYSum,
  3292. nextPointsPlotYSum,
  3293. senkouSpanTempColor,
  3294. concatArrIndex,
  3295. j,
  3296. k;
  3297. indicator.ikhMap = ikhMap;
  3298. // Generate points for all lines and spans lines:
  3299. while (pointsLength--) {
  3300. point = mainLinePoints[pointsLength];
  3301. for (i = 0; i < pointArrayMapLength; i++) {
  3302. position = indicator.pointArrayMap[i];
  3303. if (defined(point[position])) {
  3304. allIchimokuPoints[i].push({
  3305. plotX: point.plotX,
  3306. plotY: point['plot' + position],
  3307. isNull: false
  3308. });
  3309. }
  3310. }
  3311. if (negativeColor &&
  3312. pointsLength !== mainLinePoints.length - 1) {
  3313. // Check if lines intersect
  3314. var index = ikhMap.senkouSpanB.length - 1,
  3315. intersect = checkLineIntersection(ikhMap.senkouSpanA[index - 1],
  3316. ikhMap.senkouSpanA[index],
  3317. ikhMap.senkouSpanB[index - 1],
  3318. ikhMap.senkouSpanB[index]),
  3319. intersectPointObj = {
  3320. plotX: intersect.plotX,
  3321. plotY: intersect.plotY,
  3322. isNull: false,
  3323. intersectPoint: true
  3324. };
  3325. if (intersect) {
  3326. // Add intersect point to ichimoku points collection
  3327. // Create senkouSpan sections
  3328. ikhMap.senkouSpanA.splice(index, 0, intersectPointObj);
  3329. ikhMap.senkouSpanB.splice(index, 0, intersectPointObj);
  3330. intersectIndexColl.push(index);
  3331. }
  3332. }
  3333. }
  3334. // Modify options and generate lines:
  3335. objectEach(ikhMap, function (values, lineName) {
  3336. if (mainLineOptions[lineName] &&
  3337. lineName !== 'senkouSpan') {
  3338. // First line is rendered by default option
  3339. indicator.points = allIchimokuPoints[lineIndex];
  3340. indicator.options = merge(mainLineOptions[lineName].styles, gappedExtend);
  3341. indicator.graph = indicator['graph' + lineName];
  3342. indicator.fillGraph = false;
  3343. indicator.color = mainColor;
  3344. SMA.prototype.drawGraph.call(indicator);
  3345. // Now save line
  3346. indicator['graph' + lineName] = indicator.graph;
  3347. }
  3348. lineIndex++;
  3349. });
  3350. // Generate senkouSpan area:
  3351. // If graphColection exist then remove svg
  3352. // element and indicator property
  3353. if (indicator.graphCollection) {
  3354. indicator.graphCollection.forEach(function (graphName) {
  3355. indicator[graphName].destroy();
  3356. delete indicator[graphName];
  3357. });
  3358. }
  3359. // Clean grapCollection or initialize it
  3360. indicator.graphCollection = [];
  3361. // When user set negativeColor property
  3362. if (negativeColor &&
  3363. ikhMap.senkouSpanA[0] &&
  3364. ikhMap.senkouSpanB[0]) {
  3365. // Add first and last point to senkouSpan area sections
  3366. intersectIndexColl.unshift(0);
  3367. intersectIndexColl.push(ikhMap.senkouSpanA.length - 1);
  3368. // Populate points and nextPoints arrays
  3369. for (j = 0; j < intersectIndexColl.length - 1; j++) {
  3370. startIntersect = intersectIndexColl[j];
  3371. endIntersect = intersectIndexColl[j + 1];
  3372. sectionPoints = ikhMap.senkouSpanB.slice(startIntersect, endIntersect + 1);
  3373. sectionNextPoints = ikhMap.senkouSpanA.slice(startIntersect, endIntersect + 1);
  3374. // Add points to color or negativeColor arrays
  3375. // Check the middle point (if exist)
  3376. if (Math.floor(sectionPoints.length / 2) >= 1) {
  3377. var x = Math.floor(sectionPoints.length / 2);
  3378. // When middle points has equal values
  3379. // Compare all ponints plotY value sum
  3380. if (sectionPoints[x].plotY ===
  3381. sectionNextPoints[x].plotY) {
  3382. pointsPlotYSum = 0;
  3383. nextPointsPlotYSum = 0;
  3384. for (k = 0; k < sectionPoints.length; k++) {
  3385. pointsPlotYSum +=
  3386. sectionPoints[k].plotY;
  3387. nextPointsPlotYSum +=
  3388. sectionNextPoints[k].plotY;
  3389. }
  3390. concatArrIndex = (pointsPlotYSum > nextPointsPlotYSum ? 0 : 1);
  3391. points[concatArrIndex] = (points[concatArrIndex].concat(sectionPoints));
  3392. nextPoints[concatArrIndex] = (nextPoints[concatArrIndex].concat(sectionNextPoints));
  3393. }
  3394. else {
  3395. // Compare middle point of the section
  3396. concatArrIndex = (sectionPoints[x].plotY >
  3397. sectionNextPoints[x].plotY ?
  3398. 0 : 1);
  3399. points[concatArrIndex] = (points[concatArrIndex].concat(sectionPoints));
  3400. nextPoints[concatArrIndex] = (nextPoints[concatArrIndex].concat(sectionNextPoints));
  3401. }
  3402. }
  3403. else {
  3404. // Compare first point of the section
  3405. concatArrIndex = (sectionPoints[0].plotY >
  3406. sectionNextPoints[0].plotY ?
  3407. 0 : 1);
  3408. points[concatArrIndex] = (points[concatArrIndex].concat(sectionPoints));
  3409. nextPoints[concatArrIndex] = (nextPoints[concatArrIndex].concat(sectionNextPoints));
  3410. }
  3411. }
  3412. // Render color and negativeColor paths
  3413. [
  3414. 'graphsenkouSpanColor', 'graphsenkouSpanNegativeColor'
  3415. ].forEach(function (areaName, i) {
  3416. if (points[i].length && nextPoints[i].length) {
  3417. senkouSpanTempColor = (i === 0) ?
  3418. color : negativeColor;
  3419. drawSenkouSpan({
  3420. indicator: indicator,
  3421. points: points[i],
  3422. nextPoints: nextPoints[i],
  3423. color: senkouSpanTempColor,
  3424. options: mainLineOptions,
  3425. gap: gappedExtend,
  3426. graph: indicator[areaName]
  3427. });
  3428. // Now save line
  3429. indicator[areaName] = indicator.graph;
  3430. indicator.graphCollection.push(areaName);
  3431. }
  3432. });
  3433. }
  3434. else {
  3435. // When user set only senkouSpan style.fill property
  3436. drawSenkouSpan({
  3437. indicator: indicator,
  3438. points: ikhMap.senkouSpanB,
  3439. nextPoints: ikhMap.senkouSpanA,
  3440. color: color,
  3441. options: mainLineOptions,
  3442. gap: gappedExtend,
  3443. graph: indicator.graphsenkouSpan
  3444. });
  3445. // Now save line
  3446. indicator.graphsenkouSpan = indicator.graph;
  3447. }
  3448. // Clean temporary properties:
  3449. delete indicator.nextPoints;
  3450. delete indicator.fillGraph;
  3451. // Restore options and draw the Tenkan line:
  3452. indicator.points = mainLinePoints;
  3453. indicator.options = mainLineOptions;
  3454. indicator.graph = mainLinePath;
  3455. },
  3456. getGraphPath: function (points) {
  3457. var indicator = this,
  3458. path = [],
  3459. spanA,
  3460. spanAarr = [];
  3461. points = points || this.points;
  3462. // Render Senkou Span
  3463. if (indicator.fillGraph && indicator.nextPoints) {
  3464. spanA = SMA.prototype.getGraphPath.call(indicator,
  3465. // Reverse points, so Senkou Span A will start from the end:
  3466. indicator.nextPoints);
  3467. spanA[0][0] = 'L';
  3468. path = SMA.prototype.getGraphPath.call(indicator, points);
  3469. spanAarr = spanA.slice(0, path.length);
  3470. for (var i = spanAarr.length - 1; i >= 0; i--) {
  3471. path.push(spanAarr[i]);
  3472. }
  3473. }
  3474. else {
  3475. path = SMA.prototype.getGraphPath.apply(indicator, arguments);
  3476. }
  3477. return path;
  3478. },
  3479. getValues: function (series, params) {
  3480. var period = params.period,
  3481. periodTenkan = params.periodTenkan,
  3482. periodSenkouSpanB = params.periodSenkouSpanB,
  3483. xVal = series.xData,
  3484. yVal = series.yData,
  3485. xAxis = series.xAxis,
  3486. yValLen = (yVal && yVal.length) || 0,
  3487. closestPointRange = getClosestPointRange(xAxis),
  3488. IKH = [],
  3489. xData = [],
  3490. dateStart,
  3491. date,
  3492. slicedTSY,
  3493. slicedKSY,
  3494. slicedSSBY,
  3495. pointTS,
  3496. pointKS,
  3497. pointSSB,
  3498. i,
  3499. TS,
  3500. KS,
  3501. CS,
  3502. SSA,
  3503. SSB;
  3504. // Ikh requires close value
  3505. if (xVal.length <= period ||
  3506. !isArray(yVal[0]) ||
  3507. yVal[0].length !== 4) {
  3508. return;
  3509. }
  3510. // Add timestamps at the beginning
  3511. dateStart = xVal[0] - (period * closestPointRange);
  3512. for (i = 0; i < period; i++) {
  3513. xData.push(dateStart + i * closestPointRange);
  3514. }
  3515. for (i = 0; i < yValLen; i++) {
  3516. // Tenkan Sen
  3517. if (i >= periodTenkan) {
  3518. slicedTSY = yVal.slice(i - periodTenkan, i);
  3519. pointTS = highlowLevel(slicedTSY);
  3520. TS = (pointTS.high + pointTS.low) / 2;
  3521. }
  3522. if (i >= period) {
  3523. slicedKSY = yVal.slice(i - period, i);
  3524. pointKS = highlowLevel(slicedKSY);
  3525. KS = (pointKS.high + pointKS.low) / 2;
  3526. SSA = (TS + KS) / 2;
  3527. }
  3528. if (i >= periodSenkouSpanB) {
  3529. slicedSSBY = yVal.slice(i - periodSenkouSpanB, i);
  3530. pointSSB = highlowLevel(slicedSSBY);
  3531. SSB = (pointSSB.high + pointSSB.low) / 2;
  3532. }
  3533. CS = yVal[i][3];
  3534. date = xVal[i];
  3535. if (IKH[i] === UNDEFINED) {
  3536. IKH[i] = [];
  3537. }
  3538. if (IKH[i + period] === UNDEFINED) {
  3539. IKH[i + period] = [];
  3540. }
  3541. IKH[i + period][0] = TS;
  3542. IKH[i + period][1] = KS;
  3543. IKH[i + period][2] = UNDEFINED;
  3544. IKH[i][2] = CS;
  3545. if (i <= period) {
  3546. IKH[i + period][3] = UNDEFINED;
  3547. IKH[i + period][4] = UNDEFINED;
  3548. }
  3549. if (IKH[i + 2 * period] === UNDEFINED) {
  3550. IKH[i + 2 * period] = [];
  3551. }
  3552. IKH[i + 2 * period][3] = SSA;
  3553. IKH[i + 2 * period][4] = SSB;
  3554. xData.push(date);
  3555. }
  3556. // Add timestamps for further points
  3557. for (i = 1; i <= period; i++) {
  3558. xData.push(date + i * closestPointRange);
  3559. }
  3560. return {
  3561. values: IKH,
  3562. xData: xData,
  3563. yData: IKH
  3564. };
  3565. }
  3566. });
  3567. /**
  3568. * A `IKH` series. If the [type](#series.ikh.type) option is not
  3569. * specified, it is inherited from [chart.type](#chart.type).
  3570. *
  3571. * @extends series,plotOptions.ikh
  3572. * @since 6.0.0
  3573. * @product highstock
  3574. * @excluding dataParser, dataURL
  3575. * @requires stock/indicators/indicators
  3576. * @requires stock/indicators/ichimoku-kinko-hyo
  3577. * @apioption series.ikh
  3578. */
  3579. ''; // add doclet above to transpiled file
  3580. });
  3581. _registerModule(_modules, 'Stock/Indicators/KeltnerChannelsIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Mixins/MultipleLines.js']], function (H, U, multipleLinesMixin) {
  3582. /* *
  3583. *
  3584. * License: www.highcharts.com/license
  3585. *
  3586. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  3587. *
  3588. * */
  3589. var correctFloat = U.correctFloat,
  3590. merge = U.merge,
  3591. seriesType = U.seriesType;
  3592. var SMA = H.seriesTypes.sma,
  3593. EMA = H.seriesTypes.ema,
  3594. ATR = H.seriesTypes.atr;
  3595. /**
  3596. * The Keltner Channels series type.
  3597. *
  3598. * @private
  3599. * @class
  3600. * @name Highcharts.seriesTypes.keltnerchannels
  3601. *
  3602. * @augments Highcharts.Series
  3603. */
  3604. seriesType('keltnerchannels', 'sma',
  3605. /**
  3606. * Keltner Channels. This series requires the `linkedTo` option to be set
  3607. * and should be loaded after the `stock/indicators/indicators.js`,
  3608. * `stock/indicators/atr.js`, and `stock/ema/.js`.
  3609. *
  3610. * @sample {highstock} stock/indicators/keltner-channels
  3611. * Keltner Channels
  3612. *
  3613. * @extends plotOptions.sma
  3614. * @since 7.0.0
  3615. * @product highstock
  3616. * @excluding allAreas, colorAxis, compare, compareBase, joinBy, keys,
  3617. * navigatorOptions, pointInterval, pointIntervalUnit,
  3618. * pointPlacement, pointRange, pointStart,showInNavigator,
  3619. * stacking
  3620. * @requires stock/indicators/indicators
  3621. * @requires stock/indicators/keltner-channels
  3622. * @optionparent plotOptions.keltnerchannels
  3623. */
  3624. {
  3625. params: {
  3626. period: 20,
  3627. /**
  3628. * The ATR period.
  3629. */
  3630. periodATR: 10,
  3631. /**
  3632. * The ATR multiplier.
  3633. */
  3634. multiplierATR: 2
  3635. },
  3636. /**
  3637. * Bottom line options.
  3638. *
  3639. */
  3640. bottomLine: {
  3641. /**
  3642. * Styles for a bottom line.
  3643. *
  3644. */
  3645. styles: {
  3646. /**
  3647. * Pixel width of the line.
  3648. */
  3649. lineWidth: 1,
  3650. /**
  3651. * Color of the line. If not set, it's inherited from
  3652. * `plotOptions.keltnerchannels.color`
  3653. */
  3654. lineColor: void 0
  3655. }
  3656. },
  3657. /**
  3658. * Top line options.
  3659. *
  3660. * @extends plotOptions.keltnerchannels.bottomLine
  3661. */
  3662. topLine: {
  3663. styles: {
  3664. lineWidth: 1,
  3665. lineColor: void 0
  3666. }
  3667. },
  3668. tooltip: {
  3669. pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>Upper Channel: {point.top}<br/>EMA({series.options.params.period}): {point.middle}<br/>Lower Channel: {point.bottom}<br/>'
  3670. },
  3671. marker: {
  3672. enabled: false
  3673. },
  3674. dataGrouping: {
  3675. approximation: 'averages'
  3676. },
  3677. lineWidth: 1
  3678. },
  3679. /**
  3680. * @lends Highcharts.Series#
  3681. */
  3682. merge(multipleLinesMixin, {
  3683. pointArrayMap: ['top', 'middle', 'bottom'],
  3684. pointValKey: 'middle',
  3685. nameBase: 'Keltner Channels',
  3686. nameComponents: ['period', 'periodATR', 'multiplierATR'],
  3687. linesApiNames: ['topLine', 'bottomLine'],
  3688. requiredIndicators: ['ema', 'atr'],
  3689. init: function () {
  3690. SMA.prototype.init.apply(this, arguments);
  3691. // Set default color for lines:
  3692. this.options = merge({
  3693. topLine: {
  3694. styles: {
  3695. lineColor: this.color
  3696. }
  3697. },
  3698. bottomLine: {
  3699. styles: {
  3700. lineColor: this.color
  3701. }
  3702. }
  3703. }, this.options);
  3704. },
  3705. getValues: function (series, params) {
  3706. var period = params.period,
  3707. periodATR = params.periodATR,
  3708. multiplierATR = params.multiplierATR,
  3709. index = params.index,
  3710. yVal = series.yData,
  3711. yValLen = yVal ? yVal.length : 0,
  3712. // Keltner Channels array structure:
  3713. // 0-date, 1-top line, 2-middle line, 3-bottom line
  3714. KC = [],
  3715. // middle line, top line and bottom lineI
  3716. ML,
  3717. TL,
  3718. BL,
  3719. date,
  3720. seriesEMA = EMA.prototype.getValues(series, {
  3721. period: period,
  3722. index: index
  3723. }),
  3724. seriesATR = ATR.prototype.getValues(series, {
  3725. period: periodATR
  3726. }),
  3727. pointEMA,
  3728. pointATR,
  3729. xData = [],
  3730. yData = [],
  3731. i;
  3732. if (yValLen < period) {
  3733. return;
  3734. }
  3735. for (i = period; i <= yValLen; i++) {
  3736. pointEMA = seriesEMA.values[i - period];
  3737. pointATR = seriesATR.values[i - periodATR];
  3738. date = pointEMA[0];
  3739. TL = correctFloat(pointEMA[1] + (multiplierATR * pointATR[1]));
  3740. BL = correctFloat(pointEMA[1] - (multiplierATR * pointATR[1]));
  3741. ML = pointEMA[1];
  3742. KC.push([date, TL, ML, BL]);
  3743. xData.push(date);
  3744. yData.push([TL, ML, BL]);
  3745. }
  3746. return {
  3747. values: KC,
  3748. xData: xData,
  3749. yData: yData
  3750. };
  3751. }
  3752. }));
  3753. /**
  3754. * A Keltner Channels indicator. If the [type](#series.keltnerchannels.type)
  3755. * option is not specified, it is inherited from[chart.type](#chart.type).
  3756. *
  3757. * @extends series,plotOptions.keltnerchannels
  3758. * @since 7.0.0
  3759. * @product highstock
  3760. * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
  3761. * joinBy, keys, navigatorOptions, pointInterval,
  3762. * pointIntervalUnit, pointPlacement, pointRange, pointStart,
  3763. * stacking, showInNavigator
  3764. * @requires stock/indicators/indicators
  3765. * @requires stock/indicators/keltner-channels
  3766. * @apioption series.keltnerchannels
  3767. */
  3768. ''; // to include the above in the js output
  3769. });
  3770. _registerModule(_modules, 'Stock/Indicators/MACDIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
  3771. /* *
  3772. *
  3773. * License: www.highcharts.com/license
  3774. *
  3775. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  3776. *
  3777. * */
  3778. var correctFloat = U.correctFloat,
  3779. defined = U.defined,
  3780. merge = U.merge,
  3781. seriesType = U.seriesType;
  3782. var noop = H.noop,
  3783. SMA = H.seriesTypes.sma,
  3784. EMA = H.seriesTypes.ema;
  3785. /**
  3786. * The MACD series type.
  3787. *
  3788. * @private
  3789. * @class
  3790. * @name Highcharts.seriesTypes.macd
  3791. *
  3792. * @augments Highcharts.Series
  3793. */
  3794. seriesType('macd', 'sma',
  3795. /**
  3796. * Moving Average Convergence Divergence (MACD). This series requires
  3797. * `linkedTo` option to be set and should be loaded after the
  3798. * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
  3799. *
  3800. * @sample stock/indicators/macd
  3801. * MACD indicator
  3802. *
  3803. * @extends plotOptions.sma
  3804. * @since 6.0.0
  3805. * @product highstock
  3806. * @requires stock/indicators/indicators
  3807. * @requires stock/indicators/macd
  3808. * @optionparent plotOptions.macd
  3809. */
  3810. {
  3811. params: {
  3812. /**
  3813. * The short period for indicator calculations.
  3814. */
  3815. shortPeriod: 12,
  3816. /**
  3817. * The long period for indicator calculations.
  3818. */
  3819. longPeriod: 26,
  3820. /**
  3821. * The base period for signal calculations.
  3822. */
  3823. signalPeriod: 9,
  3824. period: 26
  3825. },
  3826. /**
  3827. * The styles for signal line
  3828. */
  3829. signalLine: {
  3830. /**
  3831. * @sample stock/indicators/macd-zones
  3832. * Zones in MACD
  3833. *
  3834. * @extends plotOptions.macd.zones
  3835. */
  3836. zones: [],
  3837. styles: {
  3838. /**
  3839. * Pixel width of the line.
  3840. */
  3841. lineWidth: 1,
  3842. /**
  3843. * Color of the line.
  3844. *
  3845. * @type {Highcharts.ColorString}
  3846. */
  3847. lineColor: void 0
  3848. }
  3849. },
  3850. /**
  3851. * The styles for macd line
  3852. */
  3853. macdLine: {
  3854. /**
  3855. * @sample stock/indicators/macd-zones
  3856. * Zones in MACD
  3857. *
  3858. * @extends plotOptions.macd.zones
  3859. */
  3860. zones: [],
  3861. styles: {
  3862. /**
  3863. * Pixel width of the line.
  3864. */
  3865. lineWidth: 1,
  3866. /**
  3867. * Color of the line.
  3868. *
  3869. * @type {Highcharts.ColorString}
  3870. */
  3871. lineColor: void 0
  3872. }
  3873. },
  3874. threshold: 0,
  3875. groupPadding: 0.1,
  3876. pointPadding: 0.1,
  3877. crisp: false,
  3878. states: {
  3879. hover: {
  3880. halo: {
  3881. size: 0
  3882. }
  3883. }
  3884. },
  3885. tooltip: {
  3886. pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> {series.name}</b><br/>' +
  3887. 'Value: {point.MACD}<br/>' +
  3888. 'Signal: {point.signal}<br/>' +
  3889. 'Histogram: {point.y}<br/>'
  3890. },
  3891. dataGrouping: {
  3892. approximation: 'averages'
  3893. },
  3894. minPointLength: 0
  3895. },
  3896. /**
  3897. * @lends Highcharts.Series#
  3898. */
  3899. {
  3900. nameComponents: ['longPeriod', 'shortPeriod', 'signalPeriod'],
  3901. requiredIndicators: ['ema'],
  3902. // "y" value is treated as Histogram data
  3903. pointArrayMap: ['y', 'signal', 'MACD'],
  3904. parallelArrays: ['x', 'y', 'signal', 'MACD'],
  3905. pointValKey: 'y',
  3906. // Columns support:
  3907. markerAttribs: noop,
  3908. getColumnMetrics: H.seriesTypes.column.prototype.getColumnMetrics,
  3909. crispCol: H.seriesTypes.column.prototype.crispCol,
  3910. // Colors and lines:
  3911. init: function () {
  3912. SMA.prototype.init.apply(this, arguments);
  3913. // Check whether series is initialized. It may be not initialized,
  3914. // when any of required indicators is missing.
  3915. if (this.options) {
  3916. // Set default color for a signal line and the histogram:
  3917. this.options = merge({
  3918. signalLine: {
  3919. styles: {
  3920. lineColor: this.color
  3921. }
  3922. },
  3923. macdLine: {
  3924. styles: {
  3925. color: this.color
  3926. }
  3927. }
  3928. }, this.options);
  3929. // Zones have indexes automatically calculated, we need to
  3930. // translate them to support multiple lines within one indicator
  3931. this.macdZones = {
  3932. zones: this.options.macdLine.zones,
  3933. startIndex: 0
  3934. };
  3935. this.signalZones = {
  3936. zones: this.macdZones.zones.concat(this.options.signalLine.zones),
  3937. startIndex: this.macdZones.zones.length
  3938. };
  3939. this.resetZones = true;
  3940. }
  3941. },
  3942. toYData: function (point) {
  3943. return [point.y, point.signal, point.MACD];
  3944. },
  3945. translate: function () {
  3946. var indicator = this, plotNames = ['plotSignal', 'plotMACD'];
  3947. H.seriesTypes.column.prototype.translate.apply(indicator);
  3948. indicator.points.forEach(function (point) {
  3949. [point.signal, point.MACD].forEach(function (value, i) {
  3950. if (value !== null) {
  3951. point[plotNames[i]] =
  3952. indicator.yAxis.toPixels(value, true);
  3953. }
  3954. });
  3955. });
  3956. },
  3957. destroy: function () {
  3958. // this.graph is null due to removing two times the same SVG element
  3959. this.graph = null;
  3960. this.graphmacd = this.graphmacd && this.graphmacd.destroy();
  3961. this.graphsignal = this.graphsignal && this.graphsignal.destroy();
  3962. SMA.prototype.destroy.apply(this, arguments);
  3963. },
  3964. drawPoints: H.seriesTypes.column.prototype.drawPoints,
  3965. drawGraph: function () {
  3966. var indicator = this,
  3967. mainLinePoints = indicator.points,
  3968. pointsLength = mainLinePoints.length,
  3969. mainLineOptions = indicator.options,
  3970. histogramZones = indicator.zones,
  3971. gappedExtend = {
  3972. options: {
  3973. gapSize: mainLineOptions.gapSize
  3974. }
  3975. },
  3976. otherSignals = [[],
  3977. []],
  3978. point;
  3979. // Generate points for top and bottom lines:
  3980. while (pointsLength--) {
  3981. point = mainLinePoints[pointsLength];
  3982. if (defined(point.plotMACD)) {
  3983. otherSignals[0].push({
  3984. plotX: point.plotX,
  3985. plotY: point.plotMACD,
  3986. isNull: !defined(point.plotMACD)
  3987. });
  3988. }
  3989. if (defined(point.plotSignal)) {
  3990. otherSignals[1].push({
  3991. plotX: point.plotX,
  3992. plotY: point.plotSignal,
  3993. isNull: !defined(point.plotMACD)
  3994. });
  3995. }
  3996. }
  3997. // Modify options and generate smoothing line:
  3998. ['macd', 'signal'].forEach(function (lineName, i) {
  3999. indicator.points = otherSignals[i];
  4000. indicator.options = merge(mainLineOptions[lineName + 'Line'].styles, gappedExtend);
  4001. indicator.graph = indicator['graph' + lineName];
  4002. // Zones extension:
  4003. indicator.currentLineZone = lineName + 'Zones';
  4004. indicator.zones =
  4005. indicator[indicator.currentLineZone].zones;
  4006. SMA.prototype.drawGraph.call(indicator);
  4007. indicator['graph' + lineName] = indicator.graph;
  4008. });
  4009. // Restore options:
  4010. indicator.points = mainLinePoints;
  4011. indicator.options = mainLineOptions;
  4012. indicator.zones = histogramZones;
  4013. indicator.currentLineZone = null;
  4014. // indicator.graph = null;
  4015. },
  4016. getZonesGraphs: function (props) {
  4017. var allZones = SMA.prototype.getZonesGraphs.call(this,
  4018. props),
  4019. currentZones = allZones;
  4020. if (this.currentLineZone) {
  4021. currentZones = allZones.splice(this[this.currentLineZone].startIndex + 1);
  4022. if (!currentZones.length) {
  4023. // Line has no zones, return basic graph "zone"
  4024. currentZones = [props[0]];
  4025. }
  4026. else {
  4027. // Add back basic prop:
  4028. currentZones.splice(0, 0, props[0]);
  4029. }
  4030. }
  4031. return currentZones;
  4032. },
  4033. applyZones: function () {
  4034. // Histogram zones are handled by drawPoints method
  4035. // Here we need to apply zones for all lines
  4036. var histogramZones = this.zones;
  4037. // signalZones.zones contains all zones:
  4038. this.zones = this.signalZones.zones;
  4039. SMA.prototype.applyZones.call(this);
  4040. // applyZones hides only main series.graph, hide macd line manually
  4041. if (this.graphmacd && this.options.macdLine.zones.length) {
  4042. this.graphmacd.hide();
  4043. }
  4044. this.zones = histogramZones;
  4045. },
  4046. getValues: function (series, params) {
  4047. var j = 0,
  4048. MACD = [],
  4049. xMACD = [],
  4050. yMACD = [],
  4051. signalLine = [],
  4052. shortEMA,
  4053. longEMA,
  4054. i;
  4055. if (series.xData.length <
  4056. params.longPeriod + params.signalPeriod) {
  4057. return;
  4058. }
  4059. // Calculating the short and long EMA used when calculating the MACD
  4060. shortEMA = EMA.prototype.getValues(series, {
  4061. period: params.shortPeriod
  4062. });
  4063. longEMA = EMA.prototype.getValues(series, {
  4064. period: params.longPeriod
  4065. });
  4066. shortEMA = shortEMA.values;
  4067. longEMA = longEMA.values;
  4068. // Subtract each Y value from the EMA's and create the new dataset
  4069. // (MACD)
  4070. for (i = 1; i <= shortEMA.length; i++) {
  4071. if (defined(longEMA[i - 1]) &&
  4072. defined(longEMA[i - 1][1]) &&
  4073. defined(shortEMA[i + params.shortPeriod + 1]) &&
  4074. defined(shortEMA[i + params.shortPeriod + 1][0])) {
  4075. MACD.push([
  4076. shortEMA[i + params.shortPeriod + 1][0],
  4077. 0,
  4078. null,
  4079. shortEMA[i + params.shortPeriod + 1][1] -
  4080. longEMA[i - 1][1]
  4081. ]);
  4082. }
  4083. }
  4084. // Set the Y and X data of the MACD. This is used in calculating the
  4085. // signal line.
  4086. for (i = 0; i < MACD.length; i++) {
  4087. xMACD.push(MACD[i][0]);
  4088. yMACD.push([0, null, MACD[i][3]]);
  4089. }
  4090. // Setting the signalline (Signal Line: X-day EMA of MACD line).
  4091. signalLine = EMA.prototype.getValues({
  4092. xData: xMACD,
  4093. yData: yMACD
  4094. }, {
  4095. period: params.signalPeriod,
  4096. index: 2
  4097. });
  4098. signalLine = signalLine.values;
  4099. // Setting the MACD Histogram. In comparison to the loop with pure
  4100. // MACD this loop uses MACD x value not xData.
  4101. for (i = 0; i < MACD.length; i++) {
  4102. // detect the first point
  4103. if (MACD[i][0] >= signalLine[0][0]) {
  4104. MACD[i][2] = signalLine[j][1];
  4105. yMACD[i] = [0, signalLine[j][1], MACD[i][3]];
  4106. if (MACD[i][3] === null) {
  4107. MACD[i][1] = 0;
  4108. yMACD[i][0] = 0;
  4109. }
  4110. else {
  4111. MACD[i][1] = correctFloat(MACD[i][3] -
  4112. signalLine[j][1]);
  4113. yMACD[i][0] = correctFloat(MACD[i][3] -
  4114. signalLine[j][1]);
  4115. }
  4116. j++;
  4117. }
  4118. }
  4119. return {
  4120. values: MACD,
  4121. xData: xMACD,
  4122. yData: yMACD
  4123. };
  4124. }
  4125. });
  4126. /**
  4127. * A `MACD` series. If the [type](#series.macd.type) option is not
  4128. * specified, it is inherited from [chart.type](#chart.type).
  4129. *
  4130. * @extends series,plotOptions.macd
  4131. * @since 6.0.0
  4132. * @product highstock
  4133. * @excluding dataParser, dataURL
  4134. * @requires stock/indicators/indicators
  4135. * @requires stock/indicators/macd
  4136. * @apioption series.macd
  4137. */
  4138. ''; // to include the above in the js output
  4139. });
  4140. _registerModule(_modules, 'Stock/Indicators/MFIIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  4141. /* *
  4142. *
  4143. * Money Flow Index indicator for Highstock
  4144. *
  4145. * (c) 2010-2020 Grzegorz Blachliński
  4146. *
  4147. * License: www.highcharts.com/license
  4148. *
  4149. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  4150. *
  4151. * */
  4152. var error = U.error,
  4153. isArray = U.isArray,
  4154. seriesType = U.seriesType;
  4155. /* eslint-disable require-jsdoc */
  4156. // Utils:
  4157. function sumArray(array) {
  4158. return array.reduce(function (prev, cur) {
  4159. return prev + cur;
  4160. });
  4161. }
  4162. function toFixed(a, n) {
  4163. return parseFloat(a.toFixed(n));
  4164. }
  4165. function calculateTypicalPrice(point) {
  4166. return (point[1] + point[2] + point[3]) / 3;
  4167. }
  4168. function calculateRawMoneyFlow(typicalPrice, volume) {
  4169. return typicalPrice * volume;
  4170. }
  4171. /* eslint-enable require-jsdoc */
  4172. /**
  4173. * The MFI series type.
  4174. *
  4175. * @private
  4176. * @class
  4177. * @name Highcharts.seriesTypes.mfi
  4178. *
  4179. * @augments Highcharts.Series
  4180. */
  4181. seriesType('mfi', 'sma',
  4182. /**
  4183. * Money Flow Index. This series requires `linkedTo` option to be set and
  4184. * should be loaded after the `stock/indicators/indicators.js` file.
  4185. *
  4186. * @sample stock/indicators/mfi
  4187. * Money Flow Index Indicator
  4188. *
  4189. * @extends plotOptions.sma
  4190. * @since 6.0.0
  4191. * @product highstock
  4192. * @requires stock/indicators/indicators
  4193. * @requires stock/indicators/mfi
  4194. * @optionparent plotOptions.mfi
  4195. */
  4196. {
  4197. /**
  4198. * @excluding index
  4199. */
  4200. params: {
  4201. period: 14,
  4202. /**
  4203. * The id of volume series which is mandatory.
  4204. * For example using OHLC data, volumeSeriesID='volume' means
  4205. * the indicator will be calculated using OHLC and volume values.
  4206. */
  4207. volumeSeriesID: 'volume',
  4208. /**
  4209. * Number of maximum decimals that are used in MFI calculations.
  4210. */
  4211. decimals: 4
  4212. }
  4213. },
  4214. /**
  4215. * @lends Highcharts.Series#
  4216. */
  4217. {
  4218. nameBase: 'Money Flow Index',
  4219. getValues: function (series, params) {
  4220. var period = params.period,
  4221. xVal = series.xData,
  4222. yVal = series.yData,
  4223. yValLen = yVal ? yVal.length : 0,
  4224. decimals = params.decimals,
  4225. // MFI starts calculations from the second point
  4226. // Cause we need to calculate change between two points
  4227. range = 1,
  4228. volumeSeries = series.chart.get(params.volumeSeriesID),
  4229. yValVolume = (volumeSeries && volumeSeries.yData),
  4230. MFI = [],
  4231. isUp = false,
  4232. xData = [],
  4233. yData = [],
  4234. positiveMoneyFlow = [],
  4235. negativeMoneyFlow = [],
  4236. newTypicalPrice,
  4237. oldTypicalPrice,
  4238. rawMoneyFlow,
  4239. negativeMoneyFlowSum,
  4240. positiveMoneyFlowSum,
  4241. moneyFlowRatio,
  4242. MFIPoint,
  4243. i;
  4244. if (!volumeSeries) {
  4245. error('Series ' +
  4246. params.volumeSeriesID +
  4247. ' not found! Check `volumeSeriesID`.', true, series.chart);
  4248. return;
  4249. }
  4250. // MFI requires high low and close values
  4251. if ((xVal.length <= period) || !isArray(yVal[0]) ||
  4252. yVal[0].length !== 4 ||
  4253. !yValVolume) {
  4254. return;
  4255. }
  4256. // Calculate first typical price
  4257. newTypicalPrice = calculateTypicalPrice(yVal[range]);
  4258. // Accumulate first N-points
  4259. while (range < period + 1) {
  4260. // Calculate if up or down
  4261. oldTypicalPrice = newTypicalPrice;
  4262. newTypicalPrice = calculateTypicalPrice(yVal[range]);
  4263. isUp = newTypicalPrice >= oldTypicalPrice;
  4264. // Calculate raw money flow
  4265. rawMoneyFlow = calculateRawMoneyFlow(newTypicalPrice, yValVolume[range]);
  4266. // Add to array
  4267. positiveMoneyFlow.push(isUp ? rawMoneyFlow : 0);
  4268. negativeMoneyFlow.push(isUp ? 0 : rawMoneyFlow);
  4269. range++;
  4270. }
  4271. for (i = range - 1; i < yValLen; i++) {
  4272. if (i > range - 1) {
  4273. // Remove first point from array
  4274. positiveMoneyFlow.shift();
  4275. negativeMoneyFlow.shift();
  4276. // Calculate if up or down
  4277. oldTypicalPrice = newTypicalPrice;
  4278. newTypicalPrice = calculateTypicalPrice(yVal[i]);
  4279. isUp = newTypicalPrice > oldTypicalPrice;
  4280. // Calculate raw money flow
  4281. rawMoneyFlow = calculateRawMoneyFlow(newTypicalPrice, yValVolume[i]);
  4282. // Add to array
  4283. positiveMoneyFlow.push(isUp ? rawMoneyFlow : 0);
  4284. negativeMoneyFlow.push(isUp ? 0 : rawMoneyFlow);
  4285. }
  4286. // Calculate sum of negative and positive money flow:
  4287. negativeMoneyFlowSum = sumArray(negativeMoneyFlow);
  4288. positiveMoneyFlowSum = sumArray(positiveMoneyFlow);
  4289. moneyFlowRatio = positiveMoneyFlowSum / negativeMoneyFlowSum;
  4290. MFIPoint = toFixed(100 - (100 / (1 + moneyFlowRatio)), decimals);
  4291. MFI.push([xVal[i], MFIPoint]);
  4292. xData.push(xVal[i]);
  4293. yData.push(MFIPoint);
  4294. }
  4295. return {
  4296. values: MFI,
  4297. xData: xData,
  4298. yData: yData
  4299. };
  4300. }
  4301. });
  4302. /**
  4303. * A `MFI` series. If the [type](#series.mfi.type) option is not specified, it
  4304. * is inherited from [chart.type](#chart.type).
  4305. *
  4306. * @extends series,plotOptions.mfi
  4307. * @since 6.0.0
  4308. * @excluding dataParser, dataURL
  4309. * @product highstock
  4310. * @requires stock/indicators/indicators
  4311. * @requires stock/indicators/mfi
  4312. * @apioption series.mfi
  4313. */
  4314. ''; // to include the above in the js output
  4315. });
  4316. _registerModule(_modules, 'Stock/Indicators/MomentumIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  4317. /* *
  4318. *
  4319. * License: www.highcharts.com/license
  4320. *
  4321. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  4322. *
  4323. * */
  4324. var isArray = U.isArray,
  4325. seriesType = U.seriesType;
  4326. /* eslint-disable require-jsdoc */
  4327. function populateAverage(points, xVal, yVal, i, period) {
  4328. var mmY = yVal[i - 1][3] - yVal[i - period - 1][3],
  4329. mmX = xVal[i - 1];
  4330. points.shift(); // remove point until range < period
  4331. return [mmX, mmY];
  4332. }
  4333. /* eslint-enable require-jsdoc */
  4334. /**
  4335. * The Momentum series type.
  4336. *
  4337. * @private
  4338. * @class
  4339. * @name Highcharts.seriesTypes.momentum
  4340. *
  4341. * @augments Highcharts.Series
  4342. */
  4343. seriesType('momentum', 'sma',
  4344. /**
  4345. * Momentum. This series requires `linkedTo` option to be set.
  4346. *
  4347. * @sample stock/indicators/momentum
  4348. * Momentum indicator
  4349. *
  4350. * @extends plotOptions.sma
  4351. * @since 6.0.0
  4352. * @product highstock
  4353. * @requires stock/indicators/indicators
  4354. * @requires stock/indicators/momentum
  4355. * @optionparent plotOptions.momentum
  4356. */
  4357. {
  4358. params: {
  4359. period: 14
  4360. }
  4361. },
  4362. /**
  4363. * @lends Highcharts.Series#
  4364. */
  4365. {
  4366. nameBase: 'Momentum',
  4367. getValues: function (series, params) {
  4368. var period = params.period,
  4369. xVal = series.xData,
  4370. yVal = series.yData,
  4371. yValLen = yVal ? yVal.length : 0,
  4372. xValue = xVal[0],
  4373. yValue = yVal[0],
  4374. MM = [],
  4375. xData = [],
  4376. yData = [],
  4377. index,
  4378. i,
  4379. points,
  4380. MMPoint;
  4381. if (xVal.length <= period) {
  4382. return;
  4383. }
  4384. // Switch index for OHLC / Candlestick / Arearange
  4385. if (isArray(yVal[0])) {
  4386. yValue = yVal[0][3];
  4387. }
  4388. else {
  4389. return;
  4390. }
  4391. // Starting point
  4392. points = [
  4393. [xValue, yValue]
  4394. ];
  4395. // Calculate value one-by-one for each period in visible data
  4396. for (i = (period + 1); i < yValLen; i++) {
  4397. MMPoint = populateAverage(points, xVal, yVal, i, period, index);
  4398. MM.push(MMPoint);
  4399. xData.push(MMPoint[0]);
  4400. yData.push(MMPoint[1]);
  4401. }
  4402. MMPoint = populateAverage(points, xVal, yVal, i, period, index);
  4403. MM.push(MMPoint);
  4404. xData.push(MMPoint[0]);
  4405. yData.push(MMPoint[1]);
  4406. return {
  4407. values: MM,
  4408. xData: xData,
  4409. yData: yData
  4410. };
  4411. }
  4412. });
  4413. /**
  4414. * A `Momentum` series. If the [type](#series.momentum.type) option is not
  4415. * specified, it is inherited from [chart.type](#chart.type).
  4416. *
  4417. * @extends series,plotOptions.momentum
  4418. * @since 6.0.0
  4419. * @excluding dataParser, dataURL
  4420. * @product highstock
  4421. * @requires stock/indicators/indicators
  4422. * @requires stock/indicators/momentum
  4423. * @apioption series.momentum
  4424. */
  4425. ''; // to include the above in the js output
  4426. });
  4427. _registerModule(_modules, 'Stock/Indicators/NATRIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
  4428. /* *
  4429. *
  4430. * License: www.highcharts.com/license
  4431. *
  4432. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  4433. *
  4434. * */
  4435. var seriesType = U.seriesType;
  4436. var ATR = H.seriesTypes.atr;
  4437. /**
  4438. * The NATR series type.
  4439. *
  4440. * @private
  4441. * @class
  4442. * @name Highcharts.seriesTypes.natr
  4443. *
  4444. * @augments Highcharts.Series
  4445. */
  4446. seriesType('natr', 'sma',
  4447. /**
  4448. * Normalized average true range indicator (NATR). This series requires
  4449. * `linkedTo` option to be set and should be loaded after the
  4450. * `stock/indicators/indicators.js` and `stock/indicators/atr.js`.
  4451. *
  4452. * @sample {highstock} stock/indicators/natr
  4453. * NATR indicator
  4454. *
  4455. * @extends plotOptions.atr
  4456. * @since 7.0.0
  4457. * @product highstock
  4458. * @requires stock/indicators/indicators
  4459. * @requires stock/indicators/natr
  4460. * @optionparent plotOptions.natr
  4461. */
  4462. {
  4463. tooltip: {
  4464. valueSuffix: '%'
  4465. }
  4466. },
  4467. /**
  4468. * @lends Highcharts.Series#
  4469. */
  4470. {
  4471. requiredIndicators: ['atr'],
  4472. getValues: function (series, params) {
  4473. var atrData = (ATR.prototype.getValues.apply(this,
  4474. arguments)),
  4475. atrLength = atrData.values.length,
  4476. period = params.period - 1,
  4477. yVal = series.yData,
  4478. i = 0;
  4479. if (!atrData) {
  4480. return;
  4481. }
  4482. for (; i < atrLength; i++) {
  4483. atrData.yData[i] = (atrData.values[i][1] / yVal[period][3] * 100);
  4484. atrData.values[i][1] = atrData.yData[i];
  4485. period++;
  4486. }
  4487. return atrData;
  4488. }
  4489. });
  4490. /**
  4491. * A `NATR` series. If the [type](#series.natr.type) option is not specified, it
  4492. * is inherited from [chart.type](#chart.type).
  4493. *
  4494. * @extends series,plotOptions.natr
  4495. * @since 7.0.0
  4496. * @product highstock
  4497. * @excluding dataParser, dataURL
  4498. * @requires stock/indicators/indicators
  4499. * @requires stock/indicators/natr
  4500. * @apioption series.natr
  4501. */
  4502. ''; // to include the above in the js output'
  4503. });
  4504. _registerModule(_modules, 'Stock/Indicators/PivotPointsIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
  4505. /* *
  4506. *
  4507. * License: www.highcharts.com/license
  4508. *
  4509. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  4510. *
  4511. * */
  4512. var defined = U.defined,
  4513. isArray = U.isArray,
  4514. seriesType = U.seriesType;
  4515. var SMA = H.seriesTypes.sma;
  4516. /* eslint-disable valid-jsdoc */
  4517. /**
  4518. * @private
  4519. */
  4520. function destroyExtraLabels(point, functionName) {
  4521. var props = point.series.pointArrayMap,
  4522. prop,
  4523. i = props.length;
  4524. SMA.prototype.pointClass.prototype[functionName].call(point);
  4525. while (i--) {
  4526. prop = 'dataLabel' + props[i];
  4527. // S4 dataLabel could be removed by parent method:
  4528. if (point[prop] && point[prop].element) {
  4529. point[prop].destroy();
  4530. }
  4531. point[prop] = null;
  4532. }
  4533. }
  4534. /* eslint-enable valid-jsdoc */
  4535. /**
  4536. * The Pivot Points series type.
  4537. *
  4538. * @private
  4539. * @class
  4540. * @name Highcharts.seriesTypes.pivotpoints
  4541. *
  4542. * @augments Highcharts.Series
  4543. */
  4544. seriesType('pivotpoints', 'sma',
  4545. /**
  4546. * Pivot points indicator. This series requires the `linkedTo` option to be
  4547. * set and should be loaded after `stock/indicators/indicators.js` file.
  4548. *
  4549. * @sample stock/indicators/pivot-points
  4550. * Pivot points
  4551. *
  4552. * @extends plotOptions.sma
  4553. * @since 6.0.0
  4554. * @product highstock
  4555. * @requires stock/indicators/indicators
  4556. * @requires stock/indicators/pivotpoints
  4557. * @optionparent plotOptions.pivotpoints
  4558. */
  4559. {
  4560. /**
  4561. * @excluding index
  4562. */
  4563. params: {
  4564. period: 28,
  4565. /**
  4566. * Algorithm used to calculate ressistance and support lines based
  4567. * on pivot points. Implemented algorithms: `'standard'`,
  4568. * `'fibonacci'` and `'camarilla'`
  4569. */
  4570. algorithm: 'standard'
  4571. },
  4572. marker: {
  4573. enabled: false
  4574. },
  4575. enableMouseTracking: false,
  4576. dataLabels: {
  4577. enabled: true,
  4578. format: '{point.pivotLine}'
  4579. },
  4580. dataGrouping: {
  4581. approximation: 'averages'
  4582. }
  4583. },
  4584. /**
  4585. * @lends Highcharts.Series#
  4586. */
  4587. {
  4588. nameBase: 'Pivot Points',
  4589. pointArrayMap: ['R4', 'R3', 'R2', 'R1', 'P', 'S1', 'S2', 'S3', 'S4'],
  4590. pointValKey: 'P',
  4591. toYData: function (point) {
  4592. return [point.P]; // The rest should not affect extremes
  4593. },
  4594. translate: function () {
  4595. var indicator = this;
  4596. SMA.prototype.translate.apply(indicator);
  4597. indicator.points.forEach(function (point) {
  4598. indicator.pointArrayMap.forEach(function (value) {
  4599. if (defined(point[value])) {
  4600. point['plot' + value] = (indicator.yAxis.toPixels(point[value], true));
  4601. }
  4602. });
  4603. });
  4604. // Pivot points are rendered as horizontal lines
  4605. // And last point start not from the next one (as it's the last one)
  4606. // But from the approximated last position in a given range
  4607. indicator.plotEndPoint = indicator.xAxis.toPixels(indicator.endPoint, true);
  4608. },
  4609. getGraphPath: function (points) {
  4610. var indicator = this,
  4611. pointsLength = points.length,
  4612. allPivotPoints = ([[],
  4613. [],
  4614. [],
  4615. [],
  4616. [],
  4617. [],
  4618. [],
  4619. [],
  4620. []]),
  4621. path = [],
  4622. endPoint = indicator.plotEndPoint,
  4623. pointArrayMapLength = indicator.pointArrayMap.length,
  4624. position,
  4625. point,
  4626. i;
  4627. while (pointsLength--) {
  4628. point = points[pointsLength];
  4629. for (i = 0; i < pointArrayMapLength; i++) {
  4630. position = indicator.pointArrayMap[i];
  4631. if (defined(point[position])) {
  4632. allPivotPoints[i].push({
  4633. // Start left:
  4634. plotX: point.plotX,
  4635. plotY: point['plot' + position],
  4636. isNull: false
  4637. }, {
  4638. // Go to right:
  4639. plotX: endPoint,
  4640. plotY: point['plot' + position],
  4641. isNull: false
  4642. }, {
  4643. // And add null points in path to generate breaks:
  4644. plotX: endPoint,
  4645. plotY: null,
  4646. isNull: true
  4647. });
  4648. }
  4649. }
  4650. endPoint = point.plotX;
  4651. }
  4652. allPivotPoints.forEach(function (pivotPoints) {
  4653. path = path.concat(SMA.prototype.getGraphPath.call(indicator, pivotPoints));
  4654. });
  4655. return path;
  4656. },
  4657. // TODO: Rewrite this logic to use multiple datalabels
  4658. drawDataLabels: function () {
  4659. var indicator = this,
  4660. pointMapping = indicator.pointArrayMap,
  4661. currentLabel,
  4662. pointsLength,
  4663. point,
  4664. i;
  4665. if (indicator.options.dataLabels.enabled) {
  4666. pointsLength = indicator.points.length;
  4667. // For every Ressitance/Support group we need to render labels.
  4668. // Add one more item, which will just store dataLabels from
  4669. // previous iteration
  4670. pointMapping.concat([false]).forEach(function (position, k) {
  4671. i = pointsLength;
  4672. while (i--) {
  4673. point = indicator.points[i];
  4674. if (!position) {
  4675. // Store S4 dataLabel too:
  4676. point['dataLabel' + pointMapping[k - 1]] =
  4677. point.dataLabel;
  4678. }
  4679. else {
  4680. point.y = point[position];
  4681. point.pivotLine = position;
  4682. point.plotY = point['plot' + position];
  4683. currentLabel = point['dataLabel' + position];
  4684. // Store previous label
  4685. if (k) {
  4686. point['dataLabel' + pointMapping[k - 1]] = point.dataLabel;
  4687. }
  4688. if (!point.dataLabels) {
  4689. point.dataLabels = [];
  4690. }
  4691. point.dataLabels[0] = point.dataLabel =
  4692. currentLabel =
  4693. currentLabel && currentLabel.element ?
  4694. currentLabel :
  4695. null;
  4696. }
  4697. }
  4698. SMA.prototype.drawDataLabels.apply(indicator, arguments);
  4699. });
  4700. }
  4701. },
  4702. getValues: function (series, params) {
  4703. var period = params.period,
  4704. xVal = series.xData,
  4705. yVal = series.yData,
  4706. yValLen = yVal ? yVal.length : 0,
  4707. placement = this[params.algorithm + 'Placement'],
  4708. // 0- from, 1- to, 2- R1, 3- R2, 4- pivot, 5- S1 etc.
  4709. PP = [],
  4710. endTimestamp,
  4711. xData = [],
  4712. yData = [],
  4713. slicedXLen,
  4714. slicedX,
  4715. slicedY,
  4716. lastPP,
  4717. pivot,
  4718. avg,
  4719. i;
  4720. // Pivot Points requires high, low and close values
  4721. if (xVal.length < period ||
  4722. !isArray(yVal[0]) ||
  4723. yVal[0].length !== 4) {
  4724. return;
  4725. }
  4726. for (i = period + 1; i <= yValLen + period; i += period) {
  4727. slicedX = xVal.slice(i - period - 1, i);
  4728. slicedY = yVal.slice(i - period - 1, i);
  4729. slicedXLen = slicedX.length;
  4730. endTimestamp = slicedX[slicedXLen - 1];
  4731. pivot = this.getPivotAndHLC(slicedY);
  4732. avg = placement(pivot);
  4733. lastPP = PP.push([endTimestamp]
  4734. .concat(avg));
  4735. xData.push(endTimestamp);
  4736. yData.push(PP[lastPP - 1].slice(1));
  4737. }
  4738. // We don't know exact position in ordinal axis
  4739. // So we use simple logic:
  4740. // Get first point in last range, calculate visible average range
  4741. // and multiply by period
  4742. this.endPoint = slicedX[0] + ((endTimestamp - slicedX[0]) /
  4743. slicedXLen) * period;
  4744. return {
  4745. values: PP,
  4746. xData: xData,
  4747. yData: yData
  4748. };
  4749. },
  4750. getPivotAndHLC: function (values) {
  4751. var high = -Infinity,
  4752. low = Infinity,
  4753. close = values[values.length - 1][3],
  4754. pivot;
  4755. values.forEach(function (p) {
  4756. high = Math.max(high, p[1]);
  4757. low = Math.min(low, p[2]);
  4758. });
  4759. pivot = (high + low + close) / 3;
  4760. return [pivot, high, low, close];
  4761. },
  4762. standardPlacement: function (values) {
  4763. var diff = values[1] - values[2],
  4764. avg = [
  4765. null,
  4766. null,
  4767. values[0] + diff,
  4768. values[0] * 2 - values[2],
  4769. values[0],
  4770. values[0] * 2 - values[1],
  4771. values[0] - diff,
  4772. null,
  4773. null
  4774. ];
  4775. return avg;
  4776. },
  4777. camarillaPlacement: function (values) {
  4778. var diff = values[1] - values[2],
  4779. avg = [
  4780. values[3] + diff * 1.5,
  4781. values[3] + diff * 1.25,
  4782. values[3] + diff * 1.1666,
  4783. values[3] + diff * 1.0833,
  4784. values[0],
  4785. values[3] - diff * 1.0833,
  4786. values[3] - diff * 1.1666,
  4787. values[3] - diff * 1.25,
  4788. values[3] - diff * 1.5
  4789. ];
  4790. return avg;
  4791. },
  4792. fibonacciPlacement: function (values) {
  4793. var diff = values[1] - values[2],
  4794. avg = [
  4795. null,
  4796. values[0] + diff,
  4797. values[0] + diff * 0.618,
  4798. values[0] + diff * 0.382,
  4799. values[0],
  4800. values[0] - diff * 0.382,
  4801. values[0] - diff * 0.618,
  4802. values[0] - diff,
  4803. null
  4804. ];
  4805. return avg;
  4806. }
  4807. },
  4808. /**
  4809. * @lends Highcharts.Point#
  4810. */
  4811. {
  4812. // Destroy labels:
  4813. // This method is called when cropping data:
  4814. destroyElements: function () {
  4815. destroyExtraLabels(this, 'destroyElements');
  4816. },
  4817. // This method is called when removing points, e.g. series.update()
  4818. destroy: function () {
  4819. destroyExtraLabels(this, 'destroyElements');
  4820. }
  4821. });
  4822. /**
  4823. * A pivot points indicator. If the [type](#series.pivotpoints.type) option is
  4824. * not specified, it is inherited from [chart.type](#chart.type).
  4825. *
  4826. * @extends series,plotOptions.pivotpoints
  4827. * @since 6.0.0
  4828. * @product highstock
  4829. * @excluding dataParser, dataURL
  4830. * @requires stock/indicators/indicators
  4831. * @requires stock/indicators/pivotpoints
  4832. * @apioption series.pivotpoints
  4833. */
  4834. ''; // to include the above in the js output'
  4835. });
  4836. _registerModule(_modules, 'Stock/Indicators/PPOIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Mixins/IndicatorRequired.js']], function (H, U, requiredIndicator) {
  4837. /* *
  4838. *
  4839. * License: www.highcharts.com/license
  4840. *
  4841. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  4842. *
  4843. * */
  4844. var correctFloat = U.correctFloat,
  4845. error = U.error,
  4846. seriesType = U.seriesType;
  4847. var EMA = H.seriesTypes.ema;
  4848. /**
  4849. * The PPO series type.
  4850. *
  4851. * @private
  4852. * @class
  4853. * @name Highcharts.seriesTypes.ppo
  4854. *
  4855. * @augments Highcharts.Series
  4856. */
  4857. seriesType('ppo', 'ema',
  4858. /**
  4859. * Percentage Price Oscillator. This series requires the
  4860. * `linkedTo` option to be set and should be loaded after the
  4861. * `stock/indicators/indicators.js` and `stock/indicators/ema.js`.
  4862. *
  4863. * @sample {highstock} stock/indicators/ppo
  4864. * Percentage Price Oscillator
  4865. *
  4866. * @extends plotOptions.ema
  4867. * @since 7.0.0
  4868. * @product highstock
  4869. * @excluding allAreas, colorAxis, joinBy, keys, navigatorOptions,
  4870. * pointInterval, pointIntervalUnit, pointPlacement,
  4871. * pointRange, pointStart, showInNavigator, stacking
  4872. * @requires stock/indicators/indicators
  4873. * @requires stock/indicators/ema
  4874. * @requires stock/indicators/ppo
  4875. * @optionparent plotOptions.ppo
  4876. */
  4877. {
  4878. /**
  4879. * Paramters used in calculation of Percentage Price Oscillator series
  4880. * points.
  4881. *
  4882. * @excluding period
  4883. */
  4884. params: {
  4885. /**
  4886. * Periods for Percentage Price Oscillator calculations.
  4887. *
  4888. * @type {Array<number>}
  4889. * @default [12, 26]
  4890. */
  4891. periods: [12, 26]
  4892. }
  4893. },
  4894. /**
  4895. * @lends Highcharts.Series.prototype
  4896. */
  4897. {
  4898. nameBase: 'PPO',
  4899. nameComponents: ['periods'],
  4900. init: function () {
  4901. var args = arguments,
  4902. ctx = this;
  4903. requiredIndicator.isParentLoaded(EMA, 'ema', ctx.type, function (indicator) {
  4904. indicator.prototype.init.apply(ctx, args);
  4905. return;
  4906. });
  4907. },
  4908. getValues: function (series, params) {
  4909. var periods = params.periods,
  4910. index = params.index,
  4911. // 0- date, 1- Percentage Price Oscillator
  4912. PPO = [],
  4913. xData = [],
  4914. yData = [],
  4915. periodsOffset,
  4916. // Shorter Period EMA
  4917. SPE,
  4918. // Longer Period EMA
  4919. LPE,
  4920. oscillator,
  4921. i;
  4922. // Check if periods are correct
  4923. if (periods.length !== 2 || periods[1] <= periods[0]) {
  4924. error('Error: "PPO requires two periods. Notice, first period ' +
  4925. 'should be lower than the second one."');
  4926. return;
  4927. }
  4928. SPE = EMA.prototype.getValues.call(this, series, {
  4929. index: index,
  4930. period: periods[0]
  4931. });
  4932. LPE = EMA.prototype.getValues.call(this, series, {
  4933. index: index,
  4934. period: periods[1]
  4935. });
  4936. // Check if ema is calculated properly, if not skip
  4937. if (!SPE || !LPE) {
  4938. return;
  4939. }
  4940. periodsOffset = periods[1] - periods[0];
  4941. for (i = 0; i < LPE.yData.length; i++) {
  4942. oscillator = correctFloat((SPE.yData[i + periodsOffset] -
  4943. LPE.yData[i]) /
  4944. LPE.yData[i] *
  4945. 100);
  4946. PPO.push([LPE.xData[i], oscillator]);
  4947. xData.push(LPE.xData[i]);
  4948. yData.push(oscillator);
  4949. }
  4950. return {
  4951. values: PPO,
  4952. xData: xData,
  4953. yData: yData
  4954. };
  4955. }
  4956. });
  4957. /**
  4958. * A `Percentage Price Oscillator` series. If the [type](#series.ppo.type)
  4959. * option is not specified, it is inherited from [chart.type](#chart.type).
  4960. *
  4961. * @extends series,plotOptions.ppo
  4962. * @since 7.0.0
  4963. * @product highstock
  4964. * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
  4965. * navigatorOptions, pointInterval, pointIntervalUnit,
  4966. * pointPlacement, pointRange, pointStart, showInNavigator, stacking
  4967. * @requires stock/indicators/indicators
  4968. * @requires stock/indicators/ema
  4969. * @requires stock/indicators/ppo
  4970. * @apioption series.ppo
  4971. */
  4972. ''; // to include the above in the js output
  4973. });
  4974. _registerModule(_modules, 'Mixins/ReduceArray.js', [], function () {
  4975. /**
  4976. *
  4977. * (c) 2010-2020 Pawel Fus & Daniel Studencki
  4978. *
  4979. * License: www.highcharts.com/license
  4980. *
  4981. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  4982. *
  4983. * */
  4984. var reduceArrayMixin = {
  4985. /**
  4986. * Get min value of array filled by OHLC data.
  4987. * @private
  4988. * @param {Array<*>} arr Array of OHLC points (arrays).
  4989. * @param {string} index Index of "low" value in point array.
  4990. * @return {number} Returns min value.
  4991. */
  4992. minInArray: function (arr,
  4993. index) {
  4994. return arr.reduce(function (min,
  4995. target) {
  4996. return Math.min(min,
  4997. target[index]);
  4998. }, Number.MAX_VALUE);
  4999. },
  5000. /**
  5001. * Get max value of array filled by OHLC data.
  5002. * @private
  5003. * @param {Array<*>} arr Array of OHLC points (arrays).
  5004. * @param {string} index Index of "high" value in point array.
  5005. * @return {number} Returns max value.
  5006. */
  5007. maxInArray: function (arr, index) {
  5008. return arr.reduce(function (max, target) {
  5009. return Math.max(max, target[index]);
  5010. }, -Number.MAX_VALUE);
  5011. },
  5012. /**
  5013. * Get extremes of array filled by OHLC data.
  5014. * @private
  5015. * @param {Array<*>} arr Array of OHLC points (arrays).
  5016. * @param {string} minIndex Index of "low" value in point array.
  5017. * @param {string} maxIndex Index of "high" value in point array.
  5018. * @return {Array<number,number>} Returns array with min and max value.
  5019. */
  5020. getArrayExtremes: function (arr, minIndex, maxIndex) {
  5021. return arr.reduce(function (prev, target) {
  5022. return [
  5023. Math.min(prev[0], target[minIndex]),
  5024. Math.max(prev[1], target[maxIndex])
  5025. ];
  5026. }, [Number.MAX_VALUE, -Number.MAX_VALUE]);
  5027. }
  5028. };
  5029. return reduceArrayMixin;
  5030. });
  5031. _registerModule(_modules, 'Stock/Indicators/PCIndicator.js', [_modules['Core/Utilities.js'], _modules['Mixins/ReduceArray.js'], _modules['Mixins/MultipleLines.js']], function (U, reduceArrayMixin, multipleLinesMixin) {
  5032. /* *
  5033. *
  5034. * License: www.highcharts.com/license
  5035. *
  5036. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  5037. *
  5038. * */
  5039. var merge = U.merge,
  5040. seriesType = U.seriesType;
  5041. var getArrayExtremes = reduceArrayMixin.getArrayExtremes;
  5042. /**
  5043. * The Price Channel series type.
  5044. *
  5045. * @private
  5046. * @class
  5047. * @name Highcharts.seriesTypes.pc
  5048. *
  5049. * @augments Highcharts.Series
  5050. */
  5051. seriesType('pc', 'sma',
  5052. /**
  5053. * Price channel (PC). This series requires the `linkedTo` option to be
  5054. * set and should be loaded after the `stock/indicators/indicators.js`.
  5055. *
  5056. * @sample {highstock} stock/indicators/price-channel
  5057. * Price Channel
  5058. *
  5059. * @extends plotOptions.sma
  5060. * @since 7.0.0
  5061. * @product highstock
  5062. * @excluding allAreas, colorAxis, compare, compareBase, joinBy, keys,
  5063. * navigatorOptions, pointInterval, pointIntervalUnit,
  5064. * pointPlacement, pointRange, pointStart, showInNavigator,
  5065. * stacking
  5066. * @requires stock/indicators/indicators
  5067. * @requires stock/indicators/price-channel
  5068. * @optionparent plotOptions.pc
  5069. */
  5070. {
  5071. /**
  5072. * @excluding index
  5073. */
  5074. params: {
  5075. period: 20
  5076. },
  5077. lineWidth: 1,
  5078. topLine: {
  5079. styles: {
  5080. /**
  5081. * Color of the top line. If not set, it's inherited from
  5082. * [plotOptions.pc.color](#plotOptions.pc.color).
  5083. *
  5084. * @type {Highcharts.ColorString}
  5085. */
  5086. lineColor: '#7cb5ec #434348 #90ed7d #f7a35c #8085e9 #f15c80 #e4d354 #2b908f #f45b5b #91e8e1'.split(' ')[2],
  5087. /**
  5088. * Pixel width of the line.
  5089. */
  5090. lineWidth: 1
  5091. }
  5092. },
  5093. bottomLine: {
  5094. styles: {
  5095. /**
  5096. * Color of the bottom line. If not set, it's inherited from
  5097. * [plotOptions.pc.color](#plotOptions.pc.color).
  5098. *
  5099. * @type {Highcharts.ColorString}
  5100. */
  5101. lineColor: '#7cb5ec #434348 #90ed7d #f7a35c #8085e9 #f15c80 #e4d354 #2b908f #f45b5b #91e8e1'.split(' ')[8],
  5102. /**
  5103. * Pixel width of the line.
  5104. */
  5105. lineWidth: 1
  5106. }
  5107. },
  5108. dataGrouping: {
  5109. approximation: 'averages'
  5110. }
  5111. },
  5112. /**
  5113. * @lends Highcharts.Series#
  5114. */
  5115. merge(multipleLinesMixin, {
  5116. pointArrayMap: ['top', 'middle', 'bottom'],
  5117. pointValKey: 'middle',
  5118. nameBase: 'Price Channel',
  5119. nameComponents: ['period'],
  5120. linesApiNames: ['topLine', 'bottomLine'],
  5121. getValues: function (series, params) {
  5122. var period = params.period,
  5123. xVal = series.xData,
  5124. yVal = series.yData,
  5125. yValLen = yVal ? yVal.length : 0,
  5126. // 0- date, 1-top line, 2-middle line, 3-bottom line
  5127. PC = [],
  5128. // middle line, top line and bottom line
  5129. ML,
  5130. TL,
  5131. BL,
  5132. date,
  5133. low = 2,
  5134. high = 1,
  5135. xData = [],
  5136. yData = [],
  5137. slicedY,
  5138. extremes,
  5139. i;
  5140. if (yValLen < period) {
  5141. return;
  5142. }
  5143. for (i = period; i <= yValLen; i++) {
  5144. date = xVal[i - 1];
  5145. slicedY = yVal.slice(i - period, i);
  5146. extremes = getArrayExtremes(slicedY, low, high);
  5147. TL = extremes[1];
  5148. BL = extremes[0];
  5149. ML = (TL + BL) / 2;
  5150. PC.push([date, TL, ML, BL]);
  5151. xData.push(date);
  5152. yData.push([TL, ML, BL]);
  5153. }
  5154. return {
  5155. values: PC,
  5156. xData: xData,
  5157. yData: yData
  5158. };
  5159. }
  5160. }));
  5161. /**
  5162. * A Price channel indicator. If the [type](#series.pc.type) option is not
  5163. * specified, it is inherited from [chart.type](#chart.type).
  5164. *
  5165. * @extends series,plotOptions.pc
  5166. * @since 7.0.0
  5167. * @product highstock
  5168. * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
  5169. * joinBy, keys, navigatorOptions, pointInterval,
  5170. * pointIntervalUnit, pointPlacement, pointRange, pointStart,
  5171. * showInNavigator, stacking
  5172. * @requires stock/indicators/indicators
  5173. * @requires stock/indicators/price-channel
  5174. * @apioption series.pc
  5175. */
  5176. ''; // to include the above in the js output
  5177. });
  5178. _registerModule(_modules, 'Stock/Indicators/PriceEnvelopesIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
  5179. /* *
  5180. *
  5181. * License: www.highcharts.com/license
  5182. *
  5183. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  5184. *
  5185. * */
  5186. var isArray = U.isArray,
  5187. merge = U.merge,
  5188. seriesType = U.seriesType;
  5189. var SMA = H.seriesTypes.sma;
  5190. /**
  5191. * The Price Envelopes series type.
  5192. *
  5193. * @private
  5194. * @class
  5195. * @name Highcharts.seriesTypes.priceenvelopes
  5196. *
  5197. * @augments Highcharts.Series
  5198. */
  5199. seriesType('priceenvelopes', 'sma',
  5200. /**
  5201. * Price envelopes indicator based on [SMA](#plotOptions.sma) calculations.
  5202. * This series requires the `linkedTo` option to be set and should be loaded
  5203. * after the `stock/indicators/indicators.js` file.
  5204. *
  5205. * @sample stock/indicators/price-envelopes
  5206. * Price envelopes
  5207. *
  5208. * @extends plotOptions.sma
  5209. * @since 6.0.0
  5210. * @product highstock
  5211. * @requires stock/indicators/indicators
  5212. * @requires stock/indicators/price-envelopes
  5213. * @optionparent plotOptions.priceenvelopes
  5214. */
  5215. {
  5216. marker: {
  5217. enabled: false
  5218. },
  5219. tooltip: {
  5220. pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>Top: {point.top}<br/>Middle: {point.middle}<br/>Bottom: {point.bottom}<br/>'
  5221. },
  5222. params: {
  5223. period: 20,
  5224. /**
  5225. * Percentage above the moving average that should be displayed.
  5226. * 0.1 means 110%. Relative to the calculated value.
  5227. */
  5228. topBand: 0.1,
  5229. /**
  5230. * Percentage below the moving average that should be displayed.
  5231. * 0.1 means 90%. Relative to the calculated value.
  5232. */
  5233. bottomBand: 0.1
  5234. },
  5235. /**
  5236. * Bottom line options.
  5237. */
  5238. bottomLine: {
  5239. styles: {
  5240. /**
  5241. * Pixel width of the line.
  5242. */
  5243. lineWidth: 1,
  5244. /**
  5245. * Color of the line. If not set, it's inherited from
  5246. * [plotOptions.priceenvelopes.color](
  5247. * #plotOptions.priceenvelopes.color).
  5248. *
  5249. * @type {Highcharts.ColorString}
  5250. */
  5251. lineColor: void 0
  5252. }
  5253. },
  5254. /**
  5255. * Top line options.
  5256. *
  5257. * @extends plotOptions.priceenvelopes.bottomLine
  5258. */
  5259. topLine: {
  5260. styles: {
  5261. lineWidth: 1
  5262. }
  5263. },
  5264. dataGrouping: {
  5265. approximation: 'averages'
  5266. }
  5267. },
  5268. /**
  5269. * @lends Highcharts.Series#
  5270. */
  5271. {
  5272. nameComponents: ['period', 'topBand', 'bottomBand'],
  5273. nameBase: 'Price envelopes',
  5274. pointArrayMap: ['top', 'middle', 'bottom'],
  5275. parallelArrays: ['x', 'y', 'top', 'bottom'],
  5276. pointValKey: 'middle',
  5277. init: function () {
  5278. SMA.prototype.init.apply(this, arguments);
  5279. // Set default color for lines:
  5280. this.options = merge({
  5281. topLine: {
  5282. styles: {
  5283. lineColor: this.color
  5284. }
  5285. },
  5286. bottomLine: {
  5287. styles: {
  5288. lineColor: this.color
  5289. }
  5290. }
  5291. }, this.options);
  5292. },
  5293. toYData: function (point) {
  5294. return [point.top, point.middle, point.bottom];
  5295. },
  5296. translate: function () {
  5297. var indicator = this, translatedEnvelopes = ['plotTop', 'plotMiddle', 'plotBottom'];
  5298. SMA.prototype.translate.apply(indicator);
  5299. indicator.points.forEach(function (point) {
  5300. [point.top, point.middle, point.bottom].forEach(function (value, i) {
  5301. if (value !== null) {
  5302. point[translatedEnvelopes[i]] =
  5303. indicator.yAxis.toPixels(value, true);
  5304. }
  5305. });
  5306. });
  5307. },
  5308. drawGraph: function () {
  5309. var indicator = this,
  5310. middleLinePoints = indicator.points,
  5311. pointsLength = middleLinePoints.length,
  5312. middleLineOptions = (indicator.options),
  5313. middleLinePath = indicator.graph,
  5314. gappedExtend = {
  5315. options: {
  5316. gapSize: middleLineOptions.gapSize
  5317. }
  5318. },
  5319. deviations = [[],
  5320. []], // top and bottom point place holders
  5321. point;
  5322. // Generate points for top and bottom lines:
  5323. while (pointsLength--) {
  5324. point = middleLinePoints[pointsLength];
  5325. deviations[0].push({
  5326. plotX: point.plotX,
  5327. plotY: point.plotTop,
  5328. isNull: point.isNull
  5329. });
  5330. deviations[1].push({
  5331. plotX: point.plotX,
  5332. plotY: point.plotBottom,
  5333. isNull: point.isNull
  5334. });
  5335. }
  5336. // Modify options and generate lines:
  5337. ['topLine', 'bottomLine'].forEach(function (lineName, i) {
  5338. indicator.points = deviations[i];
  5339. indicator.options = merge(middleLineOptions[lineName].styles, gappedExtend);
  5340. indicator.graph = indicator['graph' + lineName];
  5341. SMA.prototype.drawGraph.call(indicator);
  5342. // Now save lines:
  5343. indicator['graph' + lineName] = indicator.graph;
  5344. });
  5345. // Restore options and draw a middle line:
  5346. indicator.points = middleLinePoints;
  5347. indicator.options = middleLineOptions;
  5348. indicator.graph = middleLinePath;
  5349. SMA.prototype.drawGraph.call(indicator);
  5350. },
  5351. getValues: function (series, params) {
  5352. var period = params.period,
  5353. topPercent = params.topBand,
  5354. botPercent = params.bottomBand,
  5355. xVal = series.xData,
  5356. yVal = series.yData,
  5357. yValLen = yVal ? yVal.length : 0,
  5358. // 0- date, 1-top line, 2-middle line, 3-bottom line
  5359. PE = [],
  5360. // middle line, top line and bottom line
  5361. ML,
  5362. TL,
  5363. BL,
  5364. date,
  5365. xData = [],
  5366. yData = [],
  5367. slicedX,
  5368. slicedY,
  5369. point,
  5370. i;
  5371. // Price envelopes requires close value
  5372. if (xVal.length < period ||
  5373. !isArray(yVal[0]) ||
  5374. yVal[0].length !== 4) {
  5375. return;
  5376. }
  5377. for (i = period; i <= yValLen; i++) {
  5378. slicedX = xVal.slice(i - period, i);
  5379. slicedY = yVal.slice(i - period, i);
  5380. point = SMA.prototype.getValues.call(this, {
  5381. xData: slicedX,
  5382. yData: slicedY
  5383. }, params);
  5384. date = point.xData[0];
  5385. ML = point.yData[0];
  5386. TL = ML * (1 + topPercent);
  5387. BL = ML * (1 - botPercent);
  5388. PE.push([date, TL, ML, BL]);
  5389. xData.push(date);
  5390. yData.push([TL, ML, BL]);
  5391. }
  5392. return {
  5393. values: PE,
  5394. xData: xData,
  5395. yData: yData
  5396. };
  5397. }
  5398. });
  5399. /**
  5400. * A price envelopes indicator. If the [type](#series.priceenvelopes.type)
  5401. * option is not specified, it is inherited from [chart.type](#chart.type).
  5402. *
  5403. * @extends series,plotOptions.priceenvelopes
  5404. * @since 6.0.0
  5405. * @excluding dataParser, dataURL
  5406. * @product highstock
  5407. * @requires stock/indicators/indicators
  5408. * @requires stock/indicators/price-envelopes
  5409. * @apioption series.priceenvelopes
  5410. */
  5411. ''; // to include the above in the js output
  5412. });
  5413. _registerModule(_modules, 'Stock/Indicators/PSARIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  5414. /* *
  5415. *
  5416. * Parabolic SAR indicator for Highstock
  5417. *
  5418. * (c) 2010-2020 Grzegorz Blachliński
  5419. *
  5420. * License: www.highcharts.com/license
  5421. *
  5422. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  5423. *
  5424. * */
  5425. var seriesType = U.seriesType;
  5426. /* eslint-disable require-jsdoc */
  5427. // Utils:
  5428. function toFixed(a, n) {
  5429. return parseFloat(a.toFixed(n));
  5430. }
  5431. function calculateDirection(previousDirection, low, high, PSAR) {
  5432. if ((previousDirection === 1 && low > PSAR) ||
  5433. (previousDirection === -1 && high > PSAR)) {
  5434. return 1;
  5435. }
  5436. return -1;
  5437. }
  5438. /* *
  5439. * Method for calculating acceleration factor
  5440. * dir - direction
  5441. * pDir - previous Direction
  5442. * eP - extreme point
  5443. * pEP - previous extreme point
  5444. * inc - increment for acceleration factor
  5445. * maxAcc - maximum acceleration factor
  5446. * initAcc - initial acceleration factor
  5447. */
  5448. function getAccelerationFactor(dir, pDir, eP, pEP, pAcc, inc, maxAcc, initAcc) {
  5449. if (dir === pDir) {
  5450. if (dir === 1 && (eP > pEP)) {
  5451. return (pAcc === maxAcc) ? maxAcc : toFixed(pAcc + inc, 2);
  5452. }
  5453. if (dir === -1 && (eP < pEP)) {
  5454. return (pAcc === maxAcc) ? maxAcc : toFixed(pAcc + inc, 2);
  5455. }
  5456. return pAcc;
  5457. }
  5458. return initAcc;
  5459. }
  5460. function getExtremePoint(high, low, previousDirection, previousExtremePoint) {
  5461. if (previousDirection === 1) {
  5462. return (high > previousExtremePoint) ? high : previousExtremePoint;
  5463. }
  5464. return (low < previousExtremePoint) ? low : previousExtremePoint;
  5465. }
  5466. function getEPMinusPSAR(EP, PSAR) {
  5467. return EP - PSAR;
  5468. }
  5469. function getAccelerationFactorMultiply(accelerationFactor, EPMinusSAR) {
  5470. return accelerationFactor * EPMinusSAR;
  5471. }
  5472. /* *
  5473. * Method for calculating PSAR
  5474. * pdir - previous direction
  5475. * sDir - second previous Direction
  5476. * PSAR - previous PSAR
  5477. * pACCMultiply - previous acceleration factor multiply
  5478. * sLow - second previous low
  5479. * pLow - previous low
  5480. * sHigh - second previous high
  5481. * pHigh - previous high
  5482. * pEP - previous extreme point
  5483. */
  5484. function getPSAR(pdir, sDir, PSAR, pACCMulti, sLow, pLow, pHigh, sHigh, pEP) {
  5485. if (pdir === sDir) {
  5486. if (pdir === 1) {
  5487. return (PSAR + pACCMulti < Math.min(sLow, pLow)) ?
  5488. PSAR + pACCMulti :
  5489. Math.min(sLow, pLow);
  5490. }
  5491. return (PSAR + pACCMulti > Math.max(sHigh, pHigh)) ?
  5492. PSAR + pACCMulti :
  5493. Math.max(sHigh, pHigh);
  5494. }
  5495. return pEP;
  5496. }
  5497. /* eslint-enable require-jsdoc */
  5498. /**
  5499. * The Parabolic SAR series type.
  5500. *
  5501. * @private
  5502. * @class
  5503. * @name Highcharts.seriesTypes.psar
  5504. *
  5505. * @augments Highcharts.Series
  5506. */
  5507. seriesType('psar', 'sma',
  5508. /**
  5509. * Parabolic SAR. This series requires `linkedTo`
  5510. * option to be set and should be loaded
  5511. * after `stock/indicators/indicators.js` file.
  5512. *
  5513. * @sample stock/indicators/psar
  5514. * Parabolic SAR Indicator
  5515. *
  5516. * @extends plotOptions.sma
  5517. * @since 6.0.0
  5518. * @product highstock
  5519. * @requires stock/indicators/indicators
  5520. * @requires stock/indicators/psar
  5521. * @optionparent plotOptions.psar
  5522. */
  5523. {
  5524. lineWidth: 0,
  5525. marker: {
  5526. enabled: true
  5527. },
  5528. states: {
  5529. hover: {
  5530. lineWidthPlus: 0
  5531. }
  5532. },
  5533. /**
  5534. * @excluding period
  5535. */
  5536. params: {
  5537. /**
  5538. * The initial value for acceleration factor.
  5539. * Acceleration factor is starting with this value
  5540. * and increases by specified increment each time
  5541. * the extreme point makes a new high.
  5542. * AF can reach a maximum of maxAccelerationFactor,
  5543. * no matter how long the uptrend extends.
  5544. */
  5545. initialAccelerationFactor: 0.02,
  5546. /**
  5547. * The Maximum value for acceleration factor.
  5548. * AF can reach a maximum of maxAccelerationFactor,
  5549. * no matter how long the uptrend extends.
  5550. */
  5551. maxAccelerationFactor: 0.2,
  5552. /**
  5553. * Acceleration factor increases by increment each time
  5554. * the extreme point makes a new high.
  5555. *
  5556. * @since 6.0.0
  5557. */
  5558. increment: 0.02,
  5559. /**
  5560. * Index from which PSAR is starting calculation
  5561. *
  5562. * @since 6.0.0
  5563. */
  5564. index: 2,
  5565. /**
  5566. * Number of maximum decimals that are used in PSAR calculations.
  5567. *
  5568. * @since 6.0.0
  5569. */
  5570. decimals: 4
  5571. }
  5572. }, {
  5573. nameComponents: false,
  5574. getValues: function (series, params) {
  5575. var xVal = series.xData,
  5576. yVal = series.yData,
  5577. // Extreme point is the lowest low for falling and highest high
  5578. // for rising psar - and we are starting with falling
  5579. extremePoint = yVal[0][1],
  5580. accelerationFactor = params.initialAccelerationFactor,
  5581. maxAccelerationFactor = params.maxAccelerationFactor,
  5582. increment = params.increment,
  5583. // Set initial acc factor (for every new trend!)
  5584. initialAccelerationFactor = params.initialAccelerationFactor,
  5585. PSAR = yVal[0][2],
  5586. decimals = params.decimals,
  5587. index = params.index,
  5588. PSARArr = [],
  5589. xData = [],
  5590. yData = [],
  5591. previousDirection = 1,
  5592. direction,
  5593. EPMinusPSAR,
  5594. accelerationFactorMultiply,
  5595. newDirection,
  5596. prevLow,
  5597. prevPrevLow,
  5598. prevHigh,
  5599. prevPrevHigh,
  5600. newExtremePoint,
  5601. high,
  5602. low,
  5603. ind;
  5604. if (index >= yVal.length) {
  5605. return;
  5606. }
  5607. for (ind = 0; ind < index; ind++) {
  5608. extremePoint = Math.max(yVal[ind][1], extremePoint);
  5609. PSAR = Math.min(yVal[ind][2], toFixed(PSAR, decimals));
  5610. }
  5611. direction = (yVal[ind][1] > PSAR) ? 1 : -1;
  5612. EPMinusPSAR = getEPMinusPSAR(extremePoint, PSAR);
  5613. accelerationFactor = params.initialAccelerationFactor;
  5614. accelerationFactorMultiply = getAccelerationFactorMultiply(accelerationFactor, EPMinusPSAR);
  5615. PSARArr.push([xVal[index], PSAR]);
  5616. xData.push(xVal[index]);
  5617. yData.push(toFixed(PSAR, decimals));
  5618. for (ind = index + 1; ind < yVal.length; ind++) {
  5619. prevLow = yVal[ind - 1][2];
  5620. prevPrevLow = yVal[ind - 2][2];
  5621. prevHigh = yVal[ind - 1][1];
  5622. prevPrevHigh = yVal[ind - 2][1];
  5623. high = yVal[ind][1];
  5624. low = yVal[ind][2];
  5625. // Null points break PSAR
  5626. if (prevPrevLow !== null &&
  5627. prevPrevHigh !== null &&
  5628. prevLow !== null &&
  5629. prevHigh !== null &&
  5630. high !== null &&
  5631. low !== null) {
  5632. PSAR = getPSAR(direction, previousDirection, PSAR, accelerationFactorMultiply, prevPrevLow, prevLow, prevHigh, prevPrevHigh, extremePoint);
  5633. newExtremePoint = getExtremePoint(high, low, direction, extremePoint);
  5634. newDirection = calculateDirection(previousDirection, low, high, PSAR);
  5635. accelerationFactor = getAccelerationFactor(newDirection, direction, newExtremePoint, extremePoint, accelerationFactor, increment, maxAccelerationFactor, initialAccelerationFactor);
  5636. EPMinusPSAR = getEPMinusPSAR(newExtremePoint, PSAR);
  5637. accelerationFactorMultiply = getAccelerationFactorMultiply(accelerationFactor, EPMinusPSAR);
  5638. PSARArr.push([xVal[ind], toFixed(PSAR, decimals)]);
  5639. xData.push(xVal[ind]);
  5640. yData.push(toFixed(PSAR, decimals));
  5641. previousDirection = direction;
  5642. direction = newDirection;
  5643. extremePoint = newExtremePoint;
  5644. }
  5645. }
  5646. return {
  5647. values: PSARArr,
  5648. xData: xData,
  5649. yData: yData
  5650. };
  5651. }
  5652. });
  5653. /**
  5654. * A `PSAR` series. If the [type](#series.psar.type) option is not specified, it
  5655. * is inherited from [chart.type](#chart.type).
  5656. *
  5657. * @extends series,plotOptions.psar
  5658. * @since 6.0.0
  5659. * @product highstock
  5660. * @excluding dataParser, dataURL
  5661. * @requires stock/indicators/indicators
  5662. * @requires stock/indicators/psar
  5663. * @apioption series.psar
  5664. */
  5665. ''; // to include the above in the js output
  5666. });
  5667. _registerModule(_modules, 'Stock/Indicators/ROCIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  5668. /* *
  5669. *
  5670. * (c) 2010-2020 Kacper Madej
  5671. *
  5672. * License: www.highcharts.com/license
  5673. *
  5674. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  5675. *
  5676. * */
  5677. var isArray = U.isArray,
  5678. seriesType = U.seriesType;
  5679. /* eslint-disable require-jsdoc */
  5680. // Utils:
  5681. function populateAverage(xVal, yVal, i, period, index) {
  5682. /* Calculated as:
  5683. (Closing Price [today] - Closing Price [n days ago]) /
  5684. Closing Price [n days ago] * 100
  5685. Return y as null when avoiding division by zero */
  5686. var nDaysAgoY,
  5687. rocY;
  5688. if (index < 0) {
  5689. // y data given as an array of values
  5690. nDaysAgoY = yVal[i - period];
  5691. rocY = nDaysAgoY ?
  5692. (yVal[i] - nDaysAgoY) / nDaysAgoY * 100 :
  5693. null;
  5694. }
  5695. else {
  5696. // y data given as an array of arrays and the index should be used
  5697. nDaysAgoY = yVal[i - period][index];
  5698. rocY = nDaysAgoY ?
  5699. (yVal[i][index] - nDaysAgoY) / nDaysAgoY * 100 :
  5700. null;
  5701. }
  5702. return [xVal[i], rocY];
  5703. }
  5704. /* eslint-enable require-jsdoc */
  5705. /**
  5706. * The ROC series type.
  5707. *
  5708. * @private
  5709. * @class
  5710. * @name Highcharts.seriesTypes.roc
  5711. *
  5712. * @augments Highcharts.Series
  5713. */
  5714. seriesType('roc', 'sma',
  5715. /**
  5716. * Rate of change indicator (ROC). The indicator value for each point
  5717. * is defined as:
  5718. *
  5719. * `(C - Cn) / Cn * 100`
  5720. *
  5721. * where: `C` is the close value of the point of the same x in the
  5722. * linked series and `Cn` is the close value of the point `n` periods
  5723. * ago. `n` is set through [period](#plotOptions.roc.params.period).
  5724. *
  5725. * This series requires `linkedTo` option to be set.
  5726. *
  5727. * @sample stock/indicators/roc
  5728. * Rate of change indicator
  5729. *
  5730. * @extends plotOptions.sma
  5731. * @since 6.0.0
  5732. * @product highstock
  5733. * @requires stock/indicators/indicators
  5734. * @requires stock/indicators/roc
  5735. * @optionparent plotOptions.roc
  5736. */
  5737. {
  5738. params: {
  5739. index: 3,
  5740. period: 9
  5741. }
  5742. },
  5743. /**
  5744. * @lends Highcharts.Series#
  5745. */
  5746. {
  5747. nameBase: 'Rate of Change',
  5748. getValues: function (series, params) {
  5749. var period = params.period,
  5750. xVal = series.xData,
  5751. yVal = series.yData,
  5752. yValLen = yVal ? yVal.length : 0,
  5753. ROC = [],
  5754. xData = [],
  5755. yData = [],
  5756. i,
  5757. index = -1,
  5758. ROCPoint;
  5759. // Period is used as a number of time periods ago, so we need more
  5760. // (at least 1 more) data than the period value
  5761. if (xVal.length <= period) {
  5762. return;
  5763. }
  5764. // Switch index for OHLC / Candlestick / Arearange
  5765. if (isArray(yVal[0])) {
  5766. index = params.index;
  5767. }
  5768. // i = period <-- skip first N-points
  5769. // Calculate value one-by-one for each period in visible data
  5770. for (i = period; i < yValLen; i++) {
  5771. ROCPoint = populateAverage(xVal, yVal, i, period, index);
  5772. ROC.push(ROCPoint);
  5773. xData.push(ROCPoint[0]);
  5774. yData.push(ROCPoint[1]);
  5775. }
  5776. return {
  5777. values: ROC,
  5778. xData: xData,
  5779. yData: yData
  5780. };
  5781. }
  5782. });
  5783. /**
  5784. * A `ROC` series. If the [type](#series.wma.type) option is not
  5785. * specified, it is inherited from [chart.type](#chart.type).
  5786. *
  5787. * Rate of change indicator (ROC). The indicator value for each point
  5788. * is defined as:
  5789. *
  5790. * `(C - Cn) / Cn * 100`
  5791. *
  5792. * where: `C` is the close value of the point of the same x in the
  5793. * linked series and `Cn` is the close value of the point `n` periods
  5794. * ago. `n` is set through [period](#series.roc.params.period).
  5795. *
  5796. * This series requires `linkedTo` option to be set.
  5797. *
  5798. * @extends series,plotOptions.roc
  5799. * @since 6.0.0
  5800. * @product highstock
  5801. * @excluding dataParser, dataURL
  5802. * @requires stock/indicators/indicators
  5803. * @requires stock/indicators/roc
  5804. * @apioption series.roc
  5805. */
  5806. ''; // to include the above in the js output
  5807. });
  5808. _registerModule(_modules, 'Stock/Indicators/RSIIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  5809. /* *
  5810. *
  5811. * License: www.highcharts.com/license
  5812. *
  5813. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  5814. *
  5815. * */
  5816. var isArray = U.isArray,
  5817. seriesType = U.seriesType;
  5818. /* eslint-disable require-jsdoc */
  5819. // Utils:
  5820. function toFixed(a, n) {
  5821. return parseFloat(a.toFixed(n));
  5822. }
  5823. /* eslint-enable require-jsdoc */
  5824. /**
  5825. * The RSI series type.
  5826. *
  5827. * @private
  5828. * @class
  5829. * @name Highcharts.seriesTypes.rsi
  5830. *
  5831. * @augments Highcharts.Series
  5832. */
  5833. seriesType('rsi', 'sma',
  5834. /**
  5835. * Relative strength index (RSI) technical indicator. This series
  5836. * requires the `linkedTo` option to be set and should be loaded after
  5837. * the `stock/indicators/indicators.js` file.
  5838. *
  5839. * @sample stock/indicators/rsi
  5840. * RSI indicator
  5841. *
  5842. * @extends plotOptions.sma
  5843. * @since 6.0.0
  5844. * @product highstock
  5845. * @requires stock/indicators/indicators
  5846. * @requires stock/indicators/rsi
  5847. * @optionparent plotOptions.rsi
  5848. */
  5849. {
  5850. /**
  5851. * @excluding index
  5852. */
  5853. params: {
  5854. period: 14,
  5855. /**
  5856. * Number of maximum decimals that are used in RSI calculations.
  5857. */
  5858. decimals: 4
  5859. }
  5860. },
  5861. /**
  5862. * @lends Highcharts.Series#
  5863. */
  5864. {
  5865. getValues: function (series, params) {
  5866. var period = params.period,
  5867. xVal = series.xData,
  5868. yVal = series.yData,
  5869. yValLen = yVal ? yVal.length : 0,
  5870. decimals = params.decimals,
  5871. // RSI starts calculations from the second point
  5872. // Cause we need to calculate change between two points
  5873. range = 1,
  5874. RSI = [],
  5875. xData = [],
  5876. yData = [],
  5877. index = 3,
  5878. gain = 0,
  5879. loss = 0,
  5880. RSIPoint,
  5881. change,
  5882. avgGain,
  5883. avgLoss,
  5884. i;
  5885. // RSI requires close value
  5886. if ((xVal.length < period) || !isArray(yVal[0]) ||
  5887. yVal[0].length !== 4) {
  5888. return;
  5889. }
  5890. // Calculate changes for first N points
  5891. while (range < period) {
  5892. change = toFixed(yVal[range][index] - yVal[range - 1][index], decimals);
  5893. if (change > 0) {
  5894. gain += change;
  5895. }
  5896. else {
  5897. loss += Math.abs(change);
  5898. }
  5899. range++;
  5900. }
  5901. // Average for first n-1 points:
  5902. avgGain = toFixed(gain / (period - 1), decimals);
  5903. avgLoss = toFixed(loss / (period - 1), decimals);
  5904. for (i = range; i < yValLen; i++) {
  5905. change = toFixed(yVal[i][index] - yVal[i - 1][index], decimals);
  5906. if (change > 0) {
  5907. gain = change;
  5908. loss = 0;
  5909. }
  5910. else {
  5911. gain = 0;
  5912. loss = Math.abs(change);
  5913. }
  5914. // Calculate smoothed averages, RS, RSI values:
  5915. avgGain = toFixed((avgGain * (period - 1) + gain) / period, decimals);
  5916. avgLoss = toFixed((avgLoss * (period - 1) + loss) / period, decimals);
  5917. // If average-loss is equal zero, then by definition RSI is set
  5918. // to 100:
  5919. if (avgLoss === 0) {
  5920. RSIPoint = 100;
  5921. // If average-gain is equal zero, then by definition RSI is set
  5922. // to 0:
  5923. }
  5924. else if (avgGain === 0) {
  5925. RSIPoint = 0;
  5926. }
  5927. else {
  5928. RSIPoint = toFixed(100 - (100 / (1 + (avgGain / avgLoss))), decimals);
  5929. }
  5930. RSI.push([xVal[i], RSIPoint]);
  5931. xData.push(xVal[i]);
  5932. yData.push(RSIPoint);
  5933. }
  5934. return {
  5935. values: RSI,
  5936. xData: xData,
  5937. yData: yData
  5938. };
  5939. }
  5940. });
  5941. /**
  5942. * A `RSI` series. If the [type](#series.rsi.type) option is not
  5943. * specified, it is inherited from [chart.type](#chart.type).
  5944. *
  5945. * @extends series,plotOptions.rsi
  5946. * @since 6.0.0
  5947. * @product highstock
  5948. * @excluding dataParser, dataURL
  5949. * @requires stock/indicators/indicators
  5950. * @requires stock/indicators/rsi
  5951. * @apioption series.rsi
  5952. */
  5953. ''; // to include the above in the js output
  5954. });
  5955. _registerModule(_modules, 'Stock/Indicators/StochasticIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Mixins/ReduceArray.js'], _modules['Mixins/MultipleLines.js']], function (H, U, reduceArrayMixin, multipleLinesMixin) {
  5956. /* *
  5957. *
  5958. * License: www.highcharts.com/license
  5959. *
  5960. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  5961. *
  5962. * */
  5963. var isArray = U.isArray,
  5964. merge = U.merge,
  5965. seriesType = U.seriesType;
  5966. var SMA = H.seriesTypes.sma,
  5967. getArrayExtremes = reduceArrayMixin.getArrayExtremes;
  5968. /**
  5969. * The Stochastic series type.
  5970. *
  5971. * @private
  5972. * @class
  5973. * @name Highcharts.seriesTypes.stochastic
  5974. *
  5975. * @augments Highcharts.Series
  5976. */
  5977. seriesType('stochastic', 'sma',
  5978. /**
  5979. * Stochastic oscillator. This series requires the `linkedTo` option to be
  5980. * set and should be loaded after the `stock/indicators/indicators.js` file.
  5981. *
  5982. * @sample stock/indicators/stochastic
  5983. * Stochastic oscillator
  5984. *
  5985. * @extends plotOptions.sma
  5986. * @since 6.0.0
  5987. * @product highstock
  5988. * @excluding allAreas, colorAxis, joinBy, keys, navigatorOptions,
  5989. * pointInterval, pointIntervalUnit, pointPlacement,
  5990. * pointRange, pointStart, showInNavigator, stacking
  5991. * @requires stock/indicators/indicators
  5992. * @requires stock/indicators/stochastic
  5993. * @optionparent plotOptions.stochastic
  5994. */
  5995. {
  5996. /**
  5997. * @excluding index, period
  5998. */
  5999. params: {
  6000. /**
  6001. * Periods for Stochastic oscillator: [%K, %D].
  6002. *
  6003. * @type {Array<number,number>}
  6004. * @default [14, 3]
  6005. */
  6006. periods: [14, 3]
  6007. },
  6008. marker: {
  6009. enabled: false
  6010. },
  6011. tooltip: {
  6012. pointFormat: '<span style="color:{point.color}">\u25CF</span><b> {series.name}</b><br/>%K: {point.y}<br/>%D: {point.smoothed}<br/>'
  6013. },
  6014. /**
  6015. * Smoothed line options.
  6016. */
  6017. smoothedLine: {
  6018. /**
  6019. * Styles for a smoothed line.
  6020. */
  6021. styles: {
  6022. /**
  6023. * Pixel width of the line.
  6024. */
  6025. lineWidth: 1,
  6026. /**
  6027. * Color of the line. If not set, it's inherited from
  6028. * [plotOptions.stochastic.color
  6029. * ](#plotOptions.stochastic.color).
  6030. *
  6031. * @type {Highcharts.ColorString}
  6032. */
  6033. lineColor: void 0
  6034. }
  6035. },
  6036. dataGrouping: {
  6037. approximation: 'averages'
  6038. }
  6039. },
  6040. /**
  6041. * @lends Highcharts.Series#
  6042. */
  6043. merge(multipleLinesMixin, {
  6044. nameComponents: ['periods'],
  6045. nameBase: 'Stochastic',
  6046. pointArrayMap: ['y', 'smoothed'],
  6047. parallelArrays: ['x', 'y', 'smoothed'],
  6048. pointValKey: 'y',
  6049. linesApiNames: ['smoothedLine'],
  6050. init: function () {
  6051. SMA.prototype.init.apply(this, arguments);
  6052. // Set default color for lines:
  6053. this.options = merge({
  6054. smoothedLine: {
  6055. styles: {
  6056. lineColor: this.color
  6057. }
  6058. }
  6059. }, this.options);
  6060. },
  6061. getValues: function (series, params) {
  6062. var periodK = params.periods[0],
  6063. periodD = params.periods[1],
  6064. xVal = series.xData,
  6065. yVal = series.yData,
  6066. yValLen = yVal ? yVal.length : 0,
  6067. // 0- date, 1-%K, 2-%D
  6068. SO = [],
  6069. xData = [],
  6070. yData = [],
  6071. slicedY,
  6072. close = 3,
  6073. low = 2,
  6074. high = 1,
  6075. CL,
  6076. HL,
  6077. LL,
  6078. K,
  6079. D = null,
  6080. points,
  6081. extremes,
  6082. i;
  6083. // Stochastic requires close value
  6084. if (yValLen < periodK ||
  6085. !isArray(yVal[0]) ||
  6086. yVal[0].length !== 4) {
  6087. return;
  6088. }
  6089. // For a N-period, we start from N-1 point, to calculate Nth point
  6090. // That is why we later need to comprehend slice() elements list
  6091. // with (+1)
  6092. for (i = periodK - 1; i < yValLen; i++) {
  6093. slicedY = yVal.slice(i - periodK + 1, i + 1);
  6094. // Calculate %K
  6095. extremes = getArrayExtremes(slicedY, low, high);
  6096. LL = extremes[0]; // Lowest low in %K periods
  6097. CL = yVal[i][close] - LL;
  6098. HL = extremes[1] - LL;
  6099. K = CL / HL * 100;
  6100. xData.push(xVal[i]);
  6101. yData.push([K, null]);
  6102. // Calculate smoothed %D, which is SMA of %K
  6103. if (i >= (periodK - 1) + (periodD - 1)) {
  6104. points = SMA.prototype.getValues.call(this, {
  6105. xData: xData.slice(-periodD),
  6106. yData: yData.slice(-periodD)
  6107. }, {
  6108. period: periodD
  6109. });
  6110. D = points.yData[0];
  6111. }
  6112. SO.push([xVal[i], K, D]);
  6113. yData[yData.length - 1][1] = D;
  6114. }
  6115. return {
  6116. values: SO,
  6117. xData: xData,
  6118. yData: yData
  6119. };
  6120. }
  6121. }));
  6122. /**
  6123. * A Stochastic indicator. If the [type](#series.stochastic.type) option is not
  6124. * specified, it is inherited from [chart.type](#chart.type).
  6125. *
  6126. * @extends series,plotOptions.stochastic
  6127. * @since 6.0.0
  6128. * @product highstock
  6129. * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
  6130. * navigatorOptions, pointInterval, pointIntervalUnit,
  6131. * pointPlacement, pointRange, pointStart, showInNavigator, stacking
  6132. * @requires stock/indicators/indicators
  6133. * @requires stock/indicators/stochastic
  6134. * @apioption series.stochastic
  6135. */
  6136. ''; // to include the above in the js output
  6137. });
  6138. _registerModule(_modules, 'Stock/Indicators/SlowStochasticIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Mixins/IndicatorRequired.js']], function (H, U, requiredIndicator) {
  6139. /* *
  6140. *
  6141. * License: www.highcharts.com/license
  6142. *
  6143. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  6144. *
  6145. * */
  6146. var seriesType = U.seriesType;
  6147. var seriesTypes = H.seriesTypes;
  6148. /**
  6149. * The Slow Stochastic series type.
  6150. *
  6151. * @private
  6152. * @class
  6153. * @name Highcharts.seriesTypes.slowstochastic
  6154. *
  6155. * @augments Highcharts.Series
  6156. */
  6157. seriesType('slowstochastic', 'stochastic',
  6158. /**
  6159. * Slow Stochastic oscillator. This series requires the `linkedTo` option
  6160. * to be set and should be loaded after `stock/indicators/indicators.js`
  6161. * and `stock/indicators/stochastic.js` files.
  6162. *
  6163. * @sample stock/indicators/slow-stochastic
  6164. * Slow Stochastic oscillator
  6165. *
  6166. * @extends plotOptions.stochastic
  6167. * @since 8.0.0
  6168. * @product highstock
  6169. * @requires stock/indicators/indicators
  6170. * @requires stock/indicators/stochastic
  6171. * @requires stock/indicators/slowstochastic
  6172. * @optionparent plotOptions.slowstochastic
  6173. */
  6174. {
  6175. params: {
  6176. /**
  6177. * Periods for Slow Stochastic oscillator: [%K, %D, SMA(%D)].
  6178. *
  6179. * @type {Array<number,number,number>}
  6180. * @default [14, 3, 3]
  6181. */
  6182. periods: [14, 3, 3]
  6183. }
  6184. },
  6185. /**
  6186. * @lends Highcharts.Series#
  6187. */
  6188. {
  6189. nameBase: 'Slow Stochastic',
  6190. init: function () {
  6191. var args = arguments,
  6192. ctx = this;
  6193. requiredIndicator.isParentLoaded(H.seriesTypes.stochastic, 'stochastic', ctx.type, function (indicator) {
  6194. indicator.prototype.init.apply(ctx, args);
  6195. return;
  6196. });
  6197. },
  6198. getValues: function (series, params) {
  6199. var periods = params.periods,
  6200. fastValues = seriesTypes.stochastic.prototype.getValues.call(this,
  6201. series,
  6202. params),
  6203. slowValues = {
  6204. values: [],
  6205. xData: [],
  6206. yData: []
  6207. };
  6208. var i = 0;
  6209. if (!fastValues) {
  6210. return;
  6211. }
  6212. slowValues.xData = fastValues.xData.slice(periods[1] - 1);
  6213. var fastYData = fastValues.yData.slice(periods[1] - 1);
  6214. // Get SMA(%D)
  6215. var smoothedValues = seriesTypes.sma.prototype.getValues.call(this, {
  6216. xData: slowValues.xData,
  6217. yData: fastYData
  6218. }, {
  6219. index: 1,
  6220. period: periods[2]
  6221. });
  6222. if (!smoothedValues) {
  6223. return;
  6224. }
  6225. var xDataLen = slowValues.xData.length;
  6226. // Format data
  6227. for (; i < xDataLen; i++) {
  6228. slowValues.yData[i] = [
  6229. fastYData[i][1],
  6230. smoothedValues.yData[i - periods[2] + 1] || null
  6231. ];
  6232. slowValues.values[i] = [
  6233. slowValues.xData[i],
  6234. fastYData[i][1],
  6235. smoothedValues.yData[i - periods[2] + 1] || null
  6236. ];
  6237. }
  6238. return slowValues;
  6239. }
  6240. });
  6241. /**
  6242. * A Slow Stochastic indicator. If the [type](#series.slowstochastic.type)
  6243. * option is not specified, it is inherited from [chart.type](#chart.type).
  6244. *
  6245. * @extends series,plotOptions.slowstochastic
  6246. * @since 8.0.0
  6247. * @product highstock
  6248. * @requires stock/indicators/indicators
  6249. * @requires stock/indicators/stochastic
  6250. * @requires stock/indicators/slowstochastic
  6251. * @apioption series.slowstochastic
  6252. */
  6253. ''; // to include the above in the js output
  6254. });
  6255. _registerModule(_modules, 'Stock/Indicators/SupertrendIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js']], function (H, U) {
  6256. /* *
  6257. *
  6258. * License: www.highcharts.com/license
  6259. *
  6260. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  6261. *
  6262. * */
  6263. var correctFloat = U.correctFloat,
  6264. merge = U.merge,
  6265. seriesType = U.seriesType;
  6266. var isArray = U.isArray,
  6267. objectEach = U.objectEach;
  6268. var ATR = H.seriesTypes.atr,
  6269. SMA = H.seriesTypes.sma;
  6270. /* eslint-disable require-jsdoc */
  6271. // Utils:
  6272. function createPointObj(mainSeries, index, close) {
  6273. return {
  6274. index: index,
  6275. close: mainSeries.yData[index][close],
  6276. x: mainSeries.xData[index]
  6277. };
  6278. }
  6279. /* eslint-enable require-jsdoc */
  6280. /**
  6281. * The Supertrend series type.
  6282. *
  6283. * @private
  6284. * @class
  6285. * @name Highcharts.seriesTypes.supertrend
  6286. *
  6287. * @augments Highcharts.Series
  6288. */
  6289. seriesType('supertrend', 'sma',
  6290. /**
  6291. * Supertrend indicator. This series requires the `linkedTo` option to be
  6292. * set and should be loaded after the `stock/indicators/indicators.js` and
  6293. * `stock/indicators/sma.js`.
  6294. *
  6295. * @sample {highstock} stock/indicators/supertrend
  6296. * Supertrend indicator
  6297. *
  6298. * @extends plotOptions.sma
  6299. * @since 7.0.0
  6300. * @product highstock
  6301. * @excluding allAreas, cropThreshold, negativeColor, colorAxis, joinBy,
  6302. * keys, navigatorOptions, pointInterval, pointIntervalUnit,
  6303. * pointPlacement, pointRange, pointStart, showInNavigator,
  6304. * stacking, threshold
  6305. * @requires stock/indicators/indicators
  6306. * @requires stock/indicators/supertrend
  6307. * @optionparent plotOptions.supertrend
  6308. */
  6309. {
  6310. /**
  6311. * Paramters used in calculation of Supertrend indicator series points.
  6312. *
  6313. * @excluding index
  6314. */
  6315. params: {
  6316. /**
  6317. * Multiplier for Supertrend Indicator.
  6318. */
  6319. multiplier: 3,
  6320. /**
  6321. * The base period for indicator Supertrend Indicator calculations.
  6322. * This is the number of data points which are taken into account
  6323. * for the indicator calculations.
  6324. */
  6325. period: 10
  6326. },
  6327. /**
  6328. * Color of the Supertrend series line that is beneath the main series.
  6329. *
  6330. * @sample {highstock} stock/indicators/supertrend/
  6331. * Example with risingTrendColor
  6332. *
  6333. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6334. */
  6335. risingTrendColor: '#06B535',
  6336. /**
  6337. * Color of the Supertrend series line that is above the main series.
  6338. *
  6339. * @sample {highstock} stock/indicators/supertrend/
  6340. * Example with fallingTrendColor
  6341. *
  6342. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  6343. */
  6344. fallingTrendColor: '#F21313',
  6345. /**
  6346. * The styles for the Supertrend line that intersect main series.
  6347. *
  6348. * @sample {highstock} stock/indicators/supertrend/
  6349. * Example with changeTrendLine
  6350. */
  6351. changeTrendLine: {
  6352. styles: {
  6353. /**
  6354. * Pixel width of the line.
  6355. */
  6356. lineWidth: 1,
  6357. /**
  6358. * Color of the line.
  6359. *
  6360. * @type {Highcharts.ColorString}
  6361. */
  6362. lineColor: '#333333',
  6363. /**
  6364. * The dash or dot style of the grid lines. For possible
  6365. * values, see
  6366. * [this demonstration](https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/series-dashstyle-all/).
  6367. *
  6368. * @sample {highcharts} highcharts/yaxis/gridlinedashstyle/
  6369. * Long dashes
  6370. * @sample {highstock} stock/xaxis/gridlinedashstyle/
  6371. * Long dashes
  6372. *
  6373. * @type {Highcharts.DashStyleValue}
  6374. * @since 7.0.0
  6375. */
  6376. dashStyle: 'LongDash'
  6377. }
  6378. }
  6379. },
  6380. /**
  6381. * @lends Highcharts.Series.prototype
  6382. */
  6383. {
  6384. nameBase: 'Supertrend',
  6385. nameComponents: ['multiplier', 'period'],
  6386. requiredIndicators: ['atr'],
  6387. init: function () {
  6388. var options,
  6389. parentOptions;
  6390. SMA.prototype.init.apply(this, arguments);
  6391. options = this.options;
  6392. parentOptions = this.linkedParent.options;
  6393. // Indicator cropThreshold has to be equal linked series one
  6394. // reduced by period due to points comparison in drawGraph method
  6395. // (#9787)
  6396. options.cropThreshold = (parentOptions.cropThreshold -
  6397. (options.params.period - 1));
  6398. },
  6399. drawGraph: function () {
  6400. var indicator = this,
  6401. indicOptions = indicator.options,
  6402. // Series that indicator is linked to
  6403. mainSeries = indicator.linkedParent,
  6404. mainLinePoints = (mainSeries ? mainSeries.points : []),
  6405. indicPoints = indicator.points,
  6406. indicPath = indicator.graph,
  6407. indicPointsLen = indicPoints.length,
  6408. // Points offset between lines
  6409. tempOffset = mainLinePoints.length - indicPointsLen,
  6410. offset = tempOffset > 0 ? tempOffset : 0,
  6411. // @todo: fix when ichi-moku indicator is merged to master.
  6412. gappedExtend = {
  6413. options: {
  6414. gapSize: indicOptions.gapSize
  6415. }
  6416. },
  6417. // Sorted supertrend points array
  6418. groupedPoitns = {
  6419. top: [],
  6420. bottom: [],
  6421. intersect: [] // Change trend line points
  6422. },
  6423. // Options for trend lines
  6424. supertrendLineOptions = {
  6425. top: {
  6426. styles: {
  6427. lineWidth: indicOptions.lineWidth,
  6428. lineColor: (indicOptions.fallingTrendColor ||
  6429. indicOptions.color),
  6430. dashStyle: indicOptions.dashStyle
  6431. }
  6432. },
  6433. bottom: {
  6434. styles: {
  6435. lineWidth: indicOptions.lineWidth,
  6436. lineColor: (indicOptions.risingTrendColor ||
  6437. indicOptions.color),
  6438. dashStyle: indicOptions.dashStyle
  6439. }
  6440. },
  6441. intersect: indicOptions.changeTrendLine
  6442. },
  6443. close = 3,
  6444. // Supertrend line point
  6445. point,
  6446. // Supertrend line next point (has smaller x pos than point)
  6447. nextPoint,
  6448. // Main series points
  6449. mainPoint,
  6450. nextMainPoint,
  6451. // Used when supertrend and main points are shifted
  6452. // relative to each other
  6453. prevMainPoint,
  6454. prevPrevMainPoint,
  6455. // Used when particular point color is set
  6456. pointColor,
  6457. // Temporary points that fill groupedPoitns array
  6458. newPoint,
  6459. newNextPoint;
  6460. // Loop which sort supertrend points
  6461. while (indicPointsLen--) {
  6462. point = indicPoints[indicPointsLen];
  6463. nextPoint = indicPoints[indicPointsLen - 1];
  6464. mainPoint = mainLinePoints[indicPointsLen - 1 + offset];
  6465. nextMainPoint = mainLinePoints[indicPointsLen - 2 + offset];
  6466. prevMainPoint = mainLinePoints[indicPointsLen + offset];
  6467. prevPrevMainPoint = mainLinePoints[indicPointsLen + offset + 1];
  6468. pointColor = point.options.color;
  6469. newPoint = {
  6470. x: point.x,
  6471. plotX: point.plotX,
  6472. plotY: point.plotY,
  6473. isNull: false
  6474. };
  6475. // When mainPoint is the last one (left plot area edge)
  6476. // but supertrend has additional one
  6477. if (!nextMainPoint &&
  6478. mainPoint && mainSeries.yData[mainPoint.index - 1]) {
  6479. nextMainPoint = createPointObj(mainSeries, mainPoint.index - 1, close);
  6480. }
  6481. // When prevMainPoint is the last one (right plot area edge)
  6482. // but supertrend has additional one (and points are shifted)
  6483. if (!prevPrevMainPoint &&
  6484. prevMainPoint && mainSeries.yData[prevMainPoint.index + 1]) {
  6485. prevPrevMainPoint = createPointObj(mainSeries, prevMainPoint.index + 1, close);
  6486. }
  6487. // When points are shifted (right or left plot area edge)
  6488. if (!mainPoint &&
  6489. nextMainPoint && mainSeries.yData[nextMainPoint.index + 1]) {
  6490. mainPoint = createPointObj(mainSeries, nextMainPoint.index + 1, close);
  6491. }
  6492. else if (!mainPoint &&
  6493. prevMainPoint && mainSeries.yData[prevMainPoint.index - 1]) {
  6494. mainPoint = createPointObj(mainSeries, prevMainPoint.index - 1, close);
  6495. }
  6496. // Check if points are shifted relative to each other
  6497. if (point &&
  6498. mainPoint &&
  6499. prevMainPoint &&
  6500. nextMainPoint &&
  6501. point.x !== mainPoint.x) {
  6502. if (point.x === prevMainPoint.x) {
  6503. nextMainPoint = mainPoint;
  6504. mainPoint = prevMainPoint;
  6505. }
  6506. else if (point.x === nextMainPoint.x) {
  6507. mainPoint = nextMainPoint;
  6508. nextMainPoint = {
  6509. close: mainSeries.yData[mainPoint.index - 1][close],
  6510. x: mainSeries.xData[mainPoint.index - 1]
  6511. };
  6512. }
  6513. else if (prevPrevMainPoint && point.x === prevPrevMainPoint.x) {
  6514. mainPoint = prevPrevMainPoint;
  6515. nextMainPoint = prevMainPoint;
  6516. }
  6517. }
  6518. if (nextPoint && nextMainPoint && mainPoint) {
  6519. newNextPoint = {
  6520. x: nextPoint.x,
  6521. plotX: nextPoint.plotX,
  6522. plotY: nextPoint.plotY,
  6523. isNull: false
  6524. };
  6525. if (point.y >= mainPoint.close &&
  6526. nextPoint.y >= nextMainPoint.close) {
  6527. point.color = (pointColor || indicOptions.fallingTrendColor ||
  6528. indicOptions.color);
  6529. groupedPoitns.top.push(newPoint);
  6530. }
  6531. else if (point.y < mainPoint.close &&
  6532. nextPoint.y < nextMainPoint.close) {
  6533. point.color = (pointColor || indicOptions.risingTrendColor ||
  6534. indicOptions.color);
  6535. groupedPoitns.bottom.push(newPoint);
  6536. }
  6537. else {
  6538. groupedPoitns.intersect.push(newPoint);
  6539. groupedPoitns.intersect.push(newNextPoint);
  6540. // Additional null point to make a gap in line
  6541. groupedPoitns.intersect.push(merge(newNextPoint, {
  6542. isNull: true
  6543. }));
  6544. if (point.y >= mainPoint.close &&
  6545. nextPoint.y < nextMainPoint.close) {
  6546. point.color = (pointColor || indicOptions.fallingTrendColor ||
  6547. indicOptions.color);
  6548. nextPoint.color = (pointColor || indicOptions.risingTrendColor ||
  6549. indicOptions.color);
  6550. groupedPoitns.top.push(newPoint);
  6551. groupedPoitns.top.push(merge(newNextPoint, {
  6552. isNull: true
  6553. }));
  6554. }
  6555. else if (point.y < mainPoint.close &&
  6556. nextPoint.y >= nextMainPoint.close) {
  6557. point.color = (pointColor || indicOptions.risingTrendColor ||
  6558. indicOptions.color);
  6559. nextPoint.color = (pointColor || indicOptions.fallingTrendColor ||
  6560. indicOptions.color);
  6561. groupedPoitns.bottom.push(newPoint);
  6562. groupedPoitns.bottom.push(merge(newNextPoint, {
  6563. isNull: true
  6564. }));
  6565. }
  6566. }
  6567. }
  6568. else if (mainPoint) {
  6569. if (point.y >= mainPoint.close) {
  6570. point.color = (pointColor || indicOptions.fallingTrendColor ||
  6571. indicOptions.color);
  6572. groupedPoitns.top.push(newPoint);
  6573. }
  6574. else {
  6575. point.color = (pointColor || indicOptions.risingTrendColor ||
  6576. indicOptions.color);
  6577. groupedPoitns.bottom.push(newPoint);
  6578. }
  6579. }
  6580. }
  6581. // Generate lines:
  6582. objectEach(groupedPoitns, function (values, lineName) {
  6583. indicator.points = values;
  6584. indicator.options = merge(supertrendLineOptions[lineName].styles, gappedExtend);
  6585. indicator.graph = indicator['graph' + lineName + 'Line'];
  6586. SMA.prototype.drawGraph.call(indicator);
  6587. // Now save line
  6588. indicator['graph' + lineName + 'Line'] = indicator.graph;
  6589. });
  6590. // Restore options:
  6591. indicator.points = indicPoints;
  6592. indicator.options = indicOptions;
  6593. indicator.graph = indicPath;
  6594. },
  6595. // Supertrend (Multiplier, Period) Formula:
  6596. // BASIC UPPERBAND = (HIGH + LOW) / 2 + Multiplier * ATR(Period)
  6597. // BASIC LOWERBAND = (HIGH + LOW) / 2 - Multiplier * ATR(Period)
  6598. // FINAL UPPERBAND =
  6599. // IF(
  6600. // Current BASICUPPERBAND < Previous FINAL UPPERBAND AND
  6601. // Previous Close > Previous FINAL UPPERBAND
  6602. // ) THEN (Current BASIC UPPERBAND)
  6603. // ELSE (Previous FINALUPPERBAND)
  6604. // FINAL LOWERBAND =
  6605. // IF(
  6606. // Current BASIC LOWERBAND > Previous FINAL LOWERBAND AND
  6607. // Previous Close < Previous FINAL LOWERBAND
  6608. // ) THEN (Current BASIC LOWERBAND)
  6609. // ELSE (Previous FINAL LOWERBAND)
  6610. // SUPERTREND =
  6611. // IF(
  6612. // Previous Supertrend == Previous FINAL UPPERBAND AND
  6613. // Current Close < Current FINAL UPPERBAND
  6614. // ) THAN Current FINAL UPPERBAND
  6615. // ELSE IF(
  6616. // Previous Supertrend == Previous FINAL LOWERBAND AND
  6617. // Current Close < Current FINAL LOWERBAND
  6618. // ) THAN Current FINAL UPPERBAND
  6619. // ELSE IF(
  6620. // Previous Supertrend == Previous FINAL UPPERBAND AND
  6621. // Current Close > Current FINAL UPPERBAND
  6622. // ) THAN Current FINAL LOWERBAND
  6623. // ELSE IF(
  6624. // Previous Supertrend == Previous FINAL LOWERBAND AND
  6625. // Current Close > Current FINAL LOWERBAND
  6626. // ) THAN Current FINAL LOWERBAND
  6627. getValues: function (series, params) {
  6628. var period = params.period,
  6629. multiplier = params.multiplier,
  6630. xVal = series.xData,
  6631. yVal = series.yData,
  6632. ATRData = [],
  6633. // 0- date, 1- Supertrend indicator
  6634. ST = [],
  6635. xData = [],
  6636. yData = [],
  6637. close = 3,
  6638. low = 2,
  6639. high = 1,
  6640. periodsOffset = (period === 0) ? 0 : period - 1,
  6641. basicUp,
  6642. basicDown,
  6643. finalUp = [],
  6644. finalDown = [],
  6645. supertrend,
  6646. prevFinalUp,
  6647. prevFinalDown,
  6648. prevST, // previous Supertrend
  6649. prevY,
  6650. y,
  6651. i;
  6652. if ((xVal.length <= period) || !isArray(yVal[0]) ||
  6653. yVal[0].length !== 4 || period < 0) {
  6654. return;
  6655. }
  6656. ATRData = ATR.prototype.getValues.call(this, series, {
  6657. period: period
  6658. }).yData;
  6659. for (i = 0; i < ATRData.length; i++) {
  6660. y = yVal[periodsOffset + i];
  6661. prevY = yVal[periodsOffset + i - 1] || [];
  6662. prevFinalUp = finalUp[i - 1];
  6663. prevFinalDown = finalDown[i - 1];
  6664. prevST = yData[i - 1];
  6665. if (i === 0) {
  6666. prevFinalUp = prevFinalDown = prevST = 0;
  6667. }
  6668. basicUp = correctFloat((y[high] + y[low]) / 2 + multiplier * ATRData[i]);
  6669. basicDown = correctFloat((y[high] + y[low]) / 2 - multiplier * ATRData[i]);
  6670. if ((basicUp < prevFinalUp) ||
  6671. (prevY[close] > prevFinalUp)) {
  6672. finalUp[i] = basicUp;
  6673. }
  6674. else {
  6675. finalUp[i] = prevFinalUp;
  6676. }
  6677. if ((basicDown > prevFinalDown) ||
  6678. (prevY[close] < prevFinalDown)) {
  6679. finalDown[i] = basicDown;
  6680. }
  6681. else {
  6682. finalDown[i] = prevFinalDown;
  6683. }
  6684. if (prevST === prevFinalUp && y[close] < finalUp[i] ||
  6685. prevST === prevFinalDown && y[close] < finalDown[i]) {
  6686. supertrend = finalUp[i];
  6687. }
  6688. else if (prevST === prevFinalUp && y[close] > finalUp[i] ||
  6689. prevST === prevFinalDown && y[close] > finalDown[i]) {
  6690. supertrend = finalDown[i];
  6691. }
  6692. ST.push([xVal[periodsOffset + i], supertrend]);
  6693. xData.push(xVal[periodsOffset + i]);
  6694. yData.push(supertrend);
  6695. }
  6696. return {
  6697. values: ST,
  6698. xData: xData,
  6699. yData: yData
  6700. };
  6701. }
  6702. });
  6703. /**
  6704. * A `Supertrend indicator` series. If the [type](#series.supertrend.type)
  6705. * option is not specified, it is inherited from [chart.type](#chart.type).
  6706. *
  6707. * @extends series,plotOptions.supertrend
  6708. * @since 7.0.0
  6709. * @product highstock
  6710. * @excluding allAreas, colorAxis, cropThreshold, data, dataParser, dataURL,
  6711. * joinBy, keys, navigatorOptions, negativeColor, pointInterval,
  6712. * pointIntervalUnit, pointPlacement, pointRange, pointStart,
  6713. * showInNavigator, stacking, threshold
  6714. * @requires stock/indicators/indicators
  6715. * @requires stock/indicators/supertrend
  6716. * @apioption series.supertrend
  6717. */
  6718. ''; // to include the above in the js output
  6719. });
  6720. _registerModule(_modules, 'Stock/Indicators/VBPIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Series/Point.js'], _modules['Core/Utilities.js']], function (H, Point, U) {
  6721. /* *
  6722. *
  6723. * (c) 2010-2020 Paweł Dalek
  6724. *
  6725. * Volume By Price (VBP) indicator for Highstock
  6726. *
  6727. * License: www.highcharts.com/license
  6728. *
  6729. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  6730. *
  6731. * */
  6732. var addEvent = U.addEvent,
  6733. animObject = U.animObject,
  6734. arrayMax = U.arrayMax,
  6735. arrayMin = U.arrayMin,
  6736. correctFloat = U.correctFloat,
  6737. error = U.error,
  6738. extend = U.extend,
  6739. isArray = U.isArray,
  6740. seriesType = U.seriesType;
  6741. /* eslint-disable require-jsdoc */
  6742. // Utils
  6743. function arrayExtremesOHLC(data) {
  6744. var dataLength = data.length,
  6745. min = data[0][3],
  6746. max = min,
  6747. i = 1,
  6748. currentPoint;
  6749. for (; i < dataLength; i++) {
  6750. currentPoint = data[i][3];
  6751. if (currentPoint < min) {
  6752. min = currentPoint;
  6753. }
  6754. if (currentPoint > max) {
  6755. max = currentPoint;
  6756. }
  6757. }
  6758. return {
  6759. min: min,
  6760. max: max
  6761. };
  6762. }
  6763. /* eslint-enable require-jsdoc */
  6764. var abs = Math.abs,
  6765. noop = H.noop,
  6766. columnPrototype = H.seriesTypes.column.prototype;
  6767. /**
  6768. * The Volume By Price (VBP) series type.
  6769. *
  6770. * @private
  6771. * @class
  6772. * @name Highcharts.seriesTypes.vbp
  6773. *
  6774. * @augments Highcharts.Series
  6775. */
  6776. seriesType('vbp', 'sma',
  6777. /**
  6778. * Volume By Price indicator.
  6779. *
  6780. * This series requires `linkedTo` option to be set.
  6781. *
  6782. * @sample stock/indicators/volume-by-price
  6783. * Volume By Price indicator
  6784. *
  6785. * @extends plotOptions.sma
  6786. * @since 6.0.0
  6787. * @product highstock
  6788. * @requires stock/indicators/indicators
  6789. * @requires stock/indicators/volume-by-price
  6790. * @optionparent plotOptions.vbp
  6791. */
  6792. {
  6793. /**
  6794. * @excluding index, period
  6795. */
  6796. params: {
  6797. /**
  6798. * The number of price zones.
  6799. */
  6800. ranges: 12,
  6801. /**
  6802. * The id of volume series which is mandatory. For example using
  6803. * OHLC data, volumeSeriesID='volume' means the indicator will be
  6804. * calculated using OHLC and volume values.
  6805. */
  6806. volumeSeriesID: 'volume'
  6807. },
  6808. /**
  6809. * The styles for lines which determine price zones.
  6810. */
  6811. zoneLines: {
  6812. /**
  6813. * Enable/disable zone lines.
  6814. */
  6815. enabled: true,
  6816. /**
  6817. * Specify the style of zone lines.
  6818. *
  6819. * @type {Highcharts.CSSObject}
  6820. * @default {"color": "#0A9AC9", "dashStyle": "LongDash", "lineWidth": 1}
  6821. */
  6822. styles: {
  6823. /** @ignore-options */
  6824. color: '#0A9AC9',
  6825. /** @ignore-options */
  6826. dashStyle: 'LongDash',
  6827. /** @ignore-options */
  6828. lineWidth: 1
  6829. }
  6830. },
  6831. /**
  6832. * The styles for bars when volume is divided into positive/negative.
  6833. */
  6834. volumeDivision: {
  6835. /**
  6836. * Option to control if volume is divided.
  6837. */
  6838. enabled: true,
  6839. styles: {
  6840. /**
  6841. * Color of positive volume bars.
  6842. *
  6843. * @type {Highcharts.ColorString}
  6844. */
  6845. positiveColor: 'rgba(144, 237, 125, 0.8)',
  6846. /**
  6847. * Color of negative volume bars.
  6848. *
  6849. * @type {Highcharts.ColorString}
  6850. */
  6851. negativeColor: 'rgba(244, 91, 91, 0.8)'
  6852. }
  6853. },
  6854. // To enable series animation; must be animationLimit > pointCount
  6855. animationLimit: 1000,
  6856. enableMouseTracking: false,
  6857. pointPadding: 0,
  6858. zIndex: -1,
  6859. crisp: true,
  6860. dataGrouping: {
  6861. enabled: false
  6862. },
  6863. dataLabels: {
  6864. allowOverlap: true,
  6865. enabled: true,
  6866. format: 'P: {point.volumePos:.2f} | N: {point.volumeNeg:.2f}',
  6867. padding: 0,
  6868. style: {
  6869. /** @internal */
  6870. fontSize: '7px'
  6871. },
  6872. verticalAlign: 'top'
  6873. }
  6874. },
  6875. /**
  6876. * @lends Highcharts.Series#
  6877. */
  6878. {
  6879. nameBase: 'Volume by Price',
  6880. bindTo: {
  6881. series: false,
  6882. eventName: 'afterSetExtremes'
  6883. },
  6884. calculateOn: 'render',
  6885. markerAttribs: noop,
  6886. drawGraph: noop,
  6887. getColumnMetrics: columnPrototype.getColumnMetrics,
  6888. crispCol: columnPrototype.crispCol,
  6889. init: function (chart) {
  6890. var indicator = this,
  6891. params,
  6892. baseSeries,
  6893. volumeSeries;
  6894. H.seriesTypes.sma.prototype.init.apply(indicator, arguments);
  6895. params = indicator.options.params;
  6896. baseSeries = indicator.linkedParent;
  6897. volumeSeries = chart.get(params.volumeSeriesID);
  6898. indicator.addCustomEvents(baseSeries, volumeSeries);
  6899. return indicator;
  6900. },
  6901. // Adds events related with removing series
  6902. addCustomEvents: function (baseSeries, volumeSeries) {
  6903. var indicator = this;
  6904. /* eslint-disable require-jsdoc */
  6905. function toEmptyIndicator() {
  6906. indicator.chart.redraw();
  6907. indicator.setData([]);
  6908. indicator.zoneStarts = [];
  6909. if (indicator.zoneLinesSVG) {
  6910. indicator.zoneLinesSVG.destroy();
  6911. delete indicator.zoneLinesSVG;
  6912. }
  6913. }
  6914. /* eslint-enable require-jsdoc */
  6915. // If base series is deleted, indicator series data is filled with
  6916. // an empty array
  6917. indicator.dataEventsToUnbind.push(addEvent(baseSeries, 'remove', function () {
  6918. toEmptyIndicator();
  6919. }));
  6920. // If volume series is deleted, indicator series data is filled with
  6921. // an empty array
  6922. if (volumeSeries) {
  6923. indicator.dataEventsToUnbind.push(addEvent(volumeSeries, 'remove', function () {
  6924. toEmptyIndicator();
  6925. }));
  6926. }
  6927. return indicator;
  6928. },
  6929. // Initial animation
  6930. animate: function (init) {
  6931. var series = this,
  6932. inverted = series.chart.inverted,
  6933. group = series.group,
  6934. attr = {},
  6935. translate,
  6936. position;
  6937. if (!init && group) {
  6938. translate = inverted ? 'translateY' : 'translateX';
  6939. position = inverted ? series.yAxis.top : series.xAxis.left;
  6940. group['forceAnimate:' + translate] = true;
  6941. attr[translate] = position;
  6942. group.animate(attr, extend(animObject(series.options.animation), {
  6943. step: function (val, fx) {
  6944. series.group.attr({
  6945. scaleX: Math.max(0.001, fx.pos)
  6946. });
  6947. }
  6948. }));
  6949. }
  6950. },
  6951. drawPoints: function () {
  6952. var indicator = this;
  6953. if (indicator.options.volumeDivision.enabled) {
  6954. indicator.posNegVolume(true, true);
  6955. columnPrototype.drawPoints.apply(indicator, arguments);
  6956. indicator.posNegVolume(false, false);
  6957. }
  6958. columnPrototype.drawPoints.apply(indicator, arguments);
  6959. },
  6960. // Function responsible for dividing volume into positive and negative
  6961. posNegVolume: function (initVol, pos) {
  6962. var indicator = this, signOrder = pos ?
  6963. ['positive', 'negative'] :
  6964. ['negative', 'positive'], volumeDivision = indicator.options.volumeDivision, pointLength = indicator.points.length, posWidths = [], negWidths = [], i = 0, pointWidth, priceZone, wholeVol, point;
  6965. if (initVol) {
  6966. indicator.posWidths = posWidths;
  6967. indicator.negWidths = negWidths;
  6968. }
  6969. else {
  6970. posWidths = indicator.posWidths;
  6971. negWidths = indicator.negWidths;
  6972. }
  6973. for (; i < pointLength; i++) {
  6974. point = indicator.points[i];
  6975. point[signOrder[0] + 'Graphic'] = point.graphic;
  6976. point.graphic = point[signOrder[1] + 'Graphic'];
  6977. if (initVol) {
  6978. pointWidth = point.shapeArgs.width;
  6979. priceZone = indicator.priceZones[i];
  6980. wholeVol = priceZone.wholeVolumeData;
  6981. if (wholeVol) {
  6982. posWidths.push(pointWidth / wholeVol * priceZone.positiveVolumeData);
  6983. negWidths.push(pointWidth / wholeVol * priceZone.negativeVolumeData);
  6984. }
  6985. else {
  6986. posWidths.push(0);
  6987. negWidths.push(0);
  6988. }
  6989. }
  6990. point.color = pos ?
  6991. volumeDivision.styles.positiveColor :
  6992. volumeDivision.styles.negativeColor;
  6993. point.shapeArgs.width = pos ?
  6994. indicator.posWidths[i] :
  6995. indicator.negWidths[i];
  6996. point.shapeArgs.x = pos ?
  6997. point.shapeArgs.x :
  6998. indicator.posWidths[i];
  6999. }
  7000. },
  7001. translate: function () {
  7002. var indicator = this,
  7003. options = indicator.options,
  7004. chart = indicator.chart,
  7005. yAxis = indicator.yAxis,
  7006. yAxisMin = yAxis.min,
  7007. zoneLinesOptions = indicator.options.zoneLines,
  7008. priceZones = (indicator.priceZones),
  7009. yBarOffset = 0,
  7010. indicatorPoints,
  7011. volumeDataArray,
  7012. maxVolume,
  7013. primalBarWidth,
  7014. barHeight,
  7015. barHeightP,
  7016. oldBarHeight,
  7017. barWidth,
  7018. pointPadding,
  7019. chartPlotTop,
  7020. barX,
  7021. barY;
  7022. columnPrototype.translate.apply(indicator);
  7023. indicatorPoints = indicator.points;
  7024. // Do translate operation when points exist
  7025. if (indicatorPoints.length) {
  7026. pointPadding = options.pointPadding < 0.5 ?
  7027. options.pointPadding :
  7028. 0.1;
  7029. volumeDataArray = indicator.volumeDataArray;
  7030. maxVolume = arrayMax(volumeDataArray);
  7031. primalBarWidth = chart.plotWidth / 2;
  7032. chartPlotTop = chart.plotTop;
  7033. barHeight = abs(yAxis.toPixels(yAxisMin) -
  7034. yAxis.toPixels(yAxisMin + indicator.rangeStep));
  7035. oldBarHeight = abs(yAxis.toPixels(yAxisMin) -
  7036. yAxis.toPixels(yAxisMin + indicator.rangeStep));
  7037. if (pointPadding) {
  7038. barHeightP = abs(barHeight * (1 - 2 * pointPadding));
  7039. yBarOffset = abs((barHeight - barHeightP) / 2);
  7040. barHeight = abs(barHeightP);
  7041. }
  7042. indicatorPoints.forEach(function (point, index) {
  7043. barX = point.barX = point.plotX = 0;
  7044. barY = point.plotY = (yAxis.toPixels(priceZones[index].start) -
  7045. chartPlotTop -
  7046. (yAxis.reversed ?
  7047. (barHeight - oldBarHeight) :
  7048. barHeight) -
  7049. yBarOffset);
  7050. barWidth = correctFloat(primalBarWidth *
  7051. priceZones[index].wholeVolumeData / maxVolume);
  7052. point.pointWidth = barWidth;
  7053. point.shapeArgs = indicator.crispCol.apply(// eslint-disable-line no-useless-call
  7054. indicator, [barX, barY, barWidth, barHeight]);
  7055. point.volumeNeg = priceZones[index].negativeVolumeData;
  7056. point.volumePos = priceZones[index].positiveVolumeData;
  7057. point.volumeAll = priceZones[index].wholeVolumeData;
  7058. });
  7059. if (zoneLinesOptions.enabled) {
  7060. indicator.drawZones(chart, yAxis, indicator.zoneStarts, zoneLinesOptions.styles);
  7061. }
  7062. }
  7063. },
  7064. getValues: function (series, params) {
  7065. var indicator = this,
  7066. xValues = series.processedXData,
  7067. yValues = series.processedYData,
  7068. chart = indicator.chart,
  7069. ranges = params.ranges,
  7070. VBP = [],
  7071. xData = [],
  7072. yData = [],
  7073. isOHLC,
  7074. volumeSeries,
  7075. priceZones;
  7076. // Checks if base series exists
  7077. if (!series.chart) {
  7078. error('Base series not found! In case it has been removed, add ' +
  7079. 'a new one.', true, chart);
  7080. return;
  7081. }
  7082. // Checks if volume series exists
  7083. if (!(volumeSeries = (chart.get(params.volumeSeriesID)))) {
  7084. error('Series ' +
  7085. params.volumeSeriesID +
  7086. ' not found! Check `volumeSeriesID`.', true, chart);
  7087. return;
  7088. }
  7089. // Checks if series data fits the OHLC format
  7090. isOHLC = isArray(yValues[0]);
  7091. if (isOHLC && yValues[0].length !== 4) {
  7092. error('Type of ' +
  7093. series.name +
  7094. ' series is different than line, OHLC or candlestick.', true, chart);
  7095. return;
  7096. }
  7097. // Price zones contains all the information about the zones (index,
  7098. // start, end, volumes, etc.)
  7099. priceZones = indicator.priceZones = indicator.specifyZones(isOHLC, xValues, yValues, ranges, volumeSeries);
  7100. priceZones.forEach(function (zone, index) {
  7101. VBP.push([zone.x, zone.end]);
  7102. xData.push(VBP[index][0]);
  7103. yData.push(VBP[index][1]);
  7104. });
  7105. return {
  7106. values: VBP,
  7107. xData: xData,
  7108. yData: yData
  7109. };
  7110. },
  7111. // Specifing where each zone should start ans end
  7112. specifyZones: function (isOHLC, xValues, yValues, ranges, volumeSeries) {
  7113. var indicator = this,
  7114. rangeExtremes = (isOHLC ? arrayExtremesOHLC(yValues) : false),
  7115. lowRange = rangeExtremes ?
  7116. rangeExtremes.min :
  7117. arrayMin(yValues),
  7118. highRange = rangeExtremes ?
  7119. rangeExtremes.max :
  7120. arrayMax(yValues),
  7121. zoneStarts = indicator.zoneStarts = [],
  7122. priceZones = [],
  7123. i = 0,
  7124. j = 1,
  7125. rangeStep,
  7126. zoneStartsLength;
  7127. if (!lowRange || !highRange) {
  7128. if (this.points.length) {
  7129. this.setData([]);
  7130. this.zoneStarts = [];
  7131. this.zoneLinesSVG.destroy();
  7132. }
  7133. return [];
  7134. }
  7135. rangeStep = indicator.rangeStep =
  7136. correctFloat(highRange - lowRange) / ranges;
  7137. zoneStarts.push(lowRange);
  7138. for (; i < ranges - 1; i++) {
  7139. zoneStarts.push(correctFloat(zoneStarts[i] + rangeStep));
  7140. }
  7141. zoneStarts.push(highRange);
  7142. zoneStartsLength = zoneStarts.length;
  7143. // Creating zones
  7144. for (; j < zoneStartsLength; j++) {
  7145. priceZones.push({
  7146. index: j - 1,
  7147. x: xValues[0],
  7148. start: zoneStarts[j - 1],
  7149. end: zoneStarts[j]
  7150. });
  7151. }
  7152. return indicator.volumePerZone(isOHLC, priceZones, volumeSeries, xValues, yValues);
  7153. },
  7154. // Calculating sum of volume values for a specific zone
  7155. volumePerZone: function (isOHLC, priceZones, volumeSeries, xValues, yValues) {
  7156. var indicator = this,
  7157. volumeXData = volumeSeries.processedXData,
  7158. volumeYData = volumeSeries.processedYData,
  7159. lastZoneIndex = priceZones.length - 1,
  7160. baseSeriesLength = yValues.length,
  7161. volumeSeriesLength = volumeYData.length,
  7162. previousValue,
  7163. startFlag,
  7164. endFlag,
  7165. value,
  7166. i;
  7167. // Checks if each point has a corresponding volume value
  7168. if (abs(baseSeriesLength - volumeSeriesLength)) {
  7169. // If the first point don't have volume, add 0 value at the
  7170. // beggining of the volume array
  7171. if (xValues[0] !== volumeXData[0]) {
  7172. volumeYData.unshift(0);
  7173. }
  7174. // If the last point don't have volume, add 0 value at the end
  7175. // of the volume array
  7176. if (xValues[baseSeriesLength - 1] !==
  7177. volumeXData[volumeSeriesLength - 1]) {
  7178. volumeYData.push(0);
  7179. }
  7180. }
  7181. indicator.volumeDataArray = [];
  7182. priceZones.forEach(function (zone) {
  7183. zone.wholeVolumeData = 0;
  7184. zone.positiveVolumeData = 0;
  7185. zone.negativeVolumeData = 0;
  7186. for (i = 0; i < baseSeriesLength; i++) {
  7187. startFlag = false;
  7188. endFlag = false;
  7189. value = isOHLC ? yValues[i][3] : yValues[i];
  7190. previousValue = i ?
  7191. (isOHLC ?
  7192. yValues[i - 1][3] :
  7193. yValues[i - 1]) :
  7194. value;
  7195. // Checks if this is the point with the
  7196. // lowest close value and if so, adds it calculations
  7197. if (value <= zone.start && zone.index === 0) {
  7198. startFlag = true;
  7199. }
  7200. // Checks if this is the point with the highest
  7201. // close value and if so, adds it calculations
  7202. if (value >= zone.end && zone.index === lastZoneIndex) {
  7203. endFlag = true;
  7204. }
  7205. if ((value > zone.start || startFlag) &&
  7206. (value < zone.end || endFlag)) {
  7207. zone.wholeVolumeData += volumeYData[i];
  7208. if (previousValue > value) {
  7209. zone.negativeVolumeData += volumeYData[i];
  7210. }
  7211. else {
  7212. zone.positiveVolumeData += volumeYData[i];
  7213. }
  7214. }
  7215. }
  7216. indicator.volumeDataArray.push(zone.wholeVolumeData);
  7217. });
  7218. return priceZones;
  7219. },
  7220. // Function responsoble for drawing additional lines indicating zones
  7221. drawZones: function (chart, yAxis, zonesValues, zonesStyles) {
  7222. var indicator = this,
  7223. renderer = chart.renderer,
  7224. zoneLinesSVG = indicator.zoneLinesSVG,
  7225. zoneLinesPath = [],
  7226. leftLinePos = 0,
  7227. rightLinePos = chart.plotWidth,
  7228. verticalOffset = chart.plotTop,
  7229. verticalLinePos;
  7230. zonesValues.forEach(function (value) {
  7231. verticalLinePos = yAxis.toPixels(value) - verticalOffset;
  7232. zoneLinesPath = zoneLinesPath.concat(chart.renderer.crispLine([[
  7233. 'M',
  7234. leftLinePos,
  7235. verticalLinePos
  7236. ], [
  7237. 'L',
  7238. rightLinePos,
  7239. verticalLinePos
  7240. ]], zonesStyles.lineWidth));
  7241. });
  7242. // Create zone lines one path or update it while animating
  7243. if (zoneLinesSVG) {
  7244. zoneLinesSVG.animate({
  7245. d: zoneLinesPath
  7246. });
  7247. }
  7248. else {
  7249. zoneLinesSVG = indicator.zoneLinesSVG =
  7250. renderer.path(zoneLinesPath).attr({
  7251. 'stroke-width': zonesStyles.lineWidth,
  7252. 'stroke': zonesStyles.color,
  7253. 'dashstyle': zonesStyles.dashStyle,
  7254. 'zIndex': indicator.group.zIndex + 0.1
  7255. })
  7256. .add(indicator.group);
  7257. }
  7258. }
  7259. },
  7260. /**
  7261. * @lends Highcharts.Point#
  7262. */
  7263. {
  7264. // Required for destroying negative part of volume
  7265. destroy: function () {
  7266. // @todo: this.negativeGraphic doesn't seem to be used anywhere
  7267. if (this.negativeGraphic) {
  7268. this.negativeGraphic = this.negativeGraphic.destroy();
  7269. }
  7270. return Point.prototype.destroy.apply(this, arguments);
  7271. }
  7272. });
  7273. /**
  7274. * A `Volume By Price (VBP)` series. If the [type](#series.vbp.type) option is
  7275. * not specified, it is inherited from [chart.type](#chart.type).
  7276. *
  7277. * @extends series,plotOptions.vbp
  7278. * @since 6.0.0
  7279. * @product highstock
  7280. * @excluding dataParser, dataURL
  7281. * @requires stock/indicators/indicators
  7282. * @requires stock/indicators/volume-by-price
  7283. * @apioption series.vbp
  7284. */
  7285. ''; // to include the above in the js output
  7286. });
  7287. _registerModule(_modules, 'Stock/Indicators/VWAPIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  7288. /* *
  7289. *
  7290. * (c) 2010-2020 Paweł Dalek
  7291. *
  7292. * Volume Weighted Average Price (VWAP) indicator for Highstock
  7293. *
  7294. * License: www.highcharts.com/license
  7295. *
  7296. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  7297. *
  7298. * */
  7299. var error = U.error,
  7300. isArray = U.isArray,
  7301. seriesType = U.seriesType;
  7302. /**
  7303. * The Volume Weighted Average Price (VWAP) series type.
  7304. *
  7305. * @private
  7306. * @class
  7307. * @name Highcharts.seriesTypes.vwap
  7308. *
  7309. * @augments Highcharts.Series
  7310. */
  7311. seriesType('vwap', 'sma',
  7312. /**
  7313. * Volume Weighted Average Price indicator.
  7314. *
  7315. * This series requires `linkedTo` option to be set.
  7316. *
  7317. * @sample stock/indicators/vwap
  7318. * Volume Weighted Average Price indicator
  7319. *
  7320. * @extends plotOptions.sma
  7321. * @since 6.0.0
  7322. * @product highstock
  7323. * @requires stock/indicators/indicators
  7324. * @requires stock/indicators/vwap
  7325. * @optionparent plotOptions.vwap
  7326. */
  7327. {
  7328. /**
  7329. * @excluding index
  7330. */
  7331. params: {
  7332. period: 30,
  7333. /**
  7334. * The id of volume series which is mandatory. For example using
  7335. * OHLC data, volumeSeriesID='volume' means the indicator will be
  7336. * calculated using OHLC and volume values.
  7337. */
  7338. volumeSeriesID: 'volume'
  7339. }
  7340. },
  7341. /**
  7342. * @lends Highcharts.Series#
  7343. */
  7344. {
  7345. /**
  7346. * Returns the final values of the indicator ready to be presented on a
  7347. * chart
  7348. * @private
  7349. * @param {Highcharts.VWAPIndicator} this indicator
  7350. * @param {Highcharts.Series} series - series for indicator
  7351. * @param {object} params - params
  7352. * @return {object} - computed VWAP
  7353. **/
  7354. getValues: function (series, params) {
  7355. var indicator = this,
  7356. chart = series.chart,
  7357. xValues = series.xData,
  7358. yValues = series.yData,
  7359. period = params.period,
  7360. isOHLC = true,
  7361. volumeSeries;
  7362. // Checks if volume series exists
  7363. if (!(volumeSeries = (chart.get(params.volumeSeriesID)))) {
  7364. error('Series ' +
  7365. params.volumeSeriesID +
  7366. ' not found! Check `volumeSeriesID`.', true, chart);
  7367. return;
  7368. }
  7369. // Checks if series data fits the OHLC format
  7370. if (!(isArray(yValues[0]))) {
  7371. isOHLC = false;
  7372. }
  7373. return indicator.calculateVWAPValues(isOHLC, xValues, yValues, volumeSeries, period);
  7374. },
  7375. /**
  7376. * Main algorithm used to calculate Volume Weighted Average Price (VWAP)
  7377. * values
  7378. * @private
  7379. * @param {boolean} isOHLC - says if data has OHLC format
  7380. * @param {Array<number>} xValues - array of timestamps
  7381. * @param {Array<number|Array<number,number,number,number>>} yValues -
  7382. * array of yValues, can be an array of a four arrays (OHLC) or array of
  7383. * values (line)
  7384. * @param {Array<*>} volumeSeries - volume series
  7385. * @param {number} period - number of points to be calculated
  7386. * @return {object} - Object contains computed VWAP
  7387. **/
  7388. calculateVWAPValues: function (isOHLC, xValues, yValues, volumeSeries, period) {
  7389. var volumeValues = volumeSeries.yData,
  7390. volumeLength = volumeSeries.xData.length,
  7391. pointsLength = xValues.length,
  7392. cumulativePrice = [],
  7393. cumulativeVolume = [],
  7394. xData = [],
  7395. yData = [],
  7396. VWAP = [],
  7397. commonLength,
  7398. typicalPrice,
  7399. cPrice,
  7400. cVolume,
  7401. i,
  7402. j;
  7403. if (pointsLength <= volumeLength) {
  7404. commonLength = pointsLength;
  7405. }
  7406. else {
  7407. commonLength = volumeLength;
  7408. }
  7409. for (i = 0, j = 0; i < commonLength; i++) {
  7410. // Depending on whether series is OHLC or line type, price is
  7411. // average of the high, low and close or a simple value
  7412. typicalPrice = isOHLC ?
  7413. ((yValues[i][1] + yValues[i][2] +
  7414. yValues[i][3]) / 3) :
  7415. yValues[i];
  7416. typicalPrice *= volumeValues[i];
  7417. cPrice = j ?
  7418. (cumulativePrice[i - 1] + typicalPrice) :
  7419. typicalPrice;
  7420. cVolume = j ?
  7421. (cumulativeVolume[i - 1] + volumeValues[i]) :
  7422. volumeValues[i];
  7423. cumulativePrice.push(cPrice);
  7424. cumulativeVolume.push(cVolume);
  7425. VWAP.push([xValues[i], (cPrice / cVolume)]);
  7426. xData.push(VWAP[i][0]);
  7427. yData.push(VWAP[i][1]);
  7428. j++;
  7429. if (j === period) {
  7430. j = 0;
  7431. }
  7432. }
  7433. return {
  7434. values: VWAP,
  7435. xData: xData,
  7436. yData: yData
  7437. };
  7438. }
  7439. });
  7440. /**
  7441. * A `Volume Weighted Average Price (VWAP)` series. If the
  7442. * [type](#series.vwap.type) option is not specified, it is inherited from
  7443. * [chart.type](#chart.type).
  7444. *
  7445. * @extends series,plotOptions.vwap
  7446. * @since 6.0.0
  7447. * @product highstock
  7448. * @excluding dataParser, dataURL
  7449. * @requires stock/indicators/indicators
  7450. * @requires stock/indicators/vwap
  7451. * @apioption series.vwap
  7452. */
  7453. ''; // to include the above in the js output
  7454. });
  7455. _registerModule(_modules, 'Stock/Indicators/WilliamsRIndicator.js', [_modules['Core/Utilities.js'], _modules['Mixins/ReduceArray.js']], function (U, reduceArrayMixin) {
  7456. /* *
  7457. *
  7458. * License: www.highcharts.com/license
  7459. *
  7460. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  7461. *
  7462. * */
  7463. var isArray = U.isArray,
  7464. seriesType = U.seriesType;
  7465. var getArrayExtremes = reduceArrayMixin.getArrayExtremes;
  7466. /**
  7467. * The Williams %R series type.
  7468. *
  7469. * @private
  7470. * @class
  7471. * @name Highcharts.seriesTypes.williamsr
  7472. *
  7473. * @augments Highcharts.Series
  7474. */
  7475. seriesType('williamsr', 'sma',
  7476. /**
  7477. * Williams %R. This series requires the `linkedTo` option to be
  7478. * set and should be loaded after the `stock/indicators/indicators.js`.
  7479. *
  7480. * @sample {highstock} stock/indicators/williams-r
  7481. * Williams %R
  7482. *
  7483. * @extends plotOptions.sma
  7484. * @since 7.0.0
  7485. * @product highstock
  7486. * @excluding allAreas, colorAxis, joinBy, keys, navigatorOptions,
  7487. * pointInterval, pointIntervalUnit, pointPlacement,
  7488. * pointRange, pointStart, showInNavigator, stacking
  7489. * @requires stock/indicators/indicators
  7490. * @requires stock/indicators/williams-r
  7491. * @optionparent plotOptions.williamsr
  7492. */
  7493. {
  7494. /**
  7495. * Paramters used in calculation of Williams %R series points.
  7496. * @excluding index
  7497. */
  7498. params: {
  7499. /**
  7500. * Period for Williams %R oscillator
  7501. */
  7502. period: 14
  7503. }
  7504. },
  7505. /**
  7506. * @lends Highcharts.Series#
  7507. */
  7508. {
  7509. nameBase: 'Williams %R',
  7510. getValues: function (series, params) {
  7511. var period = params.period,
  7512. xVal = series.xData,
  7513. yVal = series.yData,
  7514. yValLen = yVal ? yVal.length : 0,
  7515. WR = [], // 0- date, 1- Williams %R
  7516. xData = [],
  7517. yData = [],
  7518. slicedY,
  7519. close = 3,
  7520. low = 2,
  7521. high = 1,
  7522. extremes,
  7523. R,
  7524. HH, // Highest high value in period
  7525. LL, // Lowest low value in period
  7526. CC, // Current close value
  7527. i;
  7528. // Williams %R requires close value
  7529. if (xVal.length < period ||
  7530. !isArray(yVal[0]) ||
  7531. yVal[0].length !== 4) {
  7532. return;
  7533. }
  7534. // For a N-period, we start from N-1 point, to calculate Nth point
  7535. // That is why we later need to comprehend slice() elements list
  7536. // with (+1)
  7537. for (i = period - 1; i < yValLen; i++) {
  7538. slicedY = yVal.slice(i - period + 1, i + 1);
  7539. extremes = getArrayExtremes(slicedY, low, high);
  7540. LL = extremes[0];
  7541. HH = extremes[1];
  7542. CC = yVal[i][close];
  7543. R = ((HH - CC) / (HH - LL)) * -100;
  7544. if (xVal[i]) {
  7545. WR.push([xVal[i], R]);
  7546. xData.push(xVal[i]);
  7547. yData.push(R);
  7548. }
  7549. }
  7550. return {
  7551. values: WR,
  7552. xData: xData,
  7553. yData: yData
  7554. };
  7555. }
  7556. });
  7557. /**
  7558. * A `Williams %R Oscillator` series. If the [type](#series.williamsr.type)
  7559. * option is not specified, it is inherited from [chart.type](#chart.type).
  7560. *
  7561. * @extends series,plotOptions.williamsr
  7562. * @since 7.0.0
  7563. * @product highstock
  7564. * @excluding allAreas, colorAxis, dataParser, dataURL, joinBy, keys,
  7565. * navigatorOptions, pointInterval, pointIntervalUnit,
  7566. * pointPlacement, pointRange, pointStart, showInNavigator, stacking
  7567. * @requires stock/indicators/indicators
  7568. * @requires stock/indicators/williams-r
  7569. * @apioption series.williamsr
  7570. */
  7571. ''; // adds doclets above to the transpiled file
  7572. });
  7573. _registerModule(_modules, 'Stock/Indicators/WMAIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  7574. /* *
  7575. *
  7576. * (c) 2010-2020 Kacper Madej
  7577. *
  7578. * License: www.highcharts.com/license
  7579. *
  7580. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  7581. *
  7582. * */
  7583. var isArray = U.isArray,
  7584. seriesType = U.seriesType;
  7585. /* eslint-disable valid-jsdoc */
  7586. // Utils:
  7587. /**
  7588. * @private
  7589. */
  7590. function accumulateAverage(points, xVal, yVal, i, index) {
  7591. var xValue = xVal[i],
  7592. yValue = index < 0 ? yVal[i] : yVal[i][index];
  7593. points.push([xValue, yValue]);
  7594. }
  7595. /**
  7596. * @private
  7597. */
  7598. function weightedSumArray(array, pLen) {
  7599. // The denominator is the sum of the number of days as a triangular number.
  7600. // If there are 5 days, the triangular numbers are 5, 4, 3, 2, and 1.
  7601. // The sum is 5 + 4 + 3 + 2 + 1 = 15.
  7602. var denominator = (pLen + 1) / 2 * pLen;
  7603. // reduce VS loop => reduce
  7604. return array.reduce(function (prev, cur, i) {
  7605. return [null, prev[1] + cur[1] * (i + 1)];
  7606. })[1] / denominator;
  7607. }
  7608. /**
  7609. * @private
  7610. */
  7611. function populateAverage(points, xVal, yVal, i) {
  7612. var pLen = points.length,
  7613. wmaY = weightedSumArray(points,
  7614. pLen),
  7615. wmaX = xVal[i - 1];
  7616. points.shift(); // remove point until range < period
  7617. return [wmaX, wmaY];
  7618. }
  7619. /* eslint-enable valid-jsdoc */
  7620. /**
  7621. * The SMA series type.
  7622. *
  7623. * @private
  7624. * @class
  7625. * @name Highcharts.seriesTypes.wma
  7626. *
  7627. * @augments Highcharts.Series
  7628. */
  7629. seriesType('wma', 'sma',
  7630. /**
  7631. * Weighted moving average indicator (WMA). This series requires `linkedTo`
  7632. * option to be set.
  7633. *
  7634. * @sample stock/indicators/wma
  7635. * Weighted moving average indicator
  7636. *
  7637. * @extends plotOptions.sma
  7638. * @since 6.0.0
  7639. * @product highstock
  7640. * @requires stock/indicators/indicators
  7641. * @requires stock/indicators/wma
  7642. * @optionparent plotOptions.wma
  7643. */
  7644. {
  7645. params: {
  7646. index: 3,
  7647. period: 9
  7648. }
  7649. },
  7650. /**
  7651. * @lends Highcharts.Series#
  7652. */
  7653. {
  7654. getValues: function (series, params) {
  7655. var period = params.period,
  7656. xVal = series.xData,
  7657. yVal = series.yData,
  7658. yValLen = yVal ? yVal.length : 0,
  7659. range = 1,
  7660. xValue = xVal[0],
  7661. yValue = yVal[0],
  7662. WMA = [],
  7663. xData = [],
  7664. yData = [],
  7665. index = -1,
  7666. i,
  7667. points,
  7668. WMAPoint;
  7669. if (xVal.length < period) {
  7670. return;
  7671. }
  7672. // Switch index for OHLC / Candlestick
  7673. if (isArray(yVal[0])) {
  7674. index = params.index;
  7675. yValue = yVal[0][index];
  7676. }
  7677. // Starting point
  7678. points = [[xValue, yValue]];
  7679. // Accumulate first N-points
  7680. while (range !== period) {
  7681. accumulateAverage(points, xVal, yVal, range, index);
  7682. range++;
  7683. }
  7684. // Calculate value one-by-one for each period in visible data
  7685. for (i = range; i < yValLen; i++) {
  7686. WMAPoint = populateAverage(points, xVal, yVal, i);
  7687. WMA.push(WMAPoint);
  7688. xData.push(WMAPoint[0]);
  7689. yData.push(WMAPoint[1]);
  7690. accumulateAverage(points, xVal, yVal, i, index);
  7691. }
  7692. WMAPoint = populateAverage(points, xVal, yVal, i);
  7693. WMA.push(WMAPoint);
  7694. xData.push(WMAPoint[0]);
  7695. yData.push(WMAPoint[1]);
  7696. return {
  7697. values: WMA,
  7698. xData: xData,
  7699. yData: yData
  7700. };
  7701. }
  7702. });
  7703. /**
  7704. * A `WMA` series. If the [type](#series.wma.type) option is not specified, it
  7705. * is inherited from [chart.type](#chart.type).
  7706. *
  7707. * @extends series,plotOptions.wma
  7708. * @since 6.0.0
  7709. * @product highstock
  7710. * @excluding dataParser, dataURL
  7711. * @requires stock/indicators/indicators
  7712. * @requires stock/indicators/wma
  7713. * @apioption series.wma
  7714. */
  7715. ''; // adds doclet above to the transpiled file
  7716. });
  7717. _registerModule(_modules, 'Stock/Indicators/ZigzagIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  7718. /* *
  7719. *
  7720. * (c) 2010-2020 Kacper Madej
  7721. *
  7722. * License: www.highcharts.com/license
  7723. *
  7724. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  7725. *
  7726. * */
  7727. var seriesType = U.seriesType;
  7728. var UNDEFINED;
  7729. /**
  7730. * The Zig Zag series type.
  7731. *
  7732. * @private
  7733. * @class
  7734. * @name Highcharts.seriesTypes.zigzag
  7735. *
  7736. * @augments Highcharts.Series
  7737. */
  7738. seriesType('zigzag', 'sma',
  7739. /**
  7740. * Zig Zag indicator.
  7741. *
  7742. * This series requires `linkedTo` option to be set.
  7743. *
  7744. * @sample stock/indicators/zigzag
  7745. * Zig Zag indicator
  7746. *
  7747. * @extends plotOptions.sma
  7748. * @since 6.0.0
  7749. * @product highstock
  7750. * @requires stock/indicators/indicators
  7751. * @requires stock/indicators/zigzag
  7752. * @optionparent plotOptions.zigzag
  7753. */
  7754. {
  7755. /**
  7756. * @excluding index, period
  7757. */
  7758. params: {
  7759. /**
  7760. * The point index which indicator calculations will base - low
  7761. * value.
  7762. *
  7763. * For example using OHLC data, index=2 means the indicator will be
  7764. * calculated using Low values.
  7765. */
  7766. lowIndex: 2,
  7767. /**
  7768. * The point index which indicator calculations will base - high
  7769. * value.
  7770. *
  7771. * For example using OHLC data, index=1 means the indicator will be
  7772. * calculated using High values.
  7773. */
  7774. highIndex: 1,
  7775. /**
  7776. * The threshold for the value change.
  7777. *
  7778. * For example deviation=1 means the indicator will ignore all price
  7779. * movements less than 1%.
  7780. */
  7781. deviation: 1
  7782. }
  7783. },
  7784. /**
  7785. * @lends Highcharts.Series#
  7786. */
  7787. {
  7788. nameComponents: ['deviation'],
  7789. nameSuffixes: ['%'],
  7790. nameBase: 'Zig Zag',
  7791. getValues: function (series, params) {
  7792. var lowIndex = params.lowIndex,
  7793. highIndex = params.highIndex,
  7794. deviation = params.deviation / 100,
  7795. deviations = {
  7796. 'low': 1 + deviation,
  7797. 'high': 1 - deviation
  7798. },
  7799. xVal = series.xData,
  7800. yVal = series.yData,
  7801. yValLen = yVal ? yVal.length : 0,
  7802. zigzag = [],
  7803. xData = [],
  7804. yData = [],
  7805. i,
  7806. j,
  7807. zigzagPoint,
  7808. firstZigzagLow,
  7809. firstZigzagHigh,
  7810. directionUp,
  7811. zigzagLen,
  7812. exitLoop = false,
  7813. yIndex = false;
  7814. // Exit if not enught points or no low or high values
  7815. if (!xVal || xVal.length <= 1 ||
  7816. (yValLen &&
  7817. (yVal[0][lowIndex] === UNDEFINED ||
  7818. yVal[0][highIndex] === UNDEFINED))) {
  7819. return;
  7820. }
  7821. // Set first zigzag point candidate
  7822. firstZigzagLow = yVal[0][lowIndex];
  7823. firstZigzagHigh = yVal[0][highIndex];
  7824. // Search for a second zigzag point candidate,
  7825. // this will also set first zigzag point
  7826. for (i = 1; i < yValLen; i++) {
  7827. // requried change to go down
  7828. if (yVal[i][lowIndex] <= firstZigzagHigh * deviations.high) {
  7829. zigzag.push([xVal[0], firstZigzagHigh]);
  7830. // second zigzag point candidate
  7831. zigzagPoint = [xVal[i], yVal[i][lowIndex]];
  7832. // next line will be going up
  7833. directionUp = true;
  7834. exitLoop = true;
  7835. // requried change to go up
  7836. }
  7837. else if (yVal[i][highIndex] >= firstZigzagLow * deviations.low) {
  7838. zigzag.push([xVal[0], firstZigzagLow]);
  7839. // second zigzag point candidate
  7840. zigzagPoint = [xVal[i], yVal[i][highIndex]];
  7841. // next line will be going down
  7842. directionUp = false;
  7843. exitLoop = true;
  7844. }
  7845. if (exitLoop) {
  7846. xData.push(zigzag[0][0]);
  7847. yData.push(zigzag[0][1]);
  7848. j = i++;
  7849. i = yValLen;
  7850. }
  7851. }
  7852. // Search for next zigzags
  7853. for (i = j; i < yValLen; i++) {
  7854. if (directionUp) { // next line up
  7855. // lower when going down -> change zigzag candidate
  7856. if (yVal[i][lowIndex] <= zigzagPoint[1]) {
  7857. zigzagPoint = [xVal[i], yVal[i][lowIndex]];
  7858. }
  7859. // requried change to go down -> new zigzagpoint and
  7860. // direction change
  7861. if (yVal[i][highIndex] >=
  7862. zigzagPoint[1] * deviations.low) {
  7863. yIndex = highIndex;
  7864. }
  7865. }
  7866. else { // next line down
  7867. // higher when going up -> change zigzag candidate
  7868. if (yVal[i][highIndex] >= zigzagPoint[1]) {
  7869. zigzagPoint = [xVal[i], yVal[i][highIndex]];
  7870. }
  7871. // requried change to go down -> new zigzagpoint and
  7872. // direction change
  7873. if (yVal[i][lowIndex] <=
  7874. zigzagPoint[1] * deviations.high) {
  7875. yIndex = lowIndex;
  7876. }
  7877. }
  7878. if (yIndex !== false) { // new zigzag point and direction change
  7879. zigzag.push(zigzagPoint);
  7880. xData.push(zigzagPoint[0]);
  7881. yData.push(zigzagPoint[1]);
  7882. zigzagPoint = [xVal[i], yVal[i][yIndex]];
  7883. directionUp = !directionUp;
  7884. yIndex = false;
  7885. }
  7886. }
  7887. zigzagLen = zigzag.length;
  7888. // no zigzag for last point
  7889. if (zigzagLen !== 0 &&
  7890. zigzag[zigzagLen - 1][0] < xVal[yValLen - 1]) {
  7891. // set last point from zigzag candidate
  7892. zigzag.push(zigzagPoint);
  7893. xData.push(zigzagPoint[0]);
  7894. yData.push(zigzagPoint[1]);
  7895. }
  7896. return {
  7897. values: zigzag,
  7898. xData: xData,
  7899. yData: yData
  7900. };
  7901. }
  7902. });
  7903. /**
  7904. * A `Zig Zag` series. If the [type](#series.zigzag.type) option is not
  7905. * specified, it is inherited from [chart.type](#chart.type).
  7906. *
  7907. * @extends series,plotOptions.zigzag
  7908. * @since 6.0.0
  7909. * @product highstock
  7910. * @excluding dataParser, dataURL
  7911. * @requires stock/indicators/indicators
  7912. * @requires stock/indicators/zigzag
  7913. * @apioption series.zigzag
  7914. */
  7915. ''; // adds doclets above to transpiled file
  7916. });
  7917. _registerModule(_modules, 'Stock/Indicators/RegressionIndicators.js', [_modules['Core/Utilities.js']], function (U) {
  7918. /**
  7919. *
  7920. * (c) 2010-2020 Kamil Kulig
  7921. *
  7922. * License: www.highcharts.com/license
  7923. *
  7924. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  7925. *
  7926. * */
  7927. var isArray = U.isArray,
  7928. seriesType = U.seriesType;
  7929. /**
  7930. * Linear regression series type.
  7931. *
  7932. * @private
  7933. * @class
  7934. * @name Highcharts.seriesTypes.linearregression
  7935. *
  7936. * @augments Highcharts.Series
  7937. */
  7938. seriesType('linearRegression', 'sma',
  7939. /**
  7940. * Linear regression indicator. This series requires `linkedTo` option to be
  7941. * set.
  7942. *
  7943. * @sample {highstock} stock/indicators/linear-regression
  7944. * Linear regression indicator
  7945. *
  7946. * @extends plotOptions.sma
  7947. * @since 7.0.0
  7948. * @product highstock
  7949. * @requires stock/indicators/indicators
  7950. * @requires stock/indicators/regressions
  7951. * @optionparent plotOptions.linearregression
  7952. */
  7953. {
  7954. params: {
  7955. /**
  7956. * Unit (in milliseconds) for the x axis distances used to compute
  7957. * the regression line paramters (slope & intercept) for every
  7958. * range. In Highstock the x axis values are always represented in
  7959. * milliseconds which may cause that distances between points are
  7960. * "big" integer numbers.
  7961. *
  7962. * Highstock's linear regression algorithm (least squares method)
  7963. * will utilize these "big" integers for finding the slope and the
  7964. * intercept of the regression line for each period. In consequence,
  7965. * this value may be a very "small" decimal number that's hard to
  7966. * interpret by a human.
  7967. *
  7968. * For instance: `xAxisUnit` equealed to `86400000` ms (1 day)
  7969. * forces the algorithm to treat `86400000` as `1` while computing
  7970. * the slope and the intercept. This may enchance the legiblitity of
  7971. * the indicator's values.
  7972. *
  7973. * Default value is the closest distance between two data points.
  7974. *
  7975. * @sample {highstock} stock/plotoptions/linear-regression-xaxisunit
  7976. * xAxisUnit set to 1 minute
  7977. *
  7978. * @example
  7979. * // In Liniear Regression Slope Indicator series `xAxisUnit` is
  7980. * // `86400000` (1 day) and period is `3`. There're 3 points in the
  7981. * // base series:
  7982. *
  7983. * data: [
  7984. * [Date.UTC(2020, 0, 1), 1],
  7985. * [Date.UTC(2020, 0, 2), 3],
  7986. * [Date.UTC(2020, 0, 3), 5]
  7987. * ]
  7988. *
  7989. * // This will produce one point in the indicator series that has a
  7990. * // `y` value of `2` (slope of the regression line). If we change
  7991. * // the `xAxisUnit` to `1` (ms) the value of the indicator's point
  7992. * // will be `2.3148148148148148e-8` which is harder to interpert
  7993. * // for a human.
  7994. *
  7995. * @type {number}
  7996. * @product highstock
  7997. */
  7998. xAxisUnit: void 0
  7999. },
  8000. tooltip: {
  8001. valueDecimals: 4
  8002. }
  8003. },
  8004. /**
  8005. * @lends Highcharts.Series#
  8006. */
  8007. {
  8008. nameBase: 'Linear Regression Indicator',
  8009. /**
  8010. * Return the slope and intercept of a straight line function.
  8011. * @private
  8012. * @param {Highcharts.LinearRegressionIndicator} this indicator to use
  8013. * @param {Array<number>} xData - list of all x coordinates in a period
  8014. * @param {Array<number>} yData - list of all y coordinates in a period
  8015. * @return {Highcharts.RegressionLineParametersObject}
  8016. * object that contains the slope and the intercept
  8017. * of a straight line function
  8018. */
  8019. getRegressionLineParameters: function (xData, yData) {
  8020. // least squares method
  8021. var yIndex = this.options.params.index,
  8022. getSingleYValue = function (yValue,
  8023. yIndex) {
  8024. return isArray(yValue) ? yValue[yIndex] : yValue;
  8025. }, xSum = xData.reduce(function (accX, val) {
  8026. return val + accX;
  8027. }, 0), ySum = yData.reduce(function (accY, val) {
  8028. return getSingleYValue(val, yIndex) + accY;
  8029. }, 0), xMean = xSum / xData.length, yMean = ySum / yData.length, xError, yError, formulaNumerator = 0, formulaDenominator = 0, i, slope;
  8030. for (i = 0; i < xData.length; i++) {
  8031. xError = xData[i] - xMean;
  8032. yError = getSingleYValue(yData[i], yIndex) - yMean;
  8033. formulaNumerator += xError * yError;
  8034. formulaDenominator += Math.pow(xError, 2);
  8035. }
  8036. slope = formulaDenominator ?
  8037. formulaNumerator / formulaDenominator : 0; // don't divide by 0
  8038. return {
  8039. slope: slope,
  8040. intercept: yMean - slope * xMean
  8041. };
  8042. },
  8043. /**
  8044. * Return the y value on a straight line.
  8045. * @private
  8046. * @param {Highcharts.RegressionLineParametersObject} lineParameters
  8047. * object that contains the slope and the intercept
  8048. * of a straight line function
  8049. * @param {number} endPointX - x coordinate of the point
  8050. * @return {number} - y value of the point that lies on the line
  8051. */
  8052. getEndPointY: function (lineParameters, endPointX) {
  8053. return lineParameters.slope * endPointX + lineParameters.intercept;
  8054. },
  8055. /**
  8056. * Transform the coordinate system so that x values start at 0 and
  8057. * apply xAxisUnit.
  8058. * @private
  8059. * @param {Array<number>} xData - list of all x coordinates in a period
  8060. * @param {number} xAxisUnit - option (see the API)
  8061. * @return {Array<number>} - array of transformed x data
  8062. */
  8063. transformXData: function (xData, xAxisUnit) {
  8064. var xOffset = xData[0];
  8065. return xData.map(function (xValue) {
  8066. return (xValue - xOffset) / xAxisUnit;
  8067. });
  8068. },
  8069. /**
  8070. * Find the closest distance between points in the base series.
  8071. * @private
  8072. * @param {Array<number>} xData
  8073. list of all x coordinates in the base series
  8074. * @return {number} - closest distance between points in the base series
  8075. */
  8076. findClosestDistance: function (xData) {
  8077. var distance,
  8078. closestDistance,
  8079. i;
  8080. for (i = 1; i < xData.length - 1; i++) {
  8081. distance = xData[i] - xData[i - 1];
  8082. if (distance > 0 &&
  8083. (typeof closestDistance === 'undefined' ||
  8084. distance < closestDistance)) {
  8085. closestDistance = distance;
  8086. }
  8087. }
  8088. return closestDistance;
  8089. },
  8090. // Required to be implemented - starting point for indicator's logic
  8091. getValues: function (baseSeries, regressionSeriesParams) {
  8092. var xData = baseSeries.xData,
  8093. yData = baseSeries.yData,
  8094. period = regressionSeriesParams.period,
  8095. lineParameters,
  8096. i,
  8097. periodStart,
  8098. periodEnd,
  8099. // format required to be returned
  8100. indicatorData = {
  8101. xData: [],
  8102. yData: [],
  8103. values: []
  8104. },
  8105. endPointX,
  8106. endPointY,
  8107. periodXData,
  8108. periodYData,
  8109. periodTransformedXData,
  8110. xAxisUnit = this.options.params.xAxisUnit ||
  8111. this.findClosestDistance(xData);
  8112. // Iteration logic: x value of the last point within the period
  8113. // (end point) is used to represent the y value (regression)
  8114. // of the entire period.
  8115. for (i = period - 1; i <= xData.length - 1; i++) {
  8116. periodStart = i - period + 1; // adjusted for slice() function
  8117. periodEnd = i + 1; // (as above)
  8118. endPointX = xData[i];
  8119. periodXData = xData.slice(periodStart, periodEnd);
  8120. periodYData = yData.slice(periodStart, periodEnd);
  8121. periodTransformedXData = this.transformXData(periodXData, xAxisUnit);
  8122. lineParameters = this.getRegressionLineParameters(periodTransformedXData, periodYData);
  8123. endPointY = this.getEndPointY(lineParameters, periodTransformedXData[periodTransformedXData.length - 1]);
  8124. // @todo this is probably not used anywhere
  8125. indicatorData.values.push({
  8126. regressionLineParameters: lineParameters,
  8127. x: endPointX,
  8128. y: endPointY
  8129. });
  8130. indicatorData.xData.push(endPointX);
  8131. indicatorData.yData.push(endPointY);
  8132. }
  8133. return indicatorData;
  8134. }
  8135. });
  8136. /**
  8137. * A linear regression series. If the [type](#series.linearregression.type)
  8138. * option is not specified, it is inherited from [chart.type](#chart.type).
  8139. *
  8140. * @extends series,plotOptions.linearregression
  8141. * @since 7.0.0
  8142. * @product highstock
  8143. * @excluding dataParser,dataURL
  8144. * @requires stock/indicators/indicators
  8145. * @requires stock/indicators/regressions
  8146. * @apioption series.linearregression
  8147. */
  8148. /* ************************************************************************** */
  8149. /**
  8150. * The Linear Regression Slope series type.
  8151. *
  8152. * @private
  8153. * @class
  8154. * @name Highcharts.seriesTypes.linearRegressionSlope
  8155. *
  8156. * @augments Highcharts.Series
  8157. */
  8158. seriesType('linearRegressionSlope', 'linearRegression',
  8159. /**
  8160. * Linear regression slope indicator. This series requires `linkedTo`
  8161. * option to be set.
  8162. *
  8163. * @sample {highstock} stock/indicators/linear-regression-slope
  8164. * Linear regression slope indicator
  8165. *
  8166. * @extends plotOptions.linearregression
  8167. * @since 7.0.0
  8168. * @product highstock
  8169. * @requires stock/indicators/indicators
  8170. * @requires stock/indicators/regressions
  8171. * @optionparent plotOptions.linearregressionslope
  8172. */
  8173. {},
  8174. /**
  8175. * @lends Highcharts.Series#
  8176. */
  8177. {
  8178. nameBase: 'Linear Regression Slope Indicator',
  8179. getEndPointY: function (lineParameters) {
  8180. return lineParameters.slope;
  8181. }
  8182. });
  8183. /**
  8184. * A linear regression slope series. If the
  8185. * [type](#series.linearregressionslope.type) option is not specified, it is
  8186. * inherited from [chart.type](#chart.type).
  8187. *
  8188. * @extends series,plotOptions.linearregressionslope
  8189. * @since 7.0.0
  8190. * @product highstock
  8191. * @excluding dataParser,dataURL
  8192. * @requires stock/indicators/indicators
  8193. * @requires stock/indicators/regressions
  8194. * @apioption series.linearregressionslope
  8195. */
  8196. /* ************************************************************************** */
  8197. /**
  8198. * The Linear Regression Intercept series type.
  8199. *
  8200. * @private
  8201. * @class
  8202. * @name Highcharts.seriesTypes.linearRegressionIntercept
  8203. *
  8204. * @augments Highcharts.Series
  8205. */
  8206. seriesType('linearRegressionIntercept', 'linearRegression',
  8207. /**
  8208. * Linear regression intercept indicator. This series requires `linkedTo`
  8209. * option to be set.
  8210. *
  8211. * @sample {highstock} stock/indicators/linear-regression-intercept
  8212. * Linear intercept slope indicator
  8213. *
  8214. * @extends plotOptions.linearregression
  8215. * @since 7.0.0
  8216. * @product highstock
  8217. * @requires stock/indicators/indicators
  8218. * @requires stock/indicators/regressions
  8219. * @optionparent plotOptions.linearregressionintercept
  8220. */
  8221. {},
  8222. /**
  8223. * @lends Highcharts.Series#
  8224. */
  8225. {
  8226. nameBase: 'Linear Regression Intercept Indicator',
  8227. getEndPointY: function (lineParameters) {
  8228. return lineParameters.intercept;
  8229. }
  8230. });
  8231. /**
  8232. * A linear regression intercept series. If the
  8233. * [type](#series.linearregressionintercept.type) option is not specified, it is
  8234. * inherited from [chart.type](#chart.type).
  8235. *
  8236. * @extends series,plotOptions.linearregressionintercept
  8237. * @since 7.0.0
  8238. * @product highstock
  8239. * @excluding dataParser,dataURL
  8240. * @requires stock/indicators/indicators
  8241. * @requires stock/indicators/regressions
  8242. * @apioption series.linearregressionintercept
  8243. */
  8244. /* ************************************************************************** */
  8245. /**
  8246. * The Linear Regression Angle series type.
  8247. *
  8248. * @private
  8249. * @class
  8250. * @name Highcharts.seriesTypes.linearRegressionAngle
  8251. *
  8252. * @augments Highcharts.Series
  8253. */
  8254. seriesType('linearRegressionAngle', 'linearRegression',
  8255. /**
  8256. * Linear regression angle indicator. This series requires `linkedTo`
  8257. * option to be set.
  8258. *
  8259. * @sample {highstock} stock/indicators/linear-regression-angle
  8260. * Linear intercept angle indicator
  8261. *
  8262. * @extends plotOptions.linearregression
  8263. * @since 7.0.0
  8264. * @product highstock
  8265. * @requires stock/indicators/indicators
  8266. * @requires stock/indicators/regressions
  8267. * @optionparent plotOptions.linearregressionangle
  8268. */
  8269. {
  8270. tooltip: {
  8271. pointFormat: '<span style="color:{point.color}">\u25CF</span>' +
  8272. '{series.name}: <b>{point.y}°</b><br/>'
  8273. }
  8274. },
  8275. /**
  8276. * @lends Highcharts.Series#
  8277. */
  8278. {
  8279. nameBase: 'Linear Regression Angle Indicator',
  8280. /**
  8281. * Convert a slope of a line to angle (in degrees) between
  8282. * the line and x axis
  8283. * @private
  8284. * @param {number} slope of the straight line function
  8285. * @return {number} angle in degrees
  8286. */
  8287. slopeToAngle: function (slope) {
  8288. return Math.atan(slope) * (180 / Math.PI); // rad to deg
  8289. },
  8290. getEndPointY: function (lineParameters) {
  8291. return this.slopeToAngle(lineParameters.slope);
  8292. }
  8293. });
  8294. /**
  8295. * A linear regression intercept series. If the
  8296. * [type](#series.linearregressionangle.type) option is not specified, it is
  8297. * inherited from [chart.type](#chart.type).
  8298. *
  8299. * @extends series,plotOptions.linearregressionangle
  8300. * @since 7.0.0
  8301. * @product highstock
  8302. * @excluding dataParser,dataURL
  8303. * @requires stock/indicators/indicators
  8304. * @requires stock/indicators/regressions
  8305. * @apioption series.linearregressionangle
  8306. */
  8307. ''; // to include the above in the js output
  8308. });
  8309. _registerModule(_modules, 'Stock/Indicators/ABIndicator.js', [_modules['Core/Globals.js'], _modules['Core/Utilities.js'], _modules['Mixins/MultipleLines.js']], function (H, U, multipleLinesMixin) {
  8310. /* *
  8311. *
  8312. * License: www.highcharts.com/license
  8313. *
  8314. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  8315. *
  8316. * */
  8317. var correctFloat = U.correctFloat,
  8318. merge = U.merge,
  8319. seriesType = U.seriesType;
  8320. var SMA = H.seriesTypes.sma;
  8321. /* eslint-disable valid-jsdoc */
  8322. /**
  8323. * @private
  8324. */
  8325. function getBaseForBand(low, high, factor) {
  8326. return (((correctFloat(high - low)) /
  8327. ((correctFloat(high + low)) / 2)) * 1000) * factor;
  8328. }
  8329. /**
  8330. * @private
  8331. */
  8332. function getPointUB(high, base) {
  8333. return high * (correctFloat(1 + 2 * base));
  8334. }
  8335. /**
  8336. * @private
  8337. */
  8338. function getPointLB(low, base) {
  8339. return low * (correctFloat(1 - 2 * base));
  8340. }
  8341. /* eslint-enable valid-jsdoc */
  8342. /**
  8343. * The ABands series type
  8344. *
  8345. * @private
  8346. * @class
  8347. * @name Highcharts.seriesTypes.abands
  8348. *
  8349. * @augments Highcharts.Series
  8350. */
  8351. seriesType('abands', 'sma',
  8352. /**
  8353. * Acceleration bands (ABANDS). This series requires the `linkedTo` option
  8354. * to be set and should be loaded after the
  8355. * `stock/indicators/indicators.js`.
  8356. *
  8357. * @sample {highstock} stock/indicators/acceleration-bands
  8358. * Acceleration Bands
  8359. *
  8360. * @extends plotOptions.sma
  8361. * @mixes Highcharts.MultipleLinesMixin
  8362. * @since 7.0.0
  8363. * @product highstock
  8364. * @excluding allAreas, colorAxis, compare, compareBase, joinBy, keys,
  8365. * navigatorOptions, pointInterval, pointIntervalUnit,
  8366. * pointPlacement, pointRange, pointStart, showInNavigator,
  8367. * stacking,
  8368. * @requires stock/indicators/indicators
  8369. * @requires stock/indicators/acceleration-bands
  8370. * @optionparent plotOptions.abands
  8371. */
  8372. {
  8373. params: {
  8374. period: 20,
  8375. /**
  8376. * The algorithms factor value used to calculate bands.
  8377. *
  8378. * @product highstock
  8379. */
  8380. factor: 0.001,
  8381. index: 3
  8382. },
  8383. lineWidth: 1,
  8384. topLine: {
  8385. styles: {
  8386. /**
  8387. * Pixel width of the line.
  8388. */
  8389. lineWidth: 1
  8390. }
  8391. },
  8392. bottomLine: {
  8393. styles: {
  8394. /**
  8395. * Pixel width of the line.
  8396. */
  8397. lineWidth: 1
  8398. }
  8399. },
  8400. dataGrouping: {
  8401. approximation: 'averages'
  8402. }
  8403. },
  8404. /**
  8405. * @lends Highcharts.Series#
  8406. */
  8407. merge(multipleLinesMixin, {
  8408. pointArrayMap: ['top', 'middle', 'bottom'],
  8409. pointValKey: 'middle',
  8410. nameBase: 'Acceleration Bands',
  8411. nameComponents: ['period', 'factor'],
  8412. linesApiNames: ['topLine', 'bottomLine'],
  8413. getValues: function (series, params) {
  8414. var period = params.period,
  8415. factor = params.factor,
  8416. index = params.index,
  8417. xVal = series.xData,
  8418. yVal = series.yData,
  8419. yValLen = yVal ? yVal.length : 0,
  8420. // Upperbands
  8421. UB = [],
  8422. // Lowerbands
  8423. LB = [],
  8424. // ABANDS array structure:
  8425. // 0-date, 1-top line, 2-middle line, 3-bottom line
  8426. ABANDS = [],
  8427. // middle line, top line and bottom line
  8428. ML,
  8429. TL,
  8430. BL,
  8431. date,
  8432. bandBase,
  8433. pointSMA,
  8434. ubSMA,
  8435. lbSMA,
  8436. low = 2,
  8437. high = 1,
  8438. xData = [],
  8439. yData = [],
  8440. slicedX,
  8441. slicedY,
  8442. i;
  8443. if (yValLen < period) {
  8444. return;
  8445. }
  8446. for (i = 0; i <= yValLen; i++) {
  8447. // Get UB and LB values of every point. This condition
  8448. // is necessary, because there is a need to calculate current
  8449. // UB nad LB values simultaneously with given period SMA
  8450. // in one for loop.
  8451. if (i < yValLen) {
  8452. bandBase = getBaseForBand(yVal[i][low], yVal[i][high], factor);
  8453. UB.push(getPointUB(yVal[i][high], bandBase));
  8454. LB.push(getPointLB(yVal[i][low], bandBase));
  8455. }
  8456. if (i >= period) {
  8457. slicedX = xVal.slice(i - period, i);
  8458. slicedY = yVal.slice(i - period, i);
  8459. ubSMA = SMA.prototype.getValues.call(this, {
  8460. xData: slicedX,
  8461. yData: UB.slice(i - period, i)
  8462. }, {
  8463. period: period
  8464. });
  8465. lbSMA = SMA.prototype.getValues.call(this, {
  8466. xData: slicedX,
  8467. yData: LB.slice(i - period, i)
  8468. }, {
  8469. period: period
  8470. });
  8471. pointSMA = SMA.prototype.getValues.call(this, {
  8472. xData: slicedX,
  8473. yData: slicedY
  8474. }, {
  8475. period: period,
  8476. index: index
  8477. });
  8478. date = pointSMA.xData[0];
  8479. TL = ubSMA.yData[0];
  8480. BL = lbSMA.yData[0];
  8481. ML = pointSMA.yData[0];
  8482. ABANDS.push([date, TL, ML, BL]);
  8483. xData.push(date);
  8484. yData.push([TL, ML, BL]);
  8485. }
  8486. }
  8487. return {
  8488. values: ABANDS,
  8489. xData: xData,
  8490. yData: yData
  8491. };
  8492. }
  8493. }));
  8494. /**
  8495. * An Acceleration bands indicator. If the [type](#series.abands.type) option is not
  8496. * specified, it is inherited from [chart.type](#chart.type).
  8497. *
  8498. * @extends series,plotOptions.abands
  8499. * @since 7.0.0
  8500. * @product highstock
  8501. * @excluding allAreas, colorAxis, compare, compareBase, dataParser, dataURL,
  8502. * joinBy, keys, navigatorOptions, pointInterval,
  8503. * pointIntervalUnit, pointPlacement, pointRange, pointStart,
  8504. * stacking, showInNavigator,
  8505. * @requires stock/indicators/indicators
  8506. * @requires stock/indicators/acceleration-bands
  8507. * @apioption series.abands
  8508. */
  8509. ''; // to include the above in jsdoc
  8510. });
  8511. _registerModule(_modules, 'Stock/Indicators/TrendLineIndicator.js', [_modules['Core/Utilities.js']], function (U) {
  8512. /* *
  8513. *
  8514. * License: www.highcharts.com/license
  8515. *
  8516. * !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
  8517. *
  8518. * */
  8519. var isArray = U.isArray,
  8520. seriesType = U.seriesType;
  8521. /**
  8522. * The Trend line series type.
  8523. *
  8524. * @private
  8525. * @class
  8526. * @name Highcharts.seriesTypes.trendline
  8527. *
  8528. * @augments Highcharts.Series
  8529. */
  8530. seriesType('trendline', 'sma',
  8531. /**
  8532. * Trendline (linear regression) fits a straight line to the selected data
  8533. * using a method called the Sum Of Least Squares. This series requires the
  8534. * `linkedTo` option to be set.
  8535. *
  8536. * @sample stock/indicators/trendline
  8537. * Trendline indicator
  8538. *
  8539. * @extends plotOptions.sma
  8540. * @since 7.1.3
  8541. * @product highstock
  8542. * @requires stock/indicators/indicators
  8543. * @requires stock/indicators/trendline
  8544. * @optionparent plotOptions.trendline
  8545. */
  8546. {
  8547. /**
  8548. * @excluding period
  8549. */
  8550. params: {
  8551. /**
  8552. * The point index which indicator calculations will base. For
  8553. * example using OHLC data, index=2 means the indicator will be
  8554. * calculated using Low values.
  8555. *
  8556. * @default 3
  8557. */
  8558. index: 3
  8559. }
  8560. },
  8561. /**
  8562. * @lends Highcharts.Series#
  8563. */
  8564. {
  8565. nameBase: 'Trendline',
  8566. nameComponents: false,
  8567. getValues: function (series, params) {
  8568. var xVal = series.xData,
  8569. yVal = series.yData,
  8570. LR = [],
  8571. xData = [],
  8572. yData = [],
  8573. sumX = 0,
  8574. sumY = 0,
  8575. sumXY = 0,
  8576. sumX2 = 0,
  8577. xValLength = xVal.length,
  8578. index = params.index,
  8579. alpha,
  8580. beta,
  8581. i,
  8582. x,
  8583. y;
  8584. // Get sums:
  8585. for (i = 0; i < xValLength; i++) {
  8586. x = xVal[i];
  8587. y = isArray(yVal[i]) ? yVal[i][index] : yVal[i];
  8588. sumX += x;
  8589. sumY += y;
  8590. sumXY += x * y;
  8591. sumX2 += x * x;
  8592. }
  8593. // Get slope and offset:
  8594. alpha = (xValLength * sumXY - sumX * sumY) /
  8595. (xValLength * sumX2 - sumX * sumX);
  8596. if (isNaN(alpha)) {
  8597. alpha = 0;
  8598. }
  8599. beta = (sumY - alpha * sumX) / xValLength;
  8600. // Calculate linear regression:
  8601. for (i = 0; i < xValLength; i++) {
  8602. x = xVal[i];
  8603. y = alpha * x + beta;
  8604. // Prepare arrays required for getValues() method
  8605. LR[i] = [x, y];
  8606. xData[i] = x;
  8607. yData[i] = y;
  8608. }
  8609. return {
  8610. xData: xData,
  8611. yData: yData,
  8612. values: LR
  8613. };
  8614. }
  8615. });
  8616. /**
  8617. * A `TrendLine` series. If the [type](#series.trendline.type) option is not
  8618. * specified, it is inherited from [chart.type](#chart.type).
  8619. *
  8620. * @extends series,plotOptions.trendline
  8621. * @since 7.1.3
  8622. * @product highstock
  8623. * @excluding dataParser, dataURL
  8624. * @requires stock/indicators/indicators
  8625. * @requires stock/indicators/trendline
  8626. * @apioption series.trendline
  8627. */
  8628. ''; // to include the above in the js output
  8629. });
  8630. _registerModule(_modules, 'masters/indicators/indicators-all.src.js', [], function () {
  8631. });
  8632. }));