TTR/0000755000176200001440000000000013575463222010734 5ustar liggesusersTTR/NAMESPACE0000644000176200001440000000240413425330036012141 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(ADX) export(ALMA) export(ATR) export(BBands) export(CCI) export(CLV) export(CMF) export(CMO) export(DEMA) export(DPO) export(DVI) export(DonchianChannel) export(EMA) export(EMV) export(EVWMA) export(GMMA) export(HMA) export(KST) export(MACD) export(MFI) export(OBV) export(PBands) export(ROC) export(RSI) export(SAR) export(SMA) export(SMI) export(SNR) export(TDI) export(TRIX) export(VHF) export(VMA) export(VWAP) export(VWMA) export(WMA) export(WPR) export(ZLEMA) export(ZigZag) export(adjRatios) export(aroon) export(chaikinAD) export(chaikinVolatility) export(getYahooData) export(growth) export(lags) export(momentum) export(naCheck) export(rollSFM) export(runCor) export(runCov) export(runMAD) export(runMax) export(runMean) export(runMedian) export(runMin) export(runPercentRank) export(runSD) export(runSum) export(runVar) export(stoch) export(stockSymbols) export(ultimateOscillator) export(volatility) export(wilderSum) export(williamsAD) import(xts) import(zoo) importFrom(curl,curl_download) importFrom(curl,new_handle) importFrom(stats,approx) importFrom(stats,embed) importFrom(stats,na.omit) importFrom(stats,sd) importFrom(utils,flush.console) importFrom(utils,read.csv) importFrom(utils,read.table) useDynLib(TTR) TTR/THANKS0000644000176200001440000000053013425330036011633 0ustar liggesusersIn no particular order: - I can't thank Jeff Ryan enough for all his help with TTR via: motivation to submit TTR to CRAN, helpful comments, testing, and providing an example Fortran implementation of 'EMA' (from which all other included Fortran functions are based). - Many thanks to Ion Georgiadis for helpful suggestions and testing. TTR/data/0000755000176200001440000000000013425330036011633 5ustar liggesusersTTR/data/ttrc.rda0000644000176200001440000024363213425330036013311 0ustar liggesusers yU&ittw֘uoj0(626 "(2ABy H@dU9ʩ_?<{^?onᆗw^ҫƗ\w[_vy?nw\q| wmtõo'4`?}#9gB~ 7_~W_;_3o`%M7~og w~ogVdm1;`석3vllvl.(dOO?,_؟c+ /ľ2vW_co/a7ga]MUnKؗ7ɾ2&-m]={W)4{=˾}-:Q1qI<^`]v!{=b}}ٿʾd?e?쇳~ 7ُe'o`6,>ǟ~*K1>,Y{L?|c{,=>ٯ`1=Zc{~#Kt.c:|tb1=Cvc{Llc{\ ۲tg1=t7Y:|Kw;+,>tc{Lw=c{쟰߿dʮ媥wg߃;WdNcg!v=da Ktw@wKtw@wاX:<;x}oޟ>>(Y;gُctx@wtwxx@twxxx@wxx@w@xxx@wxx@wtw8x@tw@wxxtx@wtwϳtx@wtwxx@tw@wxxtxY;<<;<<z//p.///././/././c./p//p/././/g//./¹Ă////.///2//.///././///.//y/.K,p/.p/qna[YzOx9{w>ރOe|WzvKXzv+gqwvgw~v7gٽ||Ƿ?d|D ~mq|voN#i$;÷da&{o^Ƿd?a]e<߾mOCͷoe;|VǷe;#ķeO|f H ~7~߾/wK|f|f|gA|hzC>}뾃;>o?&߾-gαOۿ7?=}=䰮׳O߳}߾}:߾}&}do.>qBy|}[8"B?bs9>Ⱦ.|3/#Jx$j>ɾK'?n̾1g|}dgo%du}+dk8(7|<}e}/eKٿ{)~qUV>~GºqW6la٘8Y6liقs㸬,>:lyُ^c|O}g 0i>N~=Y>~ ?f#Ǔ/}gǙ/qf|w>~5845>~Gǥodǫw5]>~7߹B| mG|1fwg/8a89>q9s|=89>q99>qq~89>q<:9>q89>q:9>qj89.789.qq~|\9xs\8Źq>>q'89>q\=9>q󽰮s\89.qq|>9.Οqqs\9~s\x89p?9px8| 89?s<~7p,x8x>p78'u8Cs\9.qqsS89.qq89.qqs<_w>\|w89.qq|\8Hs\o8ŹQr\8z>.qqs\%9.qqo :.qq8o8Źmr\8>.qqs\}'9.qq8Ź߃8?8ǹߍr|8qs|K9>qu9>qs?89>q89>qw89>*89ps<x89Εx8 |<x8{Xv>.qq9.qqs89.qq;a]9x8ps.n~+p <\8pN\ݯ.px.px.^.p #..pqu<\.pq|<\x{d <\p <\8.Yp <\p <\.xx3|x.pWx.pw..^u<\.p <\|8xpN\..pq \\|,x ..pq..pqq |\|*>.N\gq |\>.qw]O |\>.qWiWq |\>.q |\|eXqq <\xZ>.p <\}.p.p ..pq..pq..3xÅ <\x>>.p <\ݽ.p.p x.p1xu8E.pp᜸;Qp <\|<\xPPxŏp <\B@..~&븸Ņ..~ \\/qq \\Wx;PPx p <\B=C|\\..pq ..pq \\ ..I..pqWs&J\\F>..3xåz%.._%..qqKu%..qqK\\(qqK\\RDK\\&J\\T7Q>&J|\&J|\T7Qǥ%>.Ot^\RDK|\&J|\T7Qǥa]W/QxT'Qxå:x%.Ix%.pN|\\$J\\T/QGuxT'Qx|N%.pK%.pK<\~x%.Mx%.K8%.qp^%.qpK%.qpKĥzx%.Kx%.pn%.p7pK<\RD|\\o:..qq^%..qqK%..qqK\\(qqK\\%..qqn%..qq^%.pK[%..K%..qq^%..qqK%..qqK\\(qqK\\RDK\\&J\\u%..qq^e%..M%..qqn%..qqKu%..qqK\\(qqK\\RD%>.M%>.qn%>.qKu ||\&J|\||\(qKť%>.M%>.qn%>.qKu%>.qK%..qqKu%.pK<\(*-Y>^u\WQp+<\p+<\JD+<\ WuW8RQ W8 W8W8ppN68R'Q W8: W8IT8GT¿o>¿o圸RQ W8 W8IT8ppNW;p>p+p+<\p+<\JD+<\ W$*<\ W#*\ W8R'Qp+<\p+<\JD+<\ Wo WxÕ: WxKTxp^.pq+.pq+\\ WxÕ: WxKTxp^p+՛xKTxp^RG\ WR/Q Wŕz W.KT.pq^.pq+u.pq].pq+..KT.pq^.pqְ W#*\ W8RQ W8(¿Jp+\J]Dqp+\pp6¿ V¿ET¿o.¿o+o+[o+[JD+[ºVRQ Vz;_}D{+[ʹp>¿o+o+[o+[JD+[pNpp|pp+p* YZpk<\Z}Dk<\k<\x~eXqpkzxõx5Gx5p>5pk5p :x5Ix5pN5pk<\xVQxõ:x5Ix5pN5pku5pk<\ ׸5.׸ŵ:׸5.IԸ5.qqN5.qqk5.qqku5.qqk\\qqk\\ZDk\\$j\\o:pk5pk<\pk<\úk\qpk\Z]Dn5p>5pk5pk<\8o"j\8VQ8:85I85qpN5qpku5qpk\qpk\w88~ $j\8V'Q8:x5pk<\Z}Dk<\#j5.qqk5.qqk\\qqqqku5p]Gk\\#j\\׸VQ׸ŵ׸5.GԸ5.qqN5.qqku5.qqk\\q5.qqk5.qqk\\qqk\\ZDk\\$j\\׸V'Q׸ŵ:׸5.Ik|\$j|\U'7Ǎ:7 >nK4 .nI4|7$|7Q'7Ǎ:7 >npq\7"<7x9uF=D7! np np<ܨhp<78 nC48 npp nppu nppܨh78Q7878 nG48 n>8sF]D7"78Q78ͳ|78Q |<78 nE48 nppNQ'7xQ7xÍ7x nG4xhppF]jfxÍ7xy7"<7xQ7xÍ7x nG4x np> np78QѨnn<6xQ6xy _Cw66xQ6xF]p{FC{66Q6:66΁FC{66Q6'úwu mpns mpnsۨwhpns6 |u:68:68 m;48 mpno|6|6Q6z6 m=4 mm mmnaW[\׶7qmk[\VCk[\ֹoŷ-mmo[u-mmo[|۪hmo[|VCo[|߶Zu-mqns[-mqns[u-mqns[۪{hOnw[۪{hnw[Vow[ZZ8UЪmnw[۪{hnw[VCw[ﶇ|xU>mnŻ-mnw[-mnw[8ŹxŻ-mxŻ-mnŻ-mnw[-mnw[۪hxUoVCŽ-mqoŽ-mqo{[-mqo{[۪hqo{[VC{[ ZZUvqoŽ-mqo&xŻ_u-mqns[۪whqns[߶ŷ-m9[Z:m{[-nqp<ſ-moΡſ-mo[u-mo[۪mo[Vo[ZUſſ-m?ſ-m=ſ-moſ-mo[-mo[۪ho[VC[-nqp[-nqp-nqp[u-nqp[ܪmx-n?x-npv>np_:nqp[uxíx-n=x-np-np[u-np[<ܪhp[ppޡNC;wÿoΡSw8Sw8zw8o;NC;v:=ǿvÿWvÿzvÿ;tÿoÿoưvSvSЩwo;NC;Yvÿ=tÿsw:ιo :ppޡppΡSw8Sw8:w8o;=WЩpp;ܩspp;NC;w:w8Sw8zw8;t8ppޡppyXo;upp;U|w8Sw8zw8;t8ppޡSwxSwxÝzwx;txpޡp;uxzwx;txpޡp;p;upp;ܩspp;NC;ǿ=oW=78=qpΡ=qp{u=qp{u^}C{zWǿz~{۟ :Oqoޡǽ=qo{{=qo{{۫wqo{{;;ǿ=oޡǿ=o{u=o{۫{o{;=8?޹p%8ޡ=qp{xýzx=x=p{zu=p{=p{<ܫwpgxWxýzx==x=p=p{u=p{<ܿ1xýzx==x=p=jj=x=p=p{u=p{<ܫ{=.==.qq=>q{u=>q{|ܫq{\ܫC=>E=>q>>q{|ܫq{|ú{\xý:x=qp{^C{zu=p{u=p{<ܫ+>p.88=?8=qp=qp{=qp{ܫqp{^=D{/qp{ܫov>!z8W88=E8=qp.=p? :qp=qp{Ϫkxx.bxxy#/E,//E,_uTKKTTKqoV5qMzgw~/k~ڏy_?ˮ>udo׫NW9|;܏9|7]:M~y_n;7]͇/;^q<|~W\g |5O{740|bGso|d^n>O7t_o5y ?GzZ??㍿{e2Nq}xߘ/}i#7Wx+3$Y<ߑssJ~|KV~'kɏfb¿<,n6x.yy^G?'xfH}%]xOwѯxyK{_a=Jq|q輱ȯw~J:z{{g%ɏ\OtG?1?yYu#䳷Gu^,s]^c#?#1وĝ_1x> CS>s1w3qny'_oygw]"_"{=ޛlQ=F~w7֑#O=UIV_%ޫ{^k\^WuO?5}Ƒ|O{+ڹxo{'sޛlݼ/.z>qOd~O_}4]}uq8Ƽh?~1|"و1svxvWqZZ?_?Oq> NxnxIG<Ѿ?ǃAyP4Cu8?d^t]b|ރ~h/%$R#.Ko|E<)1?Ɨڋ~Gܴ׭!{׍yxwq]NcGc̣yHyGa{6>euƇwC^OAN4{Xa7;#8r_|O6Xw#޳7=lnvNˋᴼ>Uֿ?ʗu{Oq|ק]s/=i?cΘxy3^?-N˳Sri]>R\c^cG#/"_!o^p]p`+x(8zo^<"nϰnϺ|C'g4a#bн듸/ })w{Oɿdo8g-OBG$ {*Ħv?Bb\Wt=I?E>#c|XUgv;k::1l#3|Z'_~"AG~sjwc_>l\7Db##/I,owO\oF##'NOi$+O/ww@-=eҺțڵ}9!lYQ:6#^B?"_cu =c{c>c-hMc?smD~yc/?}H~7c#_엡/k: Wi_<6z"/v_{<y#b'c_1}1Ѓ8}4:ڋs?gz_j'\? Xn]0gqpyT|&N>~D\l[tM|U?8gl|ߡqN{|/wZn>N1h?8cߊxF?x>~3h7~48nwtOyd|Ǽ;~G?GO 8#[t.[~u( St&ﱎ"|W۵_uyy+g;o~qYCB"o:&+u{G5/`د""?c|~ipPwK|z?wpH\.}"ֺ߃?~5.L>= WGy/rΞ/!ƗNta3i|?3q_ȣn|<;]E;]k׃G{&g=׿#_[O{g?;ڍ|0wYXǑ_߱.\k;w뜞U ȧȏȫ?siu:;~w=OOjN7h_mq|=pwѼvwh/~'8)uK-x 8cg;YMvI;c=9Ϙ35/fǹ|Lg>c?ވ[ϓ~F𣏕w=¼udݤ< ݉ng{u'z 4ϧb_:6Y'<|<Ǽy;3t6|\׮:֟g?8ga~w}}ayKzq׵8c>AZĺ ] П3X%?UgBwpuuGzډu_c]B7"n!v-nɏ |F#1G3h/Io\?= ?]XW߰8~DDy8빳1ϱY:xg'ў=+gu/gzk5qV^Fy?+>No?=.vr:x#1y03]vgMu_z=xj?Qgkkkpka{"?1?#"ݸ?y?q]k#ZqK63u::ϽN^N\5Gѣ_GˣxT?ՏGǣ#c1~Lǭc}:|,.3˧Ǎq~?~vݼ<.k}1Ǽ1q\~>.Ω=yy}L33?Ovv{ݳst =!Ox=n"Oh񈷼DRSqqq:&"N11oxxsss;?޼sjƫsh~zsO'_߹Vq:~}{.z>g|On{R/|v?q=;~y+?Vq}%+o<\I󒞋1ғ{<v_y|zOsWyxVy7o]~^yq?O6|=k}ݻcm^{WnM4M)7Kʟ.N?_ߧ?yg:%vRM_GMq KO"OOZO҇'ƕ4tMy齛qS~nʫMy)7yzn&=v/rӏMzi6M'gS77wS~^)koѵ-u+ܖyܲnk]m7gc|m[m[|sۺܱlG;#wpHeG^O־#v׮vJ׍cW>v|OXW;%׼jvpʎ]L溜K;厼߱Rt{=hޓ{q]ҫt|7{o]e?|ۣ{u_{8rGǾm:ߧ#a_t8#ݾg{q\E=:ϧD{ڿ(O=+쓻}ϺJָ'N??pWԯh/zs|]1{ѕ7yߵȻ-<#iHǶm-:ulg8v.ߴ{tg~GoS\w8B/߮|ލ~]%IcǾOwyz}0ƛtm:?=5DZO~ Ӿ4ߩGb_LJ;qٿyAqߋubqŘgSi~{٤E:QЛxH/Z?E~_G׾<7㾸\}bsB/C#tȼMzzI?qڟϞ}(^[GCwyޥxm}N\Kwۉu:): u$/=I GqKp^G˓4?xw$3_ґ֏IA¶xlɇ-y|-yB|OkNviq%>G&7qn@qp}pޓkS\fӼqs19 -Ωˣ8L:q6}s Ƴe}]{\!o'=bm{ʟ': ii'siﵰ=B9B_yBWy 7t~E~Do"]jOF>EyH:?0۱?F.?b}-:'tAiO:瑯{{8V't"H–ŭ8IkB7c|wm?ӹW]_ҩxEG|'x4h"xoK^e]3Ι^L=c;ޗCC?c[cߍ}}H|e}~q['a>ow7>{ہqɺ?@8=;S#1n;<;cޭKgؔt䀞_?)838!! 5=`;t)q]yy,߈u[u7hq_.ٿ/Sx)xsO˻)y4ފЁKW?vxh]+aXWuv>G؛캾ej|5k;iM=<ӻL@QC $J,p STҨ0 K40I$ RR11Ō5J(?C.:<zӚy_kY`Wgs O뿆[ek5<ז:x'o[S6KfƼ@> ɟ!0.Eِ[>Yģ?~|[{C+$0/9ꪆuI͸5US5M|R558ps`)nu/|;Crכַ#o3S׮ԕ }?r:zq?Y0,ꅾ nI%rg}Hݶdc}S%f:dI\+N]YS+q~Kv\ĝ}%7K=NE=SQuUbaՏbM_u=xCo~Ӛ ?NIOvc} S6abܯ9wwegyBL7sxS§w7f|7νH&֙wL^&rS'W3v%^#'C\u&/|+_ 98_[9~ rosco<s{V^8US+]9w {,<Ϲ{x(Xo%^֝9?:udS_q#rp}nYOC9Gu׵+}fcYOOub*zUUo{RYy>o~g[Y>߱~ͺ[#~+9w#Q .ju2L jGYGS'u.9W$tT+#`+[QׯîZa+⬢s\Wb.cyv伱"Ny̧~7*?(^UKy>]|G㹿@ݱOO6P ~Ki'& l7>VKyqW 됚kV9O뚸៊}/9ǁr{%*+]cW92/WO}}"?FxC?ܳ>=N^9035Xy>]s{9HC&v<}7K~=7c]z?Ls:x5~iGLp)?ɓ;IO$g>O|g^h>m5so=rK>n#5d9朆ϙȻ`ExhC u^C|>|ې?_M>5<"yz:%B?ハqWOAQʽ _f^֑'Womk_/kOk۵\&s6~}_ߚM_y&/x\kUhbg֧-q{&i+Og@{ ѐZPK~|8oE Y'Cr ^l˖z% [޳Zϴ3u]\kK@< kƾk5ްϰ&7JS/0 /RH"rH|-۾D\W%pxJ{2򽌼/s2ٯ%pql˗e+r)?qxy FnEɳg<zW9KyoŸi폜/}y =8Eg+2m?O@ r;~V>;3~_AWkZKWϫ*xx l_eU}8+ćr8~o縯}|y_W2m99/N{?W /~w<8@~/Kkq^,EwvFk| _Ckw {\c?ל;g;z~v<_hOؑqwZre΋::nu?^Gwyo`̓}ϸ7r7?.7 p}\^ʡ|uEǵU^U?a҂3W{{įS9NyO=wnb9-dyoOu|~|cǎ7M@?;_ZيCmig^;kUƿx~mٟbG-~PܗxǞg =6qf=3q\)o{ZU)^WÎo\+񍝮3ox]?E_#>_{|rc?xW~2hW+wTxLbC^w; ߗyƇ'yg{+2mN(||k[.>v.'/țָ}Ɠߗu-rͺ82O[/JuWAڷx}^>q2,G)_ԁ3:rNיuuI[#xǮz+uW4ÕzM~n~~{_]+zX(Ivײv^+OC۸?>bܟbRn[wؗȾm| ~~oUwu[ȕ}wz}Ϯ?Ps lWqb}hz|?E}S.륢ߕ:ļRUe}d=-;/<ɗ3ў֯e[gŐlq*Yߘ̃E޻qyzy<%qgr&_ڏyo-ƽw;~|YImc·*~Ÿg+e/7i՟]J7 JKηm=;?g/>NmH\(+}ٖr^\0n`+^/[^ޑ7#py}o"߿E\o![|wGZ#[uy2]~y}b<#]ӟ{sgw.rES.0OPC=hh~w' )_P~VyzEη〫[}2.O|8;w{c{N}9pO9qG~ůOwiK{W\WwJ[z}J{y#^u>` \GO>~_졼S{;qW"i?9>} G$..~xΣ;]i_σL' z9|>yd'ϑ:^ȑqJk?t:;o?T~>'-Ƴů2ϟ-|>{bpuĸGy_ua#>fcz1;31ߟ{' pr'_ ߟ bp{~'; rߣO>t2ǼW^' <^87y>׮19f~v yGwşk'38K|"|+ߦw;y _97s R:lwh̏#8 o-ߑ_ p /e|w{{(#K|(x.kp3PM_2|/e~2hwƙG7^y6<^NGƝx<¿G?^xy#yygy ?gvߎ<~ͼʡWc]`GW{7{lAy"~.$:Kϱk+T[7cef}CZK\[W9̸uxƅEyy];7kGȼ#.ŷu!vOq_~3ccq,oY/:YYyy-+v9o}ћ||ɏ~}u|7~|~wƷuiQGʣ/[Gz_|:l|vܲng2UҞ^wr_^ϙI[~<:!϶g׏C\W뇲)7yxޱ.>w.:j^u?jUkw{7Woگ\jG>Hi/B[o a;]ao]u!q/u]_],'w;1gŞ{F^;C32xO9ow+qqyěr+?7qxNĽqVƋz8яƋ~g ɸ5zƃ3ÙH;]{ψx=~>3SyǎEg<?.|me=~ߣ{=3>i>>8z]ȗwk(|]?q?/`8|?D<`b|`!qCx~C^xwੇ^!='G1v~ļ#~/q#%v c{̸1x~}d#r`Gį?׏ccߟTݼO>ɟy׺0p'BOk~~9??<>Ͽ9u:NspyWwzsC{9v;?z=בя;%iO?p . .~ux_y.T7~o'WG_O~ǟouvN|Ge7^<#NzӃz#nz?n=ⶇ<=⠇z|\0W ?~c7[x vN3pgīxzG>QyGu|CatL\(o=zx}Ѓ?=xGS x&O;؊OǮ}x'࢏I#_q>#oki'G}p\/Y\w8CFn>㟼O|hX񜿛}}p;EiWxk3wC3{i9¿>$_ yPyoq^w<7ߝGO 13:cx ^{D~87B1~1~Gԯ#}DS11q=&^F}%OĮ>~Cx_ὴ7D!yq? G}o>?O !gp?GH?8!yc> ;c} M=!M/ףּ)zN}'y~'䓉l NM ;MCxҿ{]t5N3H uxnF2cLoʼSn)uȣ3qzhMq'}}&ā_E|MX'W7/&}BN͔Sx4)=OO\8SXɈzsDY'$ȯG?ȟcp>1ј8|lS_;'\Ns'y=Oy||%S 1>_{d>6<7DJ=b~7yw1XOS?%?Cf>yL?x"i f=sƟ{* =gwf仼GyCgbgyh nT'/x 31&ʯaN/gğqwƗI㌨RXW{p:T^7 3h&ԛ1f\G^.$!πԥ90uO]߹7 :} -<>ӿ7'3}_ rf=~7O)zػ(~Z~< ><{sF9tb^cuOp=I>ɺ ;;q}g\(UѲ?zt =⤧ݟ?ca>r[0xt]g<>9%rƐ<}-⏼^ӾY/*++ƿ+:OYà8~ vg~>zgIr-y#w~a⾀{3-Ođq/W#gq'-O<2}pW x~3\P?O9XG'.}y~ ?c9:vg#ǃs^슼>S=!q4'Ϩyf'~z&r xe܂Xayx\a՟ngߊ~guW_}>V?Wڍ[l'gEVkNW?ͼē]_3^C={6س!/6R? 8iЫ!n5'ǴNE>?e\{;6gp6-vo5x߃:yjpZ7;E^7 ZN8imW P_;}Zڎq-i;[#-Zh7{٩=cg<ϵgCsC9q[K]8[a֟ԩ8v5P?7Y5kg7qEހx~ZCi˰В[xZܶkLY#oxk5ݚ|n߉5uYyk_;y6/wڂ <Ƿ|øp{ikOې"<kX5;k;9xnk낇ĿPާ>H?ks-i z%?9B4O}k5בKxUqP81OM8_3xҸOE^ϮgķYۍ)zκuu.=tzz$keI;]쟰nXuwhjPQc7B:KX~͒oV+$Odv+ +\q>bN[%/ۊߊzc{]o*U8Ya >gq\gE>^=+y%S+} Y_ .zRTv?LSU䱬#U oUSO?]76~_n;_, n+~Sŏ*-Ufec{NOa"<{"E+#܏'#{C:ϡW67pOϏs>r\ I<{ΉB#a#>r_^ }o4WXŮ?&{{/k &īWENܫۓr/Ǟ{j|8E}E ǹƼcp{{oGO=9iu=&<3=_ԓc1@U}W}G'>M`v!g+s? /c {IGԻ:6{~?`S~sy\9x OYbogo<0)x䔼-;j^SW37+= ϹgN|:z{<%QޛGS彏/Ξ!_)ܟ?3䛹dOW{w޿P.Yνb97vN?fGwoN,J &-<;BQx={%u'q$^+c%dKM3sgۮǒ<$?.wsJz|s+׳/ÿO'VTXnz8ꗊןO͹EE>˺=+䬈8X.*0* ;T#fo{b^e k3Oe}Zkx(v}N=W_YW5~'pξB}q]'yv]K~B|W'3TWV|3Gw\gMF9F}Y>`䭊u]jg-sˌ/ `wwZsڃ+~u xm[3.hklso;}7rxO}<^=Op^q>)˚}ԋ5Zgj9|OM]S{YEss9ۀ6yu!?^ 8y z瞂7rC|Mq9eC<5Iy˽Ly!x?~њz&?Գ]\oxя[q)'&5-ya*=_|sNMKݗDx5熶-mǖqH>?ٯysZy0J-8JKAC{;>Sz/#篹'.cGx9gʕ{7_K{4[o۟, w _v .<+<<-.ɹe|w~ǖ:e+>iK>w_T|륖qGn5yxM}f{C=nOxy>r}̓e_c_m7q~7u}6Ǵ6ȿAwuzlㆼ쵁7n qW5c ߓr.#Y/=u^?=q;CvaL?wkzmG=c}c_w~ҏ|QmK^R'mݱQO>B|7-3ȟ-<[sxtȧ-q/ّvف<~=ݡupvvq+;#O{/ړu =u%x o]?>}%r\ƒ/.Kփ}Ix~OyJ^xJ=⿧)YOK%봧Siw)^}GGɛy>3z\@yEpbEEx~^Nz/“/og{^B%꽗ex|DwxEKW?E"uȋu/0 ȭ}^^;ꇲsOW)WW^9-~G7-Gg<1kq!5w!5|ks5q ;_S[{ ^ָ|}>c/Nk;Σ]ԏߣ]{q~ u}c:v>suוgבr7v=o`/qr<o0~9-vvأC;krʏvr3Z7Mƹɸ7&r>7&D|7Mwg}~WNRyߣOvY|y܄WjY{2kGӎ4NŹ/}/ mZ*@OƟ%oK-]O峿(r;+ึߕ|{uɕ:B9ę|ŭ!g2gڢKP4~|\%n5۲ne=ׯġt޲>wY%W>|#M%~^y/ϫ}V2Z<Ok{q:=^y^^'}:<'?cּb쐖_x:yo޵->_~OoCZ)^~ͳW} x}Օ|z\9yWW=|'-xI{]x~9=na״6Bmvmzyo#ו~6zv|7 s<9ߌy?Y=ēvovC[ȝKyhoyiቻ! ^w]zy<{a;̗yhcz \i+ݵ˼wCnS.ržȑq]-.v̓Fm6{z9w;|~nڛr>ڍmr:~~{~C{3}Owyb_#-_q\ʭ|.>z|w>@:~}Łrĭ~'S N9ONCDOxȸ:C._}veg̃]2ώ=37v:>>;>_+S~^їvv|O{ɿwB\bS{_ؑ8]{D.q:GpG|1Ovr3qa_=@w>nCqűqe9(9Įo0x8^#ȷgx/Haok!~KzG9~Gޗ_KߵzA/y>i_G`ļ`v>x7mSA'.lŏq _GsiyH|? Oxwy a#):43y,<;qQEgȯ'ߕyO/;*u|đV~ځ̸N|o~?_/d`!N': >Ym}e]y3Oio37vЯƅ_/\K8ҿy|3M\~q_ GqSz:R/uoa#3-#O)OOGcwOpGӺm~|޵γ.oUI|kUnҏ86g}fSV[{3[%?pxǼO&":FOG%^}_]ljKNOUgG{N{BQ~?Ƈ˼a]zFoĹJ̣}_#>[7kyź(SqlVգ2u*H;Cٺn,c]e}k]h={r:gJ~w5u8'u]?g&Xo?31qrG\f]zX޿b+Ayo~" ~ʹx='QA<<_t\C|3/~ܟ")zS9%q|HƇ_N)~)8=~ʹ'c|w9?sb{EsSq Ŀg-nW;yjy~{1~ȳ(j7;+P\?_􇸁g/tʸrs;%x.y.T.y|d^Q?p\ן^ .O|rq{;%l{ ƍv2~:+ub7εN_ޅr7Ei/M;h8ȳc O[W]ħ_o}򝼭ůY)xvyħrwS}~gu^gwgwgT v9.g!gC\w aƇvxc=p|>w}}?@|>DCp!%??@}@>!r>@wxx!⧇!v=p!gp7-y?aG=bGC!xꇾ#!z!~|;#y?!#=}.?g{?V~GQa~b?q}RW}?xD\d>߃LJ>?Ŏ>O yL\=A'n''`'}g> oO zr}α˝\K9|~csmU^p8~G9UgΧ]suaN"r?#x?W{<:9/` yA_w_`p].?{ƽx@ 什.sqwOcyEqvӌ[_7q#n.qu+ϱ#Å~.ũOr/vz~>/= =#hsx:]=>O|Y^B9.Ճ_{k?|+>}ɛ}GG~f}yOF><ٿO?Lc>0;yv}߿&>wy߯߱za=pD|Ĺ ~_; N7=ؗ7w-v'2-?ğCuHy:b c蝿#fnK>7g#5"6F!??c5uǟ#|x_:!7d|77?ocz!q]1b]8C~}/ԛd/ ~Wg]ϳ~=!z zF<=į;O`D<qS q3> q6 v;.;/v󰞙q'aB]|5E)|6/&iJL)v1 ?ۂz䟂)/8߱'LrOD?8MR7s Oc}&xc_po*'y>Ί~e\~BĞi^r[ɋc^m\c[xoowc&8ax3ɗyC|cG/<'!g'~c61E5c?:#qS%φ_SxE"Nۄ:o͐g=1:YS]'oOO&zJLY7O/<!ĝqU܌̧ܤC:O>~&^QCI]lk]mݪʭ7cfOC y_OwzzueH~ܸ#o$^}ۑqb=?Nd쓹 >G .q:GC҃?{ȗs\}W澞_9~tg/_z? }|קn^7ZS\ϸ^0nSs.g뉁Ch}g_F;aUW7xw{qS>Zn^u_N_SGYw.ׅ3Eޘ!猸f' >%xȺ:ܹ0ߦ7gfy/੩u7Uk̈q)y93xeFf=L<ߌ<1#?᡹û39?sC3p ++%%.%y~I|ܤ?8XKp$,\,%~X# 4sogrf>>îS}.Ğ'0gY7~HM2ē<*x3. yy!Ω{7/3|!^Ž'_(I~ &Ka ^{+gOe1>Ǽ#;畇9`ԓ3pJ}^soN;0a%Z%x[.%/Vq">V:=\Ņn ?U_Q}ag U?8FO~>N:?v/[M\c7:yǝ vi!55qQ0/<]Ύ5~ߠw{&k\5M'oc~w⼆_?[5~[ 5cNAuvkuUN;7_;րr`5Q;}]ܷn>lᏖ|ڲh~ӧ-|NkC >⩅[j+[ӂXp?]ࣚz-x;bOƏovqG hOOG;oAo6{ͿѰiowhiЧE||r-G-*ux#X> ppjJ|%_%x_7lk,-K`x<+~+xw^_SWO+pt|]_t:y=X›Ku?VW|` |Xf@UQ_qn>%_Xre}ԍ~Gq38g^gq%?;Z6(n7B߁|zO#<){ָV3rܳxO| ^W[:>[t = yP O` Kyu6}t ᩉTo?'7s7f|L_}0^H>#ϹEνϼ{oaMq|F r=]{/0Y?{3W##W"_3~rα9-3$?@^k7;GrNb#b%xya}{4ح.!˿w^ ˿GAo=Rه/?=دϾGȿ{{G4~~w{Ź?x''N3;$μ{1c8_r>q;x>3/+W_:`?-e=9%/sywk{B=Op|i5>$|{xgN'^vgǛ"u{ybJ^GΗ73Ožyծh?֧ww_Uk*{|'<{RO+\G`ƕc!,#/溜+>=&}+.9'xU쬝8ߨ69gq_*Uԕտa^!z. ; *#gG7b< IfVGrn¹Q)5 7rno6䑜3ëh<&vhS4إ{x\뼷?y+#~=y=8C7'sVUF^.yf^c Csuaߚ8Nr(˜sDɖW-|bnZ% j[b%ϷƑx ^Z<<& ɷ-q`mM <> qR'#wk pnm+qh_@?nkc3_Ȗy=|ܒWZ,x$/ۃ?y%%ZA> X߬׬[鹏~<{gq~M^ku|+ɳk\mӆzs} v` Qp!n拻y6!xsCyاkifF{q@X/F5}$fy#?6ԭˆ A;?0="{LЮ''s O I~;AyL$D_'}M0oN~%$'#  u0? OmZ߱Vgi|c0 Y gC`oI<,`0dȟ$|N;<$Y/KRS̯S3SsyKzdb_L1I-*EJQoSRs|S;)uA&EI^pF !ҋv'zўy&{s-)w[?֧kޖ-oIPޭu0Cއv{N8ξܿ/K8>o몥_:}z_pSoI.='?D?gtd}$d\a-bj]އȇ ڷ7֛p&z~ko_ Pkt]/G%wjO3K.(/} O_crG:[ɫG;bZ|ȇVZm-܊x8ҩG>'~ܯߏnEZi=WpXKz{nE:oE>zWxnE8oph?C/a}Dgʷ Q`VWDr+=ݔ~J4O-`J~7x/|o&az/!Ow=?%o!O8}7 \8oskw?z%k1t}>><$GtѾ#|F'/<r@k#@e }r@Kr߁@u 9D>kWp|[.Yp " 'ϾU;!|C=p{m-g}m'\CH{OzٺC7 xL}Ij [g ~jE'3''_dNCS~?UOB S@uՑT TwQ}.\_o]ʏ}W3(V|Z}ޤ|X?AuW4_t ^+>fw5>wV]Bq~8>T\3qS8ޑs5_P!;AuU܊q MYmPGQ@[>87~3/n/ l(.`=g4?Z+{(;OYd(6,ud)fSqlj_o'|C/yWk([KY %j}+?*x8ZqZGEpj76|zi-4rh}5#q05#q8ǩFqa0e֣< ~I ֣i0p{c4xH'ir"+>CZGs0ʣ%~|ɿQ_ .U|&W ˉk?陞?; |ZOEr~8q8VrD<o;_r)y I͗Z+y^H܂Wp3kI[kFt4=< 'Z>wkokg}ok5ۚz7}GpԷcGpZIp[K>~RFoZHy:x$H7Jg$žQ—:?t)HiHE>>C%Gq(>ݵ!jh?hc-m-׳hMxC1?!z?xm%p1k,|,ck,=KY87p#=Gs53zu ^I|uhʷ]t!~I/+CCxoc/F/Q#_ ?gt">8uoF=G<6XG}8]uc_? ?Os\w<?x$?S}o%>.џhz>k]ߛ܊?eEG/zI~G#xIk'c ~?NX O &_ ;k5|p52pNX:䇵s-֗ S;z0A''lyL&rD9L$)$3r2y$aיDP.J8[B'Q'#^%|_BK%ܿg -u6|,%֙LL|9o21O&'?r 8'/zyzOz(5=Ir6 8OM 3y<>KsΛ@M|6OzyZ0!KyL 9ƓIy+_u>}MEoʉ]Ɠw>ꩵm)6|1;# ֥<'ݍNc?qWʎi=<_gt%_쨭K{):\;G;i_:+g]גw|D9o"DtDD>ML$m=}@:M$= N+?L$'R''^h>gKeх|6O !&>] ǚ/?.+&0xE]vZ_q'[_s/z֛@{ȏoQ4R'Ҟ龜)D5SY?8{.= -K?ϭ\UhL"^$qIokʃ'/=9KK*l?CN( ˭P%+T[[ⓞ??^Gr,|IX~I)?ʃ,~򧤇?dwKǐ3(V_K%Z/DokGSVB%%WDy k7,~KLmX>w;^vF{yHod^Wh_٫lʾi=S#A߉OK=3S_̞i?Ct]dw p>kk]rd4^%O{ɽp<_P^Kp:uqVyڟ~*ΐWI_8~6 ONAFh_ə kY.Tv]t?d5_e8X(}zipqSYr&;,? ,? '8y]~JVT>'Sqo(o _ S_Uަ8zG0||5\TܭNɵpAqɑD]ɓH-=^f!SLuɣCz"9 ɗK\'y$'ʗ9_(_%ʗI Q/Kg;S;פ<=>t|ti]A}(/]u~sJM8j_5|:Ig2Zo2k2LO&OsM{Ox\TdWpNzG6/?DK竢H8lGF2^H/HOg[y'~I:/\OΓzmtTK&>/lT+Kp)lr"# י,NwjEML9LA+KpnI.t|4?KdD-  ɿS wɏ~Iz ə6^_t|ayѾ~n yS$wB{8ttB8m>??O~o0>R?6h)S(S(Sm6))ꉭG>Zʵё|B{`C~|4^z/9R =}ea,xroMԧN=BzmC܆Z\w*d*j*7tJxST7r3tFyJyJ8NӸ4eF|qi[4cO'<^ӹt;tzO}N|k} 7Πk0ϤΤ3ILy&b&h&yG20tIE9fQfYl,,;̢"((o,;sٔ6lm6M|fю"ϳ,Y\O}ۇ|M9E/)MMCy}9gpu.|͡Ѻj9K_s/{/: ?]ͦ=0PgzNϦ̦Egɕ#ۗz5rorΛC5k.ᙻ2>\cs zRoJ ))*!FJbRڟR_z^J~ҋ'}/os)ws~)g뒮mp ^ͣ>>[K,_嬬/SvPF/[{8YF9yƑ?eb2o߲4O91gY;+;r|,'i)7rUNS[Ar[г2[/[M奌.ΕN?XF,~66V*|RKLO.!|hʸNwğ|,((S);[zb+LOߗ~u:zIrvxZ&У]UAR%Ok\N;fC;Ws]UxI~E?vcm'SG.TA-&6^I ꃭ}+#|ƒ|}_gʃ38wi*'*ȯ bzgWM;PIzWR+J'mUUYK$奲xWR*,̷&+H GÏr]A?PA1ٷ׺{_';vpU2ΰ&+)'X|7N?YIT*ҡzTE;i鯪o=gmkR^M;[M>Siikא5ĿVMVӯTSN)Ow|OYͼxO5P.jN 5jk!:2n~V >c5o5t\.gxjoKSqU***ڋ*[EUTQh߫oᯢTnR'7U1g5WM?b|"ߵsџqɟ_i7j^ WK먇?GjGrZγi!}kO cZw^?֒iooL]h:I=Zyzz^O9ӿՓZlq_z\vzRGzG3SO(u{zfoO:2aVKPkiGjijIg-Akjeq^-᫥%k)ǵs~Oݮ &<JZIjC3嵊pVV*[#55 S )>HhjN-q!5G !> 媚L55SkWPjdDC]0? B[dO}ڝ*=?׾e7)gդC5 7[#=2N߈_-Z|Q?Z'_ph]='uZxΒu{-R';3gWO<(~^:OWt5!;8 #a{(:/FVF>,oYC8N#I۞Xܨ8xQ5VSUj).\+UbvzR#&]R"<$zUG91@8j(ޤ]b^cAyw)?d}pZՁ$W)sJ\XI|eRI",ߦ}7=P|NrQ˺T-5׊34O>X\W=|j6 Ʒķ~֡|Snzڛzҿ^9qYG8zu KĿxS .ҩ6.[~vW@( zGk6@@l`@8r@xeeCиu?*8?@z5Fo#F媑QrD1k_{\}xэq@_/9RMXJ:wY|?Sumʁ0guLrѓ5O;e_4^t7=尞v/40Ҿ&vʮ4>8 5>z ?k>62/lhbݹ]F 巉4ʹĿzL?}~=BR_5:x2~^y)5卪~r]oW=Yvu f7S?f5N*8.8Q~G+;(}fQϸB~tk}.eqQпKTOg|";nCR ~3Fك3#{ {!03jOvvHyih")_ǤL3LiE8Lz ̑P"s@ȉX7Byu#+8B77r.G;zH=qpxjxDI虠g;n?J:yã#OM.7J?]QC'GҮz([Czޥl)|}G=!'1U1Atq\r{UѕF/9_t|RokAGܟ#zw0 wA+8G w1BK8c-\nl~Eiߣ )$/mсQ=ݜ)QI+,8!J`xzA?ҟDi[Ttc_>z^GI':F8'}b78iw=_|rތ_qHLvg7c/\4& ;NL>e\`!~i_7Q)e^#bc(_[Sw!`v8F;")JQ.=Dpk]G;1N;FJoEڑ:{tscT:a>VGx|WܭY.A<o+OR>}G+﷼HqsFѤRqRϪ{0ϳz 52n_: 岑k&פC /?"ۈvYy9ԿfEß<~Y͔f%oW4?&ұ~YtW@~z8-"ѯF?h aIc~f݃7v?(/8 ¸=3:9Bz[^QvAu%x|l$闚hMhyi#vt2_zۨT9霆V;kع|chtQKxtFctG&'F;PK#8^Dн;c|YE_-QKy}sֽ> Ok)/névߜqs5y5@ |!_%մvOt=n6zSt{Uvop:sj]$wSAjKU;g|UU CUw(c)wh]ݿ5g}gBz mߗp=C9{ԯ ڻ /5t_pTnh"~UѾVNvo|{.Ի*ڛj/;j)?J~I/G99޲'b#(vL9>E:69s!?jYwA<FډFFE}Akw&FDb*f|se\pPδFQ徉r`3IL8hWG>=W>Lm&)o(b}Z_neݖ.º[LLfv#9揖_Tg&=l!#K<#?t汾^\I"kK{a9B:GDhg=X>JP/i7 $c#L}fDGwD[J:EX4_ɏD;xPum^5m>:NAYIu)Ջ/4ѮD}~63>V)Whdrv#B"92}bܣyoxGZ]?I~ jʝƺ_窻/Ay~3ڇo:'yΕժxUb:7vZڝ= ځahz@% % Nп$%X ʵ<%W +A?ڇuL`% rjt]IRL.>ԣyE0NS ;AOkQ/$$K^I‘|hSSWNIu'CsS+)gا^Ϥ)ƉiK~ 82M~zbҌ+Ro5Z|/XƵ޼^;~dEv/ux왮}/\Iiio2oޮAoۗu_4=<47cNk EN}q\!4/\k)7~jky{{ݰ͵_]M>{n?acfu8ۗ^q?N7/=Xg+-;]>n13xޮm=6xknȅgrtM=c\pmp}g~)xmX@Ϟ][]q&س/vqo7/A~~鍮߶_f׬{b p.wc ._? /Ȟr{z1u{zl~dV֝K O ǀȵKK+97 n ~W?kO/!6gqצW~o~0sx?P}m{u,ڦkwO?zu;]}X]ខM=7.{ |8{f~W>э5[nXw[؇ڷǸ'Qwz) ?/4}^7[;pO?;Op=M='G|}gaV68 v?8yˀxSw2y;\yWk+KNWOGG? >{s =¾Ch?ւ7:/uw<}U䏶y{l#}]2ǽ/ 7gqاh>ާ޸}րu? tj}p̹ߡ銋\W!sgoč7n}n|n|19xgS6޵:v[ߙ/][ºMmݍ4/yu}6}n\W^a9=ZOaڱX{@'^?2΅ۡ um½M3ˍ z=/6þW'?r69KZO ~6a׃@uoewatPo,sfL!W~"1> ӽk#oub!_4y/!n݉uVx!K/B?־#yT Ulד]:8Uط{ߕ׿ܵ6R+2 >{-ƭ_#:3:秂AohM9_mX{{Pf9k=Sc_?ֽOa O'S-:<['y/qO{S^u'3~%:st\ptHϝ3q{_q詮|,X\zo}: H9p{\Ⅰ1}Y kK^Oɮ͟č/šZ^ibWE-zɖAxyg_D_;\%Kl rcoU2˶rm;W轸?r h`|3="pƻ>|9-{/[>z_ 5MGZCy^|07؉W7S7hIv[o n#n}S >xڵmg]7~޽Ϸ vmЫ5ȯ|wwQG-;sn|b"Pz$/ykvvシa _vWXym!~,yTz!穽3êrwr7]~ |$ݸs\?٠cw":~(׶sܟ{K,E滶k_rrtM!f'зq¿vw.:,?̭v<Β5//v%t9Nv{胉?0Jov@ח`'3/#+? zs: E뚷ܸJ]iߠw?~Ϲ~p/q']nG^_x Vsn޶oΑaݗ^n뀻T7p;A Vy]xOvPA8-|-7ta>`t`WSy@oܼe~ŷMݸÿumFm~tſ/Yu{vq{~ҵ3/i9{7O9C-.ڭ`塘د;!7{]|aZn{qk>KWqy{oW|tnvK)o<Ƶ1>ԑ[g Gn~ NUx6ɸ~kXɅsN/Ծm7"_8@]Az~{]yGjīI]sqA?㋨ F>v.~ ϽO?~x_̽_|̩+{2KE4هyo_?v7<XByAw_W~C\ qF'/mgw[s/olzw @H{Oyg߹ؗ-P?L^ }LD7zDQ?He/|f >-@$9Fw`g2sqMo {.%g>c-viގK>hwtmD޸# GÞοyߺ= nj uǥ)TEݮ'ok/qmjvy|k`仸|;yZUw;EmݹwqQ b~5nk;o.Ά,vs(Tg2?]{޳us_=o9E7} <yC uܼyl ^ٶ))'Dݭvco~|+ppl{ksasaNj?rmmܼ:Х97\{hێYo;)^ɟ0^o{uxnu :ve+u-<i,ϯ^]&G { +`'yn`C:|u t! Wjkw=`W3so%R?tmK_ zǶصY;{%Oߙn7QH>1Ql"_ϛo}xt$Ld.o:p%#=A{#^{ߺ `-po ~o|߽۫-ږuqgvwǹT"{OpNnܼ<pvG=?x\1,1 }7D& >M~O_0se+v%:b\_{]f!gmupĞD&~.Wh}t<y`qxe#L\5?VG_@u|띂8{V߈$ ^CKLOuwF;]1=C?~iڭȇ|֏xk3]/.p_R )n"zev[OA2t8 /ZzPprBR[7Lf1ɮ|d6m{s^_~w~wDlbk3E<%\?WqQhs:7r8'G8L>9ګs|I>3+_:VՀak@v,v7&o!j>f_sBo! {?wmc< 8|]rġ-}Go~qWߡzHa&}!ԫro^+(WN#\&KǦ.ɆO7qm|x9ZovQWH\8sn=3#;!goۢ8o3z o{ƍ]s0sa57w;.mwڍ<z4=m=-\v%O~5/>=Ox5sBl{!~[oziyMP\sܼS!-#pT<𻝇:=s~3$3|;߆7ײ';!z W/W|0t^82; R Eq^\eVZpf؍qZ:AG>Gcce?]w.ú[ WU|8:5D=׍{M\[zqLSPHxx?9tӀsW=/tpplnC~sτ]?[J֬Cz| o>Lt8t\?ھ7ݽ_"`trs h:yJ]?yBヨ'MAOw6{9G@Wx`SkG!zw jrԡ˙ሳb?zܰ vr<%A8{гYڋa!M4r5Ssop·/Š?;~n~b9<Χ:z8xY'/[E>v9rHQ Dݭ<8^q%k1Iۣ w0aC^zq@rS+/CPJ0 aG3ھ>v-u/qA)n^nDMw\{ ]ȏr._|mK>ӹw}x.!.=Ѱ?_؜~ok7yud^(Fo|=~w ͥ>4qpѨ$W~=g7F[kLJEW!_-D!O3/\[%=6q? q??W [usw~$/ _}ylw뽰0۩[nX+MB[yK^s :Ta:-_&_3Qw4vsVȏ+\gCOL s8q_{ӓ==_|ı{}״=k ~H䋅")l8ط ?qg'sq^;݈8 uConIg ځ8aBEY9 }:< : χkz{;YW~u$ ^Ei';ys ÆcK,߉o w!'z hZùbyS /Q;م[7,.wqk翌䮈/ksm[gp =y]q&=ռ0$jq/yܳMn{r$帗\ ImhMcq#Qp5}&{3}iAYw>g| > ~"{(ո9q/ԣk#eeХ{Soc:%yO`л|@ ,T'JUxsoqv9uoNXૄ='ZnF̄>P4]Tw@Zg=s[Vmww[8 Ơ;v;mp~+蟡oގWۧsoFFA"G_<+r(k"nNUn^}]OIzc=3`? M] -ɓ|%gj-GGn.nk6e\YE<{ӿ8\`f ?y>7,A o&؅#q?G@nu =V 82C At w3o#gvOo~O桞9b^͠sish/quG8=Jw'ƽַq.߇'t;awݨw(_f{FD=q@ %7L_R&A\;P1yG{0?N{TWޗ`H몣]|t GF^Yy]?ùm]ԗ/Ы^Ay`3;|!;绲t}ΧQ_>|*il{ycs w77y;A0uȧU͸wbկ7zMC^ ,F"&=,}X:)b7rˉ"!.lvG]9sỰw6k׎s`ꆑJu"cw%΀|9"׶gGC8?\:D~1_p}:pj5κF-G;r1ڀ_c8oJ|zmf>Soδl~){h|^z7r "8oz3N OEwFF1^{p% 9ɥ"~~wK Ԧ#m82yfr·Zz}q?? lupgn(PrAfg_x$w'C;<" v\rġ7p'r63"O|ܩ׷f|6xF76~2tw/*u/#N|.>3 ' ğ-=b7p(:lE ~}`t&^w-s&a"!NK߭pl k]SӃ,3pac{9~03#cAp_;~ h9<~&~E{^@sעn]RȽaq.Ă߅6ҧ1WNK+N9us;;W1 Yv"#<{9d=9 .F~;?;qF"-P={oݸy1w?{ Rxܷ)nWs֛"K ~$ IrqĥQ?yU| qv~i d  y~`4Q?o;yގG`?*_Ͻ?~96米c>޶Nt%#?>Քw >Eܖsc.ĹS"iO)Qs"CNة<y߇%}@C\"V֗q""-ݨk7^[DG ={3.ɍH-둯8?-%ob~G$gڅ: uȇ;NyʡQN܁<9;p_'w#\=Eց'mumfι[m<?|N_R]S7^:{GYw~coÞGrxu}y\Jwݍ>ǎ?S{?yJ]_,Gfsg<"|[|,~4KƑ/Dm{_M9Bf-ϖ@ދq$8InM)L .n.d>r^v:Ha &{pNwo%k?'/ï޿;n9|##9Ǐ>SQthx\m~7رsoC c5~o U5}ak!Q~=uԅߧ45-E uDlaZWZp>QdBo?SyO+`P!>~sT;Ո+:k1>8"Ժ {AnGwgn %ނ/t @ī}!aS`W>~ |ONy+v%vE]w}ݖ)7"(k}\#հ _P?9-ԓG.SΞ݊!܎qm _\S{FA],ry{__GpyO4W~ 0)I#G!n ťk>'M^2׍ky ysC_$ᡞO}c% 5~"w_=j/`m~w-#GnykựLͳEb{~8 y7 7 gD<ǓUnwе c5͈}Wuw5<׋ebܯ%|08-'/o;߷A}pws_r罹"?ȏ6z?z,Kr4oq&݈8" 2wî;o-KiaJe%~8׉ x$WuSOw}ؑSÈc'qЯ􉸗,}ˬȗsw_lsJ>gW䃉g[xjV^i3n+ >R!ΣZ= \ DzዼW gݶߙ5܃󒶁 yY< vu*QͿe~~*}͝ }͗\.> AG߻^D >/ԬzQ3[CCb &[y| O]}sfn~ǡ5^;;wR%u%.o-ooGV &ı(-VWZwB|W)Qkv4<{Gom Y r>|8(׹~(HC;y?h؉[W4:^/7_zr8NmQ8WˎF6 upS{[~]O ĽjuܷODKqxE3Z;׵=)7xGW~/͏uRkjf/m}q^=Knב'nS[?} ^[x9*ߡf"wwǹ+Pw >/C4 9Sw  _<&=NZ co/=P;x%g)fqnU\@-x"[ y;]~+|]>waF:]1ONrH>r'evE]eW |<:8yn[' |nݲoyGđt;gag<ߎs|uPėﰧVγ^r|GY\#:0@?[9MY熩uP͎}[wFCy_,i|X|mOS_:(SD"]EQCA@BBBHnR 5RP"E bET"R,((?3kofgwgvgy 3~Je0e:M?9ocg;5qiIǫSyaǒq:'e>>&('WFp|>rOz:#{%JW"V33ç!*?D!vdߧ/BQ}ye?t=$B~:+xG_Om_>Y7Oto|{O;Iel{?41~ƣ|ב8}e؋3_fK=ugoBwHt)`Ru F_/q2e?>1~Ɵ ce; זyϐr~ߩcϭ~NBދR7#s8/<<{x KʸѦEFf`/ub?'G_HeB9ψ<_s70)~j\G࿡ 7 ?w{^`0g| '?e: .6ϯ |3=q/j#$<#6P݈_7R(#k~-Z[}Y;i͓w|9sS31 n ( 웬_vv?jq_ٵ0Ѽ,emF۸ N"yسC֔zNgYBdg^^tϟ{\;+2o>ʞ+(I(p٬a芕ĥly 㕾̏B9笓& 5~rU'>N}q5'H\ v}\Bvj-q+xc17{X=/ rNf>Қ&\v}ܯxM{ίg~ ^ ^7ܚ<ߚo o~Y#;9D&oD{~0Ns aF:3/Kj:=O+ڽV("򡥴o^ӏfHܵy){ ̱K9c^*ؗO_0[pc%<j% 6+ig_N* GB:igxj@~NH]OF*Dyk祖ǙG91%sZt=(LV tJWp ~Oj~%QNۃӅ9w'G3_軉n:߁v|B(Wjccx‹y2[|emAwm,ڵq;ԂkVTmKy j;_xD&\U&Q>#r@O*G׮_GTVr~? Հ'7v⾋#i#ȃLJ}y\C>G\ lC;`_3y*~Why#dv}sUϭ`~7^!f^"_GoELww\mϑtt8,h9U ﭾI[m :7mPc??bW?K}&x΢a=0o$&-x}ZQbEEL[=_oy1zݞorlQ_bw Sž~^~+xp8/y--8-v>}Hz( yYcYk[ym}Q)ȫW:SsF#δv$m˸8mb[=W6qKvOmM9xMqܞ Ï*}_.E%gzo oUZ}_!^X7!?Ί//~1[h߯? N{24OCd")r-畉h7֌œw9؀l@u%)[3^I'߃_;":?ʗ?z#N1qC-[VC_1Aۉ{>׵7}'6 ,( ޗX9@O:x-gVʷSK̋W1>c}m -YתI{8n Q}8OrOGB:k-v 9ާIyD>ǯaQO`v7HSǺ:y .c*})Q_0 } c=oݎ^J/N&JtQY~RfL Mأ؟~ pЖ0>kD^pl-Ƽ_*eqq<|2ըO~u[|J~h}\5 n590oO) Ÿy=CW׈ü֬/e֑y^DW弙[oE ykÔjr +J?w`蓥/zu̯o"[{䃉=¸cΛJk6Go,̺l~&c>rZ:n^JY_2|YA{?;@;~̱ƫGh=!w6_j_D?li\nOIWSlƉ܀)ԈJ{,6#o{4hqKL]~zC)U[qt<ޅq3A_tX%>$(;Eԯ^zȸہ=e ~^c4lf|˯[bs|8R3s[_ZyLNK^?gfQ _(_0"/,ߝ2W rE|_QpnIUNmD[[m:`0y8?VH>NgD\'\S̓Ɠ]jrN~sܨXO[D7`]D{彌!N_`w08ChfϿq}7iAlQ.~xwqf>nbطna{u/{qjw^ g 'm2?-W:3}2'MD Q~n ۚr!n#+. =(N9i e^v J= i߯V3|>HWҵ0+,;gwSEk4w#}s䋷WOaodCN8a🕥m3%4&J|+{ιuug7i݈Ws v@Y]4p+ DBT{vu]ܶCNgtDy}~H++HUpX:` [?|$zǜ&̛^}y 7sDAdQzX3%K\h9"SJ"s{b/bϒGОμD9/G/AT6M۰V!~Ҹr4|?:6yOHfseLmF}9~<)g\,#3Zoۖ~Z’8)g{u㽺r;יSt.Fzqb?1]jx߈V4Qj`F;y{yz#I:E+VY\=I-K\4+GvUr <]-c:kd3u6:a~u-u4I!m}"ϭ/Fku&9)q37!>hgnwnҏ7FgxTZ[߉8^&G~/#/9D惤;jUgJ%A>t*Eo.'=$zU[&ul7Oc-{ c\w傣>ȏ&g @H|\ooWﱾbtGSǝYQ/{`/6әat=Ncxyԍ Ix[t38`5T~.t}^5F;1̼` `~+C{m>_k=x~Ex׺L\']88wt*~h;LEi+sM^e_cFâ\Fa5zp>; 9wuTOM=z)꣙_@o x)`â{~Y |KO,~+6vY/|crbZga{*Kp_0~OK9V)yvTr]p!7x=8/~R&]W\}=Eۘ/ٴg ^t< Oz'RP^@q5JFyհo!v_E'INކHUЍ{]ߺOݵ'w8ߚO1~| m)?`4#}S^j6.E/l^w4|p }Gg~.9#X][z @`RKD'}[O9f>b Nç%[IǓӎbd݋³RqLl>TA ~_ 21!+|ǹ?M‡\Xw? }d5A;t(k)b?~I(_QTeo*_r3g?E;/B:x\ Ex'q5;"udO_Ӊ,XK;bOV]zp1pؕ<R!wAg[v~ ;4v!vy(vu^cvǖY[oeG[ƺ o%ΊJ|L?P>^/NfLo`\Os<%mD{ƿ|R| #YsߍyzT۝ ]iRry~^`+d:$<|Q8b/q^â|ALiZ[nQ͛*y$7n:s: [}ϜB7N =Ko3O%F? Kl$o6z|Tgcx햌@q:򋹯gzSV;=L@񍸎}Iqp2ޒ;RfMoO߈uޜM+[Ǘx5[|p[4qx(#̶ƹ̫q/,GG?r'\7hȅe\|EϘ}h)b4F9Aw)Kڗ{Q<sBys pw3y<#QᢼyZHc>F|Qb_X[l}!#jicwk2΀w.صؑi;D=)/:CKނ"HGk$7:]}xg(ǍğcgU'?Txqg{ѯ W'ǘOmW&jمJEbݍx LPp_ st/]w)oRxIüo:}݉'VQ$鯕њO!u]͓s2Wѯ~{;q}8۞^?wPoxCg[=^!Q˙Ͻw[᱃ӼxX*xq|{wUYM$)+ yoOc/NnQk)a%KEXp\ޒ k-^35'/4ijzE>//pGJ+}=hocڱUH!ߕzG2jc֣ f6.GǬ(Zc3=$WֻR0h ">ş >~;~wu7iz{7%Ҍ78 i}}- }xAcx6_яs1(P1/V8Eč+Gy:xS|6xxxL4g 81Z+Ipp%iwi|WOGyA|1 -泽ߍ茌ħꭉf,x3P9u\x>/IsV}qT5\H{qT9E>ۅN:/؛UN'῭6N'{=cxoǸg8p"9wՎn9C7Eۯ?S,IQ"KQ8GF\SdGvK=`L6[!ZoLjt5k ֊ poEbz{sڌg99W;u$O} <8,yoay m1DwĢSj(XƑՎ~j i!VtK=}iyE ~'ȸ毈}%{Fa/%I8Z-"OHg/=q~&OI)w?w)=8:]n)itB'wρw ߼εy8m[过4!7Qq':?H; ?̃׏'x;$~ z&^}/}s+_ᏢS牓y/7V'wϤ|g-OOW3WeЯϬQ8p Cs-:z@]R1Ac =pbI:;;k+9CAS]ʩ%ŧO7#Ċ[Y_o/ʭaUWJ6Q (ы^FU"o&>6H 3jD ];? =!"~hϮ qw-ya'x]HTD_Gk@<>kKza/;k^sݞZrT<>R6P0޸*&Vӧ~`n7Uuxj[|_$yB?MiiF7emvN' h+ͱ뱛lX@ܯ㱃[v_us0dir@i?F/iw>Wk53/am~@'qYvϸs8OG7JޝLpg~Ad}M)' OUNu]Enuzƿ3wbe8߉Sv JT忉2>+z KO{=|~ӞO^|KxIoi36%?$_7k:y"`jqR?[$>ā*Q[йzãG G3q#=Wޏ|eâ]C(g#χ!*[l⏽=VtbA%+ќBpC4zTp)B/n;]Obp|zTLF5' `?{J moD*S̋7rZܟgwo|p}p?0ľsz_Ⴣ{DqnB\G܇'iWQ oMvonKxG<_O$JLMynQ\X ƧĜu< Rx*:X-љG'pw'%_7F_%{#ݽ4 F//SO%Ǝz1_E s/}^IGpAƖVTTR/man/0000755000176200001440000000000013575211353011503 5ustar liggesusersTTR/man/CMO.Rd0000644000176200001440000000234513425330036012406 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/CMO.R \name{CMO} \alias{CMO} \title{Chande Momentum Oscillator} \usage{ CMO(x, n = 14) } \arguments{ \item{x}{Price, volume, etc. series that is coercible to xts or matrix.} \item{n}{Number of periods to use.} } \value{ A object of the same class as \code{x} or a vector (if \code{try.xts} fails) containing Chande Momentum Oscillator values. } \description{ The Chande Momentum Oscillator (CMO) is a modified RSI. Developed by Tushar S. Chande. } \details{ The CMO divides the total movement by the net movement ([up - down] / [up + down]), where RSI divides the upward movement by the net movement (up / [up + down]). } \note{ There are several ways to interpret the CMO: \enumerate{ \item Values over/under +/- 50 indicate overbought/oversold conditions. \item High CMO values indicate strong trends. \item When the CMO crosses above/below a moving average of the CMO, it is a buy/sell signal. } } \examples{ data(ttrc) cmo <- CMO(ttrc[,"Close"]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/CMO.htm}\cr } \seealso{ See \code{\link{RSI}}. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/ADX.Rd0000644000176200001440000000454513425330036012410 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ADX.R \name{ADX} \alias{ADX} \alias{DI} \alias{DX} \title{Welles Wilder's Directional Movement Index} \usage{ ADX(HLC, n = 14, maType, ...) } \arguments{ \item{HLC}{Object that is coercible to xts or matrix and contains High-Low-Close prices.} \item{n}{Number of periods to use for DX calculation (not ADX calculation).} \item{maType}{A function or a string naming the function to be called.} \item{\dots}{Other arguments to be passed to the \code{maType} function.} } \value{ A object of the same class as \code{HLC} or a matrix (if \code{try.xts} fails) containing the columns: \describe{ \item{ DIp }{ The positive Direction Index. } \item{ DIn }{ The negative Direction Index. } \item{ DX }{ The Direction Index. } \item{ ADX }{ The Average Direction Index (trend strength). } } } \description{ Directional Movement Index; developed by J. Welles Wilder. } \details{ The \code{DIp}/\code{DIn} (positive/negative) is the percentage of the true range that is up/down. } \note{ A buy/sell signal is generated when the +/-DI crosses up over the -/+DI, when the DX/ADX signals a strong trend. A high/low DX signals a strong/weak trend. DX is usually smoothed with a moving average (i.e. the ADX). } \examples{ data(ttrc) dmi.adx <- ADX(ttrc[,c("High","Low","Close")]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/DI.htm}\cr \url{http://www.fmlabs.com/reference/DX.htm}\cr \url{http://www.fmlabs.com/reference/ADX.htm}\cr \url{http://www.fmlabs.com/reference/ADXR.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=49}\cr \url{https://www.linnsoft.com/techind/directional-indicator-diplus-diminus}\cr \url{https://www.linnsoft.com/techind/adx-avg-directional-movement}\cr \url{https://www.linnsoft.com/techind/adxr-avg-directional-movement-rating}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:average_directional_index_adx}\cr } \seealso{ See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average options; and note Warning section. The DX calculation uses \code{\link{ATR}}. See \code{\link{aroon}}, \code{\link{CCI}}, \code{\link{TDI}}, \code{\link{VHF}}, \code{\link{GMMA}} for other indicators that measure trend direction/strength. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/CMF.Rd0000644000176200001440000000320413425330036012370 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/CMF.R \name{CMF} \alias{CMF} \title{Chaikin Money Flow} \usage{ CMF(HLC, volume, n = 20) } \arguments{ \item{HLC}{Object that is coercible to xts or matrix and contains High-Low-Close prices.} \item{volume}{Vector or matrix of volume observations corresponding to the \code{HLC} object.} \item{n}{Number of periods to use.} } \value{ A object of the same class as \code{HLC} and \code{volume} or a vector (if \code{try.xts} fails) containing the Chaikin Money Flow values. } \description{ Chaikin Money Flow compares total volume over the last \code{n} time periods to total volume times the Close Location Value (CLV) over the last \code{n} time periods. Developed by Marc Chaikin. } \details{ Chaikin Money Flow is calculated by taking dividing the sum of the Chaikin Accumulation / Distribution line over the past \code{n} periods by the sum of volume over the past \code{n} periods. } \note{ When Chaikin Money Flow is above/below +/- 0.25 it is a bullish/bearish signal. If Chaikin Money Flow remains below zero while the price is rising, it indicates a probable reversal. } \examples{ data(ttrc) cmf <- CMF(ttrc[,c("High","Low","Close")], ttrc[,"Volume"]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/ChaikinMoneyFlow.htm}\cr \url{https://www.linnsoft.com/techind/chaikin-money-flow-cmf}\cr \url{http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:chaikin_money_flow_cmf}\cr } \seealso{ See \code{\link{CLV}}, and \code{\link{chaikinAD}}. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/priceBands.Rd0000644000176200001440000000435013425330036014040 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/priceBands.R \name{PBands} \alias{PBands} \alias{priceBands} \title{Construct (optionally further smoothed and centered ) volatility bands around prices} \usage{ PBands(prices, n = 20, maType = "SMA", sd = 2, ..., fastn = 2, centered = FALSE, lavg = FALSE) } \arguments{ \item{prices}{A univariate series of prices.} \item{n}{Number of periods to average over.} \item{maType}{A function or a string naming the function to be called.} \item{sd}{The number of standard deviations to use.} \item{\dots}{any other pass-thru parameters, usually for function named by \code{maType}.} \item{fastn}{Number of periods to use for smoothing higher-frequency 'noise'.} \item{centered}{Whether to center the bands around a series adjusted for high frequency noise, default \code{FALSE}.} \item{lavg}{Whether to use a longer \code{(n*2)} smoothing period for centering, default \code{FALSE}.} } \value{ A object of the same class as \code{prices} or a matrix (if \code{try.xts} fails) containing the columns: \describe{ \item{ dn }{ The lower price volatility Band. } \item{ center }{ The smoothed centerline (see details). } \item{ up }{ The upper price volatility Band. } } } \description{ John Bollinger's famous adaptive volatility bands most often use the typical price of an HLC series, or may be calculated on a univariate price series (see \code{\link{BBands}}). } \details{ This function applies a second moving average denoted by \code{fastn} to filter out higher-frequency noise, making the bands somewhat more stable to temporary fluctuations and spikes. If \code{centered} is \code{TRUE}, the function also further smoothes and centers the bands around a centerline adjusted to remove this higher frequency noise. If \code{lavg} is also \code{TRUE}, the smoothing applied for the middle band (but not the volatility bands) is doubled to further smooth the price-response function. If you have multiple different price series in \code{prices}, and want to use this function, call this functions using \code{lapply(prices,PBands,...)}. } \examples{ data(ttrc) pbands.close <- PBands( ttrc[,"Close"] ) } \seealso{ \code{\link{BBands}} } \author{ Brian G. Peterson } \keyword{ts} TTR/man/runFun.Rd0000644000176200001440000000566113552670134013260 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/runFun.R \name{runSum} \alias{runSum} \alias{runFun} \alias{runMin} \alias{runMax} \alias{runMean} \alias{runMedian} \alias{runCov} \alias{runCor} \alias{runVar} \alias{runSD} \alias{runMAD} \alias{wilderSum} \title{Analysis of Running/Rolling/Moving Windows} \usage{ runSum(x, n = 10, cumulative = FALSE) runMin(x, n = 10, cumulative = FALSE) runMax(x, n = 10, cumulative = FALSE) runMean(x, n = 10, cumulative = FALSE) runMedian(x, n = 10, non.unique = "mean", cumulative = FALSE) runCov(x, y, n = 10, use = "all.obs", sample = TRUE, cumulative = FALSE) runCor(x, y, n = 10, use = "all.obs", sample = TRUE, cumulative = FALSE) runVar(x, y = NULL, n = 10, sample = TRUE, cumulative = FALSE) runSD(x, n = 10, sample = TRUE, cumulative = FALSE) runMAD(x, n = 10, center = NULL, stat = "median", constant = 1.4826, non.unique = "mean", cumulative = FALSE) wilderSum(x, n = 10) } \arguments{ \item{x}{Object coercible to xts or matrix.} \item{n}{Number of periods to use in the window or, if \code{cumulative=TRUE}, the number of observations to use before the first result is returned. Must be between 1 and \code{nrow(x)}, inclusive.} \item{cumulative}{Logical, use from-inception calculation?} \item{non.unique}{One of 'mean', 'max', or 'min'; which compute their respective statistics for the two middle values of even-sized samples.} \item{y}{Object coercible to xts or matrix.} \item{use}{Only \code{"all.obs"} currently implemented.} \item{sample}{Logical, sample covariance if \code{TRUE} (denominator of \code{n-1})} \item{center}{The values to use as the measure of central tendency, around which to calculate deviations. The default (\code{NULL}) uses the median.} \item{stat}{Statistic to calculate, one of 'median' or 'mean' (e.g. median absolute deviation or mean absolute deviation, respectively.)} \item{constant}{Scale factor applied to approximate the standard deviation.} } \value{ A object of the same class as \code{x} and \code{y} or a vector (if \code{try.xts} fails). \describe{ \item{runSum}{returns sums over a n-period moving window.} \item{runMin}{returns minimums over a n-period moving window.} \item{runMax}{returns maximums over a n-period moving window.} \item{runMean}{returns means over a n-period moving window.} \item{runMedian}{returns medians over a n-period moving window.} \item{runCov}{returns covariances over a n-period moving window.} \item{runCor}{returns correlations over a n-period moving window.} \item{runVar}{returns variances over a n-period moving window.} \item{runSD}{returns standard deviations over a n-period moving window.} \item{runMAD}{returns median/mean absolute deviations over a n-period moving window.} \item{wilderSum}{retuns a Welles Wilder style weighted sum over a n-period moving window.} } } \description{ Various functions to analyze data over a moving window of periods. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/MFI.Rd0000644000176200001440000000341513425330036012402 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MFI.R \name{MFI} \alias{MFI} \alias{moneyFlow} \title{Money Flow Index} \usage{ MFI(HLC, volume, n = 14) } \arguments{ \item{HLC}{Object that is coercible to xts or matrix and contains High-Low-Close prices. If only a univariate series is given, it will be used. See details.} \item{volume}{Vector or matrix of volume observations corresponding to \code{HLC} object.} \item{n}{Number of periods to use.} } \value{ A object of the same class as \code{HLC} and \code{volume} or a vector (if \code{try.xts} fails) containing the MFI values. } \description{ The MFI is a ratio of positive and negative money flow over time. } \details{ Money Flow (MF) is the product of price and volume. Positive/negative MF occur when today's price is higher/lower than yesterday's price. The MFI is calculated by dividing positive MF by negative MF for the past \code{n} periods. It is then scaled between 0 and 100. MFI is usually calculated using the typical price, but if a univariate series (e.g. Close, Weighted Close, Median Price, etc.) is provided, it will be used instead. } \note{ Divergence between MFI and price can be indicative of a reversal. In addition, values above/below 80/20 indicate market tops/bottoms. } \examples{ data(ttrc) mfi <- MFI(ttrc[,c("High","Low","Close")], ttrc[,"Volume"]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/default.htm?url=MoneyFlowIndex.htm}\cr \url{https://www.linnsoft.com/techind/money-flow-index-mfi}\cr \url{http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:money_flow_index_mfi}\cr } \seealso{ See \code{\link{OBV}} and \code{\link{CMF}}. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/TTRtools.Rd0000644000176200001440000000230613552670134013526 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TTRtools.R \name{lags} \alias{lags} \alias{growth} \alias{naCheck} \title{Miscellaneous Tools} \usage{ lags(x, n = 1) growth(price, signals, ...) naCheck(x, n = 0) } \arguments{ \item{x}{Object that is coercible to xts or matrix.} \item{n}{Number of periods to use.} \item{price}{Price series that is coercible to xts or matrix.} \item{signals}{Signals to use (defaults to vector of ones). Use '0' for no position, '1' for long position, and '-1' for short position.} \item{\dots}{Further arguments to be passed from or to other methods.} } \value{ \code{growth} returns a vector of the growth of the investment. \code{lags} returns a matrix of lagged values of the original vector. } \description{ Various functions that may be useful in designing technical trading rules. } \details{ \code{growth} calculates the growth of an investment using given prices and signals. \code{lags} calculates the lags of a given series. } \note{ In \code{growth} you can specify the number of periods and type of compounding to use when calculating returns of the price series via the \code{'\dots'} argument. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/VHF.Rd0000644000176200001440000000272013425330036012410 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/VHF.R \name{VHF} \alias{VHF} \title{Vertical Horizontal Filter} \usage{ VHF(price, n = 28) } \arguments{ \item{price}{Object that is coercible to xts or matrix and contains a Close price series, or a High-Low-Close price series.} \item{n}{Number of periods to use.} } \value{ A object of the same class as \code{price} or a vector (if \code{try.xts} fails) containing the VHF values. } \description{ The Vertical Horizontal Filter (VHF) attempts to identify starting and ending trends. Developed by Adam White. } \details{ The VHF is calculated by subtracting the \code{n}-period lowest low from the \code{n}-period highest high and dividing that result by the \code{n}-period rolling sum of the close price changes. } \note{ If Close prices are given, the function calculates the max/min using only those prices (the default). If HLC prices are given, the function calculates the max/min using the high/low prices (added for flexibility). } \examples{ data(ttrc) vhf.close <- VHF(ttrc[,"Close"]) vhf.hilow <- VHF(ttrc[,c("High","Low","Close")]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.metastock.com/Customer/Resources/TAAZ/#119}\cr } \seealso{ See \code{\link{aroon}}, \code{\link{CCI}}, \code{\link{ADX}}, \code{\link{TDI}}, \code{\link{GMMA}} for other indicators that measure trend direction/strength. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/MACD.Rd0000644000176200001440000000636713541716076012517 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MACD.R \name{MACD} \alias{MACD} \title{MACD Oscillator} \usage{ MACD(x, nFast = 12, nSlow = 26, nSig = 9, maType, percent = TRUE, ...) } \arguments{ \item{x}{Object that is coercible to xts or matrix; usually price, but can be volume, etc.} \item{nFast}{Number of periods for fast moving average.} \item{nSlow}{Number of periods for slow moving average.} \item{nSig}{Number of periods for signal moving average.} \item{maType}{Either: \enumerate{ \item A function or a string naming the function to be called. \item A \emph{list} with the first component like (1) above, and additional parameters specified as \emph{named} components. See Examples. }} \item{percent}{logical; if \code{TRUE}, the percentage difference between the fast and slow moving averages is returned, otherwise the difference between the respective averages is returned.} \item{\dots}{Other arguments to be passed to the \code{maType} function in case (1) above.} } \value{ A object of the same class as \code{x} or a matrix (if \code{try.xts} fails) containing the columns: \describe{ \item{ macd }{ The price (volume, etc.) oscillator. } \item{ signal }{ The oscillator signal line (a moving average of the oscillator). } } } \description{ The MACD was developed by Gerald Appel and is probably the most popular price oscillator. The MACD function documented in this page compares a fast moving average (MA) of a series with a slow MA of the same series. It can be used as a generic oscillator for any univariate series, not only price. } \details{ The MACD function either subtracts the fast MA from the slow MA, or finds the rate of change between the fast MA and the slow MA. } \note{ The MACD is a special case of the general oscillator applied to price. The MACD can be used as a general oscillator applied to any series. Time periods for the MACD are often given as 26 and 12, but the original formula used exponential constants of 0.075 and 0.15, which are closer to 25.6667 and 12.3333 periods. } \examples{ data(ttrc) macd <- MACD( ttrc[,"Close"], 12, 26, 9, maType="EMA" ) macd2 <- MACD( ttrc[,"Close"], 12, 26, 9, maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA)) ) } \references{ The following site(s) were used to code/document this indicator: \cr Moving Average Convergence/Divergence (MACD):\cr \url{http://www.fmlabs.com/reference/MACD.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=66}\cr \url{https://www.linnsoft.com/techind/macd}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_average_convergence_divergence_macd}\cr \cr Price Oscillator:\cr \url{http://www.fmlabs.com/reference/PriceOscillator.htm}\cr \url{http://www.fmlabs.com/reference/PriceOscillatorPct.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=94}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:price_oscillators_ppo}\cr \cr Volume Oscillator:\cr \url{http://www.fmlabs.com/reference/PVO.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=122}\cr } \seealso{ See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average options; and note Warning section. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/SAR.Rd0000644000176200001440000000266613425330036012423 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/SAR.R \name{SAR} \alias{SAR} \title{Parabolic Stop-and-Reverse} \usage{ SAR(HL, accel = c(0.02, 0.2)) } \arguments{ \item{HL}{Object that is coercible to xts or matrix and contains High-Low prices.} \item{accel}{accel[1]: Acceleration factor.\cr accel[2]: Maximum acceleration factor.} } \value{ A object of the same class as \code{HL} or a vector (if \code{try.xts} fails) containing the Parabolic Stop and Reverse values. } \description{ The Parabolic Stop-and-Reverse calculates a trailing stop. Developed by J. Welles Wilder. } \details{ The calculation for the SAR is quite complex. See the URLs in the references section for calculation notes. The SAR assumes that you are always in the market, and calculates the Stop And Reverse point when you would close a long position and open a short position or vice versa. } \examples{ data(ttrc) sar <- SAR(ttrc[,c("High","Low")]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{https://www.linnsoft.com/techind/parabolic-sar-sar}\cr \url{http://www.fmlabs.com/reference/SAR.htm}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:parabolic_sar}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=87} } \seealso{ See \code{\link{ATR}} and \code{\link{ADX}}, which were also developed by Welles Wilder. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/chaikinVolatility.Rd0000644000176200001440000000301413425330036015451 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/chaikinVolatility.R \name{chaikinVolatility} \alias{chaikinVolatility} \title{Chaikin Volatility} \usage{ chaikinVolatility(HL, n = 10, maType, ...) } \arguments{ \item{HL}{Object that is coercible to xts or matrix and contains High-Low prices.} \item{n}{Number of periods for moving average.} \item{maType}{A function or a string naming the function to be called.} \item{\dots}{Other arguments to be passed to the \code{maType} function.} } \value{ A object of the same class as \code{HL} or a vector (if \code{try.xts} fails) containing the Chaikin Volatility values. } \description{ Chaikin Volatility measures the rate of change of the security's trading range. Developed by Marc Chaikin. } \details{ The Chaikin Volatility indicator defines volatility as an increase in the difference between the high and low. } \note{ A rapid increase in Chaikin Volatility indicates an approaching bottom. A slow decrease in Chaikin Volatility indicates an approaching top. } \examples{ data(ttrc) volatility <- chaikinVolatility(ttrc[,c("High","Low")]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/ChaikinVolatility.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=120}\cr } \seealso{ See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average options; and note Warning section. See \code{\link{TR}} for another volatility measure. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/DPO.Rd0000644000176200001440000000421313552670134012415 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DPO.R \name{DPO} \alias{DPO} \title{De-Trended Price Oscillator} \usage{ DPO(x, n = 10, maType, shift = n/2 + 1, percent = FALSE, ...) } \arguments{ \item{x}{Price, volume, etc. series that is coercible to xts or matrix.} \item{n}{Number of periods for moving average.} \item{maType}{A function or a string naming the function to be called.} \item{shift}{The number of periods to shift the moving average.} \item{percent}{logical; if \code{TRUE}, the percentage difference between the slow and fast moving averages is returned, otherwise the difference between the respective averages is returned.} \item{\dots}{Other arguments to be passed to the \code{maType} function.} } \value{ A object of the same class as \code{x} or a vector (if \code{try.xts} fails) containing the DPO values. } \description{ The Detrended Price Oscillator (DPO) removes the trend in prices - or other series - by subtracting a moving average of the price from the price. } \details{ The Detrended Price shows cycles and overbought / oversold conditions. } \note{ DPO does not extend to the last date because it is based on a displaced moving average. The calculation shifts the results \code{shift} periods, so the last \code{shift} periods will be zero.\cr As stated above, the DPO can be used on any univariate series, not just price. } \section{Warning}{ The detrended price oscillator removes the trend in the series by centering the moving average. Centering the moving average causes it to include future data. Therefore, even though this indicator looks like a classic oscillator, it should not be used for trading rule signals. } \examples{ data(ttrc) priceDPO <- DPO(ttrc[,"Close"]) volumeDPO <- DPO(ttrc[,"Volume"]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:detrended_price_osci}\cr } \seealso{ See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average options; and note Warning section. See \code{\link{MACD}} for a general oscillator. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/CLV.Rd0000644000176200001440000000202513425330036012407 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/CLV.R \name{CLV} \alias{CLV} \title{Close Location Value} \usage{ CLV(HLC) } \arguments{ \item{HLC}{Object that is coercible to xts or matrix and contains High-Low-Close prices.} } \value{ A object of the same class as \code{HLC} or a vector (if \code{try.xts} fails) containing the Close Location Values of a High-Low-Close price series. } \description{ The Close Location Value (CLV) relates the day's close to its trading range. } \details{ The CLV will fall in a range of -1 to +1. If the CLV is +/-1, the close is at the high/low; if the CLV is 0, the close is directly between the high and low. } \examples{ data(ttrc) clv <- CLV(ttrc[,c("High","Low","Close")]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:accumulation_distribution_line}\cr } \seealso{ See \code{\link{chaikinAD}}, which uses CLV. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/williamsAD.Rd0000644000176200001440000000230413425330036014011 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/williamsAD.R \name{williamsAD} \alias{williamsAD} \title{Williams Accumulation / Distribution} \usage{ williamsAD(HLC) } \arguments{ \item{HLC}{Object that is coercible to xts or matrix and contains High-Low-Close prices.} } \value{ A object of the same class as \code{HLC} or a vector (if \code{try.xts} fails) containing the accumulation / distribution values. } \description{ The Williams Accumulation / Distribution (AD) line is a measure of market momentum. Developed by Larry Williams. } \details{ The Williams AD line differs from OBV and chaikinAD in that it doesn't take volume into account. } \note{ The Accumulation/Distribution Line is interpreted by looking for a divergence in the direction of the indicator relative to price. } \examples{ data(ttrc) ad <- williamsAD(ttrc[,c("High","Low","Close")]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/WilliamsAD.htm}\cr \url{http://www.metastock.com/Customer/Resources/TAAZ/#125}\cr } \seealso{ See \code{\link{OBV}}, \code{\link{chaikinAD}}, and \code{\link{ATR}}. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/volatility.Rd0000644000176200001440000001433213541716076014202 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/volatility.R \name{volatility} \alias{volatility} \alias{garman.klass} \alias{parkinson} \alias{rogers.satchell} \alias{gk.yz} \alias{yang.zhang} \title{Volatility} \usage{ volatility(OHLC, n = 10, calc = "close", N = 260, mean0 = FALSE, ...) } \arguments{ \item{OHLC}{Object that is coercible to xts or matrix and contains Open-High-Low-Close prices (or only Close prices, if \code{calc="close"}).} \item{n}{Number of periods for the volatility estimate.} \item{calc}{The calculation (type) of estimator to use.} \item{N}{Number of periods per year.} \item{mean0}{Use a mean of 0 rather than the sample mean.} \item{\dots}{Arguments to be passed to/from other methods.} } \value{ A object of the same class as \code{OHLC} or a vector (if \code{try.xts} fails) containing the chosen volatility estimator values. } \description{ Selected volatility estimators/indicators; various authors. } \details{ \itemize{ \item Close-to-Close Volatility (\code{calc="close"})\cr \deqn{ \sigma_{cl} = \sqrt{\frac{N}{n-2} \sum_{i=1}^{n-1}(r_i-\bar{r})^2} }{sqrt(N) * runSD(ROC(Cl), n-1)} \deqn{where\;\; r_i = \log \left(\frac{C_i}{C_{i-1}}\right) }{} \deqn{and\;\; \bar{r} = \frac{r_1+r_2+\ldots +r_{n-1}}{n-1} }{} \item OHLC Volatility: Garman and Klass (\code{calc="garman.klass"})\cr The Garman and Klass estimator for estimating historical volatility assumes Brownian motion with zero drift and no opening jumps (i.e. the opening = close of the previous period). This estimator is 7.4 times more efficient than the close-to-close estimator.\cr \deqn{ \sigma = \sqrt{ \frac{N}{n} \sum \left[ \textstyle\frac{1}{2}\displaystyle \left( \log \frac{H_i}{L_i} \right)^2 - (2\log 2-1) \left( \log \frac{C_i}{O_i} \right)^2 \right] } }{sqrt(N/n * runSum(0.5 * log(Hi/Lo)^2 - (2*log(2)-1) * log(Cl/Op)^2, n))} \item High-Low Volatility: Parkinson (\code{calc="parkinson"})\cr The Parkinson formula for estimating the historical volatility of an underlying based on high and low prices.\cr \deqn{ \sigma = \sqrt{ \frac{N}{4 n \times \log 2} \sum_{i=1}^{n} \left(\log \frac{H_i}{L_i}\right)^2} }{sqrt(N/(4*n*log(2)) * runSum(log(Hi/Lo)^2, n))} \item OHLC Volatility: Rogers and Satchell (\code{calc="rogers.satchell"})\cr The Roger and Satchell historical volatility estimator allows for non-zero drift, but assumed no opening jump.\cr \deqn{ \sigma = \sqrt{ \textstyle\frac{N}{n} \sum \left[ \log \textstyle\frac{H_i}{C_i} \times \log \textstyle\frac{H_i}{O_i} + \log \textstyle\frac{L_i}{C_i} \times \log \textstyle\frac{L_i}{O_i} \right] } }{sqrt(N/n * runSum(log(Hi/Cl) * log(Hi/Op) + log(Lo/Cl) * log(Lo/Op), n))} \item OHLC Volatility: Garman and Klass - Yang and Zhang (\code{calc="gk.yz"})\cr This estimator is a modified version of the Garman and Klass estimator that allows for opening gaps.\cr \deqn{ \sigma = \sqrt{ \textstyle\frac{N}{n} \sum \left[ \left( \log \textstyle\frac{O_i}{C_{i-1}} \right)^2 + \textstyle\frac{1}{2}\displaystyle \left( \log \textstyle\frac{H_i}{L_i} \right)^2 - (2 \times \log 2-1) \left( \log \textstyle\frac{C_i}{O_i} \right)^2 \right] } }{sqrt(N/n * runSum(log(Op/lag(Cl,1))^2 + 0.5 * log(Hi/Lo)^2 - (2*log(2)-1) * log(Cl/Op)^2 , n))} \item OHLC Volatility: Yang and Zhang (\code{calc="yang.zhang"})\cr The Yang and Zhang historical volatility estimator has minimum estimation error, and is independent of drift and opening gaps. It can be interpreted as a weighted average of the Rogers and Satchell estimator, the close-open volatility, and the open-close volatility. Users may override the default values of \eqn{\alpha} (1.34 by default) or \eqn{k} used in the calculation by specifying \code{alpha} or \code{k} in \code{\dots}, respectively. Specifying \code{k} will cause \code{alpha} to be ignored, if both are provided.\cr \deqn{ \sigma^2 = \sigma_o^2 + k\sigma_c^2 + (1-k)\sigma_{rs}^2 }{ s <- sqrt(s2o + k*s2c + (1-k)*(s2rs^2)) } \deqn{ \sigma_o^2 =\textstyle \frac{N}{n-1} \sum \left( \log \frac{O_i}{C_{i-1}}-\mu_o \right)^2 }{ s2o <- N * runVar(log(Op/lag(Cl,1)), n=n) } \deqn{ \mu_o=\textstyle \frac{1}{n} \sum \log \frac{O_i}{C_{i-1}} }{} \deqn{ \sigma_c^2 =\textstyle \frac{N}{n-1} \sum \left( \log \frac{C_i}{O_i}-\mu_c \right)^2 }{ s2c <- N * runVar(log(Cl/Op), n=n) } \deqn{ \mu_c=\textstyle \frac{1}{n} \sum \log \frac{C_i}{O_i} }{} \deqn{ \sigma_{rs}^2 = \textstyle\frac{N}{n} \sum \left( \log \textstyle\frac{H_i}{C_i} \times \log \textstyle\frac{H_i}{O_i} + \log \textstyle\frac{L_i}{C_i} \times \log \textstyle\frac{L_i}{O_i} \right) }{ s2rs <- volatility(OHLC, n, "rogers.satchell", N, ...) } \deqn{ k=\frac{\alpha-1}{alpha+\frac{n+1}{n-1}} }{ k <- (alpha-1) / (alpha + (n+1)/(n-1)) } } } \examples{ data(ttrc) ohlc <- ttrc[,c("Open","High","Low","Close")] vClose <- volatility(ohlc, calc="close") vClose0 <- volatility(ohlc, calc="close", mean0=TRUE) vGK <- volatility(ohlc, calc="garman") vParkinson <- volatility(ohlc, calc="parkinson") vRS <- volatility(ohlc, calc="rogers") } \references{ The following sites were used to code/document these indicators. All were created by Thijs van den Berg under the GNU Free Documentation License and were retrieved on 2008-04-20. The original links are dead, but can be accessed via internet archives.\cr \cr Close-to-Close Volatility (\code{calc="close"}):\cr \url{https://web.archive.org/web/20100421083157/http://www.sitmo.com/eq/172}\cr \cr OHLC Volatility: Garman Klass (\code{calc="garman.klass"}):\cr \url{https://web.archive.org/web/20100326172550/http://www.sitmo.com/eq/402}\cr \cr High-Low Volatility: Parkinson (\code{calc="parkinson"}):\cr \url{https://web.archive.org/web/20100328195855/http://www.sitmo.com/eq/173}\cr \cr OHLC Volatility: Rogers Satchell (\code{calc="rogers.satchell"}):\cr \url{https://web.archive.org/web/20091002233833/http://www.sitmo.com/eq/414}\cr \cr OHLC Volatility: Garman Klass - Yang Zhang (\code{calc="gk.yz"}):\cr \url{https://web.archive.org/web/20100326215050/http://www.sitmo.com/eq/409}\cr \cr OHLC Volatility: Yang Zhang (\code{calc="yang.zhang"}):\cr \url{https://web.archive.org/web/20100326215050/http://www.sitmo.com/eq/409}\cr } \seealso{ See \code{\link{TR}} and \code{\link{chaikinVolatility}} for other volatility measures. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/aroon.Rd0000644000176200001440000000433613425330036013110 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/aroon.R \name{aroon} \alias{aroon} \title{Aroon} \usage{ aroon(HL, n = 20) } \arguments{ \item{HL}{Object that is coercible to xts or matrix and contains either a High-Low price series, or a Close price series.} \item{n}{Number of periods to use in the calculation.} } \value{ A object of the same class as \code{HL} or a matrix (if \code{try.xts} fails) containing the columns: \describe{ \item{ aroonUp }{ The Aroon up indicator. } \item{ aroonDn }{ The Aroon down indicator. } \item{ oscillator }{ The Aroon oscillator (\code{aroonUp - aroonDn}). } } } \description{ The Aroon indicator attempts to identify starting trends. The indicator consists of up and down lines, which measure how long it has been since the highest high/lowest low has occurred in the last \code{n} periods. Developed by Tushar Chande in 1995. } \details{ Aroon up (down) is the elapsed time, expressed as a percentage, between today and the highest (lowest) price in the last \code{n} periods. If today's price is a new high (low) Aroon up (down) will be 100. Each subsequent period without another new high (low) causes Aroon up (down) to decrease by (1 / \code{n}) x 100. } \note{ If High-Low prices are given, the function calculates the max/min using the high/low prices. Otherwise the function calculates the max/min of the single series. Up (down) trends are indicated when the aroonUp(Dn) is between 70 and 100. Strong trends are indicated when when the aroonUp(Dn) is above 70 while the aroonDn(Up) is below 30. Also, crossovers may be useful. } \examples{ ## Get Data and Indicator ## data(ttrc) trend <- aroon( ttrc[,c("High", "Low")], n=20 ) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/Aroon.htm}\cr \url{http://www.fmlabs.com/reference/AroonOscillator.htm}\cr \url{https://www.linnsoft.com/techind/aroon-arn}\cr \url{http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:aroon}\cr } \seealso{ See \code{\link{CCI}}, \code{\link{ADX}}, \code{\link{TDI}}, \code{\link{VHF}}, \code{\link{GMMA}} for other indicators that measure trend direction/strength. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/stochastics.Rd0000644000176200001440000001204213541716076014325 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/stochastics.R \name{stoch} \alias{stoch} \alias{stochastics} \alias{stochastic} \alias{SMI} \alias{\%K} \alias{\%D} \alias{SMI} \title{Stochastic Oscillator / Stochastic Momentum Index} \usage{ stoch(HLC, nFastK = 14, nFastD = 3, nSlowD = 3, maType, bounded = TRUE, smooth = 1, ...) SMI(HLC, n = 13, nFast = 2, nSlow = 25, nSig = 9, maType, bounded = TRUE, ...) } \arguments{ \item{HLC}{Object that is coercible to xts or matrix and contains High-Low-Close prices. If only a univariate series is given, it will be used. See details.} \item{nFastK}{Number of periods for fast \%K (i.e. the number of past periods to use).} \item{nFastD}{Number of periods for fast \%D (i.e. the number smoothing periods to apply to fast \%K).} \item{nSlowD}{Number of periods for slow \%D (i.e. the number smoothing periods to apply to fast \%D).} \item{maType}{Either: \enumerate{ \item A function or a string naming the function to be called. \item A \emph{list} with the first component like (1) above, and additional parameters specified as \emph{named} components. See Examples. }} \item{bounded}{Logical, should current period's values be used in the calculation?} \item{smooth}{Number of internal smoothing periods to be applied before calculating FastK. See Details.} \item{\dots}{Other arguments to be passed to the \code{maType} function in case (1) above.} \item{n}{Number of periods to use.} \item{nFast}{Number of periods for initial smoothing.} \item{nSlow}{Number of periods for double smoothing.} \item{nSig}{Number of periods for signal line.} } \value{ A object of the same class as \code{HLC} or a matrix (if \code{try.xts} fails) containing the columns: \describe{ \item{ fastK }{ Stochastic Fast \%K } \item{ fastD }{ Stochastic Fast \%D } \item{ slowD }{ Stochastic Slow \%D } \item{ SMI }{ Stochastic Momentum Index } \item{ signal }{ Stochastic Momentum Index signal line } } } \description{ The stochastic oscillator is a momentum indicator that relates the location of each day's close relative to the high/low range over the past \code{n} periods. Developed by George C. Lane in the late 1950s. The SMI relates the close to the midpoint of the high/low range. Developed by William Blau in 1993. } \details{ If a High-Low-Close series is provided, the indicator is calculated using the high/low values. If a vector is provided, the calculation only uses that series. This allows stochastics to be calculated for: (1) series that have no HLC definition (e.g. foreign exchange), and (2) stochastic indicators (e.g. stochastic RSI - see examples). The \code{smooth} argument is the number of periods of internal smoothing to apply to the differences in the high-low-close range before calculating Fast K. Thanks to Stanley Neo for the suggestion. } \note{ The calculation for William's \%R is similar to that of stochastics' fast \%K. The value for fast \%K will be 0.5 whenever the highest high and lowest low are the same over the last \code{n} periods. The stochastic oscillator and SMI calculate relative value of the close versus the high/low range and the midpoint of the high/low range, respectively. The stochastic oscillator and the stochastic momentum index are interpreted similarly. Readings below 20 (above 80) are considered oversold (overbought). However, readings below 20 (above 80) are not necessarily bearish (bullish). Lane believed some of the best sell (buy) signals occurred when the oscillator moved from overbought (oversold) back below 80 (above 20). For the stochastic oscillator, buy (sell) signals can also be given when \%K crosses above (below) \%D. Crossover signals are quite frequent however, which may result in whipsaws. } \examples{ data(ttrc) stochOSC <- stoch(ttrc[,c("High","Low","Close")]) stochWPR <- WPR(ttrc[,c("High","Low","Close")]) plot(tail(stochOSC[,"fastK"], 100), type="l", main="Fast \%K and Williams \%R", ylab="", ylim=range(cbind(stochOSC, stochWPR), na.rm=TRUE) ) lines(tail(stochWPR, 100), col="blue") lines(tail(1-stochWPR, 100), col="red", lty="dashed") stoch2MA <- stoch( ttrc[,c("High","Low","Close")], maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA)) ) SMI3MA <- SMI(ttrc[,c("High","Low","Close")], maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA)) ) stochRSI <- stoch( RSI(ttrc[,"Close"]) ) } \references{ The following site(s) were used to code/document these indicators: \cr Stochastic Oscillator:\cr \url{http://www.fmlabs.com/reference/StochasticOscillator.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=106}\cr \url{https://www.linnsoft.com/techind/stochastics}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:stochastic_oscillator_fast_slow_and_full}\cr \cr SMI:\cr \url{http://www.fmlabs.com/reference/default.htm?url=SMI.htm}\cr } \seealso{ See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average options; and note Warning section. See \code{\link{WPR}} to compare it's results to fast \%K. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/RSI.Rd0000644000176200001440000000521013425330036012417 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/RSI.R \name{RSI} \alias{RSI} \title{Relative Strength Index} \usage{ RSI(price, n = 14, maType, ...) } \arguments{ \item{price}{Price series that is coercible to xts or matrix.} \item{n}{Number of periods for moving averages.} \item{maType}{Either: \enumerate{ \item A function or a string naming the function to be called. \item A \emph{list} with the first component like (1) above, and additional parameters specified as \emph{named} components. See Examples. }} \item{\dots}{Other arguments to be passed to the \code{maType} function in case (1) above.} } \value{ A object of the same class as \code{price} or a vector (if \code{try.xts} fails) containing the RSI values. } \description{ The Relative Strength Index (RSI) calculates a ratio of the recent upward price movements to the absolute price movement. Developed by J. Welles Wilder. } \details{ The RSI calculation is \code{RSI = 100 - 100 / ( 1 + RS )}, where \code{RS} is the smoothed ratio of 'average' gains over 'average' losses. The 'averages' aren't true averages, since they're divided by the value of \code{n} and not the number of periods in which there are gains/losses. } \note{ The RSI is usually interpreted as an overbought/oversold (over 70 / below 30) indicator. Divergence with price may also be useful. For example, if price is making new highs/lows, but RSI is not, it could indicate a reversal. You can calculate a stochastic RSI by using the function \code{\link{stoch}} on RSI values. } \examples{ data(ttrc) price <- ttrc[,"Close"] # Default case rsi <- RSI(price) # Case of one 'maType' for both MAs rsiMA1 <- RSI(price, n=14, maType="WMA", wts=ttrc[,"Volume"]) # Case of two different 'maType's for both MAs rsiMA2 <- RSI(price, n=14, maType=list(maUp=list(EMA,ratio=1/5), maDown=list(WMA,wts=1:10))) } \references{ The following site(s) were used to code/document this indicator: \cr Relative Strength Index:\cr \url{http://www.fmlabs.com/reference/RSI.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=100}\cr \url{https://www.linnsoft.com/techind/relative-strength-index-rsi}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:relative_strength_index_rsi}\cr \cr Stochastic RSI:\cr \url{http://www.fmlabs.com/reference/StochRSI.htm}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:stochrsi}\cr } \seealso{ See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average options; and note Warning section. See \code{\link{CMO}} for a variation on RSI. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/DVI.Rd0000644000176200001440000000311013541716076012414 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DVI.R \name{DVI} \alias{DVI} \title{DV Intermediate Oscillator} \usage{ DVI(price, n = 252, wts = c(0.8, 0.2), smooth = 3, magnitude = c(5, 100, 5), stretch = c(10, 100, 2), exact.multiplier = 1) } \arguments{ \item{price}{Price series that is coercible to xts or matrix.} \item{n}{Number of periods for the percent rank.} \item{wts}{The weight given to the smoothed returns (magnitude) component and the up/down days (stretch) component, respectively.} \item{smooth}{The number of periods to smooth price.} \item{magnitude}{A set of 3 periods used to smooth magnitude.} \item{stretch}{A set of 3 periods used to smooth stretch.} \item{exact.multiplier}{The weight applied to identical values in the window. See \code{runPercentRank}.} } \value{ A object of the same class as \code{price} or a vector (if \code{try.xts} fails) containing the DVI values. } \description{ The DV Intermediate oscillator (DVI) is a very smooth momentum oscillator that can also be used as a trend indicator. Created by David Varadi. } \details{ The DVI combines smoothed returns over different time windows and the relative number of up versus down days (stretch) over different time windows. } \examples{ data(ttrc) dvi <- DVI(ttrc[,"Close"]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://cssanalytics.wordpress.com/2009/12/13/what-is-the-dvi/}\cr \url{http://marketsci.wordpress.com/2010/07/27/css-analytics\%E2\%80\%99-dvi-indicator-revealed/}\cr } \author{ Joshua Ulrich } \keyword{ts} TTR/man/OBV.Rd0000644000176200001440000000262413575211353012424 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/OBV.R \name{OBV} \alias{OBV} \title{On Balance Volume (OBV)} \usage{ OBV(price, volume) } \arguments{ \item{price}{Price series that is coercible to xts or matrix.} \item{volume}{Volume series that is coercible to xts or matrix, that corresponds to price object.} } \value{ A object of the same class as \code{price} and \code{volume} or a vector (if \code{try.xts} fails) containing the OBV values. } \description{ On Balance Volume (OBV) is a measure of the money flowing into or out of a security. It is similar to Chaikin Accumulation / Distribution. } \details{ OBV is calculated by adding (subtracting) each day's volume to a running cumulative total when the security's price closes higher (lower). } \note{ OBV is usually compared with the price chart of the underlying security to look for divergences/confirmation. } \examples{ data(ttrc) obv <- OBV(ttrc[,"Close"], ttrc[,"Volume"]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/OBV.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=82}\cr \url{https://www.linnsoft.com/techind/balance-open-interest}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:on_balance_volume_obv}\cr } \seealso{ See \code{\link{chaikinAD}}. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/SNR.Rd0000644000176200001440000000236313425330036012432 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/SNR.R \name{SNR} \alias{SNR} \title{Signal to Noise Ratio} \usage{ SNR(HLC, n, ...) } \arguments{ \item{HLC}{Object that is coercible to xts or matrix and contains High-Low-Close prices.} \item{n}{Number of periods for moving average.} \item{...}{Other arguments to be passed to \code{\link{ATR}}.} } \value{ A object of the same class as HLC or a matrix (if try.xts fails) containing the signal to noise ratio. } \description{ The n-day SNR for a given market is calculated by taking the absolute price change over an n-day period and dividing it by the average n-day volatility. } \details{ \deqn{SNR_n = \frac{|C_t - C_{t-n}|}{ATR_n} }{SNR = abs(Cl - lag(Cl,n)) / ATR(HLC, n)$atr} Using average true range as the volatility measure captures more of the intraday and overnight volatility in a way that a measurement of Close-to-Close price change does not. The interpretation is then relatively intuitive: an SNR value of five indicates that the market has moved five times the volatility (average true range) over the given look-back period. } \references{ Skeggs, James and Hill, Alex (2015). Back in Black Part 2: The Opportunity Set for Trend Following. } \author{ Peter Carl } TTR/man/GMMA.Rd0000644000176200001440000000310613541716076012520 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/GMMA.R \name{GMMA} \alias{GMMA} \alias{Guppy} \alias{guppy} \title{Guppy Multiple Moving Averages} \usage{ GMMA(x, short = c(3, 5, 8, 10, 12, 15), long = c(30, 35, 40, 45, 50, 60), maType) } \arguments{ \item{x}{Price, volume, etc. series that is coercible to xts or matrix.} \item{short}{Vector of short-term periods.} \item{long}{Vector of long-term periods.} \item{maType}{Either: \enumerate{ \item A function or a string naming the function to be called. \item A \emph{list} with the first component like (1) above, and additional parameters specified as \emph{named} components. See Examples. }} } \value{ A object of the same class as \code{x} or \code{price} or a vector (if \code{try.xts} fails) containing the Guppy Multiple Moving Average. } \description{ Calculate the Guppy Multiple Moving Average of a series. } \details{ The Guppy Multiple Moving Average signals a changing trend when the \code{short} and \code{long} groups of moving averages intersect. An up/down trend exists when the short/long-term moving averages are greater than the long/short-term averages. } \examples{ data(ttrc) gmma <- GMMA(ttrc[,"Close"]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.investopedia.com/terms/g/guppy-multiple-moving-average.asp}\cr } \seealso{ See \code{\link{aroon}}, \code{\link{CCI}}, \code{\link{ADX}}, \code{\link{VHF}}, \code{\link{TDI}} for other indicators that measure trend direction/strength. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/changes.Rd0000644000176200001440000000223713552670134013407 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/changes.R \name{ROC} \alias{ROC} \alias{changes} \alias{momentum} \title{Rate of Change / Momentum} \usage{ ROC(x, n = 1, type = c("continuous", "discrete"), na.pad = TRUE) momentum(x, n = 1, na.pad = TRUE) } \arguments{ \item{x}{Price, volume, etc. series that is coercible to xts or matrix.} \item{n}{Number of periods to use.} \item{type}{Compounding type; either \code{"continuous"} (the default) or \code{"discrete"}.} \item{na.pad}{Should periods prior to \code{n} be appended? Default is \code{TRUE}.} } \value{ A object of the same class as \code{x} or a vector (if \code{try.xts} fails) containing the rate-of-change (or return) values for \code{ROC} or a vector containing the differenced price series for \code{momentum}. } \description{ Calculate the (rate of) change of a series over \code{n} periods. } \details{ The ROC indicator provides the percentage difference of a series over two observations, while the momentum indicator simply provides the difference. } \examples{ data(ttrc) roc <- ROC(ttrc[,"Close"]) mom <- momentum(ttrc[,"Close"]) } \author{ Joshua Ulrich } \keyword{ts} TTR/man/WPR.Rd0000644000176200001440000000324413425330036012437 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/WPR.R \name{WPR} \alias{WPR} \title{William's \%R} \usage{ WPR(HLC, n = 14) } \arguments{ \item{HLC}{Object that is coercible to xts or matrix and contains High-Low-Close prices. If only a univariate series is given, it will be used. See details.} \item{n}{Number of periods to use.} } \value{ A object of the same class as \code{HLC} or a vector (if \code{try.xts} fails) containing the William's \%R values. } \description{ William's \% R. } \details{ If an High-Low-Close series is provided, the indicator is calculated using the high/low values. If a vector is provided, the calculation only uses that series. } \note{ The William's \%R calculation is similar to stochastics' fast \%K. The value for William's \%R will be 0.5 whenever the highest high and lowest low are the same over the last \code{n} periods. } \examples{ data(ttrc) stochOsc <- stoch(ttrc[,c("High","Low","Close")]) stochWPR<- WPR(ttrc[,c("High","Low","Close")]) plot(tail(stochOsc[,"fastK"], 100), type="l", main="Fast \%K and Williams \%R", ylab="", ylim=range(cbind(stochOsc, stochWPR), na.rm=TRUE) ) lines(tail(stochWPR, 100), col="blue") lines(tail(1-stochWPR, 100), col="red", lty="dashed") } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/WilliamsR.htm}\cr \url{http://www.metastock.com/Customer/Resources/TAAZ/#126}\cr \url{https://www.linnsoft.com/techind/williams-r-wpr}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:williams_r}\cr } \seealso{ See \code{\link{stoch}}. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/TTR.Rd0000644000176200001440000000340713541716076012454 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TTR-package.R \docType{package} \name{TTR} \alias{TTR} \alias{TTR-package} \title{Functions to create Technical Trading Rules (TTR)} \description{ This package contains many of the most popular technical analysis functions, as well as functions to retrieve U.S. stock symbols, and data from Yahoo Finance. } \details{ Users will probably be most interested in the following functions:\cr \code{\link{ADX}}\cr \code{\link{BBands}}\cr \code{\link{changes}}\cr \code{\link{MovingAverages}}\cr \code{\link{MACD}}\cr \code{\link{RSI}}\cr \code{\link{runFun}}\cr \code{\link{stoch}}\cr \code{\link{VWAP}}\cr \code{\link{WebData}}\cr } \examples{ data(ttrc) # Bollinger Bands bbands <- BBands( ttrc[,c("High","Low","Close")] ) # Directional Movement Index adx <- ADX(ttrc[,c("High","Low","Close")]) # Moving Averages ema <- EMA(ttrc[,"Close"], n=20) sma <- SMA(ttrc[,"Close"], n=20) # MACD macd <- MACD( ttrc[,"Close"] ) # RSI rsi <- RSI(ttrc[,"Close"]) # Stochastics stochOsc <- stoch(ttrc[,c("High","Low","Close")]) ### Note: you must have a working internet connection ### for the examples below to work! if (interactive()) { # Fetch U.S. symbols from the internet nyseSymbols <- stockSymbols("NYSE") # Fetch Yahoo! Finance data from the internet ge <- getYahooData("GE", 19990404, 20050607, adjust = FALSE) } } \references{ The following sites were used to code/document this package:\cr \url{http://www.fmlabs.com/reference/default.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/}\cr \url{https://www.linnsoft.com/indicators}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators}\cr } \author{ Joshua Ulrich Maintainer: Joshua Ulrich } \keyword{package} TTR/man/runPercentRank.Rd0000644000176200001440000000322113541716076014736 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/percentRank.R \name{runPercentRank} \alias{runPercentRank} \alias{percentRank} \alias{PercentRank} \title{Percent Rank over a Moving Window} \usage{ runPercentRank(x, n = 260, cumulative = FALSE, exact.multiplier = 0.5) } \arguments{ \item{x}{Object coercible to xts or matrix.} \item{n}{Number of periods to use in the window or, if \code{cumulative=TRUE}, the number of observations to use before the first result is returned. Must be between 1 and \code{nrow(x)}, inclusive.} \item{cumulative}{Logical, use from-inception calculation?} \item{exact.multiplier}{The weight applied to identical values in the window. Must be between 0 and 1, inclusive. See details.} } \value{ A object of percent ranks over a n-period moving window of the same class as \code{x} and \code{y} or a vector (if \code{try.xts} fails). } \description{ This function computes a running/rolling percentage rank. } \details{ The computation for a percentage rank can vary depending on the weight given to values in the window identical to the value being ranked. This weight can be set using the \code{exact.multiplier} argument which defaults to 0.5. } \note{ It may be important to note that this computation is different from the one used in Microsoft Excel's PERCENTRANK formula. Excel's computation is rather strange and gives inconsistent results as it uses interpolation to rank values that are not found within the lookback window. } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://en.wikipedia.org/wiki/Percentile_rank}\cr } \author{ Charlie Friedemann } \keyword{ts} TTR/man/chaikinAD.Rd0000644000176200001440000000324613425330036013604 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/chaikinAD.R \name{chaikinAD} \alias{chaikinAD} \title{Chaikin Accumulation / Distribution} \usage{ chaikinAD(HLC, volume) } \arguments{ \item{HLC}{Object that is coercible to xts or matrix and contains High-Low-Close prices.} \item{volume}{Vector or matrix of volume observations corresponding to the \code{HLC} object.} } \value{ A object of the same class as \code{HLC} and \code{volume} or a vector (if \code{try.xts} fails) containing the accumulation / distribution values. } \description{ The Chaikin Accumulation / Distribution (AD) line is a measure of the money flowing into or out of a security. It is similar to On Balance Volume (OBV). Developed by Marc Chaikin. } \details{ The AD line is similar to OBV; the difference is that OBV sums volume multiplied by +/- 1 if the close is higher/lower than the previous close, while the AD line multiplies volume by the close location value (CLV). } \note{ The Accumulation/Distribution Line is interpreted by looking for a divergence in the direction of the indicator relative to price. } \examples{ data(ttrc) ad <- chaikinAD(ttrc[,c("High","Low","Close")], ttrc[,"Volume"]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/AccumDist.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=27}\cr \url{https://www.linnsoft.com/techind/accumulation-distribution}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:accumulation_distribution_line}\cr } \seealso{ See \code{\link{OBV}}, and \code{\link{CLV}}. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/bollingerBands.Rd0000644000176200001440000000523513425330036014716 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/bollingerBands.R \name{BBands} \alias{BBands} \alias{bollingerBands} \title{Bollinger Bands} \usage{ BBands(HLC, n = 20, maType, sd = 2, ...) } \arguments{ \item{HLC}{Object that is coercible to xts or matrix and contains High-Low-Close prices. If only a univariate series is given, it will be used. See details.} \item{n}{Number of periods for moving average.} \item{maType}{A function or a string naming the function to be called.} \item{sd}{The number of standard deviations to use.} \item{\dots}{Other arguments to be passed to the \code{maType} function.} } \value{ A object of the same class as \code{HLC} or a matrix (if \code{try.xts} fails) containing the columns: \describe{ \item{ dn }{ The lower Bollinger Band. } \item{ mavg }{ The middle Moving Average (see notes). } \item{ up }{ The upper Bollinger Band. } \item{ pctB }{ The \%B calculation. } } } \description{ Bollinger Bands are a way to compare a security's volatility and price levels over a period of time. Developed by John Bollinger. } \details{ Bollinger Bands consist of three lines: The middle band is generally a 20-period SMA of the typical price ([high + low + close]/3). The upper and lower bands are \code{sd} standard deviations (generally 2) above and below the MA. The middle band is usually calculated using the typical price, but if a univariate series (e.g. Close, Weighted Close, Median Price, etc.) is provided, it will be used instead. } \note{ Using any moving average other than SMA will result in inconsistencies between the moving average calculation and the standard deviation calculation. Since, by definition, a rolling standard deviation uses a simple moving average. } \examples{ ## The examples below show the differences between using a ## High-Low-Close series, and just a close series when ## calculating Bollinger Bands. data(ttrc) bbands.HLC <- BBands( ttrc[,c("High","Low","Close")] ) bbands.close <- BBands( ttrc[,"Close"] ) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/Bollinger.htm}\cr \url{http://www.fmlabs.com/reference/BollingerWidth.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=36}\cr \url{https://www.linnsoft.com/techind/bollinger-bands}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:bollinger_bands}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:bollinger_band_width}\cr } \seealso{ See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average options; and note Warning section. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/MovingAverages.Rd0000644000176200001440000001540513552670134014715 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/MovingAverages.R \name{SMA} \alias{SMA} \alias{MovingAverages} \alias{EMA} \alias{WMA} \alias{DEMA} \alias{GD} \alias{T3} \alias{EVWMA} \alias{ZLEMA} \alias{VWAP} \alias{VWMA} \alias{VMA} \alias{MA} \alias{HMA} \alias{ALMA} \title{Moving Averages} \usage{ SMA(x, n = 10, ...) EMA(x, n = 10, wilder = FALSE, ratio = NULL, ...) DEMA(x, n = 10, v = 1, wilder = FALSE, ratio = NULL) WMA(x, n = 10, wts = 1:n, ...) EVWMA(price, volume, n = 10, ...) ZLEMA(x, n = 10, ratio = NULL, ...) VWAP(price, volume, n = 10, ...) VMA(x, w, ratio = 1, ...) HMA(x, n = 20, ...) ALMA(x, n = 9, offset = 0.85, sigma = 6, ...) } \arguments{ \item{x}{Price, volume, etc. series that is coercible to xts or matrix.} \item{n}{Number of periods to average over. Must be between 1 and \code{nrow(x)}, inclusive.} \item{\dots}{any other passthrough parameters} \item{wilder}{logical; if \code{TRUE}, a Welles Wilder type EMA will be calculated; see notes.} \item{ratio}{A smoothing/decay ratio. \code{ratio} overrides \code{wilder} in \code{EMA}, and provides additional smoothing in \code{VMA}.} \item{v}{The 'volume factor' (a number in [0,1]). See Notes.} \item{wts}{Vector of weights. Length of \code{wts} vector must equal the length of \code{x}, or \code{n} (the default).} \item{price}{Price series that is coercible to xts or matrix.} \item{volume}{Volume series that is coercible to xts or matrix, that corresponds to price series, or a constant. See Notes.} \item{w}{Vector of weights (in [0,1]) the same length as \code{x}.} \item{offset}{Percentile at which the center of the distribution should occur.} \item{sigma}{Standard deviation of the distribution.} } \value{ A object of the same class as \code{x} or \code{price} or a vector (if \code{try.xts} fails) containing the columns: \describe{ \item{SMA}{ Simple moving average. } \item{EMA}{ Exponential moving average. } \item{WMA}{ Weighted moving average. } \item{DEMA}{ Double-exponential moving average. } \item{EVWMA}{ Elastic, volume-weighted moving average. } \item{ZLEMA}{ Zero lag exponential moving average. } \item{VWMA}{ Volume-weighed moving average (same as \code{VWAP}). } \item{VWAP}{ Volume-weighed average price (same as \code{VWMA}). } \item{VWA}{ Variable-length moving average. } \item{HMA}{ Hull moving average. } \item{ALMA}{ Arnaud Legoux moving average. } } } \description{ Calculate various moving averages (MA) of a series. } \details{ \code{SMA} calculates the arithmetic mean of the series over the past \code{n} observations. \code{EMA} calculates an exponentially-weighted mean, giving more weight to recent observations. See Warning section below. \code{WMA} is similar to an EMA, but with linear weighting if the length of \code{wts} is equal to \code{n}. If the length of \code{wts} is equal to the length of \code{x}, the WMA will use the values of \code{wts} as weights. \code{DEMA} is calculated as: \code{DEMA = (1 + v) * EMA(x,n) - EMA(EMA(x,n),n) * v} (with the corresponding \code{wilder} and \code{ratio} arguments). \code{EVWMA} uses volume to define the period of the MA. \code{ZLEMA} is similar to an EMA, as it gives more weight to recent observations, but attempts to remove lag by subtracting data prior to \code{(n-1)/2} periods (default) to minimize the cumulative effect. \code{VWMA} and \code{VWAP} calculate the volume-weighted moving average price. \code{VMA} calculate a variable-length moving average based on the absolute value of \code{w}. Higher (lower) values of \code{w} will cause \code{VMA} to react faster (slower). \code{HMA} a WMA of the difference of two other WMAs, making it very reponsive. \code{ALMA} inspired by Gaussian filters. Tends to put less weight on most recent observations, reducing tendency to overshoot. } \note{ For \code{EMA}, \code{wilder=FALSE} (the default) uses an exponential smoothing ratio of \code{2/(n+1)}, while \code{wilder=TRUE} uses Welles Wilder's exponential smoothing ratio of \code{1/n}. The \code{EMA} result is initialized with the \code{n}-period sample average at period \code{n}. The exponential decay is applied from that point forward. Since \code{WMA} can accept a weight vector of length equal to the length of \code{x} or of length \code{n}, it can be used as a regular weighted moving average (in the case \code{wts=1:n}) or as a moving average weighted by volume, another indicator, etc. Since \code{DEMA} allows adjusting \code{v}, it is technically Tim Tillson's generalized DEMA (GD). When \code{v=1} (the default), the result is the standard DEMA. When \code{v=0}, the result is a regular EMA. All other values of \code{v} return the GD result. This function can be used to calculate Tillson's T3 indicator (see example below). Thanks to John Gavin for suggesting the generalization. For \code{EVWMA}, if \code{volume} is a series, \code{n} should be chosen so the sum of the volume for \code{n} periods approximates the total number of outstanding shares for the security being averaged. If \code{volume} is a constant, it should represent the total number of outstanding shares for the security being averaged. } \section{Warning }{ Some indicators (e.g. EMA, DEMA, EVWMA, etc.) are calculated using the indicators' own previous values, and are therefore unstable in the short-term. As the indicator receives more data, its output becomes more stable. See example below. } \examples{ data(ttrc) ema.20 <- EMA(ttrc[,"Close"], 20) sma.20 <- SMA(ttrc[,"Close"], 20) dema.20 <- DEMA(ttrc[,"Close"], 20) evwma.20 <- EVWMA(ttrc[,"Close"], ttrc[,"Volume"], 20) zlema.20 <- ZLEMA(ttrc[,"Close"], 20) alma <- ALMA(ttrc[,"Close"]) hma <- HMA(ttrc[,"Close"]) ## Example of Tim Tillson's T3 indicator T3 <- function(x, n=10, v=1) DEMA(DEMA(DEMA(x,n,v),n,v),n,v) t3 <- T3(ttrc[,"Close"]) ## Example of short-term instability of EMA ## (and other indicators mentioned above) x <- rnorm(100) tail( EMA(x[90:100],10), 1 ) tail( EMA(x[70:100],10), 1 ) tail( EMA(x[50:100],10), 1 ) tail( EMA(x[30:100],10), 1 ) tail( EMA(x[10:100],10), 1 ) tail( EMA(x[ 1:100],10), 1 ) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/ExpMA.htm}\cr \url{http://www.fmlabs.com/reference/WeightedMA.htm}\cr \url{http://www.fmlabs.com/reference/DEMA.htm}\cr \url{http://www.fmlabs.com/reference/T3.htm}\cr \url{https://www.linnsoft.com/techind/evwma-elastic-volume-weighted-moving-average}\cr \url{http://www.fmlabs.com/reference/ZeroLagExpMA.htm}\cr \url{http://www.fmlabs.com/reference/VIDYA.htm}\cr \url{http://www.traderslog.com/hullmovingaverage}\cr \url{http://www.arnaudlegoux.com/}\cr } \seealso{ See \code{\link{wilderSum}}, which is used in calculating a Welles Wilder type MA. } \author{ Joshua Ulrich, Ivan Popivanov (HMA, ALMA) } \keyword{ts} TTR/man/WebData.Rd0000644000176200001440000000635613552670134013314 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/WebData.R \name{stockSymbols} \alias{stockSymbols} \alias{WebData} \alias{getYahooData} \title{Fetch Internet Data} \usage{ stockSymbols(exchange = c("AMEX", "NASDAQ", "NYSE"), sort.by = c("Exchange", "Symbol"), quiet = FALSE) getYahooData(symbol, start, end, freq = "daily", type = "price", adjust = TRUE, quiet = FALSE) } \arguments{ \item{exchange}{Character vector of exchange names on which desired instrument symbols are traded.} \item{sort.by}{Character vector of columns by which returned data will be sorted. Must be one or more of \code{"Name"}, \code{"Symbol"}, \code{"Market.Cap"}, or \code{"Exchange"}.} \item{quiet}{Logical; if \code{TRUE}, status messages will be printed to the console.} \item{symbol}{Yahoo! Finance instrument symbol.} \item{start}{Numeric; first date of desired data, in YYYYMMDD format. Default is first date of series.} \item{end}{Numeric; last date of desired data, in YYYYMMDD format. Default is last date of series.} \item{freq}{Desired data frequency. One of \code{"daily"}, \code{"weekly"}, \code{"monthly"}.} \item{type}{Type of data to return. One of \code{"price"}, or \code{"split"}. \code{type="split"} will return both split and dividend data.} \item{adjust}{Logical; if \code{TRUE}, the Open, High, Low, and Close prices will be adjusted for dividends and splits, and Volume will be adjusted for dividends.} } \value{ \code{getYahooData} returns an xts object containing the columns: \code{stockSymbols} returns a character vector containing all the listed symbols for the given exchanges. \describe{ \item{ Date }{ Trade date, in CCYYMMDD format. } \item{ Open }{ Open price. } \item{ High }{ High price. } \item{ Low }{ Low price. } \item{ Close }{ Close price. } \item{ Volume }{ Volume. } } } \description{ Get investment data from the internet. } \details{ \code{getYahooData} fetches individual stock data from the Yahoo! Finance website. It also adjusts price for splits and dividends, and volume for splits. See the Warning section, and note that it is deprecated in favor of getSymbols in the quantmod package. \code{stockSymbols} fetches instrument symbols from the nasdaq.com website, and adjusts the symbols to be compatible with the Yahoo! Finance website. } \note{ The symbols returned by \code{stockSymbols} may not be in the format necessary to retrieve data using \code{getYahooData}. \code{getYahooData} has only been tested on daily data. It isn't known if the function correctly adjusts data for any other frequency. } \section{Warning}{ As of TTR 0.23-2, \code{getYahooData} has been patched to work with changes to Yahoo Finance, which also included the following changes to the raw data: \itemize{ \item The adjusted close column appears to no longer include dividend adjustments \item The open, high, and low columns are adjusted for splits, and \item The raw data may contain missing values. \item The raw data may contain errors. } } \examples{ ### Note: you must have a working internet ### connection for these examples to work! if (interactive()) { ge <- getYahooData("GE", 19990404, 20050607, adjust = FALSE) nyse.symbols <- stockSymbols("NYSE") } } \author{ Joshua Ulrich } \keyword{ts} TTR/man/ZigZag.Rd0000644000176200001440000000420313552670134013165 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ZigZag.R \name{ZigZag} \alias{ZigZag} \alias{zigzag} \title{Zig Zag} \usage{ ZigZag(HL, change = 10, percent = TRUE, retrace = FALSE, lastExtreme = TRUE) } \arguments{ \item{HL}{Object that is coercible to xts or matrix and contains either a High-Low price series, or a Close price series.} \item{change}{Minimum price movement, either in dollars or percent (see \code{percent}).} \item{percent}{Use percentage or dollar change?} \item{retrace}{Is \code{change} a retracement of the previous move, or an absolute change from peak to trough?} \item{lastExtreme}{If the extreme price is the same over multiple periods, should the extreme price be the first or last observation?} } \value{ A object of the same class as \code{HL} or a vector (if \code{try.xts} fails) containing the Zig Zag indicator. } \description{ Zig Zag higlights trends by removing price changes smaller than \code{change} and interpolating lines between the extreme points. } \details{ The Zig Zag is non-predictive. The purpose of the Zig Zag is filter noise and make chart patterns clearer. It's more a visual tool than an indicator. } \note{ If High-Low prices are given, the function calculates the max/min using the high/low prices. Otherwise the function calculates the max/min of the single series. } \section{Warning}{ The last value of the ZigZag indicator is unstable (i.e. unknown) until the turning point actually occurs. Therefore this indicator isn't well-suited for use for systematic trading strategies. } \examples{ ## Get Data and Indicator ## data(ttrc) zz <- ZigZag( ttrc[,c("High", "Low")], change=20 ) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/default.htm?url=ZigZag.htm}\cr \url{https://www.linnsoft.com/techind/zig-zag-indicator-zig-zzo}\cr \url{https://www.linnsoft.com/techind/zig-zag-oscillator-indicator-zzo}\cr \url{http://www.metastock.com/Customer/Resources/TAAZ/#127}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:zigzag}\cr } \author{ Joshua Ulrich } \keyword{ts} TTR/man/ultimateOscillator.Rd0000644000176200001440000000172613425330036015652 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ultimateOscillator.R \name{ultimateOscillator} \alias{ultimateOscillator} \title{The Ultimate Oscillator} \usage{ ultimateOscillator(HLC, n = c(7, 14, 28), wts = c(4, 2, 1)) } \arguments{ \item{HLC}{Object that is coercible to xts or matrix and contains High-Low-Close prices.} \item{n}{A vector of the number of periods to use for each average calculation.} \item{wts}{The weights applied to each average.} } \description{ The Ultimate Oscillator is a momentum oscillator designed to capture momentum across three different time frames. } \details{ Created by Larry Williams in 1976. } \examples{ data(ttrc) ult.osc <- ultimateOscillator(ttrc[,c("High","Low","Close")]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:ultimate_oscillator}\cr } \author{ Ivan Popivanov } \keyword{ts} TTR/man/EMV.Rd0000644000176200001440000000370113425330036012414 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/EMV.R \name{EMV} \alias{EMV} \title{Arms' Ease of Movement Value} \usage{ EMV(HL, volume, n = 9, maType, vol.divisor = 10000, ...) } \arguments{ \item{HL}{Object that is coercible to xts or matrix and contains High-Low prices.} \item{volume}{Vector or matrix of volume observations corresponding to the \code{HL} object.} \item{n}{Number of periods for moving average.} \item{maType}{A function or a string naming the function to be called.} \item{vol.divisor}{An increment to make the results larger and easier to work with.} \item{\dots}{Other arguments to be passed to the \code{maType} function.} } \value{ A object of the same class as \code{HL} and \code{volume} or a matrix (if \code{try.xts} fails) containing the columns: \describe{ \item{ emv }{ The ease of movement values. } \item{ maEMV }{ The smoothed (as specified by \code{ma}) ease of movement values. } } } \description{ Arms' Ease of Movement Value (EMV) emphasizes days where the security moves easily and minimizes days where the security does not move easily. Developed by Richard W. Arms, Jr. } \details{ The EMV is calculated by dividing the midpoint ([high + low]/2) move by the 'Box Ratio' (volume divided by the high minus low). } \note{ A buy/sell signal is generated when the EMV crosses above/below zero. When the EMV hovers around zero, there are small price movements and/or high volume, and the price is not moving easily. } \examples{ data(ttrc) emv <- EMV(ttrc[,c("High","Low")], ttrc[,"Volume"]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/ArmsEMV.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=51}\cr \url{https://www.linnsoft.com/techind/arms-ease-movement}\cr } \seealso{ See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average options; and note Warning section. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/TRIX.Rd0000644000176200001440000000434413425330036012557 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TRIX.R \name{TRIX} \alias{TRIX} \title{Triple Smoothed Exponential Oscillator} \usage{ TRIX(price, n = 20, nSig = 9, maType, percent = TRUE, ...) } \arguments{ \item{price}{Price series that is coercible to xts or matrix.} \item{n}{Number of periods for moving average.} \item{nSig}{Number of periods for signal line moving average.} \item{maType}{Either: \enumerate{ \item A function or a string naming the function to be called. \item A \emph{list} with the first component like (1) above, and additional parameters specified as \emph{named} components. See Examples. }} \item{percent}{logical; if \code{TRUE}, the rate of change is calculated using the \code{ROC} function, otherwise the \code{momentum} function is used.} \item{\dots}{Other arguments to be passed to the \code{maType} function in case (1) above.} } \value{ A object of the same class as \code{price} or a vector (if \code{try.xts} fails) containing the TRIX values. } \description{ The TRIX indicator calculates the rate of change of a triple exponential moving average. Developed by Jack K. Hutson. } \details{ The TRIX is calculated as follows:\cr 3MA = \code{MA}( \code{MA}( \code{MA}(\code{price}) ) )\cr trix = 100 * [ 3MA(t) / 3MA(t-1) - 1 ] } \note{ Buy/sell signals are generated when the TRIX crosses above/below zero. A nine-period EMA of the TRIX is used as a default signal line. Buy/sell signals are generated when the TRIX crosses above/below the signal line and is also above/below zero. } \examples{ data(ttrc) trix <- TRIX(ttrc[,"Close"]) trix4 <- TRIX(ttrc[,"Close"], maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA), list(DEMA))) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/default.htm?url=TRIX.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=114}\cr \url{https://www.linnsoft.com/techind/trix-triple-smoothed-exponential-oscillator}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:trix}\cr } \seealso{ See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average options; and note Warning section. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/KST.Rd0000644000176200001440000000505613425330036012433 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/KST.R \name{KST} \alias{KST} \title{Know Sure Thing} \usage{ KST(price, n = c(10, 10, 10, 15), nROC = c(10, 15, 20, 30), nSig = 9, maType, wts = 1:NROW(n), ...) } \arguments{ \item{price}{Price series that is coercible to xts or matrix.} \item{n}{A vector of the number of periods to use in the MA calculations.} \item{nROC}{A vector of the number of periods to use in the ROC calculations.} \item{nSig}{The number of periods to use for the KST signal line.} \item{maType}{Either: \enumerate{ \item A function or a string naming the function to be called. \item A \emph{list} with the first component like (1) above, and additional parameters specified as \emph{named} components. See Examples. }} \item{wts}{A vector the same length as \code{n}, of the weight for each period (need not sum to one).} \item{\dots}{Other arguments to be passed to the \code{maType} function in case (1) above.} } \value{ A object of the same class as \code{price} or a vector (if \code{try.xts} fails) containing the Know Sure Thing values. } \description{ The Know Sure Thing (KST) is a smooth, summed, rate of change indicator. Developed by Martin Pring. } \details{ For each day (week, month, etc.), the KST calculates the ROC over several periods. Those ROCs are smoothed using the given moving averages, then multiplied by their respective weighting values. The resulting values are summed for each day (month, week, etc.). } \note{ The KST indicates bullish/bearish momentum as it crosses above/below its moving average. Because the KST tends to lead price action, look for trend confirmation in the price. The default arguments are for the daily KST. There is also the Long-Term KST, with arguments: \code{n=c(9, 12, 18, 24)} - where the periods are months, not days - and the moving average periods are 6, 6, 6, and 9 months, respectively. } \examples{ data(ttrc) kst <- KST(ttrc[,"Close"]) kst4MA <- KST(ttrc[,"Close"], maType=list(list(SMA),list(EMA),list(DEMA),list(WMA))) } \references{ The following site(s) were used to code/document this indicator:\cr \url{https://web.archive.org/web/20110715112957/http://www.pring.com/movieweb/daily_kst.htm}\cr \url{https://web.archive.org/web/20100101162707/http://www.pring.com/movieweb/KST_MCM.htm}\cr } \seealso{ See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average options; and note Warning section. See \code{\link{ROC}} for the rate-of-change function. See \code{\link{MACD}} for a generic oscillator. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/DonchianChannel.Rd0000644000176200001440000000357313425330036015010 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/DonchianChannel.R \name{DonchianChannel} \alias{DonchianChannel} \alias{Donchian} \title{Donchian Channel} \usage{ DonchianChannel(HL, n = 10, include.lag = FALSE) } \arguments{ \item{HL}{Object that is coercible to xts or matrix and contains High-Low prices.} \item{n}{Number of periods for moving average.} \item{include.lag}{Should values be lagged so that today's prices are not included in the calculation? See Note.} } \value{ A object of the same class as \code{HL} or a matrix (if \code{try.xts} fails) containing the columns: \describe{ \item{ high }{ The highest high series. } \item{ mid }{ The average of \code{high} and \code{low}. } \item{ low }{ The lowest low series. } } } \description{ Donchian Channels were created by Richard Donchian and were used to generate buy and sell signals for the Turtle Trading system. } \details{ Donchian Channels consist of two (sometimes three) lines: The top line is the highest high of the past \code{n} periods. The bottom line is the lowest low of the past \code{n} periods. The middle line is the average of the top and bottom lines. } \note{ The default of \code{include.lag=FALSE} makes \code{DonchainChannel} consistent with other \pkg{TTR} functions, in that it includes the current period in the calculation. The default is different than the original calculation, which would calculate the indicator using periods t-1 through t-n. Setting \code{include.lag=TRUE} will return the result of the original calculation. The default of this argument may change in the future. } \examples{ data(ttrc) dc <- DonchianChannel( ttrc[,c("High","Low")] ) } \references{ The following site(s) were used to code/document this indicator:\cr \url{https://www.linnsoft.com/techind/donchian-channels}\cr } \seealso{ See \code{\link{BBands}}. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/CCI.Rd0000644000176200001440000000425713425330036012372 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/CCI.R \name{CCI} \alias{CCI} \title{Commodity Channel Index} \usage{ CCI(HLC, n = 20, maType, c = 0.015, ...) } \arguments{ \item{HLC}{Object that is coercible to xts or matrix and contains High-Low-Close prices. If only a univariate series is given, it will be used. See details.} \item{n}{Number of periods for moving average.} \item{maType}{A function or a string naming the function to be called.} \item{c}{Constant to apply to the mean deviation.} \item{\dots}{Other arguments to be passed to the \code{maType} function.} } \value{ A object of the same class as \code{HLC} or a vector (if \code{try.xts} fails) containing the CCI values. } \description{ The Commodity Channel Index (CCI) attempts to identify starting and ending trends. } \details{ CCI relates the current price and the average of price over \code{n} periods. The CCI usually falls in a channel of -100 to 100. A basic CCI trading system is: Buy (sell) if CCI rises above 100 (falls below -100) and sell (buy) when it falls below 100 (rises above -100). CCI is usually calculated using the typical price, but if a univariate series (e.g. Close, Weighted Close, Median Price, etc.) is provided, it will be used instead. } \note{ If \code{HLC} is a High-Low-Close matrix, then typical price will be calculated. If \code{HLC} is a vector, then those values will be used instead of the typical price. } \examples{ data(ttrc) cci <- CCI(ttrc[,c("High","Low","Close")]) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/CCI.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=42}\cr \url{https://www.linnsoft.com/techind/cci-commodity-channel-index}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:commodity_channel_index_cci}\cr } \seealso{ See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average options; and note Warning section. See \code{\link{aroon}}, \code{\link{ADX}}, \code{\link{TDI}}, \code{\link{VHF}}, \code{\link{GMMA}} for other indicators that measure trend direction/strength. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/ttrc.Rd0000644000176200001440000000166413425330036012747 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TTR-package.R \docType{data} \name{ttrc} \alias{ttrc} \title{Technical Trading Rule Composite data} \format{The format is: \tabular{lll}{ Date: \tab Class 'Date' \tab 5480 5481 5482 5485 5486 ...\cr Open: \tab num \tab 3.18 3.09 3.11 3.09 3.10 ...\cr High: \tab num \tab 3.18 3.15 3.12 3.12 3.12 ...\cr Low: \tab num \tab 3.08 3.09 3.08 3.07 3.08 ...\cr Close: \tab num \tab 3.08 3.11 3.09 3.10 3.11 ...\cr Volume: \tab num \tab 1870906 3099506 2274157 2086758 2166348 ...\cr }} \source{ Randomly generated. } \description{ Historical Open, High, Low, Close, and Volume data for the periods January 2, 1985 to December 31, 2006. Randomly generated. } \details{ These data do not represent an actual security. They are provided so examples do not necessitate an internet connection. } \examples{ data(ttrc) plot(tail(ttrc[,"Close"],100), type="l") } \keyword{datasets} TTR/man/ATR.Rd0000644000176200001440000000407613425330036012421 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ATR.R \name{ATR} \alias{ATR} \alias{TR} \title{True Range / Average True Range} \usage{ ATR(HLC, n = 14, maType, ...) } \arguments{ \item{HLC}{Object that is coercible to xts or matrix and contains High-Low-Close prices.} \item{n}{Number of periods for moving average.} \item{maType}{A function or a string naming the function to be called.} \item{\dots}{Other arguments to be passed to the \code{maType} function.} } \value{ A object of the same class as \code{HLC} or a matrix (if \code{try.xts} fails) containing the columns: \describe{ \item{ tr }{ The true range of the series. } \item{ atr }{ The average (as specified by \code{ma}) true range of the series. } \item{ trueHigh }{ The true high of the series. } \item{ trueLow }{ The true low of the series. } } } \description{ True range (TR) is a measure of volatility of a High-Low-Close series; average true range (ATR) is a Welles Wilder's style moving average of the TR. Developed by J. Welles Wilder in 1978. } \details{ TR incorporates yesterday's close in the calculation (high minus low). E.g. if yesterday's close was higher than today's high, then the TR would equal yesterday's close minus today's low. The ATR is a component of the Welles Wilder Directional Movement Index (\code{DX}, \code{ADX}). } \examples{ data(ttrc) atr <- ATR(ttrc[,c("High","Low","Close")], n=14) } \references{ The following site(s) were used to code/document this indicator:\cr \url{http://www.fmlabs.com/reference/TR.htm}\cr \url{http://www.fmlabs.com/reference/ATR.htm}\cr \url{https://www.metastock.com/Customer/Resources/TAAZ/?p=35}\cr \url{https://www.linnsoft.com/techind/true-range-tr}\cr \url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:average_true_range_atr}\cr } \seealso{ See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average options; and note Warning section. See \code{\link{DX}}, which uses true range. See \code{\link{chaikinVolatility}} for another volatility measure. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/rollFun.Rd0000644000176200001440000000170113425330036013404 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/rollFun.R \name{rollSFM} \alias{rollSFM} \alias{rollFun} \title{Analysis of Running/Rolling/Moving Windows} \usage{ rollSFM(Ra, Rb, n = 60) } \arguments{ \item{Ra}{Object coercible to xts or matrix, containing the excess return for an individual security} \item{Rb}{Object coercible to xts or matrix, containing the market / benchmark return} \item{n}{Number of periods to use in the window} } \value{ A object of the same class as \code{Ra} (and \code{Rb}?) or a vector (if \code{try.xts} fails). \describe{ \item{rollSFM}{returns single-factor model parameters and R-squared over a n-period moving window.} } } \description{ Various functions to analyze data over a moving window of periods. } \references{ The following site(s) were used to code/document this indicator: \url{http://en.wikipedia.org/wiki/Simple_linear_regression}\cr } \author{ Joshua Ulrich } \keyword{ts} TTR/man/TDI.Rd0000644000176200001440000000346113425330036012410 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/TDI.R \name{TDI} \alias{TDI} \title{Trend Detection Index} \usage{ TDI(price, n = 20, multiple = 2) } \arguments{ \item{price}{Price series that is coercible to xts or matrix.} \item{n}{Number of periods to use.} \item{multiple}{Multiple used to calculate (2).} } \value{ A object of the same class as \code{price} or a matrix (if \code{try.xts} fails) containing the columns: \describe{ \item{ tdi }{ The Trend Detection Index. } \item{ di }{ The Direction Indicator. } } } \description{ The Trend Detection Index (TDI) attempts to identify starting and ending trends. Developed by M. H. Pee. } \details{ The TDI is the (1) absolute value of the \code{n}-day sum of the \code{n}-day momentum, minus the quantity of (2) \code{multiple}*\code{n}-day sum of the absolute value of the \code{n}-day momentum, minus (3) \code{n}-day sum of the absolute value of the \code{n}-day momentum. I.e. TDI = (1) - [ (2) - (3) ] The direction indicator is the sum of the \code{n}-day momentum over the last \code{n} days. See URL in references section for further details. } \note{ Positive/negative TDI values signal a trend/consolidation. A positive/ negative direction indicator signals a up/down trend. I.e. buy if the TDI and the direction indicator are positive, and sell if the TDI is positive while the direction indicator is negative. } \examples{ data(ttrc) tdi <- TDI(ttrc[,"Close"], n=30) } \references{ The following site(s) were used to code/document this indicator:\cr \url{https://www.linnsoft.com/techind/trend-detection-index-tdi}\cr } \seealso{ See \code{\link{aroon}}, \code{\link{CCI}}, \code{\link{ADX}}, \code{\link{VHF}}, \code{\link{GMMA}} for other indicators that measure trend direction/strength. } \author{ Joshua Ulrich } \keyword{ts} TTR/man/adjRatios.Rd0000644000176200001440000000203513425330036013704 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/adjRatios.R \name{adjRatios} \alias{adjRatios} \alias{adjust} \title{Split and dividend adjustment ratios} \usage{ adjRatios(splits, dividends, close) } \arguments{ \item{splits}{Split series that is coercible to xts.} \item{dividends}{Dividend series that is coercible to xts.} \item{close}{Close price series that is coercible to xts.} } \value{ A xts object containing the columns: \describe{ \item{ Split }{ The split adjustment ratio. } \item{ Div }{ The dividend adjustment ratio. } } } \description{ Create split and dividend adjustment ratio vectors. } \details{ \itemize{ \item If only \code{splits} is provided, the resulting object will only have as many observations as \code{splits}. \item If \code{splits} and \code{close} are provided, the resulting object will have as many observations as \code{max(NROW(splits), NROW(close))}. \item \code{close} is required if \code{dividends} is provided. } } \author{ Joshua Ulrich } \keyword{ts} TTR/DESCRIPTION0000644000176200001440000000104413575463222012441 0ustar liggesusersPackage: TTR Type: Package Title: Technical Trading Rules Version: 0.23-6 Author: Joshua Ulrich Maintainer: Joshua Ulrich Imports: xts (>= 0.10-0), zoo, curl LinkingTo: xts Enhances: quantmod Suggests: RUnit Description: Functions and data to construct technical trading rules with R. License: GPL (>= 2) URL: https://github.com/joshuaulrich/TTR BugReports: https://github.com/joshuaulrich/TTR/issues NeedsCompilation: yes Packaged: 2019-12-15 11:49:36 UTC; josh Repository: CRAN Date/Publication: 2019-12-15 17:00:02 UTC TTR/tests/0000755000176200001440000000000013425330036012064 5ustar liggesusersTTR/tests/doRUnit.R0000644000176200001440000000457313425330036013604 0ustar liggesusers## unit tests will not be done if RUnit is not available if(require("RUnit", quietly=TRUE)) { ## --- Setup --- R_CMD_CHECK <- Sys.getenv("RCMDCHECK") != "FALSE" pkg <- "TTR" # <-- Change to package name! if (R_CMD_CHECK) { ## Path to unit tests for R CMD check ## PKG.Rcheck/PKG/unitTests path <- system.file("unitTests", package=pkg) } else { ## Path to unit tests for standalone running under Makefile (not R CMD check) ## PKG/tests/../inst/unitTests path <- file.path(getwd(), "..", "inst", "unitTests") } cat("\nRunning unit tests\n") print(list(pkg=pkg, getwd=getwd(), pathToUnitTests=path)) library(package=pkg, character.only=TRUE) ## If desired, load the name space to allow testing of private functions ## if (is.element(pkg, loadedNamespaces())) ## attach(loadNamespace(pkg), name=paste("namespace", pkg, sep=":"), pos=3) ## ## or simply call PKG:::myPrivateFunction() in tests ## --- Testing --- ## Define tests testSuite <- defineTestSuite(name=paste(pkg, "unit testing"), dirs=path) ## Run tests <- runTestSuite(testSuite) ## Report to stdout cat("------------------- UNIT TEST SUMMARY ---------------------\n\n") printTextProtocol(tests, showDetails=FALSE) ## Report text files (only if not under R CMD check) if (!R_CMD_CHECK) { ## Default report name pathReport <- file.path(path, "report") printTextProtocol(tests, showDetails=FALSE, fileName=paste(pathReport, "Summary.txt", sep="")) printTextProtocol(tests, showDetails=TRUE, fileName=paste(pathReport, ".txt", sep="")) ## Report to HTML file printHTMLProtocol(tests, fileName=paste(pathReport, ".html", sep="")) } ## Return stop() to cause R CMD check stop in case of ## - failures i.e. FALSE to unit tests or ## - errors i.e. R errors testErrors <- getErrors(tests) if(testErrors$nFail > 0) { msg <- paste0(" unit test", if(testErrors$nFail > 1) "s" else "", " failed") stop("\n", testErrors$nFail, msg, sep="") } if(testErrors$nErr > 0) { msg <- paste0(" unit test", if(testErrors$nErr > 1) "s" else "", " had errors") stop("\n", testErrors$nErr, msg, sep="") } if (testErrors$nTestFunc < 1) { stop("No test functions ran!") } } else { warning("cannot run unit tests -- package RUnit is not available") } TTR/src/0000755000176200001440000000000013575416720011524 5ustar liggesusersTTR/src/ttr.h0000644000176200001440000000137013575166236012513 0ustar liggesusers#ifndef _TTR_H_ #define _TTR_H_ #include /* declare functions called via .Call() */ SEXP adjRatios(SEXP, SEXP, SEXP); SEXP aroon_max(SEXP, SEXP); SEXP ema(SEXP, SEXP, SEXP, SEXP); SEXP evwma(SEXP, SEXP, SEXP); SEXP sar(SEXP, SEXP, SEXP, SEXP); SEXP ttr_rollPercentRank(SEXP, SEXP, SEXP, SEXP); SEXP ttr_zigzag(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); SEXP vma(SEXP, SEXP, SEXP); SEXP wilderSum(SEXP, SEXP); SEXP wma(SEXP, SEXP, SEXP); SEXP zlema(SEXP, SEXP, SEXP); SEXP runsum(SEXP, SEXP); SEXP runmin(SEXP, SEXP); SEXP runmax(SEXP, SEXP); SEXP runmedian(SEXP, SEXP, SEXP, SEXP); SEXP runmad(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); SEXP runcov(SEXP, SEXP, SEXP, SEXP, SEXP); /* declare xts imports */ extern SEXP (*xts_na_check)(SEXP, SEXP); #endif TTR/src/percent_rank.c0000644000176200001440000000454713425330036014342 0ustar liggesusers/* * TTR: Technical Trading Rules * * Copyright (C) 2012-2017 Charlie Friedemann, Joshua M. Ulrich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include double calc_n_less(double* x, double mult, int i, int j1) { double n_less = mult; /* Loop over window */ for (int j = j1; j < i; j++) { double diff = x[j] - x[i]; if (diff < 0) { n_less = n_less + 1.0; } else if (fabs(diff) < 1e-8) { n_less = n_less + mult; } } return n_less; } /* Calculate a running/rolling percent rank, * or a cumulative version */ SEXP ttr_rollPercentRank(SEXP _x, SEXP _n, SEXP _cumul, SEXP _mult) { int i, P = 0; /* ensure correct types */ if (TYPEOF(_x) != REALSXP) { PROTECT(_x = coerceVector(_x, REALSXP)); P++; } double *d_x = REAL(_x); int n = asInteger(_n); int cumul = asLogical(_cumul); double mult = asReal(_mult); if (cumul) n = 1; int nr = nrows(_x); /* Initialize result R object */ SEXP result; PROTECT(result = allocVector(REALSXP, nr)); P++; double *d_result = REAL(result); /* Find first non-NA input value */ int beg = n - 1; for (i = 0; i <= beg; i++) { /* Account for leading NAs in input */ if (ISNA(d_x[i])) { d_result[i] = NA_REAL; beg++; continue; } /* Set leading NAs in output */ if (i < beg) { d_result[i] = NA_REAL; } } /* Loop over non-NA input values */ if (cumul) { d_result[beg] = mult; for (i = beg+1; i < nr; i++) { double n_less = calc_n_less(d_x, mult, i, 0); d_result[i] = n_less / (i + 1); } } else { for (i = beg; i < nr; i++) { double n_less = calc_n_less(d_x, mult, i, i-n+1); d_result[i] = n_less / n; } } UNPROTECT(P); return(result); } TTR/src/aroon.c0000644000176200001440000000533613425330036013002 0ustar liggesusers/* * TTR: Technical Trading Rules * * Copyright (C) 2007-2013 Joshua M. Ulrich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ttr.h" SEXP aroon_max (SEXP x, SEXP n) { /* Initalize loop, loc, and PROTECT counters */ int i, j, loc=0, P=0; /* Ensure x argument is double */ if(TYPEOF(x) != REALSXP) { PROTECT(x = coerceVector(x, REALSXP)); P++; } /* Pointers to function arguments */ double *real_x = REAL(x); int int_n = asInteger(n); /* Input object length */ int nr = length(x); /* Initalize result R object */ SEXP result; PROTECT(result = allocVector(REALSXP, nr)); P++; double *real_result = REAL(result); /* check for non-leading NAs and get first non-NA location */ SEXP first = PROTECT(xts_na_check(x, ScalarLogical(TRUE))); P++; int int_first = asInteger(first); if(int_n + 1 + int_first > nr) error("not enough non-NA values"); double real_max = real_x[0]; /* This portion is a modified version of roll_max from xts/zoo */ for(i=0; i= real_max) { real_max = real_x[i]; /* set max value */ loc = 0; /* set max location in window */ } loc++; continue; } else { /* if the max leaves the window */ //if(loc >= int_n-1) { // roll_max if(loc > int_n) { /* find the max over the (n+1) window */ real_max = real_x[i]; loc = 0; //for(j=0; j real_max) { real_max = real_x[i-j]; loc = j; } } } else { /* if the new value is the new max */ if(real_x[i] >= real_max) { real_max = real_x[i]; loc = 0; } } } /* set result, increment location */ real_result[i] = (100.0 * (int_n - loc)) / int_n; loc++; } /* UNPROTECT R objects and return result */ UNPROTECT(P); return(result); } TTR/src/init.c0000644000176200001440000000374213575166236012645 0ustar liggesusers/* * TTR: Technical Trading Rules * * Copyright (C) 2007-2017 Joshua M. Ulrich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* Includes and defines from WRE Section 5.4.2 */ #include "ttr.h" #include #include /* for NULL */ #include #define CALLDEF(name, n) {#name, (DL_FUNC) &name, n} /* define xts imports */ SEXP (*xts_na_check)(SEXP,SEXP); static const R_CallMethodDef CallEntries[] = { CALLDEF(adjRatios, 3), CALLDEF(aroon_max, 2), CALLDEF(ema, 4), CALLDEF(evwma, 3), CALLDEF(sar, 4), CALLDEF(ttr_rollPercentRank, 4), CALLDEF(ttr_zigzag, 6), CALLDEF(vma, 3), CALLDEF(wilderSum, 2), CALLDEF(wma, 3), CALLDEF(zlema, 3), CALLDEF(runsum, 2), CALLDEF(runmin, 2), CALLDEF(runmax, 2), CALLDEF(runmedian, 4), CALLDEF(runmad, 6), CALLDEF(runcov, 5), {NULL, NULL, 0} }; /* Restrict .Call etc to use only registered symbols */ void R_init_TTR(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); //R_forceSymbols(dll, TRUE); /* only use R symbols (not strings) */ xts_na_check = (SEXP(*)(SEXP,SEXP)) R_GetCCallable("xts", "naCheck"); } TTR/src/adjRatios.c0000644000176200001440000000463713425330036013607 0ustar liggesusers/* * TTR: Technical Trading Rules * * Copyright (C) 2007-2013 Joshua M. Ulrich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include SEXP adjRatios (SEXP split, SEXP div, SEXP close) { /* Initialize REAL pointers to function arguments */ double *real_close = REAL(close); double *real_split = REAL(split); double *real_div = REAL(div); /* Initalize loop and PROTECT counters */ int i, P = 0; /* Initalize object length (NOTE: all arguments are the same length) */ int N = length(close); /* Initalize result R objects */ SEXP result; PROTECT(result = allocVector(VECSXP, 2)); P++; SEXP s_ratio; PROTECT(s_ratio = allocVector(REALSXP,N)); P++; SEXP d_ratio; PROTECT(d_ratio = allocVector(REALSXP,N)); P++; /* Initialize REAL pointers to R objects and set their last value to '1' */ double *rs_ratio = REAL(s_ratio); double *rd_ratio = REAL(d_ratio); rs_ratio[N-1] = 1; rd_ratio[N-1] = 1; /* Loop over split/div vectors from newest period to oldest */ for(i = N-1; i > 0; i--) { /* Carry newer ratio value backward */ if(ISNA(real_split[i])) { rs_ratio[i-1] = rs_ratio[i]; /* Update split ratio */ } else { rs_ratio[i-1] = rs_ratio[i] * real_split[i]; } /* Carry newer ratio value backward */ if(ISNA(real_div[i])) { rd_ratio[i-1] = rd_ratio[i]; } else { /* Update dividend ratio */ rd_ratio[i-1] = rd_ratio[i] * (1.0 - real_div[i] / real_close[i-1]); } } /* Assign results to list */ SET_VECTOR_ELT(result, 0, s_ratio); SET_VECTOR_ELT(result, 1, d_ratio); /* UNPROTECT R objects and return result */ UNPROTECT(P); return(result); } TTR/src/zigzag.c0000644000176200001440000001066113425330036013154 0ustar liggesusers/* * TTR: Technical Trading Rules * * Copyright (C) 2007-2017 Joshua M. Ulrich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include /* price and its array index */ typedef struct { double price; int index; } price_and_index; SEXP ttr_zigzag (SEXP _high, SEXP _low, SEXP _change, SEXP _percent, SEXP _retrace, SEXP _last_extreme) { double* high = REAL(_high); double* low = REAL(_low); double change = asReal(_change); int use_percent = asLogical(_percent); int use_retrace = asLogical(_retrace); int use_last_ex = asLogical(_last_extreme); if (use_percent) change = change / 100.0; int n = length(_high); SEXP _zigzag = PROTECT(allocVector(REALSXP, n)); double* zigzag = REAL(_zigzag); price_and_index reference, inflection; reference.price = (high[0] + low[0]) / 2; reference.index = 0; inflection.price = (high[1] + low[1]) / 2; inflection.index = 1; double extreme_min, extreme_max, local_min, local_max; int signal = 0; for (int i = 1; i < n; i++) { /* Initialize all zigzag values to NA */ zigzag[i] = NA_REAL; if (use_percent) { /* If % change given (absolute move) */ extreme_min = inflection.price * (1.0 - change); extreme_max = inflection.price * (1.0 + change); } else { /* If $ change given (only absolute moves make sense) */ extreme_min = inflection.price - change; extreme_max = inflection.price + change; } /* Find local maximum and minimum */ local_max = inflection.price > high[i] ? inflection.price : high[i]; local_min = inflection.price < low[i] ? inflection.price : low[i]; /* Find first trend */ if (signal == 0) { if (use_retrace) { /* Retrace prior move */ signal = (inflection.price >= reference.price) ? 1 : -1; } else { /* Absolute move */ if (local_min <= extreme_min) { /* Confirmed Downtrend */ signal = -1; } if (local_max >= extreme_max) { /* Confirmed Uptrend */ signal = 1; } } } /* Downtrend */ if (signal == -1) { /* New Minimum */ if (low[i] == local_min) { /* Last Extreme */ if (use_last_ex) { inflection.price = low[i]; inflection.index = i; } else { /* First Extreme */ if (low[i] != low[i-1]) { inflection.price = low[i]; inflection.index = i; } } } /* Retrace prior move */ if (use_retrace) { extreme_max = inflection.price + ((reference.price - inflection.price) * change); } /* Trend Reversal */ if (high[i] >= extreme_max) { zigzag[reference.index] = reference.price; reference = inflection; inflection.price = high[i]; inflection.index = i; signal = 1; continue; } } /* Uptrend */ if (signal == 1) { /* New Maximum */ if (high[i] == local_max) { /* Last Extreme */ if (use_last_ex) { inflection.price = high[i]; inflection.index = i; } else { /* First Extreme */ if (high[i] != high[i-1]) { inflection.price = high[i]; inflection.index = i; } } } /* Retrace prior move */ if (use_retrace) { extreme_min = inflection.price - ((inflection.price - reference.price) * change); } /* Trend Reversal */ if (low[i] <= extreme_min) { zigzag[reference.index] = reference.price; reference = inflection; inflection.price = low[i]; inflection.index = i; signal = -1; continue; } } } zigzag[reference.index] = reference.price; zigzag[inflection.index] = inflection.price; UNPROTECT(1); return _zigzag; } TTR/src/wilderSum.c0000644000176200001440000000402213425330036013626 0ustar liggesusers/* * TTR: Technical Trading Rules * * Copyright (C) 2007-2013 Joshua M. Ulrich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include SEXP wilderSum (SEXP x, SEXP n) { /* Initalize loop and PROTECT counters */ int i, P=0; /* assure that 'x' is double */ if(TYPEOF(x) != REALSXP) { PROTECT(x = coerceVector(x, REALSXP)); P++; } /* Pointers to function arguments */ double *d_x = REAL(x); int i_n = asInteger(n); /* Input object length */ int nr = nrows(x); /* Initalize result R object */ SEXP result; PROTECT(result = allocVector(REALSXP,nr)); P++; double *d_result = REAL(result); /* Find first non-NA input value */ int beg = i_n - 1; double sum = 0; for(i = 0; i < beg; i++) { /* Account for leading NAs in input */ if(ISNA(d_x[i])) { d_result[i] = NA_REAL; beg++; d_result[beg] = 0; continue; } /* Set leading NAs in output */ if(i < beg) { d_result[i] = NA_REAL; } /* Calculate raw sum to start */ sum += d_x[i]; } d_result[beg] = d_x[i] + sum * (i_n-1)/i_n; /* Loop over non-NA input values */ for(i = beg+1; i < nr; i++) { d_result[i] = d_x[i] + d_result[i-1] * (i_n-1)/i_n; } /* UNPROTECT R objects and return result */ UNPROTECT(P); return(result); } TTR/src/sar.c0000644000176200001440000000715013425330036012445 0ustar liggesusers/* * TTR: Technical Trading Rules * * Copyright (C) 2007-2013 Joshua M. Ulrich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include SEXP sar (SEXP hi, SEXP lo, SEXP xl, SEXP ig) { /* Initalize loop and PROTECT counters */ int i, P=0; /* Ensure all arguments are double */ if(TYPEOF(hi) != REALSXP) { PROTECT(hi = coerceVector(hi, REALSXP)); P++; } if(TYPEOF(lo) != REALSXP) { PROTECT(lo = coerceVector(lo, REALSXP)); P++; } if(TYPEOF(xl) != REALSXP) { PROTECT(xl = coerceVector(xl, REALSXP)); P++; } double initGap = asReal(ig); /* Pointers to function arguments */ double *d_hi = REAL(hi); double *d_lo = REAL(lo); double *d_xl = REAL(xl); /* Input object length */ int nr = nrows(hi); /* Initalize result R object */ SEXP sar; PROTECT(sar = allocMatrix(REALSXP, nr, 1)); P++; double *d_sar = REAL(sar); /* Find first non-NA value */ int beg = 1; for(i=0; i < nr; i++) { if( ISNA(d_hi[i]) || ISNA(d_lo[i]) ) { d_sar[i] = NA_REAL; beg++; } else { break; } } /* Initialize values needed by the routine */ int sig0 = 1, sig1 = 0; double xpt0 = d_hi[beg-1], xpt1 = 0; double af0 = d_xl[0], af1 = 0; double lmin, lmax; d_sar[beg-1] = d_lo[beg-1]-initGap; for(i=beg; i < nr; i++) { /* Increment signal, extreme point, and acceleration factor */ sig1 = sig0; xpt1 = xpt0; af1 = af0; /* Local extrema */ lmin = fmin(d_lo[i-1], d_lo[i]); lmax = fmax(d_hi[i-1], d_hi[i]); /* Create signal and extreme price vectors */ if( sig1 == 1 ) { /* Previous buy signal */ sig0 = (d_lo[i] > d_sar[i-1]) ? 1 : -1; /* New signal */ xpt0 = fmax(lmax, xpt1); /* New extreme price */ } else { /* Previous sell signal */ sig0 = (d_hi[i] < d_sar[i-1]) ? -1 : 1; /* New signal */ xpt0 = fmin(lmin, xpt1); /* New extreme price */ } /* * Calculate acceleration factor (af) * and stop-and-reverse (sar) vector */ /* No signal change */ if( sig0 == sig1 ) { /* Initial calculations */ d_sar[i] = d_sar[i-1] + ( xpt1 - d_sar[i-1] ) * af1; af0 = (af1 == d_xl[1]) ? d_xl[1] : (d_xl[0] + af1); /* Current buy signal */ if( sig0 == 1 ) { af0 = (xpt0 > xpt1) ? af0 : af1; /* Update acceleration factor */ d_sar[i] = fmin(d_sar[i],lmin); /* Determine sar value */ } /* Current sell signal */ else { af0 = (xpt0 < xpt1) ? af0 : af1; /* Update acceleration factor */ d_sar[i] = fmax(d_sar[i],lmax); /* Determine sar value */ } } /* New signal */ else { af0 = d_xl[0]; /* reset acceleration factor */ d_sar[i] = xpt0; /* set sar value */ } } /* UNPROTECT R objects and return result */ UNPROTECT(P); return(sar); } TTR/src/runfun.c0000644000176200001440000002650413552670134013210 0ustar liggesusers/* * TTR: Technical Trading Rules * * Copyright (C) 2007-2018 Joshua M. Ulrich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include /* for memcpy */ #include "ttr.h" SEXP runsum(SEXP _x, SEXP _n) { int i, P = 0; /* ensure that 'x' is double */ if (TYPEOF(_x) != REALSXP) { _x = PROTECT(coerceVector(_x, REALSXP)); P++; } double *x = REAL(_x); int n = asInteger(_n); /* Input object length */ int nr = nrows(_x); /* Initialize result R object */ SEXP _result = PROTECT(allocVector(REALSXP, nr)); P++; double *result = REAL(_result); /* check for non-leading NAs and get first non-NA location */ SEXP _first = PROTECT(xts_na_check(_x, ScalarLogical(TRUE))); P++; int first = INTEGER(_first)[0]; if (n + first > nr) { error("not enough non-NA values"); } /* Set leading NAs in output */ for (i = 0; i < first; i++) { result[i] = NA_REAL; } /* Raw sum to start running sum */ double seed = 0.0; for (i = first; i < first + n; i++) { result[i] = NA_REAL; seed += x[i]; } result[first + n - 1] = seed; /* Loop over non-NA input values */ for (i = first + n; i < nr; i++) { result[i] = result[i-1] + x[i] - x[i-n]; } /* UNPROTECT R objects and return result */ UNPROTECT(P); return _result; } SEXP runmin(SEXP _x, SEXP _n) { int i, j, P = 0; /* ensure that 'x' is double */ if (TYPEOF(_x) != REALSXP) { _x = PROTECT(coerceVector(_x, REALSXP)); P++; } double *x = REAL(_x); int n = asInteger(_n); /* Input object length */ int nr = nrows(_x); /* Initialize result R object */ SEXP _result = PROTECT(allocVector(REALSXP, nr)); P++; double *result = REAL(_result); /* check for non-leading NAs and get first non-NA location */ SEXP _first = PROTECT(xts_na_check(_x, ScalarLogical(TRUE))); P++; int first = INTEGER(_first)[0]; if (n + first > nr) { error("not enough non-NA values"); } /* Set leading NAs in output */ for (i = 0; i < first; i++) { result[i] = NA_REAL; } /* start running min */ double lmin = x[first]; for (i = first; i < first + n; i++) { result[i] = NA_REAL; if (x[i] < lmin) { lmin = x[i]; } } result[first + n - 1] = lmin; /* Loop over non-NA input values */ for (i = first + n; i < nr; i++) { lmin = x[i]; for (j = 1; j < n; j++) { if (x[i-j] < lmin) { lmin = x[i-j]; } } result[i] = lmin; } /* UNPROTECT R objects and return result */ UNPROTECT(P); return _result; } SEXP runmax(SEXP _x, SEXP _n) { int i, j, P = 0; /* ensure that 'x' is double */ if (TYPEOF(_x) != REALSXP) { _x = PROTECT(coerceVector(_x, REALSXP)); P++; } double *x = REAL(_x); int n = asInteger(_n); /* Input object length */ int nr = nrows(_x); /* Initialize result R object */ SEXP _result = PROTECT(allocVector(REALSXP, nr)); P++; double *result = REAL(_result); /* check for non-leading NAs and get first non-NA location */ SEXP _first = PROTECT(xts_na_check(_x, ScalarLogical(TRUE))); P++; int first = INTEGER(_first)[0]; if (n + first > nr) { error("not enough non-NA values"); } /* Set leading NAs in output */ for (i = 0; i < first; i++) { result[i] = NA_REAL; } /* start running max */ double lmax = x[first]; for (i = first; i < first + n; i++) { result[i] = NA_REAL; if (x[i] > lmax) { lmax = x[i]; } } result[first + n - 1] = lmax; /* Loop over non-NA input values */ for (i = first + n; i < nr; i++) { lmax = x[i]; for (j = 1; j < n; j++) { if (x[i-j] > lmax) { lmax = x[i-j]; } } result[i] = lmax; } /* UNPROTECT R objects and return result */ UNPROTECT(P); return _result; } typedef double (*tiebreaker)(const double, const double); static inline double tiebreaker_lt(const double a, const double b) { return (a < b) ? a : b; } static inline double tiebreaker_gt(const double a, const double b) { return (a > b) ? a : b; } static inline double tiebreaker_eq(const double a, const double b) { return (a + b) / 2.0; } static inline double ttr_median(double *x, int n, tiebreaker tie_func) { int flag = n-2*(n/2); int mid = n/2-1; R_qsort(x, 1, n); double median = (flag) ? x[mid+1] : tie_func(x[mid] , x[mid+1]); return median; } SEXP runmedian(SEXP _x, SEXP _n, SEXP _tiebreak, SEXP _cumulative) { int i, P = 0; /* ensure that 'x' is double */ if (TYPEOF(_x) != REALSXP) { _x = PROTECT(coerceVector(_x, REALSXP)); P++; } double *x = REAL(_x); int n = asInteger(_n); int tiebreak = asInteger(_tiebreak); int cumulative = asLogical(_cumulative); /* Input object length */ int nr = nrows(_x); /* Initialize result R object */ SEXP _result = PROTECT(allocVector(REALSXP, nr)); P++; double *result = REAL(_result); /* check for non-leading NAs and get first non-NA location */ SEXP _first = PROTECT(xts_na_check(_x, ScalarLogical(TRUE))); P++; int first = INTEGER(_first)[0]; if (n + first > nr) { error("not enough non-NA values"); } /* Set leading NAs in output */ for (i = 0; i < first + n; i++) { result[i] = NA_REAL; } tiebreaker tie_func = NULL; if (tiebreak == 0) { tie_func = tiebreaker_eq; } else if (tiebreak < 0) { tie_func = tiebreaker_lt; } else if (tiebreak > 0) { tie_func = tiebreaker_gt; } SEXP _window; double *window; int first_i = first + n - 1; if (cumulative) { _window = PROTECT(duplicate(_x)); P++; window = REAL(_window); for (i = first_i; i < nr; i++) { result[i] = ttr_median(window, i+1, tie_func); } } else { _window = PROTECT(allocVector(REALSXP, n)); P++; window = REAL(_window); for (i = first_i; i < nr; i++) { memcpy(window, &x[i-n+1], n * sizeof(double)); result[i] = ttr_median(window, n, tie_func); } } /* UNPROTECT R objects and return result */ UNPROTECT(P); return _result; } static inline double ttr_mean(const double *x, const int n) { double mean = x[0] / n; int i; for (i = 1; i < n; i++) { mean += x[i] / n; } return mean; } SEXP runmad(SEXP _x, SEXP _center, SEXP _n, SEXP _type, SEXP _tiebreak, SEXP _cumulative) { int i, j, P = 0; /* ensure 'x' and 'center' are double */ if (TYPEOF(_x) != REALSXP) { _x = PROTECT(coerceVector(_x, REALSXP)); P++; } if (TYPEOF(_center) != REALSXP) { _center = PROTECT(coerceVector(_center, REALSXP)); P++; } double *x = REAL(_x); double *center = REAL(_center); int n = asInteger(_n); int type = asInteger(_type); int tiebreak = asInteger(_tiebreak); int cumulative = asLogical(_cumulative); /* Input object length */ int nr = nrows(_x); if (nr != nrows(_center)) { error("'x' and 'center' must have the same number of observations"); } /* Initialize result R object */ SEXP _result = PROTECT(allocVector(REALSXP, nr)); P++; double *result = REAL(_result); /* check for non-leading NAs and get first non-NA location */ SEXP _first = PROTECT(xts_na_check(_x, ScalarLogical(TRUE))); P++; int first = INTEGER(_first)[0]; if (n + first > nr) { error("not enough non-NA values in 'x'"); } /* Set leading NAs in output */ for (i = 0; i < first + n; i++) { result[i] = NA_REAL; } tiebreaker tie_func = NULL; if (tiebreak == 0) { tie_func = tiebreaker_eq; } else if (tiebreak < 0) { tie_func = tiebreaker_lt; } else if (tiebreak > 0) { tie_func = tiebreaker_gt; } SEXP _window; double *window; int first_i = first + n - 1; if (cumulative) { _window = PROTECT(duplicate(_x)); P++; window = REAL(_window); if (type) { for (i = first_i; i < nr; i++) { for (j = 0; j <= i; j++) { window[j] = fabs(x[i-j] - center[i]); } result[i] = ttr_median(window, i+1, tie_func); } } else { for (i = first_i; i < nr; i++) { for (j = 0; j <= i; j++) { window[j] = fabs(x[i-j] - center[i]); } result[i] = ttr_mean(window, i+1); } } } else { _window = PROTECT(allocVector(REALSXP, n)); P++; window = REAL(_window); if (type) { for (i = first_i; i < nr; i++) { for (j = 0; j < n; j++) { window[j] = fabs(x[i-j] - center[i]); } result[i] = ttr_median(window, n, tie_func); } } else { for (i = first_i; i < nr; i++) { for (j = 0; j < n; j++) { window[j] = fabs(x[i-j] - center[i]); } result[i] = ttr_mean(window, n); } } } /* UNPROTECT R objects and return result */ UNPROTECT(P); return _result; } SEXP runcov(SEXP _x, SEXP _y, SEXP _n, SEXP _sample, SEXP _cumulative) { int i, j, P = 0; /* ensure 'x' and 'y' are double */ if (TYPEOF(_x) != REALSXP) { _x = PROTECT(coerceVector(_x, REALSXP)); P++; } if (TYPEOF(_y) != REALSXP) { _y = PROTECT(coerceVector(_y, REALSXP)); P++; } double *x = REAL(_x); double *y = REAL(_y); int n = asInteger(_n); int cumulative = asLogical(_cumulative); int sample = asLogical(_sample); /* Input object length */ int nr = nrows(_x); if (nr != nrows(_y)) { error("'x' and 'y' must have the same number of observations"); } /* Initialize result R object */ SEXP _result = PROTECT(allocVector(REALSXP, nr)); P++; double *result = REAL(_result); /* check for non-leading NAs and get first non-NA location */ SEXP _first_x = PROTECT(xts_na_check(_x, ScalarLogical(TRUE))); P++; int first_x = INTEGER(_first_x)[0]; if (n + first_x > nr) { error("not enough non-NA values in 'x'"); } SEXP _first_y = PROTECT(xts_na_check(_y, ScalarLogical(TRUE))); P++; int first_y = INTEGER(_first_y)[0]; if (n + first_y > nr) { error("not enough non-NA values in 'y'"); } int first = (first_x > first_y) ? first_x : first_y; /* Set leading NAs in output */ for (i = 0; i < first + n; i++) { result[i] = NA_REAL; } SEXP _window; double *window, mu_x, mu_y; int first_i = first + n - 1; double denom = sample ? (n-1) : n; if (cumulative) { for (i = first_i; i < nr; i++) { mu_x = ttr_mean(x, i+1); mu_y = ttr_mean(y, i+1); result[i] = 0.0; for (j = 0; j <= i; j++) { result[i] += (x[i-j] - mu_x) * (y[i-j] - mu_y); } result[i] /= sample ? i : (i+1); } } else { _window = PROTECT(allocVector(REALSXP, n)); P++; window = REAL(_window); size_t window_size = n * sizeof(double); for (i = first_i; i < nr; i++) { memcpy(window, &x[i-n+1], window_size); mu_x = ttr_mean(window, n); memcpy(window, &y[i-n+1], window_size); mu_y = ttr_mean(window, n); result[i] = 0.0; for (j = 0; j < n; j++) { result[i] += (x[i-j] - mu_x) * (y[i-j] - mu_y); } result[i] /= denom; } } /* UNPROTECT R objects and return result */ UNPROTECT(P); return _result; } TTR/src/moving_averages.c0000644000176200001440000002050413552670134015041 0ustar liggesusers/* * TTR: Technical Trading Rules * * Copyright (C) 2007-2013 Joshua M. Ulrich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ttr.h" SEXP ema (SEXP x, SEXP n, SEXP ratio, SEXP wilder) { /* Initalize loop and PROTECT counters */ int i, P=0; /* ensure that 'x' is double */ if(TYPEOF(x) != REALSXP) { PROTECT(x = coerceVector(x, REALSXP)); P++; } double *d_x = REAL(x); /* If ratio is specified, and n is not, set n to approx 'correct' * value backed out from ratio */ int i_n; if(R_NilValue == n && R_NilValue != ratio) { i_n = (int)(2.0 / asReal(ratio) - 1.0); } else { i_n = asInteger(n); } /* Determine decay ratio */ int isWilder = LOGICAL(wilder)[0]; double d_ratio; if(R_NilValue == ratio) { d_ratio = (isWilder) ? 1.0 / i_n : 2.0 / (i_n + 1); } else { d_ratio = asReal(ratio); } /* Input object length */ int nr = nrows(x); /* Initalize result R object */ SEXP result; PROTECT(result = allocVector(REALSXP,nr)); P++; double *d_result = REAL(result); /* check for non-leading NAs and get first non-NA location */ SEXP _first = PROTECT(xts_na_check(x, ScalarLogical(TRUE))); P++; int first = INTEGER(_first)[0]; if(i_n + 1 + first > nr) { error("not enough non-NA values"); } /* Set leading NAs in output */ for(i = 0; i < first; i++) { d_result[i] = NA_REAL; } /* Raw mean to start EMA */ double seed = 0.0; for(i = first; i < first + i_n; i++) { d_result[i] = NA_REAL; seed += d_x[i] / i_n; } d_result[first + i_n - 1] = seed; /* Loop over non-NA input values */ for(i = first + i_n; i < nr; i++) { d_result[i] = d_x[i] * d_ratio + d_result[i-1] * (1-d_ratio); } /* UNPROTECT R objects and return result */ UNPROTECT(P); return(result); } SEXP evwma (SEXP pr, SEXP vo, SEXP n) { /* Initalize loop and PROTECT counters */ int i, P=0; /* ensure that 'pr' is double */ if(TYPEOF(pr) != REALSXP) { PROTECT(pr = coerceVector(pr, REALSXP)); P++; } /* ensure that 'vo' is double */ if(TYPEOF(vo) != REALSXP) { PROTECT(vo = coerceVector(vo, REALSXP)); P++; } /* Pointers to function arguments */ double *d_pr = REAL(pr); double *d_vo = REAL(vo); int i_n = asInteger(n); /* Input object length */ int nr = nrows(pr); /* Initalize result R object */ SEXP result; PROTECT(result = allocVector(REALSXP,nr)); P++; double *d_result = REAL(result); /* Volume Sum */ double volSum = 0; /* Find first non-NA input value */ int beg = i_n - 1; for(i = 0; i <= beg; i++) { /* Account for leading NAs in input */ if(ISNA(d_pr[i]) || ISNA(d_vo[i])) { d_result[i] = NA_REAL; beg++; continue; } /* Set leading NAs in output */ if(i < beg) { d_result[i] = NA_REAL; /* First result value is first price value */ } else { d_result[i] = d_pr[i]; } /* Keep track of volume Sum */ volSum += d_vo[i]; } /* Loop over non-NA input values */ for(i = beg+1; i < nr; i++) { volSum = volSum + d_vo[i] - d_vo[i-i_n]; d_result[i] = ((volSum-d_vo[i])*d_result[i-1]+d_vo[i]*d_pr[i])/volSum; } /* UNPROTECT R objects and return result */ UNPROTECT(P); return(result); } SEXP vma (SEXP x, SEXP w, SEXP ratio) { /* Initalize loop and PROTECT counters */ int i, P=0; /* ensure that 'x' is double */ if(TYPEOF(x) != REALSXP) { PROTECT(x = coerceVector(x, REALSXP)); P++; } /* ensure that 'w' is double */ if(TYPEOF(w) != REALSXP) { PROTECT(w = coerceVector(w, REALSXP)); P++; } /* Pointers to function arguments */ double *d_x = REAL(x); double *d_w = REAL(w); double d_ratio = asReal(ratio); /* Input object length */ int nr = nrows(x); /* Initalize result R object */ SEXP result; PROTECT(result = allocVector(REALSXP,nr)); P++; double *d_result = REAL(result); /* Find first non-NA input value */ int beg = 0; d_result[beg] = 0; for(i = 0; i <= beg; i++) { /* Account for leading NAs in input */ if(ISNA(d_x[i]) || ISNA(d_w[i])) { d_result[i] = NA_REAL; beg++; d_result[beg] = 0; continue; } /* Set leading NAs in output */ if(i < beg) { d_result[i] = NA_REAL; } /* Raw mean to start VMA */ d_result[beg] += d_x[i]; } /* Loop over non-NA input values */ for(i = beg+1; i < nr; i++) { d_result[i] = d_x[i] * d_w[i] * d_ratio + d_result[i-1] * (1-d_ratio*d_w[i]); } /* UNPROTECT R objects and return result */ UNPROTECT(P); return(result); } SEXP wma (SEXP x, SEXP w, SEXP n) { /* Initalize loop and PROTECT counters */ int i, j, P=0; /* ensure that 'x' is double */ if(TYPEOF(x) != REALSXP) { PROTECT(x = coerceVector(x, REALSXP)); P++; } /* ensure that 'w' is double */ if(TYPEOF(w) != REALSXP) { PROTECT(w = coerceVector(w, REALSXP)); P++; } int i_n = asInteger(n); /* Pointers to function arguments */ double *d_x = REAL(x); double *d_w = REAL(w); /* Input object length */ int nr = nrows(x); /* Initalize result R object */ SEXP result; PROTECT(result = allocVector(REALSXP,nr)); P++; double *d_result = REAL(result); /* Loop over non-NA input values */ double wtsum = 0.0; for(j = 0; j < i_n; j++) { wtsum += d_w[j]; } for(i = (i_n-1); i < nr; i++) { double num = 0.0; int ni = i - i_n + 1; for(j = 0; j < i_n; j++) { num += d_x[ni+j] * d_w[j]; } d_result[i] = num / wtsum; } /* UNPROTECT R objects and return result */ UNPROTECT(P); return(result); } SEXP zlema (SEXP x, SEXP n, SEXP ratio) { /* Initalize loop and PROTECT counters */ int i, P=0; /* ensure that 'x' is double */ if(TYPEOF(x) != REALSXP) { PROTECT(x = coerceVector(x, REALSXP)); P++; } double *d_x = REAL(x); /* If ratio is specified, and n is not, then * set n to approx 'correct' value backed out from ratio */ int i_n; double d_ratio; if(R_NilValue == n && R_NilValue != ratio) { d_ratio = asReal(ratio); i_n = (int)(2.0 / d_ratio - 1.0); } else { i_n = asInteger(n); } if(R_NilValue == ratio) { d_ratio = 2.0 / (i_n + 1); } /* Input object length */ int nr = nrows(x); /* Initalize result R object */ SEXP result; PROTECT(result = allocVector(REALSXP,nr)); P++; double *d_result = REAL(result); /* check for non-leading NAs and get first non-NA location */ SEXP _first = PROTECT(xts_na_check(x, ScalarLogical(TRUE))); P++; int first = INTEGER(_first)[0]; if(i_n + 1 + first > nr) { error("not enough non-NA values"); } /* Set leading NAs in output */ for(i = 0; i < first; i++) { d_result[i] = NA_REAL; } /* Raw mean to start EMA */ double seed = 0.0; for(i = first; i < first + i_n; i++) { d_result[i] = NA_REAL; seed += d_x[i] / i_n; } d_result[first + i_n - 1] = seed; double lag = 1.0 / d_ratio; double wt = fmod(lag, 1.0); double w1 = 1.0 - wt; double r1 = 1.0 - d_ratio; /* Loop over non-NA input values */ for(i = first + i_n; i < nr; i++) { int loc = (int)(i - lag); double value = 2 * d_x[i] - (w1 * d_x[loc] + wt * d_x[loc+1]); d_result[i] = d_ratio * value + r1 * d_result[i-1]; } /* UNPROTECT R objects and return result */ UNPROTECT(P); return(result); } TTR/R/0000755000176200001440000000000013575416720011136 5ustar liggesusersTTR/R/DonchianChannel.R0000644000176200001440000000722113552670134014273 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Donchian Channel #' #'Donchian Channels were created by Richard Donchian and were used to generate #'buy and sell signals for the Turtle Trading system. #' #'Donchian Channels consist of two (sometimes three) lines: #' #'The top line is the highest high of the past \code{n} periods. The bottom #'line is the lowest low of the past \code{n} periods. The middle line is the #'average of the top and bottom lines. #' #'@aliases DonchianChannel Donchian #'@param HL Object that is coercible to xts or matrix and contains High-Low #'prices. #'@param n Number of periods for moving average. #'@param include.lag Should values be lagged so that today's prices are not #'included in the calculation? See Note. #'@return A object of the same class as \code{HL} or a matrix (if #'\code{try.xts} fails) containing the columns: #' \describe{ #' \item{ high }{ The highest high series. } #' \item{ mid }{ The average of \code{high} and \code{low}. } #' \item{ low }{ The lowest low series. } #' } #'@note The default of \code{include.lag=FALSE} makes \code{DonchainChannel} #'consistent with other \pkg{TTR} functions, in that it includes the current #'period in the calculation. #' #'The default is different than the original calculation, which would calculate #'the indicator using periods t-1 through t-n. Setting \code{include.lag=TRUE} #'will return the result of the original calculation. #' #'The default of this argument may change in the future. #'@author Joshua Ulrich #'@seealso See \code{\link{BBands}}. #'@references The following site(s) were used to code/document this #'indicator:\cr \url{https://www.linnsoft.com/techind/donchian-channels}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' dc <- DonchianChannel( ttrc[,c("High","Low")] ) #' 'DonchianChannel' <- function(HL, n=10, include.lag=FALSE) { # Donchian Channel # Notes from John Bollinger: # # "In the old paper-calculation days you would calculate the numbers # after the close by hand and for use in the next day's trading to gauge # the "n-day" breakouts and you would have used n-days worth of data the # calc. Thus an n-day calc with a lag of one would be consistent with # practice in Donchian's day. (Total window of n+1.) Another example are # the floor traders numbers or pivots, which are calculated from the # prior period's data for use on the current period. In both case # including the current period in the calculation would not be correct." HL <- try.xts(HL, error=as.matrix) if(!(NCOL(HL) %in% c(1,2))) { stop("Price series must be either High-Low, or Close/univariate.") } if(NCOL(HL)==2) { hi <- HL[,1] lo <- HL[,2] } else { hi <- HL lo <- HL } high <- runMax(hi,n) low <- runMin(lo,n) mid <- (high+low)/2 result <- cbind(high,mid,low) colnames(result) <- c("high","mid","low") if(include.lag) { # use lag.xts in case 'result' is a matrix result <- lag.xts(result) } reclass(result, HL) } TTR/R/MFI.R0000644000176200001440000000650713552670134011700 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Money Flow Index #' #'The MFI is a ratio of positive and negative money flow over time. #' #'Money Flow (MF) is the product of price and volume. Positive/negative MF #'occur when today's price is higher/lower than yesterday's price. The MFI is #'calculated by dividing positive MF by negative MF for the past \code{n} #'periods. It is then scaled between 0 and 100. #' #'MFI is usually calculated using the typical price, but if a univariate series #'(e.g. Close, Weighted Close, Median Price, etc.) is provided, it will be used #'instead. #' #'@aliases MFI moneyFlow #'@param HLC Object that is coercible to xts or matrix and contains #'High-Low-Close prices. If only a univariate series is given, it will be #'used. See details. #'@param volume Vector or matrix of volume observations corresponding to #'\code{HLC} object. #'@param n Number of periods to use. #'@return A object of the same class as \code{HLC} and \code{volume} or a #'vector (if \code{try.xts} fails) containing the MFI values. #'@note Divergence between MFI and price can be indicative of a reversal. In #'addition, values above/below 80/20 indicate market tops/bottoms. #'@author Joshua Ulrich #'@seealso See \code{\link{OBV}} and \code{\link{CMF}}. #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{http://www.fmlabs.com/reference/default.htm?url=MoneyFlowIndex.htm}\cr #'\url{https://www.linnsoft.com/techind/money-flow-index-mfi}\cr #'\url{http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:money_flow_index_mfi}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' mfi <- MFI(ttrc[,c("High","Low","Close")], ttrc[,"Volume"]) #' "MFI" <- function(HLC, volume, n=14) { # Money Flow Index HLC <- try.xts(HLC, error=as.matrix) volume <- try.xts(volume, error=as.matrix) if(!(is.xts(HLC) && is.xts(volume))) { HLC <- as.matrix(HLC) volume <- as.matrix(volume) } if(NCOL(HLC)==3) { if(is.xts(HLC)) { HLC <- xts(apply(HLC, 1, mean),index(HLC)) } else { HLC <- apply(HLC, 1, mean) } } else if(NCOL(HLC)!=1) { stop("Price series must be either High-Low-Close, or Close/univariate.") } if(is.xts(HLC)) { priceLag <- lag.xts(HLC) } else { priceLag <- c( NA, HLC[-NROW(HLC)] ) } # Calculate Money Flow mf <- HLC * volume # Calculate positive and negative Money Flow pmf <- ifelse( HLC > priceLag, mf, 0 ) nmf <- ifelse( HLC < priceLag, mf, 0 ) # Calculate Money Ratio and Money Flow Index mr <- runSum( pmf, n ) / runSum( nmf, n ) mfi <- 100 - ( 100 / ( 1 + mr ) ) if(is.xts(mfi)) colnames(mfi) <- 'mfi' reclass( mfi, HLC ) } TTR/R/MACD.R0000644000176200001440000001333513552670134011766 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'MACD Oscillator #' #'The MACD was developed by Gerald Appel and is probably the most popular price #'oscillator. The MACD function documented in this page compares a fast moving #'average (MA) of a series with a slow MA of the same series. It can be used #'as a generic oscillator for any univariate series, not only price. #' #'The MACD function either subtracts the fast MA from the slow MA, or finds the #'rate of change between the fast MA and the slow MA. #' #'@param x Object that is coercible to xts or matrix; usually price, but can be #'volume, etc. #'@param nFast Number of periods for fast moving average. #'@param nSlow Number of periods for slow moving average. #'@param nSig Number of periods for signal moving average. #'@param maType Either: #' \enumerate{ #' \item A function or a string naming the function to be called. #' \item A \emph{list} with the first component like (1) above, and #' additional parameters specified as \emph{named} components. #' See Examples. #' } #'@param percent logical; if \code{TRUE}, the percentage difference between the #'fast and slow moving averages is returned, otherwise the difference between #'the respective averages is returned. #'@param \dots Other arguments to be passed to the \code{maType} function in #'case (1) above. #'@return A object of the same class as \code{x} or a matrix (if \code{try.xts} #'fails) containing the columns: #' \describe{ #' \item{ macd }{ The price (volume, etc.) oscillator. } #' \item{ signal }{ The oscillator signal line (a moving average of the oscillator). } #' } #'@note The MACD is a special case of the general oscillator applied to price. #'The MACD can be used as a general oscillator applied to any series. Time #'periods for the MACD are often given as 26 and 12, but the original formula #'used exponential constants of 0.075 and 0.15, which are closer to #'25.6667 and 12.3333 periods. #'@author Joshua Ulrich #'@seealso See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average #'options; and note Warning section. #'@references The following site(s) were used to code/document this #'indicator: #'\cr Moving Average Convergence/Divergence (MACD):\cr #'\url{http://www.fmlabs.com/reference/MACD.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=66}\cr #'\url{https://www.linnsoft.com/techind/macd}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_average_convergence_divergence_macd}\cr #'\cr Price Oscillator:\cr #'\url{http://www.fmlabs.com/reference/PriceOscillator.htm}\cr #'\url{http://www.fmlabs.com/reference/PriceOscillatorPct.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=94}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:price_oscillators_ppo}\cr #'\cr Volume Oscillator:\cr #'\url{http://www.fmlabs.com/reference/PVO.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=122}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' #' macd <- MACD( ttrc[,"Close"], 12, 26, 9, maType="EMA" ) #' macd2 <- MACD( ttrc[,"Close"], 12, 26, 9, #' maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA)) ) #' "MACD" <- function(x, nFast=12, nSlow=26, nSig=9, maType, percent=TRUE, ...) { # Oscillators # WISHLIST: # Add capability to allow 'ma.slow' and 'ma.fast' to be vectors # containing MAs, which would allow the oscillator to be constructed # using MAs of different prices. # Default MA if(missing(maType)) { maType <- 'EMA' } # Case of two different 'maType's for both MAs. if( is.list(maType) ) { # Make sure maType is a list of lists maTypeInfo <- sapply(maType,is.list) if( !(all(maTypeInfo) && length(maTypeInfo) == 3) ) { stop("If \'maType\' is a list, you must specify\n ", "*three* MAs (see Examples section of ?MACD)") } # If MA function has 'n' arg, see if it's populated in maType; # if it isn't, populate it with function's formal 'n' if( !is.null( formals(maType[[1]][[1]])$n ) && is.null( maType[[1]]$n ) ) { maType[[1]]$n <- nFast } if( !is.null( formals(maType[[2]][[1]])$n ) && is.null( maType[[2]]$n ) ) { maType[[2]]$n <- nSlow } if( !is.null( formals(maType[[3]][[1]])$n ) && is.null( maType[[3]]$n ) ) { maType[[3]]$n <- nSig } mavg.fast <- do.call( maType[[1]][[1]], c( list(x), maType[[1]][-1] ) ) mavg.slow <- do.call( maType[[2]][[1]], c( list(x), maType[[2]][-1] ) ) } # Case of one 'maType' for both MAs. else { mavg.fast <- do.call( maType, c( list(x), list(n=nFast, ...) ) ) mavg.slow <- do.call( maType, c( list(x), list(n=nSlow, ...) ) ) } if(percent) { macd <- 100 * ( mavg.fast / mavg.slow - 1 ) } else { macd <- mavg.fast - mavg.slow } if( is.list(maType) ) { signal <- do.call( maType[[3]][[1]], c( list( macd ), maType[[3]][-1] ) ) } else signal <- do.call( maType, c( list( macd ), list(n=nSig, ...) ) ) result <- cbind( macd, signal ) colnames(result) <- c( "macd", "signal" ) return( result ) } TTR/R/TRIX.R0000644000176200001440000001140413552670134012043 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Triple Smoothed Exponential Oscillator #' #'The TRIX indicator calculates the rate of change of a triple exponential #'moving average. Developed by Jack K. Hutson. #' #'The TRIX is calculated as follows:\cr 3MA = \code{MA}( \code{MA}( #'\code{MA}(\code{price}) ) )\cr trix = 100 * [ 3MA(t) / 3MA(t-1) - 1 ] #' #'@param price Price series that is coercible to xts or matrix. #'@param n Number of periods for moving average. #'@param nSig Number of periods for signal line moving average. #'@param maType Either: #' \enumerate{ #' \item A function or a string naming the function to be called. #' \item A \emph{list} with the first component like (1) above, and #' additional parameters specified as \emph{named} components. #' See Examples. #' } #'@param percent logical; if \code{TRUE}, the rate of change is calculated #'using the \code{ROC} function, otherwise the \code{momentum} function is #'used. #'@param \dots Other arguments to be passed to the \code{maType} function in #'case (1) above. #'@return A object of the same class as \code{price} or a vector (if #'\code{try.xts} fails) containing the TRIX values. #'@note Buy/sell signals are generated when the TRIX crosses above/below zero. #'A nine-period EMA of the TRIX is used as a default signal line. Buy/sell #'signals are generated when the TRIX crosses above/below the signal line and #'is also above/below zero. #'@author Joshua Ulrich #'@seealso See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average #'options; and note Warning section. #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{http://www.fmlabs.com/reference/default.htm?url=TRIX.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=114}\cr #'\url{https://www.linnsoft.com/techind/trix-triple-smoothed-exponential-oscillator}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:trix}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' trix <- TRIX(ttrc[,"Close"]) #' trix4 <- TRIX(ttrc[,"Close"], #' maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA), list(DEMA))) #' "TRIX" <- function(price, n=20, nSig=9, maType, percent=TRUE, ...) { # Triple Smoothed Exponential Oscillator # Default MA if(missing(maType)) { maType <- 'EMA' } # Case of different 'maType's for all MAs. if( is.list(maType) ) { # Make sure maType is a list of lists maTypeInfo <- sapply(maType,is.list) if( !(all(maTypeInfo) && length(maTypeInfo) == 4) ) { stop("If \'maType\' is a list, you must specify\n ", "*four* MAs (see Examples section of ?TRIX)") } # If MA function has 'n' arg, see if it's populated in maType; # if it isn't, populate it with function's formal 'n' if( !is.null( formals(maType[[1]][[1]])$n ) && is.null( maType[[1]]$n ) ) { maType[[1]]$n <- n } if( !is.null( formals(maType[[2]][[1]])$n ) && is.null( maType[[2]]$n ) ) { maType[[2]]$n <- n } if( !is.null( formals(maType[[3]][[1]])$n ) && is.null( maType[[3]]$n ) ) { maType[[3]]$n <- n } if( !is.null( formals(maType[[4]][[1]])$n ) && is.null( maType[[4]]$n ) ) { maType[[4]]$n <- nSig } mavg1 <- do.call( maType[[1]][[1]], c( list(price), maType[[1]][-1] ) ) mavg2 <- do.call( maType[[2]][[1]], c( list(mavg1), maType[[2]][-1] ) ) mavg3 <- do.call( maType[[3]][[1]], c( list(mavg2), maType[[3]][-1] ) ) } # Case of one 'maType' for all MAs. else { mavg1 <- do.call( maType, c( list(price), list(n=n, ...) ) ) mavg2 <- do.call( maType, c( list(mavg1), list(n=n, ...) ) ) mavg3 <- do.call( maType, c( list(mavg2), list(n=n, ...) ) ) } if(percent) { TRIX <- 100 * ROC(mavg3, n=1, na.pad=TRUE, type="discrete") } else { TRIX <- momentum( mavg3, n=1, na.pad=TRUE ) } if( is.list(maType) ) { signal <- do.call( maType[[4]][[1]], c( list(TRIX), maType[[4]][-1] ) ) } else { signal <- do.call( maType, c( list(TRIX), list(n=n, ...) ) ) } result <- cbind( TRIX, signal ) colnames(result) <- c( "TRIX", "signal" ) return( result ) } TTR/R/CLV.R0000644000176200001440000000362513552670134011707 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Close Location Value #' #'The Close Location Value (CLV) relates the day's close to its trading range. #' #'The CLV will fall in a range of -1 to +1. If the CLV is +/-1, the close is #'at the high/low; if the CLV is 0, the close is directly between the high and #'low. #' #'@param HLC Object that is coercible to xts or matrix and contains #'High-Low-Close prices. #'@return A object of the same class as \code{HLC} or a vector (if #'\code{try.xts} fails) containing the Close Location Values of a #'High-Low-Close price series. #'@author Joshua Ulrich #'@seealso See \code{\link{chaikinAD}}, which uses CLV. #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:accumulation_distribution_line}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' clv <- CLV(ttrc[,c("High","Low","Close")]) #' "CLV" <- function(HLC) { # Close Location Value HLC <- try.xts(HLC, error=as.matrix) clv <- ((HLC[,3]-HLC[,2]) - (HLC[,1]-HLC[,3])) / (HLC[,1]-HLC[,2]) # Account for H=L=C clv[is.nan(clv) | is.infinite(clv)] <- 0 if(is.xts(clv)) colnames(clv) <- 'clv' reclass( clv, HLC ) } TTR/R/stochastics.R0000644000176200001440000002623213552670134013611 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Stochastic Oscillator / Stochastic Momentum Index #' #'The stochastic oscillator is a momentum indicator that relates the location #'of each day's close relative to the high/low range over the past \code{n} #'periods. Developed by George C. Lane in the late 1950s. The SMI relates #'the close to the midpoint of the high/low range. Developed by William Blau #'in 1993. #' #'If a High-Low-Close series is provided, the indicator is calculated using the #'high/low values. If a vector is provided, the calculation only uses that #'series. This allows stochastics to be calculated for: (1) series that have #'no HLC definition (e.g. foreign exchange), and (2) stochastic indicators #'(e.g. stochastic RSI - see examples). #' #'The \code{smooth} argument is the number of periods of internal smoothing to #'apply to the differences in the high-low-close range before calculating Fast #'K. Thanks to Stanley Neo for the suggestion. #' #'@aliases stochastics stochastic stoch SMI %K %D #'@param HLC Object that is coercible to xts or matrix and contains #'High-Low-Close prices. If only a univariate series is given, it will be #'used. See details. #'@param n Number of periods to use. #'@param nFastK Number of periods for fast \%K (i.e. the number of past periods #'to use). #'@param nFastD Number of periods for fast \%D (i.e. the number smoothing #'periods to apply to fast \%K). #'@param nSlowD Number of periods for slow \%D (i.e. the number smoothing #'periods to apply to fast \%D). #'@param smooth Number of internal smoothing periods to be applied before #'calculating FastK. See Details. #'@param nFast Number of periods for initial smoothing. #'@param nSlow Number of periods for double smoothing. #'@param nSig Number of periods for signal line. #'@param maType Either: #' \enumerate{ #' \item A function or a string naming the function to be called. #' \item A \emph{list} with the first component like (1) above, and #' additional parameters specified as \emph{named} components. #' See Examples. #' } #'@param bounded Logical, should current period's values be used in the #'calculation? #'@param \dots Other arguments to be passed to the \code{maType} function in #'case (1) above. #'@return A object of the same class as \code{HLC} or a matrix (if #'\code{try.xts} fails) containing the columns: #' \describe{ #' \item{ fastK }{ Stochastic Fast \%K } #' \item{ fastD }{ Stochastic Fast \%D } #' \item{ slowD }{ Stochastic Slow \%D } #' \item{ SMI }{ Stochastic Momentum Index } #' \item{ signal }{ Stochastic Momentum Index signal line } #' } #'@note The calculation for William's \%R is similar to that of stochastics' #'fast \%K. #' #'The value for fast \%K will be 0.5 whenever the highest high and #'lowest low are the same over the last \code{n} periods. #' #'The stochastic oscillator and SMI calculate relative value of the close #'versus the high/low range and the midpoint of the high/low range, #'respectively. #' #'The stochastic oscillator and the stochastic momentum index are interpreted #'similarly. Readings below 20 (above 80) are considered oversold #'(overbought). However, readings below 20 (above 80) are not necessarily #'bearish (bullish). Lane believed some of the best sell (buy) signals #'occurred when the oscillator moved from overbought (oversold) back below 80 #'(above 20). #' #'For the stochastic oscillator, buy (sell) signals can also be given when \%K #'crosses above (below) \%D. Crossover signals are quite frequent however, #'which may result in whipsaws. #'@author Joshua Ulrich #'@seealso See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average #'options; and note Warning section. See \code{\link{WPR}} to compare it's #'results to fast \%K. #'@references The following site(s) were used to code/document these #'indicators: #'\cr Stochastic Oscillator:\cr #'\url{http://www.fmlabs.com/reference/StochasticOscillator.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=106}\cr #'\url{https://www.linnsoft.com/techind/stochastics}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:stochastic_oscillator_fast_slow_and_full}\cr #'\cr SMI:\cr #'\url{http://www.fmlabs.com/reference/default.htm?url=SMI.htm}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' stochOSC <- stoch(ttrc[,c("High","Low","Close")]) #' stochWPR <- WPR(ttrc[,c("High","Low","Close")]) #' #' plot(tail(stochOSC[,"fastK"], 100), type="l", #' main="Fast %K and Williams %R", ylab="", #' ylim=range(cbind(stochOSC, stochWPR), na.rm=TRUE) ) #' lines(tail(stochWPR, 100), col="blue") #' lines(tail(1-stochWPR, 100), col="red", lty="dashed") #' #' stoch2MA <- stoch( ttrc[,c("High","Low","Close")], #' maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA)) ) #' #' SMI3MA <- SMI(ttrc[,c("High","Low","Close")], #' maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA)) ) #' #' stochRSI <- stoch( RSI(ttrc[,"Close"]) ) #'@rdname stochastics "stoch" <- function(HLC, nFastK=14, nFastD=3, nSlowD=3, maType, bounded=TRUE, smooth=1, ...) { # Stochastics HLC <- try.xts(HLC, error=as.matrix) # Calculation if HLC series is given if(NCOL(HLC)==3) { high <- HLC[,1] low <- HLC[,2] close <- HLC[,3] } else # Calculation if price vector is given if(NCOL(HLC)==1) { high <- HLC low <- HLC close <- HLC } else stop("Price series must be either High-Low-Close, or Close") if(bounded) { hmax <- runMax(high, nFastK) lmin <- runMin( low, nFastK) } else { hmax <- runMax(c(high[1],high[-NROW(HLC)]), nFastK) lmin <- runMax(c( low[1], low[-NROW(HLC)]), nFastK) } num <- close - lmin den <- hmax - lmin if(missing(maType)) { maType <- 'SMA' } # Case of two different 'maType's for both MAs. # e.g. stoch(price, 14, 3, 3, # maType=list(maUp=list(EMA,ratio=1/5), maDown=list(WMA,wts=1:10)) ) if( is.list(maType) ) { # Make sure maType is a list of lists maTypeInfo <- sapply(maType,is.list) if( !(all(maTypeInfo) && length(maTypeInfo) == 3) ) { stop("If \'maType\' is a list, you must specify\n ", "*three* MAs (see Examples section of ?stochastics)") } # If MA function has 'n' arg, see if it's populated in maType; # if it isn't, populate it with function's formal 'n' if( !is.null( formals(maType[[1]][[1]])$n ) && is.null( maType[[1]]$n ) ) { maType[[1]]$n <- nFastD } if( !is.null( formals(maType[[2]][[1]])$n ) && is.null( maType[[2]]$n ) ) { maType[[2]]$n <- nSlowD } if( !is.null( formals(maType[[3]][[1]])$n ) && is.null( maType[[3]]$n ) ) { maType[[3]]$n <- smooth } numMA <- do.call( maType[[3]][[1]], c( list(num), maType[[3]][-1] ) ) denMA <- do.call( maType[[3]][[1]], c( list(den), maType[[3]][-1] ) ) fastK <- numMA / denMA fastK[is.nan(fastK)] <- 0.5 fastD <- do.call( maType[[1]][[1]], c( list(fastK), maType[[1]][-1] ) ) slowD <- do.call( maType[[2]][[1]], c( list(fastD), maType[[2]][-1] ) ) } # Case of one 'maType' for both MAs. # e.g. stoch(price, 14, 3, 3, maType="WMA", wts=volume ) else { numMA <- do.call( maType, c( list(num), list(n=smooth) ) ) denMA <- do.call( maType, c( list(den), list(n=smooth) ) ) fastK <- numMA / denMA fastK[is.nan(fastK)] <- 0.5 fastD <- do.call( maType, c( list(fastK), list(n=nFastD, ...) ) ) slowD <- do.call( maType, c( list(fastD), list(n=nSlowD, ...) ) ) } result <- cbind( fastK, fastD, slowD ) colnames(result) <- c( "fastK", "fastD", "slowD" ) reclass(result, HLC) } #-------------------------------------------------------------------------# #'@rdname stochastics "SMI" <- function(HLC, n=13, nFast=2, nSlow=25, nSig=9, maType, bounded=TRUE, ...) { # Stochastic Momentum Index # Not Validated # http://www.fmlabs.com/reference/default.htm?url=SMI.htm # The median in the SMI formula on the above site is incorrect. # Calculation if HLC series is given if(ncol(HLC)==3) { high <- HLC[,1] low <- HLC[,2] close <- HLC[,3] } else # Calculation if price vector is given if(ncol(HLC)==1) { high <- HLC low <- HLC close <- HLC } else stop("Price series must be either High-Low-Close, or Close") if(bounded) { hmax <- runMax(high, n) lmin <- runMin( low, n) } else { hmax <- runMax(c(high[1],high[-NROW(HLC)]), n) lmin <- runMax(c( low[1], low[-NROW(HLC)]), n) } hmax <- ifelse( is.na(hmax), high, hmax ) lmin <- ifelse( is.na(lmin), low, lmin ) HLdiff <- hmax - lmin Cdiff <- close - ( hmax + lmin ) / 2 if(missing(maType)) { maType <- 'EMA' } # Case of two different 'maType's for both MAs. # e.g. SMI(price, 13, 2, 25, 9, # maType=list(maUp=list(EMA,ratio=1/5), maDown=list(WMA,wts=1:10)) ) if( is.list(maType) ) { # Make sure maType is a list of lists maTypeInfo <- sapply(maType,is.list) if( !(all(maTypeInfo) && length(maTypeInfo) == 3) ) { stop("If \'maType\' is a list, you must specify\n ", "*three* MAs (see Examples section of ?SMI)") } # If MA function has 'n' arg, see if it's populated in maType; # if it isn't, populate it with function's formal 'n' if( !is.null( formals(maType[[1]][[1]])$n ) && is.null( maType[[1]]$n ) ) { maType[[1]]$n <- nFast } if( !is.null( formals(maType[[2]][[1]])$n ) && is.null( maType[[2]]$n ) ) { maType[[2]]$n <- nSlow } if( !is.null( formals(maType[[3]][[1]])$n ) && is.null( maType[[3]]$n ) ) { maType[[3]]$n <- nSig } num1 <- do.call( maType[[1]][[1]], c( list(Cdiff ), maType[[1]][-1] ) ) den1 <- do.call( maType[[1]][[1]], c( list(HLdiff), maType[[1]][-1] ) ) num2 <- do.call( maType[[2]][[1]], c( list( num1 ), maType[[2]][-1] ) ) den2 <- do.call( maType[[2]][[1]], c( list( den1 ), maType[[2]][-1] ) ) SMI <- 100 * ( num2 / ( den2 / 2 ) ) signal <- do.call( maType[[3]][[1]], c( list(SMI), maType[[3]][-1] ) ) } # Case of one 'maType' for both MAs. # e.g. SMI(price, 13, 2, 25, 9, maType="WMA", wts=volume ) else { num1 <- do.call( maType, c( list(Cdiff ), list(n=nSlow, ... ) ) ) den1 <- do.call( maType, c( list(HLdiff), list(n=nSlow, ... ) ) ) num2 <- do.call( maType, c( list( num1 ), list(n=nFast, ... ) ) ) den2 <- do.call( maType, c( list( den1 ), list(n=nFast, ... ) ) ) SMI <- 100 * ( num2 / ( den2 / 2 ) ) signal <- do.call( maType, c( list(SMI), list(n=nSig, ... ) ) ) } result <- cbind( SMI, signal ) colnames(result) <- c( "SMI", "signal" ) reclass( result, HLC ) } TTR/R/volatility.R0000644000176200001440000002367613552670134013473 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Volatility #' #'Selected volatility estimators/indicators; various authors. #' #'\itemize{ #'\item Close-to-Close Volatility (\code{calc="close"})\cr #'\deqn{ \sigma_{cl} = \sqrt{\frac{N}{n-2} \sum_{i=1}^{n-1}(r_i-\bar{r})^2} #'}{sqrt(N) * runSD(ROC(Cl), n-1)} #'\deqn{where\;\; r_i = \log \left(\frac{C_i}{C_{i-1}}\right) }{} #'\deqn{and\;\; \bar{r} = \frac{r_1+r_2+\ldots +r_{n-1}}{n-1} }{} #' #'\item OHLC Volatility: Garman and Klass (\code{calc="garman.klass"})\cr The #'Garman and Klass estimator for estimating historical volatility assumes #'Brownian motion with zero drift and no opening jumps (i.e. the opening = #'close of the previous period). This estimator is 7.4 times more efficient #'than the close-to-close estimator.\cr #'\deqn{ \sigma = \sqrt{ \frac{N}{n} \sum #' \left[ \textstyle\frac{1}{2}\displaystyle #' \left( \log \frac{H_i}{L_i} \right)^2 - (2\log 2-1) #' \left( \log \frac{C_i}{O_i} \right)^2 \right] } #'}{sqrt(N/n * runSum(0.5 * log(Hi/Lo)^2 - #' (2*log(2)-1) * log(Cl/Op)^2, n))} #' #'\item High-Low Volatility: Parkinson (\code{calc="parkinson"})\cr #'The Parkinson formula for estimating the historical volatility of #'an underlying based on high and low prices.\cr #'\deqn{ \sigma = \sqrt{ \frac{N}{4 n \times \log 2} \sum_{i=1}^{n} #' \left(\log \frac{H_i}{L_i}\right)^2} #'}{sqrt(N/(4*n*log(2)) * runSum(log(Hi/Lo)^2, n))} #' #'\item OHLC Volatility: Rogers and Satchell (\code{calc="rogers.satchell"})\cr #'The Roger and Satchell historical volatility estimator allows for non-zero #'drift, but assumed no opening jump.\cr #'\deqn{ \sigma = \sqrt{ \textstyle\frac{N}{n} \sum \left[ #' \log \textstyle\frac{H_i}{C_i} \times \log \textstyle\frac{H_i}{O_i} + #' \log \textstyle\frac{L_i}{C_i} \times \log \textstyle\frac{L_i}{O_i} \right] } #'}{sqrt(N/n * runSum(log(Hi/Cl) * log(Hi/Op) + #' log(Lo/Cl) * log(Lo/Op), n))} #' #'\item OHLC Volatility: Garman and Klass - Yang and Zhang #'(\code{calc="gk.yz"})\cr This estimator is a modified version of the Garman #'and Klass estimator that allows for opening gaps.\cr #'\deqn{ \sigma = \sqrt{ \textstyle\frac{N}{n} \sum \left[ #' \left( \log \textstyle\frac{O_i}{C_{i-1}} \right)^2 + #' \textstyle\frac{1}{2}\displaystyle #' \left( \log \textstyle\frac{H_i}{L_i} \right)^2 - (2 \times \log 2-1) #' \left( \log \textstyle\frac{C_i}{O_i} \right)^2 \right] } #'}{sqrt(N/n * runSum(log(Op/lag(Cl,1))^2 + #' 0.5 * log(Hi/Lo)^2 - (2*log(2)-1) * log(Cl/Op)^2 , n))} #' #'\item OHLC Volatility: Yang and Zhang (\code{calc="yang.zhang"})\cr The Yang #'and Zhang historical volatility estimator has minimum estimation error, and #'is independent of drift and opening gaps. It can be interpreted as a #'weighted average of the Rogers and Satchell estimator, the close-open #'volatility, and the open-close volatility. #' #'Users may override the default values of \eqn{\alpha} (1.34 by default) or #'\eqn{k} used in the calculation by specifying \code{alpha} or \code{k} in #'\code{\dots}, respectively. Specifying \code{k} will cause \code{alpha} to be #'ignored, if both are provided.\cr #'\deqn{ \sigma^2 = \sigma_o^2 + k\sigma_c^2 + (1-k)\sigma_{rs}^2 #'}{ s <- sqrt(s2o + k*s2c + (1-k)*(s2rs^2)) } #'\deqn{ \sigma_o^2 =\textstyle \frac{N}{n-1} \sum #' \left( \log \frac{O_i}{C_{i-1}}-\mu_o \right)^2 #'}{ s2o <- N * runVar(log(Op/lag(Cl,1)), n=n) } #'\deqn{ \mu_o=\textstyle \frac{1}{n} \sum \log \frac{O_i}{C_{i-1}} }{} #'\deqn{ \sigma_c^2 =\textstyle \frac{N}{n-1} \sum #' \left( \log \frac{C_i}{O_i}-\mu_c \right)^2 #'}{ s2c <- N * runVar(log(Cl/Op), n=n) } #'\deqn{ \mu_c=\textstyle \frac{1}{n} \sum \log \frac{C_i}{O_i} }{} #'\deqn{ \sigma_{rs}^2 = \textstyle\frac{N}{n} \sum \left( #' \log \textstyle\frac{H_i}{C_i} \times \log \textstyle\frac{H_i}{O_i} + #' \log \textstyle\frac{L_i}{C_i} \times \log \textstyle\frac{L_i}{O_i} #' \right) #'}{ s2rs <- volatility(OHLC, n, "rogers.satchell", N, ...) } #'\deqn{ k=\frac{\alpha-1}{alpha+\frac{n+1}{n-1}} #'}{ k <- (alpha-1) / (alpha + (n+1)/(n-1)) } #'} #' #'@aliases volatility garman.klass parkinson rogers.satchell gk.yz yang.zhang #'@param OHLC Object that is coercible to xts or matrix and contains #'Open-High-Low-Close prices (or only Close prices, if \code{calc="close"}). #'@param n Number of periods for the volatility estimate. #'@param calc The calculation (type) of estimator to use. #'@param N Number of periods per year. #'@param mean0 Use a mean of 0 rather than the sample mean. #'@param \dots Arguments to be passed to/from other methods. #'@return A object of the same class as \code{OHLC} or a vector (if #'\code{try.xts} fails) containing the chosen volatility estimator values. #'@author Joshua Ulrich #'@seealso See \code{\link{TR}} and \code{\link{chaikinVolatility}} for other #'volatility measures. #'@references The following sites were used to code/document these #'indicators. All were created by Thijs van den Berg under the GNU Free #'Documentation License and were retrieved on 2008-04-20. The original #'links are dead, but can be accessed via internet archives.\cr #'\cr Close-to-Close Volatility (\code{calc="close"}):\cr #'\url{https://web.archive.org/web/20100421083157/http://www.sitmo.com/eq/172}\cr #'\cr OHLC Volatility: Garman Klass (\code{calc="garman.klass"}):\cr #'\url{https://web.archive.org/web/20100326172550/http://www.sitmo.com/eq/402}\cr #'\cr High-Low Volatility: Parkinson (\code{calc="parkinson"}):\cr #'\url{https://web.archive.org/web/20100328195855/http://www.sitmo.com/eq/173}\cr #'\cr OHLC Volatility: Rogers Satchell (\code{calc="rogers.satchell"}):\cr #'\url{https://web.archive.org/web/20091002233833/http://www.sitmo.com/eq/414}\cr #'\cr OHLC Volatility: Garman Klass - Yang Zhang (\code{calc="gk.yz"}):\cr #'\url{https://web.archive.org/web/20100326215050/http://www.sitmo.com/eq/409}\cr #'\cr OHLC Volatility: Yang Zhang (\code{calc="yang.zhang"}):\cr #'\url{https://web.archive.org/web/20100326215050/http://www.sitmo.com/eq/409}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' ohlc <- ttrc[,c("Open","High","Low","Close")] #' vClose <- volatility(ohlc, calc="close") #' vClose0 <- volatility(ohlc, calc="close", mean0=TRUE) #' vGK <- volatility(ohlc, calc="garman") #' vParkinson <- volatility(ohlc, calc="parkinson") #' vRS <- volatility(ohlc, calc="rogers") #' "volatility" <- function(OHLC, n=10, calc="close", N=260, mean0=FALSE, ...) { OHLC <- try.xts(OHLC, error=as.matrix) # Choose an arg name that doesn't clash with ROC's 'type' arg calc <- match.arg(calc, c("close","garman.klass","parkinson", "rogers.satchell","gk.yz","yang.zhang")) # s Volatility # N Number of closing prices in a year # n Number of historical prices used for the volatility estimate # ci The closing price on the ith day # ri Log return on the ith day # Historical Close-to-Close Volatility # http://www.sitmo.com/eq/172 if( calc=="close" ) { # Add univariate case from Cedrick Johnson's R-SIG-Finance post if( NCOL(OHLC) == 1 ) { r <- ROC(OHLC[, 1], 1, ...) } else { r <- ROC(OHLC[, 4], 1, ...) } if( isTRUE(mean0) ) { # This is an alternative SD calculation using an effective mean of 0 s <- sqrt(N) * sqrt(runSum(r^2, n-1) / (n-2)) } else { # This is the standard SD calculation using the sample mean s <- sqrt(N) * runSD(r, n-1) } } # Historical Open-High-Low-Close Volatility: Garman Klass # http://www.sitmo.com/eq/402 if( calc=="garman.klass" ) { s <- sqrt( N/n * runSum( .5 * log(OHLC[,2]/OHLC[,3])^2 - (2*log(2)-1) * log(OHLC[,4]/OHLC[,1])^2 , n ) ) } if( calc=="parkinson" ) { # Historical High-Low Volatility: Parkinson # http://www.sitmo.com/eq/173 s <- sqrt( N/(4*n*log(2)) * runSum( log(OHLC[,2]/OHLC[,3])^2, n ) ) } if( calc=="rogers.satchell" ) { # Historical Open-High-Low-Close Volatility: Rogers Satchell # http://www.sitmo.com/eq/414 s <- sqrt( N/n * runSum( log(OHLC[,2]/OHLC[,4]) * log(OHLC[,2]/OHLC[,1]) + log(OHLC[,3]/OHLC[,4]) * log(OHLC[,3]/OHLC[,1]), n ) ) } if( calc=="gk.yz" ) { #if( calc=="garman.klass.yang.zhang" ) { # Historical Open-High-Low-Close Volatility: Garman and Klass (Yang Zhang) # http://www.sitmo.com/eq/409 if(is.xts(OHLC)) { Cl1 <- lag.xts(OHLC[,4]) } else { Cl1 <- c( NA, OHLC[-NROW(OHLC),4] ) } s <- sqrt( N/n * runSum( log(OHLC[,1]/Cl1)^2 + .5 * log(OHLC[,2]/OHLC[,3])^2 - (2*log(2)-1) * log(OHLC[,4]/OHLC[,1])^2 , n) ) #s <- sqrt( Z/n * runSum( # log(op/cl[-1])^2 + # .5*log(hi/lo)^2 - # (2*log(2)-1)*log(cl/op)^2 ) ) } if( calc=="yang.zhang" ) { # Historical Open-High-Low-Close Volatility: Yang Zhang # http://www.sitmo.com/eq/417 if(is.xts(OHLC)) { Cl1 <- lag.xts(OHLC[,4]) } else { Cl1 <- c( NA, OHLC[-NROW(OHLC),4] ) } dots <- list(...) if(is.null(dots$alpha)) { alpha <- 1.34 } if(is.null(dots$k)) { k <- (alpha-1) / ( alpha + (n+1)/(n-1) ) } s2o <- N * runVar(log(OHLC[,1] / Cl1), n=n) s2c <- N * runVar(log(OHLC[,4] / OHLC[,1]), n=n) s2rs <- volatility(OHLC=OHLC, n=n, calc="rogers.satchell", N=N, ...) s <- sqrt(s2o + k*s2c + (1-k)*(s2rs^2)) } reclass(s,OHLC) } TTR/R/zzz.R0000644000176200001440000000147513425330036012112 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2017 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # .env <- new.env() .onUnload <- function(libpath) { library.dynam.unload("TTR", libpath) } TTR/R/CMF.R0000644000176200001440000000506713552670134011672 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Chaikin Money Flow #' #'Chaikin Money Flow compares total volume over the last \code{n} time periods #'to total volume times the Close Location Value (CLV) over the last \code{n} #'time periods. Developed by Marc Chaikin. #' #'Chaikin Money Flow is calculated by taking dividing the sum of the Chaikin #'Accumulation / Distribution line over the past \code{n} periods by the sum of #'volume over the past \code{n} periods. #' #'@param HLC Object that is coercible to xts or matrix and contains #'High-Low-Close prices. #'@param volume Vector or matrix of volume observations corresponding to the #'\code{HLC} object. #'@param n Number of periods to use. #'@return A object of the same class as \code{HLC} and \code{volume} or a #'vector (if \code{try.xts} fails) containing the Chaikin Money Flow values. #'@note When Chaikin Money Flow is above/below +/- 0.25 it is a bullish/bearish #'signal. If Chaikin Money Flow remains below zero while the price is rising, #'it indicates a probable reversal. #'@author Joshua Ulrich #'@seealso See \code{\link{CLV}}, and \code{\link{chaikinAD}}. #'@references The following site(s) were used to code/document this #'indicator:\cr \url{http://www.fmlabs.com/reference/ChaikinMoneyFlow.htm}\cr #'\url{https://www.linnsoft.com/techind/chaikin-money-flow-cmf}\cr #'\url{http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:chaikin_money_flow_cmf}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' cmf <- CMF(ttrc[,c("High","Low","Close")], ttrc[,"Volume"]) #' "CMF" <- function(HLC, volume, n=20) { # Chaikin Money Flow HLC <- try.xts(HLC, error=as.matrix) volume <- try.xts(volume, error=as.matrix) if(!(is.xts(HLC) && is.xts(volume))) { clv <- CLV(as.matrix(HLC)) volume <- as.matrix(volume) } clv <- CLV(HLC) cmf <- runSum(clv*volume, n) / runSum(volume, n) reclass(cmf, HLC) } TTR/R/bollingerBands.R0000644000176200001440000001023713552670134014205 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Bollinger Bands #' #'Bollinger Bands are a way to compare a security's volatility and price levels #'over a period of time. Developed by John Bollinger. #' #'Bollinger Bands consist of three lines: #' #'The middle band is generally a 20-period SMA of the typical price ([high + #'low + close]/3). The upper and lower bands are \code{sd} standard deviations #'(generally 2) above and below the MA. #' #'The middle band is usually calculated using the typical price, but if a #'univariate series (e.g. Close, Weighted Close, Median Price, etc.) is #'provided, it will be used instead. #' #'@aliases bollingerBands BBands #'@param HLC Object that is coercible to xts or matrix and contains #'High-Low-Close prices. If only a univariate series is given, it will be #'used. See details. #'@param n Number of periods for moving average. #'@param maType A function or a string naming the function to be called. #'@param sd The number of standard deviations to use. #'@param \dots Other arguments to be passed to the \code{maType} function. #'@return A object of the same class as \code{HLC} or a matrix (if #'\code{try.xts} fails) containing the columns: #' \describe{ #' \item{ dn }{ The lower Bollinger Band. } #' \item{ mavg }{ The middle Moving Average (see notes). } #' \item{ up }{ The upper Bollinger Band. } #' \item{ pctB }{ The \%B calculation. } #' } #'@note Using any moving average other than SMA will result in inconsistencies #'between the moving average calculation and the standard deviation #'calculation. Since, by definition, a rolling standard deviation uses a #'simple moving average. #'@author Joshua Ulrich #'@seealso See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average #'options; and note Warning section. #'@references The following site(s) were used to code/document this #'indicator:\cr \url{http://www.fmlabs.com/reference/Bollinger.htm}\cr #'\url{http://www.fmlabs.com/reference/BollingerWidth.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=36}\cr #'\url{https://www.linnsoft.com/techind/bollinger-bands}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:bollinger_bands}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:bollinger_band_width}\cr #'@keywords ts #'@examples #' #' ## The examples below show the differences between using a #' ## High-Low-Close series, and just a close series when #' ## calculating Bollinger Bands. #' data(ttrc) #' bbands.HLC <- BBands( ttrc[,c("High","Low","Close")] ) #' bbands.close <- BBands( ttrc[,"Close"] ) #'@rdname bollingerBands "BBands" <- function(HLC, n=20, maType, sd=2, ...) { # Bollinger Bands HLC <- try.xts(HLC, error=as.matrix) if(NCOL(HLC)==3) { if(is.xts(HLC)) { xa <- xcoredata(HLC) HLC <- xts(apply(HLC, 1, mean),index(HLC)) xcoredata(HLC) <- xa } else { HLC <- apply(HLC, 1, mean) } } else if(NCOL(HLC)!=1) { stop("Price series must be either High-Low-Close, or Close/univariate.") } maArgs <- list(n=n, ...) # Default MA if(missing(maType)) { maType <- 'SMA' } mavg <- do.call( maType, c( list(HLC), maArgs ) ) # Calculate standard deviation by hand to incorporate various MAs sdev <- runSD(HLC, n, sample=FALSE) up <- mavg + sd * sdev dn <- mavg - sd * sdev pctB <- (HLC - dn) / (up - dn) res <- cbind(dn, mavg, up, pctB) colnames(res) <- c("dn", "mavg", "up", "pctB") reclass(res, HLC) } TTR/R/RSI.R0000644000176200001440000001165113552670134011716 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Relative Strength Index #' #'The Relative Strength Index (RSI) calculates a ratio of the recent upward #'price movements to the absolute price movement. Developed by J. Welles #'Wilder. #' #'The RSI calculation is \code{RSI = 100 - 100 / ( 1 + RS )}, where \code{RS} #'is the smoothed ratio of 'average' gains over 'average' losses. The #''averages' aren't true averages, since they're divided by the value of #'\code{n} and not the number of periods in which there are gains/losses. #' #'@param price Price series that is coercible to xts or matrix. #'@param n Number of periods for moving averages. #'@param maType Either: #' \enumerate{ #' \item A function or a string naming the function to be called. #' \item A \emph{list} with the first component like (1) above, and #' additional parameters specified as \emph{named} components. #' See Examples. #' } #'@param \dots Other arguments to be passed to the \code{maType} function in #'case (1) above. #'@return A object of the same class as \code{price} or a vector (if #'\code{try.xts} fails) containing the RSI values. #'@note The RSI is usually interpreted as an overbought/oversold (over 70 / #'below 30) indicator. Divergence with price may also be useful. For example, #'if price is making new highs/lows, but RSI is not, it could indicate a #'reversal. #' #'You can calculate a stochastic RSI by using the function \code{\link{stoch}} #'on RSI values. #'@author Joshua Ulrich #'@seealso See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average #'options; and note Warning section. See \code{\link{CMO}} for a variation on #'RSI. #'@references The following site(s) were used to code/document this #'indicator: #'\cr Relative Strength Index:\cr #'\url{http://www.fmlabs.com/reference/RSI.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=100}\cr #'\url{https://www.linnsoft.com/techind/relative-strength-index-rsi}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:relative_strength_index_rsi}\cr #'\cr Stochastic RSI:\cr #'\url{http://www.fmlabs.com/reference/StochRSI.htm}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:stochrsi}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' price <- ttrc[,"Close"] #' #' # Default case #' rsi <- RSI(price) #' #' # Case of one 'maType' for both MAs #' rsiMA1 <- RSI(price, n=14, maType="WMA", wts=ttrc[,"Volume"]) #' #' # Case of two different 'maType's for both MAs #' rsiMA2 <- RSI(price, n=14, maType=list(maUp=list(EMA,ratio=1/5), #' maDown=list(WMA,wts=1:10))) #' #' "RSI" <- function(price, n=14, maType, ...) { price <- try.xts(price, error=as.matrix) up <- momentum(price, n=1, na.pad=TRUE) which.dn <- which(up < 0) dn <- up*0 dn[which.dn] <- -up[which.dn] up[which.dn] <- 0 maArgs <- list(n=n, ...) # Default Welles Wilder EMA if(missing(maType)) { maType <- 'EMA' if(is.null(maArgs$wilder)) { # do not overwrite user-provided value maArgs$wilder <- TRUE } } # Case of two different 'maType's for both MAs. # e.g. RSI(price, n=14, maType=list(maUp=list(EMA,ratio=1/5), maDown=list(WMA,wts=1:10)) ) if( is.list(maType) ) { # Make sure maType is a list of lists maTypeInfo <- sapply(maType,is.list) if( !(all(maTypeInfo) && length(maTypeInfo) == 2) ) { stop("If \'maType\' is a list, you must specify\n ", "*two* MAs (see Examples section of ?RSI)") } # If MA function has 'n' arg, see if it's populated in maType; # if it isn't, populate it with RSI's formal 'n' for(i in 1:length(maType)) { if( !is.null( formals(maType[[i]])$n ) && is.null( maType[[i]]$n ) ) { maType[[i]]$n <- n } mavgUp <- do.call( maType[[1]][[1]], c( list(up), maType[[1]][-1] ) ) mavgDn <- do.call( maType[[2]][[1]], c( list(dn), maType[[2]][-1] ) ) } } # Case of one 'maType' for both MAs. # e.g. RSI(price, n=14, maType="WMA", wts=volume ) else { mavgUp <- do.call( maType, c( list(up), maArgs ) ) mavgDn <- do.call( maType, c( list(dn), maArgs ) ) } rsi <- 100 * mavgUp / ( mavgUp + mavgDn ) if (!is.null(dim(rsi)) && ncol(rsi) == 1L) { colnames(rsi) <- "rsi" } reclass( rsi, price ) } TTR/R/KST.R0000644000176200001440000001277013552670134011725 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Know Sure Thing #' #'The Know Sure Thing (KST) is a smooth, summed, rate of change indicator. #'Developed by Martin Pring. #' #'For each day (week, month, etc.), the KST calculates the ROC over several #'periods. Those ROCs are smoothed using the given moving averages, then #'multiplied by their respective weighting values. The resulting values are #'summed for each day (month, week, etc.). #' #'@param price Price series that is coercible to xts or matrix. #'@param n A vector of the number of periods to use in the MA calculations. #'@param nROC A vector of the number of periods to use in the ROC calculations. #'@param nSig The number of periods to use for the KST signal line. #'@param maType Either: #' \enumerate{ #' \item A function or a string naming the function to be called. #' \item A \emph{list} with the first component like (1) above, and #' additional parameters specified as \emph{named} components. #' See Examples. #' } #'@param wts A vector the same length as \code{n}, of the weight for each #'period (need not sum to one). #'@param \dots Other arguments to be passed to the \code{maType} function in #'case (1) above. #'@return A object of the same class as \code{price} or a vector (if #'\code{try.xts} fails) containing the Know Sure Thing values. #'@note The KST indicates bullish/bearish momentum as it crosses above/below #'its moving average. Because the KST tends to lead price action, look for #'trend confirmation in the price. #' #'The default arguments are for the daily KST. There is also the Long-Term #'KST, with arguments: \code{n=c(9, 12, 18, 24)} - where the periods are #'months, not days - and the moving average periods are 6, 6, 6, and 9 months, #'respectively. #'@author Joshua Ulrich #'@seealso See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average #'options; and note Warning section. See \code{\link{ROC}} for the #'rate-of-change function. See \code{\link{MACD}} for a generic oscillator. #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{https://web.archive.org/web/20110715112957/http://www.pring.com/movieweb/daily_kst.htm}\cr #'\url{https://web.archive.org/web/20100101162707/http://www.pring.com/movieweb/KST_MCM.htm}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' kst <- KST(ttrc[,"Close"]) #' #' kst4MA <- KST(ttrc[,"Close"], #' maType=list(list(SMA),list(EMA),list(DEMA),list(WMA))) #' "KST" <- function(price, n=c(10,10,10,15), nROC=c(10,15,20,30), nSig=9, maType, wts=1:NROW(n), ...) { # Know Sure Thing # Technical Analysis Explained: The Successful Investor's Guide to # Spotting Investment Trends and Turning Points # Martin J. Pring # http://www.pring.com/index.html # Daily: http://www.pring.com/movieweb/daily_kst.htm # Long-Term: http://www.pring.com/articles/article28.htm # Daily KST # MA(ROC(10)10) + MA(ROC(15)10) + MA(ROC(20)10) + MA(ROC(30)15) # # Intermediate KST # MA(ROC(10)10) + MA(ROC(13)13) + MA(ROC(15)15) + MA(ROC(20)20) # # Long-Term Monthly KST # MA(ROC(9)6) + MA(ROC(12)6) + MA(ROC(18)6) + MA(ROC(24)9) if( !all.equal(NROW(n), NROW(wts), NROW(nROC)) ) { stop("'n', 'nROC', and 'wts' must be the same length.") } else { N <- NROW(n) } #price <- as.vector(price) ret <- NULL # Default MA if(missing(maType)) { maType <- 'SMA' } # Case of two different 'maType's for both MAs. if( is.list(maType) ) { # Make sure maType is a list of lists maTypeInfo <- sapply(maType,is.list) if( !(all(maTypeInfo) && length(maTypeInfo) == N) ) { stop("If \'maType\' is a list, you must specify\n ", "the same number of MAs as elements in \'n\' and\n ", "\'nROC\' (see Examples section of ?KST)") } # If MA function has 'n' arg, see if it's populated in maType; # if it isn't, populate it with formal 'n' for(i in 1:length(maType)) { if( !is.null( formals(maType[[i]][[1]])$n ) && is.null( maType[[i]]$n ) ) { maType[[i]]$n <- n[i] } roc <- ROC(price, nROC[i], na.pad=TRUE) ma.roc <- do.call( maType[[i]][[1]], c( list(roc), maType[[i]][-1] ) ) * wts[i] ret <- cbind( ret, ma.roc ) } } # Case of one 'maType' for both MAs. else { for(i in 1:NROW(n)) { roc <- ROC(price, nROC[i], na.pad=TRUE) ma.roc <- do.call( maType, c( list(roc), list(n=n[i], ...) ) ) * wts[i] ret <- cbind( ret, ma.roc ) } } if(is.xts(ret)) { kst <- xts(100 * rowSums(ret),index(ret)) } else { kst <- 100 * rowSums(ret) } if( is.list(maType) ) { sigMA <- length(maType) signal <- do.call( maType[[sigMA]][[1]], c( list(kst), maType[[sigMA]][-1] ) ) } else { signal <- do.call( maType, c( list(kst), list(n=nSig, ...) ) ) } result <- cbind( kst, signal ) colnames(result) <- c( "kst", "signal" ) return( result ) } TTR/R/TDI.R0000644000176200001440000000553613552670134011706 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Trend Detection Index #' #'The Trend Detection Index (TDI) attempts to identify starting and ending #'trends. Developed by M. H. Pee. #' #'The TDI is the (1) absolute value of the \code{n}-day sum of the \code{n}-day #'momentum, minus the quantity of (2) \code{multiple}*\code{n}-day sum of the #'absolute value of the \code{n}-day momentum, minus (3) \code{n}-day sum of #'the absolute value of the \code{n}-day momentum. #' #'I.e. TDI = (1) - [ (2) - (3) ] #' #'The direction indicator is the sum of the \code{n}-day momentum over the last #'\code{n} days. #' #'See URL in references section for further details. #' #'@param price Price series that is coercible to xts or matrix. #'@param n Number of periods to use. #'@param multiple Multiple used to calculate (2). #'@return A object of the same class as \code{price} or a matrix (if #'\code{try.xts} fails) containing the columns: #' \describe{ #' \item{ tdi }{ The Trend Detection Index. } #' \item{ di }{ The Direction Indicator. } #' } #'@note Positive/negative TDI values signal a trend/consolidation. A positive/ #'negative direction indicator signals a up/down trend. I.e. buy if the TDI #'and the direction indicator are positive, and sell if the TDI is positive #'while the direction indicator is negative. #'@author Joshua Ulrich #'@seealso See \code{\link{aroon}}, \code{\link{CCI}}, \code{\link{ADX}}, #'\code{\link{VHF}}, \code{\link{GMMA}} for other indicators that measure trend #'direction/strength. #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{https://www.linnsoft.com/techind/trend-detection-index-tdi}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' tdi <- TDI(ttrc[,"Close"], n=30) #' "TDI" <- function(price, n=20, multiple=2) { # Trend Detection Index price <- try.xts(price, error=as.matrix) mom <- momentum(price, n, na.pad=TRUE) mom[is.na(mom)] <- 0 di <- runSum(mom, n) abs.di <- abs(di) abs.mom.2n <- runSum(abs(mom), n*multiple) abs.mom.1n <- runSum(abs(mom), n ) tdi <- abs.di - (abs.mom.2n - abs.mom.1n) result <- cbind( tdi,di ) colnames(result) <- c( "tdi","di" ) reclass( result, price ) } TTR/R/changes.R0000644000176200001440000000563613552670134012677 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Rate of Change / Momentum #' #'Calculate the (rate of) change of a series over \code{n} periods. #' #'The ROC indicator provides the percentage difference of a series over two #'observations, while the momentum indicator simply provides the difference. #' #'@aliases changes ROC momentum #'@param x Price, volume, etc. series that is coercible to xts or matrix. #'@param n Number of periods to use. #'@param type Compounding type; either \code{"continuous"} (the default) or #'\code{"discrete"}. #'@param na.pad Should periods prior to \code{n} be appended? Default is #'\code{TRUE}. #'@return A object of the same class as \code{x} or a vector (if \code{try.xts} #'fails) containing the rate-of-change (or return) values for \code{ROC} or a #'vector containing the differenced price series for \code{momentum}. #'@author Joshua Ulrich #'@keywords ts #'@examples #' #' data(ttrc) #' roc <- ROC(ttrc[,"Close"]) #' mom <- momentum(ttrc[,"Close"]) #'@rdname changes "ROC" <- function(x, n=1, type=c("continuous","discrete"), na.pad=TRUE) { # Rate of Change x <- try.xts(x, error=as.matrix) type <- match.arg(type) if(is.xts(x)) { if(type=="discrete") { roc <- x / lag.xts(x,n,na.pad=na.pad) - 1 } # Continuous change if(type=="continuous") { roc <- diff(log(x),n,na.pad=na.pad) } # Convert back to original class reclass(roc, x) } else { NAs <- NULL if(na.pad) { NAs <- rep(NA,n) } # Discrete changes if(type=="discrete") { roc <- c( NAs, x[(n+1):NROW(x)] / x[1:(NROW(x)-n)] - 1 ) } # Continuous changes if(type=="continuous") { roc <- c( NAs, diff(log(x),n) ) } return(roc) } } #-------------------------------------------------------------------------# #'@rdname changes "momentum" <- function(x, n=1, na.pad=TRUE) { # Momentum # http://www.fmlabs.com/reference/Momentum.htm # https://www.metastock.com/Customer/Resources/TAAZ/?p=95 # https://www.linnsoft.com/tour/techind/momentum.htm x <- try.xts(x, error=as.matrix) if(is.xts(x)) { mom <- diff(x,n,na.pad=na.pad) } else { NAs <- NULL if(na.pad) { NAs <- rep(NA,n) } mom <- c( NAs, diff(x, n) ) } reclass(mom,x) } TTR/R/ultimateOscillator.R0000644000176200001440000000421113552670134015133 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'The Ultimate Oscillator #' #'The Ultimate Oscillator is a momentum oscillator designed to capture momentum across three #'different time frames. #' #'Created by Larry Williams in 1976. #' #'@param HLC Object that is coercible to xts or matrix and contains #'High-Low-Close prices. #'@param n A vector of the number of periods to use for each average calculation. #'@param wts The weights applied to each average. #'@author Ivan Popivanov #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:ultimate_oscillator}\cr #'@keywords ts #'@examples #' #'data(ttrc) #'ult.osc <- ultimateOscillator(ttrc[,c("High","Low","Close")]) #' ultimateOscillator <- function(HLC, n=c(7,14,28), wts=c(4,2,1)) { # Ultimate Oscillator if(length(n) != 3 || length(wts) != 3) stop("length(n) and length(wts) must both be 3") HLC <- try.xts(HLC, error=as.matrix) # avoid reclassing in ATR and runSum HLC.RECLASS <- attr(HLC, ".RECLASS") attr(HLC, ".RECLASS") <- FALSE # only need 'tr' and 'trueLow' atr <- ATR(HLC, n=1) buyPressure <- HLC[,3] - atr[,'trueLow'] osc <- buyPressure * 0.0 for(i in 1:3) { osc <- osc + wts[i] * (runSum(buyPressure, n[i]) / runSum(atr[,'tr'], n[i])) } osc <- 100.0 * osc / sum(wts) # restore HLC .RECLASS attribute attr(HLC, ".RECLASS") <- HLC.RECLASS reclass(osc, HLC) } TTR/R/TTRtools.R0000644000176200001440000000624713552670134013020 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Miscellaneous Tools #' #'Various functions that may be useful in designing technical trading rules. #' #'\code{growth} calculates the growth of an investment using given prices and #'signals. #' #'\code{lags} calculates the lags of a given series. #' #'@aliases growth lags #'@param price Price series that is coercible to xts or matrix. #'@param signals Signals to use (defaults to vector of ones). Use '0' for no #'position, '1' for long position, and '-1' for short position. #'@param x Object that is coercible to xts or matrix. #'@param n Number of periods to use. #'@param \dots Further arguments to be passed from or to other methods. #'@return \code{growth} returns a vector of the growth of the investment. #' #'\code{lags} returns a matrix of lagged values of the original vector. #' #'@note In \code{growth} you can specify the number of periods and type of #'compounding to use when calculating returns of the price series via the #'\code{'\dots'} argument. #'@author Joshua Ulrich #'@keywords ts #'@rdname TTRtools "lags" <- function(x, n=1) { #.Deprecated(c("xts::lag.xts","quantmod::Lag"),"TTR") # Calculate lags of a series x <- as.matrix(x) if( is.null(colnames(x)) ) colnames(x) <- paste("V",1:NCOL(x),sep="") out <- embed(x, n+1) if(n==1) lag.names <- 1 else if(NCOL(x)==1) lag.names <- 1:n else lag.names <- rep(1:n,NCOL(x)) colnames(out) <- c( colnames(x), paste(colnames(x), sort(lag.names), sep=".") ) return( out ) } #-------------------------------------------------------------------------# #'@rdname TTRtools "growth" <- function(price, signals, ...) { # Calculate growth of $1 for a series of returns (and signals). if(missing(signals)) { signals <- rep(1,NROW(price)) } else { signals <- as.vector(signals) } price <- as.vector(price) growth <- cumprod( 1 + ROC(price, ...) * signals ) return( growth ) } #-------------------------------------------------------------------------# #'@rdname TTRtools 'naCheck' <- function(x, n=0) { # Ensure NAs are only at beginning of data. if(is.null(dim(x)[2])) { NAs <- sum(is.na(x)) if( NAs > 0 ) { if( any( is.na(x[-(1:NAs)]) ) ) stop("Series contains non-leading NAs") } } else { NAs <- sum( rowSums(is.na(x)) > 0 ) if( NAs > 0 ) { if( any( is.na(x[-(1:NAs),]) ) ) stop("Series contains non-leading NAs") } } res <- list() res$NAs <- NAs res$nonNA <- (1+NAs):NROW(x) res$beg <- n+NAs invisible(res) } TTR/R/chaikinVolatility.R0000644000176200001440000000457613552670134014760 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Chaikin Volatility #' #'Chaikin Volatility measures the rate of change of the security's trading #'range. Developed by Marc Chaikin. #' #'The Chaikin Volatility indicator defines volatility as an increase in the #'difference between the high and low. #' #'@param HL Object that is coercible to xts or matrix and contains High-Low #'prices. #'@param n Number of periods for moving average. #'@param maType A function or a string naming the function to be called. #'@param \dots Other arguments to be passed to the \code{maType} function. #'@return A object of the same class as \code{HL} or a vector (if #'\code{try.xts} fails) containing the Chaikin Volatility values. #'@note A rapid increase in Chaikin Volatility indicates an approaching bottom. #'A slow decrease in Chaikin Volatility indicates an approaching top. #'@author Joshua Ulrich #'@seealso See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average #'options; and note Warning section. See \code{\link{TR}} for another #'volatility measure. #'@references The following site(s) were used to code/document this #'indicator:\cr \url{http://www.fmlabs.com/reference/ChaikinVolatility.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=120}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' volatility <- chaikinVolatility(ttrc[,c("High","Low")]) #' "chaikinVolatility" <- function(HL, n=10, maType, ...) { # Chaikin Volatility HL <- try.xts(HL, error=as.matrix) maArgs <- list(n=n, ...) # Default MA if(missing(maType)) { maType <- 'EMA' } mavg <- do.call( maType, c( list(HL[,1]-HL[,2]), maArgs ) ) volatility <- ROC( mavg, n, type="discrete" ) reclass(volatility, HL) } TTR/R/MovingAverages.R0000644000176200001440000003406413552670134014201 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Moving Averages #' #'Calculate various moving averages (MA) of a series. #' #'\code{SMA} calculates the arithmetic mean of the series over the past #'\code{n} observations. #' #'\code{EMA} calculates an exponentially-weighted mean, giving more weight to #'recent observations. See Warning section below. #' #'\code{WMA} is similar to an EMA, but with linear weighting if the length of #'\code{wts} is equal to \code{n}. If the length of \code{wts} is equal to the #'length of \code{x}, the WMA will use the values of \code{wts} as weights. #' #'\code{DEMA} is calculated as: \code{DEMA = (1 + v) * EMA(x,n) - #'EMA(EMA(x,n),n) * v} (with the corresponding \code{wilder} and \code{ratio} #'arguments). #' #'\code{EVWMA} uses volume to define the period of the MA. #' #'\code{ZLEMA} is similar to an EMA, as it gives more weight to recent #'observations, but attempts to remove lag by subtracting data prior to #'\code{(n-1)/2} periods (default) to minimize the cumulative effect. #' #'\code{VWMA} and \code{VWAP} calculate the volume-weighted moving average #'price. #' #'\code{VMA} calculate a variable-length moving average based on the absolute #'value of \code{w}. Higher (lower) values of \code{w} will cause \code{VMA} #'to react faster (slower). #' #'\code{HMA} a WMA of the difference of two other WMAs, making it very #'reponsive. #' #'\code{ALMA} inspired by Gaussian filters. Tends to put less weight on most #'recent observations, reducing tendency to overshoot. #' #'@aliases MovingAverages SMA EMA WMA DEMA GD T3 EVWMA ZLEMA VWAP VWMA VMA MA #'@param x Price, volume, etc. series that is coercible to xts or matrix. #'@param price Price series that is coercible to xts or matrix. #'@param volume Volume series that is coercible to xts or matrix, that #'corresponds to price series, or a constant. See Notes. #'@param n Number of periods to average over. Must be between 1 and #'\code{nrow(x)}, inclusive. #'@param v The 'volume factor' (a number in [0,1]). See Notes. #'@param w Vector of weights (in [0,1]) the same length as \code{x}. #'@param wts Vector of weights. Length of \code{wts} vector must equal the #'length of \code{x}, or \code{n} (the default). #'@param wilder logical; if \code{TRUE}, a Welles Wilder type EMA will be #'calculated; see notes. #'@param ratio A smoothing/decay ratio. \code{ratio} overrides \code{wilder} #'in \code{EMA}, and provides additional smoothing in \code{VMA}. #'@param offset Percentile at which the center of the distribution should occur. #'@param sigma Standard deviation of the distribution. #'@param \dots any other passthrough parameters #'@return A object of the same class as \code{x} or \code{price} or a vector #'(if \code{try.xts} fails) containing the columns: #' \describe{ #' \item{SMA}{ Simple moving average. } #' \item{EMA}{ Exponential moving average. } #' \item{WMA}{ Weighted moving average. } #' \item{DEMA}{ Double-exponential moving average. } #' \item{EVWMA}{ Elastic, volume-weighted moving average. } #' \item{ZLEMA}{ Zero lag exponential moving average. } #' \item{VWMA}{ Volume-weighed moving average (same as \code{VWAP}). } #' \item{VWAP}{ Volume-weighed average price (same as \code{VWMA}). } #' \item{VWA}{ Variable-length moving average. } #' \item{HMA}{ Hull moving average. } #' \item{ALMA}{ Arnaud Legoux moving average. } #' } #'@note For \code{EMA}, \code{wilder=FALSE} (the default) uses an exponential #'smoothing ratio of \code{2/(n+1)}, while \code{wilder=TRUE} uses Welles #'Wilder's exponential smoothing ratio of \code{1/n}. The \code{EMA} result #'is initialized with the \code{n}-period sample average at period \code{n}. #'The exponential decay is applied from that point forward. #' #'Since \code{WMA} can accept a weight vector of length equal to the length of #'\code{x} or of length \code{n}, it can be used as a regular weighted moving #'average (in the case \code{wts=1:n}) or as a moving average weighted by #'volume, another indicator, etc. #' #'Since \code{DEMA} allows adjusting \code{v}, it is technically Tim Tillson's #'generalized DEMA (GD). When \code{v=1} (the default), the result is the #'standard DEMA. When \code{v=0}, the result is a regular EMA. All other #'values of \code{v} return the GD result. This function can be used to #'calculate Tillson's T3 indicator (see example below). Thanks to John Gavin #'for suggesting the generalization. #' #'For \code{EVWMA}, if \code{volume} is a series, \code{n} should be chosen so #'the sum of the volume for \code{n} periods approximates the total number of #'outstanding shares for the security being averaged. If \code{volume} is a #'constant, it should represent the total number of outstanding shares for the #'security being averaged. #'@section Warning : Some indicators (e.g. EMA, DEMA, EVWMA, etc.) are #'calculated using the indicators' own previous values, and are therefore #'unstable in the short-term. As the indicator receives more data, its output #'becomes more stable. See example below. #'@author Joshua Ulrich, Ivan Popivanov (HMA, ALMA) #'@seealso See \code{\link{wilderSum}}, which is used in calculating a Welles #'Wilder type MA. #'@references The following site(s) were used to code/document this #'indicator:\cr \url{http://www.fmlabs.com/reference/ExpMA.htm}\cr #'\url{http://www.fmlabs.com/reference/WeightedMA.htm}\cr #'\url{http://www.fmlabs.com/reference/DEMA.htm}\cr #'\url{http://www.fmlabs.com/reference/T3.htm}\cr #'\url{https://www.linnsoft.com/techind/evwma-elastic-volume-weighted-moving-average}\cr #'\url{http://www.fmlabs.com/reference/ZeroLagExpMA.htm}\cr #'\url{http://www.fmlabs.com/reference/VIDYA.htm}\cr #'\url{http://www.traderslog.com/hullmovingaverage}\cr #'\url{http://www.arnaudlegoux.com/}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' ema.20 <- EMA(ttrc[,"Close"], 20) #' sma.20 <- SMA(ttrc[,"Close"], 20) #' dema.20 <- DEMA(ttrc[,"Close"], 20) #' evwma.20 <- EVWMA(ttrc[,"Close"], ttrc[,"Volume"], 20) #' zlema.20 <- ZLEMA(ttrc[,"Close"], 20) #' alma <- ALMA(ttrc[,"Close"]) #' hma <- HMA(ttrc[,"Close"]) #' #' ## Example of Tim Tillson's T3 indicator #' T3 <- function(x, n=10, v=1) DEMA(DEMA(DEMA(x,n,v),n,v),n,v) #' t3 <- T3(ttrc[,"Close"]) #' #' ## Example of short-term instability of EMA #' ## (and other indicators mentioned above) #' x <- rnorm(100) #' tail( EMA(x[90:100],10), 1 ) #' tail( EMA(x[70:100],10), 1 ) #' tail( EMA(x[50:100],10), 1 ) #' tail( EMA(x[30:100],10), 1 ) #' tail( EMA(x[10:100],10), 1 ) #' tail( EMA(x[ 1:100],10), 1 ) #' #'@rdname MovingAverages "SMA" <- function(x, n=10, ...) { # Simple Moving Average ma <- runMean( x, n ) if(!is.null(dim(ma))) { colnames(ma) <- "SMA" } return(ma) } #-------------------------------------------------------------------------# #'@rdname MovingAverages "EMA" <- function (x, n=10, wilder=FALSE, ratio=NULL, ...) { # Exponential Moving Average x <- try.xts(x, error=as.matrix) if( n < 1 || n > NROW(x) ) stop(sprintf("n = %d is outside valid range: [1, %d]", n, NROW(x))) if(NCOL(x) > 1) { stop("ncol(x) > 1. EMA only supports univariate 'x'") } if( any(nNonNA <- n > colSums(!is.na(x))) ) stop("n > number of non-NA values in column(s) ", paste(which(nNonNA), collapse=", ")) # If ratio is specified, and n is not, set n to approx 'correct' # value backed out from ratio if(missing(n) && !missing(ratio)) n <- NULL # Call C routine ma <- .Call("ema", x, n, ratio, isTRUE(wilder), PACKAGE = "TTR") ma <- reclass(ma,x) if(!is.null(dim(ma))) { colnames(ma) <- "EMA" } return(ma) } #-------------------------------------------------------------------------# #'@rdname MovingAverages "DEMA" <- function(x, n=10, v=1, wilder=FALSE, ratio=NULL) { # Double Exponential Moving Average # Thanks to John Gavin for the v-factor generalization x <- try.xts(x, error=as.matrix) if( n < 1 || n > NROW(x) ) stop(sprintf("n = %d is outside valid range: [1, %d]", n, NROW(x))) if(NCOL(x) > 1) { stop("ncol(x) > 1. DEMA only supports univariate 'x'") } if(v < 0 || v > 1) { stop("Please ensure 0 <= v <= 1") } if(missing(n) && !missing(ratio)) n <- NULL # Call C routine ma1 <- .Call("ema", x, n, ratio, isTRUE(wilder), PACKAGE = "TTR") d <- .Call("ema", ma1, n, ratio, isTRUE(wilder), PACKAGE = "TTR") dema <- (1 + v) * ma1 - d * v dema <- reclass(dema, x) if(!is.null(dim(dema))) { colnames(dema) <- "DEMA" } return(dema) } #-------------------------------------------------------------------------# #'@rdname MovingAverages "WMA" <- function(x, n=10, wts=1:n, ...) { # Weighted Moving Average x <- try.xts(x, error=as.matrix) wts <- try.xts(wts, error=as.matrix) if( !any( NROW(wts) == c( NROW(x), n ) ) ) stop("Length of 'wts' must equal the length of 'x' or 'n'") if( n < 1 || n > NROW(x) ) stop(sprintf("n = %d is outside valid range: [1, %d]", n, NROW(x))) if(NCOL(x) > 1 || NCOL(wts) > 1) { stop("ncol(x) > 1 or ncol(wts) > 1. WMA only supports univariate 'x' and 'w'") } # Count NAs, ensure they're only at beginning of data, then remove. NAx <- sum( is.na(x) ) NAw <- sum( is.na(wts) ) NAs <- max( NAx, NAw ) if( NAs > 0 ) { if( any( is.na( x[-(1:NAx)]) ) ) stop("'x' contains non-leading NAs") if( any( is.na(wts[-(1:NAw)]) ) ) stop("'wts' contains non-leading NAs") } if( NROW(wts) == n ) { x <- na.omit(x) NAs <- NAx if( any(is.na(wts)) ) stop("'wts' vector of length 'n' cannot have NA values") # Call C routine ma <- .Call("wma", x, wts, n, PACKAGE = "TTR") } else { xw <- na.omit( cbind(x, wts) ) ma <- runSum( xw[,1]*xw[,2], n) / runSum(xw[,2], n) } # replace 1:(n-1) with NAs and prepend NAs from original data ma[1:(n-1)] <- NA ma <- c( rep( NA, NAs ), ma ) if(!is.null(dim(ma))) { colnames(ma) <- "WMA" } reclass(ma,x) } #-------------------------------------------------------------------------# #'@rdname MovingAverages "EVWMA" <- function(price, volume, n=10, ...) { # Elastic, Volume-Weighted Moving Average price <- try.xts(price, error=as.matrix) volume <- try.xts(volume, error=as.matrix) if( !any( NROW(volume) == c( NROW(price), 1 ) ) ) stop("Length of 'volume' must equal 1 or the length of 'price'") if( n < 1 || n > NROW(price) ) stop(sprintf("n = %d is outside valid range: [1, %d]", n, NROW(price))) if(NCOL(price) > 1 || NCOL(volume) > 1) { stop("ncol(price) > 1 or ncol(volume) > 1.", " EVWMA only supports univariate 'price' and 'volume'") } pv <- cbind(price, volume) if( any(nNonNA <- n > colSums(!is.na(pv))) ) stop("n > number of non-NA values in ", paste(c("price","volume")[which(nNonNA)], collapse=", ")) # Check for non-leading NAs # Leading NAs are handled in the C code pv.na <- naCheck(pv, n) # Call C routine ma <- .Call("evwma", pv[,1], pv[,2], n, PACKAGE = "TTR") if(!is.null(dim(ma))) { colnames(ma) <- "EVWMA" } # Convert back to original class reclass(ma, price) } #-------------------------------------------------------------------------# #'@rdname MovingAverages "ZLEMA" <- function (x, n=10, ratio=NULL, ...) { # Zero-Lag Exponential Moving Average x <- try.xts(x, error=as.matrix) if(NCOL(x) > 1) { stop("ncol(x) > 1. ZLEMA only supports univariate 'x'") } # If ratio is specified, and n is not, set n to approx 'correct' # value backed out from ratio if(missing(n) && !missing(ratio)) n <- NULL # Call C routine ma <- .Call("zlema", x, n, ratio, PACKAGE = "TTR") if(!is.null(dim(ma))) { colnames(ma) <- "ZLEMA" } reclass(ma,x) } #-------------------------------------------------------------------------# #'@rdname MovingAverages "VWAP" <- "VWMA" <- function(price, volume, n=10, ...) { # Volume-weighted average price # Volume-weighted moving average res <- WMA(price, n=n, volume) if(!is.null(dim(res))) { colnames(res) <- "VWAP" } return(res) } #-------------------------------------------------------------------------# #'@rdname MovingAverages "VMA" <- function (x, w, ratio=1, ...) { # Variable Moving Average x <- try.xts(x, error=as.matrix) w <- try.xts(w, error=as.matrix) if( NROW(w) != NROW(x) ) stop("Length of 'w' must equal the length of 'x'") if(NCOL(x) > 1 || NCOL(w) > 1) { stop("ncol(x) > 1 or ncol(w) > 1. VMA only supports univariate 'x' and 'w'") } # Check for non-leading NAs # Leading NAs are handled in the C code x.na <- naCheck(x, 1) w.na <- naCheck(w, 1) # Call C routine ma <- .Call("vma", x, abs(w), ratio, PACKAGE = "TTR") if(!is.null(dim(ma))) { colnames(ma) <- "VMA" } reclass(ma,x) } #-------------------------------------------------------------------------# #'@rdname MovingAverages "HMA" <- function(x, n=20, ...) { # Hull Moving Average reclass(WMA(2*WMA(x, n=n/2, ...) - WMA(x, n=n, ...), n=trunc(sqrt(n)), ...), x) } #-------------------------------------------------------------------------# #'@rdname MovingAverages "ALMA" <- function(x, n=9, offset=0.85, sigma=6, ...) { # ALMA (Arnaud Legoux Moving Average) if(offset < 0 || offset > 1) { stop("Please ensure 0 <= offset <= 1") } if(sigma <= 0) stop("sigma must be > 0") m <- floor(offset*(n-1)) s <- n/sigma wts <- exp(-((seq(0,n-1)-m)^2)/(2*s*s)) sumWeights <- sum(wts) if(sumWeights != 0) wts <- wts/sumWeights alma <- rollapply(x, width=n, FUN=function(xx) sum(xx*wts), align="right") reclass(alma, x) } TTR/R/aroon.R0000644000176200001440000000701313552670134012374 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Aroon #' #'The Aroon indicator attempts to identify starting trends. The indicator #'consists of up and down lines, which measure how long it has been since the #'highest high/lowest low has occurred in the last \code{n} periods. Developed #'by Tushar Chande in 1995. #' #'Aroon up (down) is the elapsed time, expressed as a percentage, between today #'and the highest (lowest) price in the last \code{n} periods. If today's #'price is a new high (low) Aroon up (down) will be 100. Each subsequent period #'without another new high (low) causes Aroon up (down) to decrease by (1 / #'\code{n}) x 100. #' #'@param HL Object that is coercible to xts or matrix and contains either a #'High-Low price series, or a Close price series. #'@param n Number of periods to use in the calculation. #'@return A object of the same class as \code{HL} or a matrix (if #'\code{try.xts} fails) containing the columns: #' \describe{ #' \item{ aroonUp }{ The Aroon up indicator. } #' \item{ aroonDn }{ The Aroon down indicator. } #' \item{ oscillator }{ The Aroon oscillator (\code{aroonUp - aroonDn}). } #' } #'@note If High-Low prices are given, the function calculates the max/min using #'the high/low prices. Otherwise the function calculates the max/min of the #'single series. #' #'Up (down) trends are indicated when the aroonUp(Dn) is between 70 and 100. #'Strong trends are indicated when when the aroonUp(Dn) is above 70 while the #'aroonDn(Up) is below 30. Also, crossovers may be useful. #'@author Joshua Ulrich #'@seealso See \code{\link{CCI}}, \code{\link{ADX}}, \code{\link{TDI}}, #'\code{\link{VHF}}, \code{\link{GMMA}} for other indicators that measure trend #'direction/strength. #'@references The following site(s) were used to code/document this #'indicator:\cr \url{http://www.fmlabs.com/reference/Aroon.htm}\cr #'\url{http://www.fmlabs.com/reference/AroonOscillator.htm}\cr #'\url{https://www.linnsoft.com/techind/aroon-arn}\cr #'\url{http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:aroon}\cr #'@keywords ts #'@examples #' #' ## Get Data and Indicator ## #' data(ttrc) #' trend <- aroon( ttrc[,c("High", "Low")], n=20 ) #' "aroon" <- function(HL, n=20) { # Aroon up, down, and oscillator. HL <- try.xts(HL, error=as.matrix) # Calculation if price vector is given if(NCOL(HL)==1) { high <- HL low <- HL } else # Calculation if HL series is given if(NCOL(HL)==2) { high <- HL[,1] low <- HL[,2] } else stop("Price series must be either High-Low, or Close") # Calculate Aroon UP and DOWN aroonUp <- .Call("aroon_max", high, n, PACKAGE="TTR") aroonDn <- .Call("aroon_max", -low, n, PACKAGE="TTR") oscillator <- aroonUp - aroonDn result <- cbind( aroonUp, aroonDn, oscillator ) colnames(result) <- c( "aroonUp", "aroonDn", "oscillator" ) reclass( result, HL ) } TTR/R/SNR.R0000644000176200001440000000400513552670134011716 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2016 Peter Carl, Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Signal to Noise Ratio #' #'The n-day SNR for a given market is calculated by taking the absolute #'price change over an n-day period and dividing it by the average #'n-day volatility. #' #'\deqn{SNR_n = \frac{|C_t - C_{t-n}|}{ATR_n} #'}{SNR = abs(Cl - lag(Cl,n)) / ATR(HLC, n)$atr} #' #'Using average true range as the volatility measure captures more of the #'intraday and overnight volatility in a way that a measurement of #'Close-to-Close price change does not. #' #'The interpretation is then relatively intuitive: an SNR value of five #'indicates that the market has moved five times the volatility (average true #'range) over the given look-back period. #' #'@param HLC Object that is coercible to xts or matrix and contains #'High-Low-Close prices. #'@param n Number of periods for moving average. #'@param ... Other arguments to be passed to \code{\link{ATR}}. #'@return A object of the same class as HLC or a matrix (if try.xts fails) #'containing the signal to noise ratio. #'@author Peter Carl #'@references Skeggs, James and Hill, Alex (2015). Back in Black Part 2: The #'Opportunity Set for Trend Following. #' SNR <- function(HLC, n, ...) { HLC <- try.xts(HLC, error=as.matrix) snr <- abs(HLC[,3] - lag.xts(HLC[,3], n)) / ATR(HLC, n, ...)[,"atr"] return(reclass(snr, HLC)) } TTR/R/percentRank.R0000644000176200001440000000560413552670134013536 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Percent Rank over a Moving Window #' #'This function computes a running/rolling percentage rank. #' #'The computation for a percentage rank can vary depending on the weight given #'to values in the window identical to the value being ranked. This weight can #'be set using the \code{exact.multiplier} argument which defaults to 0.5. #' #'@aliases runPercentRank percentRank PercentRank #'@param x Object coercible to xts or matrix. #'@param n Number of periods to use in the window or, if #'\code{cumulative=TRUE}, the number of observations to use before the first #'result is returned. Must be between 1 and \code{nrow(x)}, inclusive. #'@param cumulative Logical, use from-inception calculation? #'@param exact.multiplier The weight applied to identical values in the window. #'Must be between 0 and 1, inclusive. See details. #'@return A object of percent ranks over a n-period moving window of the same #'class as \code{x} and \code{y} or a vector (if \code{try.xts} fails). #'@note It may be important to note that this computation is different from the #'one used in Microsoft Excel's PERCENTRANK formula. Excel's computation is #'rather strange and gives inconsistent results as it uses interpolation to #'rank values that are not found within the lookback window. #'@author Charlie Friedemann #'@references The following site(s) were used to code/document this #'indicator:\cr \url{http://en.wikipedia.org/wiki/Percentile_rank}\cr #'@keywords ts runPercentRank <- function(x, n=260, cumulative = FALSE, exact.multiplier = 0.5) { x <- try.xts(x, error = as.matrix) if (n < 1 || n > NROW(x)) stop(sprintf("n = %d is outside valid range: [1, %d]", n, NROW(x))) if (exact.multiplier < 0 || exact.multiplier > 1) stop(sprintf("exact.multiplier = %d is outside valid range: [0, 1]", exact.multiplier)) NAs <- sum(is.na(x)) if (NAs > 0) { if (any(is.na(x[-(1:NAs)]))) stop("Series contains non-leading NAs") } if (identical(as.integer(n), 1L)) { result <- double(NROW(x)) result[] <- exact.multiplier } else { result <- .Call("ttr_rollPercentRank", x, n, isTRUE(cumulative), exact.multiplier, PACKAGE = "TTR") } reclass(result, x) } TTR/R/DVI.R0000644000176200001440000000630613552670134011704 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'DV Intermediate Oscillator #' #'The DV Intermediate oscillator (DVI) is a very smooth momentum oscillator #'that can also be used as a trend indicator. Created by David Varadi. #' #'The DVI combines smoothed returns over different time windows and the #'relative number of up versus down days (stretch) over different time windows. #' #'@param price Price series that is coercible to xts or matrix. #'@param n Number of periods for the percent rank. #'@param wts The weight given to the smoothed returns (magnitude) component and #'the up/down days (stretch) component, respectively. #'@param smooth The number of periods to smooth price. #'@param magnitude A set of 3 periods used to smooth magnitude. #'@param stretch A set of 3 periods used to smooth stretch. #'@param exact.multiplier The weight applied to identical values in the window. #'See \code{runPercentRank}. #'@return A object of the same class as \code{price} or a vector (if #'\code{try.xts} fails) containing the DVI values. #'@author Joshua Ulrich #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{http://cssanalytics.wordpress.com/2009/12/13/what-is-the-dvi/}\cr #'\url{http://marketsci.wordpress.com/2010/07/27/css-analytics\%E2\%80\%99-dvi-indicator-revealed/}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' dvi <- DVI(ttrc[,"Close"]) #' DVI <- function(price, n=252, wts=c(0.8,0.2), smooth=3, magnitude=c(5,100,5), stretch=c(10,100,2), exact.multiplier=1) { # David Varadi's DVI indicator # try to convert 'price' to xts price <- try.xts(price, error=as.matrix) # ensure magnitude + stretch = 1 wts.sum <- sum(wts) wts[1] <- wts[1] / wts.sum wts[2] <- wts[2] / wts.sum # calculate magnitude, based on average price return r <- price/SMA(price,smooth)-1 mag <- SMA( ( SMA(r,magnitude[1]) + SMA(r,magnitude[2])/10 )/2, magnitude[3] ) # calculate stretch, based on whether return is +/- b <- ifelse( price > lag.xts(price), 1, -1 ) str <- SMA( ( runSum(b,stretch[1]) + runSum(b,stretch[2])/10 )/2, stretch[3] ) # calculate the DVI magnitude and stretch for each period dvi.mag <- runPercentRank(mag, n, FALSE, exact.multiplier) dvi.str <- runPercentRank(str, n, FALSE, exact.multiplier) # calculate final DVI value dvi <- wts[1] * dvi.mag + wts[2] * dvi.str result <- cbind(dvi.mag, dvi.str, dvi) colnames(result) <- c("dvi.mag", "dvi.str", "dvi") # convert final DVI, magnitude, and stretch back to # original class of 'price' reclass(result, price) } TTR/R/priceBands.R0000644000176200001440000000762713552670134013343 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Construct (optionally further smoothed and centered ) volatility bands around #'prices #' #'John Bollinger's famous adaptive volatility bands most often use the typical #'price of an HLC series, or may be calculated on a univariate price series #'(see \code{\link{BBands}}). #' #'This function applies a second moving average denoted by \code{fastn} to #'filter out higher-frequency noise, making the bands somewhat more stable to #'temporary fluctuations and spikes. #' #'If \code{centered} is \code{TRUE}, the function also further smoothes and #'centers the bands around a centerline adjusted to remove this higher #'frequency noise. If \code{lavg} is also \code{TRUE}, the smoothing applied #'for the middle band (but not the volatility bands) is doubled to further #'smooth the price-response function. #' #'If you have multiple different price series in \code{prices}, and want to use #'this function, call this functions using \code{lapply(prices,PBands,...)}. #' #'@aliases PBands priceBands #'@param prices A univariate series of prices. #'@param n Number of periods to average over. #'@param maType A function or a string naming the function to be called. #'@param sd The number of standard deviations to use. #'@param \dots any other pass-thru parameters, usually for function named by #' \code{maType}. #'@param fastn Number of periods to use for smoothing higher-frequency 'noise'. #'@param centered Whether to center the bands around a series adjusted for high #' frequency noise, default \code{FALSE}. #'@param lavg Whether to use a longer \code{(n*2)} smoothing period for #' centering, default \code{FALSE}. #'@return A object of the same class as \code{prices} or a matrix (if #'\code{try.xts} fails) containing the columns: #' \describe{ #' \item{ dn }{ The lower price volatility Band. } #' \item{ center }{ The smoothed centerline (see details). } #' \item{ up }{ The upper price volatility Band. } #' } #'@author Brian G. Peterson #'@seealso \code{\link{BBands}} #'@keywords ts #'@examples #' #' data(ttrc) #' pbands.close <- PBands( ttrc[,"Close"] ) #' #'@rdname priceBands PBands <- function(prices, n=20, maType="SMA", sd=2, ..., fastn=2, centered=FALSE, lavg=FALSE ) { # Price Bands, implemented by Brian G. Peterson # inspired by the univariate Bollinger Bands, and Ram Ben-David if(!is.vector(prices) && ncol(prices)>1) stop('prices should be a univariate series, maybe use', 'lapply(prices,PBands) instead?') prices <- try.xts(prices, error=as.matrix) # Default MA if(missing(maType)) { maType <- 'SMA' } maArgs <- list(n=n, ...) mavg <- do.call( maType, c( list(prices), maArgs ) ) maFastArgs <-list(n=fastn,...) fastmavg <- do.call( maType, c( list(prices), maFastArgs ) ) sdev <- runSD((mavg-fastmavg),n=n,sample=FALSE) if(!isTRUE(centered)){ center <- mavg } else { centerrun <- (mavg-fastmavg)/sdev if(isTRUE(lavg)){ maArgs <- list(n=(n*2), ...) } center <- mavg + ( do.call(maType, c( list(centerrun), maArgs ) ) ) } up <- center + sd * sdev dn <- center - sd * sdev res <- cbind(dn, center, up) colnames(res) <- c("dn", "center", "up") reclass(res, prices) } TTR/R/adjRatios.R0000644000176200001440000000555013552670134013202 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Split and dividend adjustment ratios #' #'Create split and dividend adjustment ratio vectors. #' #'@aliases adjRatios adjust #'@param splits Split series that is coercible to xts. #'@param dividends Dividend series that is coercible to xts. #'@param close Close price series that is coercible to xts. #'@return A xts object containing the columns: #' \describe{ #' \item{ Split }{ The split adjustment ratio. } #' \item{ Div }{ The dividend adjustment ratio. } #' } #'@details #' \itemize{ #' \item If only \code{splits} is provided, the resulting object will #' only have as many observations as \code{splits}. #' \item If \code{splits} and \code{close} are provided, the resulting #' object will have as many observations as \code{max(NROW(splits), #' NROW(close))}. #' \item \code{close} is required if \code{dividends} is provided. #' } #' #'@author Joshua Ulrich #'@keywords ts 'adjRatios' <- function(splits, dividends, close) { if( !missing(dividends) && missing(close) ) stop('"close" must be specified to adjust dividends') # Really need a better error message if as.xts fails... seriously if(missing(close) || all(is.na(close)) || NROW(close)==0) { close <- NA } else { if(NCOL(close)!=1) stop('"close" must be univariate') close <- try.xts(close, error=stop('"as.xts(close)" failed')) } if(missing(splits) || all(is.na(splits)) || NROW(splits)==0) { splits <- NA } else { if(NCOL(splits)!=1) stop('"splits" must be univariate') splits <- try.xts(splits, error=stop('"as.xts(splits)" failed')) } if(missing(dividends) || all(is.na(dividends)) || NROW(dividends)==0) { dividends <- NA } else { if(NCOL(dividends)!=1) stop('"dividends" must be univariate') dividends <- try.xts(dividends, error=stop('"as.xts(dividends)" failed')) } obj <- merge.xts(close,splits,dividends) if(!isTRUE(is.na(close))) { obj <- obj[!is.na(obj[,1]),] # drop rows missing close prices } adj <- .Call('adjRatios',obj[,2],obj[,3],obj[,1],PACKAGE="TTR") adj <- xts(cbind(adj[[1]],adj[[2]]),index(obj)) colnames(adj) <- c('Split','Div') return(adj) } TTR/R/ZigZag.R0000644000176200001440000000710713552670134012455 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Zig Zag #' #'Zig Zag higlights trends by removing price changes smaller than \code{change} #'and interpolating lines between the extreme points. #' #'The Zig Zag is non-predictive. The purpose of the Zig Zag is filter noise #'and make chart patterns clearer. It's more a visual tool than an indicator. #' #'@aliases ZigZag zigzag #'@param HL Object that is coercible to xts or matrix and contains either a #'High-Low price series, or a Close price series. #'@param change Minimum price movement, either in dollars or percent (see #'\code{percent}). #'@param percent Use percentage or dollar change? #'@param retrace Is \code{change} a retracement of the previous move, or an #'absolute change from peak to trough? #'@param lastExtreme If the extreme price is the same over multiple periods, #'should the extreme price be the first or last observation? #'@return A object of the same class as \code{HL} or a vector (if #'\code{try.xts} fails) containing the Zig Zag indicator. #'@note If High-Low prices are given, the function calculates the max/min using #'the high/low prices. Otherwise the function calculates the max/min of the #'single series. #'@section Warning: The last value of the ZigZag indicator is unstable (i.e. #'unknown) until the turning point actually occurs. Therefore this indicator #'isn't well-suited for use for systematic trading strategies. #'@author Joshua Ulrich #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{http://www.fmlabs.com/reference/default.htm?url=ZigZag.htm}\cr #'\url{https://www.linnsoft.com/techind/zig-zag-indicator-zig-zzo}\cr #'\url{https://www.linnsoft.com/techind/zig-zag-oscillator-indicator-zzo}\cr #'\url{http://www.metastock.com/Customer/Resources/TAAZ/#127}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:zigzag}\cr #'@keywords ts #'@examples #' #' ## Get Data and Indicator ## #' data(ttrc) #' zz <- ZigZag( ttrc[,c("High", "Low")], change=20 ) #' "ZigZag" <- function( HL, change=10, percent=TRUE, retrace=FALSE, lastExtreme=TRUE ) { # Zig Zag Indicator # Adapted from Alberto Santini's code HL <- try.xts(HL, error=as.matrix) HL.na <- naCheck(HL,0) # Calculation if HL series is given if(NCOL(HL)==2) { high <- HL[HL.na$nonNA,1] low <- HL[HL.na$nonNA,2] } else # Calculation if price vector is given if(NCOL(HL.na)==1) { high <- HL[HL.na$nonNA] low <- HL[HL.na$nonNA] } else stop("Price series must be either High-Low, or Univariate") # Call C routine zz <- .Call("ttr_zigzag", as.numeric(high), as.numeric(low), as.numeric(change), as.logical(percent), as.logical(retrace), as.logical(lastExtreme), PACKAGE = "TTR") # Interpolate results zz <- na.approx(zz, na.rm = FALSE) # Prepend NAs from original data zz <- c( rep( NA, HL.na$NAs ), zz ) reclass( zz, HL ) } TTR/R/williamsAD.R0000644000176200001440000000430213552670134013302 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Williams Accumulation / Distribution #' #'The Williams Accumulation / Distribution (AD) line is a measure of market #'momentum. Developed by Larry Williams. #' #'The Williams AD line differs from OBV and chaikinAD in that it doesn't take #'volume into account. #' #'@param HLC Object that is coercible to xts or matrix and contains #'High-Low-Close prices. #'@return A object of the same class as \code{HLC} or a vector (if #'\code{try.xts} fails) containing the accumulation / distribution values. #'@note The Accumulation/Distribution Line is interpreted by looking for a #'divergence in the direction of the indicator relative to price. #'@author Joshua Ulrich #'@seealso See \code{\link{OBV}}, \code{\link{chaikinAD}}, and #'\code{\link{ATR}}. #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{http://www.fmlabs.com/reference/WilliamsAD.htm}\cr #'\url{http://www.metastock.com/Customer/Resources/TAAZ/#125}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' ad <- williamsAD(ttrc[,c("High","Low","Close")]) #' "williamsAD" <- function(HLC) { # Williams Accumulation/Distribution HLC <- try.xts(HLC, error=as.matrix) # Calculate change in close, and true high/low dCl <- momentum(HLC[,3], 1) atr <- ATR(HLC) # Calculate AD ad <- HLC[,3] - ifelse( dCl > 0, atr[,"trueLow"], atr[,"trueHigh"] ) ad[ dCl == 0 ] <- 0 ad.na <- naCheck(ad) ad <- cumsum( ad[ad.na$nonNA] ) ad <- c( rep( NA, ad.na$NAs ), ad ) reclass(ad, HLC) } TTR/R/CMO.R0000644000176200001440000000427213552670134011700 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Chande Momentum Oscillator #' #'The Chande Momentum Oscillator (CMO) is a modified RSI. Developed by Tushar #'S. Chande. #' #'The CMO divides the total movement by the net movement ([up - down] / [up + #'down]), where RSI divides the upward movement by the net movement (up / [up + #'down]). #' #'@param x Price, volume, etc. series that is coercible to xts or matrix. #'@param n Number of periods to use. #'@return A object of the same class as \code{x} or a vector (if \code{try.xts} #'fails) containing Chande Momentum Oscillator values. #'@note There are several ways to interpret the CMO: #' \enumerate{ #' \item Values over/under +/- 50 indicate overbought/oversold conditions. #' \item High CMO values indicate strong trends. #' \item When the CMO crosses above/below a moving average of the CMO, #' it is a buy/sell signal. #' } #'@author Joshua Ulrich #'@seealso See \code{\link{RSI}}. #'@references The following site(s) were used to code/document this #'indicator:\cr \url{http://www.fmlabs.com/reference/CMO.htm}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' cmo <- CMO(ttrc[,"Close"]) #' "CMO" <- function(x, n=14) { # Chande Momentum Oscillator x <- try.xts(x, error=as.matrix) up <- momentum(x, n=1) dn <- ifelse(up<0, abs(up), 0) up <- ifelse(up>0, up , 0) up <- runSum(up, n) dn <- runSum(dn, n) cmo <- 100 * (up-dn)/(up+dn) if (!is.null(dim(cmo)) && ncol(cmo) == 1L) { colnames(cmo) <- "cmo" } reclass( cmo, x ) } TTR/R/rollFun.R0000644000176200001440000000411113552670134012673 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Analysis of Running/Rolling/Moving Windows #' #'Various functions to analyze data over a moving window of periods. #' #' #'@aliases rollFun rollSFM #'@param Ra Object coercible to xts or matrix, containing the excess #'return for an individual security #'@param Rb Object coercible to xts or matrix, containing the market #'/ benchmark return #'@param n Number of periods to use in the window #' #'@return A object of the same class as \code{Ra} (and \code{Rb}?) or a vector #'(if \code{try.xts} fails). #' \describe{ #' \item{rollSFM}{returns single-factor model parameters and R-squared #' over a n-period moving window.} #' } #' #'@author Joshua Ulrich #'@references The following site(s) were used to code/document this #'indicator: #'\url{http://en.wikipedia.org/wiki/Simple_linear_regression}\cr #'@keywords ts #'@rdname rollFun rollSFM <- function(Ra, Rb, n = 60) { # Calculate a rolling single-factor model # stopifnot(is.xts(Ra) && is.xts(Rb)) # calculate beta beta <- runCov(Ra, Rb, n) / runVar(Rb, n=n) # calculate alpha alpha <- runMean(Ra, n) - beta * runMean(Rb, n) # calculate R-squared se.resid <- 1/(n*(n-2)) * (n*runSum(Ra^2,n)-runSum(Ra,n)^2 - beta^2 * (n*runSum(Rb^2,n)-runSum(Rb,n)^2)) se.Ra <- runVar(Ra, n=n) * (n-1)/(n-2) r.squared <- 1 - se.resid / se.Ra result <- merge(alpha, beta, r.squared) return(result) } TTR/R/VHF.R0000644000176200001440000000532113552670134011701 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Vertical Horizontal Filter #' #'The Vertical Horizontal Filter (VHF) attempts to identify starting and ending #'trends. Developed by Adam White. #' #'The VHF is calculated by subtracting the \code{n}-period lowest low from the #'\code{n}-period highest high and dividing that result by the \code{n}-period #'rolling sum of the close price changes. #' #'@param price Object that is coercible to xts or matrix and contains a Close #'price series, or a High-Low-Close price series. #'@param n Number of periods to use. #'@return A object of the same class as \code{price} or a vector (if #'\code{try.xts} fails) containing the VHF values. #'@note If Close prices are given, the function calculates the max/min using #'only those prices (the default). If HLC prices are given, the function #'calculates the max/min using the high/low prices (added for flexibility). #'@author Joshua Ulrich #'@seealso See \code{\link{aroon}}, \code{\link{CCI}}, \code{\link{ADX}}, #'\code{\link{TDI}}, \code{\link{GMMA}} for other indicators that measure trend #'direction/strength. #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{http://www.metastock.com/Customer/Resources/TAAZ/#119}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' vhf.close <- VHF(ttrc[,"Close"]) #' vhf.hilow <- VHF(ttrc[,c("High","Low","Close")]) #' "VHF" <- function(price, n=28) { # Vertical Horizontal Filter price <- try.xts(price, error=as.matrix) # Calculation if price series is given if(NCOL(price)==1) { high <- price low <- price close <- price } else # Calculation if HLC series is given if(NCOL(price)==3) { high <- price[,1] low <- price[,2] close <- price[,3] } else stop("Price series must be either Close, or High-Low-Close") # Find highest max, and lowest min of price series hmax <- runMax( high, n) lmin <- runMin( low, n) denom <- abs( momentum(close, n=1, na.pad=TRUE) ) VHF <- ( hmax - lmin ) / runSum(denom, n) reclass(VHF, price) } TTR/R/chaikinAD.R0000644000176200001440000000521413552670134013072 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Chaikin Accumulation / Distribution #' #'The Chaikin Accumulation / Distribution (AD) line is a measure of the money #'flowing into or out of a security. It is similar to On Balance Volume (OBV). #'Developed by Marc Chaikin. #' #'The AD line is similar to OBV; the difference is that OBV sums volume #'multiplied by +/- 1 if the close is higher/lower than the previous close, #'while the AD line multiplies volume by the close location value (CLV). #' #'@param HLC Object that is coercible to xts or matrix and contains #'High-Low-Close prices. #'@param volume Vector or matrix of volume observations corresponding to the #'\code{HLC} object. #'@return A object of the same class as \code{HLC} and \code{volume} or a #'vector (if \code{try.xts} fails) containing the accumulation / distribution #'values. #'@note The Accumulation/Distribution Line is interpreted by looking for a #'divergence in the direction of the indicator relative to price. #'@author Joshua Ulrich #'@seealso See \code{\link{OBV}}, and \code{\link{CLV}}. #'@references The following site(s) were used to code/document this #'indicator:\cr \url{http://www.fmlabs.com/reference/AccumDist.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=27}\cr #'\url{https://www.linnsoft.com/techind/accumulation-distribution}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:accumulation_distribution_line}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' ad <- chaikinAD(ttrc[,c("High","Low","Close")], ttrc[,"Volume"]) #' "chaikinAD" <- function(HLC, volume) { # Chaikin Accumulation / Distribution HLC <- try.xts(HLC, error=as.matrix) volume <- try.xts(volume, error=as.matrix) if(!(is.xts(HLC) && is.xts(volume))) { HLC <- as.matrix(HLC) volume <- as.matrix(volume) } ad <- CLV(HLC) * volume ad.na <- naCheck(ad) ad <- cumsum( ad[ad.na$nonNA] ) ad <- c( rep( NA, ad.na$NAs ), ad ) reclass(ad, HLC) } TTR/R/WebData.R0000644000176200001440000003671013552670134012573 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Fetch Internet Data #' #'Get investment data from the internet. #' #'\code{getYahooData} fetches individual stock data from the Yahoo! Finance #'website. It also adjusts price for splits and dividends, and volume for #'splits. See the Warning section, and note that it is deprecated in favor #'of getSymbols in the quantmod package. #' #'\code{stockSymbols} fetches instrument symbols from the nasdaq.com website, #'and adjusts the symbols to be compatible with the Yahoo! Finance website. #' #'@aliases WebData getYahooData stockSymbols #'@param symbol Yahoo! Finance instrument symbol. #'@param start Numeric; first date of desired data, in YYYYMMDD format. #'Default is first date of series. #'@param end Numeric; last date of desired data, in YYYYMMDD format. Default #'is last date of series. #'@param freq Desired data frequency. One of \code{"daily"}, \code{"weekly"}, #'\code{"monthly"}. #'@param type Type of data to return. One of \code{"price"}, or #'\code{"split"}. \code{type="split"} will return both split and dividend #'data. #'@param adjust Logical; if \code{TRUE}, the Open, High, Low, and Close prices #'will be adjusted for dividends and splits, and Volume will be adjusted for #'dividends. #'@param quiet Logical; if \code{TRUE}, status messages will be printed to the #'console. #'@param exchange Character vector of exchange names on which desired #'instrument symbols are traded. #'@param sort.by Character vector of columns by which returned data will be #'sorted. Must be one or more of \code{"Name"}, \code{"Symbol"}, #'\code{"Market.Cap"}, or \code{"Exchange"}. #'@return \code{getYahooData} returns an xts object containing the columns: #' #'\code{stockSymbols} returns a character vector containing all the listed #'symbols for the given exchanges. #' \describe{ #' \item{ Date }{ Trade date, in CCYYMMDD format. } #' \item{ Open }{ Open price. } #' \item{ High }{ High price. } #' \item{ Low }{ Low price. } #' \item{ Close }{ Close price. } #' \item{ Volume }{ Volume. } #' } #'@note The symbols returned by \code{stockSymbols} may not be in the format #'necessary to retrieve data using \code{getYahooData}. #' #'\code{getYahooData} has only been tested on daily data. It isn't known if #'the function correctly adjusts data for any other frequency. #'@author Joshua Ulrich #'@keywords ts #'@examples #' #' ### Note: you must have a working internet #' ### connection for these examples to work! #' if (interactive()) { #' ge <- getYahooData("GE", 19990404, 20050607, adjust = FALSE) #' #' nyse.symbols <- stockSymbols("NYSE") #' } #' #'@section Warning: #'As of TTR 0.23-2, \code{getYahooData} has been patched to work with changes #'to Yahoo Finance, which also included the following changes to the raw data: #' \itemize{ #' \item The adjusted close column appears to no longer include dividend adjustments #' \item The open, high, and low columns are adjusted for splits, and #' \item The raw data may contain missing values. #' \item The raw data may contain errors. #' } #' #'@rdname WebData "stockSymbols" <- function(exchange=c("AMEX","NASDAQ","NYSE"), sort.by=c("Exchange","Symbol"), quiet=FALSE) { # Many thanks to Ion Georgiadis for helpful suggestions and testing. # See "NYSE "behind the dot" or Nasdaq 5th-letter codes and other special # codes" here: # http://en.wikipedia.org/wiki/Ticker_symbol # http://help.yahoo.com/l/us/yahoo/finance/quotes/quote-02.html # # AMEX / NYSE Mappings (NASDAQ doesn't need transformation?): # Exchanges -> Yahoo # /WS -> -WT # /U -> -U # .[A-Z] -> NA (special notes/bonds - IG) # :[AP] -> NA (after-hours / pre-market) # ^ -> -P # / -> - # $ -> NA (NYSE Only) # ~ -> NA (NYSE Only) symbols <- NULL symbols.colnames <- c("Symbol","Name","LastSale","MarketCap","IPOyear","Sector","Industry","Exchange") exchange <- match.arg(exchange, several.ok=TRUE) sort.by <- match.arg(sort.by, symbols.colnames, several.ok=TRUE) for(i in exchange) { if(!quiet) message("Fetching ",i," symbols...") flush.console() # Fetch Symbols url <- paste("https://old.nasdaq.com/screening/companies-by-name.aspx", "?letter=0&exchange=",i,"&render=download",sep="") exch <- read.csv(url, header=TRUE, as.is=TRUE, na="n/a") # Find and order by necessary columns col.loc <- sapply(symbols.colnames, grep, names(exch), ignore.case=TRUE) exch <- exch[,c(col.loc, recursive=TRUE)] # Create "Exchange" column exch <- data.frame(exch, Exchange=i, stringsAsFactors=FALSE) colnames(exch) <- symbols.colnames # Clean up any whitespace in Symbol exch$Symbol <- gsub("[[:space:]]","",exch$Symbol) # Exchange-specific scrubbing if(i=="AMEX") { # Transform Symbols to Yahoo format exch$Symbol <- gsub("/WS$", "-WT", exch$Symbol) # AMEX, NYSE exch$Symbol <- gsub("/WS/", "-WT", exch$Symbol) # AMEX, NYSE exch$Symbol <- gsub("/U", "-U", exch$Symbol) # AMEX exch$Symbol <- gsub("\\^", "-P", exch$Symbol) # AMEX, NYSE exch$Symbol <- gsub("/", "-", exch$Symbol) # AMEX, NYSE # Drop symbols Yahoo doesn't provide drop <- c( grep("\\.", exch$Symbol), # AMEX grep("\\$", exch$Symbol), # AMEX, NYSE grep(":", exch$Symbol) ) # AMEX, NYSE if(NROW(drop)!=0) { exch <- exch[-drop,] } } else # More exchange-specific scrubbing if(i=="NYSE") { # Transform Symbols to Yahoo format exch$Symbol <- gsub("/WS$", "-WT", exch$Symbol) # AMEX, NYSE exch$Symbol <- gsub("/WS/", "-WT", exch$Symbol) # AMEX, NYSE exch$Symbol <- gsub("\\^", "-P", exch$Symbol) # AMEX, NYSE exch$Symbol <- gsub("/", "-", exch$Symbol) # AMEX, NYSE # Drop symbols Yahoo doesn't provide drop <- c( grep("\\$", exch$Symbol), # AMEX grep(":", exch$Symbol), # AMEX, NYSE grep("~", exch$Symbol) ) # AMEX, NYSE if(NROW(drop)!=0) { exch <- exch[-drop,] } } # Append data from all exchanges symbols <- rbind( symbols, exch ) } # Sort symbols <- symbols[do.call("order", symbols[,sort.by]),] # Pretty rownames rownames(symbols) <- 1:NROW(symbols) return(symbols) } #-------------------------------------------------------------------------# #'@rdname WebData "getYahooData" <- function(symbol, start, end, freq="daily", type="price", adjust=TRUE, quiet=FALSE) { warn.Deprecated <- function() { .Deprecated("quantmod::getSymbols", package = "TTR", paste("TTR::getYahooData is deprecated and will be removed in a", "future release.\nPlease use quantmod::getSymbols instead."), old = "getYahooData") } callingFun <- sys.call(-1L)[[1]] if(is.null(callingFun)) { # Called from top level warn.Deprecated() } else { if(is.call(callingFun) && any(deparse(callingFun[[1]]) == c("::", ":::"))) { if("getYahooData" != as.character(callingFun[[3]])) warn.Deprecated() } else { if("getYahooData" != deparse(callingFun)) warn.Deprecated() } } # Thank you to Giorgio Beltrame for the URL to download dividends _and_ # splits, and for his correct adjustment procedure. # Many thanks to Ion Georgiadis for helpful suggestions and testing. # symbol: Character, instrument symbol # start: Numeric, starting date, in ISO-8601 format as ccyymmdd (default # is series' first date) # end: Numeric, ending date, in ISO-8601 format as ccyymmdd (default is today) # freq: Character, frequency of data # either 'daily', 'weekly', 'monthly' # type: Character, either 'price' or 'split' # adjust: Logical, adjusts the Open, High, Low, and Close prices for # dividends and splits, and adjusts Volume for dividends. # # http://help.yahoo.com/l/us/yahoo/finance/quotes/quote-12.html # http://ichart.finance.yahoo.com/x?s=MSFT&g=d&y=0&z=30000 # # Requires R-2.4.1 # Check dates if (missing(start)) { beg <- .dateToUNIX(as.Date("1900-01-01")) } else { beg <- .dateToUNIX(as.Date(as.character(start), "%Y%m%d")) } if (missing(end)) { end <- .dateToUNIX(Sys.Date()) } else { end <- .dateToUNIX(as.Date(as.character(end), "%Y%m%d")) } if( beg > end ) stop("Start date must be before end date.") if (beg > .dateToUNIX(Sys.Date())) stop("Start date is after today's date.") # Get frequency and type parameters intervals <- c(daily = "1d", weekly = "1wk", monthly = "1mo") freq <- match.arg( freq, names(intervals) ) interval <- intervals[freq] type <- match.arg( type, c("price","split") ) if(type!="price") { if(freq!="daily" & !quiet) message("Only freq=\"daily\" data available for type=\"split\".\n", "Setting freq=\"daily\"...") } tmp <- tempfile() on.exit(unlink(tmp), add = TRUE) flush.console() if(type=="price") { if(adjust) { if(freq=="daily") { # Get price, dividend, and split data from 'beg' to present ohlc <- getYahooData(symbol, start, freq="daily", type="price", adjust=FALSE, quiet=TRUE) divspl <- getYahooData(symbol, start, freq="daily", type="split", adjust=FALSE, quiet=TRUE) ohlc <- merge(ohlc, divspl, all=TRUE) # If there are no div/spl, then ohlc is a zero-width xts object if(NROW(divspl) != 0) { adj <- adjRatios(ohlc[,'Split'],ohlc[,'Div'],ohlc[,'Close']) s.ratio <- adj[,1] d.ratio <- adj[,2] # Adjust OHLC and volume cn <- colnames(ohlc) ohlc <- cbind(ohlc,ohlc[,'Close']) colnames(ohlc) <- c(cn,'Unadj.Close') #ohlc[,'Unadj.Close'] <- ohlc[,'Close'] ohlc[,'Open'] <- ohlc[,'Open'] * d.ratio * s.ratio ohlc[,'High'] <- ohlc[,'High'] * d.ratio * s.ratio ohlc[,'Low'] <- ohlc[,'Low'] * d.ratio * s.ratio ohlc[,'Close'] <- ohlc[,'Close'] * d.ratio * s.ratio ohlc[,'Volume'] <- ohlc[,'Volume'] * ( 1 / d.ratio ) # Order columns #ohlc <- ohlc[,c("Date","Open","High","Low","Close","Volume", ohlc <- ohlc[,c("Open","High","Low","Close","Volume", "Unadj.Close","Div","Split","Adj.Div")] } } else stop("Only freq=\"daily\" adjusted data is currently supported.") # For other frequencies, get daily data and use a routine to # aggregate to desired frequency. } else { handle <- .getHandle() # Construct URL for 'beg' to 'end' url <- .yahooURL(symbol, beg, end, interval, "history", handle) # Fetch data curl::curl_download(url, destfile=tmp, quiet=quiet, handle=handle$ch) # Read data ohlc <- read.csv(tmp, na.strings="null") # Re-order and set column names cnames <- c("Date", "Open", "High", "Low", "Close", "Volume", "Adjusted") corder <- pmatch(substr(cnames, 1, 3), colnames(ohlc)) ohlc <- ohlc[,corder] colnames(ohlc) <- cnames ohlc[,'Adjusted'] <- NULL ohlc <- ohlc[order(ohlc[,"Date"]),] ohlc <- xts(ohlc[,-1], as.Date(as.character(ohlc[,1]))) } } else { if(!quiet) message("Unadjusted and adjusted dividend data are always returned.") handle <- .getHandle() # Split data url <- .yahooURL(symbol, beg, end, "1d", "split", handle) curl::curl_download(url, destfile=tmp, quiet=quiet, handle=handle$ch) spl <- read.csv(tmp, as.is=TRUE) if(NROW(spl)==0) { spl <- NA } else { spl$V3 <- 1 / sapply(parse(text=spl[,2]), eval) spl <- xts(spl$V3, as.Date(spl[,1], "%Y-%m-%d")) colnames(spl) <- NULL } # Dividend data url <- .yahooURL(symbol, beg, end, "1d", "div", handle) curl::curl_download(url, destfile=tmp, quiet=quiet, handle=handle$ch) div <- read.csv(tmp, as.is=TRUE) div <- xts(div[,2],as.Date(div[,1])) colnames(div) <- NULL ohlc <- merge(Adj.Div = div, Split = spl) # Return (empty) data if(NROW(ohlc)==0) return(ohlc) if( all(is.na(ohlc[,'Split'])) ) { s.ratio <- rep(1,NROW(ohlc)) } else { s.ratio <- adjRatios(splits=ohlc[,'Split'])[,1] } # Un-adjust dividends for Splits ohlc <- cbind(ohlc,ohlc[,"Adj.Div"] * ( 1 / s.ratio )) colnames(ohlc)[3] <- "Div" ohlc[,'Split'] <- as.numeric(ohlc[,'Split']) # Order data columns ohlc <- ohlc[,c("Div","Split","Adj.Div")] } # Only return requested data dateRange <- paste(as.Date(.POSIXct(beg, tz = "UTC")), as.Date(.POSIXct(end, tz = "UTC")), sep = "/") ohlc <- ohlc[dateRange] ### Check to see if supplied dates occur in data set # if( max(ohlc[,'Date']) != as.Date(end) ) { # if(!quiet) message("End date out of range, " , max(ohlc[,'Date']), " is last available date.") # } # if( min(ohlc[,'Date']) != as.Date(beg) ) { # if(!quiet) message("Start date out of range, ", min(ohlc[,'Date']), " is first available date.") # } return(ohlc) } .getHandle <- function(force.new = FALSE) { h <- if (exists("_handle_", .env)) get("_handle_", .env) else NULL if (is.null(h) || force.new) { # create 'h' if it doesn't exist yet if (!force.new) { h <- list() } # establish session new.session <- function(h) { tmp <- tempfile() on.exit(unlink(tmp)) for (i in 1:5) { h <- curl::new_handle() # random query to avoid cache ru <- paste(sample(c(letters, 0:9), 4), collapse = "") cu <- paste0("https://finance.yahoo.com?", ru) curl::curl_download(cu, tmp, handle = h) if (NROW(curl::handle_cookies(h)) > 0) break; Sys.sleep(0.1) } if (NROW(curl::handle_cookies(h)) == 0) stop("Could not establish session after 5 attempts.") return(h) } h$ch <- new.session() n <- if (unclass(Sys.time()) %% 1L >= 0.5) 1L else 2L query.srv <- paste0("https://query", n, ".finance.yahoo.com/", "v1/test/getcrumb") cres <- curl::curl_fetch_memory(query.srv, handle = h$ch) h$cb <- rawToChar(cres$content) assign("_handle_", h, .env) } return(h) } .yahooURL <- function(symbol, from, to, period, type, handle) { p <- match.arg(period, c("1d", "1wk", "1mo")) e <- match.arg(type, c("history", "div", "split")) n <- if (unclass(Sys.time()) %% 1L >= 0.5) 1L else 2L u <- paste0("https://query", n, ".finance.yahoo.com/v7/finance/download/", symbol, "?period1=", from, "&period2=", to, "&interval=", p, "&events=", e, "&crumb=", handle$cb) return(u) } .dateToUNIX <- function(Date) { posixct <- as.POSIXct(as.Date(Date, origin = "1970-01-01")) trunc(as.numeric(posixct)) } TTR/R/runFun.R0000644000176200001440000002436513552670134012544 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Analysis of Running/Rolling/Moving Windows #' #'Various functions to analyze data over a moving window of periods. #' #' #'@aliases runFun runSum runMin runMax runMean runMedian runCov runCor runVar #'runSD runMAD wilderSum #'@param x Object coercible to xts or matrix. #'@param y Object coercible to xts or matrix. #'@param n Number of periods to use in the window or, if #'\code{cumulative=TRUE}, the number of observations to use before the first #'result is returned. Must be between 1 and \code{nrow(x)}, inclusive. #'@param cumulative Logical, use from-inception calculation? #'@param sample Logical, sample covariance if \code{TRUE} (denominator of #'\code{n-1}) #'@param use Only \code{"all.obs"} currently implemented. #'@param non.unique One of 'mean', 'max', or 'min'; which compute their #'respective statistics for the two middle values of even-sized samples. #'@param center The values to use as the measure of central tendency, around #'which to calculate deviations. The default (\code{NULL}) uses the median. #'@param stat Statistic to calculate, one of 'median' or 'mean' (e.g. median #'absolute deviation or mean absolute deviation, respectively.) #'@param constant Scale factor applied to approximate the standard deviation. #'@return A object of the same class as \code{x} and \code{y} or a vector (if #'\code{try.xts} fails). #' \describe{ #' \item{runSum}{returns sums over a n-period moving window.} #' \item{runMin}{returns minimums over a n-period moving window.} #' \item{runMax}{returns maximums over a n-period moving window.} #' \item{runMean}{returns means over a n-period moving window.} #' \item{runMedian}{returns medians over a n-period moving window.} #' \item{runCov}{returns covariances over a n-period moving window.} #' \item{runCor}{returns correlations over a n-period moving window.} #' \item{runVar}{returns variances over a n-period moving window.} #' \item{runSD}{returns standard deviations over a n-period moving window.} #' \item{runMAD}{returns median/mean absolute deviations over a n-period moving window.} #' \item{wilderSum}{retuns a Welles Wilder style weighted sum over a n-period moving window.} #' } #' #'@author Joshua Ulrich #'@keywords ts #'@rdname runFun "runSum" <- function(x, n=10, cumulative=FALSE) { x <- try.xts(x, error=as.matrix) if( n < 1 || n > NROW(x) ) stop(sprintf("n = %d is outside valid range: [1, %d]", n, NROW(x))) if(NCOL(x) > 1) { stop("ncol(x) > 1. runSum only supports univariate 'x'") } if(cumulative) { # Count NAs, ensure they're only at beginning of data. NAs <- sum(is.na(x)) if( NAs > 0 ) { if( any( is.na(x[-(1:NAs)]) ) ) stop("Series contains non-leading NAs") if( NAs + n > NROW(x) ) stop("not enough non-NA values") } beg <- 1 + NAs len <- NROW(x) - NAs # Initialize result vector result <- double(NROW(x)) result[beg:NROW(x)] <- cumsum(x[beg:NROW(x)]) # Replace 1:(n-1) with NAs is.na(result) <- c(1:(n-1+NAs)) } else { # Call C routine result <- .Call("runsum", x, n, PACKAGE = "TTR") } # Convert back to original class reclass(result, x) } #-------------------------------------------------------------------------# #'@rdname runFun "runMin" <- function(x, n=10, cumulative=FALSE) { x <- try.xts(x, error=as.matrix) if( n < 1 || n > NROW(x) ) stop(sprintf("n = %d is outside valid range: [1, %d]", n, NROW(x))) if(NCOL(x) > 1) { stop("ncol(x) > 1. runMin only supports univariate 'x'") } if(cumulative) { # Count NAs, ensure they're only at beginning of data, then remove. NAs <- sum( is.na(x) ) if( NAs > 0 ) { if( any( is.na(x[-(1:NAs)]) ) ) stop("Series contains non-leading NAs") if( NAs + n > NROW(x) ) stop("not enough non-NA values") } beg <- 1 + NAs len <- NROW(x) - NAs # Initialize result vector result <- double(NROW(x)) result[beg:NROW(x)] <- cummin(x[beg:NROW(x)]) # Replace 1:(n-1) with NAs is.na(result) <- c(1:(n-1+NAs)) } else { # Call C routine result <- .Call("runmin", x, n, PACKAGE = "TTR") } # Convert back to original class reclass(result, x) } #-------------------------------------------------------------------------# #'@rdname runFun "runMax" <- function(x, n=10, cumulative=FALSE) { x <- try.xts(x, error=as.matrix) if( n < 1 || n > NROW(x) ) stop(sprintf("n = %d is outside valid range: [1, %d]", n, NROW(x))) if(NCOL(x) > 1) { stop("ncol(x) > 1. runMax only supports univariate 'x'") } if(cumulative) { # Count NAs, ensure they're only at beginning of data, then remove. NAs <- sum( is.na(x) ) if( NAs > 0 ) { if( any( is.na(x[-(1:NAs)]) ) ) stop("Series contains non-leading NAs") if( NAs + n > NROW(x) ) stop("not enough non-NA values") } beg <- 1 + NAs len <- NROW(x) - NAs if(NCOL(x) > 1) { stop("ncol(x) > 1. runMax only supports univariate 'x'") } # Initialize result vector result <- double(NROW(x)) result[beg:NROW(x)] <- cummax(x[beg:NROW(x)]) # Replace 1:(n-1) with NAs and prepend NAs from original data is.na(result) <- c(1:(n-1+NAs)) } else { # Call C routine result <- .Call("runmax", x, n, PACKAGE = "TTR") } # Convert back to original class reclass(result, x) } #-------------------------------------------------------------------------# #'@rdname runFun "runMean" <- function(x, n=10, cumulative=FALSE) { if(cumulative) { result <- runSum(x, n, cumulative) / 1:NROW(x) } else { result <- runSum(x, n) / n } return(result) } #-------------------------------------------------------------------------# #'@rdname runFun "runMedian" <- function(x, n=10, non.unique="mean", cumulative=FALSE) { x <- try.xts(x, error=as.matrix) if( n < 1 || n > NROW(x) ) stop(sprintf("n = %d is outside valid range: [1, %d]", n, NROW(x))) if(NCOL(x) > 1) { stop("ncol(x) > 1. runMedian only supports univariate 'x'") } # Non-unique median non.unique <- match.arg(non.unique, c('mean','max','min')) non.unique <- switch(non.unique, mean=0L, max=1L, min=-1L) # Call C routine result <- .Call("runmedian", x, n, non.unique, cumulative, PACKAGE = "TTR") # Convert back to original class reclass(result, x) } #-------------------------------------------------------------------------# #'@rdname runFun "runCov" <- function(x, y, n=10, use="all.obs", sample=TRUE, cumulative=FALSE) { x <- try.xts(x, error=as.matrix) y <- try.xts(y, error=as.matrix) if(is.xts(x) && is.xts(y)) { xy <- cbind(x,y) } else { xy <- cbind( as.vector(x), as.vector(y) ) } if( n < 1 || n > NROW(x) ) stop(sprintf("n = %d is outside valid range: [1, %d]", n, NROW(x))) if(NCOL(x) > 1 || NCOL(y) > 1) { stop("ncol(x) > 1 or ncol(y) > 1.", " runCov only supports univariate 'x' and 'y'") } # "all.obs", "complete.obs", "pairwise.complete.obs" # Call C routine result <- .Call("runcov", x, y, n, sample, cumulative, PACKAGE = "TTR") # Convert back to original class # Should the attributes of *both* x and y be retained? reclass(result, x) } #-------------------------------------------------------------------------# #'@rdname runFun "runCor" <- function(x, y, n=10, use="all.obs", sample=TRUE, cumulative=FALSE) { result <- runCov(x, y, n, use=use, sample=sample, cumulative) / ( runSD(x, n, sample=sample, cumulative) * runSD(y, n, sample=sample, cumulative) ) return( result ) } #-------------------------------------------------------------------------# #'@rdname runFun "runVar" <- function(x, y=NULL, n=10, sample=TRUE, cumulative=FALSE) { if(is.null(y)) y <- x result <- runCov(x, y, n, use="all.obs", sample=sample, cumulative) return( result ) } #-------------------------------------------------------------------------# #'@rdname runFun "runSD" <- function(x, n=10, sample=TRUE, cumulative=FALSE) { result <- sqrt( runCov(x, x, n, use="all.obs", sample=sample, cumulative) ) return( result ) } #-------------------------------------------------------------------------# #'@rdname runFun "runMAD" <- function(x, n=10, center=NULL, stat="median", constant=1.4826, non.unique="mean", cumulative=FALSE) { x <- try.xts(x, error=as.matrix) if( n < 1 || n > NROW(x) ) stop(sprintf("n = %d is outside valid range: [1, %d]", n, NROW(x))) if(NCOL(x) > 1) { stop("ncol(x) > 1. runMAD only supports univariate 'x'") } if(is.null(center)) { center <- runMedian(x, n, cumulative=cumulative) } # Mean or Median absolute deviation? median <- match.arg(stat, c("mean","median")) median <- switch( stat, median=TRUE, mean=FALSE ) # Non-unique median non.unique <- match.arg(non.unique, c('mean','max','min')) non.unique <- switch( non.unique, mean=0, max=1, min=-1 ) # Call C routine result <- .Call("runmad", x, center, n, median, non.unique, cumulative, PACKAGE = "TTR") if( median ) result <- result * constant # Convert back to original class reclass(result, x) } #-------------------------------------------------------------------------# #'@rdname runFun "wilderSum" <- function(x, n=10) { x <- try.xts(x, error=as.matrix) if( n < 1 || n > NROW(x) ) stop(sprintf("n = %d is outside valid range: [1, %d]", n, NROW(x))) if(NCOL(x) > 1) { stop("ncol(x) > 1. wilderSum only supports univariate 'x'") } # Check for non-leading NAs # Leading NAs are handled in the C code x.na <- naCheck(x, n) # Call C routine result <- .Call("wilderSum", x, n, PACKAGE = "TTR") # Convert back to original class reclass(result, x) } TTR/R/SAR.R0000644000176200001440000000615213552670134011706 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Parabolic Stop-and-Reverse #' #'The Parabolic Stop-and-Reverse calculates a trailing stop. Developed by J. #'Welles Wilder. #' #'The calculation for the SAR is quite complex. See the URLs in the references #'section for calculation notes. #' #'The SAR assumes that you are always in the market, and calculates the Stop #'And Reverse point when you would close a long position and open a short #'position or vice versa. #' #'@param HL Object that is coercible to xts or matrix and contains High-Low #'prices. #'@param accel accel[1]: Acceleration factor.\cr accel[2]: Maximum acceleration #'factor. #'@return A object of the same class as \code{HL} or a vector (if #'\code{try.xts} fails) containing the Parabolic Stop and Reverse values. #'@author Joshua Ulrich #'@seealso See \code{\link{ATR}} and \code{\link{ADX}}, which were also #'developed by Welles Wilder. #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{https://www.linnsoft.com/techind/parabolic-sar-sar}\cr #'\url{http://www.fmlabs.com/reference/SAR.htm}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:parabolic_sar}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=87} #'@keywords ts #'@examples #' #' data(ttrc) #' sar <- SAR(ttrc[,c("High","Low")]) #' "SAR" <- function(HL, accel=c(.02,.2)) { # Parabolic Stop-and-Reverse (SAR) # ---------------------------------------------- # HL = HL vector, matrix, or dataframe # accel[1] = acceleration factor # accel[2] = maximum acceleration factor # WISHLIST: # Determine signal based on DM+/DM- for first bar # If sig[1]==1, then ep[1]==high; if sig[1]==-1, then ep[1]==low # The first SAR value should be the opposite (high/low) of ep # The first acceleration factor is based on the first signal # Since I've already lost one bar, do what TA-lib does and use that bar to # determine the inital signal value. Also try to incorporate different # accel factors for long/short. # accel = c( long = c( 0.02, 0.2 ), short = long ) HL <- try.xts(HL, error=as.matrix) # Check for non-leading NAs # Leading NAs are handled in the C code HL.na <- naCheck(HL, 0) # Gap for inital SAR initGap <- sd(drop(coredata(HL[,1] - HL[,2])), na.rm=TRUE) # Call C routine sar <- .Call("sar", HL[,1], HL[,2], accel, initGap, PACKAGE = "TTR") colnames(sar) <- "sar" reclass( sar, HL ) } TTR/R/OBV.R0000644000176200001440000000506713575211333011710 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'On Balance Volume (OBV) #' #'On Balance Volume (OBV) is a measure of the money flowing into or out of a #'security. It is similar to Chaikin Accumulation / Distribution. #' #'OBV is calculated by adding (subtracting) each day's volume to a running #'cumulative total when the security's price closes higher (lower). #' #'@param price Price series that is coercible to xts or matrix. #'@param volume Volume series that is coercible to xts or matrix, that #'corresponds to price object. #'@return A object of the same class as \code{price} and \code{volume} or a #'vector (if \code{try.xts} fails) containing the OBV values. #'@note OBV is usually compared with the price chart of the underlying security #'to look for divergences/confirmation. #'@author Joshua Ulrich #'@seealso See \code{\link{chaikinAD}}. #'@references The following site(s) were used to code/document this #'indicator:\cr \url{http://www.fmlabs.com/reference/OBV.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=82}\cr #'\url{https://www.linnsoft.com/techind/balance-open-interest}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:on_balance_volume_obv}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' obv <- OBV(ttrc[,"Close"], ttrc[,"Volume"]) #' "OBV" <- function(price, volume) { # On Balance Volume price <- try.xts(price, error=as.matrix) volume <- try.xts(volume, error=as.matrix) if(!(is.xts(price) && is.xts(volume))) { price <- as.vector(price) volume <- as.vector(volume) } prChg <- ROC(price) obv <- c( volume[1], ifelse( prChg > 0, volume, -volume )[-1] ) # OBV[t] = OBV[t-1] if price change is equal to zero obv[abs(prChg) < sqrt(.Machine$double.eps)] <- 0 obv <- cumsum( obv ) if(is.xts(obv)) { obv <- xts(obv,index(price)) colnames(obv) <- 'obv' } reclass( obv, price ) } TTR/R/WPR.R0000644000176200001440000000555613552670134011740 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'William's \%R #' #'William's \% R. #' #'If an High-Low-Close series is provided, the indicator is calculated using #'the high/low values. If a vector is provided, the calculation only uses that #'series. #' #'@param HLC Object that is coercible to xts or matrix and contains #'High-Low-Close prices. If only a univariate series is given, it will be #'used. See details. #'@param n Number of periods to use. #'@return A object of the same class as \code{HLC} or a vector (if #'\code{try.xts} fails) containing the William's \%R values. #'@note The William's \%R calculation is similar to stochastics' fast \%K. #' #'The value for William's \%R will be 0.5 whenever the highest high and #'lowest low are the same over the last \code{n} periods. #'@author Joshua Ulrich #'@seealso See \code{\link{stoch}}. #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{http://www.fmlabs.com/reference/WilliamsR.htm}\cr #'\url{http://www.metastock.com/Customer/Resources/TAAZ/#126}\cr #'\url{https://www.linnsoft.com/techind/williams-r-wpr}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:williams_r}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' stochOsc <- stoch(ttrc[,c("High","Low","Close")]) #' stochWPR<- WPR(ttrc[,c("High","Low","Close")]) #' #' plot(tail(stochOsc[,"fastK"], 100), type="l", #' main="Fast %K and Williams %R", ylab="", #' ylim=range(cbind(stochOsc, stochWPR), na.rm=TRUE) ) #' lines(tail(stochWPR, 100), col="blue") #' lines(tail(1-stochWPR, 100), col="red", lty="dashed") #' "WPR" <- function(HLC, n=14) { # William's Percent R (similar to Stochastics' fast %K) HLC <- try.xts(HLC, error=as.matrix) # Calculation if HLC series is given if(NCOL(HLC)==3) { high <- HLC[,1] low <- HLC[,2] close <- HLC[,3] } else # Calculation if price vector is given if(NCOL(HLC)==1) { high <- HLC low <- HLC close <- HLC } else stop("Price series must be either High-Low-Close, or Close") hmax <- runMax(high, n) lmin <- runMin( low, n) pctR <- (hmax - close) / (hmax - lmin) pctR[is.nan(pctR)] <- 0.5 reclass( pctR, HLC ) } TTR/R/ATR.R0000644000176200001440000000667713552670134011723 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'True Range / Average True Range #' #'True range (TR) is a measure of volatility of a High-Low-Close series; #'average true range (ATR) is a Welles Wilder's style moving average of the TR. #'Developed by J. Welles Wilder in 1978. #' #'TR incorporates yesterday's close in the calculation (high minus low). E.g. #'if yesterday's close was higher than today's high, then the TR would equal #'yesterday's close minus today's low. #' #'The ATR is a component of the Welles Wilder Directional Movement Index #'(\code{DX}, \code{ADX}). #' #'@aliases ATR TR #'@param HLC Object that is coercible to xts or matrix and contains #'High-Low-Close prices. #'@param n Number of periods for moving average. #'@param maType A function or a string naming the function to be called. #'@param \dots Other arguments to be passed to the \code{maType} function. #'@return A object of the same class as \code{HLC} or a matrix (if #'\code{try.xts} fails) containing the columns: #' \describe{ #' \item{ tr }{ The true range of the series. } #' \item{ atr }{ The average (as specified by \code{ma}) true range of the series. } #' \item{ trueHigh }{ The true high of the series. } #' \item{ trueLow }{ The true low of the series. } #' } #'@author Joshua Ulrich #'@seealso See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average #'options; and note Warning section. See \code{\link{DX}}, which uses true #'range. See \code{\link{chaikinVolatility}} for another volatility measure. #'@references The following site(s) were used to code/document this #'indicator:\cr \url{http://www.fmlabs.com/reference/TR.htm}\cr #'\url{http://www.fmlabs.com/reference/ATR.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=35}\cr #'\url{https://www.linnsoft.com/techind/true-range-tr}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:average_true_range_atr}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' atr <- ATR(ttrc[,c("High","Low","Close")], n=14) #' "ATR" <- function(HLC, n=14, maType, ...) { # Average True Range / True Range HLC <- try.xts(HLC, error=as.matrix) if(is.xts(HLC)) { closeLag <- lag.xts(HLC[,3]) } else { closeLag <- c( NA, HLC[-NROW(HLC),3] ) } trueHigh <- pmax( HLC[,1], closeLag, na.rm=FALSE ) trueLow <- pmin( HLC[,2], closeLag, na.rm=FALSE ) tr <- trueHigh - trueLow maArgs <- list(n=n, ...) # Default Welles Wilder EMA if(missing(maType)) { maType <- 'EMA' if(is.null(maArgs$wilder)) { # do not overwrite user-provided value maArgs$wilder <- TRUE } } atr <- do.call( maType, c( list(tr), maArgs ) ) result <- cbind( tr, atr, trueHigh, trueLow ) colnames(result) <- c('tr','atr','trueHigh','trueLow') reclass( result, HLC ) } TTR/R/EMV.R0000644000176200001440000000643313552670134011712 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Arms' Ease of Movement Value #' #'Arms' Ease of Movement Value (EMV) emphasizes days where the security moves #'easily and minimizes days where the security does not move easily. Developed #'by Richard W. Arms, Jr. #' #'The EMV is calculated by dividing the midpoint ([high + low]/2) move by the #''Box Ratio' (volume divided by the high minus low). #' #'@param HL Object that is coercible to xts or matrix and contains High-Low #'prices. #'@param volume Vector or matrix of volume observations corresponding to the #'\code{HL} object. #'@param n Number of periods for moving average. #'@param maType A function or a string naming the function to be called. #'@param vol.divisor An increment to make the results larger and easier to work #'with. #'@param \dots Other arguments to be passed to the \code{maType} function. #'@return A object of the same class as \code{HL} and \code{volume} or a matrix #'(if \code{try.xts} fails) containing the columns: #' \describe{ #' \item{ emv }{ The ease of movement values. } #' \item{ maEMV }{ The smoothed (as specified by \code{ma}) ease of movement values. } #' } #'@note A buy/sell signal is generated when the EMV crosses above/below zero. #'When the EMV hovers around zero, there are small price movements and/or high #'volume, and the price is not moving easily. #'@author Joshua Ulrich #'@seealso See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average #'options; and note Warning section. #'@references The following site(s) were used to code/document this #'indicator:\cr \url{http://www.fmlabs.com/reference/ArmsEMV.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=51}\cr #'\url{https://www.linnsoft.com/techind/arms-ease-movement}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' emv <- EMV(ttrc[,c("High","Low")], ttrc[,"Volume"]) #' "EMV" <- function(HL, volume, n=9, maType, vol.divisor=10000, ...) { # Arms' Ease of Movement Value if( missing(HL) | missing(volume) ) stop("High-Low matrix (HL) and volume vector must be specified.") HL <- try.xts(HL, error=as.matrix) volume <- try.xts(volume, error=as.matrix) if(!(is.xts(HL) && is.xts(volume))) { HL <- as.matrix(HL) volume <- as.matrix(volume) } mid <- ( HL[,1] + HL[,2] ) / 2 volume <- volume / vol.divisor emv <- momentum(mid, n=1, na.pad=TRUE) / ( volume / ( HL[,1] - HL[,2] ) ) maArgs <- list(n=n, ...) # Default MA if(missing(maType)) { maType <- 'SMA' } maEMV <- do.call( maType, c( list(emv), maArgs ) ) result <- cbind(emv,maEMV) colnames(result) <- c('emv','maEMV') reclass( result, HL ) } TTR/R/CCI.R0000644000176200001440000000676513552670134011671 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Commodity Channel Index #' #'The Commodity Channel Index (CCI) attempts to identify starting and ending #'trends. #' #'CCI relates the current price and the average of price over \code{n} periods. #'The CCI usually falls in a channel of -100 to 100. A basic CCI trading system #'is: Buy (sell) if CCI rises above 100 (falls below -100) and sell (buy) when #'it falls below 100 (rises above -100). #' #'CCI is usually calculated using the typical price, but if a univariate series #'(e.g. Close, Weighted Close, Median Price, etc.) is provided, it will be used #'instead. #' #'@param HLC Object that is coercible to xts or matrix and contains #'High-Low-Close prices. If only a univariate series is given, it will be #'used. See details. #'@param n Number of periods for moving average. #'@param maType A function or a string naming the function to be called. #'@param c Constant to apply to the mean deviation. #'@param \dots Other arguments to be passed to the \code{maType} function. #'@return A object of the same class as \code{HLC} or a vector (if #'\code{try.xts} fails) containing the CCI values. #'@note If \code{HLC} is a High-Low-Close matrix, then typical price will be #'calculated. If \code{HLC} is a vector, then those values will be used #'instead of the typical price. #'@author Joshua Ulrich #'@seealso See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average #'options; and note Warning section. See \code{\link{aroon}}, #'\code{\link{ADX}}, \code{\link{TDI}}, \code{\link{VHF}}, \code{\link{GMMA}} #'for other indicators that measure trend direction/strength. #'@references The following site(s) were used to code/document this #'indicator:\cr \url{http://www.fmlabs.com/reference/CCI.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=42}\cr #'\url{https://www.linnsoft.com/techind/cci-commodity-channel-index}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:commodity_channel_index_cci}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' cci <- CCI(ttrc[,c("High","Low","Close")]) #' "CCI" <- function(HLC, n=20, maType, c=0.015, ...) { # Commodity Channel Index HLC <- try.xts(HLC, error=as.matrix) if(NCOL(HLC)==3) { if(is.xts(HLC)) { xa <- xcoredata(HLC) HLC <- xts(apply(HLC, 1, mean),index(HLC)) xcoredata(HLC) <- xa } else { HLC <- apply(HLC, 1, mean) } } else if(NCOL(HLC)!=1) { stop("Price series must be either High-Low-Close, or Close/univariate.") } maArgs <- list(n=n, ...) # Default MA if(missing(maType)) { maType <- 'SMA' } mavg <- do.call( maType, c( list(HLC), maArgs ) ) meanDev <- runMAD( HLC, n, center=mavg, stat="mean" ) cci <- ( HLC - mavg ) / ( c * meanDev ) if(is.xts(cci)) { colnames(cci) <- "cci" } reclass(cci, HLC) } TTR/R/ADX.R0000644000176200001440000000755513552670134011705 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Welles Wilder's Directional Movement Index #' #'Directional Movement Index; developed by J. Welles Wilder. #' #'The \code{DIp}/\code{DIn} (positive/negative) is the percentage of the true #'range that is up/down. #' #'@aliases ADX DI DX #'@param HLC Object that is coercible to xts or matrix and contains #'High-Low-Close prices. #'@param n Number of periods to use for DX calculation (not ADX calculation). #'@param maType A function or a string naming the function to be called. #'@param \dots Other arguments to be passed to the \code{maType} function. #'@return A object of the same class as \code{HLC} or a matrix (if #'\code{try.xts} fails) containing the columns: #' \describe{ #' \item{ DIp }{ The positive Direction Index. } #' \item{ DIn }{ The negative Direction Index. } #' \item{ DX }{ The Direction Index. } #' \item{ ADX }{ The Average Direction Index (trend strength). } #' } #'@note A buy/sell signal is generated when the +/-DI crosses up over the #'-/+DI, when the DX/ADX signals a strong trend. A high/low DX signals a #'strong/weak trend. DX is usually smoothed with a moving average (i.e. the #'ADX). #'@author Joshua Ulrich #'@seealso See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average #'options; and note Warning section. The DX calculation uses #'\code{\link{ATR}}. See \code{\link{aroon}}, \code{\link{CCI}}, #'\code{\link{TDI}}, \code{\link{VHF}}, \code{\link{GMMA}} for other indicators #'that measure trend direction/strength. #'@references The following site(s) were used to code/document this #'indicator:\cr \url{http://www.fmlabs.com/reference/DI.htm}\cr #'\url{http://www.fmlabs.com/reference/DX.htm}\cr #'\url{http://www.fmlabs.com/reference/ADX.htm}\cr #'\url{http://www.fmlabs.com/reference/ADXR.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=49}\cr #'\url{https://www.linnsoft.com/techind/directional-indicator-diplus-diminus}\cr #'\url{https://www.linnsoft.com/techind/adx-avg-directional-movement}\cr #'\url{https://www.linnsoft.com/techind/adxr-avg-directional-movement-rating}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:average_directional_index_adx}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' dmi.adx <- ADX(ttrc[,c("High","Low","Close")]) #' "ADX" <- function(HLC, n=14, maType, ...) { # Welles Wilder's Directional Movement Index HLC <- try.xts(HLC, error=as.matrix) dH <- momentum(HLC[,1]) dL <- -momentum(HLC[,2]) DMIp <- ifelse( dH==dL | (dH< 0 & dL< 0), 0, ifelse( dH >dL, dH, 0 ) ) DMIn <- ifelse( dH==dL | (dH< 0 & dL< 0), 0, ifelse( dH . # #'De-Trended Price Oscillator #' #'The Detrended Price Oscillator (DPO) removes the trend in prices - or other #'series - by subtracting a moving average of the price from the price. #' #'The Detrended Price shows cycles and overbought / oversold conditions. #' #'@param x Price, volume, etc. series that is coercible to xts or matrix. #'@param n Number of periods for moving average. #'@param maType A function or a string naming the function to be called. #'@param shift The number of periods to shift the moving average. #'@param percent logical; if \code{TRUE}, the percentage difference between the #'slow and fast moving averages is returned, otherwise the difference between #'the respective averages is returned. #'@param \dots Other arguments to be passed to the \code{maType} function. #'@return A object of the same class as \code{x} or a vector (if \code{try.xts} #'fails) containing the DPO values. #'@note #'DPO does not extend to the last date because it is based on a displaced moving #'average. The calculation shifts the results \code{shift} periods, so the last #'\code{shift} periods will be zero.\cr #'As stated above, the DPO can be used on any univariate series, not just price. #'@section Warning: The detrended price oscillator removes the trend in the #'series by centering the moving average. Centering the moving average causes it #'to include future data. Therefore, even though this indicator looks like a #'classic oscillator, it should not be used for trading rule signals. #'@author Joshua Ulrich #'@seealso See \code{\link{EMA}}, \code{\link{SMA}}, etc. for moving average #'options; and note Warning section. See \code{\link{MACD}} for a general #'oscillator. #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators:detrended_price_osci}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' priceDPO <- DPO(ttrc[,"Close"]) #' volumeDPO <- DPO(ttrc[,"Volume"]) #' "DPO" <- function(x, n=10, maType, shift=n/2+1, percent=FALSE, ...) { # De-Trended Price Oscillator x <- try.xts(x, error=as.matrix) maArgs <- list(n=n, ...) # Default MA if(missing(maType)) { maType <- 'SMA' } mavg <- do.call( maType, c( list(x), maArgs ) ) mavg <- lag.xts(mavg, -shift) if(percent) { DPO <- 100 * ( x[,1] / mavg - 1 ) } else { DPO <- x[,1] - mavg } reclass( DPO, x ) } TTR/R/GMMA.R0000644000176200001440000000502013552670134011773 0ustar liggesusers# # TTR: Technical Trading Rules # # Copyright (C) 2007-2013 Joshua M. Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #'Guppy Multiple Moving Averages #' #'Calculate the Guppy Multiple Moving Average of a series. #' #'The Guppy Multiple Moving Average signals a changing trend when the #'\code{short} and \code{long} groups of moving averages intersect. An up/down #'trend exists when the short/long-term moving averages are greater than the #'long/short-term averages. #' #'@aliases GMMA Guppy guppy #'@param x Price, volume, etc. series that is coercible to xts or matrix. #'@param short Vector of short-term periods. #'@param long Vector of long-term periods. #'@param maType Either: #' \enumerate{ #' \item A function or a string naming the function to be called. #' \item A \emph{list} with the first component like (1) above, and #' additional parameters specified as \emph{named} components. #' See Examples. #' } #'@return A object of the same class as \code{x} or \code{price} or a vector #'(if \code{try.xts} fails) containing the Guppy Multiple Moving Average. #'@author Joshua Ulrich #'@seealso See \code{\link{aroon}}, \code{\link{CCI}}, \code{\link{ADX}}, #'\code{\link{VHF}}, \code{\link{TDI}} for other indicators that measure trend #'direction/strength. #'@references The following site(s) were used to code/document this #'indicator:\cr #'\url{http://www.investopedia.com/terms/g/guppy-multiple-moving-average.asp}\cr #'@keywords ts #'@examples #' #' data(ttrc) #' gmma <- GMMA(ttrc[,"Close"]) #' "GMMA" <- function(x, short=c(3,5,8,10,12,15), long=c(30,35,40,45,50,60), maType) { # Guppy Multiple Moving Average x <- try.xts(x, error=as.matrix) # Default MA if(missing(maType)) { maType <- 'EMA' } fn <- function(g) { do.call(maType, list(x,n=g)) } gmma <- do.call(cbind, lapply(c(short,long), fn)) colnames(gmma) <- c(paste('short lag',short),paste('long lag',long)) reclass(gmma, x) } TTR/R/TTR-package.R0000644000176200001440000000513513552670134013323 0ustar liggesusers#'Technical Trading Rule Composite data #' #'Historical Open, High, Low, Close, and Volume data for the periods January 2, #'1985 to December 31, 2006. Randomly generated. #' #'These data do not represent an actual security. They are provided so #'examples do not necessitate an internet connection. #' #'@name ttrc #'@docType data #'@format The format is: \tabular{lll}{ Date: \tab Class 'Date' \tab 5480 5481 #'5482 5485 5486 ...\cr Open: \tab num \tab 3.18 3.09 3.11 3.09 3.10 ...\cr #'High: \tab num \tab 3.18 3.15 3.12 3.12 3.12 ...\cr Low: \tab num \tab 3.08 #'3.09 3.08 3.07 3.08 ...\cr Close: \tab num \tab 3.08 3.11 3.09 3.10 3.11 #'...\cr Volume: \tab num \tab 1870906 3099506 2274157 2086758 2166348 ...\cr } #'@source Randomly generated. #'@keywords datasets #'@examples #' #' data(ttrc) #' plot(tail(ttrc[,"Close"],100), type="l") #'@rdname ttrc NULL #'Functions to create Technical Trading Rules (TTR) #' #'This package contains many of the most popular technical analysis functions, #'as well as functions to retrieve U.S. stock symbols, and data from Yahoo #'Finance. #' #'Users will probably be most interested in the following functions:\cr #'\code{\link{ADX}}\cr \code{\link{BBands}}\cr \code{\link{changes}}\cr #'\code{\link{MovingAverages}}\cr \code{\link{MACD}}\cr \code{\link{RSI}}\cr #'\code{\link{runFun}}\cr \code{\link{stoch}}\cr \code{\link{VWAP}}\cr #'\code{\link{WebData}}\cr #' #'@name TTR #'@docType package #'@author Joshua Ulrich #' #'Maintainer: Joshua Ulrich #'@references The following sites were used to code/document this package:\cr #'\url{http://www.fmlabs.com/reference/default.htm}\cr #'\url{https://www.metastock.com/Customer/Resources/TAAZ/}\cr #'\url{https://www.linnsoft.com/indicators}\cr #'\url{http://www.stockcharts.com/school/doku.php?id=chart_school:technical_indicators}\cr #'@keywords package #'@examples #' #' data(ttrc) #' #' # Bollinger Bands #' bbands <- BBands( ttrc[,c("High","Low","Close")] ) #' #' # Directional Movement Index #' adx <- ADX(ttrc[,c("High","Low","Close")]) #' #' # Moving Averages #' ema <- EMA(ttrc[,"Close"], n=20) #' sma <- SMA(ttrc[,"Close"], n=20) #' #' # MACD #' macd <- MACD( ttrc[,"Close"] ) #' #' # RSI #' rsi <- RSI(ttrc[,"Close"]) #' #' # Stochastics #' stochOsc <- stoch(ttrc[,c("High","Low","Close")]) #' #' ### Note: you must have a working internet connection #' ### for the examples below to work! #' if (interactive()) { #' # Fetch U.S. symbols from the internet #' nyseSymbols <- stockSymbols("NYSE") #' #' # Fetch Yahoo! Finance data from the internet #' ge <- getYahooData("GE", 19990404, 20050607, adjust = FALSE) #' } #' #'@rdname TTR NULL TTR/MD50000644000176200001440000001335013575463222011246 0ustar liggesusers559d4061a6b1e5dce43a2f7eb67f5e38 *CHANGES bd2633397cd0b6f83e118705d0373c22 *DESCRIPTION 551cc739406a362bd50bfc8e7de87635 *NAMESPACE 7ef1a659d9181bf19651ee31b2fb00de *R/ADX.R 992674a6952f2c5bdd42d5726e617688 *R/ATR.R 0a5164363f7043be813dbd6a946664e6 *R/CCI.R dc478e548b6c6030b82a8d57494e025d *R/CLV.R 7df44ac8924b13a138b395f2957110f3 *R/CMF.R 2041b089804d62e819f019f40423e167 *R/CMO.R 2c3b5c047826db5a1cc0428142141455 *R/DPO.R 8be02ee83cafae2b1b7253fedb29bcb3 *R/DVI.R f017d1e21b2a9f418e89cdf39acd9021 *R/DonchianChannel.R 5cb339cb47c53e26c436ec10b4900519 *R/EMV.R 67876c4e9293132aa5d9e216fc8233b9 *R/GMMA.R 08bed5f247bffb2aa3d90e3a8d32908f *R/KST.R 46bbb713ac3997c4ed85ac49d2a4fa58 *R/MACD.R edd25697fa34e29dd8a795d956aa9d89 *R/MFI.R fd1b4a6fd7394a6068e4ba64e395ba46 *R/MovingAverages.R c2fce26396dfde8a77ede723a390a17a *R/OBV.R 3562e3e475301136dc6fb421ad69831f *R/RSI.R c87a60831dd8a697c60b8e4a325134e8 *R/SAR.R 600625303f98f02e66ea7111d03c56ef *R/SNR.R 2a67bd8c93a9e901bb5567f81eea0719 *R/TDI.R 5ec9625b6b924760f4b38099a411c262 *R/TRIX.R 20268d03c3b007dbbe2c2cf2a7c6aa10 *R/TTR-package.R 2dbdeb44bf06a540a326e6007409e49b *R/TTRtools.R 8412965fa5fe796bdfc52753a932be9d *R/VHF.R f42890501239d2465a49b07663e5b959 *R/WPR.R 8c24c9d21c5ca68edc53a0f5f175bbcf *R/WebData.R 0f2df537e38a24b154430165790f0858 *R/ZigZag.R 653cd8f90db069319d15a5db67803030 *R/adjRatios.R ce25b8f2a69816f00434209d7c737643 *R/aroon.R 9265ca4d7d5c0f0e04ea0f47dd727e61 *R/bollingerBands.R 8e0d1795093e87081dc07554567c350e *R/chaikinAD.R d291f49f9d4bee42e2cdaf0943241ca1 *R/chaikinVolatility.R 78f545f62ab4b85fad2abcaff3cde491 *R/changes.R e770e842f8f8cc6cda86b118756003f2 *R/percentRank.R 736f4a1e82951802890772634ca5029a *R/priceBands.R 1c188061eff4ec3c2aaf59c4f85d4d88 *R/rollFun.R 726bd4f3b993bcc5c2f74f88e493e88e *R/runFun.R 3aef00f2de52c4fd979717af4449162e *R/stochastics.R 871d0485886f65fea5feed504a283310 *R/ultimateOscillator.R 8213ace4bfa5f67e0fea670a31bc5e0d *R/volatility.R fc9a22b4795e67dbc584cbac423f776a *R/williamsAD.R 55f464d5b42ae9ec4db73f2e284180e2 *R/zzz.R b1c8cbf5900675293703086a0ef1f6b4 *THANKS 87ea4a9a2345d378b6078ac2b113a4a5 *data/ttrc.rda 9fd9d95de07300305cd03043f5deb78e *inst/unitTests/output.MA.rda 103e1709fb6ac849feca07ad25819ca8 *inst/unitTests/output.Oscillators.rda 8adfcbe30d3945415a806bb702c23705 *inst/unitTests/output.misc.rda 559e27421f85a7cb6aec1d3b3ed11359 *inst/unitTests/output.overlays.rda 503d4b12d9aed8e29d9ee9f6d8c7b042 *inst/unitTests/output.runFun.rda 8f299ed2b5a0f6eb9a12cde0641af15a *inst/unitTests/output.trend.rda 7eeabaf711fb54d77e5adee740bb9991 *inst/unitTests/output.volatility.rda a733627e9696f857173f03255607997a *inst/unitTests/output.volume.rda 2241426f086252acf482b0e92cb28472 *inst/unitTests/runit.TTR.DVI.R dd8caff6bfa54c36731aa798af066d77 *inst/unitTests/runit.TTR.Misc.R 0154c20459a9c1cb937f997e53e6ff03 *inst/unitTests/runit.TTR.MovingAverages.R ef74c13d7405b8f5ce0fbb790d99da64 *inst/unitTests/runit.TTR.Oscillators.R d10487a07e9489bb5d138dd25168f912 *inst/unitTests/runit.TTR.Overlays.R 7166ab7278b9c6d50d867dcc2a857288 *inst/unitTests/runit.TTR.Trend.R 92c8d95e1c96b3efc2d44e30ae7b5c28 *inst/unitTests/runit.TTR.Volatility.R 448df8f1b22e6e46e7b7b876d46759c7 *inst/unitTests/runit.TTR.Volume.R 1991def00d44b173616ee3c4e0ab3c5d *inst/unitTests/runit.TTR.runFun.R a0afc972425e22142eed7684c87d7ea9 *man/ADX.Rd 58c62c1dc5a32f57271b1bf6e31e6278 *man/ATR.Rd 9a13fa72f36a29239c1773a2fe6bf2ae *man/CCI.Rd f5ec4597921f20a847fd4062b5ed709c *man/CLV.Rd a30b4cd43cf1a5d99cecd27924d5fd5d *man/CMF.Rd 7072139a4f875b272466c74a11a74b5e *man/CMO.Rd 5c6048ec0eab516c98f760dd750a2b87 *man/DPO.Rd a0a30e84b0ee0ef223a0718f001e3ee8 *man/DVI.Rd e45745a8f6d186e698fa733c09b1903d *man/DonchianChannel.Rd 910db8f15cc97d1d7ef43e74004b8eb3 *man/EMV.Rd 1850915ec51ce0e11ab2429ab77d2a18 *man/GMMA.Rd cc7421a3497cc6e613a52b2d3c27bd6a *man/KST.Rd a137058c9c1a8b1470cbaaff70e1601a *man/MACD.Rd 41a05eada8563ab595831aed2278ae10 *man/MFI.Rd cd5eec73a9a065f1c0a67bb65b026b33 *man/MovingAverages.Rd 972a8d13d170a457c2c45f691dd9694c *man/OBV.Rd b6bc6c7949cb2a56d8bc9f160dba2a2b *man/RSI.Rd 342bc790c1a1e792e0da95ddb9c47e89 *man/SAR.Rd 303925f6368b725928057824e944f653 *man/SNR.Rd 08d7785a0fcfb789b8e7826e4c6d34f7 *man/TDI.Rd 989bb1398182d63318d6cfe668ed6b7a *man/TRIX.Rd 12a96fb6dd66a996fe4e78610ad563ae *man/TTR.Rd 4111fb0a6445697720bfdd6c52fff091 *man/TTRtools.Rd 05255b746c70ae6f37ca2a888c99f6c6 *man/VHF.Rd 44793b1f0055f10129dba539aed42dfb *man/WPR.Rd 9d8a00653052754852d0687d15fa2a2a *man/WebData.Rd a943a63337580c9a8b7e9dae4569ef1f *man/ZigZag.Rd a61249130f6899e2a91ece4041a92ac8 *man/adjRatios.Rd debdc508700777d440ba730784800256 *man/aroon.Rd 591bb4b7db7c1452111d4a4044f3c4ce *man/bollingerBands.Rd 1ec9794633e5319bcaa2e0bea6308300 *man/chaikinAD.Rd 9957974403810c1078499f93f8953dfc *man/chaikinVolatility.Rd 7f2dd4e45d21b6c9a3f34ed29ccd576e *man/changes.Rd 1aef6ee4343449af0379a18d30b32983 *man/priceBands.Rd 16bc07b474730357f88422347d6644cf *man/rollFun.Rd 3407ce1e146c26de9620ea5b6cc1311f *man/runFun.Rd 1e5bb178bdb96c3c7a01f7da702d327f *man/runPercentRank.Rd 2adba829ad3d90d5e0fa90fe7fa8c11e *man/stochastics.Rd e6d83f1826eb1aa77dfb9affc6ef6a08 *man/ttrc.Rd 7a3fdd24586cbeebae7f76aa719e82f0 *man/ultimateOscillator.Rd 0c9f2c3a3acf6b212bf574f2e4258268 *man/volatility.Rd 1fbb673020fc6f6a8cf4869e18961d08 *man/williamsAD.Rd a61afe813093802d1830b60fbb556725 *src/adjRatios.c bf35a5b5f33bc8135dd671b62b749d40 *src/aroon.c 63f680421bd5b0373c1a501a260e7c59 *src/init.c 9600b66b1c6569e1362a7f486024e22f *src/moving_averages.c 2d7f4fd1488e9eef2c3713026709da4c *src/percent_rank.c 55d673829bd3e9d86ca6ffb0ab09dd39 *src/runfun.c e1a8b1e8e028553313e988d6c313b843 *src/sar.c fdff206985cf612f98232a47b84427f0 *src/ttr.h b284326866970a2da0021d2a1b56f33d *src/wilderSum.c 5967b495255002a0209d171ba200f952 *src/zigzag.c 5a0829eae4b658df818c959ef8178567 *tests/doRUnit.R TTR/inst/0000755000176200001440000000000013425330036011677 5ustar liggesusersTTR/inst/unitTests/0000755000176200001440000000000013552670134013710 5ustar liggesusersTTR/inst/unitTests/runit.TTR.Overlays.R0000644000176200001440000000365513425330036017451 0ustar liggesusers# # RUnit tests TTR moving averages # # test reclass works and throws error # test xtsAttributes, both CLASS and USER # test all.equal(CLASS) and !all.equal(CLASS) cases # Create input data data(ttrc) rownames(ttrc) <- ttrc$Date ttrc$Date <- NULL input <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] ) input$top[1:10,] <- NA input$mid[9:20,] <- NA # Load output data load(system.file("unitTests/output.overlays.rda", package="TTR")) ################################################# # Bollinger Bands test.BBands <- function() { ia <- input$all[,c('High','Low','Close')] it <- input$top[,c('High','Low','Close')] im <- input$mid[,c('High','Low')] rownames(ia) <- rownames(it) <- NULL oa <- BBands(ia) ot <- BBands(it) rownames(oa) <- rownames(ot) <- rownames(input$all) checkEqualsNumeric( oa, output$allBBands ) checkEquals( attributes(oa), attributes(output$allBBands) ) checkEqualsNumeric( ot, output$topBBands ) checkEquals( attributes(ot), attributes(output$topBBands) ) checkException( BBands(im) ) } # SAR test.SAR <- function() { ia <- input$all[,c('High','Low')] it <- input$top[,c('High','Low')] im <- input$mid[,c('High','Low')] rownames(ia) <- rownames(it) <- rownames(im) <- NULL checkEqualsNumeric( SAR(ia), output$allSAR ) checkEquals( attributes(SAR(ia)), attributes(output$allSAR) ) checkEqualsNumeric( SAR(it), output$topSAR ) checkEquals( attributes(SAR(it)), attributes(output$topSAR) ) checkException( SAR(im) ) } # Zig Zag test.ZigZag <- function() { ia <- input$all[,c('High','Low')] it <- input$top[,c('High','Low')] im <- input$mid[,c('High','Low')] rownames(ia) <- rownames(it) <- rownames(im) <- NULL checkEqualsNumeric( ZigZag(ia), output$allZZ ) checkEquals( attributes(ZigZag(ia)), attributes(output$allZZ) ) checkEqualsNumeric( ZigZag(it), output$topZZ ) checkEquals( attributes(ZigZag(it)), attributes(output$topZZ) ) checkException( ZigZag(im) ) } TTR/inst/unitTests/runit.TTR.Volume.R0000644000176200001440000000516113425330036017106 0ustar liggesusers# # RUnit tests TTR moving averages # # test reclass works and throws error # test xtsAttributes, both CLASS and USER # test all.equal(CLASS) and !all.equal(CLASS) cases # Create input data data(ttrc) rownames(ttrc) <- ttrc$Date ttrc$Date <- NULL #input <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] ) #input$top[1:10,] <- NA #input$mid[9:20,] <- NA #iAll <- as.matrix(ttrc[1:250,]) iAll <- ttrc[1:250,] iTop <- iAll; iTop[1:10,] <- NA iMid <- iAll; iMid[9:20,] <- NA hl <- c('High','Low') hlc <- c('High','Low','Close') cl <- 'Close' # Load output data load(system.file("unitTests/output.volume.rda", package="TTR")) ################################################# # On Balance Volume test.OBV <- function() { checkEqualsNumeric( OBV(iAll$Close, iAll$Volume), output$allOBV ) #checkEqualsNumeric( OBV(iTop[,cl], iTop[,'Volume']), output$topOBV ) #checkException( OBV(iMid[,cl], iMid[,'Volume']) ) #checkException( OBV(iAll[,cl], iMid[,'Volume']) ) #checkException( OBV(iMid[,cl], iAll[,'Volume']) ) } # Chaikin Accumulation / Distribution test.chaikinAD <- function() { checkEqualsNumeric( chaikinAD(iAll[,hlc], iAll[,'Volume']), output$allChaikinAD ) #checkEqualsNumeric( chaikinAD(iTop[,hlc], iTop[,'Volume']), output$topChaikinAD ) #checkException( chaikinAD(iMid[,hlc], iMid[,'Volume']) ) #checkException( chaikinAD(iAll[,hlc], iMid[,'Volume']) ) #checkException( chaikinAD(iMid[,hlc], iAll[,'Volume']) ) } # Chaikin Money Flow test.CMF <- function() { ia <- iAll[,hlc]; rownames(ia) <- NULL it <- iTop[,hlc]; rownames(it) <- NULL checkEqualsNumeric( CMF(ia, iAll[,'Volume']), output$allCMF ) checkEqualsNumeric( CMF(it, iTop[,'Volume']), output$topCMF ) checkException( CMF(iMid[,hlc], iMid[,'Volume']) ) checkException( CMF(iAll[,hlc], iMid[,'Volume']) ) checkException( CMF(iMid[,hlc], iAll[,'Volume']) ) } # Money Flow Index test.MFI <- function() { ia <- iAll[,hlc]; rownames(ia) <- NULL it <- iTop[,hlc]; rownames(it) <- NULL checkEqualsNumeric( MFI(ia, iAll[,'Volume']), output$allMFI ) checkEqualsNumeric( MFI(it, iTop[,'Volume']), output$topMFI ) checkException( MFI(iMid[,hlc], iMid[,'Volume']) ) checkException( MFI(iAll[,hlc], iMid[,'Volume']) ) checkException( MFI(iMid[,hlc], iAll[,'Volume']) ) } # Williams' Accumulation / Distribution test.williamsAD <- function() { # non-xts ia <- iAll[,hlc] it <- iTop[,hlc] im <- iMid[,hlc] rownames(ia) <- rownames(it) <- rownames(im) <- NULL checkEqualsNumeric( williamsAD(ia), output$allWilliamsAD ) #checkEqualsNumeric( williamsAD(iTop[,hlc]), output$topWilliamsAD ) #checkException( williamsAD(iMid[,hlc]) ) } TTR/inst/unitTests/runit.TTR.Oscillators.R0000644000176200001440000001261613552670134020147 0ustar liggesusers# # RUnit tests TTR moving averages # # test reclass works and throws error # test xtsAttributes, both CLASS and USER # test all.equal(CLASS) and !all.equal(CLASS) cases # Create input data data(ttrc) rownames(ttrc) <- ttrc$Date ttrc$Date <- NULL input <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] ) input$top[1:10,] <- NA input$mid[9:20,] <- NA # Load output data load(system.file("unitTests/output.Oscillators.rda", package="TTR")) ################################################# # MACD test.MACD <- function() { checkEqualsNumeric( MACD(input$all$Close), output$allMACD ) checkEquals( attributes(MACD(input$all$Close)), attributes(output$allMACD) ) checkEqualsNumeric( MACD(input$top$Close), output$topMACD ) checkEquals( attributes(MACD(input$top$Close)), attributes(output$topMACD) ) checkException( MACD(input$mid$Close) ) } # Stochastics test.stoch <- function() { # This mess is because data.frames' attributes don't come through reclass() well ia <- as.matrix(input$all[,c('High','Low','Close')]) it <- as.matrix(input$top[,c('High','Low','Close')]) #rn <- rownames(ia) #rownames(ia) <- rownames(it) <- NULL oa <- stoch(ia); #rownames(oa) <- rn ot <- stoch(it); #rownames(ot) <- rn # End: mess checkEqualsNumeric( oa, output$allStoch ) checkEquals( attributes(oa), attributes(output$allStoch) ) checkEqualsNumeric( ot, output$topStoch ) checkEquals( attributes(ot), attributes(output$topStoch) ) checkException( stoch(input$mid[,c('High','Low','Close')]) ) } # Stochastic Momentum Index test.SMI <- function() { checkEqualsNumeric( SMI(input$all[,c('High','Low','Close')]), output$allSMI ) checkEquals( attributes(SMI(input$all[,c('High','Low','Close')])), attributes(output$allSMI) ) checkEqualsNumeric( SMI(input$top[,c('High','Low','Close')]), output$topSMI ) checkEquals( attributes(SMI(input$top[,c('High','Low','Close')])), attributes(output$topSMI) ) checkException( SMI(input$mid[,c('High','Low','Close')]) ) } # Relative Strength Index test.RSI <- function() { checkEqualsNumeric( RSI(input$all$Close), output$allRSI ) checkEquals( attributes(RSI(input$all$Close)), attributes(output$allRSI) ) checkEqualsNumeric( RSI(input$top$Close), output$topRSI ) checkEquals( attributes(RSI(input$top$Close)), attributes(output$topRSI) ) checkException( RSI(input$mid$Close) ) } test.RSI.does.not.overwrite.maArgs <- function() { wilder.and.matype <- RSI(input$all$Close, maType = "EMA", wilder = FALSE) wilder.only <- RSI(input$all$Close, wilder = FALSE) checkEqualsNumeric( wilder.and.matype, wilder.only ) } # Chande Momentum Oscillator test.CMO <- function() { checkEqualsNumeric( CMO(input$all$Close), output$allCMO ) checkEquals( attributes(CMO(input$all$Close)), attributes(output$allCMO) ) checkEqualsNumeric( CMO(input$top$Close), output$topCMO ) checkEquals( attributes(CMO(input$top$Close)), attributes(output$topCMO) ) checkException( CMO(input$mid$Close) ) } # De-trended Price Oscillator test.DPO <- function() { checkEqualsNumeric( DPO(input$all$Close), output$allDPO ) checkEquals( attributes(DPO(input$all$Close)), attributes(output$allDPO) ) checkEqualsNumeric( DPO(input$top$Close), output$topDPO ) checkEquals( attributes(DPO(input$top$Close)), attributes(output$topDPO) ) checkException( DPO(input$mid$Close) ) } # TRIX test.TRIX <- function() { checkEqualsNumeric( TRIX(input$all$Close), output$allTRIX ) checkEquals( attributes(TRIX(input$all$Close)), attributes(output$allTRIX) ) checkEqualsNumeric( TRIX(input$top$Close), output$topTRIX ) checkEquals( attributes(TRIX(input$top$Close)), attributes(output$topTRIX) ) checkException( TRIX(input$mid$Close) ) } # Willams' Percent R test.WPR <- function() { # This mess is because data.frames' attributes don't come through reclass() well ia <- input$all[,c('High','Low','Close')] it <- input$top[,c('High','Low','Close')] rn <- rownames(ia) rownames(ia) <- rownames(it) <- NULL oa <- WPR(ia); names(oa) <- rn ot <- WPR(it); names(ot) <- rn # End: mess checkEqualsNumeric( oa, output$allWPR ) checkEquals( attributes(oa), attributes(output$allWPR) ) checkEqualsNumeric( ot, output$topWPR ) checkEquals( attributes(ot), attributes(output$topWPR) ) checkException( WPR(input$mid$Close) ) } # Ultimate Oscillator test.ultimateOscillator <- function() { # This mess is because data.frames' attributes don't come through reclass() well ia <- input$all[,c('High','Low','Close')] it <- input$top[,c('High','Low','Close')] rn <- rownames(ia) rownames(ia) <- rownames(it) <- NULL oa <- ultimateOscillator(ia); names(oa) <- rn ot <- ultimateOscillator(it); names(ot) <- rn # End: mess checkEqualsNumeric( oa, output$allUltOsc ) checkEquals( attributes(oa), attributes(output$allUltOsc) ) checkEqualsNumeric( ot, output$topUltOsc ) checkEquals( attributes(ot), attributes(output$topUltOsc) ) checkException( ultimateOscillator(input$mid$Close) ) } test.ultimateOscillator.monthly.xts <- function() { stopifnot(requireNamespace("xts")) # Ultimate Oscillator on non-xts monthly data iam <- xts::to.monthly(input$all, name=NULL)[,c('High','Low','Close')] rn <- rownames(iam) rownames(iam) <- NULL oam <- ultimateOscillator(iam, c(2,5,8)) # Ultimate Oscillator on xts monthly data xia <- xts::as.xts(input$all) xiam <- xts::to.monthly(xia, name=NULL)[,c('High','Low','Close')] xoam <- ultimateOscillator(xiam, c(2,5,8)) checkEqualsNumeric( oam, xoam ) } TTR/inst/unitTests/output.volume.rda0000644000176200001440000002115513425330036017243 0ustar liggesusers{PI5"0E 0 E1"s!'Q0ADQŀŌa^n߭Ny;<}}-Jǖ&f+&$$$,4\pޏ" nGHޟ?zջ:ɿsa7lhNU|,o𸜏&G' 7>-lSjCnwj<cS >ħ1"+7g^6neg3nG 1`7.+Ohqco '7Ү7q+&^ w :9xG1J,~BKE31 d;oR˵uz>m8$ҟ10_%9gS>7 1 \y׭!uO'^ ˢ#v`_,KLTgL(xyo7)/!g;Wtk7M</Gçx8E=,C][b٧ty_Ȗ܏"W>xhKb><㶨`3.hvk|.ܱwcL:dL\#8&|Kquc_v]"e6wT`NQ_ѵxY]11?eI>9)^/v%8yxq}`^SEaܦ0 +Dmx =66.\:]0mo'D[ V3 d~Gc^6 ;<9ukSJ$m\7iZTyJPfܮY9"mnt#lF}ކ}h%!mIE ȋF/[|Nn.u7z(WJQa&kѫses;;n&y/Rը3qEއ9g!F4'uP\^\F>M֋5 &^};<{پn%(fپ)(Hʦ֣#MhiO=QpQA*O] uư \ǫF.eA 30QwG-}-c[# pFjL kSQ"֙>r{s g;؊@lPxژo/}G!r艇;A2#icr vcXmfw^@a%{Sϣ1OԽCOF@aU2uQX2Ojش(?g (Aa_͌Ӝy.g}@= #FrPHUf"wf>yf{!_EĵA1Fe1p} C^Sz Q_PSo8e@kv|c(tl`5zq q Qz<` q- s{^ǀyyG~k>NqޫC;9e"?K` J uAv%g{y#{/9e|hrD0sX$م|$O1 E7,D#er6 7l[(X{3n($'d!)[cϷ08>u3#7 8'3uxӑq=I(̸ŏbc' t /i'RYPh{o*3}&b FlE~wͺWK7tSZ&JZ-]"lf8GENK pjP r }͆0iXP4ݺhY(?96pJ;oj!K[3<\K}Zȑb8On6/ɝ'*(b,VTZH#"DNDTF!RR!" "BDC#֢{{Ј|hZޕ+ɇ :Q!" "JDC#CEhDD /)b<"NiNB`U`U`U`U`U`U`U`U`U`U`Uг22222224"wC%%:;,?BDDD0F24T2!Za ѼD*w'awX%!yVxU"aboJ[-?B5T;~*DE0_lFf_CPhrno@SiP{I ~oJ( 쟟 \ި1Id|Gcq Az#g_({< /} .bΐ|+._|X?TL<OPa*#Zjj5 Υ&(i֞{lp#g 0f p~_< lu[zϳ%]g6zNuYn/ؽji=m \z'{f^?7#O9>!;W2eeDcel#&q}~s9;,礮Y'(pgkJ}U6in[gGL=/9k?OK=^ MT\trPP,!"䋺LIGK.qݷEk㼉b$1'onss_.ڷRc[b.-%r~U'g֏7 Sc\%~i)tX hO8^?3g ϭ0pŠ|ǩϠ\7SsK&)dg~Դ{T~t/ m/3mfqA^4hhpܰz+ )Z9 P.z JzlҊ@X?ܰ߷~O+W῏+Dw=:#? ?{PI] rwSz ȟ/..#]6"7"4Tg8—T)HS8N)ڵ5eSレ,KkH BinN3ޗnN-Iu}ۍdAmV_$+%PRKAECÕ=֠Ԃe|-p}_U7puG߯9~32W_TW+W 6U gFI6Jۧrc@>SM#rpvmlQ7!ac1&7@Qn]1,'ϔڒc_wjԐ("ZtX5]A@ߤZi0-|ukz#5Q?~5TE5w,W,+5YK2LAӰۇu@CL-PX^m]P'4q%Şw.YzYj۟o uf!_H͚ hK/[ A_;y=>:k^o[ϏjW̞zD=muf_KTkPsx;nmʏO-[(́fwWNUyezA]O^"vhzfhV}zШ k$͖fq'zx+T_l.uk'>-τ:iic ӓG㄄m@ec۠+BC BáIEcAݫ6MluvCKǴ퇡Uёՠ՗f}*(v;h10*ն[ [Ʃe\[B@"U}:xq6d%x2hPl7=ZhS\3\{s&Z8Zx Z\r hur|pʹ\gg<2Qʆַ뀖%+amցyhWuEf-;z- ͩ/s;WU  gZ}i{9}v.ε_m+?m2+GMZy|C !UB'J;[hɀ/>hjäBËZiuP^c5 P?zǭp1{Amo8ђ>+PΥU'^hh k"R_eh^ oV0. Z=~84cGBC5;!CgXxAj,LCԍݰǠk(S(5v ܘV2ꚇgC4v𗌃HiVPiA`M4Z9Tph\:0[w>?m fBH)gOn~Ccv6ul>qwpYI A8fZpSP73i6A=uy 7B9P[&!wmU^x GG`Ռ{3BYyP39JOS#tz޳*Y Le'> Xw悦4ԖXuMɵD꿴[LmY B,/-؊m߮hJZ͠?iR{m; qZW{h#h'4wX\[5WZ)E.ꑜmghm*ӵl;V4h6#4w¯ F0hRٙ U L-Ѝ6v%Aurw/Ci=Z֋UBK %qƳja>N=h<__ _ __锯__!^O5(_]C|_|^oA|]˅(_W|]?FS΢|=!>z_|dW _/|=y)_oᆴᔯ'PnG׫)_/|}떔|݇u(_O_zѿ7}C_k~\WS@z)|}/|_z_/범S^ _ _w|}<;)_7|_;~(_7D{W׳)_뫆Vם~#M_뱔+_饖=!ʅ{" pu?+an?Yp2q»|p׻ԲTvz&v pW4wr&Fl S@ N;]&-h @B#ȿ~}(_O=X}`@o)Qzҡ͠tHyA/<ė߱%>/yx#j~gW>A?[`;al:{E~~xAW05 NM S |_c8>߶HݫX q^9^χ0 tҩʀQJi;CmAl[5C xy/mJWI鯋=nקt_POpN /:'QptBI>xC@ kxo)y |3:^~(eP7!oIvm̵VP[#zh}oyp{fgӳqg+l۶՝7WaUITTR/inst/unitTests/runit.TTR.Volatility.R0000644000176200001440000000462613425330036020004 0ustar liggesusers# # RUnit tests TTR moving averages # # test reclass works and throws error # test xtsAttributes, both CLASS and USER # test all.equal(CLASS) and !all.equal(CLASS) cases # Create input data data(ttrc) rownames(ttrc) <- ttrc$Date ttrc$Date <- NULL input <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] ) input$top[1:10,] <- NA input$mid[9:20,] <- NA # Load output data load(system.file("unitTests/output.volatility.rda", package="TTR")) ################################################# # Close test.Close <- function() { # Why does the last two checks fail if they're first??? #checkEqualsNumeric( volatility(input$all[,c('Open','High','Low','Close')],calc='close'), output$allClose ) #checkEqualsNumeric( volatility(input$top[,c('Open','High','Low','Close')],calc='close'), output$topClose ) checkException( volatility(input$mid[,c('Open','High','Low','Close')],calc='close') ) } # Garman Klass test.garman.klass <- function() { checkEqualsNumeric( volatility(input$all[,c('Open','High','Low','Close')],calc='garman.klass'), output$allGK ) checkEqualsNumeric( volatility(input$top[,c('Open','High','Low','Close')],calc='garman.klass'), output$topGK ) checkException( volatility(input$mid[,c('Open','High','Low','Close')],calc='garman.klass') ) } # Parkinson test.parkinson <- function() { checkEqualsNumeric( volatility(input$all[,c('Open','High','Low','Close')],calc='parkinson'), output$allParkinson ) checkEqualsNumeric( volatility(input$top[,c('Open','High','Low','Close')],calc='parkinson'), output$topParkinson ) checkException( volatility(input$mid[,c('Open','High','Low','Close')],calc='parkinson') ) } # Rogers Satchell test.rogers.satchell <- function() { checkEqualsNumeric( volatility(input$all[,c('Open','High','Low','Close')],calc='rogers.satchell'), output$allRS ) checkEqualsNumeric( volatility(input$top[,c('Open','High','Low','Close')],calc='rogers.satchell'), output$topRS ) checkException( volatility(input$mid[,c('Open','High','Low','Close')],calc='rogers.satchell') ) } # Chaikin Volatility test.chaikin <- function() { ia <- as.matrix(input$all) rownames(ia) <- NULL checkEqualsNumeric( chaikinVolatility(ia[,c('High','Low')]), output$allChaikin ) #checkEqualsNumeric( chaikinVolatility(input$top[,c('Open','High','Low','Close')],calc='rogers.satchell'), output$topRS ) #checkException( volatility(input$mid[,c('Open','High','Low','Close')],calc='rogers.satchell') ) } TTR/inst/unitTests/output.Oscillators.rda0000644000176200001440000010451413514575725020252 0ustar liggesusersX[. O3b@3 YbV ME J9g{ҋmݗ~X9gQU1(;}t`%ca%Bo 1';8N|`M>!bql^no)"388U}dġVeqfZ@a ل#TK ֓1b2єQ/jCܧ;Q~ |Q ?Em H9"[Z!ޱ4 L[+lW胞ǣ Ġ=( -pnIc>>{DF _K av'ne-g4ǪnP±ʟ2N .w:-Y`V&=+2[kմX~Y,oeh|J<\XAΛpXӾUN=X{|^2G6v ֜ ӽl???EњEXLGVdXZT:m*@k' j]E2bi/Blrq}q9aGbUhX2 Ӿs?t{qlP Vߵk%6l[G>g+skQ_{ҔYtU6)Ep^f)_d si.r(@c?5еYs4^~ayН%pAV>ؙٙs zf[r OC_p{0 1R!UNkM|ܻ ~}~ qL97J+[ۺ/ް֊tUS"xUbqE,b ]EUqIzZaARb = 78 ]K/eyʹσCw'㲒=@.G.b8/q9a"W]u^~cm.}fIz5;.[6i`] 5۱;95duᕅ؈N.6f?u_]*#6 ?wx*_wۅU?3'bXWo_(|%(~[.[ ;()Q<6w45#i8T,; +fwg)>;%rLz744Bސa df 1 +5AmSnQ[ap⌞0xRv$.tPhau`$:ڠy̹#FS[wNYծZ:t4E[mI>b8dg*hZs vJGOk엗T͔ij϶]mx_ƌ{G},:TclK혒:V_:s Up`)w45+-%mt,g\6MZMƵV-Py3 "_mrg ryLj'pK< q]Ԩwx[{hе`fh)H!^_6u{ T3na^Gݍ[f}qyf_\ؙ-sg*Nc>ܟ=8s65Cj căohR6οw F)GYa=[Bmk8F~Om ?CWVךzc9#;#(o0>Ĩ,cA'^Z!9~\~{9uFbnnhgx`qK`.a67 86Z_ly /N ggX ZB8OCwhu"߿ͧ*hQqKhtVuwl2UGu&UmPiNՐu`vwrv7S`G*qPeE{uk24Y͌!_!Gú.r]ŷ2^)tgB wVK Z,mUWW}`e]c}ZQ׽LձR~{X8ޔ/QXX|f{`犖̎ƺf\06f\de]X eWKˮ7\uT=6th[! ȦMXa{L?ͅNgȉc]Ǧ?M!V{x! V翝"/l-XIȳgGN~2d`g~01.O`S"Ţ ?LS":B휹ݒ%vИ0pmKJXfNGגRU1Z}UݽA|/yl\W hۑÀ>#vs'׹=ݿ#:u" dk??FN3q- 0vKxs|9#y[0Vwl+bXOs)b s"K_.cs>YbXp#Whhශ2W,y$(|Y+\vָgAuWbX6`?kJ*cM+]S2[`UZj'?꧿펃 nd}P|& _o+(lSRlA($=`&֞68\p X5v %ځTt$+ k`ru!\sXϒˋo&qjVEr׊EX>]Ze,Sv" u+VйOukv:X@YﶤIڇ|lpZS=lb˽'w m=\ZbV"`YSq>s#O_LN ,MذD*u{-[ dĠKҀ\0tLЁauНtTI w5_ⵅKBwGnW{u++vMgu[OY[49@~Ckk3ae%֑?yu# L! 5&V/~GZ;97{>5@['n!ЍfO+KÌDY.}8@vTr k/ ClŦ*0F  RFl0GO9>w ?2 y!i] ?eb? c}QUu=XO؟y~FSZp%qjKGfrC_؋W{㳉Hlut@lн=T\'?.z7 ^ x1ڧ#Os 0 f 5?vGV{&!۪oI /*W5O{'ndq[ I[E`mZj!uq#UYU ֣PVǾ=0SM.: yWk55&J,)aWKflǜzPXٴ'GMc%A뫶M9.u n5: ĝUJb'L|OJOۭmRCX Js<(db"X=sl89^Ŗgq9mξOвĩ0Wؗ1x3dKN ӹ#b0wnӕc7I?I~Us6BK'rR#l"'Z _!'l#'>("'v,!'WoHN t3,b8WtI9)kuh~x`H;"9)WsrR Jh8H}іx19)?=w 'eIg#tW vlFno+C֋B=3Ŝ7/_cAϮm .f?_¯Lk4wۖ8msǂztXGVZ~/~kT%zW>wƏ*n ՙ< XÛw*ͧ9ǪEza5iTz򼱆`_Y5&)h{| k Tō5mW 9LOwj4n&ܘU{o.U=Xɹ+XԇB xpdVGvkxWZp json\ֱK|s꾶ZFK: vJh Oq辑]R]=".I;vC׼ q7{ˣ05ҝ} 9%־n=' ^U[BOkfc͚& 蹫m-J /}Riwڒs_p(; /w+@67Zw:\Շ0|99GF>q!FoE7OD#ȊC}Q\>HKA͕25alnma$Te1 F2`mzw rL51H\7ɽ6W~ l|賎 MXz}-EНư\ޱ> g/xXo:+~l uwI-|Ψ':V8)|ynHöצCTI]ҐpNL 4gqV̑FmF*di 9'VeAu.@f?e!"!.(SV40'{cžX9n^aѴVKvBV/./U`ɏa-GĹbm) :ۻc6DžZuWx8W0,5ʘ46m/!֓ w=Ө60]hsTwlzHn/Zlpʹ1ilUX%Xa2XX+XױT^45v6qbGޛ=zȋș~1+ y(͆>5.z2XwI"ϲ]{nAKowy/lo4۽b䤀V;4&pfo mK\&'<''N<7}|iy|h)h.CN $-&'^ '6%'RI͏J`̘]FwPw19)gs؎]I)$q`Ӳa;9)iTIN \Nf#òkI֌9II7ᒈ%~l9)GPG8nY{1YL+B,*g:r -h4!hyCn`n<3=e&dr{yA+v^IyV0J>]JnPAnPrNR= jB?(`T{ǡ9PO6_7Лg=Cc+OѲR*jMUPx;@e{$/_ ):m-C[o,RD=q0 ˜ID~.zg~l62_m!7ճ8ˠ{똝4ٞG͉R@A+S@ffRhnQ)MJzB<МQ%j ɭ :IAVBUB_\bo:RRC3&nxRX:?WlqV wS"Vg\\#<ɭڈ(chgOb21Ds!C'Gb Eg9JA3>{gkPCnlFy"2q.s?q5Ff;'[!>Tf? 05>'X&di PDK3NN"*~vL&渝5_Ƒ/WChn|z Y .NN`"Rvamx^Ll}"_*HFP7ѿ3dPOş|a@3~nM㲟2{ǂ#k-,9?>d/wZNO%*R::v [hcJhfomV-vb]'Ew:rXA#{RMTS[aN6gL;@`|繊T{yYヶܙNU$&, ߱Gz _c*n?#, =_Y mȸ zhs)5ڞmiՐ}ںQʔкK[5Nʟ/okhCnDfZYWuWA[LCSɘ %СjkVZ>h h)U Cj"Kq$vC%3_͂?@=*PNu?u|>Tv'+kji`F^mk\=_=?;pimy!&a '$ C1 9s!mЮfOM ug8P$) j[ y;m/f? Jw_|GO,_kMO(s {ȖФ1ǭjHP%tW7/< ?ܸ~W9e1OuT7 =I?﮺04"qmrV_4ssc;qjwd̞by)/%'ݣ/ǎYPż 2Jh9xT5hxJЮ>B?h[Z% -Pko z]dsSyZ}gg^Aк ˑO6I, %\iܻ -wbCCD7!KudT{.^} ^C)3A(W̼rV/[-?{T޴z$u"$Qlw@]ݝLZ6Ps<U]ф,c eQbsɿ2mUOjR6 ,~ym8+#oCͷu[F?c6v&v& SHu[7*M6.M6gIeIFPua4V:V:Ru.!>rxnSW|z d3*UVt׵^q1QSx33\*|B8x"W ~6o y1bF!gB ׿ej(| ~nn 57kBrr%d u1ƞ1Tzk)+؃@s %Sqjsj䜡xP`7Р֦ok7ߺs#z.M{VKy<3~C%FhI+4դS"1Uߝ7}j ڙn -U.>ZI=/6%lм!z 4[v3Ŋ,۠ U`1hGn"|RzkWBUiIh,g/"Xn :ĦP9mzH[O*YBfGPDuϏ*x[鸞 m򰩬vkg!h[ض]kcݸ -Yv %%{e'%Ձ7ՁÆ)w9M t{_8ǿ._1SԿm$ͫ~ ꟔?)?|~A;| 3f7HQ8I*[T:rAudǧ9&O.m\;Tbv5ȺJ^\?!E|ʴȧkwDFيMI[ ;1+HRYb4񦐅 C-[Gy%5?= }QO#j:P?R4}C)UMer>\|ݝ2 |<EGxekn^Prd(To9Ę5nP/54l^?W^MYnl:4*r\h M1 ŎsAcLis2b(;?]d2='6܈yZ /Wޛz̛R?-Cfz[m8ȩc3-m9a;nR=P\:4YlЮl[<:9r}~ @k{TG_hf11--t* b%hbMP%M+s^zAcM!hlb9I몙b(LQR^_x?wݺЫkM)F]àξPčPD>pTzq/1VIdiBU[%P9(?Sws=< k,r#>mђhh:66t<"s뼸npl ]7W.9[R | RI2BǡaURpxh&;tm?mP m_oɴ̓^›T}$Hy2V嶁1 b[A\7(\ĽPtW0 (r9] c[vBXҶP3ԻwK5m&ƫP->jk\N5S3@U{E0}r(_2mFj (3/ E=e *E;:^CI6PsMdL^!`b1Khv7*ܡV>Ήݰ G xT]#rT2:wHֵP6$FL_}I  gʻMPA^:P,3(|䓧c9nˇ4ړK _D4`U3*vz]o_\%O΄bɁݛ @e'减Ppa 8lw奲MnP˜ uH)A#G*P++Fo^ehRP= CJA> Ps#2Pg֒[,mt z]́i{:)ht}g#Zx5'j+~iy^[aMhg)hFaxhS3ZBWMᯇ&/@b+j᭯ēkcg4/61Hpa Z|~ 1te)i)iYFiheFo4M#C%@(4#K;,ﲴ#Kk,\.W{d %M#O(44MoYFo54 BfgBC,BfU9UhVYUfU9UhVYUfU9UhVųr4;,Gr4;,Y^miFyiE[iBfgyZny/iY[iE y/;[hWY^fyZ+b^ /hPż-hPB Z+b^ /hPE 4;+"\iPBfgEZ+b^ E/ivVż"-iPBfgEZ+b^iQż-hPY^JWY^fy%hDp%hWY^JWY^fy%h1Dy%Z+|L2ʴWż2;4(,LyeZ+ӼL2ʴWż2;4(,LyeZ+ӼL -UhG /ThvV(PB Uh@6 ThPBfg(P/TNjdi9FQii52#C;_NjiZ{dh푥KwYZei푥G~.Z+мCðFQih5[^'5r4 ={aIߚb^seh8WaI ﲴ YZbaehVaI \< 0 ÒڹyYiVjI \< 01 +ud꾝Ǎg)ƿn_3I[N-'間t[cnD}tKI$rn9I[N-'}$Eݲ[ަw(ny[VQtQn9BRI"rE (&E 薗)3Ed(e*E Қ[.@-/StuR[.2[jRtKcRtK!nL-(e+E(nn)2NE[薋)2nC-u(eE\G-Qt6n[&StK Et薑2[ZStnD-)nG-Ptr5E\S_fSOw,}+/y‰˭y-z|{+"ǚm4{wUKZr{Ђu"y§Bpl#,_A>rk$Rlth:$6pXII9/)-y㾮>]ؚ4p4Wr*jHi׳HĜ7+7 ].f۷XǴ3NHм\ -ygׇL,;w]=nϞBy[~̜le!ꔤsgdϸ\3-$"-3 :~C:D&G32j8ӭ W>( ,6ڏxpd=rX2K i-LAZ+$NIuإɎGT5nw>k*Gʾ'zFo?͊Vhzw! 6c5_!/>\жWr7.t8K1Ca~&.s7RQh(.;҂Sy}.e}KF0\\Xp]G\,Z\-+jލJdQ6[kdg5wV7gn.rŗ \Ά/ڠ̲粙6m/}vT%qzhFSbehle4cwQHP͈>W{/1{wq~#'>.~ \<dX80x.lgJ\t>\\pG"&#e,T]hxŦf$<ŠMD;zyuFsGH}7v". @?3\̥i*ӃERzD7H[`3G:3ߜD:"f #m_->+H_VY_Kv<\Xp GyG#K-C2g?Fj}%ʐcHewQQ>/HUɫ 됚q Rå4Ëz#MHke5H۔ Oƍt7,Gz#Wu!c\.wl@Kt9N"Wn\'T#c du2۾Hz2Z> @mc =W‰3=GFvOTϖ!hs>خ#“ېʝlrRHpmHQ>ung-@%л)7rЗSH]#y#ZU3 r#$G+W8'ZW"pT}UľuVTRAl͉Q=Dg]Gͻ^hX$d-TQxJ$l} 7Z˞>΋$dyrsZ\{z^CA\Xz W|K?ⲋtWwߍ|W(X_WkֱYAଓ5zqUţZMhD7^n\C`+q#lk;bNzה9xU;n[ W>i-?Wy.QF{q\yO)~"fy"UIj>:i"4:޷ef!Ub75GE]V , ؉d_RX{,y9HooCHfc ]'i{"Zp;b~i;T2ۛ~?*ӼTatd~ʦ <3;y)w}\^.җ:_ʎgA|= cJ" (>3j"vj6ϞMlґusf>%dəm 2}sJC&5F6|~ t֝AO ߿{ 'kjmjHs_8yO}"C=EOS o:i;# -ՒHۻ}H5;!!6)PGWVٺ!Y_vq \4W(/ի[T+5ٚlm*{~b%Fr÷rCm<4K-)Ј7,a8_1cG} kw!HtAui+i=ءa5޹f{iW_ |~!~l Dbk"[Ei"gy_xb=l[ҍ2f:9 ߆t/x"mޙ5ڡij b,u:\}W)ٶ(@9cZvH[eEi\H1NE\(TvL6.#.4YʖL o!WJgm ϡ V<*OTQ9;ϹB:zygDcH <(My [ήt&鉸*W ؾo'dv%U{6$}'l(l/tZWd4W94kЄ6˫/dS>p?Ic6{u%S |<BrKB ?vd5j[[ eHjAg7#kjSbd&{Gr8>Nx{i}|.(%_j˽4%'I /f2++r$m.WABn/^L\ȧFT(M+ִMlh\z mֻ֛̮|L'v|𷜡!LXoP O%.y"D̳/bnF1]%2b07I6a_&ZE<27UXEmI~ /(ﵖ ;s($aǥW_բs\m =w?oaAڹ oث/5kHo3ruoxNI>7AnJ\CxC~_aNo$@݋g_-v#7H$26 ;%^^=ݳ'C* $?%2! /u#tK$(c\oI4΅$;GR ,g &̕2_= > t% W4n>Zз@:?RN]sȷ1.ʷ0E$fVPS*e?_jbbv`corbϑ3PгXQjOQ\4\a'qEьwp ?wxW(XmWjsXuu#\AjCx[\25ݪť_ |db]\T;6\"cmKKqw?l%o\:c'.q")Y\|LM9_6|r _;8O~sܥkؿ#B3l?"Y'vOSU+ %/5v  ձoׁhn1qrz|cO܆/9|[$λsn\"KTO]Hl;u8+2#ɞM6yJeO bߤ6XnAe> VfőyoLozl[lÏBζ!c:h޴S -b:BKϯʇ4dr ijiLXꊴ^~TGڑCbg#H03eҙ"" i=V,BZzy&JH̳?z?FʩV!ߟ~ԬELE*`5 n<kMĐڳvi6H}ֳ_ot%]~|{M;̃t}"C߭Y{ ozhU9QMׇ&v#WѱUKgD%3%=o_t9 ڑmrF<Wt$_GY/w,W!g.U#m׵=H5g ?SiEuB9Rt‘Cg&β*%s/I6=T>0 u;S{Uk]!? ۥ sfijDB,t~cJ(}6jbMʹ͙YJ5z?l.'LsmIW÷R89D/g7Yqo7]+Ã= b8ҼmonjKV銵ϩ؟Z=ptN_C"ܛzj[r%b; };8t:kccױI﫟?[j#%W3!bAAQ/QIg< =&Y:H/!cL}I 9!ъ=I )-7Iw %&U12\1L7g$oQXEbb$߮JooI M"4c#F &?sMu93L{  ?c6# E΋`cr8tqlIE:"ϊ!mIG-"8v"=KcY"w=o"CΉg~WYh,pzL?L_>_Umj͐GCG C/T^h\~|ؠvBoAr.BH.Rd +$cH_kO(ҋxX-.&r2/9؅ &iLAwe@zR p CT -W=O|#ݔ7vͣH3{( J!HsYEI3!1E,Ā x>핖шLg辺͓-6'>T;>,ٖrUMFekCf_[SL "OG82ZʎLknKGEvqu>!Sڄ4=+2wf1TA&v,@&a)ˑr0;$+̭QB&Mk&4;htOd뉆wd~-k'+L3{, Gʾ,YȅŦ܎bOʊȂGewO^= ?_*!#<p!q>^VkY~F!‘o/r Í63W#-&ɟf<R,6J"S"RB"i2>̹~`.#Ì56-qUt_hTJ&##׸ V` DF ~ߘKI.2v7I s=vdpFy0QC%ߣ_>B*~;A~΍s2LT8#iȨUB2h'S3͍|* _hWvΫd-2p_7TːsvCOyiÛ$Ocjd#(c=%? /IB:*UH=%ϑ61eƅ 2Mݑșo6 s^!nF mL:gR/znB3s髒7HvQkҽҟfȿm4ȷ:2Po\zdz02٬%?g G̺]=E}ihDs?BUWMAFsn|.8]Cāo}ExvӈNń4\P\س"_}Hz8z YoS̻̐`Z%J֓NVd^]*L+dFw|w>Z;~򻍓mBZf],t#|0Kb\obַ* k6_~GV7yt")d}tQWzXs#QǖIlϞhndٰIju +=)yyeﲐԓeG_^Xu Y' Z.ȟE&/ ws0`E2 !~]#=FD~Ik,Wy#mÐJ)gyJ)D/Ox'a!%#7]s2C&wӒ"vA+[#sשy(cN6dlV{ER|2زfUH``o\΄MѲf8ϐfVtgKg@2+oԕL>#f%ΈH׺aQC{\};k,9tS[yWo̷ PDF2U"|]jb 2T>xzһ$˹x(]{0!u 8"yx!ǦA*VDyb/k }^Op[-2N;,-L" ):"NGz3[]@7J|Xf-2dv4FUro@Evw"Doe;U#͙ |z(M3jBjG3zʐԅąyaTEO)_VߓYy7"#KFլd^F2si(kDٙ邏_JQr2 )Z2 V,vtdQR,lPa)aAm0سXpASEnoRRڣB/K()@I~d=r{wGkE&W4B& -퐉ҝ*K$%$d²2yi 4#,s)΃v/WFO$%'Q9vL܍, ilV%:1en{+2F }{wȲ+&WuQ׹\u {iuٞV-/IݡGf1yLGHW˒i^&z8qEKbĸ~᳢.Y'huV_eHO󲮹ҏ('T u=]^9,}D]o99 }6Q{9۟u]}D]noJ%@kD]q{nQC;"8kjI١nGӉz\YFIVK{UAu [&h}->ܕ—Gn!ɡ!k܈t{D]9w{gJu" _]Ae7'$QoV%1Y׫uJο7u]ܜu2Y׏z|Μ[Ⱥ 'yׁu&$Q׿ͱ'RbNvA!Y+.<%zY Yh#ztTYe!z}d]WGd]QgΓHa34|t.Z| R(T@G2 guP]ke\ɘg~\pip%su5ijBqvjv짤QaY^X8x9^+0oR4Rl|Y|OT;?}\__\;q)3qGMa>Xf~_g_ٮA\ aK\RR _|^A$|+lު 1 _MXuA\Ӆu5~4\:\}ʃ! e[U$|0rl}qa9 |74i|c>92xVEjL;F)? EL93 [4ETи݃Ѹ_){Mq{kLH"%"{I8DL:Ff>e>Z˴uj@j" nW!EF:AxkO1~ETѡF_Qh)5~) xng?8mnR`ړ 0_1@k\i ')3_Sn߳I7Sd 3UOƍYy$Δ񸟉C_0v9pM1J~xxåmX!D7d> 7b>HWM^#:?n\TyjO.G~\Wbľ%DFdHk!Ľ_C T,3ă<0Mq Grێ(QyۜG>TWAΡyRKnǺoT!=tl#mf@FL?Pq@-x=@c絙ԛ1!ut#6ߚ~<}NjoAL?8r܏Țٞ dmIbd`GRvWȩ%F\#Hyw"n_2/`wu}Oɺ>Y'd]X敂Xۢl72+peZl A'6X` J4ımX o '#T69= {}]!goR1yP2m4)Q7dq X`n«XBnQw"FS][;(f3aa y"HA{z0{Mvߋ` yMUo׉w'ׅQr+2 vai7},O?ϟJ|Omf`WDeWw2`^Wa>%r\1^1 qU1.|La`=0Vˀ[]pxbK/N؆ |O9qf!`> ]X(hҮlOd9\h޻09aẂ~c*>]ۙ\1lj'af<c|Nu `g1?]1]6=5Pq{1< 9.j~@3.1ǘ1XxPq^vf?|K|?Uxq,l7+d@x\(~61: 0uX y| }y~Ele΀wx qN~?Ol?GA|Mx~?9j]ⲝ10'8&0J->WD~ xK4FQsS] iyɝqg! BPqύk?J*3Au"u1w'iyπ0fުO;#1ӂ2csv~ɧ]S*OS㾆l=W8ǀcr Wu%_DǘD?=T)?30?O->Bc>Av<ώxn"#Uq.`LԵ0+q"7]y(;9GUo cn&qB&B.;8Wɺ>Y'd]u}7wix7:>H"]1oլ"J؃ΙQĸ^ٶ~'K[TV.ܔAmluF@BnA,E"Q+¥i —WK6`a몰0pľmr ~6X(ll?,d`[:8/&UXHke07WaqAXo{zPz=qfNRN~X”P #/ū\~)^\``11k>!W|?6Bb*\@D^}AQ*!U뒓Dw+Xl/"Ɲ߯D]ʡu]!Jf:NW\+x^3I|f@b}Ss+j ݚR-ex4 ۟<Ucu8!wԇ{4'^#HVK|o~Jӎ +rF>.>\L%|Z*?Hׅv6^ܶݮH2~CF s%v0$hɪ {6lkd'’jhh6TVVu2 FF<ۛ]} *Z6E#i6wP3b <hy#!B땒ǭ3Mg`n3 {~Wxι5<||=3r= A^\aVepŞH[R)p,(O >L~q2B_5>b/=*p" MűbsX슳w.t➟UW}nNHz*,W-i,Rα*,fMS} ,s>’-iÒj= Mo K 6-}K̽6_kװb8\m15ab ]jtQΉj%5ҹXSa}:Zhc]&lo F"W3 `ʅuWJk|y:@}y7Iys7܁/^vAakBW(x| 83)!@M ,)몱7yf;`o7]s5{kj3Bl6޿p‚77{*!^FuNbPs︧K,DN,tPNq4,7tw!|aZދ!,kJ,,WinbQ+E˿12$ IC!RsdkuK4굻g_wDZ‚3!v@"$IKy)I;HPY-ɏ/]] hO R~l+͂ŹkD+?u:Jb/)9ij[)4ҥDj"!D3 2OY^]~7^/Rl~'duz!7؜&O.`QD-="ffș[ r?jc(A C; {|]qDCȎH0 ~ʜ(5GmBV7ϥu8 YK_ >o /_WwoQM_+@^>|CHxs{%0 eyϝSܐ*y,^cH1*x+tC5)ѥ&G9.2{^gn*@On* ~BtD-R V@jqխuȁN9]l~(hŬ݅g™Y=[N/3$Zqn5wU!|YŲJU*أ5G1v / FwT71igBҙ%Ѝ?vcgy{nEp ZS` }6؊bq6paq:]X\ًA\Oϼu%{e,qqѯ]n`b]|RDʨH)$E ւK_6 = 4- {qW챧ש 잹˞봽3^_µo_2xeZOZ>MK|=ۥk4C͗ bc@w/$?Ҫc!q썰Z&q] |5H1WPTlM&5cfɊc~k~GnS)!k<>^<6;ٺY CuC\'ng[keqxLb1^ pXS۩=+_r 32݃@ޕ.>h-LĢNbj7uzbQX"-vG ]Z wۺ ߶i3ެâG|nl4;zn9lXK"a~]ð[덲<-h{/'inURk$B]SjI pD20{y}h+mŌ]9spAkgBǍa_$xD.m\­qtrI?$޻B\Z@+b--̆п 2kvvK^*/L u/uOO mm#?HKlRC6," '>j%[-F[H{@&[}Wn7CӆJUBz)5_0콅6<[qGZH'ʅkw!c䭖:L )W  캹;+ȗa)%sAgJ sKu?i k!m)bwWt!?cQ 箰Ha@ȩ t~5Cho}g' OnQc ;~j 0B0w8ʼnJ_[y@+Ӧȟ{t+|t )/y3z|F"H|I>) +H/!aJ c89gYȿ8wAo-A2=D %"gKe6f̦Ż ˠY_-ӨD mI;>ݎg+1.>L J#n\[b|_G QV7'p 71ZJ![ĸz~q"WW{jC υF®_'M.iob@;]/"r?s^b1EvqqխD<|K@+w_oy~=.EWMλ _q o.%|"RH䟑;,6 W\DlBy$7|*@ VHMb_ڂ7ğal2N"Rj3`_EQЕD.{lb"O8?n8H?6DW_]D.f#[2He?k;$_)H"D77tuɆgb{I䯽jtlN"<z1)'uF[E#GigxXݯb^ bTb7hLMbOq J\.fYE دXW}^7ւEjE!E||FtVF*RpKFiA_j^UXBKa#{q*b .K鬫_sZcHz0 Yԥ) OS.2\zfB O&2B$$T_J/ȝլ !|Y79m>/ؤw"dd,!aɮIm'!w;+#gUAwC-'C{EH:σSrDf'$;yڽ߮C~K,He\OK3 g:͂\Cdv-z!h9]2ҫ[5CF#oR<\tZ2dy)] Y1gv| ي_cȾmW4U 3\.^&{GD㘹̋ ޲̆p3=\ᣐ]i'1 !3agr_ yuzͷu}ޟ!w؜ߐYv 2FSȰ X!ajxFH+Pvu|(6> RW6E?)Fy [Hzv^y1;$f:$ A 셍P/vwğ?C[h=abCK nB Է^o; jJmJ5 "$\6TȟxAQ4۲sjEA|u&M <[0 D)ŎyQr.vՀaW<fی~e-3W[xכ $co<)N #fXdz9P'u|)?f#ɕF?28vEAEڙpȿ-YGJl#D[mx<@>@'*%d?!ڭ?wF=%sr y7^ C R}]׌TW!ӯHK@3Ku hb =G?%$S@oQ'&/$KG[N?J0Cۊ _qζ duP-@c?y\':ȟI52!QH-$?u!-B}ڹǼU RzA _2HShz|de!:(|B>3} yvxŔAxN#,=;>C1^6k(g U0huIC' `r5e=W?@6 i`z{Qle36bvMM3O4zB+yS396 xBm2R d7JB㮓NCD=U~{`BUp| {C&d=[ɒI*{L 9([T0I^b&w@b_ڛ67Ae[̼R&mʢW_hfޛ[{CվvVGyOwhc۴dB6 cϑ7HC"yϹ4JffR9@&׼JzCYEYP)3 nKB#_𙊷-!y5lhr_8'~;S'D0 *8Pv :ظC,՟?cJdS_˨vg8@[3.'|ڽcA^ec)hTu|ŧ2TenPCnM̢=ޞ#ӇV\_}xBV e?FfQ;g3^n61>ĸObkDe\`AjEP~t*%⾉oWs@A{9U@;]W-!tL?(EZ 5|cՐHȾHor=5pS.һ̗:42B$4r=zlӣ #c釯IwȤ?!s6"TBF^#Z2qTWȨ:ʾw!â׫"؎#L.+/k:J[.>I9;~#]sC nx*#SE_@58#mbMlI]iUؠ\2Y׾12dvPynՎ7l~̪\|.dwA.O߿L7&pAI5 $E©0 dd}BY2oo5D[/-4@gٱ#>g#ӪSM ,42_yl#W_#'|;om&v2] {2qX·oW 6[/lG+;N\BW%8&Z/utenJD 3oƇ27!/-v#<3"mX #-!"S撠fDTdx/t4q!ɍ|4Iג4daoݛ?'"cC?\E^^,ksBittޡ )d"z+C~9=B!V@/xL,FO}K3!3Ҏ/G8^yrwHOPd݈ EBҹ,Сف4P`ZF|G" x `'Zt+Hgiㅦ='?Bsp.*v-` 'ҏZx__% w"8מx Wywڷk8J N6ÆYHOiٙH_ϊ# ϮLVD;*~y^De'' _[#zT4*xqҗvOMEFY!>Gّ삥 kp2-wj@+ubE#sϠ;\9oD!= Wƽw'Eq?uAM_}GEF.z^}d7m;L}2<@&1oAOqs"-: vr&|3t S>i d;n>6d u5wO'qkǘ*2|ͨr6&d8~M FJ\t[粍"]7,["3 ӟ)"}Y\/h&_L˟?5/j&_L\?5/j&_L\S3frOL\?5/j&_L\C3/_?5/j&_L\S3fr>ű!SMmv;I>n}qSȣ#YYy=☶#Xy_{dkx ?_}C`a778qs(Ôb:CITTR/inst/unitTests/output.runFun.rda0000644000176200001440000003421713425330036017214 0ustar liggesusersy]ӣ|q<zukx\{U[;''@sA.^^P\͟|B'Nֱg|{ _kb%B !\ < !s1A(h!˻:J6PѼBq+ʮ5-GѬ2b qLIN dI\鏹̆ALCθc6.mшCt[0L9[& @L7b\zIA\'EL b )E(RҨD!T=Ey !D&B :P%>USɸ{dbz; a.x^o9@b s'n܉҄b*Eʜ1 R|&pd5bGL.3*vԫ`<ř?b"&iŽJi$b/GLI12O8rgFTZ"z;bX)vY9a="9j9`'ʳ\ HksJHzs_Ī#XdX>ν8R r:&_n=_T\"[*!{6Μy-ߢ[AHSDٕ~YD`8!V8'~YޜxfYL@,bp5Ǭфk0'YdXc953n|GLҎ1yd@ɝ@F{Ḧ́UJn~s\z?9%/%CZvj ĄUm\[+R)jX!TsWB*KD;@*Mz!9Ox@ $\w_!4&~ϰn-@gm97Iaܖb]1|W,rvr'b Z>>41%6tۅ9/գb*<BIe"sVٽQq)w1,1U+CL ;qES}G\,~⮴O{Ą@=%T3ȴ)bΨoHш2l5:bIB_u<qbJ Ԑ[{>B~6Z^CvV!jϷݹ<ۡbc'#ս 2s>N:/}QeRKGcNZPzE=:ˋƏ_xIojNi%zToc|Q쳅Hև^GrjTe!ddwn BG;qÈF=c.6!%Z|t20|<8!-# ,]{4![𸣆K/Bh95|nEl{>DsB͟Eab#_Cfv:c;6 lvyއ FL-k|_7c'JǜW.|{=0m>0hYĴ Y򶈅ɟBL;ltX!iR'.$ P WN2֍&y3T0*嶱s#q~l`\]<,"u~_T5W1LĬ,<ޏMfΞ1?_7 ۃ5.}]bK}ihwnĚevUeb ʒX{-1>!xφnGӴ>2[oO?/Bӽ`&};.oSǼgt];H@|º3V\6]y2wHdX҆W#A[Nc>kc1b?EUrtA? u`ܮU>anE'#)ŋ ۜKwz5}blk>|l;mZHs?os_f fXT/8ozU 8U_3> #w\bt?Ryإ2x?vKR<._W\<76η]6AQi]n:b~R @Ǟ|$> Lq5zؑkWѽRH=#WH{eeӞfr3:+bځt];="㴆n⟆Ѩ@tU.G>-=_4}"G?]]}^|=3B|#L'GgWb^OMRE LB|#U!2Hu@ z~6z" #^T_n FO /_[4 wHM2.ߓvI ]Ǽb2{7Rrpd>~G؏ X"TզZ"4h |)+Hc,ANֽƟ/q~2i$~}00|w(D"Y&6?yjϩ̯<Wb=| ~Rr!b.Ԁ۔.9MO10nTyą)r93t>E7I"y9K#C/kSsVք8߹P۽ }GsZo|s_u&MU+pu~>W!tḇ߇ Dlmx?~\/e,־!M;VփힿuӴ?Ϸ, -ՉI%Mu>g뇯/psۧi{%v s}*2oMx s}gE\_xU/gpߘ^#!}-?/઀ z9x`X +)>pΊbO7J) Y&1E'G\Wi/}s}GٲUr2`y p܉^G9\S1ץǾyOqw>_gql[SdZs욷1ק,Üv8(p ?{LѹvznuBf@1Q]_F0osS&JXຑwbf c']W&;bh3uв\_A"}M m1 lXAp]ݬGp= q$ו\ ~)#^Ds*g ospdZv\w9=zuS`=$1e7us\yjBp=^-z/co:џfw=~71stK G\q&.PKr]z!eI;;\wKrqƷb$'\'^7:kB!6$s?*\W%Jp kHBr}xfۤI+L!Br}$/V\ױ&^rExQ>tW"^]zoIr=iI $~(亡P"))Br}WB#YsI4\Q/i$WxZ\kAr]~iRJ$75\?}qڳ8\uK$ׇ'ud[Np} gƐ\TẠ5 8\$ח+q@r]Fu8\.9޳6|[s!sn*9qεiԹ= ʾT/ROJ9 t*ЩM"JGܼw)>/.Pɳ j}s's_oZGbTSRq"A'A3R#Ni?s\z?\_cj]w|ȍ'^'R#W~IrOZ<%A՗*7 jJP~s\z?1#3Eא[qW'.`Z$R3{ M^Aq?O=s٠g7 ZN:%KD+Zp4Fd3*Hl͸#QR<"Q{$Jv/D#f=#DAR}}R 6D/#QrHnn9$[8C~A(9OH#Ԏ#rbHHޖAHT=A<˝hT{:%+وG1ChȆ 7Mhurv4ts -ّV{9`%j$Foc$Fb,9#m$F71_8#qr=?Bd;&Hp$NS`# AGD8$H;EU%RH ߑ!J"y\z?~c\G"Թ5OQ4\FuګOsuY|rW%Q-<~rJ)}ɹW*5o9uyƵc_ߡᝇs:}8xs.iG^?qW}Gm{nNOʭ{Í3j"_sym|U'9oj{}~z\ON޹){l]kQ+{DT*ys'G/y:WJByI)³'{|t>Mم}70q}3ʏQNO[5{!n}I͏N)xqs\*'nS}B]q*oSSv N|+\@uűumVsN~s\z?) ۶3Z!fҎ[ bYfp~քT`3~Oz*0<ƙE')4'4ܠU+-|m ++u/zV-VArs@=WaV~RXLws'%d-aC;. ##F曂;Eh4r,XOtYCUNa­;`&7Q`sqƪ0l-{:pV/e+P1+XqaqP7 ^S}])QKbsOFH@`S-e58]^ :dg\ l{\8=fQe{+ʭLo kc8p:{Yݱ֦H b3E2{a ӱnJa?vU|ʌW既[ShRs/ N;n Xy*(?Dve[=c ò փN,HJw.tww>(QM{Q sgl~ {w@)Y51Wl mׯ,wWnDL4+χ5GߟW@14s}xmpM {lf!Jd;!`;]H "VMO W}R,-iC +XWnzQޙ `͂Jc]` C4O"{6 $d !/ Ôfx%8a+Y,S*2,Aj~2X=)ڛnк :7CfISe;oMdxyh]oO7$+Glk.%̈́5ӧZ&*h-Z<xYaWXTo^z?~sׁ"#o&eEnyZUlHV88)60;G۬" ~Mn6)J^ߡ)%mq'5BCVk s7Mط-/=Z; @By-:H IڡcpDdkJ^ɭݍG=ΡO&v|ޜWd+JE7«hsCKfᔧSuS<[O̠xh[^Xp5f7\vkx %cʢE!kvy>eTgh{P0hv!yhb6BJ7m<: hr-ZftŖ7l)bhwٮzlzWdL SC$eí,*`/t* ,A6_n6`~~?} ^qn䙹*v:Vp+; =VQL4>k{I\20FUx{]Ge$BBMT4=r[]ch-QOPR$4L?=&viC_Ş8'6ZEY-^jVE@GQX1w9|>netj%Rxq ݾo0%vSHlmОUٮtl tw%.Nq> :,{chf9Z<+WWE:|ܴXgLױvԋZ/*s{Vv&i6]s z g%koeNw+,,nv7`?P|=1<𸖞p[%Y$#3;pǪHV@KNŘyвCԬ=ndeh9G<^^z?~s!<+eƂ_!ԯ͔ kGb1sfX48/jV9= >5g9)m5 V_{,+4>2Ftc;wM[unPe 0˴AC*oA>@z$m蒱< bv|-K<fzRv]^%DC~Z.Y_.1Co>ӬG0UBhGgGJ[|_ {`*h}3WB8 X ؘjw+:Vؿ9}χ ]=E,`'6^-Vފ6?/clwM<:$$buVtjw ч?FkF`l>ub3e*XEw"W5 Z۳1{RgU--nc(+yx|7\6ܺ{6X-Z=J ،4,XWm,k{ypg<2]8)0 nLQY~/ci.=5ϫ`v8h@qKBa>R| ~KX[kit-p? nQ< %}i6Ӵ:`D։4йhN,&*د_"^lg ,VW=\F<3 vPћ+)i>/ {)?s_~s\z?1CQsv;8Zp6ZM 4|U[^O9#AF.ᐱWr-W7O*/fs5PT7יepZ.bDfBݡ/!}܋)!IÌpx+~p($%ptǖp£ZFn7dOrn=?EF  LiFē|}~=HvH qz4$[be It>.GLXs (d"IJMH˸.ϝ|{DZ㵢++V( Y3 BvĢ!"mNJ=ovCƺwGA7-BzGG8.&9H &{E74_&BZTdᲝnn VYH d|WX,q$R:6%o7DٌKW JEw>R3)F31Y)Z闥o3~3=\ *ʾ!On6:imQ E-4<N7-P!t <|-S%BUpz@nI(y)Φ =~>5**guu%W>N,r[@dEA*w yv{yT1cr>HkaCVt=}<5" Nd V 2O4Hv +򔇱 Krx8Jv;]HWٿ;ia/&&@I&v ͷK:QP]p9Cϣbg_d| fσz]GO,z׾~yg- i&%m7!K>dU6/y 2nWVtCv 1pGMI>$4Y9EԥݮhuPlB`>f4|2S3F&C^:]{Ȟ:d_S3Å"Fmpꥀ[ِgYWKLL>љ򶂺r^ˏSv='b@Nȹ;~ qmˎotGAhf~_դ RB>ޫZNWHCRl) Ɖ !qg\u;2GSޥ_M!k,:d5E9L[(dVYfR^ H-\&GL5,#WȽ}\O0 ȔՌ"= ( xW wشI=h$B+w A~ ۝2UF/p9$e Sv  ¹!݅UFq670NIP4ʃ1GciP:Ic/_9K!Eq#g!Ъِa6LN<٫ǐ5BGv TV;F=Us+BZ HB>MHythH]Έ p|idD]pٕa\m'RWpM7.}:93UI 'C ͒)Y#C yߧsS)8J՞g: 8:CZ[T $OQy8xj:rGxtK!7zMx+-j# 聥kNC~gHaM8%3`ydt%.%۾}jp|wdW|~VӞz?~s\Ǹg ?W|~A9(%\҉c"%" 꾘B P/|PD9;@0׼s}Gvm'mn5rƱWΤ?):"?G~;<.niqayp3? џOc}rwO4~}Ǎs"vzSoвr^orc|kno( ⬯}+}WT{yrs*s헫}W럻n`S]'ϯocw]}\v掟k3&ͦ'\n)}Y=~ܸ;?1'|ݸsڋS>)7n`Ѿ.{C]g'>8xje/8(?s\z?W :;Y{ S2wtr<]\{KBOE|"qOwT"|W"Zմ6w՟"U+?}@駶*pk?_- VP#<3!K߉i"TTR/inst/unitTests/runit.TTR.DVI.R0000644000176200001440000000050613425330036016257 0ustar liggesusers# # RUnit tests TTR DVI # # Create input data data(ttrc) rownames(ttrc) <- ttrc$Date ttrc$Date <- NULL ################################################# test.correct_column_names <- function() { dat <- setNames(ttrc$Close, rownames(ttrc)) dvi <- DVI(dat) checkEquals(colnames(dvi), c("dvi.mag", "dvi.str", "dvi")) } TTR/inst/unitTests/runit.TTR.Trend.R0000644000176200001440000000773413552670134016732 0ustar liggesusers# # RUnit tests TTR moving averages # # test reclass works and throws error # test xtsAttributes, both CLASS and USER # test all.equal(CLASS) and !all.equal(CLASS) cases # Create input data data(ttrc) rownames(ttrc) <- ttrc$Date ttrc$Date <- NULL iAll <- as.matrix(ttrc[1:250,]) iTop <- iAll; iTop[1:10,] <- NA iMid <- iAll; iMid[9:20,] <- NA hl <- c('High','Low') hlc <- c('High','Low','Close') cl <- 'Close' # Load output data load(system.file("unitTests/output.trend.rda", package="TTR")) ################################################# # ADX test.ADX <- function() { checkEqualsNumeric( ADX(iAll[,hlc]), output$allADX ) checkEquals( attributes(ADX(iAll[,hlc])), attributes(output$allADX) ) checkEqualsNumeric( ADX(iTop[,hlc]), output$topADX ) checkEquals( attributes(ADX(iTop[,hlc])), attributes(output$topADX) ) #checkException( ADX(iMid[,hlc]) ) } test.ADX.does.not.overwrite.maArgs <- function() { wilder.and.matype <- ADX(iAll[,hlc], maType = "EMA", wilder = FALSE) wilder.only <- ADX(iAll[,hlc], wilder = FALSE) checkEqualsNumeric( wilder.and.matype, wilder.only ) } # Aroon test.aroon.orig <- function() { # non-xts ia <- iAll[,hl] it <- iTop[,hl] im <- iMid[,hl] rownames(ia) <- rownames(it) <- rownames(im) <- NULL oa <- aroon(ia); rownames(oa) <- rownames(iAll) ot <- aroon(it); rownames(ot) <- rownames(iTop) checkEqualsNumeric( oa, output$allAroon ) checkEquals( attributes(oa), attributes(output$allAroon) ) checkEqualsNumeric( ot, output$topAroon ) checkEquals( attributes(ot), attributes(output$topAroon) ) #checkException( aroon(im) ) } test.aroon.xts <- function() { # xts checkEqualsNumeric( aroon(iAll[,hl]), output$allAroon ) checkEquals( attributes(aroon(iAll[,hl])), attributes(output$allAroon) ) checkEqualsNumeric( aroon(iTop[,hl]), output$topAroon ) checkEquals( attributes(aroon(iTop[,hl])), attributes(output$topAroon) ) #checkException( aroon(iMid[,hl]) ) } # Average True Range test.ATR.orig <- function() { # non-xts ia <- iAll[,hlc] it <- iTop[,hlc] im <- iMid[,hlc] rownames(ia) <- rownames(it) <- rownames(im) <- NULL aATR <- ATR(ia); rownames(aATR) <- rownames(iAll) tATR <- ATR(it); rownames(tATR) <- rownames(iTop) checkEqualsNumeric( aATR, output$allATR ) checkEquals( attributes(aATR), attributes(output$allATR) ) checkEqualsNumeric( tATR, output$topATR ) checkEquals( attributes(tATR), attributes(output$topATR) ) #checkException( ATR(im) ) } test.ATR.xts <- function() { # xts checkEqualsNumeric( ATR(iAll[,hlc]), output$allATR ) checkEquals( attributes(ATR(iAll[,hlc])), attributes(output$allATR) ) checkEqualsNumeric( ATR(iTop[,hlc]), output$topATR ) checkEquals( attributes(ATR(iTop[,hlc])), attributes(output$topATR) ) #checkException( ATR(iMid[,hlc]) ) } test.ATR.does.not.overwrite.maArgs <- function() { wilder.and.matype <- ATR(iAll[,hlc], maType = "EMA", wilder = FALSE) wilder.only <- ATR(iAll[,hlc], wilder = FALSE) checkEqualsNumeric( wilder.and.matype, wilder.only ) } # Commodity Channel Index test.CCI <- function() { checkEqualsNumeric( CCI(iAll[,hlc]), output$allCCI ) checkEquals( attributes(CCI(iAll[,hlc])), attributes(output$allCCI) ) checkEqualsNumeric( CCI(iTop[,hlc]), output$topCCI ) checkEquals( attributes(CCI(iTop[,hlc])), attributes(output$topCCI) ) #checkException( CCI(input$mid[,c('High','Low','Close')]) ) } # Trend Detection Index test.TDI <- function() { ia <- iAll[,cl] it <- iTop[,cl] names(ia) <- names(it) <- NULL checkEqualsNumeric( TDI(ia), output$allTDI ) checkEquals( attributes(TDI(ia)), attributes(output$allTDI) ) #checkEqualsNumeric( TDI(iTop[,cl]), output$topTDI ) #checkException( TDI(iMid[,cl]) ) } # Vertical Horizontal Filter test.VHF <- function() { ia <- iAll[,cl] it <- iTop[,cl] names(ia) <- names(it) <- NULL checkEqualsNumeric( VHF(ia), output$allVHF ) checkEquals( attributes(VHF(ia)), attributes(output$allVHF) ) #checkEqualsNumeric( VHF(iTop[,cl]), output$topVHF ) #checkException( VHF(iMid[,cl] ) } TTR/inst/unitTests/output.trend.rda0000644000176200001440000006513413425330036017055 0ustar liggesusersXTK6L"A0"9tNZdEPQ0 (fT@PT"YrAU D1aBw񞙹ιgv k S=HRR%W[:u77)5@BBEh7%!w?%د2,Fh-8֌^s: 9=`ݿhkW)X*./ ֥Ek/Bƾ`B} VHgyJϬ./ O/`}3,W^_6CrVOv#  **RS4X).P/ ]tpx0We&t#˭xǝZDX_ٚ޿R@m ,]P}1;(Pi } Yru(w9^;.9s*F▗{iX +m󕫀x >PocL2:x]-~@=eT;&P۞ܸ6Ô+ lx: =uG 7Het(@u@34:tֽJ"[͘wٗP_ T7c` ۽`K]r?i^|Ny~ d+ XwY؁FgNenV|0v75MAkJ{! nF`^dl2t5`FF{&Zco@/Z #jP7z<`2) c=1ں92C!C玪eGwOF+wSvAT,0j_HzzQc ;.uN"}E9P7\,$$L AktLLg #U}&ΎT]"]m@km /"6Ko?yzlih`&%^㤞!@.IWrR܌9@x( =nBHGg<}g/ǖg9#@Pgm$z.ozbX-@(8"Q@f:ר@jɦ \.l_<@a;Fox[sYkygM.3Rnuce@YEڷD0Dp`kl s~Шw[.S.a,PJ`55ﺵp\7eUuLe\mv{,Xc}T:?3ɓgY{ؑKsjMg|!ܢ`x/ύ-x|c F)];0y20GSx y`N0¯NU,-~AC@*>͍ +=foDClgmd`ȝݓKn回ւ\gTRboae)J68T:!h7NWJ'[卷Oјѱ֫woK@ |RY=2fx8mn͏\ V ;~W@Ocf}͎{qc5cDbP*9zgs>Νz(ɠ$7` 9~g<3 2k09:dZ\m"gjym |hV Pv}Y,Da[@ܐ] R%@XadC 8\YMJ7} LWsԀ~V뮋ny4-l2ⴂR>-g9`iVtʽT>* Q 4qԜ?J,hMN\ޅvꍪ׀Vnҭi, !ƭ> o4=U`{`Yz`Q6 1k8gp;7$Xi!E!`U|2{j LUJռKƮ->`k=cX-mЪ0%6(K2XljX-v[kdF#XAkN˄ rWS7ojբ#u@yEx ÃLFo%Y"HG6̺BWH0Wl>}.>*PưIQY@V1h>7ZtH^i 1Ceϋ@sEUуא J6LFܪZY^ Nxy7<m Zf f;ŮxF.l c0x=O d=f,Ұ)5?kO>w9p,PBȞ9V@ZZˉKCޒ#As{ ƺwԁ|itiy,-N߽P._uǀѩ!pOGkq=1d`Vr^u _:G]F#K-zo^h=NfŝM7D`37M3nƸB0F͸fk2Xn͆٣Uϵ`j9B!P-.tJ>Ԏ 46JaE`i;` 6!S:Ut;\+vǶ?UDؽ_~]8m(oN޲H&AFX3uG!whz_Wv(XS Y;w3eӮL@Vy%FP{fY {%1t᫦'`uُHg#~ʤr*hSj48}<F)]kP;Y&r|rR4p\nbn[tj]`2$e >S;*ev`FkHΧoX\&Be駸l1yn`̇Н5Hk]@Z=+8\Nub-WN;&'ݔvl0VonC5JXܔ#EG< 9q1wmi`vInйVuyS)c޾ﰱ<L^=Jܖ03kWA ri(F/y起4\~}=odu0dMrPN(66zΪy`r,QW@>=oK3\]3,OjQpͱQAk1h]\EDR.z[խr2GYZc.ГCHڭ`1ܹ=rƑkQpXeN[VN?r}?X ^ 瞯Zoz8J58+ؿ|]e7x~7eI}TE;Ʒ ׃QV?OسfeH%W6GQ*A߃JSX3%=h"0| _[QkN3x޳]@~pB O"KrF]P-Z9t(E ٍ{0;Qz@&3m~\s#0ߡTLOܞ ?GQ.T0J;j1$=?{r0[ B0w12?6H#_^٦@y&R{A۲_E]ܮ# S=WĜ@ߚ&-[FsY^ $R ^1ȗ?K\w bڔךeW `T=سk% e_(}2-㷽h>Π]Hܠ@3UmbUTWon 9h&n=j3HZ1sOJ-(:}yzupЬ?vzV_KKʿit:w`8(F.Xȓor,JJ=Wrށ_8͍4H1TGϢ`<;!<;G_s\=ڛbH- ٳ>*BOFp܊'ň0'T'ÈQ_iCCc|ع.^ 6nأ 6^<ؚ-Qk˟ah-<zlx`vK4@3^:/yg YAm*:oerݵ1֮K[Ú3Xue$0f4Zlj }@A4`ԃ@ޝ W⬇'QhY< 4EqɊ{llUE`X9T|t>Kels<{xJ0Sw01Pv}Bqȯ>3t m;pa}0k[eK. Mx!6dČU#ܻڱHm0!NZTݯ&mȻ $3?5y[$PM.ZpYl@kcs aufmw1Ri--9<H_Gqr)s9@my&.w|N`J}jz08^00vo6|^; I' @oVc.1`rKK0`N( X  n"yx ʪ !{1nӛpg[ &f8 j~vUBNm?2Wp1`)-|1;[sD@(m' 7o6~I)n'5?=kJ&)EsV _5?h.`uD?pb!w8{sm_=[ ##ё@G;"'?+wwy}!]wr/%$"ͲgUܿTyD&jJ H""h"HE4"u"F=DD"$wH{H"!%wHB!q"*h"F\ IDCшG;\ SXC"hDjI\HOI"=YĪdEJ*YĪdEJ*YĪdEJg"v&ؙ,bg"v&ؙ,SDflCE"2PD|AE"2PD|AE"2PD|AYxnX*by"1Oy/"*T* /"1Oy/"*TSgui"Nh"&bgHDb& /h"vz00F9foN5,mHsؾWVןΝVx 5jV(XLzz iyHYXw>[fMrx oCZz$0m\&ۃ%_'sK_sE[- ڸҀse쵧`q ezִ@Lx>|J~$ n ڲ2;<c%`8I.XJv'9t͎Uw^=F88-'Ցy>+'lwri?V6nϐvD%myN[qݥ`ysJf r?:㷪)h>Isב!>; jWJY̵_!ʍqb}w.5߀KO[X6w߽4rT nOt)bq`Vk' &]ģI69%+@P]ƛ[v|ûRs"#e"5ҎCghJ@rѼWlM@$fj/_q誛̦5^@30Ư.K#祂vukw``Szaz#-AwZ'fKS'ӫՙYgFzc#hk.U{g)}J?J!_WzZ73˃-:}iB(]w&skZ7OiE)@J ff}A`,Ֆ{䮃.T  kiea@8.GFsv<gAX^Z0˖_nV-^5e`kX4({CFN,ҊR6v@sǦi{Ճ]W VdLWq sT,_;cW 9>̹cWD,y #uxYn4K+V +: [ѭ/ws%u;{=]> m:7i8 7awCY >v+/]ceh~X gKYK7Anjd'-ظ3FW'3~^ºՇAƊYl<| 4:s.}rEvSư'@P99d;.k;x 7^VeWmR16Rd⊺˱4EEY c֩[=Fr6漷KT>٬=i,edKV5@NM9FwMA $2[_~/'l9> #ѾEqd)f<˷hBޕ3z%Y]m9uoyX> 6QNǹ #A38~D-[m>g}Wj>Pv< Ӯ28`wD587H`3vm} 40`.t\~V0u5@|LcMvEօ8B6.=?4+ 'a$c`"TpzB^;&(^ίh1grzĨ0?9Ğd6)pqq8Y^4_2&9W=NzNE?}IWq f!`?Hu5e^ɪ?-FE{@r\-|.X)uxSÚ{%j&&GQReGXk5.i-|.#Ay;sw\z41OjNqeK=?tO7hY⨉<_P lN<{s7zqeOp^T0˫`qNH2Dz *? 9sAuu&Kf~GWn EujmZ+mݎ u@޺e٠~!tMy~^1왳[<ӷR%6 BAbQj0n0oK={W'#.?;d8]l&۬{ i-gLkUiۧ0j A3p[L^hfhP l͵пS;yv]A]Jli0wR Mms@#dz}k5u}&(ݾDYg5mTDȿU]qJ`rl̸R'r~P'$k>uAH^+ AWV*&S[&U,"NRۮo@, +tur}ABO,]1}jʌ梶.]k6]y:]dX}]QǮ_cUOǥ;]* Vɝ{5k=nGtSmy8顫@]NYcKP>ʁ @/PyW! Kؤm犗䚃@_hc@[ $ O 9~V{ݳ8< hE7zple|>~t̒1&dÍ,IH!ƙ\EI7#R~?|^q`o%`p80{E >X[?G #'[˫6_uWvYa˕'d;` ?ՙDYw@<8$ EfDJ)~ؑ{PM,<;ʊ=x '(cy' ^~a{!o&,9į9IymjLSP&hnPz9c%0v_)usʷF2:-XeVG%ŀ{) ]jy t"'PV4?w%awIKLYqqW=߽o;)>w'{#>w/wsf{Ɨ?~.ssKX]*l;%&.v]]\ 8Ϟn/ss}4sh.j.j.j.j.h.Ј] i.j.j.j.j.j.j.h7~!'P#/5SRc7-xhXW|ovoKnܜtP$=qAl|A*{Remzk{B9B}뇠\̞ڽ /v'jW؟N>Q{߻=ש?@ IP=υ'z@p:7q$/~R7^^M>J? O~Ayw~eLc E8n{}~yB -KAZx/ll! KD-4^,>A?Ǖp9Wǃ@z~;W'H kyP=a W\ G~~ WC٭n GY̍QF7+eT[J?|@%\:?*?˝o^srpe;Q5Ү QC=dQ "k FNDL XpePϵ.3V*,܅2[%EYoh?Ӹ~\֢x#ΡGsF+CNd=elW8fwWC9'Ÿkx͈V=P7xu~'z!qPq 퀲.zrFeZ ;PF[jTKeNwezn;{[ClSʺu);cUt=o\x; eS3A9SG6IRT4/ɛcQ(G1!4*e_̤]QnMF9PNqͭ(GÀ6ɍƠʕU)a(VfkڸH=6VyZgeSkWpKP nD]wrwG9o;:QGKQ꒬B[?# o)ZH|TA=4o[z;(qw!ǁJʛ?@SWۡOoB ī)rR@WOnmnPx{=y}{]>%[x{? ; ?{ 37è?+x.ܮ ~ơ@vS?AiA}4+{  &8_Pwxġ<^)x.H M?]{%>땸~nx;0@N 돏A;mޏx>'RPoo{ 㿷x\/zw~$xvmzK *G/q_0wo|N/o_{ {݂}]8.qKgRxzKo|SvTWۡO ^ _?*zC x7קW0*;w"xZd띏`^q;mR A?^z SA~:'XRRݻ W;  $^4맠^v'z/`_|[WJco< @}H/~7RW|IAMxğ~Tz[>Bx? ?y)<_]?p<]7]w<&`&]%.+q/^ġ` |A W8q/G}[^$.vڏ[xG! zKW^d"`xu=`~ ;77< 1BX#QՈyh<1F̣(h<1GW#QՈy}5bE_GW#QՈy}5o(d'RAߤ}z*z%i9^zʵK񗟱s)k.?>/Rp}_̥'h<;?2n\ 1B̥s)܌Yi=HF^t3dL^s}~:r=(e|*e`bx6,ZڠY(cP؊(ˇ\ eXWh FUM=H(9yB@w)\' 5e ؔI(Srƭ+P«oQ}iߪ(CM#(=J!=.Zq v}$YKIJ\V^Rk dQSW8:Ⱥ7*^omCTxs2i[/4#tPfGR J.xͭo߆Uޖ(}BaY7vi0J;5M(eRQ (2eLϵ`ЎQ(=#DÎ(#aPz`B=9O@G rR(=;e9:ܦMJI,~sT+~R8.-lR_XTBi]rz(݅a~yn3&JM9;} XQF7"v{(aB]yy\?H^Kvk%X=e.ן#.7 >snɹuQz噐(}32.(꟡ty0 E1'~9i*Ox+JS7je Ju0BӝuoݏR8xzJlG'(m95ގELQ e};lU"!dRuN4r 85Eʚj=fE-R,,.[2+e&Yڐl(j^L^;tO=h(gPedm;_!6!Ώ KGY FzBYc;_FYY'z82?PֲÞ͖@Y!dsP¬ν(+Fe|M?Yzf#W_tf"`.23ynހ2_=2o =͝W#6SP93Y(kaˌ(ԳF( dt8ʌ7^0 eucIviHuA O̸zHe8Z2ȴ;(sλA?̚٩kuQf|+@ :Yt=׽e(3KIh&ʒZ:8e!"u[i/MBbSr*ehRm\ o! _l9y4y.pߗbx+ނ6\6wH:*?CmN 3mw|ZA%f_>gìa+gZ|٭~gyz^0a0i-0Y쫷ZTsKuvݎS[ Pg&&G20YF0<< /qc;?r|O 'mrfk__UM;іA~A1KQ)gD;ceʔeG. xH9 AjM@nwI'3.۳6ơ0u]~Ij}kUۃC5;͜Yxه8+&+>Yw0hr25#hw˜V8F >[5%~6ʹm-)&($ZOJyun s{U`ۄ`ٽ7ָ} &Iw&6pɘr Ss/U0-IJфm3 ^|S l6fiV<QO{]Fză?Ӏuռ=zO5IGG6N98 g#nO渭tc nXa6V˭e0{~tZ^m3/%`ܬ֢Yϭ)7cmfNΐ3OWUDݘe=%=S8 ͈͖SaT߰'Oᥟsv޳<]W2F([ykjn[ S~q-vv=gFe -*0bXRBr>d& 96 -t=̈ؓ[Y{").,Q5cr|ީ[F1Tv8(|,6AxƙN1Μ9Y3Q/3v^bz*Z>ۿpSx_x|%gDgSm#CI's! Z6krE~Yhv<*膜>&? hGξ`rgtO=50LYtNy.?p O{+ogq ajbCz]|?YT )DfwIaٹ7Sc^L}D=uwMaS,E՜"{e?3|2t5y-x̩mWyC,s /p<9X,rs.(U&|GT5 |lߟ9>wgwOzΝ>6 ^f)ӦqM*pg>iW5I`ٵMg795 2C9%ݑqq0̓){Uۑc;1W#v~ш1W#vjNc;hN_c;}5blFՈ1W#??/0& l>5?!diA6$ ҉A6^cdCA6Edly' lb l.Jk 8dSC6dÒ 's帅:dA6d+C6qA6#1I( #b' Y Pq&l(+0# q؎A6c 5l1FA6Z0fd4ܩ uA6_c c?} A6 04x0Zl~!!uI!8dlqFlN!8dC!C68dA6 ]8dsl1ƨlp&ltpȆC60Ȧ lLA6fdsy# @ C61&P1,lF`Mg \:A6␍d!MdSцC68dC6qf٬!Q8dA6U1Ȧl$hd3>l܏Mj㐍HcMA C640Ȧu"  3 g Ɍ!"i ͏d$l>?^ɇlU1f ~C6s͓, dc_A6!5dslcMY!8dӂC6q8d!;dsll0fٜ < i  ZC6s0&w8ل[9A6 0FƇleb!m`7`7eqVr y,8ns7\/QH/&rawQfە~įW-i ؅=6~>k$ص r~{M|~~Ͽ##?6f"v_;dvcoav'//?po?[Ll~ױO|}nȑ_߹v}g$ni6Ӆc!Iw,w~;_̟?|?Gظ4uEOI2[v= Ŝ~p#W=>_qo'ؼ7sP;߮g_WMU`8껆S-on<}r~Nl>pa6i4AZ߯ ^.}_K ^'% y|Fqboxn \~oO%b}hvV>O`r8xZ v9rN#H`7ecI7,Fv]cu^'T;/ؼ?a?|[oC_~|ԳyO\{#hD騕|Ko+| xa7F.or\o؍F܀DZFD0~" 9q&~/~*~C2&ɡ~s~C˵= di~(H'$Hcq2ؾaP {fIxo|?Yq ?$~3&_FI : i7 ҈ϛ'ygWEx*Fqr #|ߋ}}l^El:acWv?CfcUpvg?nX<^bne'Od|.{' |//͏)~Ol?nnV(a 35nTo-c~1G[9x>,l`p;-v(>f2nHO<.%v/w"y<α~E77v7nA ͩjX?@ js5<Sz>]m*h.&X; yc0 ֥G0O})~RG/iufTY7TSAu+s{|P5ԨGzlQGΫ?ͨY*=ZcP±'Pvf'G~wcg*7QF7aSͨMp4 j9=~reH"z|ӓ؊-=5bfTѣahk+T4iRqkWٽn[PW/PbK\ac.ʈO聦à9jK'tg[^y3%$w[5)xntq@!9͐Fwt|MFeQ[VQ"?TDTqGL)a|;޿ɨwN*ߤJ=ʺoBetmU"AnpO _KTc<7~\M.Gq!tPEw:C +aCr|T;hGU=BUd@챻?z񡨪0f54/ 4Ge8k@O86JK(1􎡧]w^͹[f~_QՁ+ƃ7=QD _,FOuO>=pTzhSQy|sj'*1|?u tO-In/V`^ߔL+{p ï7OOM:cr7oemWn>zIIg9<1@W͠ljI*FFkTG4k9ݧjQvgfXtsr)taPTZu4T6iܪ7)tY/+PաoPhGs<+KULM?|dv)i}S9BdTTR/inst/unitTests/output.overlays.rda0000644000176200001440000003415313425330036017602 0ustar liggesusersyXM8T93$y0;Ch@e")21E$CR" E)*f,s~z\˹{9뜳Zks^5m,=j%###+#'/'#+G(/KNF^F@Zk=\z7t?#PFFvWLCS_M]c@+=@U(nѧ 'ۀ`kbٯ *~v-Nq… N;Sa75-@p` |w/Oʥl| }iq Pݶ= CZeKy2%?)yg Z~,M+'hH~>_ ^-hVlt/z-[ھ@}4b1?ẽ/@9; 3&e7vnj Ku<԰W电 s]%U1F(YED_oj»η2y72P\jtjfVb Pʅ{˓AP (tO<^i3<oF\T΁y4D\^/Cژ\4 J|r8 N\ u7 wAk -+;˂vK%# xPgآWZfƿe>g@1UP|{‚0؅1XGKi+'bl)()W cA1eŠxexף@񒱇˷P>)2 /LZ]B;o(>: o*A`}^GZط έ68M3că;uĉwه8)CYwIcXwqj?kx @LvX55vd@ߖI1 BUf@xa#IFG~(]~~ζlo:֋HkRZ`nޣu!p)!_v}NڈA@szow ޟ09Б]d_}:} I 0fv+-`ho\:"B`ffd) ~L䵃'lup U`{5֞/Z5u.K2_z_,+vY}+QP zYGa\ i__4y4`Ik?|mř?ʯku mRI:ߴeGs9X3$rrOΧ $=#w]]8}[srp6`w>(*@v_\$'اdSeG`9K7oֽCí׏,5ӐcwXFo(gZ]uW0>$M*a ʠ޴@ $EΫϲ=-^q7#&#y ~6Ճ$?O>襝z~Κ k#WKHnqf=&3^ds;3C|YH{(WQ~7Y;-^,7ЉV)?EkXR_ݍ}4Z&уFNHVJ6?FU5n= w;'o`27LfskrZ`6-QkN !ٳSԋdl;b;lrE[Rw׭BX{04RWzM] ZV[wwEgH=}:'+4/1%]ͻVOvm+M%R{O]`W:mB95݄ ߂гgx- PW)eGl#3wؙy&oZ `_링y[8sW |2:3گ T$2bY j hKn=AZ@o=hTH\%{&zhUp2n?S9֚{[,W}ѐ@!q98ɻj"KR 'S]'Ž/*j%ۮk|uƀ\]<+&ĐqlH r:XE9z;VLJ@[="2dw2\!Ygv6֜7j<̧. @.JXui!@7e3.PĻI|ⵄ3ړ>\:d~:=|`47[uh}OCIv|?€ !A##w>ޱG+YWPPͬN'F.RA#Hb5غrW6s1P¨'YJ z5c69lNy2vq<)A%i/#DvP Fl-@<(R _uYnCY= 8קdC$g$m[p1Gtv"yKo46cSRwt8B#X TUt(IÐ+fdg,:9DX`2qfs}fD*Kif/.mg0UuD"5Xq6zQXV(k5`zڝqXrvL'[`_75؏Ʌ:؟-%j o~K2늌c<E@h~),~HZ/$.3+Q=# @r$ H_ q\.y. l_ 'VVaqx=%{<)e#a;dٔlqAB|Jfפ/c~|5`Cq̛+0$ G(&[մ%g`V+[<< -ysZFr]/游$s0u;$2׀Y/~q|#e/sQlRx޶@߷<Ìd's40IBzd%Z=F+.x'x3W`2o 咴Xɑ+H|% lx1Xijːh rvz} Bɼ {J =JG:rrN 78DzRx_"'r)W|a _L@$k{PyNc3dAI9u3@I{$vGv>KV.Oi "B+V)&)zel4Ptk;d*qd*M2ɺ+.}בVs<QRVRCMz0;fmAqdr]80S9-ݕ io݆Nd\xgY`v3/ƐFIzc.+9Ojkô~*FL@w lrMtkȺ+Ĩ`Yxb}d]jGw%L\Ku% :<|]3w/}*j@'\:ܐ\C|]+I>˃+|s?{w" Q&7 S{*[M{ݤ.|#Z-(߉̗O'6&ۮ9i"09[:{wh?3 Ӿ?$d^P$32~9_ ̽-HW6|__`TN׋gύ'㜨׸r{]D6%V"!ɺ*>*wɩүCf1`˟v'l"ܝ"H " 0 ,)G}pLGWdvv^ X uD]?]9aA1 2ۗnzxgZKҕ /?n@d;1/lG_ҺMDӕ "J @˙uȸk WϘ}WVnE2*t jV{09NY5V |+x2?ߧOK7G _V; &+.S (mkoh8v1_1nٝd{,@ our\JQ r`Z%_q\if=^C;_MP9 |#3jͺ% VgSq1?aIǀpPu\vuF Dqai1]4AkIt`]أC' /On銞v>tѿ1֍:!w}\>@D%*/#m}*zpad2mnl?\7ݫ,Kl_K%CI]څVݚlg߁}U-mLU|ج[d)!͙7xaLn{H^,zo/8o*%ͮHeU R}yL&q7kd'Zw&>z_/{iAPr{js( ?n>(Qz](W=WecT.RM#T+a9B֪]XjI7x)IB9A)f򮠔wzZM;jGv=eWSᄦ>W0\Ek}4)?;7hx0ɡ\Ơ+qM :qo{^;ijrĮǷxxgǼ+ٟJs5≥S?Gp&l^{/̝_\N6*l1+7hS_R'Q2s;:apNq?\ͥ<^.8|ѥ%Ho1;SS($&.^̺g?>ryr%+ܹMdjr.fp#Ye;, lszTWqmuK<5,lW|_.r-/"F-˅/{:X.R5Js=Q{4Wf_Qۋ{a*NN}#1C5DpetSLjhUȅ$*wƄ+ wO#3{e=({!W[q}F13sy~5=97mujxej e>ښ0(<=/Zw߱ΥY׾0.&K~R=KNw:g]urV#j˳rKo^*Nn\N-XjlI5άOM>~q;U9=нUǙlrKWA*cK'fde*]3gs7*6ދv;'mWxfdk/U /=-UgrG/qUizpU]5UpTVMpɽZmW},9:OΗ[tww}mrՕ{=Wy/]'QsLwVxrsT\"ՎzͣfoTKŞ#>ߟ5osq/~޽*޼t9r޷N)ܛ Gr5~;U*|ArUǻ$TrQS3SRY5>OqӭAWѕ[>d˄^\_SɭW\i_.o~\wg7p&&/ʮ٩j~U%\t+.OV+M޼$d٥|;gLΠ+ŭ^ Yn:cGzsOE^u*n;?ard9J.K1-eLRjo4\O/e3%J StC>q^d]pG-/ߜU:&+9x3aG1isS/kRccr|R7zU?ӍrM.'gqY{,"ݞq_q9U[_L1Fk5Oz5^>>d\Ȉ܋E-^xP30rѱ8E|xD=5Yx t:wXæ515yzB.|5qy< 4^x4=+yUq8{61j*NhU:*qZpjzei8G<̺1ǾpU FQqf:/ pCf\2 Zr=;=kIKpktZbn5H6pi40iܻ~K-5inUoČV.וsDZ\c/ݹ]19uk̓k-n՞goZo;so}H"vPjn=ʽzv٥rݧC795oN)wD9Eğ5h>F/i)=vӞs\]W}t\]}Z(=|?4IƥɯrϺk:oo/]?]n iX?|#EU \?w)I+}551z x=Ƽ^=:]^o_#^xtyǣۗx;=;w}޹q/8ϋ>/&ּ/ƀ7col1-\raol1-\raol1-\raobȋ!/jސW\ra˅! y5o˅!/\jސW\ra˅! y77sT7وWFLj #^.xq6ռx0ˆg#^jވ #^.xq6ռx/;Ƽ7ռ1/Ƽ*ܘWƼ"ő1yn̋1/Ƽ*ܘWƼ"ő1y5o̫y^.Lx0EބW&7eDŽ^Mx5o«y^vLx1EބW&7eDŽ^Mx5o«y^vLx1ռ)o1” S^MyW)*0” S^MyW)*0” S^MyW)*0ϨY=^>ǀc1٣;]G{x=o_zs㝻xxǣcew+1zy=&y?k^ܣϟÊ{Luy\]=wzs3z<Vw˻gauy{Xqo_ּ/Z]]?kw+݌<"hIe]^W'1WS+WX!b+ W"E^qy+W+ B^qyuWWF^1yEPOW|C^"yS+BW+ ByE ?+X+n!b#+. HF^ᇼb"+F!"y;WG^ф3  +"0E^b9+z!+>#(B^ypW@^y+BQy+#y$+W"xmWDV&3W$ B^ab ]"dZ A^qy;+WtA^1yEwV+!`WP+#؅y^WLC^y}WB^y%+W$#* !+#Xb 3ߐW2+W#G^1yLWE^1yE* W @^QyW\E^b+tW}WD^ф" y.y+WLE^ьy%ېWOϳkW"p@^" yE_+JW""y[%$WW#D^By_$08+~"h3+W D^yt+ B^yaa+ґW (D^y'cW"0A^"y->+WG^qy+ D^qyE%e+ (F^1y'+#hb W+W B^QByE K7W|C^ᇼ+ uˑW!hF^ayE N+!pC^yE n+W"H@^ ycW!xy> }ӐWB^ab+W8 yE3Auj+#8B^"9Om%"@+"@^yDP[+*Z "yŲIxE'n+RW!XJxE5 GWd b> +#B^qyp;W"8++!@^ჼ" yW A^0+6 HG6 yEIx^-+W B^qyE+yE1+"(@^b+WE^ yE\X=W"胼y}W,A^abbW#Xb W#y<6KyE$U+W@^1yE.+"W4 C^yE(M+!"yE7+& C^ᏼ"yE +Hy 7+\W+JW"D^Qy{/Wd!8" yE,+#PE^ylːW@^ByE_+#D^ay>v+ܑWd#؆b"0WX#HD^1yE !+#@^ByE7>+ W"w+ ߭WlB^1yEO W!Xy!V+&!臼HW\D^"yE=+!X0 {W,F^A!@^y\+WF^1yE8+ @^Q=+ PyE[+(ÐWX!ByE5+v#B^"y^KWC^qyE~+W+WF^!D^By6C+lWF^yE: EWW#0D^a+!hOϳk\C+fIyE+"Xb2=+䥼bN= 5W HB^)fOWtf^a29[+{IyE )x/5R^d-!wbW|?WHyER sW8"PA^y,)xR" 뤼⃙W} )+Zߥb[WẄ+,- ])l@^qyR)8*G"Wܿ&C"rWe+WLG^1yj)yP+D^*IyEW f+ ByEW"y 5+ґW C^1y+n ؉b:)+#!)yW,ER^b5+U~^ӂ +Jy1_a+Ky+W C)U+h)x4W+V? &WɛHF+tD^ByEw)xPbW 򊰟R^qdW/Wh#% D^ yEW|kD^1y@+2Wx"W<@^y/ @^qy!+"x*+WLF^b0+Hy֗+W" i+WtG^b) ++¤"#C+n"脼ByUWI/k* _Cg_C_z5k(P篡g_C_z5k(P篡g_CϞ= @gU@P\{(z7ŭ6(;l悢jFP !Cώ2kcO-;D|htR'hk߱{&M@b3V ؿH[\;A;?BA67I?n&PTEztmj~:,kPz?'[k6ߘUg+|:ȢP<߭Qm&lx'R].{=Aeɉ[f\kZoff{3|]"`Nvy9,|j17=9@L-¶V] 2rPJVX8tI]F+PjQEE@O:1":yr t&g.kU[ׁʪ_w;;0cR5nM ckP#Y6vŶj`N'Xxc.<("e8Td _o DtD" qk+JYG@?|t#1,vX㌂h`U`Z*s y>3:eJ: 52OyN+PGZA) w@|S5~ XǢ)*@q;eC4颪ǝ}`#UgM&qJL̏?և\̀)9P`$5ww&$]vR;`XC1:fMzmuzy>SV&T˝S[z@O1VdEݝZs e9*o]sAˏ@ ~U[cvQal*0= Lc}€9qmQ.s^\/FUӁU{]w`44+ s].D1 ;!JSg-{ Bű A5i4Nu] 盕;M&}HTd DC;OUޔ=P)Ҩtʀ֩\ɗANMstA\n2P \&to:ͿĵKEdV:qv)@;ډL-8e]]]]]]]XH@)HTn Ŵ ~ Hsd )-/>KH"B%gԒH f%1@IpebV%SDK"܀4+(wh :Ylh19)Z(P)Yd({LS@RJMm=6^w`%tM+㚿l^$)FƺqtO`Fmӻf S}YHldM*xEzMdjit@_4.uY@דݳL5BzQ:GVTf 4|bQ^f2BS&ܦjB _ )dPjFN?[*\%݋pf1}#9n@Y*:9O}?Pi+%ޚ3e}/HcߏǬ/@fAJa7 (gy<] ᄑ$¯Lr0"M!Kq>y]I ؞J3W.A?n[HA >S+@z9 P<@0N@Qݬ 8-QuNkSz%8=U/i$N[.VjTƇd)9bSX1 ]FD3|(y3b=]$_p:A#@_?.<:J /5elD[ kݔ3#@΍[½[ܪẃ;<VY~@h4YՂPݨ3 yFY2dIв~/C*Ubb؜Z}ҳ=;np'``-ǿ"SV]چoyN۰w`G} t/vmz<`w\̯u9Sr婗d1q KwnY7^[A{!'mTjwz2SQNf2iu-ç;ۦ攠W*1@weU&CT=IMm;Sh*Oζ eɸ8Gec`j#c1}ԧr:[j[ETQLZ/d[%},]_c*11cYOy YCWk[y6 ;?^W"u4DF2E;煮i_0Z[[k 2FA$j]/~ "KѺlRo CuOQBKB ƏNv^ڠq֥@I݆|r=(Z(] c?fV=K+ml2׈2JTM(%x׼?$b(1ddbI%b܂KD*%/h,?CF%Kc@KMo?f%В'715䀑3^#lV`$r>w^;cׯ+``ʕc,X_]Kyٴ=#/=kO^y"nl@7TTR/inst/unitTests/output.misc.rda0000644000176200001440000003072113425330036016666 0ustar liggesusers 8U}QJ"(^2FYTʜ8$)IO)deN+MB:o\\>׺׽}u^RL1CPX)h߲ҾP(\v1W.W;Z<ڟ 1W G"vgWݏ7SͅcfE¢ȷ|M\,vʖbQwzwl}N\YwW߷z-,[UgX7b:sMY,m_kH=ϔXl_sx1& 8nY܅{U3y]Yc=*qudgN;(Q}fݶ7~ID1iֺ l'.ܛR*} c3&s,ܖ/KV_)M۹$H0G"#yan妧GvuV3>J"<?ON&N,xֆů [4p[ )^DþDgmccXǻ[w'unD$ ".jr%¿.;9{o_b" ˉ Ŋe-_0l-٨()b:o]u.~,^Uf C}dZ.1G#C~3HȖn pAY*h.4)s|ZRzpC쐣.]7cg'`1O誔v&Q<<.c3bP7/Of½2e@HwVxodssCe,ڲ"rIaY#<]8s YPx ;<_#ޅ{ML0ֲyܞ[mJ%SY;οV2 !.˷j˞&Bn݌Qo;m!v)WĦ[Z^x7KG uq(zQ\1 g]~ & ;^(A4jKcD7{O 6Ӧa~n4qٿTc*[!͠X3{L1J_3xUcZLA\.V[ʖ@Z~YH|o>/. ۡ-g^P6'˴6-UM%zL]NdD9'I&0 VN,wn1H1zXHZƨccސ4}-=BT=*x.z.ʹ[2!kFՄM'1` bcQy!UM+NbMbAǬ^j⨜ bX c(*\j&'+ݱb.`V-8dn!—+>U.qKݗŃNg e&{L/", IX~)ewf%X`nI"g<,|@˿`{j(;?=SA%9S1z[z(KJ v-()a/rvPMbR {9|k-)EFI"^vʒ  *H_{}A;GÓ,@#=L~^0/총B9/{ ,TE@YyRg/V`A,IT\Z{(m#24;<)۶^;$;u$VoONgԣU],,-ǏJNۡٝ_BMrS1۩)"Xs;I1S<==;,ߩDGoN /#[H#HC*q5z$<ɳ/γBMCBD+nN??o,:x=>WLbvWIZ~мVIaȈxaD !ҷY vq4 a3zi~_#GYih--qAh^ag(dH[ G!C~.gT"hc645IDLJD)< nb^犗QKX~Eu^iZޛXДNr04f‚@Pol E%;&Z~KV/=';MO3:#l~ #.>Lm1 'q)TvnJ;iFӯJE4R#ŊxOOݳvrQ0)7uQH5٠G w;on{:j%%]rw.JWuZ_{b٭wQ1v.*q]MT-KOď+fM4O HzMgwrK%I,D/_ oo/ ;؏^WBذ!nk;ltJ\@(IC"}GU'bG;=Bh@tE 2=31?KbB Z;O"p&a$B5BдicT 'aU"k~d9m}(.s?E~vYl)Dz΄4-MSVm jR!-,̱39MGQ֦aӭ5]إ# UI2gݦ]M['cF..`ΥKKܦ{B 1˯! sLް|Q&Lz*/z*i˃6D855e;\I͌ue͢/|8ܮE͌ rjsVKV敥_iXx,YmY۰x"zhmz,OȮےbɒ(#9Gs=0[BXPJ~Dk`ivw팾J{ߍrx΃*,S\:v.MEڅVݹ6uXt?!//2獮z\BT [F|0cL`>Ť:_臩u[;/f-3F|q.s0QW:109ň蚾ʧܹ5u`o_9er_˼7G#M!?331bp`1D|ߵ%؛nW4{ƚ}kIڵsez| z?)4/}ې߁t LϟX7n<ɨCzq8͆ފ d?m)oD<ׁd[S/܋p7s73uD+ }dne~î>ZHu'S6QTiޭrxMn57>,҆ k7 Dm_ y t)O}y'bLJ#ַC)t ӛs  =$g1(we1N&2/l0af}<:"]V|8 jX} C͆Gnϴ&Jx5gԱ,!_)y84 x](/^aH<#Ow7;NHw{Ǹc>Wm\Ac[> ]xOC:/Gd@̈́l_wԾJɻߵ}n>wg?sXg|h<3ok?x2T;-jj> }[ .ۗ?1L*XJs|R0];j~Rſ^ϤLN|^:~&xnWRn$Qg<~o+{^~eJ*)%)Y[KT4>\og3x[i O ՜L_.8%T>mvJv,+Jik͠|U㴷E~E*_يAnīhwɕ`ޒ f'urcf= K[;ބo۞M'[At_`ĀwBY~p$,j5=zVޙV@ܴ2{gm,:$~@|ͽlnХ~$喳{iy ?wX2x+E"Va|Aܵ_A|ިsMdt q~rD.}kS~Id2Cj^<9H'U!TWk"W/‹ҟVKG_kcx߉w>,|">~kƜ 8})gS⬏.=Sݿfa|l#1N |i$)"r7 +kZ8)(&W>NvmW 􎄍vCx.+ ^+)dmM*w3`/>~ز#iSo4 LyQvC#'5SdI;OxޘaC/^rxuQɛx's~SZ3sbz}?5aa$/[Ë6g*ݭw u}112Bc\mm(E:n]j- =gto  } ( u"GvV{\mg#@RBkN)E5T%)_}!kdj WPA-WP_A^S%}F>AGN˗ ˒[Wf\A#w+f qFkG H.L.,eߝ/5Y*oIPآt=˥>=V;X=\~ }^ ϙru6.BAEXPxWXP.sx g!lpq/f_sXsw6Xn^w:zV =VVPy =My ui0""αB]xxɃ,xɮ828ݤT& y\M M >.M wr8&Zm Ń{dU夊T~Gm>^ѮR|w&^f1' 6;/Xs-KL+~jE6j,6]!^[<=E4xJVd5+c@moVxohDw4gsPq\f9xx {$ w'dொ$l9Moik-Ҭ&l z 6^EL*^rJ;0(FokL-_W{4E=Oټx' 7ؗ} sK9-Q;ts>w>|o(uc[ ^)\N3 -i>T .6o݌Wto/Q:{_v͎U[ҭ,+{'Z30O̴tu9jd=i~ow3Nn[v' 3};-T$4#fٮ|asuPA/np0/bpsO۪u>pcbּ'>#I-Yf2TKn7\!R@,F^jWL.V8l "AJᑷJIx8 >#<;$(vM˕ $wXr)h*PL4ZIJ= ny=JڐCn^9Dnz6zj5=Q~**@8?ԙ{9bM,~6X^H.+j)`B-1V3utݪIpw؎wΥ_zS1 xΝPmpP)T[ŊOL, ?Y?܀Vh~nK4#+_1? ܻE_@uC-ߡ:0&P]21C-\" ՟ĵc# c}z!PGdf;׋z,=uΧB=sG$;~6m54(W=ᾯNT+>@RzXC ,w&?4\'5؆Pi UTnL)*uTrmZα"T3PGľ (!ݺJoW~ ʢuPRy3Y7npݩ "SFG!E_JpQӁpq.[\!o/6$)2As̏R@a)K:9e'@||g2@\ǻu}9v}׬U=e}"r[ohp4äNtùR: [,ՑpH>R<}/R9+ TϤy2|CUgrrw9)ƑOV(%kr#}?P5r;_|R<ǹǣH\?ȕ ^y)$aP"]W>NϳswD˴j=M=O ͽHT1޻>q,Tw`K]ΤT7ݝ7q@-xC\t^C]4UjsxG!CχZ 'ٚfݎ9%^Pd軎;PsW}OPj3v.huc`Wv.j'^\HX`*ZRrTxx/־msnj'~}%R:};,SmuX>(^j+Z9=|$zl{򃅡ת2bQq{N:G}{c#O"Pn! >͇[Ѧ} xs+>9>+T]rF">5{qWK"/TUCذ* -ӁF@Ǐ*ۧ?ec|?%y>Cנp&9֗ 7h9 E*tÕk~l4r\}&^n5cujRوv #İr:R,+1j;LR|^t6%P#pO5f<~\$I +-[r\uc^lzG { ^o ,-ђ_BJZ85 Kac>[H跟HpVWP~{IRP/ ,gt D7Zܥ6oJOFR;ً7R-NM8NpkN/V*R/5N%ՖۜXs,T]Y휟x{,}Em$T|м?ě2{IW/_2L9jxym$%\I,iE.zM//?g d叅vCuWY4W|Aܧxq`_ĵ$V Tn<8eZ U'+CZ1vyKÖ$ѹy~QԼٱ#n/uwֱo@m;vB^<{C#p6Ae;þ =;06 CgG !Wuabp`Y(44wR;mx*  (<+kfx`#']I{ۣ-=/#?7_D?-O D7BfO#B?M!D?"G#Ei}/G 7#A_$%!_!8ǘ d210cm@6_ i~50)_C(:W!_?D>Z΀+B :O{!B__#@{W 7A.#@OA_/3"@??!euw 0 UK ߁ *g!7E"&&YB_L Y0L<bӿDo?bg!D{@?X{"D/ Zg#߁!l"G߅_ .G_^J]A߈?/8A}{#_9U G??T~!_*C;L!D@"_?  "ODߏ??1!O"OA_ ?7  gC T!?_C@-u!Cொ6?#Gs7 Eߌ_O#AOEύ -s mo!@9N!e?ohǜNYk/En9}7۲XXTTR/inst/unitTests/runit.TTR.MovingAverages.R0000644000176200001440000001131413425330036020551 0ustar liggesusers# # RUnit tests TTR moving averages # # Create input data data(ttrc) rownames(ttrc) <- ttrc$Date ttrc$Date <- NULL input <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] ) input$top[1:10,] <- NA input$mid[9:20,] <- NA # Load output data load(system.file("unitTests/output.MA.rda", package="TTR")) ################################################# # Simple Moving Average test.SMA <- function() { checkEqualsNumeric( SMA(input$all$Close), output$allSMA ) checkEquals( attributes(SMA(input$all$Close)), attributes(output$allSMA) ) checkEqualsNumeric( SMA(input$top$Close), output$topSMA ) checkEquals( attributes(SMA(input$top$Close)), attributes(output$topSMA) ) checkException( SMA(input$mid$Close) ) checkException( SMA(input$all[,1:2]) ) } # Exponential Moving Average test.EMA <- function() { checkEqualsNumeric( EMA(input$all$Close), output$allEMA ) checkEquals( attributes(EMA(input$all$Close)), attributes(output$allEMA) ) checkEqualsNumeric( EMA(input$top$Close), output$topEMA ) checkEquals( attributes(EMA(input$top$Close)), attributes(output$topEMA) ) checkException( EMA(input$mid$Close) ) checkException( EMA(input$all[,1:2]) ) checkException( EMA(input$all$Close, n = -1) ) checkException( EMA(input$all$Close, n = NROW(input$all) + 1) ) } test.EMA.n.ratio <- function() { out <- 0:9 * 1.0 is.na(out) <- 1:2 checkEqualsNumeric(EMA(1:10, ratio = 0.5), out) checkEqualsNumeric(EMA(1:10, n = 3), out) } # Exponential Moving Average, Wilder ratio test.EMA.wilder <- function() { checkEqualsNumeric( EMA(input$all$Close, wilder=TRUE), output$allEMAwilder ) checkEquals( attributes(EMA(input$all$Close, wilder=TRUE)), attributes(output$allEMAwilder) ) checkEqualsNumeric( EMA(input$top$Close, wilder=TRUE), output$topEMAwilder ) checkEquals( attributes(EMA(input$top$Close, wilder=TRUE)), attributes(output$topEMAwilder) ) checkException( EMA(input$mid$Close, wilder=TRUE) ) } # Double-Exponential Moving Average test.DEMA <- function() { checkEqualsNumeric( DEMA(input$all$Close), output$allDEMA ) checkEquals( attributes(DEMA(input$all$Close)), attributes(output$allDEMA) ) checkEqualsNumeric( DEMA(input$top$Close), output$topDEMA ) checkEquals( attributes(DEMA(input$top$Close)), attributes(output$topDEMA) ) checkException( DEMA(input$mid$Close) ) checkException( DEMA(input$all[,1:2]) ) } # Weighted Moving Average, 1:n test.WMA <- function() { checkEqualsNumeric( WMA(input$all$Close), output$allWMA ) checkEquals( attributes(WMA(input$all$Close)), attributes(output$allWMA) ) checkEqualsNumeric( WMA(input$top$Close), output$topWMA ) checkEquals( attributes(WMA(input$top$Close)), attributes(output$topWMA) ) checkException( WMA(input$mid$Close) ) checkException( WMA(input$all$Close, wts=1) ) checkException( WMA(input$all[,1:2]) ) checkException( WMA(input$all$Close, n = -1) ) checkException( WMA(input$all$Close, n = NROW(input$all) + 1) ) } # Weighted Moving Average, Volume test.WMAvol <- function() { checkEqualsNumeric( WMA(input$all$Close, wts=input$all$Volume), output$allWMAvol ) checkEquals( attributes(WMA(input$all$Close, wts=input$all$Volume)), attributes(output$allWMAvol) ) checkEqualsNumeric( WMA(input$top$Close, wts=input$top$Volume), output$topWMAvol ) checkEquals( attributes(WMA(input$top$Close, wts=input$top$Volume)), attributes(output$topWMAvol) ) checkException( WMA(input$all$Close, wts=input$mid$Volume) ) checkException( WMA(input$all[,1:2], wts=input$all$Volume) ) checkException( WMA(input$all$Close, wts=input$all[,1:2]) ) } # Exponential, Volume-Weighted Moving Average test.EVWMA <- function() { checkEqualsNumeric( EVWMA(input$all$Close, input$all$Volume), output$allEVWMA ) checkEquals( attributes(EVWMA(input$all$Close, input$all$Volume)), attributes(output$allEVWMA) ) checkEqualsNumeric( EVWMA(input$top$Close, input$top$Volume), output$topEVWMA ) checkEquals( attributes(EVWMA(input$top$Close, input$top$Volume)), attributes(output$topEVWMA) ) checkException( EVWMA(input$mid$Close, input$mid$Volume) ) checkException( EVWMA(input$all$Close) ) checkException( EVWMA(input$all[,1:2], input$all$Volume) ) checkException( EVWMA(input$all$Close, input$all[,1:2]) ) checkException( EVWMA(input$all$Close, n = -1) ) checkException( EVWMA(input$all$Close, n = NROW(input$all) + 1) ) } # Zero-Lag Exponential Moving Average test.ZLEMA <- function() { checkEqualsNumeric( ZLEMA(input$all$Close), output$allZLEMA ) checkEquals( attributes(ZLEMA(input$all$Close)), attributes(output$allZLEMA) ) checkEqualsNumeric( ZLEMA(input$top$Close), output$topZLEMA ) checkEquals( attributes(ZLEMA(input$top$Close)), attributes(output$topZLEMA) ) checkException( ZLEMA(input$mid$Close) ) checkException( ZLEMA(input$all[,1:2]) ) } TTR/inst/unitTests/runit.TTR.Misc.R0000644000176200001440000000565713425330036016544 0ustar liggesusers# # RUnit tests TTR moving averages # # test reclass works and throws error # test xtsAttributes, both CLASS and USER # test all.equal(CLASS) and !all.equal(CLASS) cases # Create input data data(ttrc) rownames(ttrc) <- ttrc$Date ttrc$Date <- NULL input <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] ) input$top[1:10,] <- NA input$mid[9:20,] <- NA #iAll <- as.matrix(ttrc[1:250,]) iAll <- ttrc[1:250,] iTop <- iAll; iTop[1:10,] <- NA iMid <- iAll; iMid[9:20,] <- NA hl <- c('High','Low') hlc <- c('High','Low','Close') cl <- 'Close' # Load output data load(system.file("unitTests/output.misc.rda", package="TTR")) ################################################# # Rate-of-Change test.ROC.continuous <- function() { roc <- ROC(iAll[,cl], type='continuous') checkEqualsNumeric( roc, output$allROCc ) checkEquals( attributes(roc), attributes(output$allROCc) ) #checkEqualsNumeric( ROC(input$top$Close, type='continuous'), output$topROCc ) #checkException( ROC(input$mid$Close) ) } test.ROC.discrete <- function() { roc <- ROC(input$all$Close, type='discrete') checkEqualsNumeric( roc, output$allROCd ) checkEquals( attributes(roc), attributes(output$allROCd) ) #checkEqualsNumeric( ROC(input$top$Close, type='discrete'), output$topROCd ) } # Momentum test.momentum <- function() { mom <- momentum(input$all$Close) checkEqualsNumeric( mom, output$allMom ) checkEquals( attributes(mom), attributes(output$allMom) ) #checkEqualsNumeric( momentum(input$top$Close), output$topMom ) #checkException( momentum(input$mid$Close) ) } # Close Location Value test.CLV <- function() { ia <- iAll[,hlc]; rownames(ia) <- NULL it <- iTop[,hlc]; rownames(it) <- NULL oa <- as.data.frame(output$allCLV); rownames(oa) <- rownames(ia) ot <- as.data.frame(output$topCLV); rownames(ot) <- rownames(it) checkEqualsNumeric( CLV(ia), output$allCLV ) checkEquals( attributes(CLV(ia)), attributes(output$allCLV) ) checkEqualsNumeric( CLV(it), output$topCLV ) checkEquals( attributes(CLV(it)), attributes(output$topCLV) ) } # Arms' Ease of Movement test.EMV <- function() { ia <- iAll[,hl]; rownames(ia) <- NULL emv.all <- EMV(ia, input$all$Volume) checkEqualsNumeric( emv.all, output$allEMV ) checkEquals( attributes(emv.all), attributes(output$allEMV) ) #emv.top<- EMV(input$top[,c('High','Low')], input$top$Volume) #checkEqualsNumeric( emv.top, output$topEMV ) #checkEquals( attributes(emv.top), attributes(output$topEMV) ) #checkException( EMV(input$mid[,c('High','Low')], input$mid$Volume) ) #checkException( EMV(input$all[,c('High','Low')], input$mid$Volume) ) #checkException( EMV(input$mid[,c('High','Low')], input$all$Volume) ) } # Know Sure Thing test.KST <- function() { checkEqualsNumeric( KST(input$all$Close), output$allKST ) checkEquals( attributes(KST(input$all$Close)), attributes(output$allKST) ) #checkEqualsNumeric( KST(input$top$Close), output$topKST ) #checkException( KST(input$mid$Close) ) } TTR/inst/unitTests/runit.TTR.runFun.R0000644000176200001440000002577113552670134017134 0ustar liggesusers# # RUnit tests TTR running/rolling functions # # Create input data data(ttrc) rownames(ttrc) <- ttrc$Date ttrc$Date <- NULL input <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] ) input$top[1:10,] <- NA input$mid[9:20,] <- NA # Load output data load(system.file("unitTests/output.runFun.rda", package="TTR")) ################################################# # Sum test.runSum <- function() { checkEqualsNumeric( runSum(input$all$Close), output$allSum ) checkEquals( attributes(runSum(input$all$Close)), attributes(output$allSum) ) checkEqualsNumeric( runSum(input$top$Close), output$topSum ) checkEquals( attributes(runSum(input$top$Close)), attributes(output$topSum) ) checkException( runSum(input$mid$Close) ) checkException( runSum(input$all[,1:2]) ) checkEqualsNumeric( tail(runSum(input$all$Close,250),1), sum(input$all$Close) ) checkException( runSum(input$all$Close, n = -1) ) checkException( runSum(input$all$Close, n = NROW(input$all) + 1) ) } # Wilder Sum test.wilderSum <- function() { checkEqualsNumeric( wilderSum(input$all$Close), output$allwSum ) checkEquals( attributes(wilderSum(input$all$Close)), attributes(output$allwSum) ) checkEqualsNumeric( wilderSum(input$top$Close), output$topwSum ) checkEquals( attributes(wilderSum(input$top$Close)), attributes(output$topwSum) ) checkException( wilderSum(input$mid$Close) ) checkException( wilderSum(input$all[,1:2]) ) checkException( wilderSum(input$all$Close, n = -1) ) checkException( wilderSum(input$all$Close, n = NROW(input$all) + 1) ) } # Min test.runMin <- function() { checkEqualsNumeric( runMin(input$all$Close), output$allMin ) checkEquals( attributes(runMin(input$all$Close)), attributes(output$allMin) ) checkEqualsNumeric( runMin(input$top$Close), output$topMin ) checkEquals( attributes(runMin(input$top$Close)), attributes(output$topMin) ) checkException( runMin(input$mid$Close) ) checkException( runMin(input$all[,1:2]) ) checkException( runMin(input$all$Close, n = -1) ) checkException( runMin(input$all$Close, n = NROW(input$all) + 1) ) checkEqualsNumeric( tail(runMin(input$all$Close,250),1), min(input$all$Close) ) } test.runMin.cumulative <- function() { ttr <- runMin(input$all$Close, 1, TRUE) base <- cummin(input$all$Close) is.na(base) <- 1 checkEqualsNumeric(base, ttr) } # Max test.runMax <- function() { checkEqualsNumeric( runMax(input$all$Close), output$allMax ) checkEquals( attributes(runMax(input$all$Close)), attributes(output$allMax) ) checkEqualsNumeric( runMax(input$top$Close), output$topMax ) checkEquals( attributes(runMax(input$top$Close)), attributes(output$topMax) ) checkException( runMax(input$mid$Close) ) checkException( runMax(input$all[,1:2]) ) checkException( runMax(input$all$Close, n = -1) ) checkException( runMax(input$all$Close, n = NROW(input$all) + 1) ) checkEqualsNumeric( tail(runMax(input$all$Close,250),1), max(input$all$Close) ) } test.runMax.cumulative <- function() { ttr <- runMax(input$all$Close, 1, TRUE) base <- cummax(input$all$Close) is.na(base) <- 1 checkEqualsNumeric(base, ttr) } # Mean test.runMean <- function() { checkEqualsNumeric( runMean(input$all$Close), output$allMean ) checkEquals( attributes(runMean(input$all$Close)), attributes(output$allMean) ) checkEqualsNumeric( runMean(input$top$Close), output$topMean ) checkEquals( attributes(runMean(input$top$Close)), attributes(output$topMean) ) checkException( runMean(input$mid$Close) ) checkException( runMean(input$all[,1:2]) ) checkException( runMean(input$all$Close, n = -1) ) checkException( runMean(input$all$Close, n = NROW(input$all) + 1) ) checkEqualsNumeric( tail(runMean(input$all$Close,250),1), mean(input$all$Close) ) } test.runMean.cumulative <- function() { ttr <- runMean(input$all$Close, 5, TRUE) base <- cumsum(input$all$Close) / seq_along(input$all$Close) is.na(base) <- 1:4 checkEqualsNumeric(base, ttr) } # Median test.runMedian <- function() { checkEqualsNumeric( runMedian(input$all$Close), output$allMedian ) checkEquals( attributes(runMedian(input$all$Close)), attributes(output$allMedian) ) checkEqualsNumeric( runMedian(input$top$Close), output$topMedian ) checkEquals( attributes(runMedian(input$top$Close)), attributes(output$topMedian) ) checkException( runMedian(input$mid$Close) ) checkException( runMedian(input$all[,1:2]) ) checkException( runMedian(input$all$Close, n = -1) ) checkException( runMedian(input$all$Close, n = NROW(input$all) + 1) ) checkEqualsNumeric( tail(runMedian(input$all$Close,250),1), median(input$all$Close) ) } test.runMedian.cumulative <- function() { cummedian <- compiler::cmpfun( function(x) { med <- x * NA_real_ for (i in seq_along(x)) { med[i] <- median(x[1:i]) } med } ) base <- cummedian(input$all$Close) is.na(base) <- 1:4 ttr <- runMedian(input$all$Close, 5, "mean", TRUE) checkEqualsNumeric(base, ttr) is.na(base) <- 1:5 ttr <- runMedian(input$all$Close, 6, "mean", TRUE) checkEqualsNumeric(base, ttr) } # Covariance test.runCov <- function() { checkEqualsNumeric( runCov(input$all$High, input$all$Low), output$allCov ) checkEquals( attributes(runCov(input$all$High, input$all$Low)), attributes(output$allCov) ) checkEqualsNumeric( runCov(input$top$High, input$top$Low), output$topCov ) checkEquals( attributes(runCov(input$top$High, input$top$Low)), attributes(output$topCov) ) checkException( runCov(input$mid$High, input$mid$Low) ) checkException( runCov(input$all$High) ) checkException( runCov(input$all[,1:2], input$all$Low) ) checkException( runCov(input$all$Close, n = -1) ) checkException( runCov(input$all$Close, n = NROW(input$all) + 1) ) checkEqualsNumeric( tail(runCov(input$all$High, input$all$Low, 250),1), cov(input$all$High, input$all$Low) ) } test.runCov.cumulative <- function() { cumcov <- compiler::cmpfun( function(x) { cov <- x * NA_real_ for (i in seq_along(x)) { y <- x[1:i] cov[i] <- cov(y, y) } cov } ) x <- input$all$Close base <- cumcov(x) is.na(base) <- 1:4 ttr <- runCov(x, x, 5, "all.obs", TRUE, TRUE) checkEqualsNumeric(base, ttr) is.na(base) <- 1:5 ttr <- runCov(x, x, 6, "all.obs", TRUE, TRUE) checkEqualsNumeric(base, ttr) } # Correlation test.runCor <- function() { checkEqualsNumeric( runCor(input$all$High, input$all$Low), output$allCor ) checkEquals( attributes(runCor(input$all$High, input$all$Low)), attributes(output$allCor) ) checkEqualsNumeric( runCor(input$top$High, input$top$Low), output$topCor ) checkEquals( attributes(runCor(input$top$High, input$top$Low)), attributes(output$topCor) ) checkException( runCor(input$mid$High, input$mid$Low) ) checkException( runCor(input$all$High) ) checkException( runCor(input$all[,1:2], input$all$Low) ) checkException( runCor(input$all$Close, n = -1) ) checkException( runCor(input$all$Close, n = NROW(input$all) + 1) ) checkEqualsNumeric( tail(runCor(input$all$High, input$all$Low, 250),1), cor(input$all$High, input$all$Low) ) } # Variance test.runVar <- function() { checkEqualsNumeric( runVar(input$all$Close), output$allVar ) checkEquals( attributes(runVar(input$all$Close)), attributes(output$allVar) ) checkEqualsNumeric( runVar(input$top$Close), output$topVar ) checkEquals( attributes(runVar(input$top$Close)), attributes(output$topVar) ) checkException( runVar(input$mid$Close) ) checkException( runVar(input$all[,1:2], input$all$Low) ) checkException( runVar(input$all$Close, n = -1) ) checkException( runVar(input$all$Close, n = NROW(input$all) + 1) ) checkEqualsNumeric( tail(runVar(input$all$Close,n=250),1), var(input$all$Close) ) } # Standard Deviation test.runSD <- function() { checkEqualsNumeric( runSD(input$all$Close), output$allSD ) checkEquals( attributes(runSD(input$all$Close)), attributes(output$allSD) ) checkEqualsNumeric( runSD(input$top$Close), output$topSD ) checkEquals( attributes(runSD(input$top$Close)), attributes(output$topSD) ) checkException( runSD(input$mid$Close) ) checkException( runSD(input$all[,1:2]) ) checkException( runSD(input$all$Close, n = -1) ) checkException( runSD(input$all$Close, n = NROW(input$all) + 1) ) checkEqualsNumeric( tail(runSD(input$all$Close,250),1), sd(input$all$Close) ) } # Absolute deviation test.runMAD <- function() { checkEqualsNumeric( runMAD(input$all$Close), output$allMAD ) checkEquals( attributes(runMAD(input$all$Close)), attributes(output$allMAD) ) checkEqualsNumeric( runMAD(input$top$Close), output$topMAD ) checkEquals( attributes(runMAD(input$top$Close)), attributes(output$topMAD) ) checkException( runMAD(input$mid$Close) ) checkException( runMAD(input$all[,1:2]) ) checkException( runMAD(input$all$Close, n = -1) ) checkException( runMAD(input$all$Close, n = NROW(input$all) + 1) ) checkEqualsNumeric( tail(runMAD(input$all$Close,250),1), mad(input$all$Close) ) } test.runMAD.cumulative <- function() { cummad <- compiler::cmpfun( function(x) { mad <- x * NA_real_ for (i in seq_along(x)) { y <- x[1:i] mad[i] <- mad(y) } mad } ) x <- input$all$Close base <- cummad(x) is.na(base) <- 1:4 ttr <- runMAD(x, 5, cumulative = TRUE) checkEqualsNumeric(base, ttr) is.na(base) <- 1:5 ttr <- runMAD(x, 6, cumulative = TRUE) checkEqualsNumeric(base, ttr) } # Percent Rank test.runPercentRank_exact.multiplier_bounds <- function() { x <- input$all$Close checkException( runPercentRank(x, 10, exact.multiplier = -0.1) ) checkException( runPercentRank(x, 10, exact.multiplier = 1.1) ) } xdata <- c(7.9, 5.2, 17.5, -12.7, 22, 4.3, -15.7, -9.3, 0.6, 0, -22.8, 7.6, -5.5, 1.7, 5.6, 15.1, 6.6, 11.2, -7.8, -4.3) xrank10_1 <- c(NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.4, 0.1, 0.8, 0.5, 0.7, 0.9, 1, 0.8, 0.9, 0.2, 0.4) xrank10_0 <- c(NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.3, 0, 0.7, 0.4, 0.6, 0.8, 0.9, 0.7, 0.8, 0.1, 0.3) test.runPercentRank_exact.multiplier_eq0 <- function() { xrank <- round(xrank10_0, 2) checkIdentical(xrank, runPercentRank(xdata, 10, FALSE, 0)) } test.runPercentRank_exact.multiplier_eq0.5 <- function() { xrank <- round(xrank10_0 + 0.05, 2) checkIdentical(xrank, runPercentRank(xdata, 10, FALSE, 0.5)) } test.runPercentRank_exact.multiplier_eq1 <- function() { xrank <- round(xrank10_0 + 0.1, 2) checkIdentical(xrank, runPercentRank(xdata, 10, FALSE, 1)) } test.runPercentRank_cumulTRUE_exact.multiplier_eq0 <- function() { xrank <- c(0, 0, 2, 0, 4, 1, 0, 2, 3, 3, 0, 8, 4, 7, 10, 13, 11, 14, 4, 6) / 1:20 checkIdentical(xrank, runPercentRank(xdata, 10, TRUE, 0)) } test.runPercentRank_cumulTRUE_exact.multiplier_eq0.5 <- function() { xrank <- (c(0, 0, 2, 0, 4, 1, 0, 2, 3, 3, 0, 8, 4, 7, 10, 13, 11, 14, 4, 6) + 0.5) / 1:20 #xrank[1] <- 0 checkIdentical(xrank, runPercentRank(xdata, 10, TRUE, 0.5)) } test.runPercentRank_cumulTRUE_exact.multiplier_eq1 <- function() { xrank <- (c(0, 0, 2, 0, 4, 1, 0, 2, 3, 3, 0, 8, 4, 7, 10, 13, 11, 14, 4, 6) + 1) / 1:20 #xrank[1] <- 0 checkIdentical(xrank, runPercentRank(xdata, 10, TRUE, 1)) } TTR/inst/unitTests/output.volatility.rda0000644000176200001440000003011413425330036020127 0ustar liggesusersyX?𑲄di#ʾ$Z4ƬeC%*Nb~xA6!aE6Dmjk!sqfNj?*::<,`!jQh,Zv kNjt=?~pz6Fq9wUb?ܑ@mBC CcP,'L5t[]L o/,yLn aGBmp7% .'҆B_{';8d&X >(6"c e]+ @(˘Q6A(HJoiHGA`-aЅ>(8v={8wEq)[CքQ3ow. "y j^n>|w$?!PjR^oGI.a#!~$GdD:@(aJtٖ G~}<^T]RGuߦ#nt]ba|Wu@?2Ag;nr1e" na{i"dN+<{}9̟{%Cmhz'Od1)0t,zR3R&5OVm?n~B䔒5֬bOI,9CN~9;u?c.9ne>'q׬(pLz(d5_E;}(Ȳ~ QӬgo\PU#u&'Em p[no %tbخ޺x2 ~4 n25xC>xاI v?*")91X>hҁe=[~l)!4SpNm1#^\=)PM#"b.u{Nӻܪcn5\_ɶ)c1>t] ʡCWCm]Q!8臢C4$xק-qX,1^1hKE .i4,,? އ_h2Cɒ9DſVny׃Ct`'42m`ZQjC!vqQJbdF>8ou;y-p {{b?e+,2DP~3AzvtX}gu=|s9sf_^;at}#^=煿*Z—:tEb3f?F(6(8X`/ƒgָȷeS# ;]`~8G}&nd&X遲\U(0ݹ%oVY/Ac-|&@t`-ZaPYA[Z満;2gI 7,|om7zgfcAz>?H# {'U-/X%|NKp$~ aj+kUx 5q >Cظ^ 5xH/͌k:҅rܥ c)3)ǁ?'|C%:iW-lò0+[p8Zۼ'\Χ;7CX;fa%Y^CޠD7 ek =;[\t-a*$a P%9|s,w܋v^^C޶)ܬ .n켕!;8e/p8 ޼Kܖ`+P_΀7o{Ve.p1sT+xm2oa̎ Y_ rUVd̅'=i[rnd 5󫋇!|bzϚ>+J&܊2Nڮnx'Q[zk!^jA0])VBYMHd@T<S+e.q~{dDoJMhmK<ȸCroCepUuw]"W]!8rS~p}Rj+\V>fD5~~`9ܛ[M:}`5ps˪h+H^z?ѡʰm+_\hM=/Y #35L~}ɮk}.Jy>6UEics?^868wSk65B2}k\kq$ O#B8+ q%3NB8h9ҁp <"SN !لp  Lg$!p;FB8"3NӟVB8Vp>9Clj#B8pt &ցp2;:!ip~‰@8 xyL7!pDp‰ Mga;!pdpGG؁p‰'sN_B8c ¹K'JB8B8NpyCǨ#SAg'!KpCGE4!yp"$yIǙNOB8لpB $#%MI'N!!"B8!p$Up$s%%(&JQL( G1QB$H( G1Qb$DI8p%(&J{$ɿ$@\e0MV.>(=ۨnRYVfAv{9jz&зBSzlgiȢ;!nw m:5RO fyA,Kn8/i0oċ!Z}US{fLU7o+! (}<iic;𷑷[(DC|?C8rvCwz [c::Ύs}m8ՊvBq`xVMHz'LN@41N3x>WYb^Boe t<߂'O Qޢ7В; +-!3#{&߰{q'WN0v_;N2SYM$ny߶_g"E&oUU<;%i͓Qt.K87Cы/'%xWZO`+o;y{QsuC }3~'qoօEv ;qN/15qR^ рHYG&>51lX'Oȷ#}krx$`;s cseb;by?yQ{sgsv/EvE-Z钝=л-@xqVW񬐪6:~7{(N|[a[mءi&:S-{5w -NSb/ LɜN&u)prrUeq`Lz ;akRc}P,q@6oKl 7?v{ |b:6NDNZkBuҼXGm,x|8D>lٷ^Kޤ|h╓Z]/?zp:&JQL( G1Qb$DI8p%(&J{$p%(&JQL( G!Qοȧp3N!p^!LǓ&!لp 0 ,'@LjB8 p'Lg&!#B8Fp&™B5!KB8g ‰&"sN;!Մp,!cHg.!XB8 !Bg+!B8΄pJ E'!p"Cg5!Apl &cKǏ&! pr I"B8 $‘7±fYI'N! B8 l#OqB8p^YA !opIǎ)!ՄpYFg!фpOLJ+!VB8K&3\'3hB8g $3N ! B8p DL7!%p L$J!Kp!B8%pn &# G!DŽpT "SDg"!=B8p>©$3N>!ۄpBG!B8pp%J!+B8g I SD!pMGN$!B8GGǗ&B8=L cH'NB8:pF@!p”1Qb$DI8p%(&JQL( G1Q%tH( G1Qb$DI8 p>#\RD#LuPw]AY$q//׌]!(ﶣ)­xO!&Hu m{h]=?tul kdmM(yҾb[9[eT*3Ǫ̼B$ b.I !bbQp}œfκk :o\ʳ_~ )wq N˕{W`ѲGƳ=u˨+B: m!?Q-|NDa! 9C7"^%5_A8}/)DMU۬[ 2)>?-@2Pb9C l { =APTMg4˶=Ë*׃yu[4xOW-%-M?2 h;ulz6u9'6EUנwڠ(>-\Mac6$: t>~7b˦-\-d>o}+IbL3uŴ/H^kѫL+4GzcݖCRC 4aBB$-eow^ 6n;ϳyݔ#n;ir "(4y {'O?竮4U t_ߺln0 X \{#n|:e p4m o~e0++wXvÍneTTH e@ҧ?LtVm-6"-p͛s9ۏ>/X?_;%"SQr)q/l"JW[dn^g:FcdѫWR p\p'/[`Kn^ 5]-˂Bl?懭?z >~9 aMB{%ߖݺE͘iPrNu޼~!5r3S sXPm \f@ qFe6a9U߹S~X{C|\,m{|𵵊ulYMkr@ Wmy] @bxk RϾ]k[X WZ!8h@\|eo{, fαG[Y0y"Wz74]JxPWnد^.?tG>-'Ԇ`xJŮ(7$ev[J=Cw utL^har.'!|qN>?nw&"ÎsL!y'k&@tMdD2j7|{%:iC Zu'KzK݀!(絤 eüM7}EN ?svdQo x_@5̌\keNcDUHԩ># 9bP%]DI톴V<к{JP:ˠbS@d6@]k8s߱B2q,w aUNDI8p%(&JQL( G1Qb$DI8O!Qb$DI8p%($Jp$%( GI8JQp:$JQL( %(&JQL( G1Qb$DI8 p!Qb$DI8p4ny}uY Lh~< 3nj*vZH4a˨ *®0}nz_>U=u/fV )U{ԅ.c??fյ)a *k@-TpaHJwjlmV\J)1ѧ8V+T#R"zRK-.ȧ/9\" QMݷ d4䢩wY6Ap?6 hg*#ѫ\),ӜB!:#>17~=Fݣqooa 8h6-sgC02#'8u]N6|bWJ2)ܾRQ/W.7+nOdP BIlzx@eqf #fEc>*ycC5W)U^)t}AUaJpE|6D}ץVC)~?^̲ѤB[;yr3餷6g[>~{*jMey'6"* ΚpgNU#'ۃ.9R,>Ф>:> 'w *3) *O@|OI_\He \;oy+%|!7U|ޕwjN J2rUzMS>T";B!'ɳ3k ?WWeBzGɡfq;a2D}^K'9x+VWS ;1U:պ`y%-^M {x9QyQ~ҍY\fDQ$z}R>:1 azhjdcVuQy0 #GC*i`t[*Wѿt!8/< `_h;T2n >&T9&'QM9jziE榹xP~AC.ѝǃ󡙫ܜWcr/޻"9dk--*Oai(1wa0)p-2󳮴R't[1tmQwAeuۙGܓF rYe)|M~XPedD.ytrҧr6o^r:m\sL[0Y9 &#S/nLwTzzPڪϦR9u:yÏc LhnF+Jӫ:)ueoYTW;Ck;z&.|]y >OjCzvi\<"um. qz`<~ܪsCbs.^=E鸽i}OdƏ]^yŹC- ﶡ8iJ#MT+@ᬝ '\[)pm{MnK|ɓ(!EU'OV]N} ܬVi]+m+,ב7Jf]3F\v@}4gz=΃ɈrVEȏ+H3N4v"N5ai{"`쀕.&Dl1*7UTnߪ1ב&rU?yzZk{{ڻwlɄ!&&&!&AA8/ [m݂o 5bW]lpw e~F?^ۧd6< ˷Yr C w@'aģHHYK'ݵ@G4y:*_b C@@pis{C|O]G@qD̤qmx|vTo^nS<G9y-u@[W^M`"3xSjM`va]6D2{DiM ;--@dL x;oqx x(;;qW_DsHh\2Tf=4?\XҊ+@ @9H\Rt?$~.8n5Q)l@ŝ)PyRYJeZP\XŹPP\g^uPܸPmN N&b(n7ņxc@sТ롹c hnLƷO/0<)#pq w^Y".׹Z w^|_-`Kُ``y) `8y|Mg>Nbgæ<chW6ܮТ:{Z:`yg*0lh\vl͆\|4F itTgOy8wJ7FŦRO؟2P\wIw>%QQGP<(~3]Q9s9w='nx 7xk/hvC 4w-Zh.0lڠ08#:p>=Np%>Q-[]7sssps@ %|]0 i= 8{ `V녾ppa%y=?i纨_/Ifi0;^\Т^\4#=_ra)>Xl=RW@X$ l:ن҉aAGQw5}cˀs˘R" ǔ-p F^lKE7vx- =: r@޲{l';WFwn*bz'$YS~2 %z+5: dy!"k˄~  'DC[ ;NqESAj #w7 j j5@4%Ʃj#ϗ.Y)o=DkDbm vWLK>I.KA=O,~I\/"y'y!we ō4!wTCocv@}pZd8{l;6YDȌ-X/M3U ľ/fVMs85G+(:?hoo#b͞=ؒX\Zqtkb՛83jH"`StjS!:;qxh,^ы=Vl/^š^vk$uYR:`ݐc8~ ~+DiDZN*b-x ܪS('*|]W>I >{䜱/:,ot/:2an j!E8Z4O?o; AZ@jݬJc\o6O:1:3mnYϿJqn_ۀYټ`|܄y}B/u3̧g+?eߩmz вexa==pfVvHn^@_qba??dFŖlϦO}Z ]j{=+ekwV^)yy@_zS _Buf|ֲp͗,<.nZR }̂C:l>,x]!ί0ewf\?#3rSx\ۗzbXo2㋜!krxv!0&q-^Gp)UYɿ~(rf_̈`uG9B 9wʕ笆L_!z0>w0!ûq|: y|P{h/خϵ@PKlcO\.҉z~b@kto.{vc||b=PK O+kwix:vgH\6}_띹I*~LPSt6b\u7EKa֟@OΈyXur. V^ԥ5IN7 -@5\_U6 󑣲ɫBJ??.o`#+ I]~#U?9 À 5pf8,x=e>عqM,}a\d?wZf eR@~WI P[ye _r6 ̿yxO@=qrxTZpVM*W4i8jI'n" 4轙/7 suhxƺY}W)]nYT@ȧ[ukq?.x埍g{eMVnh@G`DH3>OjTF .eG/BfWX-Dsuww_tQb o2*EG߶={>̎yK=0[?c]/~a ;ݿ! ڡR/W؞*sf'mb]Q0u}\AzН|t;}|a:~4n{ tTi!+p;j*/y)ƺNdºc OƳ߬Ⱥ5oFFzXu#GW[Yw)Ra]κn0͈x?lX n_̺^3ћum8eǹ ƹ1ϥ9ׇ\7ݬȹ| z^1ΙGsQĹ~sYm!sHʭ9?'s\?s'm[9Ͻ\\zJ-zV/J9שo #t;ޟ&'n4s}p1B/]o(.)t]a9s_Msmׅ8 ]?.t=WzMu{Bpgޑ+tB$\_'r "G ],r=TpA"uD;\%r}uBD\>C亻q"ח\.r=KEK\_/r] r=S] ׃=x#9^xmW??>}]8ЈU> 繵p6T?1\y}99oOeցdm˛z@V|a`7Ǘb +_~낶YXge:?o) g5viE6ϟ1w2YicEȪ @`vt仇c&%Gy&o9N1o|2~N]H 7"w"y{@F^PddնaӀ۰ݣ eUSx}ert/ Uf-eʩ 23 ğIRݠJWc)9ہ^S֫%to/ ObG\e]/u>Dn;˓FR$ '3ἤo@n"1Iv8nvr%XѮwHwep{ lnhꙇ`:~ &͚%t}Wpm9y-. A1ny-@ȧ?y"sY/ 2>zuC5@ׅ&"hܯwkO -?z[ii_zqڑM4_90H.s4301kB o*oS V1/dFʕlJqU QFcɠKc"֓'(=|q PkGVjWX/mjY<[ޮIkVm@GGkbߪ 3uJ'~2w@EXp9'wqH:L+e͘W\s!薾m֯3`~dz^_*~6mlk./w ob~g1*~.cy=u3>nߎjw=QKf,luz\0ߏlzm}` |4'UOkF`BW p6RKa1뛑iϞH߯ =}-ɗ\lpaKН| w~(L:~W16Z tVDc?}:&u. S'`]3Gv*г] <9E=xhS"Ǩ|n;|!-9"?vAD; eNu5嗯o` r>8Nz0V)@j~qLͺ!z\s@QHF/p=z3^]W CzwF e^[x1p&XA ?hG?xjd̓V8ߝC3Zu*κ]g6q(Ӊ(#KCכN~KBT y?m`>)J5>f]Jds<6exKqUfgN LA#wfKĦjcq>mf{FmNc]O?^w]/p:^"vEם\va\L^LND_D+W'"8E7H(TkFD_yp4xx^9l8v"Ο3p[M,yuj?],9?/{5ʷuJt=x_cnYUi&Qz̫KXׯIuǽ8q뫜fpnZŹ>}1@Ks}uu'M+:9ן8c]'q)su^q[Vpa.\?Hq\Zsu8yvqGs\ωzù{s"'g\Ϛj¹nvsR w&ݜv~ tF)s+?N\'̹^V1s Q8ו\ ]o#tEz[8/~BCZ3yB׿~wM78#?\(t}k;Y ]o!t B ] UjUׁݑ/^nMryWQі?屟9`ms2n[t@f d_oپ`@m4gNb. yIv@X\P!\ ʾYɍ ĸ~H|2}-ћ0 Z:(2:ug;ͧ:s̋r׆|[?/_Fi'^֤ HaW2ѳ<%}zeGn],+]p_ dDVRA" CEYDv@]`Ӂuϊu/׿0܆κ^"uؗ,;23&@t=Ē?=bǙ]׀GUnj"}l}K-úᬲ\;@D?y=+(6g9Et~dož9J{ RJ7/6 +zF/`ƛ<3D{ tyZ pcsgx쳍M<+b !+[sμ>yhH2t8GbXw'Ǜ1z3Ox /p {h lU]Ǭ|_?߄<ُ'Ϯ1}ɧu{p4i1F>/J_ PVα/YK\ Iݢ@}:-Pfϔ#7sslx@yXt 6Jw]*qu9'c4G-Y2B\#tHC;wOtچn)GZ)-Rtة9IGm؇tK|f%'˙~kyQq!.gotgQ,MŠ#+ޒGr0Vs| _z~;0?}L}>E {LREpo[VDUW0ƧO-=t3ˬnk`Ċ+~%q|-hq蛸6dvV:;ziy?nk _.X̜ؖ;|z|[V%=5yeY!03nl,{y6㸟30sfQlSbG@g t>k4\rT}G =Z&mjh%뫫=dc,Ҙ^m)XoYSN '}L;uA f9Iٺ1c7 Wh$YY?9Բa>9{mnub7|`2 c0Nk N7UGU{Zhnt5~WU4D4У@ЙoZ\"$wI,֗cw8c}ҿhGצ9L'f%X,gy ~Nۺ<aSUo}`y]o^菮V-Ae&|G׍WnXNGJVB?lߍ(AחFkSԚToIz{HC`=ux{-Xt=]qWhg5WZ~v֨c]u=R#xިQ/SX׋tf f]?j7`únź§uzY¤Y- `]7xzK25g]OXu)xz۷FqI_%{жe]e)M%Zi7f*ng]w/uqb]z+tz9=kY׃<\{fc 9ח<\Ŝ.JqQ9׳]Xݜ&n`]>Ϲ^^缢9s{%97wO\~o!:[\O}>ȹ>z[gq;?ιqn#\Ogh.tgB׳ ]_RĹ>kB ]o~Y躩Z7 ]n/t%B躇E焮Wh ]_)t]Vz\#$t4)Bף҄W ]OG#" ]9Rz"DoLJ'D-r}u}D&r}U"E}QslVJ6@_٫?/zj^Cf~4e y@MX{n.T"7" Rb]Or8QejǗ:^0ȥdQ沕xGT{4UٿN(8#J@Ig!#m޹@6Q)oB?<ƾ%`u>-_} )s<{;cϴG(-,4C/~uVU2T9 /lR8Oq;x<ԗ<~(;p8˿Jx9bg;NYuQ{zF {,gkW g#x4P!iU_FOy*o=_{WrV軗^=t9@D&nD #)7-=8kܭPl> z凯1#:հuxinkm}.*" +neK8:@F|bE@16٨'u$dJb6c:x6@:^JoZeL4y;|1bJsmcN&{Ǐa@@82Jïi}sB&@u.J`LPz܀cis5!PJ21,󶥸 :P w fbck'-*}Zf4N@?V-aí?GW)t`̉}*.Wa6 naws>>>s 79!Xc RPgWt5"`f>¼w|u'C0(~]]uNzwʆq.`K6oJP_+Vp7s ج?Xd_ 5o-sxj#/^ߜQ .cv푋>j ts/g8pa2m#̓/g==q9@K}׾];;y@5\蹧01`g( +4`d;=~îşd6i-8渭~O|kOb(lԪ?OuB {P\>z((cZ}1Pʁ\[v/I_'>3<Q/N m&@7ze!@_iE1xЂYOS֣?3B|YN6z@Ϙp6}E Uw_`# :"X3W-5lѦEOA :< `G+ǧ!D ޟN<_-,|lNڝ :$q&nG@ /]]]]sx7eoި*雽m wk0_KJ QBnF]ƚ5@L]"70ˁX(aZ 6UEo`?kDESJ z.& {@Z$\T_H=/mT_* WVIyZUC =yM ȇjr^<ͽgYLY?cT3ՀKY%(|W:N?Ťi~>֢ȯoFrd [#_iY= #>FJ˷]Mٯ]kςQThDO.Q&o*Μ!@\WGJ/>Q$Zi| -q躂kb x{@W̌~&ʓ HuXT bߡ@W^=|CcU}rH/l bT >r 6:. 0 I@DHuEVENQ3 >:y 729{tF-)S |Aԗ7W4sĂ `G+q/;LbI N[8o^_TKN*0]9:?Fp- ^Z3-ۺiIk czWa~uu@2,r8* 䧹Z1ʬl RV{bV՗Ge@}i4i?2#iRW 4ZζYU{m.+z`꟭5RN̏*]O;(0 .& J[? X琝ٻs\00;\;qW0{Nu̲`,Ίu0S^,s8h|06󌇵>Ԩ0[ vv`>%8X?qj~N09pdb`@#\itAJHw< zoXu7;o`xzW%3bWd`H?]ɎzσLJzs_ۋN ~Mq0YzT?n:eԚ@dazqEsdĖt`;eWSwZ*E._X9{~YOّ^S1@ܮ l8(.I= Xܛhn5 ܉q+9D,r]zA?wQ^+Nע'&Tbf 3]$Yo+w4aS c= 6hg>!$~M bYgrF=8 @R/T&On`]|8w58(qIO2k!^gM+H>?[g5.zdm-o; ę7i< Y8g/ VDb˻Ƒ8g%s3uB'NzbIW{d 4zSZE4_B q=I"xnk{z;C5}}}<8Cf'_Ι\k=Zq5M%qe;jDbE@fdžCr1>X/ u9a@,˴[ 8M ;ŀ|{l7nc/++˳->} f-= 3WmuJUy{F\.`O^J=jG|TNk{gl Jt s';JU-3Oo{b_x]U|sFn-(M@7NN!;{Ƀd2`,XIF`sUJ`贎칲h_ φc^?[0R/vwb'ӟ- ~KSLg^^|u `_S|KmWE/z?Z[0^Mce< R`&p-7uƜf.m]n`}j6i`13Q䡊}9,P}Lc9l`.)[+;u|b"1n}Ykqv"A =fgWrWlx# h¢@Tdm@G>'_6v+p>R-^9Y+}zV`CtϤf|}h1ՠ@WU@q( ºc`۸tXQ >fn:?P#hU'P xGtw/Z_q|{1aM&3es7~=MEo{V9։}~ >e/w}#^e2.7WSRAa',8m~㓳8S񞙫[%kv@E9)?A0\"dsn|WHN^1?߯ HȘc;aH5|}t7<ҹHwݤ4̟kw}T;  -LSo; ȫI=7@OoVRK%}|Wˑgk0pzؗ7+Љ+<;*tA~Νy6vz_UMmBt\ XYOsT,9(!:Ni.úE|)iO;.BG`C@[eo#] y+,u|>_%V>Fu@8xs>~ݪxĹ~D~k}qԻ{_c}vY玠%$@tyVv]슮gNu"~k5~c.̼̇': _bX|*c`oO|"RX%uR>{vz2wCubt[Ms e~HܽXח}B ?~˰$zZrƬṛYד^z|~ n(:@ W>Rdz{~Ǻc]Xuܳm[e];Gu}a;c땍聆d]_^T̺W?d]Of]_;=8z]륉W`]?Vú2IuqլcuN7`}KX-- gY׃7OͺozZ#ziʟleb!8\.Ǻn뙫X׍L%9}N\wuzWus8s/Ko9׻N\7ɹf\=뇬9YP8!9K{r߻^¹߮ϹbTϹs׸ ű6~ yP!n!c_n?!<ObЯL)_l h^9}9xؗO 5KL]ߪ0>w .9ӃӰo'skOCBgzk7`?r@>ҵ b%4ȋ1:zc*|"- 22eWr. Ӯ~V7[ t?~n] F!@ݕ@,0?QS@dpF/o~:{0|a?ozw/&p1rPz'@.,:Ww` w,t13^oA@Hipp]t:XKaPH@w>cykAc~3DOoمs t09F@疋+hOeiw:t^2qFSnf~r60& ` G|zږ,`fFf{(ʀNi z<}Lϋ0>Nkԙտ_rΦzY%jf6f+ 7wߴ_{UДnƈ7_3zMsğf-B/VbVtNN7@{Won<0 }fZlgĭo)_}}.rq1G6!nj.l=f߸cx\@+DV/sH)˃aŒ-HhbCI$p{FOmWW* 2y3շ*;Kw0q}x|,Υ+&Ho Y`#7 G 琄"N rKq%蟭Y1\$\t}[ kn}E-\WZjF ptp@\/0Rոy_6LWgzyi;!ph8iy\x0[7d&>Ap]B ?y\ ifluk|:{O\_O!=*ˈ]zue*!uK8zq9q=!/"$~:zU(q8u^E]RA\WPׇ 7˩OMuc*wyG7u|uu&kuYF]9@]w`;P׷3sf˙u9sc s\`3m1Bzs݌~.d\~z sݜsW\_veqQ_/fY \%',浨"2*q>GG,8O4C +^.2x|u #u3 cx-&pC!~TTR/CHANGES0000644000176200001440000003000413425330036011712 0ustar liggesusers#-#-#-#-#-#-#-#-#-# Changes in TTR version 0.23-0 #-#-#-#-#-#-#-#-#-# SIGNIFICANT USER-VISIBLE CHANGES - Update DVI to use runPercentRank. Thanks to Ivan Popivanov for the patch. - getYahooData now returns an xts object with Date index (not POSIXct). - MA function colnames no longer based on input colnames. NEW FEATURES - Add HMA and ALMA functions/docs. Thanks to Ivan Popivanov. - Add Ultimate Oscillator function/docs/tests. Thanks to Ivan Popivanov. BUG FIXES - runFuns now throw error if there are not enough non-NA values. - Change all instances of lag() to lag.xts() in case 'x' is a matrix. Thanks to Ivan Popivanov for the report. - Correct output column names in ATR docs. - CLV now sets NaN and Inf values to 0, instead of only NaN values. - Fix OBV so OBV[t] = OBV[t-1] when Close[t] == Close[t-1]. - Fix dead links in documentation. #-#-#-#-#-#-#-#-#-# Changes in TTR version 0.22-0 #-#-#-#-#-#-#-#-#-# SIGNIFICANT USER-VISIBLE CHANGES - CCI now returns an object with colnames ("cci"). - All moving average functions now attempt to set colnames. - Added clarification on the displaced nature of DPO. - SAR now sets the initial gap based on the standard deviation of the high-low range instead of hard-coding it at 0.01. NEW FEATURES - Added rollSFM function that calculates alpha, beta, and R-squared for a single-factor model, thanks to James Toll for the prototype. - Added runPercentRank function, thanks to Charlie Friedemann. - Moved slowest portion of aroon() to C. - DonchianChannel gains an 'include.lag=FALSE' argument, which includes the current period's data in the calculation. Setting it to TRUE replicates the original calculation. Thanks to Garrett See and John Bollinger. - The Stochastic Oscillator and Williams' %R now return 0.5 (instead of NaN) when a securities' price doesn't change over a sufficient period. - All moving average functions gain '...'. - Users can now change alpha in Yang Zhang volatility calculation. BUG FIXES - Fixed MACD when maType is a list. Now mavg.slow=maType[[2]] and mavg.fast=maType[[1]], as users expected based on the order of the nFast and nSlow arguments. Thanks to Phani Nukala and Jonathan Roy. - Fixed bug in lags function, thanks to Michael Weylandt. - Corrected error in Yang Zhang volatility calculation, thanks to several people for identifying this error. - Correction to SAR extreme point calculations, thanks to Vamsi Galigutta. - adjRatios now ensures all inputs are univariate, thanks to Garrett See. - EMA and EVWMA now ensure n < number of non-NA values, thanks to Roger Bos. - Fix to BBands docs, thanks to Evelyn Mitchell. #-#-#-#-#-#-#-#-#-# Changes in TTR version 0.21-1 #-#-#-#-#-#-#-#-#-# BUG FIXES - Fixed stockSymbols for nasdaq.com changes (again), and attempted to make stockSymbols more robust to nasdaq.com changes. - Corrected final calculation in Yang-Zhang volatility, thanks to Shal Patel. - Corrected k in Yang-Zhang volatility, thanks to Ian Rayner. - Corrected s2o and s2c in Yang-Zhang volatility, thanks to Ian Rayner. - Corrected KST when input is xts (res is now * 100), thanks to Yuanwei. #-#-#-#-#-#-#-#-#-# Changes in TTR version 0.21-0 #-#-#-#-#-#-#-#-#-# NEW FEATURES - Added variable moving average function, VMA. - Added Brian Peterson's price bands function, PBands. - Added David Varadi's DVI indicator, DVI. - Added wilder and ratio arguments to DEMA. Thanks to Matthew Fornari for the suggestion. BUG FIXES - Changed wilderSum to seed initial value with raw sum. This matches Wilder's original calculations. Thanks to Mahesh Bp for the report. - The BBands sd calculation now uses the population instead of sample statistic. This is consistent with Bollinger Band literature. Thanks to Jeff Ryan for the patch. - Fixed stockSymbols for nasdaq.com changes. - Fixed ZLEMA default ratio by changing it from 2/(n-1) to 2/(n+1). This makes it consistent with EMA. Thanks to Dirk Eddelbuettel. - Corrected close-to-close volatility. Thanks to James Toll for the report. - adjRatios failed (spectacularly) if there were missing close prices. Thanks to Garrett See for the report. #-#-#-#-#-#-#-#-#-# Changes in TTR version 0.20-2 #-#-#-#-#-#-#-#-#-# NEW FEATURES - Added VWAP and VWMA, thanks to Brian Peterson. - Added v-factor generalization to DEMA, thanks to John Gavin. - Updated volatility() to handle univariate case of calc='close', thanks to Cedrick Johnson. - Moved EMA, SAR, and wilderSum from .Fortran to .Call and used xts:::naCheck in lieu of TTR's NA check mechanism. - RSI up/down momentum now faster with xts, thanks to Jeff Ryan. - If 'ratio' is specified in EMA but 'n' is missing, the traditional value of 'n' is approximated and returned as the first non-NA value. BUG FIXES - Fix to stoch() when maType is a list and 'n' is not set in the list's 3rd element, thanks to Wind Me. - Fixed fastK in stoch() when smooth != 1. - Fixed segfault caused by EMA when n < NROW(x), thanks to Douglas Hobbs. - test.EMA.wilder failed under R-devel, thanks to Prof Brian Ripley. #-#-#-#-#-#-#-#-#-# Changes in TTR version 0.20-1 #-#-#-#-#-#-#-#-#-# NEW FEATURES - Updated CMO, DPO, DonchianChannel, RSI, and TDI to *explicitly* use xts internally. BUG FIXES - Fixed bug in WMA, EVWMA, ZLEMA, and GMMA; results were not being reclassed back to their original class. - Set colnames after cbind call in the following functions: ADX, aroon, ATR, BBands, DonchianChannel, EMV, KST, MACD, stoch, SMI, TDI, TRIX. - Fixed bug in VHF; missing abs() calculation in the denominator. Thanks to Jürgen Wurzer for the report! #-#-#-#-#-#-#-#-#-# Changes in TTR version 0.20-0 #-#-#-#-#-#-#-#-#-# NEW FEATURES - adjRatios() creates split and/or dividend adjustment ratio series via C code. - GMMA() calculates the Guppy Multiple Moving Average. - volatility() now has Yang Zhang, and Garman-Klass (Yang Zhang) calculations. - The functions below now have cumulative argument. This allows the calculation of "from inception" running series. - runSum, runMin, runMax - runMean, runMedian - runCov, runCor, runVar, runSD, runMAD - Added internal smoothing to FastK in stoch() via 'smooth' argument, thanks to Stanley Neo. - getYahooData() now uses adjRatios(), which yields significant speed improvements for larger data sets. BUG FIXES - Fixed version number; 0.20-0 is now > 0.14-0 (rookie mistake). - Fixed bug when maType was a list and 'n' was not specified in maType. This affected: stoch(), SMI(), RSI(), KST(), MACD(), TRIX(). #-#-#-#-#-#-#-#-#-# Changes in TTR version 0.2-0 #-#-#-#-#-#-#-#-#-# SIGNIFICANT USER-VISIBLE CHANGES - getYahooData() now returns an xts object. - Added colnames to output for ADX, EMV, and CLV (for xts). - momentum() in CMO() no longer sets na=100. - Replaced 'na' argument in momentum() and ROC() with 'na.pad'. - Moved maType argument default values from function formals to function body for the following functions: ADX, ATR, CCI, DPO, EMV, KST, MACD, RSI, TRIX, BBands, chaikinVolatility, stoch, SMI NEW FEATURES - All functions now use xts internally, adding support for all major time series classes. If try.xts() fails on the input object(s), they will be converted to a matrix and a matrix object will be returned. - Added 'bounded' arg to stoch() and SMI(), which includes the current period in the calculation. - Added the zig zag indicator: ZigZag(). - Added volatility estimators/indicators: volatility(), with the following calculations: - Close-to-Close - Garman Klass - Parkinson - Rogers Satchell - Added Money Flow Index: MFI(). - Added Donchian channel: DonchianChannel(). - Added 'multiple' argument to TDI(), allowing more user control. - Added naCheck() and implemented it in the moving average functions. BUG FIXES - Corrected NaN replacement in CLV(). - Corrected williamsAD(): AD=0 if C(t)=C(t-1). - Corrected runMedian() and runMAD(). The argument controlling which type of median to calculate for even-numbered samples wasn't being passed to the Fortran routine. - aroon() calculation starts at period n+1, instead of n. - Added NA to first element of closeLag of ATR(). - Corrected BBands() and CCI() for rowMeans use on xts objects. - Made changes to Rd files to pass R CMD check on R-devel (2.9.0). #-#-#-#-#-#-#-#-#-# Changes in TTR version 0.14-0 #-#-#-#-#-#-#-#-#-# SIGNIFICANT USER-VISIBLE CHANGES - Changed default 'type' of 'ROC' to 'continuous'. - Changed 'BBands' %B output value from 'pct.b' to 'pctB'. - Changed 'WPR' output value from 'pct.R' to 'pctR'. - Changed 'WPR' MA output value from 'ma.emv' to 'emvMA'. - Changed 'aroon' output values from 'aroon.xx' to 'aroonXx'. - Renamed: 'chaikinMF' to 'CMF' 'stochastic' to 'stoch' 'bollingerBands' to 'BBands' - Set 'na=NA' for 'momentum' and 'ROC' functions in files KST.R, RSI.R, and TDI.R, and changed 'ROC' to use 'type="discrete"' in 'chaikinVolatility.R' - Made the following changes to the 'ZLEMA' function: - Add ratio argument with default = NULL - Non-integer lags are a weighted mean of the two nearest observations, based on thier proximity to the lag value - Change 'lag = ratio^(-1)' to fully support 'ratio' argument - Changed the 'BBands' function's 'sd' argument from a list that allows other dispersion functions to simply indicate the number of standard deviations to use NEW FEATURES - Changed MA-type args and updated documentation for: RSIm ADX, ATR, CCI, DPO, EMV, RSI, BBands, chaikinVolatility, stoch, SMI, TRIX, MACD, and KST. - Added Stochastic Momentum Index (SMI) and williamsAD functions and documentation. - Added Fortran implementations of SMA, EMA, WMA, EVWMA, ZLEMA, PSAR. - Added NA checking/handling for many functions. - Added 'ratio' argument to EMA with default=NULL. - Changed all usage of 'rollFun' to their respective Fortran implementations and removed the 'rollFun' function. Added Fortran based functions are: runSum, wilderSum, runMin, runMax, runMean, runCov, runCor, runVar, runSD, runMedian, runMAD. - Changed 'CCI' to use 'runMAD' internally. DEPRECATED & DEFUNCT - Removed 'oscillator' function and transferred functionality to 'MACD' function. - Removed chaikinOscillator, since it can be created via MACD(chaikinAD(...)). BUG FIXES - match.arg(type) in ROC changed to simple subsetting of type. - Changed trailing zeros to trailing NAs in DPO. - Fixed 'WMA' bug that allowed 'x' and 'wts' vectors to have different length if either series had leading NAs (similar to EVWMA function). - Fixed 'runCov' bug that allowed 'x' and 'y' vectors to have different length if either series had leading NAs (similar to EVWMA function). - Corrected EVWMA to start at period 'n' instead of 'n-1'. - Removed 'message' function from CCI.R, VHF.R, WPR.R, aroon.R bollingerBands.R, and stochastics.R. #-#-#-#-#-#-#-#-#-# Changes in TTR version 0.13-2 #-#-#-#-#-#-#-#-#-# SIGNIFICANT USER-VISIBLE CHANGES - Changed order of oscillator() arguments from 'ma.slow, ma.fast, ma.sig' to the traditional 'ma.fast, ma.slow, ma.sig'. Thanks to Jeff Ryan. - The arguments to the chaikinOscillator function were changed as above. - Changed EVWMA so period n contains the value for periods (i-n+1):n and so periods 1:(n-2) will be NA. - Changed EMA so periods 1:n will be NA. #-#-#-#-#-#-#-#-#-# Changes in TTR version 0.13-1 #-#-#-#-#-#-#-#-#-# SIGNIFICANT USER-VISIBLE CHANGES - Changed 'bbands()' to 'bollingerBands()' - Changed 'DX()' to 'ADX()' - Changed 'stoch()' to 'stochastic()' BUG FIXES - Corrected mis-spellings in documentation. #-#-#-#-#-#-#-#-#-# SIGNIFICANT USER-VISIBLE CHANGES NEW FEATURES DEPRECATED & DEFUNCT BUG FIXES