[
  {
    "path": ".Rbuildignore",
    "content": "R/pivots.R\nLICENSE\nWISHLIST\n^.*\\.Rproj$\n^\\.Rproj\\.user$\n\\.git\n\\.gitignore\n^.*\\.orig$\n^.*\\.sw.\n.travis.yml\n^0.*\\.patch$\n^.*\\.tar.gz$\nMakefile\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: [joshuaulrich]\n"
  },
  {
    "path": ".github/issue_template.md",
    "content": "### Description\n\n[Describe the issue]\n\n### Expected behavior\n\n[Describe the behavior/output you expected]\n\n### Minimal, reproducible example\n\n```r\n[Insert sample data and code]\n```\n\n### Session Info\n\n```r\n[Insert your sessionInfo() output]\n```\n\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "Please review the [contributing guide](CONTRIBUTING.md) before submitting your pull request. Please pay special attention to the [pull request](CONTRIBUTING.md#want-to-submit-a-pull-request) and [commit message](CONTRIBUTING.md#commit-messages) sections. Thanks for your contribution and interest in the project!\n"
  },
  {
    "path": ".github/security.md",
    "content": "# Security Policy\n\n## Supported Versions\n\nAs with most R packages, only the latest package version is supported with bug\nfixes, features, etc. This also applies to security updates.\n\n## Reporting a Vulnerability\n\nTo report a security vulnerability, please use the\n[Tidelift security contact](https://tidelift.com/security).\nTidelift will coordinate the fix and disclosure.\n\n"
  },
  {
    "path": ".github/workflows/ci.yaml",
    "content": "# Run CI for R using https://eddelbuettel.github.io/r-ci/\n\nname: ci\n\non:\n  push:\n  pull_request:\n\nenv:\n  USE_BSPM: \"true\"\n  _R_CHECK_FORCE_SUGGESTS_: \"false\"\n  _R_CHECK_CRAN_INCOMING_ : \"false\"\n  _R_S3_METHOD_LOOKUP_BASEENV_AFTER_GLOBALENV_: \"true\"\n  _R_CHECK_CODETOOLS_PROFILE_: \"suppressLocalUnused=false\"\n  _R_CHECK_LENGTH_1_CONDITION_: \"true\"\n  _R_CHECK_LENGTH_1_LOGIC2_: \"true\"\n  _R_CHECK_UNDOC_USE_ALL_NAMES_: \"true\"\n\n\njobs:\n  build:\n    strategy:\n      matrix:\n        config:\n          #- {os: macOS-latest}\n          - {os: ubuntu-latest}\n\n    runs-on: ${{ matrix.config.os }}\n\n    steps:\n      - uses: actions/checkout@v3\n\n      - name: Bootstrap\n        run: |\n          curl -OLs https://eddelbuettel.github.io/r-ci/run.sh\n          chmod 0755 run.sh\n          ./run.sh bootstrap\n\n      - name: Dependencies\n        run: ./run.sh install_all\n\n      - name: Test\n        run: ./run.sh run_tests\n\n"
  },
  {
    "path": ".gitignore",
    "content": "# History and data files\n.Rhistory\n.Rapp.history\n.RData\n\n# RStudio files\n.Rproj.user/\n\n# produced vignettes\nvignettes/*.html\nvignettes/*.pdf\n\n# knitr and R markdown\n/*_cache/\n/cache/\n*.utf8.md\n*.knit.md\n\n# object and shared objects\n*.o\n*.so\n\n# vim\n*.swp\n*.swo\n*~\n\n# R package build/check\n*.tar.gz\n*.Rcheck/\n\n# miscellaneous\n0*.patch\n*.bak\n*.orig\n"
  },
  {
    "path": "DESCRIPTION",
    "content": "Package: TTR\nType: Package\nTitle: Technical Trading Rules\nVersion: 0.24.4.1\nAuthors@R: c(\n  person(given=\"Joshua\", family=\"Ulrich\", role=c(\"cre\",\"aut\"), email=\"josh.m.ulrich@gmail.com\"),\n  person(given=c(\"Ethan\",\"B.\"), family=\"Smith\", role=\"ctb\")\n  )\nImports: xts (>= 0.10-0), zoo, curl\nLinkingTo: xts\nEnhances: quantmod\nSuggests: tinytest\nDescription: A collection of over 50 technical indicators for creating technical trading rules. The package also provides fast implementations of common rolling-window functions, and several volatility calculations.\nLicense: GPL (>= 2)\nURL: https://github.com/joshuaulrich/TTR\nBugReports: https://github.com/joshuaulrich/TTR/issues\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.\n"
  },
  {
    "path": "Makefile",
    "content": "#https://stackoverflow.com/questions/34603415/makefile-automatic-target-generation\n#https://www.gnu.org/software/make/manual/make.html#Static-Pattern\n#https://stackoverflow.com/questions/2826029/passing-additional-variables-from-command-line-to-make\n#https://stackoverflow.com/questions/2214575/passing-arguments-to-make-run\n\nR_HOME = /usr\n\nPKG_PATH = ${PWD}\nTOP = ${PWD}/..\nPKG_DESC = ${PKG_PATH}/DESCRIPTION\nPKG_NAME = $(shell sed -ne \"s/^Package: //p\" ${PKG_DESC} | tr -d '\\n')\nPKG_VER = $(shell sed -ne \"s/^Version: \\(.*\\)/\\1/p\" ${PKG_DESC} | tr -d '\\n')\nPKG_TARGZ = $(PKG_NAME)_$(PKG_VER).tar.gz\n\n\nPKG_BUILD_OPTS ?= --no-build-vignettes\nR_LIB ?= $(shell Rscript -e 'cat(.libPaths()[1L])')\n\nPKG_INST_FILE = $(R_LIB)/${PKG_NAME}/DESCRIPTION\n\nPKG_R_FILES := $(wildcard ${PKG_PATH}/R/*.R)\nPKG_RD_FILES := $(wildcard ${PKG_PATH}/man/*.Rd)\nPKG_SRC_FILES := $(wildcard ${PKG_PATH}/src/*)\nPKG_HEADER_FILES := $(wildcard ${PKG_PATH}/inst/include/*h)\nPKG_ALL_FILES := ${PKG_PATH}/DESCRIPTION ${PKG_PATH}/NAMESPACE ${PKG_HEADER_FILES} \\\n  $(PKG_R_FILES) $(PKG_RD_FILES) $(PKG_SRC_FILES) ${PKG_PATH}/.Rbuildignore\n\nHTML_FILES := $(patsubst %.Rmd, %.html, $(wildcard *.Rmd)) \\\n              $(patsubst %.md, %.html, $(wildcard *.md))\n\nUNIT_TEST_SUITE = ${PKG_PATH}/tests/tinytest.R\nUNIT_TEST_FILES = $(wildcard ${PKG_PATH}/inst/tinytest/test-*.R)\n\nBENCHMARK_FILE = ${PKG_PATH}/inst/benchmarks/benchmark.subset.R\n\n.PHONY: docs build install check tests test clean\n\nall: cran\n\n#man/*.Rd depend on R/*.R files\nprint:\n\t@echo 'path: $(PKG_PATH) \\\n\tinst_file: $(PKG_INST_FILE) \\\n\ttar.gz: $(PKG_TARGZ)'\n\n# Build package\nbuild: $(PKG_TARGZ)\n$(PKG_TARGZ): $(PKG_ALL_FILES) $(UNIT_TEST_FILES) $(UNIT_TEST_SUITE)\n\t@${R_HOME}/bin/R CMD build ${PKG_BUILD_OPTS} ${PKG_PATH} --no-build-vignettes\n\n# Install package\ninstall: build $(PKG_INST_FILE)\n$(PKG_INST_FILE): $(PKG_TARGZ)\n\t@${R_HOME}/bin/R CMD INSTALL ${PKG_TARGZ} --no-byte-compile\n\n# Run R CMD check\ncheck: docs build\n\t@_R_CHECK_CRAN_INCOMING_=false \\\n\t_PKG_TINYTEST_VERBOSE_=1 _PKG_TINYTEST_COLOR_=FALSE \\\n\t${R_HOME}/bin/R CMD check ${PKG_TARGZ} --no-vignettes\n\ndocs: ${PKG_R_FILES}\n\t@${R_HOME}/bin/Rscript -e \"roxygen2::roxygenize(roclets='rd')\" \\\n\t  && sed -i '/^RoxygenNote/d' ${PKG_PATH}/DESCRIPTION \\\n\t  && /bin/rm --force ${PKG_PATH}/src/*.o \\\n\t  && /bin/rm --force ${PKG_PATH}/src/*.so\n\n# Check for CRAN\ncran:\n\t@${R_HOME}/bin/R CMD build ${PKG_PATH} && \\\n\t_PKG_TINYTEST_VERBOSE_=1 _PKG_TINYTEST_COLOR_=FALSE \\\n\t_R_CHECK_CRAN_INCOMING_=false ${R_HOME}/bin/R CMD check ${PKG_TARGZ} --as-cran\n\n# Run unit test suite\ntests: install ${UNIT_TEST_FILES}\n\t@_PKG_TINYTEST_VERBOSE_=2 _PKG_TINYTEST_COLOR_=TRUE \\\n\t${R_HOME}/bin/Rscript ${UNIT_TEST_SUITE}\n\nhtml: $(HTML_FILES)\n\n%.html: %.Rmd\n\tR --slave -e \"set.seed(100);rmarkdown::render('$<')\"\n\n%.html: %.md\n\tR --slave -e \"set.seed(100);rmarkdown::render('$<')\"\n\nclean:\n\t/bin/rm --force $(HTML_FILES) ${PKG_PATH}/src/*.o ${PKG_PATH}/src/*.so\n"
  },
  {
    "path": "NAMESPACE",
    "content": "export(ADX)\nexport(ALMA)\nexport(ATR)\nexport(BBands)\nexport(CCI)\nexport(CLV)\nexport(CMF)\nexport(CMO)\nexport(CTI)\nexport(DEMA)\nexport(DPO)\nexport(DVI)\nexport(DonchianChannel)\nexport(EMA)\nexport(EMV)\nexport(EVWMA)\nexport(GMMA)\nexport(HMA)\nexport(KST)\nexport(MACD)\nexport(MFI)\nexport(OBV)\nexport(PBands)\nexport(ROC)\nexport(RSI)\nexport(SAR)\nexport(SMA)\nexport(SMI)\nexport(SNR)\nexport(TDI)\nexport(TR)\nexport(TRIX)\nexport(VHF)\nexport(VWAP)\nexport(VWMA)\nexport(WMA)\nexport(WPR)\nexport(ZLEMA)\nexport(ZigZag)\nexport(adjRatios)\nexport(aroon)\nexport(chaikinAD)\nexport(chaikinVolatility)\nexport(getYahooData)\nexport(growth)\nexport(keltnerChannels)\nexport(lags)\nexport(momentum)\nexport(naCheck)\nexport(rollSFM)\nexport(runCor)\nexport(runCov)\nexport(runMAD)\nexport(runMax)\nexport(runMean)\nexport(runMedian)\nexport(runMin)\nexport(runRange)\nexport(runPercentRank)\nexport(runSD)\nexport(runSum)\nexport(runVar)\nexport(stoch)\nexport(stockSymbols)\nexport(ultimateOscillator)\nexport(volatility)\nexport(wilderSum)\nexport(williamsAD)\nimport(xts)\nimport(zoo)\nimportFrom(curl,curl_download)\nimportFrom(curl,new_handle)\nimportFrom(stats,approx)\nimportFrom(stats,embed)\nimportFrom(stats,na.omit)\nimportFrom(stats,sd)\nimportFrom(stats,cor)\nimportFrom(utils,flush.console)\nimportFrom(utils,read.csv)\nimportFrom(utils,read.table)\n\nuseDynLib(TTR, .registration = TRUE, .fixes = \"C_\")\n"
  },
  {
    "path": "NEWS.md",
    "content": "# Changes in 0.24.4\n\n* Added Ethan B. Smith as a contributor. Thanks Ethan!\n\n### NEW FEATURES\n\n- Added a `TR()` function to calculate the true high, true low, and true\n  range. Refactored `ATR()` to use the `TR()` function. Thanks to @openbmsjsc\n  and Steve Bronder for the reports, and Ethan B. Smith for the PR.\n  (#18, #114, #124)\n\n### BUG FIXES\n\n* Fix `stockSymbols()` for ticker \"NA\". `read.table()` converts the string \"NA\"\n  to a missing value (NA) because `na.strings = \"NA\"` by default. This causes\n  an issue because there's actually a company with \"NA\" for the ticker. (#128)\n\n- `CTI()` did not pad its result with leading NA when the input was not\n  coerced to an xts object. This was different from other TTR functions\n  (e.g. `SMA()`, `RSI()`, `ROC()`). (#127)\n\n- Removed the `VMA()` function, which was never correct because the\n  results made no sense.\n\n- Check that the `wma()` C function has enough non-NA values and throw\n  an error if it doesn't. This could cause the `WMA()` function to crash\n  the user's R session. (#126)\n\n- `runMean(..., cumulative = TRUE)` didn't account for leading NA in the\n  denominator. (#122)\n\n- `runSD(x, cumulative = TRUE)` returned all NA when `x` had any leading\n  NA. Thanks to Ethan B. Smith for the report. (#121)\n\n- The `TRIX()` signal line did not use `nSig` unless `maType` was provided.\n  Thanks to @SatoshiReport for the... report. (#120)\n\n### MISCELLANEOUS\n\n- Use symbols for native routine entry points to make them explicit and\n  unable to be found accidentally. (#123)\n\n# Changes in 0.24.3\n\n### SIGNIFICANT USER-VISIBLE CHANGES\n\n- Significant improvement to `ALMA()` calculation speed. Thanks to\n  Ethan B. Smith for the report and suggested fix. (#117)\n\n### NEW FEATURES\n\n- Added Keltner Channels. Thanks to Nick Procyk for the patch and docs (#106)\n\n### BUG FIXES\n\n- `runPercentRank()` would segfault if `x` had fewer non-NA observations\n  than the value for `n`. Thanks to Ian Fellows for the report. (#112)\n\n- `run*(x, n = 1, cumulative = TRUE)` functions would return NA for the\n  first value. Thanks to Ethan B. Smith for the report and PR! (#111, #108, #88)\n\n- Fix NA check off-by-one error in `aroon()` that caused it to fail if there\n  were exactly enough non-NA values. (#102)\n\n# Changes in 0.24.2\n\n### BUG FIXES\n\n- Check for `ratio > 0` before calculating `n` in `zlema()` C code. The prior\n  code could result in division by 0, which was flagged by clang-UBSAN.\n  Thanks to Prof Brian Ripley for the report. (#100)\n\n# Changes in 0.24.1\n\n### BUG FIXES\n\n- Fix leading NA accounting in `wma()` C code. The prior code caused invalid\n  reads under valgrind. Thanks to Prof Brian Ripley for the report. (#99)\n\n- Check for `ratio > 0` before calculating `n` `n ema()` C code. The prior\n  code could result in division by 0, which was flagged by UBSAN. Thanks to\n  Prof Brian Ripley for the report. (#100)\n\n- Make `ALMA()` output length equal input length when the input can not be\n  converted to xts. This was caused by the difference between\n  `rollapply.default()` and `rollapply.xts()`. Thanks to GitHub user\n  @marksimmonds for the report. (#29)\n\n- Fix `stoch()` in very rare cases where `fastK = Inf`. I could only reproduce\n  this if the Close is > High and High and Low are equal, but that is a data\n  error. I fixed anyway because there may be other cases I don't anticipate.\n  Thanks to GitHub user @cjuncosa for the report. (#52)\n\n- Fix `MFI()` when money flow is always zero or positive. The denominator of\n  the money ratio will be zero if there is no negative money flow for `n`\n  consecutive observations (e.g. during a strong up-trend), which causes the\n  money flow index to be Inf. Set the money flow index to 100 in this case.\n\n  And the money ratio will be NaN if there's no money flow for `n`\n  consecutive observations (e.g. if there are no trades), which causes the\n  money flow index to be NaN. Set the money flow index to 50 in this case.\n\n  Thanks to GitHub user @jgehw for the report, reproducible example, and\n  suggested patch. (#81)\n\n# Changes in 0.24.0\n\n### SIGNIFICANT USER-VISIBLE CHANGES\n\n- Updated `stockSymbols()` to use the NASDAQ FTP site instead of downloading\n  the CSV from the NASDAQ stock screener page. Some columns are no longer\n  populated because they are not provided in the FTP file:\n      LastSale ,MarketCap, IPOyear, Sector, Industry\n  These columns will be removed in a future version. (#98, #5, #97)\n\n- `runPercentRank(x, n, cumulative = TRUE)` now sets observations in the\n  initialization period to NA. This is consistent with the other\n  running/rolling functions in TTR. If you want the previous behavior,\n  you should use `runPercentRank(x, n = 1, cumulative = TRUE)`. Thanks to\n  GitHub user @httassadar for the report. (#73)\n\n### NEW FEATURES\n\n- Add Ehler's Correlation Trend Indicator. Thanks to Evelyn Mitchell for\n  the suggestion, and for Ethan B. Smith for the initial implementation. (#92)\n\n### BUG FIXES\n\n- `runMAD()` returned incorrect values when `cumulative = TRUE` and the input\n  contained leading NA. Thanks to GitHub user @stellathecat for the report.\n  This also affected `runMedian()`. (#93)\n\n- `ZLEMA()` would crash when `ratio = 0.0` and `n` was not specified. Thanks\n  to GitHub user @yogat3ch for the report! (#95)\n\n- `WMA()` did not return an xts object when passed an xts object for `x` that\n  had leading NA, with the default `wts = 1:n`. Thanks to Cory Fletcher for\n  reporting this issue via email. (#96)\n\n- `stoch()` was wrong when `bounded = FALSE`. Thanks to GitHub user @rfinfun\n  for the report and patch. (#74)\n\n- `HMA()` threw an error when `n` was an odd number. This was because the\n  first call to `WMA()` used `n = n / 2` which caused `n` to not be an\n  integer. Thanks to GitHub user @dragie for the report. (#76)\n\n# Changes in 0.23.0\n\n### SIGNIFICANT USER-VISIBLE CHANGES\n\n- Update `DVI()` to use `runPercentRank()`. Thanks to Ivan Popivanov for the\n  patch.\n\n- `getYahooData()` now returns an xts object with Date index (not POSIXct).\n\n- Column names for moving average function outputs are no longer based on the\n  input column names.\n\n### NEW FEATURES\n\n- Add `HMA()` and `ALMA()` functions/docs. Thanks to Ivan Popivanov.\n\n- Add Ultimate Oscillator function/docs/tests. Thanks to Ivan Popivanov.\n\n### BUG FIXES\n\n- `run*()` functions now error if there are not enough non-NA values.\n\n- Change all instances of `lag()` to `lag.xts()` in case `x` is a matrix.\n  Thanks to Ivan Popivanov for the report.\n\n- Correct output column names in `ATR()` docs.\n\n- `CLV()` now sets NaN and Inf values to 0, instead of only NaN values.\n\n- Fix `OBV()` so `OBV[t] = OBV[t-1]` when `Close[t] == Close[t-1]`.\n\n- Fix dead links in documentation.\n\n# Changes in 0.22.0\n\n### SIGNIFICANT USER-VISIBLE CHANGES\n\n- `CCI()` now returns an object with column names (\"cci\").\n\n- All moving average functions now attempt to set column names.\n\n- Added clarification on the displaced nature of `DPO()`.\n\n- `SAR()` now sets the initial gap based on the standard deviation of the\n  high-low range instead of hard-coding it at 0.01.\n\n### NEW FEATURES\n\n- Added `rollSFM()` function that calculates alpha, beta, and R-squared for a\n  single-factor model. Thanks to James Toll for the prototype.\n\n- Added `runPercentRank()` function. Thanks to Charlie Friedemann.\n\n- Moved slowest portion of `aroon()` to C.\n\n- `DonchianChannel()` gains an `include.lag = FALSE` argument, which includes\n  the current period's data in the calculation. Setting it to `TRUE` replicates\n  the original calculation. Thanks to Garrett See and John Bollinger.\n\n- The Stochastic Oscillator and Williams' %R now return 0.5 (instead of NaN)\n  when a securities' price doesn't change over a sufficient period.\n\n- All moving average functions gain `...`.\n\n- Users can now change alpha in Yang Zhang volatility calculation.\n\n### BUG FIXES\n\n- Fixed `MACD()` when `maType` is a list. Now `mavg.slow = maType[[2]]` and\n  `mavg.fast = maType[[1]]`, as users expected based on the order of the\n  `nFast` and `nSlow` arguments. Thanks to Phani Nukala and Jonathan Roy.\n\n- Fixed bug in `lags()`. Thanks to Michael Weylandt.\n\n- Corrected error in Yang Zhang volatility calculation. Thanks to several\n  people for identifying this error.\n\n- Correction to `SAR()` extreme point calculations. Thanks to Vamsi Galigutta.\n\n- `adjRatios()` now ensures all inputs are univariate. Thanks to Garrett See.\n\n- `EMA()` and `EVWMA()` now ensure `n` is less than the number of non-NA\n  values. Thanks to Roger Bos.\n\n- Fix to `BBands()` docs. Thanks to Evelyn Mitchell.\n\n# Changes in 0.21.1\n\n### BUG FIXES\n\n- Fixed `stockSymbols()` for nasdaq.com changes (again), and attempted to make\n  `stockSymbols()` more robust to nasdaq.com changes.\n\n- Corrected final calculation in Yang-Zhang volatility. Thanks to Shal Patel.\n\n- Corrected `k` in Yang-Zhang volatility. Thanks to Ian Rayner.\n\n- Corrected `s2o` and `s2c` in Yang-Zhang volatility. Thanks to Ian Rayner.\n\n- Corrected `KST()` when input is xts (result is now * 100). Thanks to Yuanwei.\n\n# Changes in 0.21.0\n\n### NEW FEATURES\n\n- Added variable moving average function, `VMA()`.\n\n- Added Brian Peterson's price bands function, `PBands()`.\n\n- Added David Varadi's `DVI()` indicator.\n\n- Added `wilder` and `ratio` arguments to `DEMA`. Thanks to Matthew Fornari\n  for the suggestion.\n\n### BUG FIXES\n\n- Changed `wilderSum()` to seed initial value with raw sum. This matches\n  Wilder's original calculations. Thanks to Mahesh Bp for the report.\n\n- The `BBands()` standard deviation calculation now uses the population\n  instead of sample statistic. This is consistent with Bollinger Band\n  literature. Thanks to Jeff Ryan for the patch.\n\n- Fixed `stockSymbols()` for nasdaq.com changes.\n\n- Fixed `ZLEMA()` default ratio by changing it from `2/(n-1)` to `2/(n+1)`.\n  This makes it consistent with `EMA()`. Thanks to Dirk Eddelbuettel.\n\n- Corrected close-to-close volatility. Thanks to James Toll for the report.\n\n- `adjRatios()` failed (spectacularly) if there were missing close prices.\n  Thanks to Garrett See for the report.\n\n# Changes in 0.20.2\n\n### NEW FEATURES\n\n- Added `VWAP()` and `VWMA()`. Thanks to Brian Peterson.\n\n- Added v-factor generalization to `DEMA()`. Thanks to John Gavin.\n\n- Updated `volatility()` to handle univariate case of `calc = \"close\"`.\n  Thanks to Cedrick Johnson.\n\n- Moved `EMA()`, `SAR()`, and `wilderSum ()`from .Fortran to `.Call ()`and\n  used `xts:::naCheck()` instead of TTR's NA check mechanism.\n\n- `RSI ()`up/down momentum is now faster with xts. Thanks to Jeff Ryan.\n\n- If `ratio` is specified in `EMA ()`but `n` is missing, the traditional\n  value of `n` is approximated and returned as the first non-NA value.\n\n### BUG FIXES\n\n- Fix to `stoch()` when `maType` is a list and `n` is not set in the list's\n  3rd element. Thanks to Wind Me.\n\n- Fixed `fastK` in `stoch()` when `smooth != 1`.\n\n- Fixed segfault in `EMA ()`when `n < NROW(x)`. Thanks to Douglas Hobbs.\n\n- `test.EMA.wilder()` failed under R-devel. Thanks to Prof Brian Ripley.\n\n# Changes in 0.20.1\n\n### NEW FEATURES\n\n- Updated `CMO()`, `DPO()`, `DonchianChannel()`, `RSI()`, and `TDI ()`\n  to *explicitly* use xts internally.\n\n### BUG FIXES\n\n- Fixed bug in `WMA()`, `EVWMA()`, `ZLEMA()`, and `GMMA()`; results were not\n  being `reclass()`ed back to their original class.\n\n- Set column names after `cbind ()` call in the following functions:\n    - `ADX()`\n    - `aroon()`\n    - `ATR()`\n    - `BBands()`\n    - `DonchianChannel()`\n    - `EMV()`\n    - `KST()`\n    - `MACD()`\n    - `stoch()`\n    - `SMI()`\n    - `TDI()`\n    - `TRIX()`\n\n- Fixed bug in `VHF()`; missing `abs()` calculation in the denominator.\n  Thanks to Jürgen Wurzer for the report!\n\n# Changes in 0.20.0\n\n- Fixed version number; 0.20-0 is now > 0.14-0 (rookie mistake).\n\n### SIGNIFICANT USER-VISIBLE CHANGES\n\n- `getYahooData()` now returns an xts object.\n\n- Added column names to output for `ADX()`, `EMV()`, and `CLV ()` (for xts).\n\n- `momentum()` in `CMO()` no longer sets `na = 100`.\n\n- Replaced `na` argument in `momentum()` and `ROC()` with `na.pad`.\n\n- Moved `maType` argument default values from function formals to\n  function body for the following functions:\n    - `ADX()`\n    - `ATR()`\n    - `CCI()`\n    - `DPO()`\n    - `EMV()`\n    - `KST()`\n    - `MACD()`\n    - `RSI()`\n    - `TRIX()`\n    - `BBands()`\n    - `chaikinVolatility()`\n    - `stoch()`\n    - `SMI()`\n\n### NEW FEATURES\n\n- `adjRatios()` creates split and/or dividend adjustment ratio series via\n  C code.\n\n- `GMMA()` calculates the Guppy Multiple Moving Average.\n\n- `volatility()` now has Yang Zhang, and Garman-Klass (Yang Zhang)\n  calculations.\n\n- The functions below now have cumulative argument.  This allows the\n  calculation of \"from inception\" running series.\n    - `runSum()`, `runMin()`, `runMax()`\n    - `runMean()`, `runMedian()`\n    - `runCov()`, `runCor()`, `runVar()`, `runSD()`, `runMAD()`\n\n- Added internal smoothing to `FastK` in `stoch()` via `smooth` argument.\n  Thanks to Stanley Neo.\n\n- `getYahooData()` now uses `adjRatios(),` which yields significant speed\n  improvements for larger data sets.\n\n- All functions now use xts internally, adding support for all major time\n  series classes. If `try.xts()` fails on the input object(s), they will be\n  converted to a matrix and a matrix object will be returned.\n\n- Added `bounded` arg to `stoch()` and `SMI()`, which includes the current\n  period in the calculation.\n\n- Added the zig zag indicator: `ZigZag()`.\n\n- Added volatility estimators/indicators: `volatility()`, with the following\n  calculations:\n    - Close-to-Close\n    - Garman Klass\n    - Parkinson\n    - Rogers Satchell\n\n- Added Money Flow Index: `MFI()`.\n\n- Added Donchian channel: `DonchianChannel()`.\n\n- Added `multiple` argument to `TDI()`, allowing more user control.\n\n- Added `naCheck()` and implemented it in the moving average functions.\n\n### BUG FIXES\n\n- Fixed bug when `maType` was a list and `n` was not specified in `maType`.\n  This affected: `stoch()`, `SMI()`, `RSI()`, `KST()`, `MACD()`, `TRIX()`.\n\n- Corrected NaN replacement in `CLV()`.\n\n- Corrected `williamsAD()`: the result is 0 if C(t) = C(t-1).\n\n- Corrected `runMedian()` and `runMAD()`.  The argument controlling which type\n  of median to calculate for even-numbered samples wasn't being passed to\n  the Fortran routine.\n\n- `aroon()` calculation starts at period `n+1`, instead of `n`.\n\n- Added NA to first element of `closeLag` of `ATR()`.\n\n- Corrected `BBands()` and `CCI()` for `rowMeans()` use on xts objects.\n\n- Made changes to Rd files to pass R CMD check on R-devel (2.9.0).\n\n# Changes in 0.14.0\n\n### SIGNIFICANT USER-VISIBLE CHANGES\n\n- Changed default `type` of `ROC()` to `continuous`.\n\n- Changed `BBands()` %B output value from `pct.b` to `pctB`.\n\n- Changed `WPR()` output value from `pct.R` to `pctR`.\n\n- Changed `WPR()` MA output value from `ma.emv` to `emvMA`.\n\n- Changed `aroon()` output values from `aroon.xx` to `aroonXx`.\n\n- Renamed:\n    - `chaikinMF()` to `CMF()`\n    - `stochastic()` to `stoch()`\n    - `bollingerBands()` to `BBands()`\n\n- Set `na = NA` for `momentum()` and `ROC()` functions in files KST.R,\n  RSI.R, and TDI.R, and changed `ROC()` to use `type = \"discrete\"`\n  in chaikinVolatility.R.\n\n- Made the following changes to the `ZLEMA()` function:\n   - Add `ratio = NULL` argument.\n   - Non-integer lags are a weighted mean of the two nearest\n     observations, based on their proximity to the lag value.\n   - Change 'lag = ratio^(-1)' to fully support `ratio` argument.\n\n- Changed the `BBands()` function's `sd` argument from a list\n  that allows other dispersion functions to simply indicate the\n  number of standard deviations to use.\n\n### NEW FEATURES\n\n- Changed `maType` arguments and updated documentation for:\n    - `RSIm()`\n    - `ADX()`\n    - `ATR()`\n    - `CCI()`\n    - `DPO()`\n    - `EMV()`\n    - `RSI()`\n    - `BBands()`\n    - `chaikinVolatility()`\n    - `stoch()`\n    - `SMI()`\n    - `TRIX()`\n    - `MACD()`\n    - `KST()`\n\n- Added Stochastic Momentum Index `SMI()` and `williamsAD()` functions\n  and documentation.\n\n- Added Fortran implementations of\n    - `SMA()`\n    - `EMA()`\n    - `WMA()`\n    - `EVWMA()`\n    - `ZLEMA()`\n    - `PSAR()`\n\n- Added NA checking/handling for many functions.\n\n- Added `ratio = NULL` argument to `EMA()`.\n\n- Changed all usage of `roll*()` to their respective Fortran\n  implementations and removed the `rollFun()` function.  Added Fortran\n  based functions are:\n    - `runSum()`\n    - `wilderSum()`\n    - `runMin()`\n    - `runMax()`\n    - `runMean()`\n    - `runCov()`\n    - `runCor()`\n    - `runVar()`\n    - `runSD()`\n    - `runMedian()`\n    - `runMAD()`\n\n- Changed `CCI()` to use `runMAD()` internally.\n\n### DEPRECATED & DEFUNCT\n\n- Removed `oscillator()` function and transferred functionality\n  to `MACD()` function.\n\n- Removed `chaikinOscillator()`, since it can be created via\n  `MACD(chaikinAD(...))`.\n\n### BUG FIXES\n\n- `match.arg(type)` in `ROC()` changed to simple subsetting of type.\n\n- Changed trailing zeros to trailing NAs in `DPO()`.\n\n- Fixed `WMA()` bug that allowed `x` and `wts` vectors to have different\n  length if either series had leading NAs (similar to `EVWMA()` function).\n\n- Fixed `runCov()` bug that allowed `x` and `y` vectors to have different\n  length if either series had leading NAs (similar to `EVWMA()` function).\n\n- Corrected `EVWMA()` to start at period `n` instead of `n-1`.\n\n- Removed `message` function from CCI.R, VHF.R, WPR.R, aroon.R\n  bollingerBands.R, and stochastics.R.\n\n# Changes in 0.13.2\n\n### SIGNIFICANT USER-VISIBLE CHANGES\n\n- Changed order of `oscillator()` arguments from `ma.slow`, `ma.fast`, `ma.sig`\n  to the traditional `ma.fast`, `ma.slow`, `ma.sig`. Thanks to Jeff Ryan.\n\n- The arguments to the `chaikinOscillator()` function were changed as above.\n\n- Changed `EVWMA()` so period `n` contains the value for periods `(i-n+1):n`\n  and so periods `1:(n-2)` will be NA.\n\n- Changed `EMA()` so periods `1:n` will be NA.\n\n# Changes in 0.13.1\n\n### SIGNIFICANT USER-VISIBLE CHANGES\n\n- Changed `bbands()` to `bollingerBands()`.\n\n- Changed `DX()` to `ADX()`.\n\n- Changed `stoch()` to `stochastic()`.\n\n\n### BUG FIXES\n\n- Corrected mis-spellings in documentation.\n"
  },
  {
    "path": "R/ADX.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Welles Wilder's Directional Movement Index\n#'\n#' Directional Movement Index; developed by J. Welles Wilder.\n#'\n#' The \\code{DIp}/\\code{DIn} (positive/negative) is the percentage of the true\n#' range that is up/down.\n#'\n#' @aliases ADX DI DX\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices.\n#' @param n Number of periods to use for DX calculation (not ADX calculation).\n#' @param maType A function or a string naming the function to be called.\n#' @param \\dots Other arguments to be passed to the \\code{maType} function.\n#' @return A object of the same class as \\code{HLC} or a matrix (if\n#' \\code{try.xts} fails) containing the columns:\n#'  \\describe{\n#'   \\item{ DIp }{ The positive Direction Index. }\n#'   \\item{ DIn }{ The negative Direction Index. }\n#'   \\item{ DX }{ The Direction Index. }\n#'   \\item{ ADX }{ The Average Direction Index (trend strength). }\n#'  }\n#' @note A buy/sell signal is generated when the +/-DI crosses up over the\n#' -/+DI, when the DX/ADX signals a strong trend.  A high/low DX signals a\n#' strong/weak trend.  DX is usually smoothed with a moving average (i.e. the\n#' ADX).\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\n#' options; and note Warning section.  The DX calculation uses\n#' \\code{\\link{ATR}}.  See \\code{\\link{aroon}}, \\code{\\link{CCI}},\n#' \\code{\\link{TDI}}, \\code{\\link{VHF}}, \\code{\\link{GMMA}} for other indicators\n#' that measure trend direction/strength.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://www.fmlabs.com/reference/DI.htm}\\cr\n#' \\url{https://www.fmlabs.com/reference/DX.htm}\\cr\n#' \\url{https://www.fmlabs.com/reference/ADX.htm}\\cr\n#' \\url{https://www.fmlabs.com/reference/ADXR.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=49}\\cr\n#' \\url{https://www.linnsoft.com/techind/directional-indicator-diplus-diminus}\\cr\n#' \\url{https://www.linnsoft.com/techind/adx-avg-directional-movement}\\cr\n#' \\url{https://www.linnsoft.com/techind/adxr-avg-directional-movement-rating}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:average_directional_index_adx}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  dmi.adx <- ADX(ttrc[,c(\"High\",\"Low\",\"Close\")])\n#'\n\"ADX\" <-\nfunction(HLC, n=14, maType, ...) {\n\n  # Welles Wilder's Directional Movement Index\n\n  HLC <- try.xts(HLC, error=as.matrix)\n  dH  <- momentum(HLC[,1])\n  dL  <- -momentum(HLC[,2])\n\n  DMIp <- ifelse( dH==dL | (dH< 0 & dL< 0), 0, ifelse( dH >dL, dH, 0 ) )\n  DMIn <- ifelse( dH==dL | (dH< 0 & dL< 0), 0, ifelse( dH <dL, dL, 0 ) )\n\n  tr    <- TR(HLC)[,\"tr\"]\n  TRsum <- wilderSum(tr, n=n)\n\n  DIp <- 100 * wilderSum(DMIp, n=n) / TRsum\n  DIn <- 100 * wilderSum(DMIn, n=n) / TRsum\n\n  DX  <- 100 * ( abs(DIp - DIn) / (DIp + DIn) )\n\n  maArgs <- list(n=n, ...)\n\n  # Default Welles Wilder EMA\n  if(missing(maType)) {\n    maType <- 'EMA'\n    if(is.null(maArgs$wilder)) {\n      # do not overwrite user-provided value\n      maArgs$wilder <- TRUE\n    }\n  }\n\n  ADX <- do.call( maType, c( list(DX), maArgs ) )\n\n  result <- cbind( DIp, DIn, DX, ADX )\n  colnames(result) <- c( \"DIp\", \"DIn\", \"DX\", \"ADX\" )\n\n  reclass(result, HLC)\n}\n"
  },
  {
    "path": "R/ATR.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' True Range / Average True Range\n#'\n#' True range (TR) is a measure of volatility of a High-Low-Close series;\n#' average true range (ATR) is a Welles Wilder's style moving average of the TR.\n#' Developed by J. Welles Wilder in 1978.\n#'\n#' TR incorporates yesterday's close in the calculation (high minus low).  E.g.\n#' if yesterday's close was higher than today's high, then the TR would equal\n#' yesterday's close minus today's low.\n#'\n#' The ATR is a component of the Welles Wilder Directional Movement Index\n#' (\\code{DX}, \\code{ADX}).\n#'\n#' @aliases ATR TR\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices.\n#' @param n Number of periods for moving average.\n#' @param maType A function or a string naming the function to be called.\n#' @param \\dots Other arguments to be passed to the \\code{maType} function.\n#' @return A object of the same class as \\code{HLC} or a matrix (if\n#' \\code{try.xts} fails) containing the columns:\n#'  \\describe{\n#'   \\item{ tr }{ The true range of the series. }\n#'   \\item{ atr }{ The average (as specified by \\code{ma}) true range of the series. }\n#'   \\item{ trueHigh }{ The true high of the series. }\n#'   \\item{ trueLow }{ The true low of the series. }\n#'  }\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\n#' options; and note Warning section.  See \\code{\\link{DX}}, which uses true\n#' range.  See \\code{\\link{chaikinVolatility}} for another volatility measure.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://www.fmlabs.com/reference/TR.htm}\\cr\n#' \\url{https://www.fmlabs.com/reference/ATR.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=35}\\cr\n#' \\url{https://www.linnsoft.com/techind/true-range-tr}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:average_true_range_atr}\\cr\n#' @keywords ts\n#' @examples\n#'\n#' data(ttrc)\n#' tr <- TR(ttrc[,c(\"High\",\"Low\",\"Close\")])\n#' atr <- ATR(ttrc[,c(\"High\",\"Low\",\"Close\")], n=14)\n#'\n#' @rdname ATR\n\"TR\" <-\nfunction(HLC) {\n  # True Range\n\n  HLC <- try.xts(HLC, error=as.matrix)\n\n  if(is.xts(HLC)) {\n    closeLag <- lag.xts(HLC[,3])\n  } else {\n    closeLag <- c( NA, HLC[-NROW(HLC),3] )\n  }\n\n  trueHigh <- pmax( HLC[,1], closeLag, na.rm=FALSE )\n  trueLow  <- pmin( HLC[,2], closeLag, na.rm=FALSE )\n  tr       <- trueHigh - trueLow\n\n  result <- cbind(tr, trueHigh, trueLow )\n  colnames(result) <- c('tr','trueHigh','trueLow')\n\n  reclass( result, HLC )\n}\n\n#' @rdname ATR\n\"ATR\" <-\nfunction(HLC, n=14, maType, ...) {\n\n  # Average True Range / True Range\n\n  HLC <- try.xts(HLC, error=as.matrix)\n  tr <- TR(HLC)\n\n  maArgs <- list(n=n, ...)\n\n  # Default Welles Wilder EMA\n  if(missing(maType)) {\n    maType <- 'EMA'\n    if(is.null(maArgs$wilder)) {\n      # do not overwrite user-provided value\n      maArgs$wilder <- TRUE\n    }\n  }\n\n  atr <- do.call( maType, c( list(tr[,1]), maArgs ) )\n\n  result <- cbind( tr[,1], atr, tr[,2:3])\n  colnames(result) <- c('tr','atr','trueHigh','trueLow')\n\n  reclass( result, HLC )\n}\n"
  },
  {
    "path": "R/CCI.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Commodity Channel Index\n#'\n#' The Commodity Channel Index (CCI) attempts to identify starting and ending\n#' trends.\n#'\n#' CCI relates the current price and the average of price over \\code{n} periods.\n#' The CCI usually falls in a channel of -100 to 100. A basic CCI trading system\n#' is: Buy (sell) if CCI rises above 100 (falls below -100) and sell (buy) when\n#' it falls below 100 (rises above -100).\n#'\n#' CCI is usually calculated using the typical price, but if a univariate series\n#' (e.g. Close, Weighted Close, Median Price, etc.) is provided, it will be used\n#' instead.\n#'\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices.  If only a univariate series is given, it will be\n#' used.  See details.\n#' @param n Number of periods for moving average.\n#' @param maType A function or a string naming the function to be called.\n#' @param c Constant to apply to the mean deviation.\n#' @param \\dots Other arguments to be passed to the \\code{maType} function.\n#' @return A object of the same class as \\code{HLC} or a vector (if\n#' \\code{try.xts} fails) containing the CCI values.\n#' @note If \\code{HLC} is a High-Low-Close matrix, then typical price will be\n#' calculated.  If \\code{HLC} is a vector, then those values will be used\n#' instead of the typical price.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\n#' options; and note Warning section.  See \\code{\\link{aroon}},\n#' \\code{\\link{ADX}}, \\code{\\link{TDI}}, \\code{\\link{VHF}}, \\code{\\link{GMMA}}\n#' for other indicators that measure trend direction/strength.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://www.fmlabs.com/reference/CCI.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=42}\\cr\n#' \\url{https://www.linnsoft.com/techind/cci-commodity-channel-index}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:commodity_channel_index_cci}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  cci <- CCI(ttrc[,c(\"High\",\"Low\",\"Close\")])\n#'\n\"CCI\" <-\nfunction(HLC, n=20, maType, c=0.015, ...) {\n\n  # Commodity Channel Index\n\n  HLC <- try.xts(HLC, error=as.matrix)\n\n  if(NCOL(HLC)==3) {\n    if(is.xts(HLC)) {\n      xa <- xcoredata(HLC)\n      HLC <- xts(apply(HLC, 1, mean),index(HLC))\n      xcoredata(HLC) <- xa\n    } else {\n      HLC <- apply(HLC, 1, mean)\n    }\n  } else\n  if(NCOL(HLC)!=1) {\n    stop(\"Price series must be either High-Low-Close, or Close/univariate.\")\n  }\n\n  maArgs <- list(n=n, ...)\n  # Default MA\n  if(missing(maType)) {\n    maType <- 'SMA'\n  }\n\n  mavg  <- do.call( maType, c( list(HLC), maArgs ) )\n  meanDev <- runMAD( HLC, n, center=mavg, stat=\"mean\" )\n\n  cci <- ( HLC - mavg ) / ( c * meanDev )\n\n  if(is.xts(cci)) {\n    colnames(cci) <- \"cci\"\n  }\n\n  reclass(cci, HLC)\n}\n"
  },
  {
    "path": "R/CLV.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Close Location Value\n#'\n#' The Close Location Value (CLV) relates the day's close to its trading range.\n#'\n#' The CLV will fall in a range of -1 to +1.  If the CLV is +/-1, the close is\n#' at the high/low; if the CLV is 0, the close is directly between the high and\n#' low.\n#'\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices.\n#' @return A object of the same class as \\code{HLC} or a vector (if\n#' \\code{try.xts} fails) containing the Close Location Values of a\n#' High-Low-Close price series.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{chaikinAD}}, which uses CLV.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:accumulation_distribution_line}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  clv <- CLV(ttrc[,c(\"High\",\"Low\",\"Close\")])\n#'\n\"CLV\" <-\nfunction(HLC) {\n\n  # Close Location Value\n\n  HLC <- try.xts(HLC, error=as.matrix)\n  clv <- ((HLC[,3]-HLC[,2]) - (HLC[,1]-HLC[,3])) / (HLC[,1]-HLC[,2])\n\n  # Account for H=L=C\n  clv[is.nan(clv) | is.infinite(clv)] <- 0\n\n  if(is.xts(clv)) colnames(clv) <- 'clv'\n  reclass( clv, HLC )\n}\n"
  },
  {
    "path": "R/CMF.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Chaikin Money Flow\n#'\n#' Chaikin Money Flow compares total volume over the last \\code{n} time periods\n#' to total volume times the Close Location Value (CLV) over the last \\code{n}\n#' time periods.  Developed by Marc Chaikin.\n#'\n#' Chaikin Money Flow is calculated by taking dividing the sum of the Chaikin\n#' Accumulation / Distribution line over the past \\code{n} periods by the sum of\n#' volume over the past \\code{n} periods.\n#'\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices.\n#' @param volume Vector or matrix of volume observations corresponding to the\n#' \\code{HLC} object.\n#' @param n Number of periods to use.\n#' @return A object of the same class as \\code{HLC} and \\code{volume} or a\n#' vector (if \\code{try.xts} fails) containing the Chaikin Money Flow values.\n#' @note When Chaikin Money Flow is above/below +/- 0.25 it is a bullish/bearish\n#' signal.  If Chaikin Money Flow remains below zero while the price is rising,\n#' it indicates a probable reversal.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{CLV}}, and \\code{\\link{chaikinAD}}.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://www.fmlabs.com/reference/ChaikinMoneyFlow.htm}\\cr\n#' \\url{https://www.linnsoft.com/techind/chaikin-money-flow-cmf}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:chaikin_money_flow_cmf}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  cmf <- CMF(ttrc[,c(\"High\",\"Low\",\"Close\")], ttrc[,\"Volume\"])\n#'\n\"CMF\" <-\nfunction(HLC, volume, n=20) {\n\n  # Chaikin Money Flow\n\n  HLC <- try.xts(HLC, error=as.matrix)\n  volume <- try.xts(volume, error=as.matrix)\n\n  if(!(is.xts(HLC) && is.xts(volume))) {\n    clv <- CLV(as.matrix(HLC))\n    volume <- as.matrix(volume)\n  }\n  clv <- CLV(HLC)\n\n  cmf <- runSum(clv*volume, n) / runSum(volume, n)\n\n  reclass(cmf, HLC)\n}\n"
  },
  {
    "path": "R/CMO.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Chande Momentum Oscillator\n#'\n#' The Chande Momentum Oscillator (CMO) is a modified RSI.  Developed by Tushar\n#' S. Chande.\n#'\n#' The CMO divides the total movement by the net movement ([up - down] / [up +\n#' down]), where RSI divides the upward movement by the net movement (up / [up +\n#' down]).\n#'\n#' @param x Price, volume, etc. series that is coercible to xts or matrix.\n#' @param n Number of periods to use.\n#' @return A object of the same class as \\code{x} or a vector (if \\code{try.xts}\n#' fails) containing Chande Momentum Oscillator values.\n#' @note There are several ways to interpret the CMO:\n#'  \\enumerate{\n#'    \\item Values over/under +/- 50 indicate overbought/oversold conditions.\n#'    \\item High CMO values indicate strong trends.\n#'    \\item When the CMO crosses above/below a moving average of the CMO,\n#'          it is a buy/sell signal.\n#'  }\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{RSI}}.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://www.fmlabs.com/reference/CMO.htm}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  cmo <- CMO(ttrc[,\"Close\"])\n#'\n\"CMO\" <-\nfunction(x, n=14) {\n\n  # Chande Momentum Oscillator\n\n  x <- try.xts(x, error=as.matrix)\n\n  up <- momentum(x, n=1)\n  dn <- ifelse(up<0, abs(up), 0)\n  up <- ifelse(up>0,     up , 0)\n\n  up <- runSum(up, n)\n  dn <- runSum(dn, n)\n\n  cmo <- 100 * (up-dn)/(up+dn)\n\n  if (!is.null(dim(cmo)) && ncol(cmo) == 1L) {\n    colnames(cmo) <- \"cmo\"\n  }\n\n  reclass( cmo, x )\n}\n"
  },
  {
    "path": "R/CTI.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2020  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Ehler's Correlation Trend Indicator\n#'\n#' Ehler's Correlation Trend Indicator (CTI) measures the Spearman correlation\n#' of the price with the ideal trend line: a straight line with increasing\n#' slope.\n#'\n#' The CTI measures the Spearman correlation between the price and the ideal\n#' trend line with slope of \\code{slope}, over the past \\code{n} days.\n#'\n#' See URL in references section for further details.\n#'\n#' @param price Price series that is coercible to xts or matrix.\n#' @param n Number of periods to use.\n#' @param slope Slope of desired trend.\n#' @return A object of the same class as \\code{price} or a matrix (if\n#' \\code{try.xts} fails) with the column:\n#'  \\describe{\n#'   \\item{cti}{ The Correlation Trend Indicator. }\n#'  }\n#' @note Positive/negative CTI values signal positive/negative correlation with\n#' the desired trend line slope. A simple strategy could be long when the CTI\n#' is positive and, short when it is negative.\n#' @author Ethan Smith, Joshua Ulrich\n#' @seealso See \\code{\\link{aroon}}, \\code{\\link{CCI}}, \\code{\\link{ADX}},\n#' \\code{\\link{VHF}}, \\code{\\link{GMMA}}, \\code{\\link{TDI}} for other\n#' indicators that measure trend direction/strength.\n#' @references\n#' John Ehlers, Correlation Trend Indicator, Stocks & Commodities May-2020\n#' The following site(s) were used to code/document this indicator:\\cr\n#' \\url{https://financial-hacker.com/petra-on-programming-a-unique-trend-indicator/}\\cr\n#' @keywords ts\n#' @examples\n#'\n#' data(ttrc)\n#' cti <- CTI(ttrc[,\"Close\"], n = 20)\n#'\nCTI <-\nfunction(price, n = 20, slope = 1)\n{\n  x <- try.xts(price, error = as.matrix)\n  y <- slope * seq_along(x)\n\n  f <- function(.) {\n    cor(.[,1], .[,2], method = \"spearman\")\n  }\n  cti <- rollapplyr(cbind(x, y), n, f, by.column = FALSE, fill = NA)\n\n  if(!is.null(dim(cti))) {\n    colnames(cti) <- \"cti\"\n  }\n\n  reclass(cti, x)\n}\n"
  },
  {
    "path": "R/DPO.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' De-Trended Price Oscillator\n#'\n#' The Detrended Price Oscillator (DPO) removes the trend in prices - or other\n#' series - by subtracting a moving average of the price from the price.\n#'\n#' The Detrended Price shows cycles and overbought / oversold conditions.\n#'\n#' @param x Price, volume, etc. series that is coercible to xts or matrix.\n#' @param n Number of periods for moving average.\n#' @param maType A function or a string naming the function to be called.\n#' @param shift The number of periods to shift the moving average.\n#' @param percent logical; if \\code{TRUE}, the percentage difference between the\n#' slow and fast moving averages is returned, otherwise the difference between\n#' the respective averages is returned.\n#' @param \\dots Other arguments to be passed to the \\code{maType} function.\n#' @return A object of the same class as \\code{x} or a vector (if \\code{try.xts}\n#' fails) containing the DPO values.\n#' @note\n#' DPO does not extend to the last date because it is based on a displaced moving\n#' average. The calculation shifts the results \\code{shift} periods, so the last\n#' \\code{shift} periods will be zero.\\cr\n#' As stated above, the DPO can be used on any univariate series, not just price.\n#' @section Warning: The detrended price oscillator removes the trend in the\n#' series by centering the moving average. Centering the moving average causes it\n#' to include future data. Therefore, even though this indicator looks like a\n#' classic oscillator, it should not be used for trading rule signals.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\n#' options; and note Warning section.  See \\code{\\link{MACD}} for a general\n#' oscillator.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:detrended_price_osci}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  priceDPO <- DPO(ttrc[,\"Close\"])\n#'  volumeDPO <- DPO(ttrc[,\"Volume\"])\n#'\n\"DPO\" <-\nfunction(x, n=10, maType, shift=n/2+1, percent=FALSE, ...) {\n\n  # De-Trended Price Oscillator\n\n  x <- try.xts(x, error=as.matrix)\n\n  maArgs <- list(n=n, ...)\n  # Default MA\n  if(missing(maType)) {\n    maType <- 'SMA'\n  }\n\n  mavg <- do.call( maType, c( list(x), maArgs ) )\n  mavg <- lag.xts(mavg, -shift)\n\n  if(percent) {\n    DPO <- 100 * ( x[,1] / mavg - 1 )\n  } else {\n    DPO <- x[,1] - mavg\n  }\n\n  reclass( DPO, x )\n}\n"
  },
  {
    "path": "R/DVI.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' DV Intermediate Oscillator\n#'\n#' The DV Intermediate oscillator (DVI) is a very smooth momentum oscillator\n#' that can also be used as a trend indicator.  Created by David Varadi.\n#'\n#' The DVI combines smoothed returns over different time windows and the\n#' relative number of up versus down days (stretch) over different time windows.\n#'\n#' @param price Price series that is coercible to xts or matrix.\n#' @param n Number of periods for the percent rank.\n#' @param wts The weight given to the smoothed returns (magnitude) component and\n#' the up/down days (stretch) component, respectively.\n#' @param smooth The number of periods to smooth price.\n#' @param magnitude A set of 3 periods used to smooth magnitude.\n#' @param stretch A set of 3 periods used to smooth stretch.\n#' @param exact.multiplier The weight applied to identical values in the window.\n#' See \\code{runPercentRank}.\n#' @return A object of the same class as \\code{price} or a vector (if\n#' \\code{try.xts} fails) containing the DVI values.\n#' @author Joshua Ulrich\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://cssanalytics.wordpress.com/2009/12/13/what-is-the-dvi/}\\cr\n#' \\url{https://marketsci.wordpress.com/2010/07/27/css-analytics\\%E2\\%80\\%99-dvi-indicator-revealed/}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  dvi <- DVI(ttrc[,\"Close\"])\n#'\nDVI <- function(price, n=252, wts=c(0.8,0.2), smooth=3,\n  magnitude=c(5,100,5), stretch=c(10,100,2), exact.multiplier=1) {\n\n  # David Varadi's DVI indicator\n\n  # try to convert 'price' to xts\n  price <- try.xts(price, error=as.matrix)\n\n  # ensure magnitude + stretch = 1\n  wts.sum <- sum(wts)\n  wts[1] <- wts[1] / wts.sum\n  wts[2] <- wts[2] / wts.sum\n\n  # calculate magnitude, based on average price return\n  r <- price/SMA(price,smooth)-1\n  mag <- SMA( ( SMA(r,magnitude[1]) + SMA(r,magnitude[2])/10 )/2, magnitude[3] )\n\n  # calculate stretch, based on whether return is +/-\n  b <- ifelse( price > lag.xts(price), 1, -1 )\n  str <- SMA( ( runSum(b,stretch[1]) + runSum(b,stretch[2])/10 )/2, stretch[3] )\n\n\n  # calculate the DVI magnitude and stretch for each period\n  dvi.mag <- runPercentRank(mag, n, FALSE, exact.multiplier)\n  dvi.str <- runPercentRank(str, n, FALSE, exact.multiplier)\n\n  # calculate final DVI value\n  dvi <- wts[1] * dvi.mag + wts[2] * dvi.str\n\n  result <- cbind(dvi.mag, dvi.str, dvi)\n  colnames(result) <- c(\"dvi.mag\", \"dvi.str\", \"dvi\")\n\n  # convert final DVI, magnitude, and stretch back to\n  # original class of 'price'\n  reclass(result, price)\n}\n\n"
  },
  {
    "path": "R/DonchianChannel.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Donchian Channel\n#'\n#' Donchian Channels were created by Richard Donchian and were used to generate\n#' buy and sell signals for the Turtle Trading system.\n#'\n#' Donchian Channels consist of two (sometimes three) lines:\n#'\n#' The top line is the highest high of the past \\code{n} periods.  The bottom\n#' line is the lowest low of the past \\code{n} periods.  The middle line is the\n#' average of the top and bottom lines.\n#'\n#' @aliases DonchianChannel Donchian\n#' @param HL Object that is coercible to xts or matrix and contains High-Low\n#' prices.\n#' @param n Number of periods for moving average.\n#' @param include.lag Should values be lagged so that today's prices are not\n#' included in the calculation? See Note.\n#' @return A object of the same class as \\code{HL} or a matrix (if\n#' \\code{try.xts} fails) containing the columns:\n#'  \\describe{\n#'   \\item{ high }{ The highest high series. }\n#'   \\item{ mid }{ The average of \\code{high} and \\code{low}. }\n#'   \\item{ low }{ The lowest low series. }\n#'  }\n#' @note The default of \\code{include.lag=FALSE} makes \\code{DonchainChannel}\n#' consistent with other \\pkg{TTR} functions, in that it includes the current\n#' period in the calculation.\n#'\n#' The default is different than the original calculation, which would calculate\n#' the indicator using periods t-1 through t-n. Setting \\code{include.lag=TRUE}\n#' will return the result of the original calculation.\n#'\n#' The default of this argument may change in the future.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{BBands}}.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://www.linnsoft.com/techind/donchian-channels}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  dc <- DonchianChannel( ttrc[,c(\"High\",\"Low\")] )\n#'\n'DonchianChannel' <-\nfunction(HL, n=10, include.lag=FALSE) {\n\n  # Donchian Channel\n\n  # Notes from John Bollinger:\n  #\n  # \"In the old paper-calculation days you would calculate the numbers\n  #  after the close by hand and for use in the next day's trading to gauge\n  #  the \"n-day\" breakouts and you would have used n-days worth of data the\n  #  calc. Thus an n-day calc with a lag of one would be consistent with\n  #  practice in Donchian's day. (Total window of n+1.) Another example are\n  #  the floor traders numbers or pivots, which are calculated from the\n  #  prior period's data for use on the current period. In both case\n  #  including the current period in the calculation would not be correct.\"\n\n  HL <- try.xts(HL, error=as.matrix)\n\n  if(!(NCOL(HL) %in% c(1,2))) {\n    stop(\"Price series must be either High-Low, or Close/univariate.\")\n  }\n  if(NCOL(HL)==2) {\n      hi <- HL[,1]\n      lo <- HL[,2]\n  } else {\n      hi <- HL\n      lo <- HL\n  }\n\n  high <- runMax(hi,n)\n  low  <- runMin(lo,n)\n  mid  <- (high+low)/2\n\n  result <- cbind(high,mid,low)\n  colnames(result) <- c(\"high\",\"mid\",\"low\")\n\n  if(include.lag) {\n    # use lag.xts in case 'result' is a matrix\n    result <- lag.xts(result)\n  }\n\n  reclass(result, HL)\n}\n"
  },
  {
    "path": "R/EMV.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Arms' Ease of Movement Value\n#'\n#' Arms' Ease of Movement Value (EMV) emphasizes days where the security moves\n#' easily and minimizes days where the security does not move easily.  Developed\n#' by Richard W. Arms, Jr.\n#'\n#' The EMV is calculated by dividing the midpoint ([high + low]/2) move by the\n#' 'Box Ratio' (volume divided by the high minus low).\n#'\n#' @param HL Object that is coercible to xts or matrix and contains High-Low\n#' prices.\n#' @param volume Vector or matrix of volume observations corresponding to the\n#' \\code{HL} object.\n#' @param n Number of periods for moving average.\n#' @param maType A function or a string naming the function to be called.\n#' @param vol.divisor An increment to make the results larger and easier to work\n#' with.\n#' @param \\dots Other arguments to be passed to the \\code{maType} function.\n#' @return A object of the same class as \\code{HL} and \\code{volume} or a matrix\n#' (if \\code{try.xts} fails) containing the columns:\n#'  \\describe{\n#'   \\item{ emv }{ The ease of movement values. }\n#'   \\item{ maEMV }{ The smoothed (as specified by \\code{ma}) ease of movement values. }\n#'  }\n#' @note A buy/sell signal is generated when the EMV crosses above/below zero.\n#' When the EMV hovers around zero, there are small price movements and/or high\n#' volume, and the price is not moving easily.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\n#' options; and note Warning section.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://www.fmlabs.com/reference/ArmsEMV.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=51}\\cr\n#' \\url{https://www.linnsoft.com/techind/arms-ease-movement}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  emv <- EMV(ttrc[,c(\"High\",\"Low\")], ttrc[,\"Volume\"])\n#'\n\"EMV\" <-\nfunction(HL, volume, n=9, maType, vol.divisor=10000, ...) {\n\n  # Arms' Ease of Movement Value\n\n  if( missing(HL) || missing(volume) )\n    stop(\"High-Low matrix (HL) and volume vector must be specified.\")\n\n  HL <- try.xts(HL, error=as.matrix)\n  volume <- try.xts(volume, error=as.matrix)\n\n  if(!(is.xts(HL) && is.xts(volume))) {\n    HL <- as.matrix(HL)\n    volume <- as.matrix(volume)\n  }\n\n  mid     <- ( HL[,1] + HL[,2] ) / 2\n  volume  <- volume / vol.divisor\n\n  emv    <- momentum(mid, n=1, na.pad=TRUE) / ( volume / ( HL[,1] - HL[,2] ) )\n\n  maArgs <- list(n=n, ...)\n  # Default MA\n  if(missing(maType)) {\n    maType <- 'SMA'\n  }\n\n  maEMV <- do.call( maType, c( list(emv), maArgs ) )\n\n  result <- cbind(emv,maEMV)\n  colnames(result) <- c('emv','maEMV')\n\n  reclass( result, HL )\n}\n"
  },
  {
    "path": "R/GMMA.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Guppy Multiple Moving Averages\n#'\n#' Calculate the Guppy Multiple Moving Average of a series.\n#'\n#' The Guppy Multiple Moving Average signals a changing trend when the\n#' \\code{short} and \\code{long} groups of moving averages intersect.  An up/down\n#' trend exists when the short/long-term moving averages are greater than the\n#' long/short-term averages.\n#'\n#' @aliases GMMA Guppy guppy\n#' @param x Price, volume, etc. series that is coercible to xts or matrix.\n#' @param short Vector of short-term periods.\n#' @param long Vector of long-term periods.\n#' @param maType Either:\n#'  \\enumerate{\n#'    \\item A function or a string naming the function to be called.\n#'    \\item A \\emph{list} with the first component like (1) above, and\n#'      additional parameters specified as \\emph{named} components.\n#'      See Examples.\n#'  }\n#' @return A object of the same class as \\code{x} or \\code{price} or a vector\n#' (if \\code{try.xts} fails) containing the Guppy Multiple Moving Average.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{aroon}}, \\code{\\link{CCI}}, \\code{\\link{ADX}},\n#' \\code{\\link{VHF}}, \\code{\\link{TDI}} for other indicators that measure trend\n#' direction/strength.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://www.investopedia.com/terms/g/guppy-multiple-moving-average.asp}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  gmma <- GMMA(ttrc[,\"Close\"])\n#'\n\"GMMA\" <-\nfunction(x, short=c(3,5,8,10,12,15), long=c(30,35,40,45,50,60), maType) {\n\n  # Guppy Multiple Moving Average\n\n  x <- try.xts(x, error=as.matrix)\n\n  # Default MA\n  if(missing(maType)) {\n    maType <- 'EMA'\n  }\n\n  fn <- function(g) { do.call(maType, list(x,n=g)) }\n  gmma <- do.call(cbind, lapply(c(short,long), fn))\n  colnames(gmma) <- c(paste('short lag',short),paste('long lag',long))\n\n  reclass(gmma, x)\n}\n"
  },
  {
    "path": "R/KST.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Know Sure Thing\n#'\n#' The Know Sure Thing (KST) is a smooth, summed, rate of change indicator.\n#' Developed by Martin Pring.\n#'\n#' For each day (week, month, etc.), the KST calculates the ROC over several\n#' periods.  Those ROCs are smoothed using the given moving averages, then\n#' multiplied by their respective weighting values.  The resulting values are\n#' summed for each day (month, week, etc.).\n#'\n#' @param price Price series that is coercible to xts or matrix.\n#' @param n A vector of the number of periods to use in the MA calculations.\n#' @param nROC A vector of the number of periods to use in the ROC calculations.\n#' @param nSig The number of periods to use for the KST signal line.\n#' @param maType Either:\n#'  \\enumerate{\n#'    \\item A function or a string naming the function to be called.\n#'    \\item A \\emph{list} with the first component like (1) above, and\n#'      additional parameters specified as \\emph{named} components.\n#'      See Examples.\n#'  }\n#' @param wts A vector the same length as \\code{n}, of the weight for each\n#' period (need not sum to one).\n#' @param \\dots Other arguments to be passed to the \\code{maType} function in\n#' case (1) above.\n#' @return A object of the same class as \\code{price} or a vector (if\n#' \\code{try.xts} fails) containing the Know Sure Thing values.\n#' @note The KST indicates bullish/bearish momentum as it crosses above/below\n#' its moving average.  Because the KST tends to lead price action, look for\n#' trend confirmation in the price.\n#'\n#' The default arguments are for the daily KST.  There is also the Long-Term\n#' KST, with arguments: \\code{n=c(9, 12, 18, 24)} - where the periods are\n#' months, not days - and the moving average periods are 6, 6, 6, and 9 months,\n#' respectively.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\n#' options; and note Warning section.  See \\code{\\link{ROC}} for the\n#' rate-of-change function.  See \\code{\\link{MACD}} for a generic oscillator.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://web.archive.org/web/20110715112957/http://www.pring.com/movieweb/daily_kst.htm}\\cr\n#' \\url{https://web.archive.org/web/20100101162707/http://www.pring.com/movieweb/KST_MCM.htm}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  kst <- KST(ttrc[,\"Close\"])\n#'\n#'  kst4MA <- KST(ttrc[,\"Close\"],\n#'    maType=list(list(SMA),list(EMA),list(DEMA),list(WMA)))\n#'\n\"KST\" <-\nfunction(price, n=c(10,10,10,15), nROC=c(10,15,20,30), nSig=9,\n         maType, wts=1:NROW(n), ...) {\n\n  # Know Sure Thing\n\n  # Technical Analysis Explained: The Successful Investor's Guide to\n  # Spotting Investment Trends and Turning Points\n  # Martin J. Pring\n  # http://www.pring.com/index.html\n  # Daily:\thttp://www.pring.com/movieweb/daily_kst.htm\n  # Long-Term:\thttp://www.pring.com/articles/article28.htm\n\n  # Daily KST\n  # MA(ROC(10)10) + MA(ROC(15)10) + MA(ROC(20)10) + MA(ROC(30)15)\n  #\n  # Intermediate KST\n  # MA(ROC(10)10) + MA(ROC(13)13) + MA(ROC(15)15) + MA(ROC(20)20)\n  #\n  # Long-Term Monthly KST\n  # MA(ROC(9)6) + MA(ROC(12)6) + MA(ROC(18)6) + MA(ROC(24)9)\n\n  if( !all.equal(NROW(n), NROW(wts), NROW(nROC)) ) {\n    stop(\"'n', 'nROC', and 'wts' must be the same length.\")\n  } else {\n    N <- NROW(n)\n  }\n\n  #price <- as.vector(price)\n  ret <- NULL\n\n  # Default MA\n  if(missing(maType)) {\n    maType <- 'SMA'\n  }\n\n  # Case of two different 'maType's for both MAs.\n  if( is.list(maType) ) {\n\n    # Make sure maType is a list of lists\n    maTypeInfo <- sapply(maType,is.list)\n    if( !(all(maTypeInfo) && length(maTypeInfo) == N) ) {\n      stop(\"If \\'maType\\' is a list, you must specify\\n \",\n      \"the same number of MAs as elements in \\'n\\' and\\n \",\n      \"\\'nROC\\' (see Examples section of ?KST)\")\n    }\n\n    # If MA function has 'n' arg, see if it's populated in maType;\n    # if it isn't, populate it with formal 'n'\n    for(i in 1:length(maType)) {\n      if( !is.null( formals(maType[[i]][[1]])$n ) && is.null( maType[[i]]$n ) ) {\n        maType[[i]]$n <- n[i]\n      }\n      roc <- ROC(price, nROC[i], na.pad=TRUE)\n      ma.roc <- do.call( maType[[i]][[1]], c( list(roc), maType[[i]][-1] ) ) * wts[i]\n      ret <- cbind( ret, ma.roc )\n    }\n\n  }\n\n  # Case of one 'maType' for both MAs.\n  else {\n\n    for(i in 1:NROW(n)) {\n      roc <- ROC(price, nROC[i], na.pad=TRUE)\n      ma.roc <- do.call( maType, c( list(roc), list(n=n[i], ...) ) ) * wts[i]\n      ret <- cbind( ret, ma.roc )\n    }\n\n  }\n\n  if(is.xts(ret)) {\n    kst <- xts(100 * rowSums(ret),index(ret))\n  } else {\n    kst <- 100 * rowSums(ret)\n  }\n\n  if( is.list(maType) ) {\n    sigMA <- length(maType)\n    signal <- do.call( maType[[sigMA]][[1]], c( list(kst), maType[[sigMA]][-1] ) )\n  } else {\n    signal <- do.call( maType, c( list(kst), list(n=nSig, ...) ) )\n  }\n\n  result <- cbind( kst, signal )\n  colnames(result) <- c( \"kst\", \"signal\" )\n\n  return( result )\n}\n"
  },
  {
    "path": "R/MACD.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' MACD Oscillator\n#'\n#' The MACD was developed by Gerald Appel and is probably the most popular price\n#' oscillator.  The MACD function documented in this page compares a fast moving\n#' average (MA) of a series with a slow MA of the same series.  It can be used\n#' as a generic oscillator for any univariate series, not only price.\n#'\n#' The MACD function either subtracts the fast MA from the slow MA, or finds the\n#' rate of change between the fast MA and the slow MA.\n#'\n#' @param x Object that is coercible to xts or matrix; usually price, but can be\n#' volume, etc.\n#' @param nFast Number of periods for fast moving average.\n#' @param nSlow Number of periods for slow moving average.\n#' @param nSig Number of periods for signal moving average.\n#' @param maType Either:\n#'  \\enumerate{\n#'    \\item A function or a string naming the function to be called.\n#'    \\item A \\emph{list} with the first component like (1) above, and\n#'      additional parameters specified as \\emph{named} components.\n#'      See Examples.\n#'  }\n#' @param percent logical; if \\code{TRUE}, the percentage difference between the\n#' fast and slow moving averages is returned, otherwise the difference between\n#' the respective averages is returned.\n#' @param \\dots Other arguments to be passed to the \\code{maType} function in\n#' case (1) above.\n#' @return A object of the same class as \\code{x} or a matrix (if \\code{try.xts}\n#' fails) containing the columns:\n#'  \\describe{\n#'   \\item{ macd }{ The price (volume, etc.) oscillator. }\n#'   \\item{ signal }{ The oscillator signal line (a moving average of the oscillator). }\n#'  }\n#' @note The MACD is a special case of the general oscillator applied to price.\n#' The MACD can be used as a general oscillator applied to any series. Time\n#' periods for the MACD are often given as 26 and 12, but the original formula\n#' used exponential constants of 0.075 and 0.15, which are closer to\n#' 25.6667 and 12.3333 periods.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\n#' options; and note Warning section.\n#' @references The following site(s) were used to code/document this\n#' indicator:\n#' \\cr Moving Average Convergence/Divergence (MACD):\\cr\n#' \\url{https://www.fmlabs.com/reference/MACD.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=66}\\cr\n#' \\url{https://www.linnsoft.com/techind/macd}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:moving_average_convergence_divergence_macd}\\cr\n#' \\cr Price Oscillator:\\cr\n#' \\url{https://www.fmlabs.com/reference/PriceOscillator.htm}\\cr\n#' \\url{https://www.fmlabs.com/reference/PriceOscillatorPct.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=94}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:price_oscillators_ppo}\\cr\n#' \\cr Volume Oscillator:\\cr\n#' \\url{https://www.fmlabs.com/reference/PVO.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=122}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'\n#'  macd  <- MACD( ttrc[,\"Close\"], 12, 26, 9, maType=\"EMA\" )\n#'  macd2 <- MACD( ttrc[,\"Close\"], 12, 26, 9,\n#'           maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA)) )\n#'\n\"MACD\" <-\nfunction(x, nFast=12, nSlow=26, nSig=9, maType, percent=TRUE, ...) {\n\n  # Oscillators\n\n  # WISHLIST:\n  # Add capability to allow 'ma.slow' and 'ma.fast' to be vectors\n  # containing MAs, which would allow the oscillator to be constructed\n  # using MAs of different prices.\n\n  # Default MA\n  if(missing(maType)) {\n    maType <- 'EMA'\n  }\n\n  # Case of two different 'maType's for both MAs.\n  if( is.list(maType) ) {\n\n    # Make sure maType is a list of lists\n    maTypeInfo <- sapply(maType,is.list)\n    if( !(all(maTypeInfo) && length(maTypeInfo) == 3) ) {\n      stop(\"If \\'maType\\' is a list, you must specify\\n \",\n      \"*three* MAs (see Examples section of ?MACD)\")\n    }\n\n    # If MA function has 'n' arg, see if it's populated in maType;\n    # if it isn't, populate it with function's formal 'n'\n    if( !is.null( formals(maType[[1]][[1]])$n ) && is.null( maType[[1]]$n ) ) {\n      maType[[1]]$n <- nFast\n    }\n    if( !is.null( formals(maType[[2]][[1]])$n ) && is.null( maType[[2]]$n ) ) {\n      maType[[2]]$n <- nSlow\n    }\n    if( !is.null( formals(maType[[3]][[1]])$n ) && is.null( maType[[3]]$n ) ) {\n      maType[[3]]$n <- nSig\n    }\n\n    mavg.fast <- do.call( maType[[1]][[1]], c( list(x), maType[[1]][-1] ) )\n    mavg.slow <- do.call( maType[[2]][[1]], c( list(x), maType[[2]][-1] ) )\n\n  }\n\n  # Case of one 'maType' for both MAs.\n  else {\n\n    mavg.fast <- do.call( maType, c( list(x), list(n=nFast, ...) ) )\n    mavg.slow <- do.call( maType, c( list(x), list(n=nSlow, ...) ) )\n\n  }\n\n  if(percent) {\n    macd <- 100 * ( mavg.fast / mavg.slow - 1 )\n  } else {\n    macd <- mavg.fast - mavg.slow\n  }\n\n  if( is.list(maType) ) {\n    signal <- do.call( maType[[3]][[1]], c( list( macd ), maType[[3]][-1] ) )\n  } else\n    signal <- do.call( maType, c( list( macd ), list(n=nSig, ...) ) )\n\n  result <- cbind( macd, signal )\n  colnames(result) <- c( \"macd\", \"signal\" )\n\n  return( result )\n}\n"
  },
  {
    "path": "R/MFI.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Money Flow Index\n#'\n#' The MFI is a ratio of positive and negative money flow over time.\n#'\n#' Money Flow (MF) is the product of price and volume.  Positive/negative MF\n#' occur when today's price is higher/lower than yesterday's price.  The MFI is\n#' calculated by dividing positive MF by negative MF for the past \\code{n}\n#' periods.  It is then scaled between 0 and 100.\n#'\n#' MFI is usually calculated using the typical price, but if a univariate series\n#' (e.g. Close, Weighted Close, Median Price, etc.) is provided, it will be used\n#' instead.\n#'\n#' @aliases MFI moneyFlow\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices.  If only a univariate series is given, it will be\n#' used.  See details.\n#' @param volume Vector or matrix of volume observations corresponding to\n#' \\code{HLC} object.\n#' @param n Number of periods to use.\n#' @return A object of the same class as \\code{HLC} and \\code{volume} or a\n#' vector (if \\code{try.xts} fails) containing the MFI values.\n#' @note Divergence between MFI and price can be indicative of a reversal.  In\n#' addition, values above/below 80/20 indicate market tops/bottoms.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{OBV}} and \\code{\\link{CMF}}.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://www.fmlabs.com/reference/default.htm?url=MoneyFlowIndex.htm}\\cr\n#' \\url{https://www.linnsoft.com/techind/money-flow-index-mfi}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:money_flow_index_mfi}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  mfi <- MFI(ttrc[,c(\"High\",\"Low\",\"Close\")], ttrc[,\"Volume\"])\n#'\n\"MFI\" <-\nfunction(HLC, volume, n=14) {\n\n  # Money Flow Index\n\n  HLC <- try.xts(HLC, error=as.matrix)\n  volume <- try.xts(volume, error=as.matrix)\n\n  if(!(is.xts(HLC) && is.xts(volume))) {\n    HLC <- as.matrix(HLC)\n    volume <- as.matrix(volume)\n  }\n\n  if(NCOL(HLC)==3) {\n    if(is.xts(HLC)) {\n      HLC <- xts(apply(HLC, 1, mean),index(HLC))\n    } else {\n      HLC <- apply(HLC, 1, mean)\n    }\n  } else\n  if(NCOL(HLC)!=1) {\n    stop(\"Price series must be either High-Low-Close, or Close/univariate.\")\n  }\n\n  if(is.xts(HLC)) {\n    priceLag <- lag.xts(HLC)\n  } else {\n    priceLag <- c( NA, HLC[-NROW(HLC)] )\n  }\n\n  # Calculate Money Flow\n  mf <- HLC * volume\n  # Calculate positive and negative Money Flow\n  pmf <- ifelse( HLC > priceLag, mf, 0 )\n  nmf <- ifelse( HLC < priceLag, mf, 0 )\n\n  # Calculate Money Ratio and Money Flow Index\n  num <- runSum( pmf, n )\n  den <- runSum( nmf, n )\n  mr <- num / den\n  mfi <- 100 - ( 100 / ( 1 + mr ) )\n  mfi[0 == den] <- 100\n  mfi[0 == den & 0 == num] <- 50\n\n  if(is.xts(mfi)) colnames(mfi) <- 'mfi'\n\n  reclass( mfi, HLC )\n}\n"
  },
  {
    "path": "R/MovingAverages.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Moving Averages\n#'\n#' Calculate various moving averages (MA) of a series.\n#'\n#' \\code{SMA} calculates the arithmetic mean of the series over the past\n#' \\code{n} observations.\n#'\n#' \\code{EMA} calculates an exponentially-weighted mean, giving more weight to\n#' recent observations.  See Warning section below.\n#'\n#' \\code{WMA} is similar to an EMA, but with linear weighting if the length of\n#' \\code{wts} is equal to \\code{n}.  If the length of \\code{wts} is equal to the\n#' length of \\code{x}, the WMA will use the values of \\code{wts} as weights.\n#'\n#' \\code{DEMA} is calculated as: \\code{DEMA = (1 + v) * EMA(x,n) -\n#' EMA(EMA(x,n),n) * v} (with the corresponding \\code{wilder} and \\code{ratio}\n#' arguments).\n#'\n#' \\code{EVWMA} uses volume to define the period of the MA.\n#'\n#' \\code{ZLEMA} is similar to an EMA, as it gives more weight to recent\n#' observations, but attempts to remove lag by subtracting data prior to\n#' \\code{(n-1)/2} periods (default) to minimize the cumulative effect.\n#'\n#' \\code{VWMA} and \\code{VWAP} calculate the volume-weighted moving average\n#' price.\n#'\n#' \\code{HMA} a WMA of the difference of two other WMAs, making it very\n#' reponsive.\n#'\n#' \\code{ALMA} inspired by Gaussian filters. Tends to put less weight on most\n#' recent observations, reducing tendency to overshoot.\n#'\n#' @aliases MovingAverages SMA EMA WMA DEMA GD T3 EVWMA ZLEMA VWAP VWMA MA\n#' @param x Price, volume, etc. series that is coercible to xts or matrix.\n#' @param price Price series that is coercible to xts or matrix.\n#' @param volume Volume series that is coercible to xts or matrix, that\n#' corresponds to price series, or a constant.  See Notes.\n#' @param n Number of periods to average over. Must be between 1 and\n#' \\code{nrow(x)}, inclusive.\n#' @param v The 'volume factor' (a number in [0,1]).  See Notes.\n#' @param wts Vector of weights.  Length of \\code{wts} vector must equal the\n#' length of \\code{x}, or \\code{n} (the default).\n#' @param wilder logical; if \\code{TRUE}, a Welles Wilder type EMA will be\n#' calculated; see notes.\n#' @param ratio A smoothing/decay ratio.  \\code{ratio} overrides \\code{wilder}\n#' in \\code{EMA}.\n#' @param offset Percentile at which the center of the distribution should occur.\n#' @param sigma Standard deviation of the distribution.\n#' @param \\dots any other passthrough parameters\n#' @return A object of the same class as \\code{x} or \\code{price} or a vector\n#' (if \\code{try.xts} fails) containing the columns:\n#'  \\describe{\n#'     \\item{SMA}{ Simple moving average. }\n#'     \\item{EMA}{ Exponential moving average. }\n#'     \\item{WMA}{ Weighted moving average. }\n#'     \\item{DEMA}{ Double-exponential moving average. }\n#'     \\item{EVWMA}{ Elastic, volume-weighted moving average. }\n#'     \\item{ZLEMA}{ Zero lag exponential moving average. }\n#'     \\item{VWMA}{ Volume-weighed moving average (same as \\code{VWAP}). }\n#'     \\item{VWAP}{ Volume-weighed average price (same as \\code{VWMA}). }\n#'     \\item{VWA}{ Variable-length moving average. }\n#'     \\item{HMA}{ Hull moving average. }\n#'     \\item{ALMA}{ Arnaud Legoux moving average. }\n#'  }\n#' @note For \\code{EMA}, \\code{wilder=FALSE} (the default) uses an exponential\n#' smoothing ratio of \\code{2/(n+1)}, while \\code{wilder=TRUE} uses Welles\n#' Wilder's exponential smoothing ratio of \\code{1/n}. The \\code{EMA} result\n#' is initialized with the \\code{n}-period sample average at period \\code{n}.\n#' The exponential decay is applied from that point forward.\n#'\n#' Since \\code{WMA} can accept a weight vector of length equal to the length of\n#' \\code{x} or of length \\code{n}, it can be used as a regular weighted moving\n#' average (in the case \\code{wts=1:n}) or as a moving average weighted by\n#' volume, another indicator, etc.\n#'\n#' Since \\code{DEMA} allows adjusting \\code{v}, it is technically Tim Tillson's\n#' generalized DEMA (GD).  When \\code{v=1} (the default), the result is the\n#' standard DEMA.  When \\code{v=0}, the result is a regular EMA.  All other\n#' values of \\code{v} return the GD result.  This function can be used to\n#' calculate Tillson's T3 indicator (see example below).  Thanks to John Gavin\n#' for suggesting the generalization.\n#'\n#' For \\code{EVWMA}, if \\code{volume} is a series, \\code{n} should be chosen so\n#' the sum of the volume for \\code{n} periods approximates the total number of\n#' outstanding shares for the security being averaged.  If \\code{volume} is a\n#' constant, it should represent the total number of outstanding shares for the\n#' security being averaged.\n#' @section Warning : Some indicators (e.g. EMA, DEMA, EVWMA, etc.) are\n#' calculated using the indicators' own previous values, and are therefore\n#' unstable in the short-term.  As the indicator receives more data, its output\n#' becomes more stable.  See example below.\n#' @author Joshua Ulrich, Ivan Popivanov (HMA, ALMA)\n#' @seealso See \\code{\\link{wilderSum}}, which is used in calculating a Welles\n#' Wilder type MA.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://www.fmlabs.com/reference/ExpMA.htm}\\cr\n#' \\url{https://www.fmlabs.com/reference/WeightedMA.htm}\\cr\n#' \\url{https://www.fmlabs.com/reference/DEMA.htm}\\cr\n#' \\url{https://www.fmlabs.com/reference/T3.htm}\\cr\n#' \\url{https://www.linnsoft.com/techind/evwma-elastic-volume-weighted-moving-average}\\cr\n#' \\url{https://www.fmlabs.com/reference/ZeroLagExpMA.htm}\\cr\n#' \\url{https://www.fmlabs.com/reference/VIDYA.htm}\\cr\n#' \\url{https://www.traderslog.com/hullmovingaverage}\\cr\n#' \\url{https://web.archive.org/web/20180222085959/http://arnaudlegoux.com/}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  ema.20 <-   EMA(ttrc[,\"Close\"], 20)\n#'  sma.20 <-   SMA(ttrc[,\"Close\"], 20)\n#'  dema.20 <-  DEMA(ttrc[,\"Close\"], 20)\n#'  evwma.20 <- EVWMA(ttrc[,\"Close\"], ttrc[,\"Volume\"], 20)\n#'  zlema.20 <- ZLEMA(ttrc[,\"Close\"], 20)\n#'  alma <- ALMA(ttrc[,\"Close\"])\n#'  hma <- HMA(ttrc[,\"Close\"])\n#'\n#'  ## Example of Tim Tillson's T3 indicator\n#'  T3 <- function(x, n=10, v=1) DEMA(DEMA(DEMA(x,n,v),n,v),n,v)\n#'  t3 <- T3(ttrc[,\"Close\"])\n#'\n#'  ## Example of short-term instability of EMA\n#'  ## (and other indicators mentioned above)\n#'  x <- rnorm(100)\n#'  tail( EMA(x[90:100],10), 1 )\n#'  tail( EMA(x[70:100],10), 1 )\n#'  tail( EMA(x[50:100],10), 1 )\n#'  tail( EMA(x[30:100],10), 1 )\n#'  tail( EMA(x[10:100],10), 1 )\n#'  tail( EMA(x[ 1:100],10), 1 )\n#'\n#' @rdname MovingAverages\n\"SMA\" <-\nfunction(x, n=10, ...) {\n\n  # Simple Moving Average\n\n  ma <- runMean( x, n )\n\n  if(!is.null(dim(ma))) {\n    colnames(ma) <- \"SMA\"\n  }\n\n  return(ma)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname MovingAverages\n\"EMA\" <-\nfunction (x, n=10, wilder=FALSE, ratio=NULL, ...) {\n\n  # Exponential Moving Average\n\n  x <- try.xts(x, error=as.matrix)\n  if( n < 1 || n > NROW(x) )\n    stop(sprintf(\"n = %d is outside valid range: [1, %d]\", n, NROW(x)))\n\n  # If ratio is specified, and n is not, set n to approx 'correct'\n  # value backed out from ratio\n  if(missing(n) && !missing(ratio))\n    n <- NULL\n\n  # Call C routine\n  ma <- .Call(C_ema, x, n, ratio, isTRUE(wilder))\n\n  ma <- reclass(ma,x)\n\n  if(!is.null(dim(ma))) {\n    colnames(ma) <- \"EMA\"\n  }\n\n  return(ma)\n\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname MovingAverages\n\"DEMA\" <-\nfunction(x, n=10, v=1, wilder=FALSE, ratio=NULL) {\n\n  # Double Exponential Moving Average\n  # Thanks to John Gavin for the v-factor generalization\n\n  x <- try.xts(x, error=as.matrix)\n  if( n < 1 || n > NROW(x) )\n    stop(sprintf(\"n = %d is outside valid range: [1, %d]\", n, NROW(x)))\n  if(NCOL(x) > 1) {\n    stop(\"ncol(x) > 1. DEMA only supports univariate 'x'\")\n  }\n  if(v < 0 || v > 1) {\n    stop(\"Please ensure 0 <= v <= 1\")\n  }\n\n  if(missing(n) && !missing(ratio))\n    n <- NULL\n\n  # Call C routine\n  ma1 <- .Call(C_ema, x, n, ratio, isTRUE(wilder))\n  d <- .Call(C_ema, ma1, n, ratio, isTRUE(wilder))\n\n  dema <- (1 + v) * ma1 - d * v\n  dema <- reclass(dema, x)\n\n  if(!is.null(dim(dema))) {\n    colnames(dema) <- \"DEMA\"\n  }\n\n  return(dema)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname MovingAverages\n\"WMA\" <-\nfunction(x, n=10, wts=1:n, ...) {\n\n  # Weighted Moving Average\n\n  x <- try.xts(x, error=as.matrix)\n  wts <- try.xts(wts, error=as.matrix)\n\n  if( !any( NROW(wts) == c( NROW(x), n ) ) )\n    stop(\"Length of 'wts' must equal the length of 'x' or 'n'\")\n  if( n < 1 || n > NROW(x) )\n    stop(sprintf(\"n = %d is outside valid range: [1, %d]\", n, NROW(x)))\n  if(NCOL(x) > 1 || NCOL(wts) > 1) {\n    stop(\"ncol(x) > 1 or ncol(wts) > 1. WMA only supports univariate 'x' and 'w'\")\n  }\n\n  # Count NAs, ensure they're only at beginning of data, then remove.\n  NAx <- sum( is.na(x) )\n  NAw <- sum( is.na(wts) )\n  NAs <- max( NAx, NAw )\n  if( NAs > 0 ) {\n    if( any( is.na(  x[-(1:NAx)]) ) )\n      stop(\"'x' contains non-leading NAs\")\n    if( any( is.na(wts[-(1:NAw)]) ) )\n      stop(\"'wts' contains non-leading NAs\")\n  }\n\n  if( NROW(wts) == n ) {\n\n    NAs <- NAx\n\n    if( any(is.na(wts)) )\n      stop(\"'wts' vector of length 'n' cannot have NA values\")\n\n    # Call C routine\n    ma <- .Call(C_wma, x, wts, n)\n\n  } else {\n\n    xw <- cbind(x, wts)\n    ma <- runSum( xw[,1]*xw[,2], n) / runSum(xw[,2], n)\n  }\n\n  # replace 1:(n-1) with NAs and prepend NAs from original data\n  ma[1:(n-1)] <- NA\n\n  # Convert back to original class\n  ma <- reclass(ma,x)\n\n  if(!is.null(dim(ma))) {\n    colnames(ma) <- \"WMA\"\n  }\n\n  return(ma)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname MovingAverages\n\"EVWMA\" <-\nfunction(price, volume, n=10, ...) {\n\n  # Elastic, Volume-Weighted Moving Average\n\n  price <- try.xts(price, error=as.matrix)\n  volume <- try.xts(volume, error=as.matrix)\n\n  if( !any( NROW(volume) == c( NROW(price), 1 ) ) )\n    stop(\"Length of 'volume' must equal 1 or the length of 'price'\")\n  if( n < 1 || n > NROW(price) )\n    stop(sprintf(\"n = %d is outside valid range: [1, %d]\", n, NROW(price)))\n  if(NCOL(price) > 1 || NCOL(volume) > 1) {\n    stop(\"ncol(price) > 1 or ncol(volume) > 1.\",\n         \" EVWMA only supports univariate 'price' and 'volume'\")\n  }\n\n  pv <- cbind(price, volume)\n\n  if( any(nNonNA <- n > colSums(!is.na(pv))) )\n    stop(\"n > number of non-NA values in \",\n         paste(c(\"price\",\"volume\")[which(nNonNA)], collapse=\", \"))\n\n  # Call C routine\n  ma <- .Call(C_evwma, pv[,1], pv[,2], n)\n\n  # Convert back to original class\n  ma <- reclass(ma, price)\n\n  if(!is.null(dim(ma))) {\n    colnames(ma) <- \"EVWMA\"\n  }\n\n  return(ma)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname MovingAverages\n\"ZLEMA\" <-\nfunction (x, n=10, ratio=NULL, ...) {\n\n  # Zero-Lag Exponential Moving Average\n\n  x <- try.xts(x, error=as.matrix)\n  if(NCOL(x) > 1) {\n    stop(\"ncol(x) > 1. ZLEMA only supports univariate 'x'\")\n  }\n\n  # If ratio is specified, and n is not, set n to approx 'correct'\n  # value backed out from ratio\n  if(missing(n) && !missing(ratio))\n    n <- NULL\n\n  # Call C routine\n  ma <- .Call(C_zlema, x, n, ratio)\n\n  # Convert back to original class\n  ma <- reclass(ma,x)\n\n  if(!is.null(dim(ma))) {\n    colnames(ma) <- \"ZLEMA\"\n  }\n\n  return(ma)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname MovingAverages\n\"VWAP\" <- \"VWMA\" <-\nfunction(price, volume, n=10, ...) {\n\n  # Volume-weighted average price\n  # Volume-weighted moving average\n\n  res <- WMA(price, n=n, volume)\n\n  if(!is.null(dim(res))) {\n    colnames(res) <- \"VWAP\"\n  }\n\n  return(res)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname MovingAverages\n\"HMA\" <-\nfunction(x, n=20, ...) {\n\n  # Hull Moving Average\n\n  madiff <- 2 * WMA(x, n = trunc(n / 2), ...) - WMA(x, n = n, ...)\n\n  hma <- WMA(madiff, n = trunc(sqrt(n)), ...)\n\n  if(!is.null(dim(hma))) {\n    colnames(hma) <- \"HMA\"\n  }\n\n  return(hma)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname MovingAverages\n\"ALMA\" <-\nfunction(x, n=9, offset=0.85, sigma=6, ...) {\n\n  # ALMA (Arnaud Legoux Moving Average)\n  x <- try.xts(x, error=as.matrix)\n\n  if(offset < 0 || offset > 1) {\n    stop(\"Please ensure 0 <= offset <= 1\")\n  }\n  if(sigma <= 0)\n    stop(\"sigma must be > 0\")\n\n  m <- floor(offset*(n-1))\n  s <- n/sigma\n  wts <- exp(-((seq(0,n-1)-m)^2)/(2*s*s))\n  sumWeights <- sum(wts)\n  if(sumWeights != 0)\n    wts <- wts/sumWeights\n\n  alma <- x * NA_real_\n  for(i in seq_len(NCOL(x))) {\n    alma[,i] <- WMA(x[,i], n, wts)\n  }\n\n  if(!is.null(dim(alma))) {\n    colnames(alma) <- \"ALMA\"\n  }\n\n  reclass(alma, x)\n}\n"
  },
  {
    "path": "R/OBV.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' On Balance Volume (OBV)\n#'\n#' On Balance Volume (OBV) is a measure of the money flowing into or out of a\n#' security.  It is similar to Chaikin Accumulation / Distribution.\n#'\n#' OBV is calculated by adding (subtracting) each day's volume to a running\n#' cumulative total when the security's price closes higher (lower).\n#'\n#' @param price Price series that is coercible to xts or matrix.\n#' @param volume Volume series that is coercible to xts or matrix, that\n#' corresponds to price object.\n#' @return A object of the same class as \\code{price} and \\code{volume} or a\n#' vector (if \\code{try.xts} fails) containing the OBV values.\n#' @note OBV is usually compared with the price chart of the underlying security\n#' to look for divergences/confirmation.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{chaikinAD}}.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://www.fmlabs.com/reference/OBV.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=82}\\cr\n#' \\url{https://www.linnsoft.com/techind/balance-open-interest}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:on_balance_volume_obv}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  obv <- OBV(ttrc[,\"Close\"], ttrc[,\"Volume\"])\n#'\n\"OBV\" <-\nfunction(price, volume) {\n\n  # On Balance Volume\n\n  price <- try.xts(price, error=as.matrix)\n  volume <- try.xts(volume, error=as.matrix)\n\n  if(!(is.xts(price) && is.xts(volume))) {\n    price <- as.vector(price)\n    volume <- as.vector(volume)\n  }\n  prChg <- ROC(price)\n  obv <- c( volume[1], ifelse( prChg > 0, volume, -volume )[-1] )\n  # OBV[t] = OBV[t-1] if price change is equal to zero\n  obv[abs(prChg) < sqrt(.Machine$double.eps)] <- 0\n  obv <- cumsum( obv )\n\n  if(is.xts(obv)) {\n    obv <- xts(obv,index(price))\n    colnames(obv) <- 'obv'\n  }\n\n  reclass( obv, price )\n}\n"
  },
  {
    "path": "R/RSI.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Relative Strength Index\n#'\n#' The Relative Strength Index (RSI) calculates a ratio of the recent upward\n#' price movements to the absolute price movement.  Developed by J. Welles\n#' Wilder.\n#'\n#' The RSI calculation is \\code{RSI = 100 - 100 / ( 1 + RS )}, where \\code{RS}\n#' is the smoothed ratio of 'average' gains over 'average' losses.  The\n#' 'averages' aren't true averages, since they're divided by the value of\n#' \\code{n} and not the number of periods in which there are  gains/losses.\n#'\n#' @param price Price series that is coercible to xts or matrix.\n#' @param n Number of periods for moving averages.\n#' @param maType Either:\n#'  \\enumerate{\n#'    \\item A function or a string naming the function to be called.\n#'    \\item A \\emph{list} with the first component like (1) above, and\n#'      additional parameters specified as \\emph{named} components.\n#'      See Examples.\n#'  }\n#' @param \\dots Other arguments to be passed to the \\code{maType} function in\n#' case (1) above.\n#' @return A object of the same class as \\code{price} or a vector (if\n#' \\code{try.xts} fails) containing the RSI values.\n#' @note The RSI is usually interpreted as an overbought/oversold (over 70 /\n#' below 30) indicator.  Divergence with price may also be useful.  For example,\n#' if price is making new highs/lows, but RSI is not, it could indicate a\n#' reversal.\n#'\n#' You can calculate a stochastic RSI by using the function \\code{\\link{stoch}}\n#' on RSI values.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\n#' options; and note Warning section.  See \\code{\\link{CMO}} for a variation on\n#' RSI.\n#' @references The following site(s) were used to code/document this\n#' indicator:\n#' \\cr Relative Strength Index:\\cr\n#' \\url{https://www.fmlabs.com/reference/RSI.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=100}\\cr\n#' \\url{https://www.linnsoft.com/techind/relative-strength-index-rsi}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:relative_strength_index_rsi}\\cr\n#' \\cr Stochastic RSI:\\cr\n#' \\url{https://www.fmlabs.com/reference/StochRSI.htm}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:stochrsi}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  price <- ttrc[,\"Close\"]\n#'\n#'  # Default case\n#'  rsi <- RSI(price)\n#'\n#'  # Case of one 'maType' for both MAs\n#'  rsiMA1 <- RSI(price, n=14, maType=\"WMA\", wts=ttrc[,\"Volume\"])\n#'\n#'  # Case of two different 'maType's for both MAs\n#'  rsiMA2 <- RSI(price, n=14, maType=list(maUp=list(EMA),maDown=list(WMA)))\n#'\n#'\n\"RSI\" <-\nfunction(price, n=14, maType, ...) {\n\n  price <- try.xts(price, error=as.matrix)\n\n  up <- momentum(price, n=1, na.pad=TRUE)\n  which.dn <- which(up < 0)\n  dn <- up*0\n  dn[which.dn] <- -up[which.dn]\n  up[which.dn] <- 0\n\n  maArgs <- list(n=n, ...)\n  # Default Welles Wilder EMA\n  if(missing(maType)) {\n    maType <- 'EMA'\n    if(is.null(maArgs$wilder)) {\n      # do not overwrite user-provided value\n      maArgs$wilder <- TRUE\n    }\n  }\n\n  # Case of two different 'maType's for both MAs.\n  # e.g. RSI(price, n=14, maType=list(maUp=list(EMA,ratio=1/5), maDown=list(WMA,wts=1:10)) )\n  if( is.list(maType) ) {\n\n    # Make sure maType is a list of lists\n    maTypeInfo <- sapply(maType,is.list)\n    if( !(all(maTypeInfo) && length(maTypeInfo) == 2) ) {\n      stop(\"If \\'maType\\' is a list, you must specify\\n \",\n      \"*two* MAs (see Examples section of ?RSI)\")\n    }\n\n    # If MA function has 'n' arg, see if it's populated in maType;\n    # if it isn't, populate it with RSI's formal 'n'\n    for(i in 1:length(maType)) {\n      if( !is.null( formals(maType[[i]][[1]])$n ) && is.null( maType[[i]]$n ) ) {\n        maType[[i]]$n <- n\n      }\n      mavgUp <- do.call( maType[[1]][[1]], c( list(up), maType[[1]][-1] ) )\n      mavgDn <- do.call( maType[[2]][[1]], c( list(dn), maType[[2]][-1] ) )\n    }\n  }\n\n  # Case of one 'maType' for both MAs.\n  # e.g. RSI(price, n=14, maType=\"WMA\", wts=volume )\n  else {\n\n    mavgUp <- do.call( maType, c( list(up), maArgs ) )\n    mavgDn <- do.call( maType, c( list(dn), maArgs ) )\n  }\n\n  rsi <- 100 * mavgUp / ( mavgUp + mavgDn )\n\n  if (!is.null(dim(rsi)) && ncol(rsi) == 1L) {\n    colnames(rsi) <- \"rsi\"\n  }\n\n  reclass( rsi, price )\n}\n"
  },
  {
    "path": "R/SAR.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Parabolic Stop-and-Reverse\n#'\n#' The Parabolic Stop-and-Reverse calculates a trailing stop.  Developed by J.\n#' Welles Wilder.\n#'\n#' The calculation for the SAR is quite complex.  See the URLs in the references\n#' section for calculation notes.\n#'\n#' The SAR assumes that you are always in the market, and calculates the Stop\n#' And Reverse point when you would close a long position and open a short\n#' position or vice versa.\n#'\n#' @param HL Object that is coercible to xts or matrix and contains High-Low\n#' prices.\n#' @param accel accel[1]: Acceleration factor.\\cr accel[2]: Maximum acceleration\n#' factor.\n#' @return A object of the same class as \\code{HL} or a vector (if\n#' \\code{try.xts} fails) containing the Parabolic Stop and Reverse values.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{ATR}} and \\code{\\link{ADX}}, which were also\n#' developed by Welles Wilder.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://www.linnsoft.com/techind/parabolic-sar-sar}\\cr\n#' \\url{https://www.fmlabs.com/reference/SAR.htm}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:parabolic_sar}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=87}\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  sar <- SAR(ttrc[,c(\"High\",\"Low\")])\n#'\n\"SAR\" <-\nfunction(HL, accel=c(.02,.2)) {\n\n  # Parabolic Stop-and-Reverse (SAR)\n  # ----------------------------------------------\n  #       HL = HL vector, matrix, or dataframe\n  # accel[1] = acceleration factor\n  # accel[2] = maximum acceleration factor\n\n  # WISHLIST:\n  # Determine signal based on DM+/DM- for first bar\n  # If sig[1]==1, then ep[1]==high; if sig[1]==-1, then ep[1]==low\n  # The first SAR value should be the opposite (high/low) of ep\n  # The first acceleration factor is based on the first signal\n\n  # Since I've already lost one bar, do what TA-lib does and use that bar to\n  # determine the inital signal value.  Also try to incorporate different\n  # accel factors for long/short.\n  # accel = c( long = c( 0.02, 0.2 ), short = long )\n\n  HL <- try.xts(HL, error=as.matrix)\n\n  # Check for non-leading NAs\n  # Leading NAs are handled in the C code\n  naCheck(HL, 0)  # called for error handling side-effect\n\n  # Call C routine\n  sar <- .Call(C_sar, HL[,1], HL[,2], accel)\n  colnames(sar) <- \"sar\"\n\n  reclass( sar, HL )\n}\n"
  },
  {
    "path": "R/SNR.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2016  Peter Carl, Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Signal to Noise Ratio\n#'\n#' The n-day SNR for a given market is calculated by taking the absolute\n#' price change over an n-day period and dividing it by the average\n#' n-day volatility.\n#'\n#' \\deqn{SNR_n = \\frac{|C_t - C_{t-n}|}{ATR_n}\n#' }{SNR = abs(Cl - lag(Cl,n)) / ATR(HLC, n)$atr}\n#'\n#' Using average true range as the volatility measure captures more of the\n#' intraday and overnight volatility in a way that a measurement of\n#' Close-to-Close price change does not.\n#'\n#' The interpretation is then relatively intuitive: an SNR value of five\n#' indicates that the market has moved five times the volatility (average true\n#' range) over the given look-back period.\n#'\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices.\n#' @param n Number of periods for moving average.\n#' @param ... Other arguments to be passed to \\code{\\link{ATR}}.\n#' @return A object of the same class as HLC or a matrix (if try.xts fails)\n#' containing the signal to noise ratio.\n#' @author Peter Carl\n#' @references Skeggs, James and Hill, Alex (2015). Back in Black Part 2: The\n#' Opportunity Set for Trend Following.\n#'\nSNR <- function(HLC, n, ...) {\n  HLC <- try.xts(HLC, error=as.matrix)\n\n  snr <- abs(HLC[,3] - lag.xts(HLC[,3], n)) / ATR(HLC, n, ...)[,\"atr\"]\n\n  return(reclass(snr, HLC))\n}\n"
  },
  {
    "path": "R/TDI.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Trend Detection Index\n#'\n#' The Trend Detection Index (TDI) attempts to identify starting and ending\n#' trends.  Developed by M. H. Pee.\n#'\n#' The TDI is the (1) absolute value of the \\code{n}-day sum of the \\code{n}-day\n#' momentum, minus the quantity of (2) \\code{multiple}*\\code{n}-day sum of the\n#' absolute value of the \\code{n}-day momentum, minus (3) \\code{n}-day sum of\n#' the absolute value of the \\code{n}-day momentum.\n#'\n#' I.e. TDI = (1) - [ (2) - (3) ]\n#'\n#' The direction indicator is the sum of the \\code{n}-day momentum over the last\n#' \\code{n} days.\n#'\n#' See URL in references section for further details.\n#'\n#' @param price Price series that is coercible to xts or matrix.\n#' @param n Number of periods to use.\n#' @param multiple Multiple used to calculate (2).\n#' @return A object of the same class as \\code{price} or a matrix (if\n#' \\code{try.xts} fails) containing the columns:\n#'  \\describe{\n#'   \\item{ tdi }{ The Trend Detection Index. }\n#'   \\item{ di }{ The Direction Indicator. }\n#'  }\n#' @note Positive/negative TDI values signal a trend/consolidation.  A positive/\n#' negative direction indicator signals a up/down trend.  I.e. buy if the TDI\n#' and the direction indicator are positive, and sell if the TDI is positive\n#' while the direction indicator is negative.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{aroon}}, \\code{\\link{CCI}}, \\code{\\link{ADX}},\n#' \\code{\\link{VHF}}, \\code{\\link{GMMA}} for other indicators that measure trend\n#' direction/strength.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://www.linnsoft.com/techind/trend-detection-index-tdi}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  tdi <- TDI(ttrc[,\"Close\"], n=30)\n#'\n\"TDI\" <-\nfunction(price, n=20, multiple=2) {\n\n  # Trend Detection Index\n\n  price <- try.xts(price, error=as.matrix)\n\n  mom <- momentum(price, n, na.pad=TRUE)\n  mom[is.na(mom)] <- 0\n\n  di  <- runSum(mom, n)\n  abs.di <- abs(di)\n\n  abs.mom.2n <- runSum(abs(mom), n*multiple)\n  abs.mom.1n <- runSum(abs(mom), n  )\n\n  tdi <- abs.di - (abs.mom.2n - abs.mom.1n)\n\n  result <- cbind( tdi,di )\n  colnames(result) <- c( \"tdi\",\"di\" )\n\n  reclass( result, price )\n}\n"
  },
  {
    "path": "R/TRIX.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Triple Smoothed Exponential Oscillator\n#'\n#' The TRIX indicator calculates the rate of change of a triple exponential\n#' moving average.  Developed by Jack K. Hutson.\n#'\n#' The TRIX is calculated as follows:\\cr 3MA = \\code{MA}( \\code{MA}(\n#' \\code{MA}(\\code{price}) ) )\\cr trix = 100 * [ 3MA(t) / 3MA(t-1) - 1 ]\n#'\n#' @param price Price series that is coercible to xts or matrix.\n#' @param n Number of periods for moving average.\n#' @param nSig Number of periods for signal line moving average.\n#' @param maType Either:\n#'  \\enumerate{\n#'    \\item A function or a string naming the function to be called.\n#'    \\item A \\emph{list} with the first component like (1) above, and\n#'      additional parameters specified as \\emph{named} components.\n#'      See Examples.\n#'  }\n#' @param percent logical; if \\code{TRUE}, the rate of change is calculated\n#' using the \\code{ROC} function, otherwise the \\code{momentum} function is\n#' used.\n#' @param \\dots Other arguments to be passed to the \\code{maType} function in\n#' case (1) above.\n#' @return A object of the same class as \\code{price} or a vector (if\n#' \\code{try.xts} fails) containing the TRIX values.\n#' @note Buy/sell signals are generated when the TRIX crosses above/below zero.\n#' A nine-period EMA of the TRIX is used as a default signal line.  Buy/sell\n#' signals are generated when the TRIX crosses above/below the signal line and\n#' is also above/below zero.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\n#' options; and note Warning section.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://www.fmlabs.com/reference/default.htm?url=TRIX.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=114}\\cr\n#' \\url{https://www.linnsoft.com/techind/trix-triple-smoothed-exponential-oscillator}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:trix}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  trix  <- TRIX(ttrc[,\"Close\"])\n#'  trix4 <- TRIX(ttrc[,\"Close\"],\n#'  maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA), list(DEMA)))\n#'\n\"TRIX\" <-\nfunction(price, n=20, nSig=9, maType, percent=TRUE, ...) {\n\n  # Triple Smoothed Exponential Oscillator\n\n  # Default MA\n  if(missing(maType)) {\n    maType <- 'EMA'\n  }\n\n  # Case of different 'maType's for all MAs.\n  if( is.list(maType) ) {\n\n    # Make sure maType is a list of lists\n    maTypeInfo <- sapply(maType,is.list)\n    if( !(all(maTypeInfo) && length(maTypeInfo) == 4) ) {\n      stop(\"If \\'maType\\' is a list, you must specify\\n \",\n      \"*four* MAs (see Examples section of ?TRIX)\")\n    }\n\n    # If MA function has 'n' arg, see if it's populated in maType;\n    # if it isn't, populate it with function's formal 'n'\n    if( !is.null( formals(maType[[1]][[1]])$n ) && is.null( maType[[1]]$n ) ) {\n      maType[[1]]$n <- n\n    }\n    if( !is.null( formals(maType[[2]][[1]])$n ) && is.null( maType[[2]]$n ) ) {\n      maType[[2]]$n <- n\n    }\n    if( !is.null( formals(maType[[3]][[1]])$n ) && is.null( maType[[3]]$n ) ) {\n      maType[[3]]$n <- n\n    }\n    if( !is.null( formals(maType[[4]][[1]])$n ) && is.null( maType[[4]]$n ) ) {\n      maType[[4]]$n <- nSig\n    }\n\n    mavg1 <- do.call( maType[[1]][[1]], c( list(price), maType[[1]][-1] ) )\n    mavg2 <- do.call( maType[[2]][[1]], c( list(mavg1), maType[[2]][-1] ) )\n    mavg3 <- do.call( maType[[3]][[1]], c( list(mavg2), maType[[3]][-1] ) )\n\n  }\n\n  # Case of one 'maType' for all MAs.\n  else {\n\n    mavg1 <- do.call( maType, c( list(price), list(n=n, ...) ) )\n    mavg2 <- do.call( maType, c( list(mavg1), list(n=n, ...) ) )\n    mavg3 <- do.call( maType, c( list(mavg2), list(n=n, ...) ) )\n\n  }\n\n  if(percent) {\n    TRIX <- 100 * ROC(mavg3, n=1, na.pad=TRUE, type=\"discrete\")\n  } else {\n    TRIX <- momentum( mavg3, n=1, na.pad=TRUE )\n  }\n\n  if( is.list(maType) ) {\n    signal <- do.call( maType[[4]][[1]], c( list(TRIX), maType[[4]][-1] ) )\n  } else {\n    signal <- do.call( maType, c( list(TRIX), list(n=nSig, ...) ) )\n  }\n\n  result <- cbind( TRIX, signal )\n  colnames(result) <- c( \"TRIX\", \"signal\" )\n\n  return( result )\n}\n"
  },
  {
    "path": "R/TTR-package.R",
    "content": "#' Technical Trading Rule Composite data\n#'\n#' Historical Open, High, Low, Close, and Volume data for the periods January 2,\n#' 1985 to December 31, 2006. Randomly generated.\n#'\n#' These data do not represent an actual security.  They are provided so\n#' examples do not necessitate an internet connection.\n#'\n#' @name ttrc\n#' @docType data\n#' @format The format is: \\tabular{lll}{ Date: \\tab Class 'Date' \\tab 5480 5481\n#' 5482 5485 5486 ...\\cr Open: \\tab num \\tab 3.18 3.09 3.11 3.09 3.10 ...\\cr\n#' High: \\tab num \\tab 3.18 3.15 3.12 3.12 3.12 ...\\cr Low: \\tab num \\tab 3.08\n#' 3.09 3.08 3.07 3.08 ...\\cr Close: \\tab num \\tab 3.08 3.11 3.09 3.10 3.11\n#' ...\\cr Volume: \\tab num \\tab 1870906 3099506 2274157 2086758 2166348 ...\\cr }\n#' @source Randomly generated.\n#' @keywords datasets\n#' @examples\n#'\n#'  data(ttrc)\n#'  plot(tail(ttrc[,\"Close\"],100), type=\"l\")\n#' @rdname ttrc\nNULL\n\n\n#' Functions to create Technical Trading Rules (TTR)\n#'\n#' This package contains many of the most popular technical analysis functions,\n#' as well as functions to retrieve U.S. stock symbols, and data from Yahoo\n#' Finance.\n#'\n#' Users will probably be most interested in the following functions:\\cr\n#' \\code{\\link{ADX}}\\cr \\code{\\link{BBands}}\\cr \\code{\\link{changes}}\\cr\n#' \\code{\\link{MovingAverages}}\\cr \\code{\\link{MACD}}\\cr \\code{\\link{RSI}}\\cr\n#' \\code{\\link{runFun}}\\cr \\code{\\link{stoch}}\\cr \\code{\\link{VWAP}}\\cr\n#' \\code{\\link{WebData}}\\cr\n#'\n#' @name TTR\n#' @aliases TTR-package\n#' @author Joshua Ulrich\n#'\n#' Maintainer: Joshua Ulrich\n#' @references The following sites were used to code/document this package:\\cr\n#' \\url{https://www.fmlabs.com/reference/default.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/}\\cr\n#' \\url{https://www.linnsoft.com/indicators}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators}\\cr\n#' @keywords package\n#' @examples\n#'\n#'  data(ttrc)\n#'\n#'  # Bollinger Bands\n#'  bbands <- BBands( ttrc[,c(\"High\",\"Low\",\"Close\")] )\n#'\n#'  # Directional Movement Index\n#'  adx <- ADX(ttrc[,c(\"High\",\"Low\",\"Close\")])\n#'\n#'  # Moving Averages\n#'  ema <- EMA(ttrc[,\"Close\"], n=20)\n#'  sma <- SMA(ttrc[,\"Close\"], n=20)\n#'\n#'  # MACD\n#'  macd <- MACD( ttrc[,\"Close\"] )\n#'\n#'  # RSI\n#'  rsi <- RSI(ttrc[,\"Close\"])\n#'\n#'  # Stochastics\n#'  stochOsc <- stoch(ttrc[,c(\"High\",\"Low\",\"Close\")])\n#'\n#'  ### Note: you must have a working internet connection\n#'  ### for the examples below to work!\n#'  if (interactive()) {\n#'    # Fetch U.S. symbols from the internet\n#'    nyseSymbols <- stockSymbols(\"NYSE\")\n#'\n#'    # Fetch Yahoo! Finance data from the internet\n#'    ge <- getYahooData(\"GE\", 19990404, 20050607, adjust = FALSE)\n#'  }\n#'\n#' @rdname TTR\n\"_PACKAGE\"\n"
  },
  {
    "path": "R/TTRtools.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Miscellaneous Tools\n#'\n#' Various functions that may be useful in designing technical trading rules.\n#'\n#' \\code{growth} calculates the growth of an investment using given prices and\n#' signals.\n#'\n#' \\code{lags} calculates the lags of a given series.\n#'\n#' @aliases growth lags\n#' @param price Price series that is coercible to xts or matrix.\n#' @param signals Signals to use (defaults to vector of ones).  Use '0' for no\n#' position, '1' for long position, and '-1' for short position.\n#' @param x Object that is coercible to xts or matrix.\n#' @param n Number of periods to use.\n#' @param \\dots Further arguments to be passed from or to other methods.\n#' @return \\code{growth} returns a vector of the growth of the investment.\n#'\n#' \\code{lags} returns a matrix of lagged values of the original vector.\n#'\n#' @note In \\code{growth} you can specify the number of periods and type of\n#' compounding to use when calculating returns of the price series via the\n#' \\code{'\\dots'} argument.\n#' @author Joshua Ulrich\n#' @keywords ts\n#' @rdname TTRtools\n\"lags\" <-\nfunction(x, n=1) {\n\n  #.Deprecated(c(\"xts::lag.xts\",\"quantmod::Lag\"),\"TTR\")\n\n  # Calculate lags of a series\n\n  x <- as.matrix(x)\n  if( is.null(colnames(x)) ) colnames(x) <- paste(\"V\",1:NCOL(x),sep=\"\")\n\n  out <- embed(x, n+1)\n  if(n==1)       lag.names <- 1    else\n  if(NCOL(x)==1) lag.names <- 1:n  else  lag.names <- rep(1:n,NCOL(x))\n\n  colnames(out) <- c( colnames(x), paste(colnames(x), sort(lag.names), sep=\".\") )\n\n  return( out )\n}\n\n#-------------------------------------------------------------------------#\n#' @rdname TTRtools\n\"growth\" <-\nfunction(price, signals, ...) {\n\n  # Calculate growth of $1 for a series of returns (and signals).\n\n  if(missing(signals)) {\n    signals <- rep(1,NROW(price))\n  } else {\n    signals <- as.vector(signals)\n  }\n  price  <- as.vector(price)\n  growth <- cumprod( 1 + ROC(price, ...) * signals )\n\n  return( growth )\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname TTRtools\n'naCheck' <-\nfunction(x, n=0) {\n\n  # Ensure NAs are only at beginning of data.\n  if(is.null(dim(x)[2])) {\n    NAs <- sum(is.na(x))\n    if( NAs > 0 ) {\n      if( any( is.na(x[-(1:NAs)]) ) ) stop(\"Series contains non-leading NAs\")\n    }\n  } else {\n    NAs <- sum( rowSums(is.na(x)) > 0 )\n    if( NAs > 0 ) {\n      if( any( is.na(x[-(1:NAs),]) ) ) stop(\"Series contains non-leading NAs\")\n    }\n  }\n\n  res <- list()\n  res$NAs <- NAs\n  res$nonNA <- (1+NAs):NROW(x)\n  res$beg <- n+NAs\n\n  invisible(res)\n}\n"
  },
  {
    "path": "R/VHF.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Vertical Horizontal Filter\n#'\n#' The Vertical Horizontal Filter (VHF) attempts to identify starting and ending\n#' trends.  Developed by Adam White.\n#'\n#' The VHF is calculated by subtracting the \\code{n}-period lowest low from the\n#' \\code{n}-period highest high and dividing that result by the \\code{n}-period\n#' rolling sum of the close price changes.\n#'\n#' @param price Object that is coercible to xts or matrix and contains a Close\n#' price series, or a High-Low-Close price series.\n#' @param n Number of periods to use.\n#' @return A object of the same class as \\code{price} or a vector (if\n#' \\code{try.xts} fails) containing the VHF values.\n#' @note If Close prices are given, the function calculates the max/min using\n#' only those prices (the default).  If HLC prices are given, the function\n#' calculates the max/min using the high/low prices (added for flexibility).\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{aroon}}, \\code{\\link{CCI}}, \\code{\\link{ADX}},\n#' \\code{\\link{TDI}}, \\code{\\link{GMMA}} for other indicators that measure trend\n#' direction/strength.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=119}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  vhf.close <- VHF(ttrc[,\"Close\"])\n#'  vhf.hilow <- VHF(ttrc[,c(\"High\",\"Low\",\"Close\")])\n#'\n\"VHF\" <-\nfunction(price, n=28) {\n\n  # Vertical Horizontal Filter\n\n  price <- try.xts(price, error=as.matrix)\n\n  # Calculation if price series is given\n  if(NCOL(price)==1) {\n    high  <- price\n    low   <- price\n    close <- price\n  } else\n\n  # Calculation if HLC series is given\n  if(NCOL(price)==3) {\n    high  <- price[,1]\n    low   <- price[,2]\n    close <- price[,3]\n  } else\n\n  stop(\"Price series must be either Close, or High-Low-Close\")\n\n  # Find highest max, and lowest min of price series\n  hmax  <- runMax( high, n)\n  lmin  <- runMin(  low, n)\n  denom <- abs( momentum(close, n=1, na.pad=TRUE) )\n\n  VHF <- ( hmax - lmin ) / runSum(denom, n)\n\n  reclass(VHF, price)\n}\n"
  },
  {
    "path": "R/WPR.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' William's \\%R\n#'\n#' William's \\% R.\n#'\n#' If an High-Low-Close series is provided, the indicator is calculated using\n#' the high/low values.  If a vector is provided, the calculation only uses that\n#' series.\n#'\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices.  If only a univariate series is given, it will be\n#' used.  See details.\n#' @param n Number of periods to use.\n#' @param scale Scale the result to be between 0 and -100.\n#' @return A object of the same class as \\code{HLC} or a vector (if\n#' \\code{try.xts} fails) containing the William's \\%R values.\n#' @note The William's \\%R calculation is similar to stochastics' fast \\%K,\n#' and the result of \\code{WPR} is equal to \\code{1-fastK}.\n#'\n#' The value for William's \\%R will be 0.5 whenever the highest high and\n#' lowest low are the same over the last \\code{n} periods.\n#'\n#' William's \\%R is usually scaled to be between 0 and -100, which is not what\n#' \\code{WPR} returns by default. Set \\code{scale = TRUE} to return the result\n#' with the usual scaling.\n#'\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{stoch}}.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://www.fmlabs.com/reference/WilliamsR.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=126}\\cr\n#' \\url{https://www.linnsoft.com/techind/williams-r-wpr}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:williams_r}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  hlc <- ttrc[,c(\"High\",\"Low\",\"Close\")]\n#'  stochOsc <- stoch(hlc)\n#'  stochWPR <- WPR(hlc)\n#'\n#'  # WPR is a transformation of stochastics' fastK\n#'  all.equal(stochWPR, 1-stochOsc[,'fastK'])  # TRUE\n#'\n#'  # WPR converted to the usual scaling between 0 and -100\n#'  scaledWPR <- WPR(hlc, scale=TRUE)\n#'\n#'  plot(tail(stochOsc[,\"fastK\"], 100), type=\"l\",\n#'      main=\"Fast %K and Williams %R\", ylab=\"\",\n#'      ylim=range(cbind(stochOsc, stochWPR), na.rm=TRUE) )\n#'  lines(tail(stochWPR, 100), col=\"blue\")\n#'  lines(tail(1-stochWPR, 100), col=\"red\", lty=\"dashed\")\n#'\n\"WPR\" <-\nfunction(HLC, n=14, scale=FALSE) {\n\n  # William's Percent R (similar to Stochastics' fast %K)\n\n  HLC <- try.xts(HLC, error=as.matrix)\n\n  # Calculation if HLC series is given\n  if(NCOL(HLC)==3) {\n    high  <- HLC[,1]\n    low   <- HLC[,2]\n    close <- HLC[,3]\n  } else\n\n  # Calculation if price vector is given\n  if(NCOL(HLC)==1) {\n    high  <- HLC\n    low   <- HLC\n    close <- HLC\n  } else\n\n  stop(\"Price series must be either High-Low-Close, or Close\")\n\n  hmax <- runMax(high, n)\n  lmin <- runMin( low, n)\n\n  pctR <- (hmax - close) / (hmax - lmin)\n  pctR[is.nan(pctR)] <- 0.5\n\n  if(isTRUE(scale)) {\n      pctR <- -100 * pctR\n  }\n\n  reclass( pctR, HLC )\n}\n"
  },
  {
    "path": "R/WebData.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Fetch Internet Data\n#'\n#' Get investment data from the internet.\n#'\n#' \\code{getYahooData} fetches individual stock data from the Yahoo! Finance\n#' website.  It also adjusts price for splits and dividends, and volume for\n#' splits.  See the Warning section, and note that it is deprecated in favor\n#' of getSymbols in the quantmod package.\n#'\n#' \\code{stockSymbols} fetches instrument symbols from the nasdaq.com website,\n#' and adjusts the symbols to be compatible with the Yahoo! Finance website.\n#'\n#' @aliases WebData getYahooData stockSymbols\n#' @param symbol Yahoo! Finance instrument symbol.\n#' @param start Numeric; first date of desired data, in YYYYMMDD format.\n#' Default is first date of series.\n#' @param end Numeric; last date of desired data, in YYYYMMDD format.  Default\n#' is last date of series.\n#' @param freq Desired data frequency.  One of \\code{\"daily\"}, \\code{\"weekly\"},\n#' \\code{\"monthly\"}.\n#' @param type Type of data to return.  One of \\code{\"price\"}, or\n#' \\code{\"split\"}.  \\code{type=\"split\"} will return both split and dividend\n#' data.\n#' @param adjust Logical; if \\code{TRUE}, the Open, High, Low, and Close prices\n#' will be adjusted for dividends and splits, and Volume will be adjusted for\n#' dividends.\n#' @param quiet Logical; if \\code{TRUE}, status messages will be printed to the\n#' console.\n#' @param exchange Character vector of exchange names on which desired\n#' instrument symbols are traded.\n#' @param sort.by Character vector of columns by which returned data will be\n#' sorted.  Must be one or more of \\code{\"Name\"}, \\code{\"Symbol\"},\n#' \\code{\"Market.Cap\"}, or \\code{\"Exchange\"}.\n#' @return \\code{getYahooData} returns an xts object containing the columns:\n#'\n#' \\code{stockSymbols} returns a character vector containing all the listed\n#' symbols for the given exchanges.\n#'  \\describe{\n#'     \\item{ Date }{ Trade date, in CCYYMMDD format. }\n#'     \\item{ Open }{ Open price. }\n#'     \\item{ High }{ High price. }\n#'     \\item{ Low }{ Low price. }\n#'     \\item{ Close }{ Close price. }\n#'     \\item{ Volume }{ Volume. }\n#'  }\n#' @note The symbols returned by \\code{stockSymbols} may not be in the format\n#' necessary to retrieve data using \\code{getYahooData}.\n#'\n#' \\code{getYahooData} has only been tested on daily data.  It isn't known if\n#' the function correctly adjusts data for any other frequency.\n#' @author Joshua Ulrich\n#' @keywords ts\n#' @examples\n#'\n#'  ### Note: you must have a working internet\n#'  ### connection for these examples to work!\n#'  if (interactive()) {\n#'    ge <- getYahooData(\"GE\", 19990404, 20050607, adjust = FALSE)\n#'\n#'    nyse.symbols <- stockSymbols(\"NYSE\")\n#'  }\n#'\n#' @section Warning:\n#' As of TTR 0.23-2, \\code{getYahooData} has been patched to work with changes\n#' to Yahoo Finance, which also included the following changes to the raw data:\n#'   \\itemize{\n#'     \\item The adjusted close column appears to no longer include dividend adjustments\n#'     \\item The open, high, and low columns are adjusted for splits, and\n#'     \\item The raw data may contain missing values.\n#'     \\item The raw data may contain errors.\n#'   }\n#'\n#' As of TTR 0.24.2, \\code{stockSymbols} began using data from NASDAQ's FTP\n#' site because the data from the original site is no longer available. This\n#' new file does not contain data for the columns: LastSale, MarketCap,\n#' IPOyear, Sector, and Industry. All the columns still appear in the results,#' but all the values in the columns are set to \\code{NA}.\n#'\n#' @references\n#'\n#'  \\itemize{\n#'    \\item \\href{https://quant.stackexchange.com/questions/1640/where-to-download-list-of-all-common-stocks-traded-on-nyse-nasdaq-and-amex/1862}{Quant StackExchange: Download list of all stock symbols?}\n#'    \\item \\href{https://www.nasdaqtrader.com/trader.aspx?id=CQSsymbolconvention}{CQS symbol convention}\n#'    \\item \\href{https://web.archive.org/web/20111023221931/http://help.yahoo.com/l/us/yahoo/finance/quotes/quote-02.html}{Yahoo Finance symbol conventions}\n#'  }\n#'\n#' @rdname WebData\n\"stockSymbols\" <-\nfunction(exchange = c(\"AMEX\", \"NASDAQ\", \"NYSE\", \"ARCA\", \"BATS\", \"IEX\"),\n         sort.by = c(\"Exchange\", \"Symbol\"),\n         quiet = FALSE)\n{\n\n  # Many thanks to Ion Georgiadis for helpful suggestions and testing.\n\n  # See \"NYSE \"behind the dot\" or Nasdaq 5th-letter codes and other special\n  # codes\" here:\n  # http://en.wikipedia.org/wiki/Ticker_symbol\n  #\n  # AMEX / NYSE Mappings (NASDAQ doesn't need transformation?):\n  # Exchanges -> Yahoo\n  # /WS       -> -WT\n  # /U        -> -U\n  # .[A-Z]    -> NA (special notes/bonds - IG)\n  # :[AP]     -> NA (after-hours / pre-market)\n  # ^         -> -P\n  # /         -> -\n  # $         -> NA (NYSE Only)\n  # ~         -> NA (NYSE Only)\n\n  symbols.colnames <-\n    c(\"Symbol\",\"Name\",\"LastSale\",\"MarketCap\",\"IPOyear\",\"Sector\",\"Industry\",\n      \"Exchange\", \"Test.Issue\", \"Round.Lot.Size\", \"ETF\",\n      \"Market.Category\", \"Financial.Status\", \"Next.Shares\", \"ACT.Symbol\",\n      \"CQS.Symbol\")\n\n  exchange <- match.arg(exchange, several.ok=TRUE)\n  sort.by  <- match.arg(sort.by, symbols.colnames, several.ok=TRUE)\n\n  ### nasdaqlisted.txt\n  ##nasdaq.colnames <-\n  ##  c(\"Symbol\",\n  ##    \"Security.Name\",\n  ##    \"Market.Category\",\n  ##    \"Test.Issue\",\n  ##    \"Financial.Status\",\n  ##    \"Round.Lot.Size\",\n  ##    \"ETF\",\n  ##    \"NextShares\")\n\n  .market.category <-\n    c(Q = \"NASDAQ Global Select MarketSM\",\n      G = \"NASDAQ Global MarketSM\",\n      S = \"NASDAQ Capital Market\")\n\n  ### otherlisted.txt\n  ##other.colnames <-\n  ##  c(\"ACT.Symbol\",\n  ##    \"Security.Name\",\n  ##    \"Exchange\",\n  ##    \"CQS.Symbol\",\n  ##    \"ETF\",\n  ##    \"Round.Lot.Size\",\n  ##    \"Test.Issue\",\n  ##    \"NASDAQ.Symbol\")\n\n  .exchange <-\n    c(A = \"AMEX\",\n      N = \"NYSE\",\n      P = \"ARCA\",\n      Z = \"BATS\",\n      V = \"IEX\")\n\n  .financial.status <-\n    c(D = \"Deficient\",\n      E = \"Delinquent\",\n      Q = \"Bankrupt\",\n      N = \"Normal (Default)\",\n      G = \"Deficient and Bankrupt\",\n      H = \"Deficient and Delinquent\",\n      J = \"Delinquent and Bankrupt\",\n      K = \"Deficient, Delinquent, and Bankrupt\")\n\n  tmp <- tempfile()\n\n  base.url <- \"ftp://ftp.nasdaqtrader.com/SymbolDirectory/\"\n  nasdaq.url <- paste0(base.url, \"nasdaqlisted.txt\")\n  other.url <- paste0(base.url, \"otherlisted.txt\")\n\n  nasdaq <- NULL\n  if (\"NASDAQ\" %in% exchange) {\n    if (!quiet) {\n      message(\"Fetching NASDAQ symbols...\")\n      flush.console()\n    }\n    curl::curl_download(nasdaq.url, destfile = tmp)\n    nasdaq <- read.table(tmp, header = TRUE, sep = \"|\", quote = \"\",\n                         fill = TRUE, na.strings = NULL)\n\n    # add symbols columns not in file\n    nasdaq$Name <- nasdaq$Security.Name\n    nasdaq$Exchange <- \"NASDAQ\"\n    nasdaq[, setdiff(symbols.colnames, colnames(nasdaq))] <- NA\n\n    # order columns\n    nasdaq <- nasdaq[, symbols.colnames]\n\n    # convert market category code to name\n    nasdaq$Market.Category <- .market.category[nasdaq$Market.Category]\n\n    # convert financial status code to name\n    nasdaq$Financial.Status <- .financial.status[nasdaq$Financial.Status]\n  }\n\n  other <- NULL\n  if (length(exchange) > 1L) {\n    if (!quiet) {\n      message(\"Fetching non-NASDAQ symbols...\")\n      flush.console()\n    }\n\n    curl::curl_download(other.url, destfile = tmp)\n    other <- read.table(tmp, header = TRUE, sep = \"|\", quote = \"\",\n                        fill = TRUE, na.strings = NULL)\n\n    # remove last row (File creation time)\n    other <- other[-nrow(other),]\n\n    # add symbols columns not in file\n    other$Name <- other$Security.Name\n    other$Symbol <- other$NASDAQ.Symbol\n    other[, setdiff(symbols.colnames, colnames(other))] <- NA\n\n    # convert exchange code to name\n    other$Exchange <- .exchange[other$Exchange]\n\n    # order columns\n    other <- other[, symbols.colnames]\n  }\n\n  # Append data from all exchanges\n  symbols <- rbind(nasdaq, other)\n\n  # Convert symbol from NASDAQ to Yahoo format\n  # symbols[grep(\"[-.*$+!@%^=#].?$\", symbols$NASDAQ.Symbol),c(\"Symbol\", \"NASDAQ.Symbol\")]\n  symbols$NASDAQ.Symbol <- symbols$Symbol\n  # preferreds\n  symbols$Symbol <- sub(\"-(.?)$\", \"-P\\\\1\", symbols$Symbol)\n  # classes\n  symbols$Symbol <- sub(\"\\\\.(.?)$\", \"-\\\\1\", symbols$Symbol)\n  # warrants\n  symbols$Symbol <- sub(\"\\\\+(.?)$\", \"-WT\\\\1\", symbols$Symbol)\n  # units\n  symbols$Symbol <- sub(\"\\\\=$\", \"-UN\", symbols$Symbol)\n  # rights\n  symbols$Symbol <- sub(\"\\\\^$\", \"-R\", symbols$Symbol)\n\n  # convert ETF and Test.Issue to logical\n  symbols$ETF <- (\"Y\" == symbols$ETF)\n  symbols$Test.Issue <- (\"Y\" == symbols$Test.Issue)\n\n  # Sort\n  symbols <- symbols[do.call(\"order\", symbols[,sort.by]),]\n\n  # Pretty rownames\n  rownames(symbols) <- NULL\n\n  return(symbols)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname WebData\n\"getYahooData\" <-\nfunction(symbol, start, end, freq=\"daily\", type=\"price\", adjust=TRUE, quiet=FALSE) {\n\n  warn.Deprecated <- function() {\n    .Deprecated(\"quantmod::getSymbols\", package = \"TTR\",\n                paste(\"TTR::getYahooData is deprecated and will be removed in a\",\n                      \"future release.\\nPlease use quantmod::getSymbols instead.\"),\n                old = \"getYahooData\")\n  }\n\n  callingFun <- sys.call(-1L)[[1]]\n  if(is.null(callingFun)) {\n    # Called from top level\n    warn.Deprecated()\n  } else {\n    if(is.call(callingFun) && any(deparse(callingFun[[1]]) == c(\"::\", \":::\"))) {\n       if(\"getYahooData\" != as.character(callingFun[[3]])) warn.Deprecated()\n    } else {\n       if(\"getYahooData\" != deparse(callingFun)) warn.Deprecated()\n    }\n  }\n\n  # Thank you to Giorgio Beltrame for the URL to download dividends _and_\n  # splits, and for his correct adjustment procedure.\n  # Many thanks to Ion Georgiadis for helpful suggestions and testing.\n\n  # symbol:  Character, instrument symbol\n  # start:   Numeric, starting date, in ISO-8601 format as ccyymmdd (default\n  #          is series' first date)\n  # end:     Numeric, ending date, in ISO-8601 format as ccyymmdd (default is today)\n  # freq:    Character, frequency of data\n  #          either 'daily', 'weekly', 'monthly'\n  # type:    Character, either 'price' or 'split'\n  # adjust:  Logical, adjusts the Open, High, Low, and Close prices for\n  #          dividends and splits, and adjusts Volume for dividends.\n  #\n  #          http://help.yahoo.com/l/us/yahoo/finance/quotes/quote-12.html\n  #          http://ichart.finance.yahoo.com/x?s=MSFT&g=d&y=0&z=30000\n  #\n  # Requires R-2.4.1\n\n  # Check dates\n  if (missing(start)) {\n    beg <- .dateToUNIX(as.Date(\"1900-01-01\"))\n  } else {\n    beg <- .dateToUNIX(as.Date(as.character(start), \"%Y%m%d\"))\n  }\n  if (missing(end)) {\n    end <- .dateToUNIX(Sys.Date())\n  } else {\n    end <- .dateToUNIX(as.Date(as.character(end), \"%Y%m%d\"))\n  }\n\n  if( beg > end )                     stop(\"Start date must be before end date.\")\n  if (beg > .dateToUNIX(Sys.Date()))  stop(\"Start date is after today's date.\")\n\n  # Get frequency and type parameters\n  intervals <- c(daily = \"1d\", weekly = \"1wk\", monthly = \"1mo\")\n  freq <- match.arg( freq, names(intervals) )\n  interval <- intervals[freq]\n  type <- match.arg( type, c(\"price\",\"split\") )\n  if(type!=\"price\") {\n    if(freq!=\"daily\" && !quiet)\n      message(\"Only freq=\\\"daily\\\" data available for type=\\\"split\\\".\\n\",\n              \"Setting freq=\\\"daily\\\"...\")\n  }\n\n  tmp <- tempfile()\n  on.exit(unlink(tmp), add = TRUE)\n\n  flush.console()\n\n  if(type==\"price\") {\n\n    if(adjust) {\n\n      if(freq==\"daily\") {\n\n        # Get price, dividend, and split data from 'beg' to present\n        ohlc   <- getYahooData(symbol, start, freq=\"daily\", type=\"price\",\n                    adjust=FALSE, quiet=TRUE)\n        divspl <- getYahooData(symbol, start, freq=\"daily\", type=\"split\",\n                    adjust=FALSE, quiet=TRUE)\n        ohlc   <- merge(ohlc, divspl, all=TRUE)\n\n        # If there are no div/spl, then ohlc is a zero-width xts object\n        if(NROW(divspl) != 0) {\n\n          adj <- adjRatios(ohlc[,'Split'],ohlc[,'Div'],ohlc[,'Close'])\n          s.ratio <- adj[,1]\n          d.ratio <- adj[,2]\n\n          # Adjust OHLC and volume\n          cn <- colnames(ohlc)\n          ohlc <- cbind(ohlc,ohlc[,'Close'])\n          colnames(ohlc) <- c(cn,'Unadj.Close')\n          #ohlc[,'Unadj.Close'] <- ohlc[,'Close']\n          ohlc[,'Open']   <- ohlc[,'Open']  * d.ratio * s.ratio\n          ohlc[,'High']   <- ohlc[,'High']  * d.ratio * s.ratio\n          ohlc[,'Low']    <- ohlc[,'Low']   * d.ratio * s.ratio\n          ohlc[,'Close']  <- ohlc[,'Close'] * d.ratio * s.ratio\n          ohlc[,'Volume'] <- ohlc[,'Volume'] * ( 1 / d.ratio )\n\n          # Order columns\n          #ohlc <- ohlc[,c(\"Date\",\"Open\",\"High\",\"Low\",\"Close\",\"Volume\",\n          ohlc <- ohlc[,c(\"Open\",\"High\",\"Low\",\"Close\",\"Volume\",\n                          \"Unadj.Close\",\"Div\",\"Split\",\"Adj.Div\")]\n        }\n\n      } else stop(\"Only freq=\\\"daily\\\" adjusted data is currently supported.\")\n\n      # For other frequencies, get daily data and use a routine to\n      # aggregate to desired frequency.\n\n    } else {\n\n      handle <- .getHandle()\n\n      # Construct URL for 'beg' to 'end'\n      url <- .yahooURL(symbol, beg, end, interval, \"history\", handle)\n\n      # Fetch data\n      curl::curl_download(url, destfile=tmp, quiet=quiet, handle=handle$ch)\n\n      # Read data\n      ohlc <- read.csv(tmp, na.strings=\"null\")\n\n      # Re-order and set column names\n      cnames <- c(\"Date\", \"Open\", \"High\", \"Low\", \"Close\", \"Volume\", \"Adjusted\")\n      corder <- pmatch(substr(cnames, 1, 3), colnames(ohlc))\n      ohlc <- ohlc[,corder]\n      colnames(ohlc) <- cnames\n\n      ohlc[,'Adjusted'] <- NULL\n      ohlc <- ohlc[order(ohlc[,\"Date\"]),]\n      ohlc <- xts(ohlc[,-1], as.Date(as.character(ohlc[,1])))\n\n    }\n\n  } else {\n\n      if(!quiet) message(\"Unadjusted and adjusted dividend data are always returned.\")\n\n      handle <- .getHandle()\n\n      # Split data\n      url <- .yahooURL(symbol, beg, end, \"1d\", \"split\", handle)\n      curl::curl_download(url, destfile=tmp, quiet=quiet, handle=handle$ch)\n      spl <- read.csv(tmp, as.is=TRUE)\n      if(NROW(spl)==0) {\n        spl <- NA\n      } else {\n        spl$V3 <- 1 / sapply(parse(text=spl[,2]), eval)\n        spl <- xts(spl$V3, as.Date(spl[,1], \"%Y-%m-%d\"))\n        colnames(spl) <- NULL\n      }\n\n      # Dividend data\n      url <- .yahooURL(symbol, beg, end, \"1d\", \"div\", handle)\n      curl::curl_download(url, destfile=tmp, quiet=quiet, handle=handle$ch)\n      div <- read.csv(tmp, as.is=TRUE)\n      div <- xts(div[,2],as.Date(div[,1]))\n      colnames(div) <- NULL\n\n      ohlc <- merge(Adj.Div = div, Split = spl)\n\n      # Return (empty) data\n      if(NROW(ohlc)==0) return(ohlc)\n\n      if( all(is.na(ohlc[,'Split'])) ) {\n        s.ratio <- rep(1,NROW(ohlc))\n      } else {\n        s.ratio <- adjRatios(splits=ohlc[,'Split'])[,1]\n      }\n\n      # Un-adjust dividends for Splits\n      ohlc <- cbind(ohlc,ohlc[,\"Adj.Div\"] * ( 1 / s.ratio ))\n      colnames(ohlc)[3] <- \"Div\"\n      ohlc[,'Split'] <- as.numeric(ohlc[,'Split'])\n\n      # Order data columns\n      ohlc <- ohlc[,c(\"Div\",\"Split\",\"Adj.Div\")]\n    }\n\n  # Only return requested data\n  dateRange <- paste(as.Date(.POSIXct(beg, tz = \"UTC\")),\n                     as.Date(.POSIXct(end, tz = \"UTC\")), sep = \"/\")\n  ohlc <- ohlc[dateRange]\n\n  ### Check to see if supplied dates occur in data set\n#  if( max(ohlc[,'Date']) != as.Date(end) ) {\n#    if(!quiet) message(\"End date out of range, \"  , max(ohlc[,'Date']), \" is last available date.\")\n#  }\n#  if( min(ohlc[,'Date']) != as.Date(beg) ) {\n#    if(!quiet) message(\"Start date out of range, \", min(ohlc[,'Date']), \" is first available date.\")\n#  }\n\n  return(ohlc)\n}\n\n.getHandle <- function(force.new = FALSE)\n{\n  h <- if (exists(\"_handle_\", .env)) get(\"_handle_\", .env) else NULL\n\n  if (is.null(h) || force.new) {\n    # create 'h' if it doesn't exist yet\n    if (!force.new) {\n      h <- list()\n    }\n\n    # establish session\n    new.session <- function(h) {\n      tmp <- tempfile()\n      on.exit(unlink(tmp))\n\n      for (i in 1:5) {\n        h <- curl::new_handle()\n        # random query to avoid cache\n        ru <- paste(sample(c(letters, 0:9), 4), collapse = \"\")\n        cu <- paste0(\"https://finance.yahoo.com?\", ru)\n        curl::curl_download(cu, tmp, handle = h)\n        if (NROW(curl::handle_cookies(h)) > 0)\n          break;\n        Sys.sleep(0.1)\n      }\n\n      if (NROW(curl::handle_cookies(h)) == 0)\n        stop(\"Could not establish session after 5 attempts.\")\n\n      return(h)\n    }\n\n    h$ch <- new.session()\n\n    n <- if (unclass(Sys.time()) %% 1L >= 0.5) 1L else 2L\n    query.srv <- paste0(\"https://query\", n, \".finance.yahoo.com/\",\n                        \"v1/test/getcrumb\")\n    cres <- curl::curl_fetch_memory(query.srv, handle = h$ch)\n\n    h$cb <- rawToChar(cres$content)\n    assign(\"_handle_\", h, .env)\n  }\n  return(h)\n}\n\n.yahooURL <-\nfunction(symbol, from, to, period, type, handle)\n{\n  p <- match.arg(period, c(\"1d\", \"1wk\", \"1mo\"))\n  e <- match.arg(type, c(\"history\", \"div\", \"split\"))\n  n <- if (unclass(Sys.time()) %% 1L >= 0.5) 1L else 2L\n  u <- paste0(\"https://query\", n, \".finance.yahoo.com/v7/finance/download/\",\n              symbol, \"?period1=\", from, \"&period2=\", to, \"&interval=\", p,\n              \"&events=\", e, \"&crumb=\", handle$cb)\n  return(u)\n}\n\n.dateToUNIX <- function(Date) {\n  posixct <- as.POSIXct(as.Date(Date, origin = \"1970-01-01\"))\n  trunc(as.numeric(posixct))\n}\n"
  },
  {
    "path": "R/ZigZag.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Zig Zag\n#'\n#' Zig Zag higlights trends by removing price changes smaller than \\code{change}\n#' and interpolating lines between the extreme points.\n#'\n#' The Zig Zag is non-predictive.  The purpose of the Zig Zag is filter noise\n#' and make chart patterns clearer.  It's more a visual tool than an indicator.\n#'\n#' @aliases ZigZag zigzag\n#' @param HL Object that is coercible to xts or matrix and contains either a\n#' High-Low price series, or a Close price series.\n#' @param change Minimum price movement, either in dollars or percent (see\n#' \\code{percent}).\n#' @param percent Use percentage or dollar change?\n#' @param retrace Is \\code{change} a retracement of the previous move, or an\n#' absolute change from peak to trough?\n#' @param lastExtreme If the extreme price is the same over multiple periods,\n#' should the extreme price be the first or last observation?\n#' @return A object of the same class as \\code{HL} or a vector (if\n#' \\code{try.xts} fails) containing the Zig Zag indicator.\n#' @note If High-Low prices are given, the function calculates the max/min using\n#' the high/low prices.  Otherwise the function calculates the max/min of the\n#' single series.\n#' @section Warning: The last value of the ZigZag indicator is unstable (i.e.\n#' unknown) until the turning point actually occurs. Therefore this indicator\n#' isn't well-suited for use for systematic trading strategies.\n#' @author Joshua Ulrich\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://www.fmlabs.com/reference/default.htm?url=ZigZag.htm}\\cr\n#' \\url{https://www.linnsoft.com/techind/zig-zag-indicator-zig-zzo}\\cr\n#' \\url{https://www.linnsoft.com/techind/zig-zag-oscillator-indicator-zzo}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=127}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:zigzag}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  ## Get Data and Indicator ##\n#'  data(ttrc)\n#'  zz <- ZigZag( ttrc[,c(\"High\", \"Low\")], change=20 )\n#'\n\"ZigZag\" <-\nfunction( HL, change=10, percent=TRUE, retrace=FALSE, lastExtreme=TRUE ) {\n\n  # Zig Zag Indicator\n  # Adapted from Alberto Santini's code\n\n  HL <- try.xts(HL, error=as.matrix)\n  HL.na <- naCheck(HL,0)\n\n  # Calculation if HL series is given\n  if(NCOL(HL)==2) {\n    high  <- HL[HL.na$nonNA,1]\n    low   <- HL[HL.na$nonNA,2]\n  } else\n\n  # Calculation if price vector is given\n  if(NCOL(HL.na)==1) {\n    high  <- HL[HL.na$nonNA]\n    low   <- HL[HL.na$nonNA]\n  } else\n\n  stop(\"Price series must be either High-Low, or Univariate\")\n\n  # Call C routine\n  zz <- .Call(C_ttr_zigzag, as.numeric(high), as.numeric(low),\n              as.numeric(change), as.logical(percent), as.logical(retrace),\n              as.logical(lastExtreme))\n\n  # Interpolate results\n  zz <- na.approx(zz, na.rm = FALSE)\n\n  # Prepend NAs from original data\n  zz <- c( rep( NA, HL.na$NAs ), zz )\n\n  reclass( zz, HL )\n}\n\n"
  },
  {
    "path": "R/adjRatios.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Split and dividend adjustment ratios\n#'\n#' Create split and dividend adjustment ratio vectors.\n#'\n#' @aliases adjRatios adjust\n#' @param splits Split series that is coercible to xts.\n#' @param dividends Dividend series that is coercible to xts.\n#' @param close Close price series that is coercible to xts.\n#' @return A xts object containing the columns:\n#'  \\describe{\n#'    \\item{ Split }{ The split adjustment ratio. }\n#'    \\item{ Div }{ The dividend adjustment ratio. }\n#'  }\n#' @details\n#'  \\itemize{\n#'    \\item If only \\code{splits} is provided, the resulting object will\n#'      only have as many observations as \\code{splits}.\n#'    \\item If \\code{splits} and \\code{close} are provided, the resulting\n#'      object will have as many observations as \\code{max(NROW(splits),\n#'      NROW(close))}.\n#'    \\item \\code{close} is required if \\code{dividends} is provided.\n#'  }\n#'\n#' @author Joshua Ulrich\n#' @keywords ts\n'adjRatios' <-\nfunction(splits, dividends, close) {\n\n  if( !missing(dividends) &&\n       missing(close) )\n    stop('\"close\" must be specified to adjust dividends')\n\n  # Really need a better error message if as.xts fails... seriously\n  if(missing(close) || all(is.na(close)) || NROW(close)==0) {\n    close <- NA\n  } else {\n    if(NCOL(close)!=1) stop('\"close\" must be univariate')\n    close <- try.xts(close,\n      error=stop('\"as.xts(close)\" failed'))\n  }\n  if(missing(splits) || all(is.na(splits)) || NROW(splits)==0) {\n    splits <- NA\n  } else {\n    if(NCOL(splits)!=1) stop('\"splits\" must be univariate')\n    splits <- try.xts(splits,\n      error=stop('\"as.xts(splits)\" failed'))\n  }\n  if(missing(dividends) || all(is.na(dividends)) || NROW(dividends)==0) {\n    dividends <- NA\n  } else {\n    if(NCOL(dividends)!=1) stop('\"dividends\" must be univariate')\n    dividends <- try.xts(dividends,\n      error=stop('\"as.xts(dividends)\" failed'))\n  }\n\n  obj <- merge.xts(close,splits,dividends)\n  if(!isTRUE(is.na(close))) {\n    obj <- obj[!is.na(obj[,1]),]  # drop rows missing close prices\n  }\n  adj <- .Call(C_adjRatios, obj[,2], obj[,3], obj[,1])\n  adj <- xts(cbind(adj[[1]],adj[[2]]),index(obj))\n  colnames(adj) <- c('Split','Div')\n\n  return(adj)\n\n}\n"
  },
  {
    "path": "R/aroon.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Aroon\n#'\n#' The Aroon indicator attempts to identify starting trends.  The indicator\n#' consists of up and down lines, which measure how long it has been since the\n#' highest high/lowest low has occurred in the last \\code{n} periods.  Developed\n#' by Tushar Chande in 1995.\n#'\n#' Aroon up (down) is the elapsed time, expressed as a percentage, between today\n#' and the highest (lowest) price in the last \\code{n} periods.  If today's\n#' price is a new high (low) Aroon up (down) will be 100. Each subsequent period\n#' without another new high (low) causes Aroon up (down) to decrease by (1 /\n#' \\code{n}) x 100.\n#'\n#' @param HL Object that is coercible to xts or matrix and contains either a\n#' High-Low price series, or a Close price series.\n#' @param n Number of periods to use in the calculation.\n#' @return A object of the same class as \\code{HL} or a matrix (if\n#' \\code{try.xts} fails) containing the columns:\n#'  \\describe{\n#'   \\item{ aroonUp }{ The Aroon up indicator. }\n#'   \\item{ aroonDn }{ The Aroon down indicator. }\n#'   \\item{ oscillator }{ The Aroon oscillator (\\code{aroonUp - aroonDn}). }\n#'  }\n#' @note If High-Low prices are given, the function calculates the max/min using\n#' the high/low prices.  Otherwise the function calculates the max/min of the\n#' single series.\n#'\n#' Up (down) trends are indicated when the aroonUp(Dn) is between 70 and 100.\n#' Strong trends are indicated when when the aroonUp(Dn) is above 70 while the\n#' aroonDn(Up) is below 30.  Also, crossovers may be useful.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{CCI}}, \\code{\\link{ADX}}, \\code{\\link{TDI}},\n#' \\code{\\link{VHF}}, \\code{\\link{GMMA}} for other indicators that measure trend\n#' direction/strength.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://www.fmlabs.com/reference/Aroon.htm}\\cr\n#' \\url{https://www.fmlabs.com/reference/AroonOscillator.htm}\\cr\n#' \\url{https://www.linnsoft.com/techind/aroon-arn}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:aroon}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  ## Get Data and Indicator ##\n#'  data(ttrc)\n#'  trend <- aroon( ttrc[,c(\"High\", \"Low\")], n=20 )\n#'\n\"aroon\" <-\nfunction(HL, n=20) {\n\n  # Aroon up, down, and oscillator.\n\n  HL <- try.xts(HL, error=as.matrix)\n\n  # Calculation if price vector is given\n  if(NCOL(HL)==1) {\n    high <- HL\n    low  <- HL\n  } else\n\n  # Calculation if HL series is given\n  if(NCOL(HL)==2) {\n    high <- HL[,1]\n    low  <- HL[,2]\n  } else\n\n  stop(\"Price series must be either High-Low, or Close\")\n\n  # Calculate Aroon UP and DOWN\n  aroonUp <- .Call(C_aroon_max, high, n)\n  aroonDn <- .Call(C_aroon_max, -low, n)\n\n  oscillator <- aroonUp - aroonDn\n  result <- cbind( aroonUp, aroonDn, oscillator )\n  colnames(result) <- c( \"aroonUp\", \"aroonDn\", \"oscillator\" )\n\n  reclass( result, HL )\n}\n"
  },
  {
    "path": "R/bollingerBands.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Bollinger Bands\n#'\n#' Bollinger Bands are a way to compare a security's volatility and price levels\n#' over a period of time.  Developed by John Bollinger.\n#'\n#' Bollinger Bands consist of three lines:\n#'\n#' The middle band is generally a 20-period SMA of the typical price ([high +\n#' low + close]/3).  The upper and lower bands are \\code{sd} standard deviations\n#' (generally 2) above and below the MA.\n#'\n#' The middle band is usually calculated using the typical price, but if a\n#' univariate series (e.g. Close, Weighted Close, Median Price, etc.) is\n#' provided, it will be used instead.\n#'\n#' @aliases bollingerBands BBands\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices.  If only a univariate series is given, it will be\n#' used.  See details.\n#' @param n Number of periods for moving average.\n#' @param maType A function or a string naming the function to be called.\n#' @param sd The number of standard deviations to use.\n#' @param \\dots Other arguments to be passed to the \\code{maType} function.\n#' @return A object of the same class as \\code{HLC} or a matrix (if\n#' \\code{try.xts} fails) containing the columns:\n#'  \\describe{\n#'   \\item{ dn }{ The lower Bollinger Band. }\n#'   \\item{ mavg }{ The middle Moving Average (see notes). }\n#'   \\item{ up }{ The upper Bollinger Band. }\n#'   \\item{ pctB }{ The \\%B calculation. }\n#'  }\n#' @note Using any moving average other than SMA will result in inconsistencies\n#' between the moving average calculation and the standard deviation\n#' calculation.  Since, by definition, a rolling standard deviation uses a\n#' simple moving average.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\n#' options; and note Warning section.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://www.fmlabs.com/reference/Bollinger.htm}\\cr\n#' \\url{https://www.fmlabs.com/reference/BollingerWidth.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=36}\\cr\n#' \\url{https://www.linnsoft.com/techind/bollinger-bands}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:bollinger_bands}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:bollinger_band_width}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  ## The examples below show the differences between using a\n#'  ## High-Low-Close series, and just a close series when\n#'  ## calculating Bollinger Bands.\n#'  data(ttrc)\n#'  bbands.HLC <- BBands( ttrc[,c(\"High\",\"Low\",\"Close\")] )\n#'  bbands.close <- BBands( ttrc[,\"Close\"] )\n#' @rdname bollingerBands\n\"BBands\" <-\nfunction(HLC, n=20, maType, sd=2, ...) {\n\n  # Bollinger Bands\n\n  HLC <- try.xts(HLC, error=as.matrix)\n\n  if(NCOL(HLC)==3) {\n    if(is.xts(HLC)) {\n      xa <- xcoredata(HLC)\n      HLC <- xts(apply(HLC, 1, mean),index(HLC))\n      xcoredata(HLC) <- xa\n    } else {\n      HLC <- apply(HLC, 1, mean)\n    }\n  } else\n  if(NCOL(HLC)!=1) {\n    stop(\"Price series must be either High-Low-Close, or Close/univariate.\")\n  }\n\n  maArgs <- list(n=n, ...)\n  # Default MA\n  if(missing(maType)) {\n    maType <- 'SMA'\n  }\n\n  mavg  <- do.call( maType, c( list(HLC), maArgs ) )\n\n  # Calculate standard deviation by hand to incorporate various MAs\n  sdev   <- runSD(HLC, n, sample=FALSE)\n\n  up     <- mavg + sd * sdev\n  dn     <- mavg - sd * sdev\n  pctB  <- (HLC - dn) / (up - dn)\n\n  res <- cbind(dn, mavg, up, pctB)\n  colnames(res) <- c(\"dn\", \"mavg\", \"up\", \"pctB\")\n\n  reclass(res, HLC)\n}\n"
  },
  {
    "path": "R/chaikinAD.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Chaikin Accumulation / Distribution\n#'\n#' The Chaikin Accumulation / Distribution (AD) line is a measure of the money\n#' flowing into or out of a security.  It is similar to On Balance Volume (OBV).\n#' Developed by Marc Chaikin.\n#'\n#' The AD line is similar to OBV; the difference is that OBV sums volume\n#' multiplied by +/- 1 if the close is higher/lower than the previous close,\n#' while the AD line multiplies volume by the close location value (CLV).\n#'\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices.\n#' @param volume Vector or matrix of volume observations corresponding to the\n#' \\code{HLC} object.\n#' @return A object of the same class as \\code{HLC} and \\code{volume} or a\n#' vector (if \\code{try.xts} fails) containing the accumulation / distribution\n#' values.\n#' @note The Accumulation/Distribution Line is interpreted by looking for a\n#' divergence in the direction of the indicator relative to price.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{OBV}}, and \\code{\\link{CLV}}.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://www.fmlabs.com/reference/AccumDist.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=27}\\cr\n#' \\url{https://www.linnsoft.com/techind/accumulation-distribution}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:accumulation_distribution_line}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  ad <- chaikinAD(ttrc[,c(\"High\",\"Low\",\"Close\")], ttrc[,\"Volume\"])\n#'\n\"chaikinAD\" <-\nfunction(HLC, volume) {\n\n  # Chaikin Accumulation / Distribution\n\n  HLC <- try.xts(HLC, error=as.matrix)\n  volume <- try.xts(volume, error=as.matrix)\n\n  if(!(is.xts(HLC) && is.xts(volume))) {\n    HLC <- as.matrix(HLC)\n    volume <- as.matrix(volume)\n  }\n\n  ad  <- CLV(HLC) * volume\n\n  ad.na <- naCheck(ad)\n  ad <- cumsum( ad[ad.na$nonNA] )\n  ad <- c( rep( NA, ad.na$NAs ), ad )\n\n  reclass(ad, HLC)\n}\n"
  },
  {
    "path": "R/chaikinVolatility.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Chaikin Volatility\n#'\n#' Chaikin Volatility measures the rate of change of the security's trading\n#' range.  Developed by Marc Chaikin.\n#'\n#' The Chaikin Volatility indicator defines volatility as an increase in the\n#' difference between the high and low.\n#'\n#' @param HL Object that is coercible to xts or matrix and contains High-Low\n#' prices.\n#' @param n Number of periods for moving average.\n#' @param maType A function or a string naming the function to be called.\n#' @param \\dots Other arguments to be passed to the \\code{maType} function.\n#' @return A object of the same class as \\code{HL} or a vector (if\n#' \\code{try.xts} fails) containing the Chaikin Volatility values.\n#' @note A rapid increase in Chaikin Volatility indicates an approaching bottom.\n#' A slow decrease in Chaikin Volatility indicates an approaching top.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\n#' options; and note Warning section.  See \\code{\\link{TR}} for another\n#' volatility measure.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://www.fmlabs.com/reference/ChaikinVolatility.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=120}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  volatility <- chaikinVolatility(ttrc[,c(\"High\",\"Low\")])\n#'\n\"chaikinVolatility\" <-\nfunction(HL, n=10, maType, ...) {\n\n  # Chaikin Volatility\n\n  HL <- try.xts(HL, error=as.matrix)\n\n  maArgs <- list(n=n, ...)\n  # Default MA\n  if(missing(maType)) {\n    maType <- 'EMA'\n  }\n\n  mavg <- do.call( maType, c( list(HL[,1]-HL[,2]), maArgs ) )\n\n  volatility <- ROC( mavg, n, type=\"discrete\" )\n\n  reclass(volatility, HL)\n}\n"
  },
  {
    "path": "R/changes.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Rate of Change / Momentum\n#'\n#' Calculate the (rate of) change of a series over \\code{n} periods.\n#'\n#' The ROC indicator provides the percentage difference of a series over two\n#' observations, while the momentum indicator simply provides the difference.\n#'\n#' @aliases changes ROC momentum\n#' @param x Price, volume, etc. series that is coercible to xts or matrix.\n#' @param n Number of periods to use.\n#' @param type Compounding type; either \\code{\"continuous\"} (the default) or\n#' \\code{\"discrete\"}.\n#' @param na.pad Should periods prior to \\code{n} be appended?  Default is\n#' \\code{TRUE}.\n#' @return A object of the same class as \\code{x} or a vector (if \\code{try.xts}\n#' fails) containing the rate-of-change (or return) values for \\code{ROC} or a\n#' vector containing the differenced price series for \\code{momentum}.\n#' @author Joshua Ulrich\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  roc <- ROC(ttrc[,\"Close\"])\n#'  mom <- momentum(ttrc[,\"Close\"])\n#' @rdname changes\n\"ROC\" <-\nfunction(x, n=1, type=c(\"continuous\",\"discrete\"), na.pad=TRUE) {\n\n  # Rate of Change\n\n  x <- try.xts(x, error=as.matrix)\n  type <- match.arg(type)\n\n  if(is.xts(x)) {\n    if(type==\"discrete\") {\n      roc <- x / lag.xts(x,n,na.pad=na.pad) - 1\n    }\n    # Continuous change\n    if(type==\"continuous\") {\n      roc <- diff(log(x),n,na.pad=na.pad)\n    }\n    # Convert back to original class\n    reclass(roc, x)\n  } else {\n    NAs <- NULL\n    if(na.pad) {\n      NAs <- rep(NA,n)\n    }\n    # Discrete changes\n    if(type==\"discrete\") {\n      roc <- c( NAs, x[(n+1):NROW(x)] / x[1:(NROW(x)-n)] - 1 )\n    }\n    # Continuous changes\n    if(type==\"continuous\") {\n      roc <- c( NAs, diff(log(x),n) )\n    }\n    return(roc)\n  }\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname changes\n\"momentum\" <-\nfunction(x, n=1, na.pad=TRUE) {\n\n  # Momentum\n\n  # http://www.fmlabs.com/reference/Momentum.htm\n  # https://www.metastock.com/Customer/Resources/TAAZ/?p=95\n  # https://www.linnsoft.com/tour/techind/momentum.htm\n\n  x <- try.xts(x, error=as.matrix)\n  if(is.xts(x)) {\n    mom <- diff(x,n,na.pad=na.pad)\n  } else {\n    NAs <- NULL\n    if(na.pad) {\n      NAs <- rep(NA,n)\n    }\n    mom <- c( NAs, diff(x, n) )\n  }\n  reclass(mom,x)\n}\n"
  },
  {
    "path": "R/keltnerChannels.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2020  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Keltner Channels\n#'\n#' Keltner Channels are volatility-based envelopes set above and below a moving\n#' average. This indicator is similar to Bollinger Bands, but Keltner Channels\n#' use the Average True Range (ATR) to set channel distance.\n#'\n#' Keltner Channels are a trend following indicator, and can also be used to\n#' identify overbought and oversold levels when there is no trend.\n#'\n#' Chester Keltner is credited with the original version of Keltner Channels in\n#' his 1960 book. Linda Bradford Raschke introduced the newer version of\n#' Keltner Channels in the 1980s.\n#'\n#' @aliases keltnerChannels\n#'\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices. If only a univariate series is given, it will be used.\n#' See details.\n#' @param n Number of periods for moving average.\n#' @param maType A function or a string naming the function to be called.\n#' @param atr The number of average true range distances to apply.\n#' @param ... Other arguments to be passed to the maType function.\n#'\n#' @section Details : Keltner Channels consist of three lines:\n#' The middle band is generally a 20-period EMA of the typical price\n#' ([high + low + close]/3). The upper and lower bands are multiples of average\n#' true range (usually 2) above and below the MA.\n#'\n#' The middle band is usually calculated using the typical price, but if a\n#' univariate series (e.g. Close, Weighted Close, Median Price, etc.) is\n#' provided, it will be used instead.\n#'\n#' @return A object of the same class as \\code{HLC} or a matrix (if\n#' \\code{try.xts} fails) containing the columns:\n#'  \\describe{\n#'     \\item{SMA}{ Simple moving average. }\n#'     \\item{EMA}{ Exponential moving average. }\n#'  }\n#'\n#' \\item{dn}{ The lower Keltner Channel. }\n#' \\item{mavg}{ The middle moving average. }\n#' \\item{up}{ The upper Keltner Channel. }\n#'\n#' @author Nick Procyk, Joshua Ulrich\n#'\n#' References\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:keltner_channels}\\cr\n#' \\url{https://www.linnsoft.com/techind/keltner-channels-keltu-keltd}\\cr\n#' \\url{https://www.investopedia.com/terms/k/keltnerchannel.asp}\\cr\n#'\n#' @seealso See \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\n#' options; and note Warning section.\n#'\n#' @examples\n#'\n#' data(ttrc)\n#' kc <- keltnerChannels(ttrc[,c(\"High\",\"Low\",\"Close\")])\n#'\n#' @keywords ts\n#' @rdname keltnerChannels\nkeltnerChannels <-\nfunction (HLC, n = 20, maType, atr = 2, ...)\n{\n  atrHLC <- HLC\n  HLC <- try.xts(HLC, error = as.matrix)\n  if (NCOL(HLC) == 3) {\n    if (is.xts(HLC)) {\n      xa <- xcoredata(HLC)\n      HLC <- xts(apply(HLC, 1, mean), index(HLC))\n      xcoredata(HLC) <- xa\n    }\n    else {\n      HLC <- apply(HLC, 1, mean)\n    }\n  }\n  else if (NCOL(HLC) != 1) {\n    stop(\"Price series must be either High-Low-Close, or Close/univariate.\")\n  }\n  maArgs <- list(n = n, ...)\n  if (missing(maType)) {\n    maType <- \"EMA\"\n  }\n  mavg <- do.call(maType, c(list(HLC), maArgs))\n  avgtruerange <- ATR(atrHLC, n = n)\n\n  up <- mavg + atr * avgtruerange[,2]\n  dn <- mavg - atr * avgtruerange[,2]\n\n  res <- cbind(dn, mavg, up)\n  colnames(res) <- c(\"dn\", \"mavg\", \"up\")\n  reclass(res, HLC)\n}\n"
  },
  {
    "path": "R/percentRank.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Percent Rank over a Moving Window\n#'\n#' This function computes a running/rolling percentage rank.\n#'\n#' The computation for a percentage rank can vary depending on the weight given\n#' to values in the window that are equal to the value being ranked. This weight\n#' can be set using the \\code{exact.multiplier} argument which defaults to 0.5.\n#'\n#' \\code{exact.multiplier = 0} scores equal values in the lookback window as\n#' always being greater than the value being ranked. \\code{exact.multiplier = 1}\n#' scores equal values as being below the value being ranked. Any multiplier\n#' between 0 and 1 counts that proportion of the equal values as being below\n#' the value being ranked.\n#'\n#' The value of \\code{exact.multiplier} has the most impact when the window is\n#' relatively small or when the number of discrete values in the window is\n#' small. For non-repeating values, changing \\code{exact.multiplier = 0} to\n#' \\code{exact.multiplier = 1} for a window of size \\code{N} will shift the\n#' resulting percentile rankings by \\code{1/N}. It is equivalent to changing\n#' the question from, \"how many values are < the value\" to \"how many values\n#' are <= the value\".\n#'\n#' @aliases runPercentRank percentRank PercentRank\n#' @param x Object coercible to xts or matrix.\n#' @param n Number of periods to use in the window or, if\n#' \\code{cumulative=TRUE}, the number of observations to use before the first\n#' result is returned. Must be between 1 and \\code{nrow(x)}, inclusive.\n#' @param cumulative Logical, use from-inception calculation?\n#' @param exact.multiplier The weight applied to identical values in the window.\n#' Must be between 0 and 1, inclusive. See details.\n#'\n#' @return A object of percent ranks over a n-period moving window of the same\n#' class as \\code{x} and \\code{y} or a vector (if \\code{try.xts} fails).\n#'\n#' @note This computation is different from the one used in Microsoft Excel's\n#' \\code{PERCENTRANK} formula. Excel's computation is rather strange and gives\n#' inconsistent results as it uses interpolation to rank values that are not\n#' found within the lookback window.\n#'\n#' @author Charlie Friedemann\n#'\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr \\url{https://en.wikipedia.org/wiki/Percentile_rank}\\cr\n#'\n#' @keywords ts\nrunPercentRank <- function(x, n=260, cumulative = FALSE, exact.multiplier = 0.5) {\n  x <- try.xts(x, error = as.matrix)\n\n  if (n < 1 || n > NROW(x))\n    stop(sprintf(\"n = %d is outside valid range: [1, %d]\", n, NROW(x)))\n  if (exact.multiplier < 0 || exact.multiplier > 1)\n    stop(sprintf(\"exact.multiplier = %d is outside valid range: [0, 1]\", exact.multiplier))\n\n  NAs <- sum(is.na(x))\n  if (NAs > 0) {\n    if (any(is.na(x[-(1:NAs)]))) stop(\"Series contains non-leading NAs\")\n  }\n\n  if (!isTRUE(cumulative) && identical(as.integer(n), 1L)) {\n    result <- double(NROW(x))\n    result[] <- exact.multiplier\n  } else {\n    result <- .Call(C_ttr_rollPercentRank, x, n, isTRUE(cumulative),\n                    exact.multiplier)\n  }\n\n  reclass(result, x)\n}\n"
  },
  {
    "path": "R/pivots.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n\"pivots\" <-\nfunction(data, lagts=TRUE) {\n\n  # Author: Brian G. Peterson\n  # http://www.investopedia.com/articles/forex/05/FXpivots.asp\n  # http://www.investopedia.com/articles/technical/04/041404.asp\n\n  # CentralPivot Point (P) = (High + Low + Close) / 3\n  center <- xts(rowSums(HLC(data))/3,order.by=index(data))\n\n  R1 <- (2*center)-Lo(data)  # First Resistance (R1) = (2*P) - Low\n  S1 <- (2*center)-Hi(data)  # First Support (S1) = (2*P) - High\n  R2 <- center + (R1 - S1)   # Second Resistance (R2) = P + (R1-S1)\n  S2 <- center - (R1 - S1)   # Second Support (S2) = P - (R1- S1)\n  ret <- cbind(center,R1,R2,S1,S2)\n  colnames(ret) <- c('center','R1','R2','S1','S2')\n  if(lagts){\n    newrow <- xts(t(rep(NA,5)), order.by=last(index(data))+1)\n    ret <- rbind(ret,newrow)\n    ret <- lag.xts(ret)\n  }\n  return(ret)\n}\n\n"
  },
  {
    "path": "R/priceBands.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Construct (optionally further smoothed and centered ) volatility bands around\n#' prices\n#'\n#' John Bollinger's famous adaptive volatility bands most often use the typical\n#' price of an HLC series, or may be calculated on a univariate price series\n#' (see \\code{\\link{BBands}}).\n#'\n#' This function applies a second moving average denoted by \\code{fastn} to\n#' filter out higher-frequency noise, making the bands somewhat more stable to\n#' temporary fluctuations and spikes.\n#'\n#' If \\code{centered} is \\code{TRUE}, the function also further smoothes and\n#' centers the bands around a centerline adjusted to remove this higher\n#' frequency noise.  If \\code{lavg} is also \\code{TRUE}, the smoothing applied\n#' for the middle band (but not the volatility bands) is doubled to further\n#' smooth the price-response function.\n#'\n#' If you have multiple different price series in \\code{prices}, and want to use\n#' this function, call this functions using \\code{lapply(prices,PBands,...)}.\n#'\n#' @aliases PBands priceBands\n#' @param prices A univariate series of prices.\n#' @param n Number of periods to average over.\n#' @param maType A function or a string naming the function to be called.\n#' @param sd The number of standard deviations to use.\n#' @param \\dots any other pass-thru parameters, usually for function named by\n#'  \\code{maType}.\n#' @param fastn Number of periods to use for smoothing higher-frequency 'noise'.\n#' @param centered Whether to center the bands around a series adjusted for high\n#'  frequency noise, default \\code{FALSE}.\n#' @param lavg Whether to use a longer \\code{(n*2)} smoothing period for\n#'  centering, default \\code{FALSE}.\n#' @return A object of the same class as \\code{prices} or a matrix (if\n#' \\code{try.xts} fails) containing the columns:\n#'  \\describe{\n#'     \\item{ dn }{ The lower price volatility Band. }\n#'     \\item{ center }{ The smoothed centerline (see details). }\n#'     \\item{ up }{ The upper price volatility Band. }\n#'  }\n#' @author Brian G. Peterson\n#' @seealso \\code{\\link{BBands}}\n#' @keywords ts\n#' @examples\n#'\n#'    data(ttrc)\n#'    pbands.close <- PBands( ttrc[,\"Close\"] )\n#'\n#' @rdname priceBands\nPBands <- function(prices, n=20, maType=\"SMA\", sd=2, ..., fastn=2,\n  centered=FALSE, lavg=FALSE ) {\n\n  # Price Bands, implemented by Brian G. Peterson <brian@braverock.com>\n  # inspired by the univariate Bollinger Bands, and Ram Ben-David\n\n  if(!is.vector(prices) && ncol(prices)>1)\n    stop('prices should be a univariate series, maybe use',\n         'lapply(prices,PBands) instead?')\n\n  prices <- try.xts(prices, error=as.matrix)\n\n  # Default MA\n  if(missing(maType)) {\n    maType <- 'SMA'\n  }\n\n  maArgs <- list(n=n, ...)\n  mavg  <- do.call( maType, c( list(prices), maArgs ) )\n\n  maFastArgs <-list(n=fastn,...)\n  fastmavg  <- do.call( maType, c( list(prices), maFastArgs ) )\n\n  sdev <- runSD((mavg-fastmavg),n=n,sample=FALSE)\n\n  if(!isTRUE(centered)){\n    center <- mavg\n  } else {\n    centerrun <- (mavg-fastmavg)/sdev\n    if(isTRUE(lavg)){\n      maArgs <- list(n=(n*2), ...)\n    }\n    center <- mavg + ( do.call(maType, c( list(centerrun), maArgs ) ) )\n  }\n\n  up     <- center + sd * sdev\n  dn     <- center - sd * sdev\n\n  res <- cbind(dn, center, up)\n  colnames(res) <- c(\"dn\", \"center\", \"up\")\n\n  reclass(res, prices)\n}\n"
  },
  {
    "path": "R/rollFun.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Analysis of Running/Rolling/Moving Windows\n#'\n#' Various functions to analyze data over a moving window of periods.\n#'\n#'\n#' @aliases rollFun rollSFM\n#' @param Ra Object coercible to xts or matrix, containing the excess\n#' return for an individual security\n#' @param Rb Object coercible to xts or matrix, containing the market\n#' / benchmark return\n#' @param n Number of periods to use in the window\n#'\n#' @return A object of the same class as \\code{Ra} (and \\code{Rb}?) or a vector\n#' (if \\code{try.xts} fails).\n#'  \\describe{\n#'   \\item{rollSFM}{returns single-factor model parameters and R-squared\n#'     over a n-period moving window.}\n#'  }\n#'\n#' @author Joshua Ulrich\n#' @references The following site(s) were used to code/document this\n#' indicator:\n#' \\url{https://en.wikipedia.org/wiki/Simple_linear_regression}\\cr\n#' @keywords ts\n#' @rdname rollFun\n\nrollSFM <- function(Ra, Rb, n = 60) {\n  # Calculate a rolling single-factor model\n#  stopifnot(is.xts(Ra) && is.xts(Rb))\n  # calculate beta\n  beta <- runCov(Ra, Rb, n) / runVar(Rb, n=n)\n  # calculate alpha\n  alpha <- runMean(Ra, n) - beta * runMean(Rb, n)\n  # calculate R-squared\n  se.resid <-\n    1/(n*(n-2)) * (n*runSum(Ra^2,n)-runSum(Ra,n)^2\n       - beta^2 * (n*runSum(Rb^2,n)-runSum(Rb,n)^2))\n  se.Ra <- runVar(Ra, n=n) * (n-1)/(n-2)\n  r.squared <- 1 - se.resid / se.Ra\n  result <- merge(alpha, beta, r.squared)\n  return(result)\n}\n"
  },
  {
    "path": "R/runFun.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Analysis of Running/Rolling/Moving Windows\n#'\n#' Various functions to analyze data over a moving window of periods.\n#'\n#'\n#' @aliases runFun runSum runMin runMax runMean runMedian runCov runCor runVar\n#' runSD runMAD wilderSum\n#' @param x Object coercible to xts or matrix.\n#' @param y Object coercible to xts or matrix.\n#' @param n Number of periods to use in the window or, if\n#' \\code{cumulative=TRUE}, the number of observations to use before the first\n#' result is returned. Must be between 1 and \\code{nrow(x)}, inclusive.\n#' @param cumulative Logical, use from-inception calculation?\n#' @param sample Logical, sample covariance if \\code{TRUE} (denominator of\n#' \\code{n-1})\n#' @param use Only \\code{\"all.obs\"} currently implemented.\n#' @param non.unique One of 'mean', 'max', or 'min'; which compute their\n#' respective statistics for the two middle values of even-sized samples.\n#' @param center The values to use as the measure of central tendency, around\n#' which to calculate deviations. The default (\\code{NULL}) uses the median.\n#' @param stat Statistic to calculate, one of 'median' or 'mean' (e.g. median\n#' absolute deviation or mean absolute deviation, respectively.)\n#' @param constant Scale factor applied to approximate the standard deviation.\n#' @return A object of the same class as \\code{x} and \\code{y} or a vector (if\n#' \\code{try.xts} fails).\n#'  \\describe{\n#'   \\item{runSum}{returns sums over a n-period moving window.}\n#'   \\item{runMin}{returns minimums over a n-period moving window.}\n#'   \\item{runMax}{returns maximums over a n-period moving window.}\n#'   \\item{runMean}{returns means over a n-period moving window.}\n#'   \\item{runMedian}{returns medians over a n-period moving window.}\n#'   \\item{runCov}{returns covariances over a n-period moving window.}\n#'   \\item{runCor}{returns correlations over a n-period moving window.}\n#'   \\item{runVar}{returns variances over a n-period moving window.}\n#'   \\item{runSD}{returns standard deviations over a n-period moving window.}\n#'   \\item{runMAD}{returns median/mean absolute deviations over a n-period moving window.}\n#'   \\item{wilderSum}{retuns a Welles Wilder style weighted sum over a n-period moving window.}\n#'  }\n#'\n#' @author Joshua Ulrich\n#' @keywords ts\n#' @rdname runFun\n\"runSum\" <-\nfunction(x, n=10, cumulative=FALSE) {\n\n  x <- try.xts(x, error=as.matrix)\n\n  if( n < 1 || n > NROW(x) )\n    stop(sprintf(\"n = %d is outside valid range: [1, %d]\", n, NROW(x)))\n\n  if(NCOL(x) > 1) {\n    stop(\"ncol(x) > 1. runSum only supports univariate 'x'\")\n  }\n\n  if(cumulative) {\n    # Count NAs, ensure they're only at beginning of data.\n    NAs <- sum(is.na(x))\n    if( NAs > 0 ) {\n      if( any( is.na(x[-(1:NAs)]) ) ) stop(\"Series contains non-leading NAs\")\n      if( NAs + n > NROW(x) ) stop(\"not enough non-NA values\")\n    }\n    beg <- 1 + NAs\n\n    # Initialize result vector\n    result <- double(NROW(x))\n\n    result[beg:NROW(x)] <- cumsum(x[beg:NROW(x)])\n\n    # Replace 1:(n-1) with NAs\n    is.na(result) <- seq_len(n-1+NAs)\n  } else {\n    # Call C routine\n    result <- .Call(C_runsum, x, n)\n  }\n\n  # Convert back to original class\n  reclass(result, x)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname runFun\n\"runMin\" <-\nfunction(x, n=10, cumulative=FALSE) {\n\n  x <- try.xts(x, error=as.matrix)\n  if(NCOL(x) > 1) {\n    stop(\"ncol(x) > 1. runMin only supports univariate 'x'\")\n  }\n  result <- runRange(x, n=n, cumulative=cumulative)[, 1]\n  reclass(result, x)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname runFun\n\"runMax\" <-\nfunction(x, n=10, cumulative=FALSE) {\n\n  x <- try.xts(x, error=as.matrix)\n  if(NCOL(x) > 1) {\n    stop(\"ncol(x) > 1. runMax only supports univariate 'x'\")\n  }\n  result <- runRange(x, n=n, cumulative=cumulative)[, 2]\n  reclass(result, x)\n}\n\n#' @rdname runFun\n\"runRange\" <-\nfunction(x, n=10, cumulative=FALSE) {\n\n  x <- try.xts(x, error=as.matrix)\n\n  if( n < 1 || n > NROW(x) )\n    stop(sprintf(\"n = %d is outside valid range: [1, %d]\", n, NROW(x)))\n\n  if(NCOL(x) > 1) {\n    stop(\"ncol(x) > 1. runRange only supports univariate 'x'\")\n  }\n\n  if(cumulative) {\n    # Count NAs, ensure they're only at beginning of data, then remove.\n    NAs <- sum( is.na(x) )\n    if( NAs > 0 ) {\n      if( any( is.na(x[-(1:NAs)]) ) ) stop(\"Series contains non-leading NAs\")\n      if( NAs + n > NROW(x) ) stop(\"not enough non-NA values\")\n    }\n    beg <- 1 + NAs\n\n    # Initialize result matrix\n    result <- matrix(NA_real_, nrow = NROW(x), ncol = 2)\n    sub <- beg:NROW(x)\n    result[sub,] <- cbind(cummin(x[sub]), cummax(x[sub]))\n    # Replace 1:(n-1) with NAs and prepend NAs from original data\n    is.na(result[seq_len(n-1+NAs), ]) <- TRUE\n  } else {\n    # Call C routine\n    result <- .Call(C_runrange, x, n)\n  }\n\n  # Convert back to original class\n  r <- reclass(result, x)\n  colnames(r) <- c(\"min\", \"max\")\n  return(r)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname runFun\n\"runMean\" <-\nfunction(x, n=10, cumulative=FALSE) {\n\n  if(cumulative) {\n    x.na <- sum(is.na(x))\n    denom <- c(rep(NA_real_, x.na), seq_len(NROW(x)-x.na))\n    result <- runSum(x, n, cumulative) / denom\n  } else {\n    result <- runSum(x, n) / n\n  }\n\n  return(result)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname runFun\n\"runMedian\" <-\nfunction(x, n=10, non.unique=\"mean\", cumulative=FALSE) {\n\n  x <- try.xts(x, error=as.matrix)\n\n  if( n < 1 || n > NROW(x) )\n    stop(sprintf(\"n = %d is outside valid range: [1, %d]\", n, NROW(x)))\n\n  if(NCOL(x) > 1) {\n    stop(\"ncol(x) > 1. runMedian only supports univariate 'x'\")\n  }\n\n  # Non-unique median\n  non.unique <- match.arg(non.unique, c('mean','max','min'))\n  non.unique <- switch(non.unique, mean=0L, max=1L, min=-1L)\n\n  # Call C routine\n  result <- .Call(C_runmedian, x, n, non.unique, cumulative)\n\n  # Convert back to original class\n  reclass(result, x)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname runFun\n\"runCov\" <-\nfunction(x, y, n=10, use=\"all.obs\", sample=TRUE, cumulative=FALSE) {\n\n  x <- try.xts(x, error=as.matrix)\n  y <- try.xts(y, error=as.matrix)\n  if(is.xts(x) && is.xts(y)) {\n    xy <- cbind(x,y)\n  } else {\n    xy <- cbind( as.vector(x), as.vector(y) )\n  }\n\n  if( n < 1 || n > NROW(x) )\n    stop(sprintf(\"n = %d is outside valid range: [1, %d]\", n, NROW(x)))\n\n  if(NCOL(x) > 1 || NCOL(y) > 1) {\n    stop(\"ncol(x) > 1 or ncol(y) > 1.\",\n         \" runCov only supports univariate 'x' and 'y'\")\n  }\n\n  # \"all.obs\", \"complete.obs\", \"pairwise.complete.obs\"\n\n  # Call C routine\n  result <- .Call(C_runcov, xy[,1], xy[,2], n, sample, cumulative)\n\n  # Convert back to original class\n  # Should the attributes of *both* x and y be retained?\n  reclass(result, x)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname runFun\n\"runCor\" <-\nfunction(x, y, n=10, use=\"all.obs\", sample=TRUE, cumulative=FALSE) {\n\n  result <- runCov(x, y, n, use=use, sample=sample, cumulative) /\n            ( runSD(x, n, sample=sample, cumulative) *\n              runSD(y, n, sample=sample, cumulative) )\n\n  return( result )\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname runFun\n\"runVar\" <-\nfunction(x, y=NULL, n=10, sample=TRUE, cumulative=FALSE) {\n\n  if(is.null(y)) y <- x\n  result <- runCov(x, y, n, use=\"all.obs\", sample=sample, cumulative)\n\n  return( result )\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname runFun\n\"runSD\" <-\nfunction(x, n=10, sample=TRUE, cumulative=FALSE) {\n\n  result <- sqrt( runCov(x, x, n, use=\"all.obs\",\n                  sample=sample, cumulative) )\n\n  return( result )\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname runFun\n\"runMAD\" <-\nfunction(x, n=10, center=NULL, stat=\"median\",\n         constant=1.4826, non.unique=\"mean\", cumulative=FALSE) {\n\n  x <- try.xts(x, error=as.matrix)\n\n  if( n < 1 || n > NROW(x) )\n    stop(sprintf(\"n = %d is outside valid range: [1, %d]\", n, NROW(x)))\n\n  if(NCOL(x) > 1) {\n    stop(\"ncol(x) > 1. runMAD only supports univariate 'x'\")\n  }\n\n  if(is.null(center)) {\n    center <- runMedian(x, n, cumulative=cumulative)\n  }\n\n  # Mean or Median absolute deviation?\n  median <- match.arg(stat, c(\"mean\",\"median\"))\n  median <- switch( stat, median=TRUE, mean=FALSE )\n\n  # Non-unique median\n  non.unique <- match.arg(non.unique, c('mean','max','min'))\n  non.unique <- switch( non.unique, mean=0, max=1, min=-1 )\n\n  # Call C routine\n  result <- .Call(C_runmad, x, center, n, median, non.unique, cumulative)\n\n  if( median ) result <- result * constant\n\n  # Convert back to original class\n  reclass(result, x)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname runFun\n\"wilderSum\" <-\nfunction(x, n=10) {\n\n  x <- try.xts(x, error=as.matrix)\n\n  if( n < 1 || n > NROW(x) )\n    stop(sprintf(\"n = %d is outside valid range: [1, %d]\", n, NROW(x)))\n\n  if(NCOL(x) > 1) {\n    stop(\"ncol(x) > 1. wilderSum only supports univariate 'x'\")\n  }\n\n  # Check for non-leading NAs\n  # Leading NAs are handled in the C code\n  naCheck(x, n)  # called for error handling side-effect\n\n  # Call C routine\n  result <- .Call(C_wilderSum, x, n)\n\n  # Convert back to original class\n  reclass(result, x)\n}\n"
  },
  {
    "path": "R/stochastics.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Stochastic Oscillator / Stochastic Momentum Index\n#'\n#' The stochastic oscillator is a momentum indicator that relates the location\n#' of each day's close relative to the high/low range over the past \\code{n}\n#' periods.  Developed by George C.  Lane in the late 1950s.  The SMI relates\n#' the close to the midpoint of the high/low range.  Developed by William Blau\n#' in 1993.\n#'\n#' If a High-Low-Close series is provided, the indicator is calculated using the\n#' high/low values.  If a vector is provided, the calculation only uses that\n#' series.  This allows stochastics to be calculated for: (1) series that have\n#' no HLC definition (e.g. foreign exchange), and (2) stochastic indicators\n#' (e.g. stochastic RSI - see examples).\n#'\n#' The \\code{smooth} argument is the number of periods of internal smoothing to\n#' apply to the differences in the high-low-close range before calculating Fast\n#' K.  Thanks to Stanley Neo for the suggestion.\n#'\n#' @aliases stochastics stochastic stoch SMI %K %D\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices.  If only a univariate series is given, it will be\n#' used.  See details.\n#' @param n Number of periods to use.\n#' @param nFastK Number of periods for fast \\%K (i.e. the number of past periods\n#' to use).\n#' @param nFastD Number of periods for fast \\%D (i.e. the number smoothing\n#' periods to apply to fast \\%K).\n#' @param nSlowD Number of periods for slow \\%D (i.e. the number smoothing\n#' periods to apply to fast \\%D).\n#' @param smooth Number of internal smoothing periods to be applied before\n#' calculating FastK. See Details.\n#' @param nFast Number of periods for initial smoothing.\n#' @param nSlow Number of periods for double smoothing.\n#' @param nSig Number of periods for signal line.\n#' @param maType Either:\n#'  \\enumerate{\n#'    \\item A function or a string naming the function to be called.\n#'    \\item A \\emph{list} with the first component like (1) above, and\n#'      additional parameters specified as \\emph{named} components.\n#'      See Examples.\n#'  }\n#' @param bounded Logical, should current period's values be used in the\n#' calculation?\n#' @param \\dots Other arguments to be passed to the \\code{maType} function in\n#' case (1) above.\n#' @return A object of the same class as \\code{HLC} or a matrix (if\n#' \\code{try.xts} fails) containing the columns:\n#'  \\describe{\n#'     \\item{ fastK }{ Stochastic Fast \\%K }\n#'     \\item{ fastD }{ Stochastic Fast \\%D }\n#'     \\item{ slowD }{ Stochastic Slow \\%D }\n#'     \\item{ SMI }{ Stochastic Momentum Index }\n#'     \\item{ signal }{ Stochastic Momentum Index signal line }\n#'  }\n#' @note The calculation for William's \\%R is similar to that of stochastics'\n#' fast \\%K.\n#'\n#' The value for fast \\%K will be 0.5 whenever the highest high and\n#' lowest low are the same over the last \\code{n} periods.\n#'\n#' The stochastic oscillator and SMI calculate relative value of the close\n#' versus the high/low range and the midpoint of the high/low range,\n#' respectively.\n#'\n#' The stochastic oscillator and the stochastic momentum index are interpreted\n#' similarly.  Readings below 20 (above 80) are considered oversold\n#' (overbought).  However, readings below 20 (above 80) are not necessarily\n#' bearish (bullish).  Lane believed some of the best sell (buy) signals\n#' occurred when the oscillator moved from overbought (oversold) back below 80\n#' (above 20).\n#'\n#' For the stochastic oscillator, buy (sell) signals can also be given when \\%K\n#' crosses above (below) \\%D.  Crossover signals are quite frequent however,\n#' which may result in whipsaws.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\n#' options; and note Warning section.  See \\code{\\link{WPR}} to compare it's\n#' results to fast \\%K.\n#' @references The following site(s) were used to code/document these\n#' indicators:\n#' \\cr Stochastic Oscillator:\\cr\n#' \\url{https://www.fmlabs.com/reference/StochasticOscillator.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=106}\\cr\n#' \\url{https://www.linnsoft.com/techind/stochastics}\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:stochastic_oscillator_fast_slow_and_full}\\cr\n#' \\cr SMI:\\cr\n#' \\url{https://www.fmlabs.com/reference/default.htm?url=SMI.htm}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  stochOSC <- stoch(ttrc[,c(\"High\",\"Low\",\"Close\")])\n#'  stochWPR <- WPR(ttrc[,c(\"High\",\"Low\",\"Close\")])\n#'\n#'  plot(tail(stochOSC[,\"fastK\"], 100), type=\"l\",\n#'      main=\"Fast %K and Williams %R\", ylab=\"\",\n#'      ylim=range(cbind(stochOSC, stochWPR), na.rm=TRUE) )\n#'  lines(tail(stochWPR, 100), col=\"blue\")\n#'  lines(tail(1-stochWPR, 100), col=\"red\", lty=\"dashed\")\n#'\n#'  stoch2MA <- stoch( ttrc[,c(\"High\",\"Low\",\"Close\")],\n#'      maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA)) )\n#'\n#'  SMI3MA <- SMI(ttrc[,c(\"High\",\"Low\",\"Close\")],\n#'      maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA)) )\n#'\n#'  stochRSI <- stoch( RSI(ttrc[,\"Close\"]) )\n#' @rdname stochastics\n\"stoch\" <-\nfunction(HLC, nFastK=14, nFastD=3, nSlowD=3, maType, bounded=TRUE, smooth=1, ...) {\n\n  # Stochastics\n\n  HLC <- try.xts(HLC, error=as.matrix)\n\n  # Calculation if HLC series is given\n  if(NCOL(HLC)==3) {\n    high  <- HLC[,1]\n    low   <- HLC[,2]\n    close <- HLC[,3]\n  } else\n\n  # Calculation if price vector is given\n  if(NCOL(HLC)==1) {\n    high  <- HLC\n    low   <- HLC\n    close <- HLC\n  } else\n\n  stop(\"Price series must be either High-Low-Close, or Close\")\n\n  if(bounded) {\n    hmax <- runMax(high, nFastK)\n    lmin <- runMin( low, nFastK)\n  } else {\n    hmax <- runMax(c(high[1],high[-NROW(HLC)]), nFastK)\n    lmin <- runMin(c( low[1], low[-NROW(HLC)]), nFastK)\n  }\n\n  num <- close - lmin\n  den <- hmax - lmin\n\n  if(missing(maType)) {\n    maType <- 'SMA'\n  }\n\n  # Case of two different 'maType's for both MAs.\n  # e.g. stoch(price, 14, 3, 3,\n  #           maType=list(maUp=list(EMA,ratio=1/5), maDown=list(WMA,wts=1:10)) )\n  if( is.list(maType) ) {\n\n    # Make sure maType is a list of lists\n    maTypeInfo <- sapply(maType,is.list)\n    if( !(all(maTypeInfo) && length(maTypeInfo) == 3) ) {\n      stop(\"If \\'maType\\' is a list, you must specify\\n \",\n      \"*three* MAs (see Examples section of ?stochastics)\")\n    }\n\n    # If MA function has 'n' arg, see if it's populated in maType;\n    # if it isn't, populate it with function's formal 'n'\n    if( !is.null( formals(maType[[1]][[1]])$n ) && is.null( maType[[1]]$n ) ) {\n      maType[[1]]$n <- nFastD\n    }\n    if( !is.null( formals(maType[[2]][[1]])$n ) && is.null( maType[[2]]$n ) ) {\n      maType[[2]]$n <- nSlowD\n    }\n    if( !is.null( formals(maType[[3]][[1]])$n ) && is.null( maType[[3]]$n ) ) {\n      maType[[3]]$n <- smooth\n    }\n\n    numMA <- do.call( maType[[3]][[1]], c( list(num), maType[[3]][-1] ) )\n    denMA <- do.call( maType[[3]][[1]], c( list(den), maType[[3]][-1] ) )\n\n    fastK <- numMA / denMA\n    fastK[!is.finite(fastK) & !is.na(fastK)] <- 0.5\n    fastD <- do.call( maType[[1]][[1]], c( list(fastK), maType[[1]][-1] ) )\n    slowD <- do.call( maType[[2]][[1]], c( list(fastD), maType[[2]][-1] ) )\n  }\n\n  # Case of one 'maType' for both MAs.\n  # e.g. stoch(price, 14, 3, 3, maType=\"WMA\", wts=volume )\n  else {\n\n    numMA <- do.call( maType, c( list(num), list(n=smooth) ) )\n    denMA <- do.call( maType, c( list(den), list(n=smooth) ) )\n\n    fastK <- numMA / denMA\n    fastK[!is.finite(fastK) & !is.na(fastK)] <- 0.5\n    fastD <- do.call( maType, c( list(fastK), list(n=nFastD, ...) ) )\n    slowD <- do.call( maType, c( list(fastD), list(n=nSlowD, ...) ) )\n\n  }\n\n  result <- cbind( fastK, fastD, slowD )\n  colnames(result) <- c( \"fastK\", \"fastD\", \"slowD\" )\n\n  reclass(result, HLC)\n}\n\n#-------------------------------------------------------------------------#\n\n#' @rdname stochastics\n\"SMI\" <-\nfunction(HLC, n=13, nFast=2, nSlow=25, nSig=9, maType, bounded=TRUE, ...) {\n\n  # Stochastic Momentum Index\n  # Not Validated\n\n  # http://www.fmlabs.com/reference/default.htm?url=SMI.htm\n  # The median in the SMI formula on the above site is incorrect.\n\n  # Calculation if HLC series is given\n  if(ncol(HLC)==3) {\n    high  <- HLC[,1]\n    low   <- HLC[,2]\n    close <- HLC[,3]\n  } else\n\n  # Calculation if price vector is given\n  if(ncol(HLC)==1) {\n    high  <- HLC\n    low   <- HLC\n    close <- HLC\n  } else\n\n  stop(\"Price series must be either High-Low-Close, or Close\")\n\n  if(bounded) {\n    hmax <- runMax(high, n)\n    lmin <- runMin( low, n)\n  } else {\n    hmax <- runMax(c(high[1],high[-NROW(HLC)]), n)\n    lmin <- runMax(c( low[1], low[-NROW(HLC)]), n)\n  }\n  hmax <- ifelse( is.na(hmax), high, hmax )\n  lmin <- ifelse( is.na(lmin),  low, lmin )\n\n  HLdiff <- hmax - lmin\n  Cdiff  <- close - ( hmax + lmin ) / 2\n\n  if(missing(maType)) {\n    maType <- 'EMA'\n  }\n\n  # Case of two different 'maType's for both MAs.\n  # e.g. SMI(price, 13, 2, 25, 9,\n  #           maType=list(maUp=list(EMA,ratio=1/5), maDown=list(WMA,wts=1:10)) )\n  if( is.list(maType) ) {\n\n    # Make sure maType is a list of lists\n    maTypeInfo <- sapply(maType,is.list)\n    if( !(all(maTypeInfo) && length(maTypeInfo) == 3) ) {\n      stop(\"If \\'maType\\' is a list, you must specify\\n \",\n      \"*three* MAs (see Examples section of ?SMI)\")\n    }\n\n    # If MA function has 'n' arg, see if it's populated in maType;\n    # if it isn't, populate it with function's formal 'n'\n    if( !is.null( formals(maType[[1]][[1]])$n ) && is.null( maType[[1]]$n ) ) {\n      maType[[1]]$n <- nFast\n    }\n    if( !is.null( formals(maType[[2]][[1]])$n ) && is.null( maType[[2]]$n ) ) {\n      maType[[2]]$n <- nSlow\n    }\n    if( !is.null( formals(maType[[3]][[1]])$n ) && is.null( maType[[3]]$n ) ) {\n      maType[[3]]$n <- nSig\n    }\n\n    num1 <- do.call( maType[[1]][[1]], c( list(Cdiff ), maType[[1]][-1] ) )\n    den1 <- do.call( maType[[1]][[1]], c( list(HLdiff), maType[[1]][-1] ) )\n    num2 <- do.call( maType[[2]][[1]], c( list( num1 ), maType[[2]][-1] ) )\n    den2 <- do.call( maType[[2]][[1]], c( list( den1 ), maType[[2]][-1] ) )\n\n    SMI <- 100 * ( num2 / ( den2 / 2 ) )\n    signal <- do.call( maType[[3]][[1]], c( list(SMI), maType[[3]][-1] ) )\n\n  }\n\n  # Case of one 'maType' for both MAs.\n  # e.g. SMI(price, 13, 2, 25, 9, maType=\"WMA\", wts=volume )\n  else {\n\n    num1 <- do.call( maType, c( list(Cdiff ), list(n=nSlow, ... ) ) )\n    den1 <- do.call( maType, c( list(HLdiff), list(n=nSlow, ... ) ) )\n    num2 <- do.call( maType, c( list( num1 ), list(n=nFast, ... ) ) )\n    den2 <- do.call( maType, c( list( den1 ), list(n=nFast, ... ) ) )\n\n    SMI <- 100 * ( num2 / ( den2 / 2 ) )\n    signal <- do.call( maType, c( list(SMI), list(n=nSig, ... ) ) )\n\n  }\n\n  result <- cbind( SMI, signal )\n  colnames(result) <- c( \"SMI\", \"signal\" )\n\n  reclass( result, HLC )\n}\n"
  },
  {
    "path": "R/ultimateOscillator.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' The Ultimate Oscillator\n#'\n#' The Ultimate Oscillator is a momentum oscillator designed to capture momentum across three\n#' different time frames.\n#'\n#' Created by Larry Williams in 1976.\n#'\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices.\n#' @param n A vector of the number of periods to use for each average calculation.\n#' @param wts The weights applied to each average.\n#' @author Ivan Popivanov\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://school.stockcharts.com/doku.php?id=technical_indicators:ultimate_oscillator}\\cr\n#' @keywords ts\n#' @examples\n#'\n#' data(ttrc)\n#' ult.osc <- ultimateOscillator(ttrc[,c(\"High\",\"Low\",\"Close\")])\n#'\nultimateOscillator <-\nfunction(HLC, n=c(7,14,28), wts=c(4,2,1)) {\n\n  # Ultimate Oscillator\n\n  if(length(n) != 3 || length(wts) != 3)\n    stop(\"length(n) and length(wts) must both be 3\")\n\n  HLC <- try.xts(HLC, error=as.matrix)\n\n  # avoid reclassing in ATR and runSum\n  HLC.RECLASS <- attr(HLC, \".RECLASS\")\n  attr(HLC, \".RECLASS\") <- FALSE\n\n  # only need 'tr' and 'trueLow'\n  atr <- ATR(HLC, n=1)\n\n  buyPressure <- HLC[,3] - atr[,'trueLow']\n\n  osc <- buyPressure * 0.0\n  for(i in 1:3) {\n    osc <- osc + wts[i] * (runSum(buyPressure, n[i]) / runSum(atr[,'tr'], n[i]))\n  }\n  osc <- 100.0 * osc / sum(wts)\n\n  # restore HLC .RECLASS attribute\n  attr(HLC, \".RECLASS\") <- HLC.RECLASS\n\n  reclass(osc, HLC)\n}\n"
  },
  {
    "path": "R/volatility.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Volatility\n#'\n#' Selected volatility estimators/indicators; various authors.\n#'\n#' \\itemize{\n#' \\item Close-to-Close Volatility (\\code{calc=\"close\"})\\cr\n#' \\deqn{ \\sigma_{cl} = \\sqrt{\\frac{N}{n-2} \\sum_{i=1}^{n-1}(r_i-\\bar{r})^2}\n#' }{sqrt(N) * runSD(ROC(Cl), n-1)}\n#' \\deqn{where\\;\\; r_i = \\log \\left(\\frac{C_i}{C_{i-1}}\\right) }\n#' \\deqn{and\\;\\; \\bar{r} = \\frac{r_1+r_2+\\ldots +r_{n-1}}{n-1} }\n#'\n#' \\item OHLC Volatility: Garman and Klass (\\code{calc=\"garman.klass\"})\\cr The\n#' Garman and Klass estimator for estimating historical volatility assumes\n#' Brownian motion with zero drift and no opening jumps (i.e. the opening =\n#' close of the previous period). This estimator is 7.4 times more efficient\n#' than the close-to-close estimator.\\cr\n#' \\deqn{ \\sigma = \\sqrt{ \\frac{N}{n} \\sum\n#'   \\left[ \\textstyle\\frac{1}{2}\\displaystyle\n#'     \\left( \\log \\frac{H_i}{L_i} \\right)^2  - (2\\log 2-1)\n#'     \\left( \\log \\frac{C_i}{O_i} \\right)^2 \\right] }\n#' }{sqrt(N/n * runSum(0.5 * log(Hi/Lo)^2 -\n#'            (2*log(2)-1) * log(Cl/Op)^2, n))}\n#'\n#' \\item High-Low Volatility: Parkinson (\\code{calc=\"parkinson\"})\\cr\n#' The Parkinson formula for estimating the historical volatility of\n#' an underlying based on high and low prices.\\cr\n#' \\deqn{ \\sigma = \\sqrt{ \\frac{N}{4 n \\times \\log 2} \\sum_{i=1}^{n}\n#'   \\left(\\log \\frac{H_i}{L_i}\\right)^2}\n#' }{sqrt(N/(4*n*log(2)) * runSum(log(Hi/Lo)^2, n))}\n#'\n#' \\item OHLC Volatility: Rogers and Satchell (\\code{calc=\"rogers.satchell\"})\\cr\n#' The Roger and Satchell historical volatility estimator allows for non-zero\n#' drift, but assumed no opening jump.\\cr\n#' \\deqn{ \\sigma = \\sqrt{ \\textstyle\\frac{N}{n} \\sum \\left[\n#'   \\log \\textstyle\\frac{H_i}{C_i} \\times \\log \\textstyle\\frac{H_i}{O_i} +\n#'   \\log \\textstyle\\frac{L_i}{C_i} \\times \\log \\textstyle\\frac{L_i}{O_i} \\right] }\n#' }{sqrt(N/n * runSum(log(Hi/Cl) * log(Hi/Op) +\n#'                     log(Lo/Cl) * log(Lo/Op), n))}\n#'\n#' \\item OHLC Volatility: Garman and Klass - Yang and Zhang\n#' (\\code{calc=\"gk.yz\"})\\cr This estimator is a modified version of the Garman\n#' and Klass estimator that allows for opening gaps.\\cr\n#' \\deqn{ \\sigma = \\sqrt{ \\textstyle\\frac{N}{n} \\sum \\left[\n#'   \\left( \\log \\textstyle\\frac{O_i}{C_{i-1}} \\right)^2  +\n#'     \\textstyle\\frac{1}{2}\\displaystyle\n#'   \\left( \\log \\textstyle\\frac{H_i}{L_i} \\right)^2 - (2 \\times \\log 2-1)\n#'   \\left( \\log \\textstyle\\frac{C_i}{O_i} \\right)^2 \\right] }\n#' }{sqrt(N/n * runSum(log(Op/lag(Cl,1))^2 +\n#'   0.5 * log(Hi/Lo)^2 - (2*log(2)-1) * log(Cl/Op)^2 , n))}\n#'\n#' \\item OHLC Volatility: Yang and Zhang (\\code{calc=\"yang.zhang\"})\\cr The Yang\n#' and Zhang historical volatility estimator has minimum estimation error, and\n#' is independent of drift and opening gaps.  It can be interpreted as a\n#' weighted average of the Rogers and Satchell estimator, the close-open\n#' volatility, and the open-close volatility.\n#'\n#' Users may override the default values of \\eqn{\\alpha} (1.34 by default) or\n#' \\eqn{k} used in the calculation by specifying \\code{alpha} or \\code{k} in\n#' \\code{\\dots}, respectively. Specifying \\code{k} will cause \\code{alpha} to be\n#' ignored, if both are provided.\\cr\n#' \\deqn{ \\sigma^2 = \\sigma_o^2 + k\\sigma_c^2 + (1-k)\\sigma_{rs}^2\n#' }{ s <- sqrt(s2o + k*s2c + (1-k)*(s2rs^2)) }\n#' \\deqn{ \\sigma_o^2 =\\textstyle \\frac{N}{n-1} \\sum\n#'   \\left( \\log \\frac{O_i}{C_{i-1}}-\\mu_o \\right)^2\n#' }{ s2o <- N * runVar(log(Op/lag(Cl,1)), n=n) }\n#' \\deqn{ \\mu_o=\\textstyle \\frac{1}{n} \\sum \\log \\frac{O_i}{C_{i-1}} }\n#' \\deqn{ \\sigma_c^2 =\\textstyle \\frac{N}{n-1} \\sum\n#'   \\left( \\log \\frac{C_i}{O_i}-\\mu_c \\right)^2\n#' }{ s2c <- N * runVar(log(Cl/Op), n=n) }\n#' \\deqn{ \\mu_c=\\textstyle \\frac{1}{n} \\sum \\log \\frac{C_i}{O_i} }\n#' \\deqn{ \\sigma_{rs}^2 = \\textstyle\\frac{N}{n} \\sum \\left(\n#'   \\log \\textstyle\\frac{H_i}{C_i} \\times \\log \\textstyle\\frac{H_i}{O_i} +\n#'   \\log \\textstyle\\frac{L_i}{C_i} \\times \\log \\textstyle\\frac{L_i}{O_i}\n#'   \\right)\n#' }{ s2rs <- volatility(OHLC, n, \"rogers.satchell\", N, ...) }\n#' \\deqn{ k=\\frac{\\alpha-1}{alpha+\\frac{n+1}{n-1}}\n#' }{ k <- (alpha-1) / (alpha + (n+1)/(n-1)) }\n#' }\n#'\n#' @aliases volatility garman.klass parkinson rogers.satchell gk.yz yang.zhang\n#' @param OHLC Object that is coercible to xts or matrix and contains\n#' Open-High-Low-Close prices (or only Close prices, if \\code{calc=\"close\"}).\n#' @param n Number of periods for the volatility estimate.\n#' @param calc The calculation (type) of estimator to use.\n#' @param N Number of periods per year.\n#' @param mean0 Use a mean of 0 rather than the sample mean.\n#' @param \\dots Arguments to be passed to/from other methods.\n#' @return A object of the same class as \\code{OHLC} or a vector (if\n#' \\code{try.xts} fails) containing the chosen volatility estimator values.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{TR}} and \\code{\\link{chaikinVolatility}} for other\n#' volatility measures.\n#' @references The following sites were used to code/document these\n#' indicators. All were created by Thijs van den Berg under the GNU Free\n#' Documentation License and were retrieved on 2008-04-20. The original\n#' links are dead, but can be accessed via internet archives.\\cr\n#' \\cr Close-to-Close Volatility (\\code{calc=\"close\"}):\\cr\n#' \\url{https://web.archive.org/web/20100421083157/http://www.sitmo.com/eq/172}\\cr\n#' \\cr OHLC Volatility: Garman Klass (\\code{calc=\"garman.klass\"}):\\cr\n#' \\url{https://web.archive.org/web/20100326172550/http://www.sitmo.com/eq/402}\\cr\n#' \\cr High-Low Volatility: Parkinson (\\code{calc=\"parkinson\"}):\\cr\n#' \\url{https://web.archive.org/web/20100328195855/http://www.sitmo.com/eq/173}\\cr\n#' \\cr OHLC Volatility: Rogers Satchell (\\code{calc=\"rogers.satchell\"}):\\cr\n#' \\url{https://web.archive.org/web/20091002233833/http://www.sitmo.com/eq/414}\\cr\n#' \\cr OHLC Volatility: Garman Klass - Yang Zhang (\\code{calc=\"gk.yz\"}):\\cr\n#' \\url{https://web.archive.org/web/20100326215050/http://www.sitmo.com/eq/409}\\cr\n#' \\cr OHLC Volatility: Yang Zhang (\\code{calc=\"yang.zhang\"}):\\cr\n#' \\url{https://web.archive.org/web/20100326215050/http://www.sitmo.com/eq/409}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  ohlc <- ttrc[,c(\"Open\",\"High\",\"Low\",\"Close\")]\n#'  vClose <- volatility(ohlc, calc=\"close\")\n#'  vClose0 <- volatility(ohlc, calc=\"close\", mean0=TRUE)\n#'  vGK <- volatility(ohlc, calc=\"garman\")\n#'  vParkinson <- volatility(ohlc, calc=\"parkinson\")\n#'  vRS <- volatility(ohlc, calc=\"rogers\")\n#'\n\"volatility\" <-\nfunction(OHLC, n=10, calc=\"close\", N=260, mean0=FALSE, ...) {\n\n  OHLC <- try.xts(OHLC, error=as.matrix)\n\n  # Choose an arg name that doesn't clash with ROC's 'type' arg\n  calc <- match.arg(calc,\n            c(\"close\",\"garman.klass\",\"parkinson\",\n              \"rogers.satchell\",\"gk.yz\",\"yang.zhang\"))\n\n  # s       Volatility\n  # N       Number of closing prices in a year\n  # n       Number of historical prices used for the volatility estimate\n  # ci      The closing price on the ith day\n  # ri      Log return on the ith day\n\n  # Historical Close-to-Close Volatility\n  # http://www.sitmo.com/eq/172\n  if( calc==\"close\" ) {\n    # Add univariate case from Cedrick Johnson's R-SIG-Finance post\n    if( NCOL(OHLC) == 1 ) {\n      r <- ROC(OHLC[, 1], 1, ...)\n    } else {\n      r <- ROC(OHLC[, 4], 1, ...)\n    }\n    if( isTRUE(mean0) ) {\n      # This is an alternative SD calculation using an effective mean of 0\n      s <- sqrt(N) * sqrt(runSum(r^2, n-1) / (n-2))\n    } else {\n      # This is the standard SD calculation using the sample mean\n      s <- sqrt(N) * runSD(r, n-1)\n    }\n  }\n\n  # Historical Open-High-Low-Close Volatility: Garman Klass\n  # http://www.sitmo.com/eq/402\n  if( calc==\"garman.klass\" ) {\n    s <- sqrt( N/n * runSum( .5 * log(OHLC[,2]/OHLC[,3])^2 -\n               (2*log(2)-1) * log(OHLC[,4]/OHLC[,1])^2 , n ) )\n  }\n\n  if( calc==\"parkinson\" ) {\n    # Historical High-Low Volatility: Parkinson\n    # http://www.sitmo.com/eq/173\n    s <- sqrt( N/(4*n*log(2)) * runSum( log(OHLC[,2]/OHLC[,3])^2, n ) )\n  }\n\n  if( calc==\"rogers.satchell\" ) {\n    # Historical Open-High-Low-Close Volatility: Rogers Satchell\n    # http://www.sitmo.com/eq/414\n    s <- sqrt( N/n * runSum(\n               log(OHLC[,2]/OHLC[,4]) * log(OHLC[,2]/OHLC[,1]) +\n               log(OHLC[,3]/OHLC[,4]) * log(OHLC[,3]/OHLC[,1]), n ) )\n  }\n\n  if( calc==\"gk.yz\" ) {\n  #if( calc==\"garman.klass.yang.zhang\" ) {\n    # Historical Open-High-Low-Close Volatility: Garman and Klass (Yang Zhang)\n    # http://www.sitmo.com/eq/409\n    if(is.xts(OHLC)) {\n      Cl1 <- lag.xts(OHLC[,4])\n    } else {\n      Cl1 <- c( NA, OHLC[-NROW(OHLC),4] )\n    }\n    s <- sqrt( N/n * runSum(\n               log(OHLC[,1]/Cl1)^2 +\n               .5 * log(OHLC[,2]/OHLC[,3])^2 -\n               (2*log(2)-1) * log(OHLC[,4]/OHLC[,1])^2 , n) )\n\n    #s <- sqrt( Z/n * runSum(\n    #          log(op/cl[-1])^2 +\n    #          .5*log(hi/lo)^2 -\n    #          (2*log(2)-1)*log(cl/op)^2 ) )\n  }\n\n  if( calc==\"yang.zhang\" ) {\n    # Historical Open-High-Low-Close Volatility: Yang Zhang\n    # http://www.sitmo.com/eq/417\n    if(is.xts(OHLC)) {\n      Cl1 <- lag.xts(OHLC[,4])\n    } else {\n      Cl1 <- c( NA, OHLC[-NROW(OHLC),4] )\n    }\n\n    dots <- list(...)\n    if(is.null(dots$alpha)) {\n      alpha <- 1.34\n    }\n    if(is.null(dots$k)) {\n      k <- (alpha-1) / ( alpha + (n+1)/(n-1) )\n    }\n\n    s2o <- N * runVar(log(OHLC[,1] / Cl1), n=n)\n    s2c <- N * runVar(log(OHLC[,4] / OHLC[,1]), n=n)\n    s2rs <- volatility(OHLC=OHLC, n=n, calc=\"rogers.satchell\", N=N, ...)\n    s <- sqrt(s2o + k*s2c + (1-k)*(s2rs^2))\n  }\n\n  reclass(s,OHLC)\n}\n"
  },
  {
    "path": "R/williamsAD.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2007-2013  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n\n#' Williams Accumulation / Distribution\n#'\n#' The Williams Accumulation / Distribution (AD) line is a measure of market\n#' momentum.  Developed by Larry Williams.\n#'\n#' The Williams AD line differs from OBV and chaikinAD in that it doesn't take\n#' volume into account.\n#'\n#' @param HLC Object that is coercible to xts or matrix and contains\n#' High-Low-Close prices.\n#' @return A object of the same class as \\code{HLC} or a vector (if\n#' \\code{try.xts} fails) containing the accumulation / distribution values.\n#' @note The Accumulation/Distribution Line is interpreted by looking for a\n#' divergence in the direction of the indicator relative to price.\n#' @author Joshua Ulrich\n#' @seealso See \\code{\\link{OBV}}, \\code{\\link{chaikinAD}}, and\n#' \\code{\\link{ATR}}.\n#' @references The following site(s) were used to code/document this\n#' indicator:\\cr\n#' \\url{https://www.fmlabs.com/reference/WilliamsAD.htm}\\cr\n#' \\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=125}\\cr\n#' @keywords ts\n#' @examples\n#'\n#'  data(ttrc)\n#'  ad <- williamsAD(ttrc[,c(\"High\",\"Low\",\"Close\")])\n#'\n\"williamsAD\" <-\nfunction(HLC) {\n\n  # Williams Accumulation/Distribution\n\n  HLC <- try.xts(HLC, error=as.matrix)\n\n  # Calculate change in close, and true high/low\n  dCl <- momentum(HLC[,3], 1)\n  atr <- ATR(HLC)\n\n  # Calculate AD\n  ad <- HLC[,3] - ifelse( dCl > 0, atr[,\"trueLow\"], atr[,\"trueHigh\"] )\n  ad[ dCl == 0 ] <- 0\n\n  ad.na <- naCheck(ad)\n  ad <- cumsum( ad[ad.na$nonNA] )\n  ad <- c( rep( NA, ad.na$NAs ), ad )\n\n  reclass(ad, HLC)\n}\n"
  },
  {
    "path": "R/zzz.R",
    "content": "#\n#   TTR: Technical Trading Rules\n#\n#   Copyright (C) 2017  Joshua M. Ulrich\n#\n#   This program is free software: you can redistribute it and/or modify\n#   it under the terms of the GNU General Public License as published by\n#   the Free Software Foundation, either version 2 of the License, or\n#   (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful,\n#   but WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n#   GNU General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program.  If not, see <http://www.gnu.org/licenses/>.\n#\n.env <- new.env()\n\n.onUnload <- function(libpath) {\n  library.dynam.unload(\"TTR\", libpath)\n}\n"
  },
  {
    "path": "README.md",
    "content": "### About\n\nTTR is an [R](https://www.r-project.org) package that provides the most popular\ntechnical analysis functions for financial market data. Many of these functions\nare used as components of systematic trading strategies and financial charts.\n\n### Supporting TTR development\n\nIf you are interested in supporting the ongoing development and maintenance of TTR, please consider [becoming a sponsor](https://github.com/sponsors/joshuaulrich).\n\n### Installation\n\nThe current release is available on [CRAN](https://CRAN.R-project.org/package=TTR),\nwhich you can install via:\n\n```r\ninstall.packages(\"TTR\")\n```\n\nTo install the development version, you need to clone the repository and build\nfrom source, or run one of:\n\n```r\n# lightweight\nremotes::install_github(\"joshuaulrich/TTR\")\n# or\ndevtools::install_github(\"joshuaulrich/TTR\")\n```\n\nYou will need tools to compile C/C++ code. See the relevant\nappendix in the [R Installation and Administration manual](https://cran.r-project.org/doc/manuals/r-release/R-admin.html)\nfor your operating system:\n\n- [Windows](https://cran.r-project.org/doc/manuals/r-release/R-admin.html#The-Windows-toolset)\n- [MacOS](https://cran.r-project.org/doc/manuals/r-release/R-admin.html#macOS) (the [R for Mac OS X Developer's Page](https://mac.R-project.org/) might also be helpful)\n- [Unix-alike](https://cran.r-project.org/doc/manuals/r-release/R-admin.html#Essential-and-useful-other-programs-under-a-Unix_002dalike)\n\n### Getting Started\n\nHere are a few examples of some of the more well-known indicators:\n\n```r\n# \"TTR Composite\" (simulated data)\ndata(ttrc)\nhlc <- ttrc[, c(\"High\", \"Low\", \"Close\")]\n\n# Bollinger Bands\nbbands <- BBands(hlc)\n\n# Directional Movement Index\nadx <- ADX(hlc)\n\n# Moving Averages\nema <- EMA(ttrc[, \"Close\"], n = 20)\nsma <- SMA(ttrc[, \"Close\"], n = 20)\n\n# MACD\nmacd <- MACD(ttrc[,\"Close\"])\n\n# RSI\nrsi <- RSI(ttrc[,\"Close\"])\n\n# Stochastics\nstochOsc <- stoch(hlc)\n```\n\nTTR works with the `chartSeries()` function in [quantmod](https://github.com/joshuaulrich/quantmod). Here's an example that uses `chartSeries()` and adds TTR-calculated indicators and overlays to the chart.\n\n```r\nlibrary(quantmod)\ndata(ttrc)\n\n# create an xts object\nx <- as.xts(ttrc)\n\nchartSeries(x, subset = \"2006-09/\", theme = \"white\")\naddBBands()\naddRSI()\n```\n\n![](https://drive.google.com/uc?export=view&id=1TrgoZujgcI9GCMEWHlDgzkQQvBItyLwq)\n\n### Have a question?\n\nAsk your question on [Stack Overflow](https://stackoverflow.com/questions/tagged/r)\nor the [R-SIG-Finance](https://stat.ethz.ch/mailman/listinfo/r-sig-finance)\nmailing list (you must subscribe to post).\n\n### Contributing\n\nPlease see the [Contributing Guide](https://github.com/joshuaulrich/TTR/wiki/Contributing-Guide).\n\n### See Also\n\n- [quantmod](https://CRAN.R-project.org/package=quantmod): quantitative financial modeling framework\n- [xts](https://CRAN.R-project.org/package=xts): eXtensible Time Series based\non [zoo](https://CRAN.R-project.org/package=zoo)\n\n### Author\n\n[Joshua Ulrich](https://about.me/joshuaulrich)\n\n"
  },
  {
    "path": "THANKS",
    "content": "In no particular order:\n\n- I can't thank Jeff Ryan enough for all his help with TTR via:\n  motivation to submit TTR to CRAN, helpful comments, testing, and\n  providing an example Fortran implementation of 'EMA' (from which\n  all other included Fortran functions are based).\n\n- Many thanks to Ion Georgiadis for helpful suggestions and testing.\n"
  },
  {
    "path": "inst/tinytest/test-dvi.R",
    "content": "# Create input data\ndata(ttrc)\nrownames(ttrc) <- ttrc$Date\nttrc$Date <- NULL\n\n# Run test\ndat <- setNames(ttrc$Close, rownames(ttrc))\ndvi <- DVI(dat)\n\nexpect_equal(colnames(dvi), c(\"dvi.mag\", \"dvi.str\", \"dvi\"))\n"
  },
  {
    "path": "inst/tinytest/test-misc.R",
    "content": "# Create input data\ndata(ttrc)\nrownames(ttrc) <- ttrc$Date\nttrc$Date <- NULL\n\ninput <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] )\ninput$top[1:10,] <- NA\ninput$mid[9:20,] <- NA\n\n#iAll <- as.matrix(ttrc[1:250,])\niAll <- ttrc[1:250,]\niTop <- iAll; iTop[1:10,] <- NA\niMid <- iAll; iMid[9:20,] <- NA\n\nhl  <- c('High','Low')\nhlc <- c('High','Low','Close')\ncl  <- 'Close'\n\n# Load output data\nload(system.file(\"tinytest/output/misc.rda\", package=\"TTR\"))\n\n#################################################\n\n# Rate-of-Change\nroc <- ROC(iAll[,cl], type='continuous')\nexpect_equal( roc, output$allROCc )\nexpect_equal( attributes(roc), attributes(output$allROCc) )\n#expect_equal( ROC(input$top$Close, type='continuous'), output$topROCc )\n#expect_error( ROC(input$mid$Close) )\n\nroc <- ROC(input$all$Close, type='discrete')\nexpect_equal( roc, output$allROCd )\nexpect_equal( attributes(roc), attributes(output$allROCd) )\n#expect_equal( ROC(input$top$Close, type='discrete'), output$topROCd )\n\n# Momentum\nmom <- momentum(input$all$Close)\nexpect_equal( mom, output$allMom )\nexpect_equal( attributes(mom), attributes(output$allMom) )\n#expect_equal( momentum(input$top$Close), output$topMom )\n#expect_error( momentum(input$mid$Close) )\n\n# Close Location Value\nia <- iAll[,hlc];  rownames(ia) <- NULL\nit <- iTop[,hlc];  rownames(it) <- NULL\noa <- as.data.frame(output$allCLV); rownames(oa) <- rownames(ia)\not <- as.data.frame(output$topCLV); rownames(ot) <- rownames(it)\nexpect_equal( CLV(ia), output$allCLV )\nexpect_equal( attributes(CLV(ia)), attributes(output$allCLV) )\nexpect_equal( CLV(it), output$topCLV )\nexpect_equal( attributes(CLV(it)), attributes(output$topCLV) )\n\n# Arms' Ease of Movement\nia <- iAll[,hl];  rownames(ia) <- NULL\nemv.all <- EMV(ia, input$all$Volume)\nexpect_equal( emv.all, output$allEMV )\nexpect_equal( attributes(emv.all), attributes(output$allEMV) )\n#emv.top<- EMV(input$top[,c('High','Low')], input$top$Volume)\n#expect_equal( emv.top, output$topEMV )\n#expect_equal( attributes(emv.top), attributes(output$topEMV) )\n#expect_error( EMV(input$mid[,c('High','Low')], input$mid$Volume) )\n#expect_error( EMV(input$all[,c('High','Low')], input$mid$Volume) )\n#expect_error( EMV(input$mid[,c('High','Low')], input$all$Volume) )\n\n# Know Sure Thing\nexpect_equal( KST(input$all$Close), output$allKST )\nexpect_equal( attributes(KST(input$all$Close)), attributes(output$allKST) )\n#expect_equal( KST(input$top$Close), output$topKST )\n#expect_error( KST(input$mid$Close) )\n\n# CTI\nexpect_equal(length(input$all$Close), length(CTI(input$all$Close)))\n"
  },
  {
    "path": "inst/tinytest/test-moving-averages.R",
    "content": "# Create input data\ndata(ttrc)\nrownames(ttrc) <- ttrc$Date\nttrc$Date <- NULL\n\ninput <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] )\ninput$top[1:10,] <- NA\ninput$mid[9:20,] <- NA\n\n# Load output data\nload(system.file(\"tinytest/output/moving-averages.rda\", package=\"TTR\"))\n\n#################################################\n\n# ALMA\nv <- 1:10\nx <- xts::.xts(v, seq_along(v))\nav <- ALMA(v)\nax <- ALMA(x)\nexpect_equal(NROW(av), NROW(ax))\n\n# Simple Moving Average\nexpect_equal( SMA(input$all$Close), output$allSMA )\nexpect_equal( attributes(SMA(input$all$Close)), attributes(output$allSMA) )\nexpect_equal( SMA(input$top$Close), output$topSMA )\nexpect_equal( attributes(SMA(input$top$Close)), attributes(output$topSMA) )\nexpect_error( SMA(input$mid$Close) )\nexpect_error( SMA(input$all[,1:2]) )\n\n# Exponential Moving Average\nexpect_equal( EMA(input$all$Close), output$allEMA )\nexpect_equal( attributes(EMA(input$all$Close)), attributes(output$allEMA) )\nexpect_equal( EMA(input$top$Close), output$topEMA )\nexpect_equal( attributes(EMA(input$top$Close)), attributes(output$topEMA) )\nexpect_error( EMA(input$mid$Close) )\nexpect_error( EMA(input$all[,1:2]) )\nexpect_error( EMA(input$all$Close, n = -1) )\nexpect_error( EMA(input$all$Close, n = NROW(input$all) + 1) )\n\nout <- 0:9 * 1.0\nis.na(out) <- 1:2\nexpect_equal(EMA(1:10, ratio = 0.5), out)\nexpect_equal(EMA(1:10, n = 3), out)\nexpect_warning(ema_n_ratio <- EMA(1:10, n = 3, ratio = 0.5), info = \"'n' and 'ratio' specified\")\nexpect_equal(ema_n_ratio, out)\nexpect_error(EMA(1:10, ratio = 0.0), info = \"ratio = 0\")\n\n# Exponential Moving Average, Wilder ratio\nexpect_equal( EMA(input$all$Close, wilder=TRUE), output$allEMAwilder )\nexpect_equal( attributes(EMA(input$all$Close, wilder=TRUE)), attributes(output$allEMAwilder) )\nexpect_equal( EMA(input$top$Close, wilder=TRUE), output$topEMAwilder )\nexpect_equal( attributes(EMA(input$top$Close, wilder=TRUE)), attributes(output$topEMAwilder) )\nexpect_error( EMA(input$mid$Close, wilder=TRUE) )\n\n# Double-Exponential Moving Average\nexpect_equal( DEMA(input$all$Close), output$allDEMA )\nexpect_equal( attributes(DEMA(input$all$Close)), attributes(output$allDEMA) )\nexpect_equal( DEMA(input$top$Close), output$topDEMA )\nexpect_equal( attributes(DEMA(input$top$Close)), attributes(output$topDEMA) )\nexpect_error( DEMA(input$mid$Close) )\nexpect_error( DEMA(input$all[,1:2]) )\n\n# Hull Moving Average\nhma <- HMA(1:10, 2)\nexpect_equal(hma, c(NA, 2:10 + 1/3))\n\nhma <- HMA(1:10, 3)\nexpect_equal(hma, c(rep(NA, 2), 3:10 + 2/3))\n\n# Weighted Moving Average, 1:n\nexpect_equal( WMA(input$all$Close), output$allWMA )\nexpect_equal( attributes(WMA(input$all$Close)), attributes(output$allWMA) )\nexpect_equal( WMA(input$top$Close), output$topWMA )\nexpect_equal( attributes(WMA(input$top$Close)), attributes(output$topWMA) )\nexpect_error( WMA(input$mid$Close) )\nexpect_error( WMA(input$all$Close, wts=1) )\nexpect_error( WMA(input$all[,1:2]) )\nexpect_error( WMA(input$all$Close, n = -1) )\nexpect_error( WMA(input$all$Close, n = NROW(input$all) + 1) )\n\n# Weighted Moving Average, Volume\nexpect_equal( WMA(input$all$Close, wts=input$all$Volume), output$allWMAvol )\nexpect_equal( attributes(WMA(input$all$Close, wts=input$all$Volume)), attributes(output$allWMAvol) )\nexpect_equal( WMA(input$top$Close, wts=input$top$Volume), output$topWMAvol )\nexpect_equal( attributes(WMA(input$top$Close, wts=input$top$Volume)), attributes(output$topWMAvol) )\nexpect_error( WMA(input$all$Close, wts=input$mid$Volume) )\nexpect_error( WMA(input$all[,1:2], wts=input$all$Volume) )\nexpect_error( WMA(input$all$Close, wts=input$all[,1:2]) )\n\nx <- xts::.xts(x = c(NA, 1:3), 1:4)\nwma <- WMA(x, 2)\nexpect_true(inherits(wma, \"xts\"))\n\n# Exponential, Volume-Weighted Moving Average\nexpect_equal( EVWMA(input$all$Close, input$all$Volume), output$allEVWMA )\nexpect_equal( attributes(EVWMA(input$all$Close, input$all$Volume)), attributes(output$allEVWMA) )\nexpect_equal( EVWMA(input$top$Close, input$top$Volume), output$topEVWMA )\nexpect_equal( attributes(EVWMA(input$top$Close, input$top$Volume)), attributes(output$topEVWMA) )\nexpect_error( EVWMA(input$mid$Close, input$mid$Volume) )\nexpect_error( EVWMA(input$all$Close) )\nexpect_error( EVWMA(input$all[,1:2], input$all$Volume) )\nexpect_error( EVWMA(input$all$Close, input$all[,1:2]) )\nexpect_error( EVWMA(input$all$Close, n = -1) )\nexpect_error( EVWMA(input$all$Close, n = NROW(input$all) + 1) )\n\n# Zero-Lag Exponential Moving Average\nexpect_equal( ZLEMA(input$all$Close), output$allZLEMA )\nexpect_equal( attributes(ZLEMA(input$all$Close)), attributes(output$allZLEMA) )\nexpect_equal( ZLEMA(input$top$Close), output$topZLEMA )\nexpect_equal( attributes(ZLEMA(input$top$Close)), attributes(output$topZLEMA) )\nexpect_error( ZLEMA(input$mid$Close) )\nexpect_error( ZLEMA(input$all[,1:2]) )\n\nout <- c(rep(NA, 6), 4.0, 6.0, 7.75, 9.3125)\nexpect_equal(ZLEMA(1:10, ratio = 0.25), out)\nexpect_equal(ZLEMA(1:10, n = 7), out)\nexpect_warning(zlema_n_ratio <- ZLEMA(1:10, n = 7, ratio = 0.25), info = \"'n' and 'ratio' specified\")\nexpect_equal(zlema_n_ratio, out)\nexpect_error(ZLEMA(1:10, ratio = 0.0), info = \"ratio = 0\")\n\nx <- c(NA, rnorm(10))\nexpect_silent(EMA(x, 10), info = \"non-na equals 'n' does not error\")\nexpect_silent(ZLEMA(x, 10), info = \"non-na equals 'n' does not error\")\n\n# column names\nx <- xts::as.xts(ttrc)\np <- x[, \"Close\"]\nv <- x[, \"Volume\"]\nexpect_equal(\"SMA\",   colnames(SMA(p)))\nexpect_equal(\"EMA\",   colnames(EMA(p)))\nexpect_equal(\"DEMA\",  colnames(DEMA(p)))\nexpect_equal(\"WMA\",   colnames(WMA(p)))\nexpect_equal(\"EVWMA\", colnames(EVWMA(p, v)))\nexpect_equal(\"ZLEMA\", colnames(ZLEMA(p)))\nexpect_equal(\"VWAP\",  colnames(VWAP(p, v)))\nexpect_equal(\"HMA\",   colnames(HMA(p)))\nexpect_equal(\"ALMA\",  colnames(ALMA(p)))\n"
  },
  {
    "path": "inst/tinytest/test-oscillators.R",
    "content": "# Create input data\ndata(ttrc)\nrownames(ttrc) <- ttrc$Date\nttrc$Date <- NULL\n\ninput <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] )\ninput$top[1:10,] <- NA\ninput$mid[9:20,] <- NA\n\n# Load output data\nload(system.file(\"tinytest/output/oscillators.rda\", package=\"TTR\"))\n\n#################################################\n\n# MACD\nexpect_equal( MACD(input$all$Close), output$allMACD )\nexpect_equal( attributes(MACD(input$all$Close)), attributes(output$allMACD) )\nexpect_equal( MACD(input$top$Close), output$topMACD )\nexpect_equal( attributes(MACD(input$top$Close)), attributes(output$topMACD) )\nexpect_error( MACD(input$mid$Close) )\n\n# Stochastics\n# This mess is because data.frames' attributes don't come through reclass() well\nia <- as.matrix(input$all[,c('High','Low','Close')])\nit <- as.matrix(input$top[,c('High','Low','Close')])\n#rn <- rownames(ia)\n#rownames(ia) <- rownames(it) <- NULL\noa <- stoch(ia); #rownames(oa) <- rn\not <- stoch(it); #rownames(ot) <- rn\n# End: mess\nexpect_equal( oa, output$allStoch )\nexpect_equal( attributes(oa), attributes(output$allStoch) )\nexpect_equal( ot, output$topStoch )\nexpect_equal( attributes(ot), attributes(output$topStoch) )\nexpect_error( stoch(input$mid[,c('High','Low','Close')]) )\n\na <- c(53.99, 54.69, rep(55.55, 3), rep(52.5, 13), rep(51.77, 2))\nidx <- structure(1446422400 + cumsum(c(0, rep(86400, 4), 259200,\n   rep(86400, 4), 259200, rep(86400,4), 259200, rep(86400, 2), 172800,\n   259200)), tzone = \"UTC\", tclass = \"Date\")\nX <- structure(c(a, a, a+0.1), .Dim = c(20L, 3L), class = c(\"xts\", \"zoo\"),\n      index = idx, .Dimnames = list(NULL, c(\"High\", \"Low\", \"Close\")))\n\no <- structure(c(rep(NA, 9), rep(0.0327868852459021, 5), rep(0.5, 4),\n    rep(0.136986301369856, 2), rep(NA, 11), rep(0.0327868852459021, 3),\n    0.188524590163935, 0.344262295081967, 0.5, 0.5, 0.378995433789952,\n    0.257990867579904, rep(NA, 13), 0.0327868852459021, 0.084699453551913,\n    0.188524590163935, 0.344262295081967, 0.448087431693989,\n    0.459665144596651, 0.378995433789952), .Dim = c(20L, 3L),\n    .Dimnames = list(NULL, c(\"fastK\", \"fastD\", \"slowD\")), index = idx,\n    class = c(\"xts\", \"zoo\"))\n\ns <- TTR::stoch(X, 10, 3)\nexpect_equal(s, o, info = \"handle Inf fastK\")\n# TODO: delete line above after xts is released w/fix for #322\n#expect_equal(s, o\n\n\n# Stochastic Momentum Index\nexpect_equal( SMI(input$all[,c('High','Low','Close')]), output$allSMI )\nexpect_equal( attributes(SMI(input$all[,c('High','Low','Close')])), attributes(output$allSMI) )\nexpect_equal( SMI(input$top[,c('High','Low','Close')]), output$topSMI )\nexpect_equal( attributes(SMI(input$top[,c('High','Low','Close')])), attributes(output$topSMI) )\nexpect_error( SMI(input$mid[,c('High','Low','Close')]) )\n\n# Relative Strength Index\nexpect_equal( RSI(input$all$Close), output$allRSI )\nexpect_equal( attributes(RSI(input$all$Close)), attributes(output$allRSI) )\nexpect_equal( RSI(input$top$Close), output$topRSI )\nexpect_equal( attributes(RSI(input$top$Close)), attributes(output$topRSI) )\nexpect_error( RSI(input$mid$Close) )\n\nwilder.and.matype <- RSI(input$all$Close, maType = \"EMA\", wilder = FALSE)\nwilder.only <- RSI(input$all$Close, wilder = FALSE)\nexpect_equal( wilder.and.matype, wilder.only, info = \"RSI does not overwrite maArgs\")\n\n# Chande Momentum Oscillator\nexpect_equal( CMO(input$all$Close), output$allCMO )\nexpect_equal( attributes(CMO(input$all$Close)), attributes(output$allCMO) )\nexpect_equal( CMO(input$top$Close), output$topCMO )\nexpect_equal( attributes(CMO(input$top$Close)), attributes(output$topCMO) )\nexpect_error( CMO(input$mid$Close) )\n\n# De-trended Price Oscillator\nexpect_equal( DPO(input$all$Close), output$allDPO )\nexpect_equal( attributes(DPO(input$all$Close)), attributes(output$allDPO) )\nexpect_equal( DPO(input$top$Close), output$topDPO )\nexpect_equal( attributes(DPO(input$top$Close)), attributes(output$topDPO) )\nexpect_error( DPO(input$mid$Close) )\n\n# TRIX\nexpect_equal( TRIX(input$all$Close), output$allTRIX )\nexpect_equal( attributes(TRIX(input$all$Close)), attributes(output$allTRIX) )\nexpect_equal( TRIX(input$top$Close), output$topTRIX )\nexpect_equal( attributes(TRIX(input$top$Close)), attributes(output$topTRIX) )\nexpect_error( TRIX(input$mid$Close) )\n\n# Willams' Percent R\n# This mess is because data.frames' attributes don't come through reclass() well\nia <- input$all[,c('High','Low','Close')]\nit <- input$top[,c('High','Low','Close')]\nrn <- rownames(ia)\nrownames(ia) <- rownames(it) <- NULL\noa <- WPR(ia); names(oa) <- rn\not <- WPR(it); names(ot) <- rn\n# End: mess\nexpect_equal( oa, output$allWPR )\nexpect_equal( attributes(oa), attributes(output$allWPR) )\nexpect_equal( ot, output$topWPR )\nexpect_equal( attributes(ot), attributes(output$topWPR) )\nexpect_error( WPR(input$mid$Close) )\n\n# Ultimate Oscillator\n# This mess is because data.frames' attributes don't come through reclass() well\nia <- input$all[,c('High','Low','Close')]\nit <- input$top[,c('High','Low','Close')]\nrn <- rownames(ia)\nrownames(ia) <- rownames(it) <- NULL\noa <- ultimateOscillator(ia); names(oa) <- rn\not <- ultimateOscillator(it); names(ot) <- rn\n# End: mess\nexpect_equal( oa, output$allUltOsc )\nexpect_equal( attributes(oa), attributes(output$allUltOsc) )\nexpect_equal( ot, output$topUltOsc )\nexpect_equal( attributes(ot), attributes(output$topUltOsc) )\nexpect_error( ultimateOscillator(input$mid$Close) )\n\n# Ultimate Oscillator on non-xts monthly data\niam <- xts::to.monthly(input$all, name=NULL)[,c('High','Low','Close')]\nrn <- rownames(iam)\nrownames(iam) <- NULL\noam <- ultimateOscillator(iam, c(2,5,8))\n# Ultimate Oscillator on xts monthly data\nxia <- xts::as.xts(input$all)\nxiam <- xts::to.monthly(xia, name=NULL)[,c('High','Low','Close')]\nxoam <- ultimateOscillator(xiam, c(2,5,8))\nexpect_equal( oam, as.numeric(xoam) )\n"
  },
  {
    "path": "inst/tinytest/test-overlays.R",
    "content": "# Create input data\ndata(ttrc)\nrownames(ttrc) <- ttrc$Date\nttrc$Date <- NULL\n\ninput <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] )\ninput$top[1:10,] <- NA\ninput$mid[9:20,] <- NA\n\n# Load output data\nload(system.file(\"tinytest/output/overlays.rda\", package=\"TTR\"))\n\n#################################################\n\n# Bollinger Bands\nia <- input$all[,c('High','Low','Close')]\nit <- input$top[,c('High','Low','Close')]\nim <- input$mid[,c('High','Low')]\nrownames(ia) <- rownames(it) <- NULL\noa <- BBands(ia)\not <- BBands(it)\nrownames(oa) <- rownames(ot) <- rownames(input$all)\nexpect_equal( oa, output$allBBands )\nexpect_equal( attributes(oa), attributes(output$allBBands) )\nexpect_equal( ot, output$topBBands )\nexpect_equal( attributes(ot), attributes(output$topBBands) )\nexpect_error( BBands(im) )\n\n# SAR\nia <- input$all[,c('High','Low')]\nit <- input$top[,c('High','Low')]\nim <- input$mid[,c('High','Low')]\nrownames(ia) <- rownames(it) <- rownames(im) <- NULL\nexpect_equal( SAR(ia), output$allSAR )\nexpect_equal( attributes(SAR(ia)), attributes(output$allSAR) )\nexpect_equal( SAR(it), output$topSAR )\nexpect_equal( attributes(SAR(it)), attributes(output$topSAR) )\nexpect_error( SAR(im) )\n\n# Zig Zag\nia <- input$all[,c('High','Low')]\nit <- input$top[,c('High','Low')]\nim <- input$mid[,c('High','Low')]\nrownames(ia) <- rownames(it) <- rownames(im) <- NULL\nexpect_equal( ZigZag(ia), output$allZZ )\nexpect_equal( attributes(ZigZag(ia)), attributes(output$allZZ) )\nexpect_equal( ZigZag(it), output$topZZ )\nexpect_equal( attributes(ZigZag(it)), attributes(output$topZZ) )\nexpect_error( ZigZag(im) )\n"
  },
  {
    "path": "inst/tinytest/test-runfun.R",
    "content": "# Create input data\ndata(ttrc)\nrownames(ttrc) <- ttrc$Date\nttrc$Date <- NULL\n\ninput <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] )\ninput$top[1:10,] <- NA\ninput$mid[9:20,] <- NA\n\n# Load output data\nload(system.file(\"tinytest/output/running-functions.rda\", package=\"TTR\"))\n\n#################################################\n\n# Sum\nexpect_equal( runSum(input$all$Close), output$allSum )\nexpect_equal( attributes(runSum(input$all$Close)), attributes(output$allSum) )\nexpect_equal( runSum(input$top$Close), output$topSum )\nexpect_equal( attributes(runSum(input$top$Close)), attributes(output$topSum) )\nexpect_error( runSum(input$mid$Close) )\nexpect_error( runSum(input$all[,1:2]) )\nexpect_equal( tail(runSum(input$all$Close,250),1), sum(input$all$Close) )\nexpect_error( runSum(input$all$Close, n = -1) )\nexpect_error( runSum(input$all$Close, n = NROW(input$all) + 1) )\n\n# Wilder Sum\nexpect_equal( wilderSum(input$all$Close), output$allwSum )\nexpect_equal( attributes(wilderSum(input$all$Close)), attributes(output$allwSum) )\nexpect_equal( wilderSum(input$top$Close), output$topwSum )\nexpect_equal( attributes(wilderSum(input$top$Close)), attributes(output$topwSum) )\nexpect_error( wilderSum(input$mid$Close) )\nexpect_error( wilderSum(input$all[,1:2]) )\nexpect_error( wilderSum(input$all$Close, n = -1) )\nexpect_error( wilderSum(input$all$Close, n = NROW(input$all) + 1) )\n\n# Min\nexpect_equal( runMin(input$all$Close), output$allMin )\nexpect_equal( attributes(runMin(input$all$Close)), attributes(output$allMin) )\nexpect_equal( runMin(input$top$Close), output$topMin )\nexpect_equal( attributes(runMin(input$top$Close)), attributes(output$topMin) )\nexpect_error( runMin(input$mid$Close) )\nexpect_error( runMin(input$all[,1:2]) )\nexpect_error( runMin(input$all$Close, n = -1) )\nexpect_error( runMin(input$all$Close, n = NROW(input$all) + 1) )\nexpect_equal( tail(runMin(input$all$Close,250),1), min(input$all$Close) )\n\nttr <- runMin(input$all$Close, 1, TRUE)\nbase <- cummin(input$all$Close)\nexpect_equal(base, ttr)\n\n# Max\nexpect_equal( runMax(input$all$Close), output$allMax )\nexpect_equal( attributes(runMax(input$all$Close)), attributes(output$allMax) )\nexpect_equal( runMax(input$top$Close), output$topMax )\nexpect_equal( attributes(runMax(input$top$Close)), attributes(output$topMax) )\nexpect_error( runMax(input$mid$Close) )\nexpect_error( runMax(input$all[,1:2]) )\nexpect_error( runMax(input$all$Close, n = -1) )\nexpect_error( runMax(input$all$Close, n = NROW(input$all) + 1) )\nexpect_equal( tail(runMax(input$all$Close,250),1), max(input$all$Close) )\n\nttr <- runMax(input$all$Close, 1, TRUE)\nbase <- cummax(input$all$Close)\nexpect_equal(base, ttr)\n\n# Mean\nexpect_equal( runMean(input$all$Close), output$allMean )\nexpect_equal( attributes(runMean(input$all$Close)), attributes(output$allMean) )\nexpect_equal( runMean(input$top$Close), output$topMean )\nexpect_equal( attributes(runMean(input$top$Close)), attributes(output$topMean) )\nexpect_error( runMean(input$mid$Close) )\nexpect_error( runMean(input$all[,1:2]) )\nexpect_error( runMean(input$all$Close, n = -1) )\nexpect_error( runMean(input$all$Close, n = NROW(input$all) + 1) )\nexpect_equal( tail(runMean(input$all$Close,250),1), mean(input$all$Close) )\n\nttr <- runMean(input$all$Close, 5, TRUE)\nbase <- cumsum(input$all$Close) / seq_along(input$all$Close)\nis.na(base) <- 1:4\nexpect_equal(base, ttr)\n\nn.1.cumul <- runMean(1, n = 1, cumulative = TRUE)\nn.1.noncumul <- runMean(1, n = 1, cumulative = FALSE)\nexpect_equal(n.1.cumul, n.1.noncumul, info = \"cumulative n = 1\")\n\nx <- c(rep(NA_real_, 5), 1:5)\ntarget <- c(rep(NA_real_, 5), cumsum(1:5) / 1:5)\nresult <- runMean(x, n = 1, cumulative = TRUE)\nexpect_equal(target, result, info = \"cumulative accounts for leading NA\")\n\n# Median\nexpect_equal( runMedian(input$all$Close), output$allMedian )\nexpect_equal( attributes(runMedian(input$all$Close)), attributes(output$allMedian) )\nexpect_equal( runMedian(input$top$Close), output$topMedian )\nexpect_equal( attributes(runMedian(input$top$Close)), attributes(output$topMedian) )\nexpect_error( runMedian(input$mid$Close) )\nexpect_error( runMedian(input$all[,1:2]) )\nexpect_error( runMedian(input$all$Close, n = -1) )\nexpect_error( runMedian(input$all$Close, n = NROW(input$all) + 1) )\nexpect_equal( tail(runMedian(input$all$Close,250),1), median(input$all$Close) )\n\ncummedian <- compiler::cmpfun(\n  function(x) {\n    med <- x * NA_real_\n    for (i in seq_along(x)) {\n      med[i] <- median(x[1:i])\n    }\n    med\n  }\n)\nbase <- cummedian(input$all$Close)\nis.na(base) <- 1:4\nttr <- runMedian(input$all$Close, 5, \"mean\", TRUE)\nexpect_equal(base, ttr)\n\nis.na(base) <- 1:5\nttr <- runMedian(input$all$Close, 6, \"mean\", TRUE)\nexpect_equal(base, ttr)\n\n\nna <- rep(NA, 10)\nx <- input$all$Close\nxmed <- runMedian(x, 1, \"mean\", TRUE)\ny <- c(na, input$all$Close)\nymed <- runMedian(y, 1, \"mean\", TRUE)\nexpect_equal(ymed, c(na, xmed), info = \"cumulative n = 1\")\n\nn.1.cumul <- runMedian(1, n = 1, cumulative = TRUE)\nn.1.noncumul <- runMedian(1, n = 1, cumulative = FALSE)\nexpect_equal(n.1.cumul, n.1.noncumul, info = \"cumulative accounts for leading NA\")\n\n# Covariance\nexpect_equal( runCov(input$all$High, input$all$Low), output$allCov )\nexpect_equal( attributes(runCov(input$all$High, input$all$Low)), attributes(output$allCov) )\nexpect_equal( runCov(input$top$High, input$top$Low), output$topCov )\nexpect_equal( attributes(runCov(input$top$High, input$top$Low)), attributes(output$topCov) )\nexpect_error( runCov(input$mid$High, input$mid$Low) )\nexpect_error( runCov(input$all$High) )\nexpect_error( runCov(input$all[,1:2], input$all$Low) )\nexpect_error( runCov(input$all$Close, n = -1) )\nexpect_error( runCov(input$all$Close, n = NROW(input$all) + 1) )\nexpect_equal( tail(runCov(input$all$High, input$all$Low, 250),1), cov(input$all$High, input$all$Low) )\n# x argument as xts object\nxhi <- xts::as.xts(input$all)$High\nxlo <- xts::as.xts(input$all)$Low\nexpect_equal( as.numeric(runCov(xhi, input$all$Low)), output$allCov )\n# x and y arguments as xts objects\nexpect_equal( as.numeric(runCov(xhi, xlo)), output$allCov )\n\ntop <- input$top$Close\nmid <- input$mid$Close\nexpect_error(runCov(top, mid))\n\nexpect_warning(runCov(1:10, 1:10, n = 1, cumulative = FALSE),\n    info = \"n = 1 and cumulative = FALSE throws warning\")\n\ncumcov <- compiler::cmpfun(\n  function(x) {\n    cov <- x * NA_real_\n    for (i in seq_along(x)) {\n      y <- x[1:i]\n      cov[i] <- cov(y, y)\n    }\n    cov\n  }\n)\nx <- input$all$Close\nbase <- cumcov(x)\n\nis.na(base) <- 1\nttr <- runCov(x, x, 1, \"all.obs\", TRUE, TRUE)\nexpect_equal(base, ttr)\n\nis.na(base) <- 1:4\nttr <- runCov(x, x, 5, \"all.obs\", TRUE, TRUE)\nexpect_equal(base, ttr)\n\nis.na(base) <- 1:5\nttr <- runCov(x, x, 6, \"all.obs\", TRUE, TRUE)\nexpect_equal(base, ttr)\n\n# Correlation\nexpect_equal( runCor(input$all$High, input$all$Low), output$allCor )\nexpect_equal( attributes(runCor(input$all$High, input$all$Low)), attributes(output$allCor) )\nexpect_equal( runCor(input$top$High, input$top$Low), output$topCor )\nexpect_equal( attributes(runCor(input$top$High, input$top$Low)), attributes(output$topCor) )\nexpect_error( runCor(input$mid$High, input$mid$Low) )\nexpect_error( runCor(input$all$High) )\nexpect_error( runCor(input$all[,1:2], input$all$Low) )\nexpect_error( runCor(input$all$Close, n = -1) )\nexpect_error( runCor(input$all$Close, n = NROW(input$all) + 1) )\nexpect_equal( tail(runCor(input$all$High, input$all$Low, 250),1), cor(input$all$High, input$all$Low) )\n\n# Variance\nexpect_equal( runVar(input$all$Close), output$allVar )\nexpect_equal( attributes(runVar(input$all$Close)), attributes(output$allVar) )\nexpect_equal( runVar(input$top$Close), output$topVar )\nexpect_equal( attributes(runVar(input$top$Close)), attributes(output$topVar) )\nexpect_error( runVar(input$mid$Close) )\nexpect_error( runVar(input$all[,1:2], input$all$Low) )\nexpect_error( runVar(input$all$Close, n = -1) )\nexpect_error( runVar(input$all$Close, n = NROW(input$all) + 1) )\nexpect_equal( tail(runVar(input$all$Close,n=250),1), var(input$all$Close) )\n\n# Standard Deviation\nexpect_equal( runSD(input$all$Close), output$allSD )\nexpect_equal( attributes(runSD(input$all$Close)), attributes(output$allSD) )\nexpect_equal( runSD(input$top$Close), output$topSD )\nexpect_equal( attributes(runSD(input$top$Close)), attributes(output$topSD) )\nexpect_error( runSD(input$mid$Close) )\nexpect_error( runSD(input$all[,1:2]) )\nexpect_error( runSD(input$all$Close, n = -1) )\nexpect_error( runSD(input$all$Close, n = NROW(input$all) + 1) )\nexpect_equal( tail(runSD(input$all$Close,250),1), sd(input$all$Close) )\n\nx <- c(rep(NA_real_, 5), 1:5)\ntarget <- sapply(1:5, function(i) sd(seq_len(i)))\ntarget <- c(rep(NA, 5), target)\nresult <- runSD(x, n = 1, cumulative = TRUE)\nexpect_equal(target, result)\n\n# Absolute deviation\nexpect_equal( runMAD(input$all$Close), output$allMAD )\nexpect_equal( attributes(runMAD(input$all$Close)), attributes(output$allMAD) )\nexpect_equal( runMAD(input$top$Close), output$topMAD )\nexpect_equal( attributes(runMAD(input$top$Close)), attributes(output$topMAD) )\nexpect_error( runMAD(input$mid$Close) )\nexpect_error( runMAD(input$all[,1:2]) )\nexpect_error( runMAD(input$all$Close, n = -1) )\nexpect_error( runMAD(input$all$Close, n = NROW(input$all) + 1) )\nexpect_equal( tail(runMAD(input$all$Close,250),1), mad(input$all$Close) )\n\ncummad <- compiler::cmpfun(\n  function(x) {\n    mad <- x * NA_real_\n    for (i in seq_along(x)) {\n      y <- x[1:i]\n      mad[i] <- mad(y)\n    }\n    mad\n  }\n)\nx <- input$all$Close\nbase <- cummad(x)\nis.na(base) <- 1:4\nttr <- runMAD(x, 5, cumulative = TRUE)\nexpect_equal(base, ttr)\n\nis.na(base) <- 1:5\nttr <- runMAD(x, 6, cumulative = TRUE)\nexpect_equal(base, ttr)\n\nna <- rep(NA, 10)\nx <- input$all$Close\nxmed <- runMAD(x, 1, cumulative = TRUE)\ny <- c(na, input$all$Close)\nymed <- runMAD(y, 1, cumulative = TRUE)\nexpect_equal(ymed, c(na, xmed))\n\n# Percent Rank\nx <- input$all$Close\nexpect_error( runPercentRank(x, 10, exact.multiplier = -0.1), info = \"exact.multiplier bounds\" )\nexpect_error( runPercentRank(x, 10, exact.multiplier = 1.1), info = \"exact.multiplier bounds\" )\n\nxdata <- c(7.9, 5.2, 17.5, -12.7, 22, 4.3, -15.7, -9.3, 0.6, 0,\n           -22.8, 7.6, -5.5, 1.7, 5.6, 15.1, 6.6, 11.2, -7.8, -4.3)\nxrank10_1 <- c(NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.4, 0.1, 0.8,\n               0.5, 0.7, 0.9, 1, 0.8, 0.9, 0.2, 0.4)\nxrank10_0 <- c(NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.3, 0, 0.7,\n               0.4, 0.6, 0.8, 0.9, 0.7, 0.8, 0.1, 0.3)\n\nxrank <- round(xrank10_0, 2)\nexpect_identical(xrank, runPercentRank(xdata, 10, FALSE, 0), info = \"exact.multiplier = 0\")\n\nxrank <- round(xrank10_0 + 0.05, 2)\nexpect_identical(xrank, runPercentRank(xdata, 10, FALSE, 0.5), info = \"exact.multiplier = 0.5\")\n\nxrank <- round(xrank10_0 + 0.1, 2)\nexpect_identical(xrank, runPercentRank(xdata, 10, FALSE, 1), info = \"exact.multiplier = 1\")\n\nxrank <- c(0, 0, 2, 0, 4, 1, 0, 2, 3, 3, 0, 8,\n           4, 7, 10, 13, 11, 14, 4, 6) / 1:20\nxrank[1:9] <- NA\nxrank[10] <- 0\nexpect_identical(xrank, runPercentRank(xdata, 10, TRUE, 0),\n                 info = \"exact.multiplier = 0, cumulative = TRUE\")\n\nxrank <- (c(0, 0, 2, 0, 4, 1, 0, 2, 3, 3, 0, 8,\n           4, 7, 10, 13, 11, 14, 4, 6) + 0.5) / 1:20\nxrank[1:9] <- NA\nxrank[10] <- 0.5\nexpect_identical(xrank, runPercentRank(xdata, 10, TRUE, 0.5),\n                 info = \"exact.multiplier = 0.5, cumulative = TRUE\")\n\nxrank <- (c(0, 0, 2, 0, 4, 1, 0, 2, 3, 3, 0, 8,\n           4, 7, 10, 13, 11, 14, 4, 6) + 1) / 1:20\nxrank[1:9] <- NA\nxrank[10] <- 1\nexpect_identical(xrank, runPercentRank(xdata, 10, TRUE, 1),\n                 info = \"exact.multiplier = 1, cumulative = TRUE\")\n"
  },
  {
    "path": "inst/tinytest/test-trend.R",
    "content": "# Create input data\ndata(ttrc)\nrownames(ttrc) <- ttrc$Date\nttrc$Date <- NULL\n\niAll <- as.matrix(ttrc[1:250,])\niTop <- iAll; iTop[1:10,] <- NA\niMid <- iAll; iMid[9:20,] <- NA\n\nhl  <- c('High','Low')\nhlc <- c('High','Low','Close')\ncl  <- 'Close'\n\n# Load output data\nload(system.file(\"tinytest/output/trend.rda\", package=\"TTR\"))\n\n#################################################\n\n# ADX\nexpect_equal( ADX(iAll[,hlc]), output$allADX )\nexpect_equal( attributes(ADX(iAll[,hlc])), attributes(output$allADX) )\nexpect_equal( ADX(iTop[,hlc]), output$topADX )\nexpect_equal( attributes(ADX(iTop[,hlc])), attributes(output$topADX) )\n#expect_error( ADX(iMid[,hlc]) )\n\nwilder.and.matype <- ADX(iAll[,hlc], maType = \"EMA\", wilder = FALSE)\nwilder.only <- ADX(iAll[,hlc], wilder = FALSE)\nexpect_equal( wilder.and.matype, wilder.only, info = \"ADX does not overwrite maArgs\" )\n\n# Aroon\n# non-xts\nia <- iAll[,hl]\nit <- iTop[,hl]\nim <- iMid[,hl]\nrownames(ia) <- rownames(it) <- rownames(im) <- NULL\noa <- aroon(ia);  rownames(oa) <- rownames(iAll)\not <- aroon(it);  rownames(ot) <- rownames(iTop)\nexpect_equal( oa, output$allAroon )\nexpect_equal( attributes(oa), attributes(output$allAroon) )\nexpect_equal( ot, output$topAroon )\nexpect_equal( attributes(ot), attributes(output$topAroon) )\n#expect_error( aroon(im) )\n\n# xts\nexpect_equal( aroon(iAll[,hl]), output$allAroon )\nexpect_equal( attributes(aroon(iAll[,hl])), attributes(output$allAroon) )\nexpect_equal( aroon(iTop[,hl]), output$topAroon )\nexpect_equal( attributes(aroon(iTop[,hl])), attributes(output$topAroon) )\n#expect_error( aroon(iMid[,hl]) )\n\nx <- c(NA, rnorm(10))\nexpect_silent(aroon(x, 10), info = \"non-na equals 'n' does not error\")\n\n# Average True Range\n# non-xts\nia <- iAll[,hlc]\nit <- iTop[,hlc]\nim <- iMid[,hlc]\nrownames(ia) <- rownames(it) <- rownames(im) <- NULL\naATR <- ATR(ia);  rownames(aATR) <- rownames(iAll)\ntATR <- ATR(it);  rownames(tATR) <- rownames(iTop)\nexpect_equal( aATR, output$allATR )\nexpect_equal( attributes(aATR), attributes(output$allATR) )\nexpect_equal( tATR, output$topATR )\nexpect_equal( attributes(tATR), attributes(output$topATR) )\n#expect_error( ATR(im) )\n\n# xts\nexpect_equal( ATR(iAll[,hlc]), output$allATR )\nexpect_equal( attributes(ATR(iAll[,hlc])), attributes(output$allATR) )\nexpect_equal( ATR(iTop[,hlc]), output$topATR )\nexpect_equal( attributes(ATR(iTop[,hlc])), attributes(output$topATR) )\n#expect_error( ATR(iMid[,hlc]) )\n\nwilder.and.matype <- ATR(iAll[,hlc], maType = \"EMA\", wilder = FALSE)\nwilder.only <- ATR(iAll[,hlc], wilder = FALSE)\nexpect_equal( wilder.and.matype, wilder.only, info = \"ATR does not overwrite maArgs\" )\n\n# Commodity Channel Index\nexpect_equal( CCI(iAll[,hlc]), output$allCCI )\nexpect_equal( attributes(CCI(iAll[,hlc])), attributes(output$allCCI) )\nexpect_equal( CCI(iTop[,hlc]), output$topCCI )\nexpect_equal( attributes(CCI(iTop[,hlc])), attributes(output$topCCI) )\n#expect_error( CCI(input$mid[,c('High','Low','Close')]) )\n\n# Trend Detection Index\nia <- iAll[,cl]\nit <- iTop[,cl]\nnames(ia) <- names(it) <- NULL\nexpect_equal( TDI(ia), output$allTDI )\nexpect_equal( attributes(TDI(ia)), attributes(output$allTDI) )\n#expect_equal( TDI(iTop[,cl]), output$topTDI )\n#expect_error( TDI(iMid[,cl]) )\n\n# Vertical Horizontal Filter\nia <- iAll[,cl]\nit <- iTop[,cl]\nnames(ia) <- names(it) <- NULL\nexpect_equal( VHF(ia), output$allVHF )\nexpect_equal( attributes(VHF(ia)), attributes(output$allVHF) )\n#expect_equal( VHF(iTop[,cl]), output$topVHF )\n#expect_error( VHF(iMid[,cl] )\n"
  },
  {
    "path": "inst/tinytest/test-volatility.R",
    "content": "# Create input data\ndata(ttrc)\nrownames(ttrc) <- ttrc$Date\nttrc$Date <- NULL\n\ninput <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] )\ninput$top[1:10,] <- NA\ninput$mid[9:20,] <- NA\n\n# Load output data\nload(system.file(\"tinytest/output/volatility.rda\", package=\"TTR\"))\n\n#################################################\n\n# Close\n# Why does the last two checks fail if they're first???\n#expect_equal( volatility(input$all[,c('Open','High','Low','Close')],calc='close'), output$allClose )\n#expect_equal( volatility(input$top[,c('Open','High','Low','Close')],calc='close'), output$topClose )\nexpect_error( volatility(input$mid[,c('Open','High','Low','Close')],calc='close') )\n\n\n# Garman Klass\nohlc <- c('Open','High','Low','Close')\nexpect_equal( volatility(input$all[,ohlc],calc='garman.klass')[[\"x\"]], output$allGK[[\"x\"]] )\nexpect_equal( volatility(input$top[,ohlc],calc='garman.klass')[[\"x\"]], output$topGK[[\"x\"]] )\nexpect_error( volatility(input$mid[,ohlc],calc='garman.klass') )\n\n\n# Parkinson\nohlc <- c('Open','High','Low','Close')\nexpect_equal( volatility(input$all[,ohlc],calc='parkinson')[[\"x\"]], output$allParkinson[[\"x\"]] )\nexpect_equal( volatility(input$top[,ohlc],calc='parkinson')[[\"x\"]], output$topParkinson[[\"x\"]] )\nexpect_error( volatility(input$mid[,ohlc],calc='parkinson') )\n\n\n# Rogers Satchell\nohlc <- c('Open','High','Low','Close')\nexpect_equal( volatility(input$all[,ohlc],calc='rogers.satchell')[[\"x\"]], output$allRS[[\"x\"]] )\nexpect_equal( volatility(input$top[,ohlc],calc='rogers.satchell')[[\"x\"]], output$topRS[[\"x\"]] )\nexpect_error( volatility(input$mid[,ohlc],calc='rogers.satchell') )\n\n\n# Chaikin Volatility\nia <- as.matrix(input$all)\nrownames(ia) <- NULL\nexpect_equal( chaikinVolatility(ia[,c('High','Low')]), output$allChaikin )\n#expect_equal( chaikinVolatility(input$top[,c('Open','High','Low','Close')],calc='rogers.satchell'), output$topRS )\n#expect_error( volatility(input$mid[,c('Open','High','Low','Close')],calc='rogers.satchell') )\n"
  },
  {
    "path": "inst/tinytest/test-volume.R",
    "content": "# Create input data\ndata(ttrc)\nrownames(ttrc) <- ttrc$Date\nttrc$Date <- NULL\n\n#input <- list( all=ttrc[1:250,], top=ttrc[1:250,], mid=ttrc[1:250,] )\n#input$top[1:10,] <- NA\n#input$mid[9:20,] <- NA\n\n#iAll <- as.matrix(ttrc[1:250,])\niAll <- ttrc[1:250,]\niTop <- iAll; iTop[1:10,] <- NA\niMid <- iAll; iMid[9:20,] <- NA\n\nhl  <- c('High','Low')\nhlc <- c('High','Low','Close')\ncl  <- 'Close'\n\n# Load output data\nload(system.file(\"tinytest/output/volume.rda\", package=\"TTR\"))\n\n#################################################\n\n# On Balance Volume\nexpect_equal( OBV(iAll$Close, iAll$Volume), output$allOBV )\n#expect_equal( OBV(iTop[,cl], iTop[,'Volume']), output$topOBV )\n#expect_error( OBV(iMid[,cl], iMid[,'Volume']) )\n#expect_error( OBV(iAll[,cl], iMid[,'Volume']) )\n#expect_error( OBV(iMid[,cl], iAll[,'Volume']) )\n\n# Chaikin Accumulation / Distribution\nchAD <- chaikinAD(iAll[,hlc], iAll[,'Volume'])\nexpect_equivalent( chaikinAD(iAll[,hlc], iAll[,'Volume']), output$allChaikinAD )\n#expect_equal( chaikinAD(iTop[,hlc], iTop[,'Volume']), output$topChaikinAD )\n#expect_error( chaikinAD(iMid[,hlc], iMid[,'Volume']) )\n#expect_error( chaikinAD(iAll[,hlc], iMid[,'Volume']) )\n#expect_error( chaikinAD(iMid[,hlc], iAll[,'Volume']) )\n\n# Chaikin Money Flow\nia <- iAll[,hlc];  rownames(ia) <- NULL\nit <- iTop[,hlc];  rownames(it) <- NULL\nexpect_equal( CMF(ia, iAll[,'Volume']), output$allCMF )\nexpect_equal( CMF(it, iTop[,'Volume']), output$topCMF )\nexpect_error( CMF(iMid[,hlc], iMid[,'Volume']) )\nexpect_error( CMF(iAll[,hlc], iMid[,'Volume']) )\nexpect_error( CMF(iMid[,hlc], iAll[,'Volume']) )\n\n# Money Flow Index\nia <- iAll[,hlc];  rownames(ia) <- NULL\nit <- iTop[,hlc];  rownames(it) <- NULL\nexpect_equal( MFI(ia, iAll[,'Volume']), output$allMFI )\nexpect_equal( MFI(it, iTop[,'Volume']), output$topMFI )\nexpect_error( MFI(iMid[,hlc], iMid[,'Volume']) )\nexpect_error( MFI(iAll[,hlc], iMid[,'Volume']) )\nexpect_error( MFI(iMid[,hlc], iAll[,'Volume']) )\n\nx <- structure(c(6284.19, 6284.19, 6284.19, 6284.19, 6284.19, 6285.22,\n6285.96, 6287.54, 6287.84, 6287.89, 6288.95, 6284.19, 6284.19, 6284.19,\n6284.19, 6284.19, 6283.98, 6284.20, 6285.54, 6286.71, 6286.58, 6286.75,\n6284.19, 6284.19, 6284.19, 6284.19, 6284.19, 6284.46, 6285.54, 6287.47,\n6286.92, 6286.82, 6288.95, 9171293400, 9171293400, 9171293400, 9171293400,\n9171293400, 1650189487, 1796244384, 1864666606, 1845475611, 1831082797,\n1918533018), .Dim = c(11L, 4L))\no <- c(NA, NA, NA, 50, 50, 100, 100, 100, 100, 66.95494, 67.27551)\nm <- MFI(x[,-4], x[,4], n = 3)\nexpect_equal(m, o, info = \"MFI when volume is unchanged\")\n\n# Williams' Accumulation / Distribution\n# non-xts\nia <- iAll[,hlc]\nit <- iTop[,hlc]\nim <- iMid[,hlc]\nrownames(ia) <- rownames(it) <- rownames(im) <- NULL\nexpect_equal( williamsAD(ia), output$allWilliamsAD )\n#expect_equal( williamsAD(iTop[,hlc]), output$topWilliamsAD )\n#expect_error( williamsAD(iMid[,hlc]) )\n"
  },
  {
    "path": "man/ADX.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/ADX.R\n\\name{ADX}\n\\alias{ADX}\n\\alias{DI}\n\\alias{DX}\n\\title{Welles Wilder's Directional Movement Index}\n\\usage{\nADX(HLC, n = 14, maType, ...)\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices.}\n\n\\item{n}{Number of periods to use for DX calculation (not ADX calculation).}\n\n\\item{maType}{A function or a string naming the function to be called.}\n\n\\item{\\dots}{Other arguments to be passed to the \\code{maType} function.}\n}\n\\value{\nA object of the same class as \\code{HLC} or a matrix (if\n\\code{try.xts} fails) containing the columns:\n \\describe{\n  \\item{ DIp }{ The positive Direction Index. }\n  \\item{ DIn }{ The negative Direction Index. }\n  \\item{ DX }{ The Direction Index. }\n  \\item{ ADX }{ The Average Direction Index (trend strength). }\n }\n}\n\\description{\nDirectional Movement Index; developed by J. Welles Wilder.\n}\n\\details{\nThe \\code{DIp}/\\code{DIn} (positive/negative) is the percentage of the true\nrange that is up/down.\n}\n\\note{\nA buy/sell signal is generated when the +/-DI crosses up over the\n-/+DI, when the DX/ADX signals a strong trend.  A high/low DX signals a\nstrong/weak trend.  DX is usually smoothed with a moving average (i.e. the\nADX).\n}\n\\examples{\n\n data(ttrc)\n dmi.adx <- ADX(ttrc[,c(\"High\",\"Low\",\"Close\")])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://www.fmlabs.com/reference/DI.htm}\\cr\n\\url{https://www.fmlabs.com/reference/DX.htm}\\cr\n\\url{https://www.fmlabs.com/reference/ADX.htm}\\cr\n\\url{https://www.fmlabs.com/reference/ADXR.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=49}\\cr\n\\url{https://www.linnsoft.com/techind/directional-indicator-diplus-diminus}\\cr\n\\url{https://www.linnsoft.com/techind/adx-avg-directional-movement}\\cr\n\\url{https://www.linnsoft.com/techind/adxr-avg-directional-movement-rating}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:average_directional_index_adx}\\cr\n}\n\\seealso{\nSee \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\noptions; and note Warning section.  The DX calculation uses\n\\code{\\link{ATR}}.  See \\code{\\link{aroon}}, \\code{\\link{CCI}},\n\\code{\\link{TDI}}, \\code{\\link{VHF}}, \\code{\\link{GMMA}} for other indicators\nthat measure trend direction/strength.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/ATR.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/ATR.R\n\\name{TR}\n\\alias{TR}\n\\alias{ATR}\n\\title{True Range / Average True Range}\n\\usage{\nTR(HLC)\n\nATR(HLC, n = 14, maType, ...)\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices.}\n\n\\item{n}{Number of periods for moving average.}\n\n\\item{maType}{A function or a string naming the function to be called.}\n\n\\item{\\dots}{Other arguments to be passed to the \\code{maType} function.}\n}\n\\value{\nA object of the same class as \\code{HLC} or a matrix (if\n\\code{try.xts} fails) containing the columns:\n \\describe{\n  \\item{ tr }{ The true range of the series. }\n  \\item{ atr }{ The average (as specified by \\code{ma}) true range of the series. }\n  \\item{ trueHigh }{ The true high of the series. }\n  \\item{ trueLow }{ The true low of the series. }\n }\n}\n\\description{\nTrue range (TR) is a measure of volatility of a High-Low-Close series;\naverage true range (ATR) is a Welles Wilder's style moving average of the TR.\nDeveloped by J. Welles Wilder in 1978.\n}\n\\details{\nTR incorporates yesterday's close in the calculation (high minus low).  E.g.\nif yesterday's close was higher than today's high, then the TR would equal\nyesterday's close minus today's low.\n\nThe ATR is a component of the Welles Wilder Directional Movement Index\n(\\code{DX}, \\code{ADX}).\n}\n\\examples{\n\ndata(ttrc)\ntr <- TR(ttrc[,c(\"High\",\"Low\",\"Close\")])\natr <- ATR(ttrc[,c(\"High\",\"Low\",\"Close\")], n=14)\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://www.fmlabs.com/reference/TR.htm}\\cr\n\\url{https://www.fmlabs.com/reference/ATR.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=35}\\cr\n\\url{https://www.linnsoft.com/techind/true-range-tr}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:average_true_range_atr}\\cr\n}\n\\seealso{\nSee \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\noptions; and note Warning section.  See \\code{\\link{DX}}, which uses true\nrange.  See \\code{\\link{chaikinVolatility}} for another volatility measure.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/CCI.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/CCI.R\n\\name{CCI}\n\\alias{CCI}\n\\title{Commodity Channel Index}\n\\usage{\nCCI(HLC, n = 20, maType, c = 0.015, ...)\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices.  If only a univariate series is given, it will be\nused.  See details.}\n\n\\item{n}{Number of periods for moving average.}\n\n\\item{maType}{A function or a string naming the function to be called.}\n\n\\item{c}{Constant to apply to the mean deviation.}\n\n\\item{\\dots}{Other arguments to be passed to the \\code{maType} function.}\n}\n\\value{\nA object of the same class as \\code{HLC} or a vector (if\n\\code{try.xts} fails) containing the CCI values.\n}\n\\description{\nThe Commodity Channel Index (CCI) attempts to identify starting and ending\ntrends.\n}\n\\details{\nCCI relates the current price and the average of price over \\code{n} periods.\nThe CCI usually falls in a channel of -100 to 100. A basic CCI trading system\nis: Buy (sell) if CCI rises above 100 (falls below -100) and sell (buy) when\nit falls below 100 (rises above -100).\n\nCCI is usually calculated using the typical price, but if a univariate series\n(e.g. Close, Weighted Close, Median Price, etc.) is provided, it will be used\ninstead.\n}\n\\note{\nIf \\code{HLC} is a High-Low-Close matrix, then typical price will be\ncalculated.  If \\code{HLC} is a vector, then those values will be used\ninstead of the typical price.\n}\n\\examples{\n\n data(ttrc)\n cci <- CCI(ttrc[,c(\"High\",\"Low\",\"Close\")])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://www.fmlabs.com/reference/CCI.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=42}\\cr\n\\url{https://www.linnsoft.com/techind/cci-commodity-channel-index}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:commodity_channel_index_cci}\\cr\n}\n\\seealso{\nSee \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\noptions; and note Warning section.  See \\code{\\link{aroon}},\n\\code{\\link{ADX}}, \\code{\\link{TDI}}, \\code{\\link{VHF}}, \\code{\\link{GMMA}}\nfor other indicators that measure trend direction/strength.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/CLV.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/CLV.R\n\\name{CLV}\n\\alias{CLV}\n\\title{Close Location Value}\n\\usage{\nCLV(HLC)\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices.}\n}\n\\value{\nA object of the same class as \\code{HLC} or a vector (if\n\\code{try.xts} fails) containing the Close Location Values of a\nHigh-Low-Close price series.\n}\n\\description{\nThe Close Location Value (CLV) relates the day's close to its trading range.\n}\n\\details{\nThe CLV will fall in a range of -1 to +1.  If the CLV is +/-1, the close is\nat the high/low; if the CLV is 0, the close is directly between the high and\nlow.\n}\n\\examples{\n\n data(ttrc)\n clv <- CLV(ttrc[,c(\"High\",\"Low\",\"Close\")])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:accumulation_distribution_line}\\cr\n}\n\\seealso{\nSee \\code{\\link{chaikinAD}}, which uses CLV.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/CMF.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/CMF.R\n\\name{CMF}\n\\alias{CMF}\n\\title{Chaikin Money Flow}\n\\usage{\nCMF(HLC, volume, n = 20)\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices.}\n\n\\item{volume}{Vector or matrix of volume observations corresponding to the\n\\code{HLC} object.}\n\n\\item{n}{Number of periods to use.}\n}\n\\value{\nA object of the same class as \\code{HLC} and \\code{volume} or a\nvector (if \\code{try.xts} fails) containing the Chaikin Money Flow values.\n}\n\\description{\nChaikin Money Flow compares total volume over the last \\code{n} time periods\nto total volume times the Close Location Value (CLV) over the last \\code{n}\ntime periods.  Developed by Marc Chaikin.\n}\n\\details{\nChaikin Money Flow is calculated by taking dividing the sum of the Chaikin\nAccumulation / Distribution line over the past \\code{n} periods by the sum of\nvolume over the past \\code{n} periods.\n}\n\\note{\nWhen Chaikin Money Flow is above/below +/- 0.25 it is a bullish/bearish\nsignal.  If Chaikin Money Flow remains below zero while the price is rising,\nit indicates a probable reversal.\n}\n\\examples{\n\n data(ttrc)\n cmf <- CMF(ttrc[,c(\"High\",\"Low\",\"Close\")], ttrc[,\"Volume\"])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://www.fmlabs.com/reference/ChaikinMoneyFlow.htm}\\cr\n\\url{https://www.linnsoft.com/techind/chaikin-money-flow-cmf}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:chaikin_money_flow_cmf}\\cr\n}\n\\seealso{\nSee \\code{\\link{CLV}}, and \\code{\\link{chaikinAD}}.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/CMO.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/CMO.R\n\\name{CMO}\n\\alias{CMO}\n\\title{Chande Momentum Oscillator}\n\\usage{\nCMO(x, n = 14)\n}\n\\arguments{\n\\item{x}{Price, volume, etc. series that is coercible to xts or matrix.}\n\n\\item{n}{Number of periods to use.}\n}\n\\value{\nA object of the same class as \\code{x} or a vector (if \\code{try.xts}\nfails) containing Chande Momentum Oscillator values.\n}\n\\description{\nThe Chande Momentum Oscillator (CMO) is a modified RSI.  Developed by Tushar\nS. Chande.\n}\n\\details{\nThe CMO divides the total movement by the net movement ([up - down] / [up +\ndown]), where RSI divides the upward movement by the net movement (up / [up +\ndown]).\n}\n\\note{\nThere are several ways to interpret the CMO:\n \\enumerate{\n   \\item Values over/under +/- 50 indicate overbought/oversold conditions.\n   \\item High CMO values indicate strong trends.\n   \\item When the CMO crosses above/below a moving average of the CMO,\n         it is a buy/sell signal.\n }\n}\n\\examples{\n\n data(ttrc)\n cmo <- CMO(ttrc[,\"Close\"])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://www.fmlabs.com/reference/CMO.htm}\\cr\n}\n\\seealso{\nSee \\code{\\link{RSI}}.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/CTI.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/CTI.R\n\\name{CTI}\n\\alias{CTI}\n\\title{Ehler's Correlation Trend Indicator}\n\\usage{\nCTI(price, n = 20, slope = 1)\n}\n\\arguments{\n\\item{price}{Price series that is coercible to xts or matrix.}\n\n\\item{n}{Number of periods to use.}\n\n\\item{slope}{Slope of desired trend.}\n}\n\\value{\nA object of the same class as \\code{price} or a matrix (if\n\\code{try.xts} fails) with the column:\n \\describe{\n  \\item{cti}{ The Correlation Trend Indicator. }\n }\n}\n\\description{\nEhler's Correlation Trend Indicator (CTI) measures the Spearman correlation\nof the price with the ideal trend line: a straight line with increasing\nslope.\n}\n\\details{\nThe CTI measures the Spearman correlation between the price and the ideal\ntrend line with slope of \\code{slope}, over the past \\code{n} days.\n\nSee URL in references section for further details.\n}\n\\note{\nPositive/negative CTI values signal positive/negative correlation with\nthe desired trend line slope. A simple strategy could be long when the CTI\nis positive and, short when it is negative.\n}\n\\examples{\n\ndata(ttrc)\ncti <- CTI(ttrc[,\"Close\"], n = 20)\n\n}\n\\references{\nJohn Ehlers, Correlation Trend Indicator, Stocks & Commodities May-2020\nThe following site(s) were used to code/document this indicator:\\cr\n\\url{https://financial-hacker.com/petra-on-programming-a-unique-trend-indicator/}\\cr\n}\n\\seealso{\nSee \\code{\\link{aroon}}, \\code{\\link{CCI}}, \\code{\\link{ADX}},\n\\code{\\link{VHF}}, \\code{\\link{GMMA}}, \\code{\\link{TDI}} for other\nindicators that measure trend direction/strength.\n}\n\\author{\nEthan Smith, Joshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/DPO.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/DPO.R\n\\name{DPO}\n\\alias{DPO}\n\\title{De-Trended Price Oscillator}\n\\usage{\nDPO(x, n = 10, maType, shift = n/2 + 1, percent = FALSE, ...)\n}\n\\arguments{\n\\item{x}{Price, volume, etc. series that is coercible to xts or matrix.}\n\n\\item{n}{Number of periods for moving average.}\n\n\\item{maType}{A function or a string naming the function to be called.}\n\n\\item{shift}{The number of periods to shift the moving average.}\n\n\\item{percent}{logical; if \\code{TRUE}, the percentage difference between the\nslow and fast moving averages is returned, otherwise the difference between\nthe respective averages is returned.}\n\n\\item{\\dots}{Other arguments to be passed to the \\code{maType} function.}\n}\n\\value{\nA object of the same class as \\code{x} or a vector (if \\code{try.xts}\nfails) containing the DPO values.\n}\n\\description{\nThe Detrended Price Oscillator (DPO) removes the trend in prices - or other\nseries - by subtracting a moving average of the price from the price.\n}\n\\details{\nThe Detrended Price shows cycles and overbought / oversold conditions.\n}\n\\note{\nDPO does not extend to the last date because it is based on a displaced moving\naverage. The calculation shifts the results \\code{shift} periods, so the last\n\\code{shift} periods will be zero.\\cr\nAs stated above, the DPO can be used on any univariate series, not just price.\n}\n\\section{Warning}{\n The detrended price oscillator removes the trend in the\nseries by centering the moving average. Centering the moving average causes it\nto include future data. Therefore, even though this indicator looks like a\nclassic oscillator, it should not be used for trading rule signals.\n}\n\n\\examples{\n\n data(ttrc)\n priceDPO <- DPO(ttrc[,\"Close\"])\n volumeDPO <- DPO(ttrc[,\"Volume\"])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:detrended_price_osci}\\cr\n}\n\\seealso{\nSee \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\noptions; and note Warning section.  See \\code{\\link{MACD}} for a general\noscillator.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/DVI.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/DVI.R\n\\name{DVI}\n\\alias{DVI}\n\\title{DV Intermediate Oscillator}\n\\usage{\nDVI(\n  price,\n  n = 252,\n  wts = c(0.8, 0.2),\n  smooth = 3,\n  magnitude = c(5, 100, 5),\n  stretch = c(10, 100, 2),\n  exact.multiplier = 1\n)\n}\n\\arguments{\n\\item{price}{Price series that is coercible to xts or matrix.}\n\n\\item{n}{Number of periods for the percent rank.}\n\n\\item{wts}{The weight given to the smoothed returns (magnitude) component and\nthe up/down days (stretch) component, respectively.}\n\n\\item{smooth}{The number of periods to smooth price.}\n\n\\item{magnitude}{A set of 3 periods used to smooth magnitude.}\n\n\\item{stretch}{A set of 3 periods used to smooth stretch.}\n\n\\item{exact.multiplier}{The weight applied to identical values in the window.\nSee \\code{runPercentRank}.}\n}\n\\value{\nA object of the same class as \\code{price} or a vector (if\n\\code{try.xts} fails) containing the DVI values.\n}\n\\description{\nThe DV Intermediate oscillator (DVI) is a very smooth momentum oscillator\nthat can also be used as a trend indicator.  Created by David Varadi.\n}\n\\details{\nThe DVI combines smoothed returns over different time windows and the\nrelative number of up versus down days (stretch) over different time windows.\n}\n\\examples{\n\n data(ttrc)\n dvi <- DVI(ttrc[,\"Close\"])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://cssanalytics.wordpress.com/2009/12/13/what-is-the-dvi/}\\cr\n\\url{https://marketsci.wordpress.com/2010/07/27/css-analytics\\%E2\\%80\\%99-dvi-indicator-revealed/}\\cr\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/DonchianChannel.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/DonchianChannel.R\n\\name{DonchianChannel}\n\\alias{DonchianChannel}\n\\alias{Donchian}\n\\title{Donchian Channel}\n\\usage{\nDonchianChannel(HL, n = 10, include.lag = FALSE)\n}\n\\arguments{\n\\item{HL}{Object that is coercible to xts or matrix and contains High-Low\nprices.}\n\n\\item{n}{Number of periods for moving average.}\n\n\\item{include.lag}{Should values be lagged so that today's prices are not\nincluded in the calculation? See Note.}\n}\n\\value{\nA object of the same class as \\code{HL} or a matrix (if\n\\code{try.xts} fails) containing the columns:\n \\describe{\n  \\item{ high }{ The highest high series. }\n  \\item{ mid }{ The average of \\code{high} and \\code{low}. }\n  \\item{ low }{ The lowest low series. }\n }\n}\n\\description{\nDonchian Channels were created by Richard Donchian and were used to generate\nbuy and sell signals for the Turtle Trading system.\n}\n\\details{\nDonchian Channels consist of two (sometimes three) lines:\n\nThe top line is the highest high of the past \\code{n} periods.  The bottom\nline is the lowest low of the past \\code{n} periods.  The middle line is the\naverage of the top and bottom lines.\n}\n\\note{\nThe default of \\code{include.lag=FALSE} makes \\code{DonchainChannel}\nconsistent with other \\pkg{TTR} functions, in that it includes the current\nperiod in the calculation.\n\nThe default is different than the original calculation, which would calculate\nthe indicator using periods t-1 through t-n. Setting \\code{include.lag=TRUE}\nwill return the result of the original calculation.\n\nThe default of this argument may change in the future.\n}\n\\examples{\n\n data(ttrc)\n dc <- DonchianChannel( ttrc[,c(\"High\",\"Low\")] )\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://www.linnsoft.com/techind/donchian-channels}\\cr\n}\n\\seealso{\nSee \\code{\\link{BBands}}.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/EMV.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/EMV.R\n\\name{EMV}\n\\alias{EMV}\n\\title{Arms' Ease of Movement Value}\n\\usage{\nEMV(HL, volume, n = 9, maType, vol.divisor = 10000, ...)\n}\n\\arguments{\n\\item{HL}{Object that is coercible to xts or matrix and contains High-Low\nprices.}\n\n\\item{volume}{Vector or matrix of volume observations corresponding to the\n\\code{HL} object.}\n\n\\item{n}{Number of periods for moving average.}\n\n\\item{maType}{A function or a string naming the function to be called.}\n\n\\item{vol.divisor}{An increment to make the results larger and easier to work\nwith.}\n\n\\item{\\dots}{Other arguments to be passed to the \\code{maType} function.}\n}\n\\value{\nA object of the same class as \\code{HL} and \\code{volume} or a matrix\n(if \\code{try.xts} fails) containing the columns:\n \\describe{\n  \\item{ emv }{ The ease of movement values. }\n  \\item{ maEMV }{ The smoothed (as specified by \\code{ma}) ease of movement values. }\n }\n}\n\\description{\nArms' Ease of Movement Value (EMV) emphasizes days where the security moves\neasily and minimizes days where the security does not move easily.  Developed\nby Richard W. Arms, Jr.\n}\n\\details{\nThe EMV is calculated by dividing the midpoint ([high + low]/2) move by the\n'Box Ratio' (volume divided by the high minus low).\n}\n\\note{\nA buy/sell signal is generated when the EMV crosses above/below zero.\nWhen the EMV hovers around zero, there are small price movements and/or high\nvolume, and the price is not moving easily.\n}\n\\examples{\n\n data(ttrc)\n emv <- EMV(ttrc[,c(\"High\",\"Low\")], ttrc[,\"Volume\"])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://www.fmlabs.com/reference/ArmsEMV.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=51}\\cr\n\\url{https://www.linnsoft.com/techind/arms-ease-movement}\\cr\n}\n\\seealso{\nSee \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\noptions; and note Warning section.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/GMMA.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/GMMA.R\n\\name{GMMA}\n\\alias{GMMA}\n\\alias{Guppy}\n\\alias{guppy}\n\\title{Guppy Multiple Moving Averages}\n\\usage{\nGMMA(\n  x,\n  short = c(3, 5, 8, 10, 12, 15),\n  long = c(30, 35, 40, 45, 50, 60),\n  maType\n)\n}\n\\arguments{\n\\item{x}{Price, volume, etc. series that is coercible to xts or matrix.}\n\n\\item{short}{Vector of short-term periods.}\n\n\\item{long}{Vector of long-term periods.}\n\n\\item{maType}{Either:\n\\enumerate{\n  \\item A function or a string naming the function to be called.\n  \\item A \\emph{list} with the first component like (1) above, and\n    additional parameters specified as \\emph{named} components.\n    See Examples.\n}}\n}\n\\value{\nA object of the same class as \\code{x} or \\code{price} or a vector\n(if \\code{try.xts} fails) containing the Guppy Multiple Moving Average.\n}\n\\description{\nCalculate the Guppy Multiple Moving Average of a series.\n}\n\\details{\nThe Guppy Multiple Moving Average signals a changing trend when the\n\\code{short} and \\code{long} groups of moving averages intersect.  An up/down\ntrend exists when the short/long-term moving averages are greater than the\nlong/short-term averages.\n}\n\\examples{\n\n data(ttrc)\n gmma <- GMMA(ttrc[,\"Close\"])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://www.investopedia.com/terms/g/guppy-multiple-moving-average.asp}\\cr\n}\n\\seealso{\nSee \\code{\\link{aroon}}, \\code{\\link{CCI}}, \\code{\\link{ADX}},\n\\code{\\link{VHF}}, \\code{\\link{TDI}} for other indicators that measure trend\ndirection/strength.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/KST.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/KST.R\n\\name{KST}\n\\alias{KST}\n\\title{Know Sure Thing}\n\\usage{\nKST(\n  price,\n  n = c(10, 10, 10, 15),\n  nROC = c(10, 15, 20, 30),\n  nSig = 9,\n  maType,\n  wts = 1:NROW(n),\n  ...\n)\n}\n\\arguments{\n\\item{price}{Price series that is coercible to xts or matrix.}\n\n\\item{n}{A vector of the number of periods to use in the MA calculations.}\n\n\\item{nROC}{A vector of the number of periods to use in the ROC calculations.}\n\n\\item{nSig}{The number of periods to use for the KST signal line.}\n\n\\item{maType}{Either:\n\\enumerate{\n  \\item A function or a string naming the function to be called.\n  \\item A \\emph{list} with the first component like (1) above, and\n    additional parameters specified as \\emph{named} components.\n    See Examples.\n}}\n\n\\item{wts}{A vector the same length as \\code{n}, of the weight for each\nperiod (need not sum to one).}\n\n\\item{\\dots}{Other arguments to be passed to the \\code{maType} function in\ncase (1) above.}\n}\n\\value{\nA object of the same class as \\code{price} or a vector (if\n\\code{try.xts} fails) containing the Know Sure Thing values.\n}\n\\description{\nThe Know Sure Thing (KST) is a smooth, summed, rate of change indicator.\nDeveloped by Martin Pring.\n}\n\\details{\nFor each day (week, month, etc.), the KST calculates the ROC over several\nperiods.  Those ROCs are smoothed using the given moving averages, then\nmultiplied by their respective weighting values.  The resulting values are\nsummed for each day (month, week, etc.).\n}\n\\note{\nThe KST indicates bullish/bearish momentum as it crosses above/below\nits moving average.  Because the KST tends to lead price action, look for\ntrend confirmation in the price.\n\nThe default arguments are for the daily KST.  There is also the Long-Term\nKST, with arguments: \\code{n=c(9, 12, 18, 24)} - where the periods are\nmonths, not days - and the moving average periods are 6, 6, 6, and 9 months,\nrespectively.\n}\n\\examples{\n\n data(ttrc)\n kst <- KST(ttrc[,\"Close\"])\n\n kst4MA <- KST(ttrc[,\"Close\"],\n   maType=list(list(SMA),list(EMA),list(DEMA),list(WMA)))\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://web.archive.org/web/20110715112957/http://www.pring.com/movieweb/daily_kst.htm}\\cr\n\\url{https://web.archive.org/web/20100101162707/http://www.pring.com/movieweb/KST_MCM.htm}\\cr\n}\n\\seealso{\nSee \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\noptions; and note Warning section.  See \\code{\\link{ROC}} for the\nrate-of-change function.  See \\code{\\link{MACD}} for a generic oscillator.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/MACD.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/MACD.R\n\\name{MACD}\n\\alias{MACD}\n\\title{MACD Oscillator}\n\\usage{\nMACD(x, nFast = 12, nSlow = 26, nSig = 9, maType, percent = TRUE, ...)\n}\n\\arguments{\n\\item{x}{Object that is coercible to xts or matrix; usually price, but can be\nvolume, etc.}\n\n\\item{nFast}{Number of periods for fast moving average.}\n\n\\item{nSlow}{Number of periods for slow moving average.}\n\n\\item{nSig}{Number of periods for signal moving average.}\n\n\\item{maType}{Either:\n\\enumerate{\n  \\item A function or a string naming the function to be called.\n  \\item A \\emph{list} with the first component like (1) above, and\n    additional parameters specified as \\emph{named} components.\n    See Examples.\n}}\n\n\\item{percent}{logical; if \\code{TRUE}, the percentage difference between the\nfast and slow moving averages is returned, otherwise the difference between\nthe respective averages is returned.}\n\n\\item{\\dots}{Other arguments to be passed to the \\code{maType} function in\ncase (1) above.}\n}\n\\value{\nA object of the same class as \\code{x} or a matrix (if \\code{try.xts}\nfails) containing the columns:\n \\describe{\n  \\item{ macd }{ The price (volume, etc.) oscillator. }\n  \\item{ signal }{ The oscillator signal line (a moving average of the oscillator). }\n }\n}\n\\description{\nThe MACD was developed by Gerald Appel and is probably the most popular price\noscillator.  The MACD function documented in this page compares a fast moving\naverage (MA) of a series with a slow MA of the same series.  It can be used\nas a generic oscillator for any univariate series, not only price.\n}\n\\details{\nThe MACD function either subtracts the fast MA from the slow MA, or finds the\nrate of change between the fast MA and the slow MA.\n}\n\\note{\nThe MACD is a special case of the general oscillator applied to price.\nThe MACD can be used as a general oscillator applied to any series. Time\nperiods for the MACD are often given as 26 and 12, but the original formula\nused exponential constants of 0.075 and 0.15, which are closer to\n25.6667 and 12.3333 periods.\n}\n\\examples{\n\n data(ttrc)\n\n macd  <- MACD( ttrc[,\"Close\"], 12, 26, 9, maType=\"EMA\" )\n macd2 <- MACD( ttrc[,\"Close\"], 12, 26, 9,\n          maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA)) )\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\n\\cr Moving Average Convergence/Divergence (MACD):\\cr\n\\url{https://www.fmlabs.com/reference/MACD.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=66}\\cr\n\\url{https://www.linnsoft.com/techind/macd}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:moving_average_convergence_divergence_macd}\\cr\n\\cr Price Oscillator:\\cr\n\\url{https://www.fmlabs.com/reference/PriceOscillator.htm}\\cr\n\\url{https://www.fmlabs.com/reference/PriceOscillatorPct.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=94}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:price_oscillators_ppo}\\cr\n\\cr Volume Oscillator:\\cr\n\\url{https://www.fmlabs.com/reference/PVO.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=122}\\cr\n}\n\\seealso{\nSee \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\noptions; and note Warning section.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/MFI.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/MFI.R\n\\name{MFI}\n\\alias{MFI}\n\\alias{moneyFlow}\n\\title{Money Flow Index}\n\\usage{\nMFI(HLC, volume, n = 14)\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices.  If only a univariate series is given, it will be\nused.  See details.}\n\n\\item{volume}{Vector or matrix of volume observations corresponding to\n\\code{HLC} object.}\n\n\\item{n}{Number of periods to use.}\n}\n\\value{\nA object of the same class as \\code{HLC} and \\code{volume} or a\nvector (if \\code{try.xts} fails) containing the MFI values.\n}\n\\description{\nThe MFI is a ratio of positive and negative money flow over time.\n}\n\\details{\nMoney Flow (MF) is the product of price and volume.  Positive/negative MF\noccur when today's price is higher/lower than yesterday's price.  The MFI is\ncalculated by dividing positive MF by negative MF for the past \\code{n}\nperiods.  It is then scaled between 0 and 100.\n\nMFI is usually calculated using the typical price, but if a univariate series\n(e.g. Close, Weighted Close, Median Price, etc.) is provided, it will be used\ninstead.\n}\n\\note{\nDivergence between MFI and price can be indicative of a reversal.  In\naddition, values above/below 80/20 indicate market tops/bottoms.\n}\n\\examples{\n\n data(ttrc)\n mfi <- MFI(ttrc[,c(\"High\",\"Low\",\"Close\")], ttrc[,\"Volume\"])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://www.fmlabs.com/reference/default.htm?url=MoneyFlowIndex.htm}\\cr\n\\url{https://www.linnsoft.com/techind/money-flow-index-mfi}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:money_flow_index_mfi}\\cr\n}\n\\seealso{\nSee \\code{\\link{OBV}} and \\code{\\link{CMF}}.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/MovingAverages.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/MovingAverages.R\n\\name{SMA}\n\\alias{SMA}\n\\alias{MovingAverages}\n\\alias{EMA}\n\\alias{WMA}\n\\alias{DEMA}\n\\alias{GD}\n\\alias{T3}\n\\alias{EVWMA}\n\\alias{ZLEMA}\n\\alias{VWAP}\n\\alias{VWMA}\n\\alias{MA}\n\\alias{HMA}\n\\alias{ALMA}\n\\title{Moving Averages}\n\\usage{\nSMA(x, n = 10, ...)\n\nEMA(x, n = 10, wilder = FALSE, ratio = NULL, ...)\n\nDEMA(x, n = 10, v = 1, wilder = FALSE, ratio = NULL)\n\nWMA(x, n = 10, wts = 1:n, ...)\n\nEVWMA(price, volume, n = 10, ...)\n\nZLEMA(x, n = 10, ratio = NULL, ...)\n\nVWAP(price, volume, n = 10, ...)\n\nHMA(x, n = 20, ...)\n\nALMA(x, n = 9, offset = 0.85, sigma = 6, ...)\n}\n\\arguments{\n\\item{x}{Price, volume, etc. series that is coercible to xts or matrix.}\n\n\\item{n}{Number of periods to average over. Must be between 1 and\n\\code{nrow(x)}, inclusive.}\n\n\\item{\\dots}{any other passthrough parameters}\n\n\\item{wilder}{logical; if \\code{TRUE}, a Welles Wilder type EMA will be\ncalculated; see notes.}\n\n\\item{ratio}{A smoothing/decay ratio.  \\code{ratio} overrides \\code{wilder}\nin \\code{EMA}.}\n\n\\item{v}{The 'volume factor' (a number in [0,1]).  See Notes.}\n\n\\item{wts}{Vector of weights.  Length of \\code{wts} vector must equal the\nlength of \\code{x}, or \\code{n} (the default).}\n\n\\item{price}{Price series that is coercible to xts or matrix.}\n\n\\item{volume}{Volume series that is coercible to xts or matrix, that\ncorresponds to price series, or a constant.  See Notes.}\n\n\\item{offset}{Percentile at which the center of the distribution should occur.}\n\n\\item{sigma}{Standard deviation of the distribution.}\n}\n\\value{\nA object of the same class as \\code{x} or \\code{price} or a vector\n(if \\code{try.xts} fails) containing the columns:\n \\describe{\n    \\item{SMA}{ Simple moving average. }\n    \\item{EMA}{ Exponential moving average. }\n    \\item{WMA}{ Weighted moving average. }\n    \\item{DEMA}{ Double-exponential moving average. }\n    \\item{EVWMA}{ Elastic, volume-weighted moving average. }\n    \\item{ZLEMA}{ Zero lag exponential moving average. }\n    \\item{VWMA}{ Volume-weighed moving average (same as \\code{VWAP}). }\n    \\item{VWAP}{ Volume-weighed average price (same as \\code{VWMA}). }\n    \\item{VWA}{ Variable-length moving average. }\n    \\item{HMA}{ Hull moving average. }\n    \\item{ALMA}{ Arnaud Legoux moving average. }\n }\n}\n\\description{\nCalculate various moving averages (MA) of a series.\n}\n\\details{\n\\code{SMA} calculates the arithmetic mean of the series over the past\n\\code{n} observations.\n\n\\code{EMA} calculates an exponentially-weighted mean, giving more weight to\nrecent observations.  See Warning section below.\n\n\\code{WMA} is similar to an EMA, but with linear weighting if the length of\n\\code{wts} is equal to \\code{n}.  If the length of \\code{wts} is equal to the\nlength of \\code{x}, the WMA will use the values of \\code{wts} as weights.\n\n\\code{DEMA} is calculated as: \\code{DEMA = (1 + v) * EMA(x,n) -\nEMA(EMA(x,n),n) * v} (with the corresponding \\code{wilder} and \\code{ratio}\narguments).\n\n\\code{EVWMA} uses volume to define the period of the MA.\n\n\\code{ZLEMA} is similar to an EMA, as it gives more weight to recent\nobservations, but attempts to remove lag by subtracting data prior to\n\\code{(n-1)/2} periods (default) to minimize the cumulative effect.\n\n\\code{VWMA} and \\code{VWAP} calculate the volume-weighted moving average\nprice.\n\n\\code{HMA} a WMA of the difference of two other WMAs, making it very\nreponsive.\n\n\\code{ALMA} inspired by Gaussian filters. Tends to put less weight on most\nrecent observations, reducing tendency to overshoot.\n}\n\\note{\nFor \\code{EMA}, \\code{wilder=FALSE} (the default) uses an exponential\nsmoothing ratio of \\code{2/(n+1)}, while \\code{wilder=TRUE} uses Welles\nWilder's exponential smoothing ratio of \\code{1/n}. The \\code{EMA} result\nis initialized with the \\code{n}-period sample average at period \\code{n}.\nThe exponential decay is applied from that point forward.\n\nSince \\code{WMA} can accept a weight vector of length equal to the length of\n\\code{x} or of length \\code{n}, it can be used as a regular weighted moving\naverage (in the case \\code{wts=1:n}) or as a moving average weighted by\nvolume, another indicator, etc.\n\nSince \\code{DEMA} allows adjusting \\code{v}, it is technically Tim Tillson's\ngeneralized DEMA (GD).  When \\code{v=1} (the default), the result is the\nstandard DEMA.  When \\code{v=0}, the result is a regular EMA.  All other\nvalues of \\code{v} return the GD result.  This function can be used to\ncalculate Tillson's T3 indicator (see example below).  Thanks to John Gavin\nfor suggesting the generalization.\n\nFor \\code{EVWMA}, if \\code{volume} is a series, \\code{n} should be chosen so\nthe sum of the volume for \\code{n} periods approximates the total number of\noutstanding shares for the security being averaged.  If \\code{volume} is a\nconstant, it should represent the total number of outstanding shares for the\nsecurity being averaged.\n}\n\\section{Warning }{\n Some indicators (e.g. EMA, DEMA, EVWMA, etc.) are\ncalculated using the indicators' own previous values, and are therefore\nunstable in the short-term.  As the indicator receives more data, its output\nbecomes more stable.  See example below.\n}\n\n\\examples{\n\n data(ttrc)\n ema.20 <-   EMA(ttrc[,\"Close\"], 20)\n sma.20 <-   SMA(ttrc[,\"Close\"], 20)\n dema.20 <-  DEMA(ttrc[,\"Close\"], 20)\n evwma.20 <- EVWMA(ttrc[,\"Close\"], ttrc[,\"Volume\"], 20)\n zlema.20 <- ZLEMA(ttrc[,\"Close\"], 20)\n alma <- ALMA(ttrc[,\"Close\"])\n hma <- HMA(ttrc[,\"Close\"])\n\n ## Example of Tim Tillson's T3 indicator\n T3 <- function(x, n=10, v=1) DEMA(DEMA(DEMA(x,n,v),n,v),n,v)\n t3 <- T3(ttrc[,\"Close\"])\n\n ## Example of short-term instability of EMA\n ## (and other indicators mentioned above)\n x <- rnorm(100)\n tail( EMA(x[90:100],10), 1 )\n tail( EMA(x[70:100],10), 1 )\n tail( EMA(x[50:100],10), 1 )\n tail( EMA(x[30:100],10), 1 )\n tail( EMA(x[10:100],10), 1 )\n tail( EMA(x[ 1:100],10), 1 )\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://www.fmlabs.com/reference/ExpMA.htm}\\cr\n\\url{https://www.fmlabs.com/reference/WeightedMA.htm}\\cr\n\\url{https://www.fmlabs.com/reference/DEMA.htm}\\cr\n\\url{https://www.fmlabs.com/reference/T3.htm}\\cr\n\\url{https://www.linnsoft.com/techind/evwma-elastic-volume-weighted-moving-average}\\cr\n\\url{https://www.fmlabs.com/reference/ZeroLagExpMA.htm}\\cr\n\\url{https://www.fmlabs.com/reference/VIDYA.htm}\\cr\n\\url{https://www.traderslog.com/hullmovingaverage}\\cr\n\\url{https://web.archive.org/web/20180222085959/http://arnaudlegoux.com/}\\cr\n}\n\\seealso{\nSee \\code{\\link{wilderSum}}, which is used in calculating a Welles\nWilder type MA.\n}\n\\author{\nJoshua Ulrich, Ivan Popivanov (HMA, ALMA)\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/OBV.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/OBV.R\n\\name{OBV}\n\\alias{OBV}\n\\title{On Balance Volume (OBV)}\n\\usage{\nOBV(price, volume)\n}\n\\arguments{\n\\item{price}{Price series that is coercible to xts or matrix.}\n\n\\item{volume}{Volume series that is coercible to xts or matrix, that\ncorresponds to price object.}\n}\n\\value{\nA object of the same class as \\code{price} and \\code{volume} or a\nvector (if \\code{try.xts} fails) containing the OBV values.\n}\n\\description{\nOn Balance Volume (OBV) is a measure of the money flowing into or out of a\nsecurity.  It is similar to Chaikin Accumulation / Distribution.\n}\n\\details{\nOBV is calculated by adding (subtracting) each day's volume to a running\ncumulative total when the security's price closes higher (lower).\n}\n\\note{\nOBV is usually compared with the price chart of the underlying security\nto look for divergences/confirmation.\n}\n\\examples{\n\n data(ttrc)\n obv <- OBV(ttrc[,\"Close\"], ttrc[,\"Volume\"])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://www.fmlabs.com/reference/OBV.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=82}\\cr\n\\url{https://www.linnsoft.com/techind/balance-open-interest}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:on_balance_volume_obv}\\cr\n}\n\\seealso{\nSee \\code{\\link{chaikinAD}}.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/RSI.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/RSI.R\n\\name{RSI}\n\\alias{RSI}\n\\title{Relative Strength Index}\n\\usage{\nRSI(price, n = 14, maType, ...)\n}\n\\arguments{\n\\item{price}{Price series that is coercible to xts or matrix.}\n\n\\item{n}{Number of periods for moving averages.}\n\n\\item{maType}{Either:\n\\enumerate{\n  \\item A function or a string naming the function to be called.\n  \\item A \\emph{list} with the first component like (1) above, and\n    additional parameters specified as \\emph{named} components.\n    See Examples.\n}}\n\n\\item{\\dots}{Other arguments to be passed to the \\code{maType} function in\ncase (1) above.}\n}\n\\value{\nA object of the same class as \\code{price} or a vector (if\n\\code{try.xts} fails) containing the RSI values.\n}\n\\description{\nThe Relative Strength Index (RSI) calculates a ratio of the recent upward\nprice movements to the absolute price movement.  Developed by J. Welles\nWilder.\n}\n\\details{\nThe RSI calculation is \\code{RSI = 100 - 100 / ( 1 + RS )}, where \\code{RS}\nis the smoothed ratio of 'average' gains over 'average' losses.  The\n'averages' aren't true averages, since they're divided by the value of\n\\code{n} and not the number of periods in which there are  gains/losses.\n}\n\\note{\nThe RSI is usually interpreted as an overbought/oversold (over 70 /\nbelow 30) indicator.  Divergence with price may also be useful.  For example,\nif price is making new highs/lows, but RSI is not, it could indicate a\nreversal.\n\nYou can calculate a stochastic RSI by using the function \\code{\\link{stoch}}\non RSI values.\n}\n\\examples{\n\n data(ttrc)\n price <- ttrc[,\"Close\"]\n\n # Default case\n rsi <- RSI(price)\n\n # Case of one 'maType' for both MAs\n rsiMA1 <- RSI(price, n=14, maType=\"WMA\", wts=ttrc[,\"Volume\"])\n\n # Case of two different 'maType's for both MAs\n rsiMA2 <- RSI(price, n=14, maType=list(maUp=list(EMA),maDown=list(WMA)))\n\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\n\\cr Relative Strength Index:\\cr\n\\url{https://www.fmlabs.com/reference/RSI.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=100}\\cr\n\\url{https://www.linnsoft.com/techind/relative-strength-index-rsi}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:relative_strength_index_rsi}\\cr\n\\cr Stochastic RSI:\\cr\n\\url{https://www.fmlabs.com/reference/StochRSI.htm}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:stochrsi}\\cr\n}\n\\seealso{\nSee \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\noptions; and note Warning section.  See \\code{\\link{CMO}} for a variation on\nRSI.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/SAR.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/SAR.R\n\\name{SAR}\n\\alias{SAR}\n\\title{Parabolic Stop-and-Reverse}\n\\usage{\nSAR(HL, accel = c(0.02, 0.2))\n}\n\\arguments{\n\\item{HL}{Object that is coercible to xts or matrix and contains High-Low\nprices.}\n\n\\item{accel}{accel[1]: Acceleration factor.\\cr accel[2]: Maximum acceleration\nfactor.}\n}\n\\value{\nA object of the same class as \\code{HL} or a vector (if\n\\code{try.xts} fails) containing the Parabolic Stop and Reverse values.\n}\n\\description{\nThe Parabolic Stop-and-Reverse calculates a trailing stop.  Developed by J.\nWelles Wilder.\n}\n\\details{\nThe calculation for the SAR is quite complex.  See the URLs in the references\nsection for calculation notes.\n\nThe SAR assumes that you are always in the market, and calculates the Stop\nAnd Reverse point when you would close a long position and open a short\nposition or vice versa.\n}\n\\examples{\n\n data(ttrc)\n sar <- SAR(ttrc[,c(\"High\",\"Low\")])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://www.linnsoft.com/techind/parabolic-sar-sar}\\cr\n\\url{https://www.fmlabs.com/reference/SAR.htm}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:parabolic_sar}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=87}\n}\n\\seealso{\nSee \\code{\\link{ATR}} and \\code{\\link{ADX}}, which were also\ndeveloped by Welles Wilder.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/SNR.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/SNR.R\n\\name{SNR}\n\\alias{SNR}\n\\title{Signal to Noise Ratio}\n\\usage{\nSNR(HLC, n, ...)\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices.}\n\n\\item{n}{Number of periods for moving average.}\n\n\\item{...}{Other arguments to be passed to \\code{\\link{ATR}}.}\n}\n\\value{\nA object of the same class as HLC or a matrix (if try.xts fails)\ncontaining the signal to noise ratio.\n}\n\\description{\nThe n-day SNR for a given market is calculated by taking the absolute\nprice change over an n-day period and dividing it by the average\nn-day volatility.\n}\n\\details{\n\\deqn{SNR_n = \\frac{|C_t - C_{t-n}|}{ATR_n}\n}{SNR = abs(Cl - lag(Cl,n)) / ATR(HLC, n)$atr}\n\nUsing average true range as the volatility measure captures more of the\nintraday and overnight volatility in a way that a measurement of\nClose-to-Close price change does not.\n\nThe interpretation is then relatively intuitive: an SNR value of five\nindicates that the market has moved five times the volatility (average true\nrange) over the given look-back period.\n}\n\\references{\nSkeggs, James and Hill, Alex (2015). Back in Black Part 2: The\nOpportunity Set for Trend Following.\n}\n\\author{\nPeter Carl\n}\n"
  },
  {
    "path": "man/TDI.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/TDI.R\n\\name{TDI}\n\\alias{TDI}\n\\title{Trend Detection Index}\n\\usage{\nTDI(price, n = 20, multiple = 2)\n}\n\\arguments{\n\\item{price}{Price series that is coercible to xts or matrix.}\n\n\\item{n}{Number of periods to use.}\n\n\\item{multiple}{Multiple used to calculate (2).}\n}\n\\value{\nA object of the same class as \\code{price} or a matrix (if\n\\code{try.xts} fails) containing the columns:\n \\describe{\n  \\item{ tdi }{ The Trend Detection Index. }\n  \\item{ di }{ The Direction Indicator. }\n }\n}\n\\description{\nThe Trend Detection Index (TDI) attempts to identify starting and ending\ntrends.  Developed by M. H. Pee.\n}\n\\details{\nThe TDI is the (1) absolute value of the \\code{n}-day sum of the \\code{n}-day\nmomentum, minus the quantity of (2) \\code{multiple}*\\code{n}-day sum of the\nabsolute value of the \\code{n}-day momentum, minus (3) \\code{n}-day sum of\nthe absolute value of the \\code{n}-day momentum.\n\nI.e. TDI = (1) - [ (2) - (3) ]\n\nThe direction indicator is the sum of the \\code{n}-day momentum over the last\n\\code{n} days.\n\nSee URL in references section for further details.\n}\n\\note{\nPositive/negative TDI values signal a trend/consolidation.  A positive/\nnegative direction indicator signals a up/down trend.  I.e. buy if the TDI\nand the direction indicator are positive, and sell if the TDI is positive\nwhile the direction indicator is negative.\n}\n\\examples{\n\n data(ttrc)\n tdi <- TDI(ttrc[,\"Close\"], n=30)\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://www.linnsoft.com/techind/trend-detection-index-tdi}\\cr\n}\n\\seealso{\nSee \\code{\\link{aroon}}, \\code{\\link{CCI}}, \\code{\\link{ADX}},\n\\code{\\link{VHF}}, \\code{\\link{GMMA}} for other indicators that measure trend\ndirection/strength.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/TRIX.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/TRIX.R\n\\name{TRIX}\n\\alias{TRIX}\n\\title{Triple Smoothed Exponential Oscillator}\n\\usage{\nTRIX(price, n = 20, nSig = 9, maType, percent = TRUE, ...)\n}\n\\arguments{\n\\item{price}{Price series that is coercible to xts or matrix.}\n\n\\item{n}{Number of periods for moving average.}\n\n\\item{nSig}{Number of periods for signal line moving average.}\n\n\\item{maType}{Either:\n\\enumerate{\n  \\item A function or a string naming the function to be called.\n  \\item A \\emph{list} with the first component like (1) above, and\n    additional parameters specified as \\emph{named} components.\n    See Examples.\n}}\n\n\\item{percent}{logical; if \\code{TRUE}, the rate of change is calculated\nusing the \\code{ROC} function, otherwise the \\code{momentum} function is\nused.}\n\n\\item{\\dots}{Other arguments to be passed to the \\code{maType} function in\ncase (1) above.}\n}\n\\value{\nA object of the same class as \\code{price} or a vector (if\n\\code{try.xts} fails) containing the TRIX values.\n}\n\\description{\nThe TRIX indicator calculates the rate of change of a triple exponential\nmoving average.  Developed by Jack K. Hutson.\n}\n\\details{\nThe TRIX is calculated as follows:\\cr 3MA = \\code{MA}( \\code{MA}(\n\\code{MA}(\\code{price}) ) )\\cr trix = 100 * [ 3MA(t) / 3MA(t-1) - 1 ]\n}\n\\note{\nBuy/sell signals are generated when the TRIX crosses above/below zero.\nA nine-period EMA of the TRIX is used as a default signal line.  Buy/sell\nsignals are generated when the TRIX crosses above/below the signal line and\nis also above/below zero.\n}\n\\examples{\n\n data(ttrc)\n trix  <- TRIX(ttrc[,\"Close\"])\n trix4 <- TRIX(ttrc[,\"Close\"],\n maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA), list(DEMA)))\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://www.fmlabs.com/reference/default.htm?url=TRIX.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=114}\\cr\n\\url{https://www.linnsoft.com/techind/trix-triple-smoothed-exponential-oscillator}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:trix}\\cr\n}\n\\seealso{\nSee \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\noptions; and note Warning section.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/TTR.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/TTR-package.R\n\\docType{package}\n\\name{TTR}\n\\alias{TTR}\n\\alias{TTR-package}\n\\title{Functions to create Technical Trading Rules (TTR)}\n\\description{\nThis package contains many of the most popular technical analysis functions,\nas well as functions to retrieve U.S. stock symbols, and data from Yahoo\nFinance.\n}\n\\details{\nUsers will probably be most interested in the following functions:\\cr\n\\code{\\link{ADX}}\\cr \\code{\\link{BBands}}\\cr \\code{\\link{changes}}\\cr\n\\code{\\link{MovingAverages}}\\cr \\code{\\link{MACD}}\\cr \\code{\\link{RSI}}\\cr\n\\code{\\link{runFun}}\\cr \\code{\\link{stoch}}\\cr \\code{\\link{VWAP}}\\cr\n\\code{\\link{WebData}}\\cr\n}\n\\examples{\n\n data(ttrc)\n\n # Bollinger Bands\n bbands <- BBands( ttrc[,c(\"High\",\"Low\",\"Close\")] )\n\n # Directional Movement Index\n adx <- ADX(ttrc[,c(\"High\",\"Low\",\"Close\")])\n\n # Moving Averages\n ema <- EMA(ttrc[,\"Close\"], n=20)\n sma <- SMA(ttrc[,\"Close\"], n=20)\n\n # MACD\n macd <- MACD( ttrc[,\"Close\"] )\n\n # RSI\n rsi <- RSI(ttrc[,\"Close\"])\n\n # Stochastics\n stochOsc <- stoch(ttrc[,c(\"High\",\"Low\",\"Close\")])\n\n ### Note: you must have a working internet connection\n ### for the examples below to work!\n if (interactive()) {\n   # Fetch U.S. symbols from the internet\n   nyseSymbols <- stockSymbols(\"NYSE\")\n\n   # Fetch Yahoo! Finance data from the internet\n   ge <- getYahooData(\"GE\", 19990404, 20050607, adjust = FALSE)\n }\n\n}\n\\references{\nThe following sites were used to code/document this package:\\cr\n\\url{https://www.fmlabs.com/reference/default.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/}\\cr\n\\url{https://www.linnsoft.com/indicators}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators}\\cr\n}\n\\seealso{\nUseful links:\n\\itemize{\n  \\item \\url{https://github.com/joshuaulrich/TTR}\n  \\item Report bugs at \\url{https://github.com/joshuaulrich/TTR/issues}\n}\n\n}\n\\author{\nJoshua Ulrich\n\nMaintainer: Joshua Ulrich\n}\n\\keyword{package}\n"
  },
  {
    "path": "man/TTRtools.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/TTRtools.R\n\\name{lags}\n\\alias{lags}\n\\alias{growth}\n\\alias{naCheck}\n\\title{Miscellaneous Tools}\n\\usage{\nlags(x, n = 1)\n\ngrowth(price, signals, ...)\n\nnaCheck(x, n = 0)\n}\n\\arguments{\n\\item{x}{Object that is coercible to xts or matrix.}\n\n\\item{n}{Number of periods to use.}\n\n\\item{price}{Price series that is coercible to xts or matrix.}\n\n\\item{signals}{Signals to use (defaults to vector of ones).  Use '0' for no\nposition, '1' for long position, and '-1' for short position.}\n\n\\item{\\dots}{Further arguments to be passed from or to other methods.}\n}\n\\value{\n\\code{growth} returns a vector of the growth of the investment.\n\n\\code{lags} returns a matrix of lagged values of the original vector.\n}\n\\description{\nVarious functions that may be useful in designing technical trading rules.\n}\n\\details{\n\\code{growth} calculates the growth of an investment using given prices and\nsignals.\n\n\\code{lags} calculates the lags of a given series.\n}\n\\note{\nIn \\code{growth} you can specify the number of periods and type of\ncompounding to use when calculating returns of the price series via the\n\\code{'\\dots'} argument.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/VHF.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/VHF.R\n\\name{VHF}\n\\alias{VHF}\n\\title{Vertical Horizontal Filter}\n\\usage{\nVHF(price, n = 28)\n}\n\\arguments{\n\\item{price}{Object that is coercible to xts or matrix and contains a Close\nprice series, or a High-Low-Close price series.}\n\n\\item{n}{Number of periods to use.}\n}\n\\value{\nA object of the same class as \\code{price} or a vector (if\n\\code{try.xts} fails) containing the VHF values.\n}\n\\description{\nThe Vertical Horizontal Filter (VHF) attempts to identify starting and ending\ntrends.  Developed by Adam White.\n}\n\\details{\nThe VHF is calculated by subtracting the \\code{n}-period lowest low from the\n\\code{n}-period highest high and dividing that result by the \\code{n}-period\nrolling sum of the close price changes.\n}\n\\note{\nIf Close prices are given, the function calculates the max/min using\nonly those prices (the default).  If HLC prices are given, the function\ncalculates the max/min using the high/low prices (added for flexibility).\n}\n\\examples{\n\n data(ttrc)\n vhf.close <- VHF(ttrc[,\"Close\"])\n vhf.hilow <- VHF(ttrc[,c(\"High\",\"Low\",\"Close\")])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=119}\\cr\n}\n\\seealso{\nSee \\code{\\link{aroon}}, \\code{\\link{CCI}}, \\code{\\link{ADX}},\n\\code{\\link{TDI}}, \\code{\\link{GMMA}} for other indicators that measure trend\ndirection/strength.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/WPR.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/WPR.R\n\\name{WPR}\n\\alias{WPR}\n\\title{William's \\%R}\n\\usage{\nWPR(HLC, n = 14, scale = FALSE)\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices.  If only a univariate series is given, it will be\nused.  See details.}\n\n\\item{n}{Number of periods to use.}\n\n\\item{scale}{Scale the result to be between 0 and -100.}\n}\n\\value{\nA object of the same class as \\code{HLC} or a vector (if\n\\code{try.xts} fails) containing the William's \\%R values.\n}\n\\description{\nWilliam's \\% R.\n}\n\\details{\nIf an High-Low-Close series is provided, the indicator is calculated using\nthe high/low values.  If a vector is provided, the calculation only uses that\nseries.\n}\n\\note{\nThe William's \\%R calculation is similar to stochastics' fast \\%K,\nand the result of \\code{WPR} is equal to \\code{1-fastK}.\n\nThe value for William's \\%R will be 0.5 whenever the highest high and\nlowest low are the same over the last \\code{n} periods.\n\nWilliam's \\%R is usually scaled to be between 0 and -100, which is not what\n\\code{WPR} returns by default. Set \\code{scale = TRUE} to return the result\nwith the usual scaling.\n}\n\\examples{\n\n data(ttrc)\n hlc <- ttrc[,c(\"High\",\"Low\",\"Close\")]\n stochOsc <- stoch(hlc)\n stochWPR <- WPR(hlc)\n\n # WPR is a transformation of stochastics' fastK\n all.equal(stochWPR, 1-stochOsc[,'fastK'])  # TRUE\n\n # WPR converted to the usual scaling between 0 and -100\n scaledWPR <- WPR(hlc, scale=TRUE)\n\n plot(tail(stochOsc[,\"fastK\"], 100), type=\"l\",\n     main=\"Fast \\%K and Williams \\%R\", ylab=\"\",\n     ylim=range(cbind(stochOsc, stochWPR), na.rm=TRUE) )\n lines(tail(stochWPR, 100), col=\"blue\")\n lines(tail(1-stochWPR, 100), col=\"red\", lty=\"dashed\")\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://www.fmlabs.com/reference/WilliamsR.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=126}\\cr\n\\url{https://www.linnsoft.com/techind/williams-r-wpr}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:williams_r}\\cr\n}\n\\seealso{\nSee \\code{\\link{stoch}}.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/WebData.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/WebData.R\n\\name{stockSymbols}\n\\alias{stockSymbols}\n\\alias{WebData}\n\\alias{getYahooData}\n\\title{Fetch Internet Data}\n\\usage{\nstockSymbols(\n  exchange = c(\"AMEX\", \"NASDAQ\", \"NYSE\", \"ARCA\", \"BATS\", \"IEX\"),\n  sort.by = c(\"Exchange\", \"Symbol\"),\n  quiet = FALSE\n)\n\ngetYahooData(\n  symbol,\n  start,\n  end,\n  freq = \"daily\",\n  type = \"price\",\n  adjust = TRUE,\n  quiet = FALSE\n)\n}\n\\arguments{\n\\item{exchange}{Character vector of exchange names on which desired\ninstrument symbols are traded.}\n\n\\item{sort.by}{Character vector of columns by which returned data will be\nsorted.  Must be one or more of \\code{\"Name\"}, \\code{\"Symbol\"},\n\\code{\"Market.Cap\"}, or \\code{\"Exchange\"}.}\n\n\\item{quiet}{Logical; if \\code{TRUE}, status messages will be printed to the\nconsole.}\n\n\\item{symbol}{Yahoo! Finance instrument symbol.}\n\n\\item{start}{Numeric; first date of desired data, in YYYYMMDD format.\nDefault is first date of series.}\n\n\\item{end}{Numeric; last date of desired data, in YYYYMMDD format.  Default\nis last date of series.}\n\n\\item{freq}{Desired data frequency.  One of \\code{\"daily\"}, \\code{\"weekly\"},\n\\code{\"monthly\"}.}\n\n\\item{type}{Type of data to return.  One of \\code{\"price\"}, or\n\\code{\"split\"}.  \\code{type=\"split\"} will return both split and dividend\ndata.}\n\n\\item{adjust}{Logical; if \\code{TRUE}, the Open, High, Low, and Close prices\nwill be adjusted for dividends and splits, and Volume will be adjusted for\ndividends.}\n}\n\\value{\n\\code{getYahooData} returns an xts object containing the columns:\n\n\\code{stockSymbols} returns a character vector containing all the listed\nsymbols for the given exchanges.\n \\describe{\n    \\item{ Date }{ Trade date, in CCYYMMDD format. }\n    \\item{ Open }{ Open price. }\n    \\item{ High }{ High price. }\n    \\item{ Low }{ Low price. }\n    \\item{ Close }{ Close price. }\n    \\item{ Volume }{ Volume. }\n }\n}\n\\description{\nGet investment data from the internet.\n}\n\\details{\n\\code{getYahooData} fetches individual stock data from the Yahoo! Finance\nwebsite.  It also adjusts price for splits and dividends, and volume for\nsplits.  See the Warning section, and note that it is deprecated in favor\nof getSymbols in the quantmod package.\n\n\\code{stockSymbols} fetches instrument symbols from the nasdaq.com website,\nand adjusts the symbols to be compatible with the Yahoo! Finance website.\n}\n\\note{\nThe symbols returned by \\code{stockSymbols} may not be in the format\nnecessary to retrieve data using \\code{getYahooData}.\n\n\\code{getYahooData} has only been tested on daily data.  It isn't known if\nthe function correctly adjusts data for any other frequency.\n}\n\\section{Warning}{\n\nAs of TTR 0.23-2, \\code{getYahooData} has been patched to work with changes\nto Yahoo Finance, which also included the following changes to the raw data:\n  \\itemize{\n    \\item The adjusted close column appears to no longer include dividend adjustments\n    \\item The open, high, and low columns are adjusted for splits, and\n    \\item The raw data may contain missing values.\n    \\item The raw data may contain errors.\n  }\n\nAs of TTR 0.24.2, \\code{stockSymbols} began using data from NASDAQ's FTP\nsite because the data from the original site is no longer available. This\nnew file does not contain data for the columns: LastSale, MarketCap,\nIPOyear, Sector, and Industry. All the columns still appear in the results,#' but all the values in the columns are set to \\code{NA}.\n}\n\n\\examples{\n\n ### Note: you must have a working internet\n ### connection for these examples to work!\n if (interactive()) {\n   ge <- getYahooData(\"GE\", 19990404, 20050607, adjust = FALSE)\n\n   nyse.symbols <- stockSymbols(\"NYSE\")\n }\n\n}\n\\references{\n\\itemize{\n   \\item \\href{https://quant.stackexchange.com/questions/1640/where-to-download-list-of-all-common-stocks-traded-on-nyse-nasdaq-and-amex/1862}{Quant StackExchange: Download list of all stock symbols?}\n   \\item \\href{https://www.nasdaqtrader.com/trader.aspx?id=CQSsymbolconvention}{CQS symbol convention}\n   \\item \\href{https://web.archive.org/web/20111023221931/http://help.yahoo.com/l/us/yahoo/finance/quotes/quote-02.html}{Yahoo Finance symbol conventions}\n }\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/ZigZag.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/ZigZag.R\n\\name{ZigZag}\n\\alias{ZigZag}\n\\alias{zigzag}\n\\title{Zig Zag}\n\\usage{\nZigZag(HL, change = 10, percent = TRUE, retrace = FALSE, lastExtreme = TRUE)\n}\n\\arguments{\n\\item{HL}{Object that is coercible to xts or matrix and contains either a\nHigh-Low price series, or a Close price series.}\n\n\\item{change}{Minimum price movement, either in dollars or percent (see\n\\code{percent}).}\n\n\\item{percent}{Use percentage or dollar change?}\n\n\\item{retrace}{Is \\code{change} a retracement of the previous move, or an\nabsolute change from peak to trough?}\n\n\\item{lastExtreme}{If the extreme price is the same over multiple periods,\nshould the extreme price be the first or last observation?}\n}\n\\value{\nA object of the same class as \\code{HL} or a vector (if\n\\code{try.xts} fails) containing the Zig Zag indicator.\n}\n\\description{\nZig Zag higlights trends by removing price changes smaller than \\code{change}\nand interpolating lines between the extreme points.\n}\n\\details{\nThe Zig Zag is non-predictive.  The purpose of the Zig Zag is filter noise\nand make chart patterns clearer.  It's more a visual tool than an indicator.\n}\n\\note{\nIf High-Low prices are given, the function calculates the max/min using\nthe high/low prices.  Otherwise the function calculates the max/min of the\nsingle series.\n}\n\\section{Warning}{\n The last value of the ZigZag indicator is unstable (i.e.\nunknown) until the turning point actually occurs. Therefore this indicator\nisn't well-suited for use for systematic trading strategies.\n}\n\n\\examples{\n\n ## Get Data and Indicator ##\n data(ttrc)\n zz <- ZigZag( ttrc[,c(\"High\", \"Low\")], change=20 )\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://www.fmlabs.com/reference/default.htm?url=ZigZag.htm}\\cr\n\\url{https://www.linnsoft.com/techind/zig-zag-indicator-zig-zzo}\\cr\n\\url{https://www.linnsoft.com/techind/zig-zag-oscillator-indicator-zzo}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=127}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:zigzag}\\cr\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/adjRatios.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/adjRatios.R\n\\name{adjRatios}\n\\alias{adjRatios}\n\\alias{adjust}\n\\title{Split and dividend adjustment ratios}\n\\usage{\nadjRatios(splits, dividends, close)\n}\n\\arguments{\n\\item{splits}{Split series that is coercible to xts.}\n\n\\item{dividends}{Dividend series that is coercible to xts.}\n\n\\item{close}{Close price series that is coercible to xts.}\n}\n\\value{\nA xts object containing the columns:\n \\describe{\n   \\item{ Split }{ The split adjustment ratio. }\n   \\item{ Div }{ The dividend adjustment ratio. }\n }\n}\n\\description{\nCreate split and dividend adjustment ratio vectors.\n}\n\\details{\n\\itemize{\n   \\item If only \\code{splits} is provided, the resulting object will\n     only have as many observations as \\code{splits}.\n   \\item If \\code{splits} and \\code{close} are provided, the resulting\n     object will have as many observations as \\code{max(NROW(splits),\n     NROW(close))}.\n   \\item \\code{close} is required if \\code{dividends} is provided.\n }\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/aroon.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/aroon.R\n\\name{aroon}\n\\alias{aroon}\n\\title{Aroon}\n\\usage{\naroon(HL, n = 20)\n}\n\\arguments{\n\\item{HL}{Object that is coercible to xts or matrix and contains either a\nHigh-Low price series, or a Close price series.}\n\n\\item{n}{Number of periods to use in the calculation.}\n}\n\\value{\nA object of the same class as \\code{HL} or a matrix (if\n\\code{try.xts} fails) containing the columns:\n \\describe{\n  \\item{ aroonUp }{ The Aroon up indicator. }\n  \\item{ aroonDn }{ The Aroon down indicator. }\n  \\item{ oscillator }{ The Aroon oscillator (\\code{aroonUp - aroonDn}). }\n }\n}\n\\description{\nThe Aroon indicator attempts to identify starting trends.  The indicator\nconsists of up and down lines, which measure how long it has been since the\nhighest high/lowest low has occurred in the last \\code{n} periods.  Developed\nby Tushar Chande in 1995.\n}\n\\details{\nAroon up (down) is the elapsed time, expressed as a percentage, between today\nand the highest (lowest) price in the last \\code{n} periods.  If today's\nprice is a new high (low) Aroon up (down) will be 100. Each subsequent period\nwithout another new high (low) causes Aroon up (down) to decrease by (1 /\n\\code{n}) x 100.\n}\n\\note{\nIf High-Low prices are given, the function calculates the max/min using\nthe high/low prices.  Otherwise the function calculates the max/min of the\nsingle series.\n\nUp (down) trends are indicated when the aroonUp(Dn) is between 70 and 100.\nStrong trends are indicated when when the aroonUp(Dn) is above 70 while the\naroonDn(Up) is below 30.  Also, crossovers may be useful.\n}\n\\examples{\n\n ## Get Data and Indicator ##\n data(ttrc)\n trend <- aroon( ttrc[,c(\"High\", \"Low\")], n=20 )\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://www.fmlabs.com/reference/Aroon.htm}\\cr\n\\url{https://www.fmlabs.com/reference/AroonOscillator.htm}\\cr\n\\url{https://www.linnsoft.com/techind/aroon-arn}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:aroon}\\cr\n}\n\\seealso{\nSee \\code{\\link{CCI}}, \\code{\\link{ADX}}, \\code{\\link{TDI}},\n\\code{\\link{VHF}}, \\code{\\link{GMMA}} for other indicators that measure trend\ndirection/strength.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/bollingerBands.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/bollingerBands.R\n\\name{BBands}\n\\alias{BBands}\n\\alias{bollingerBands}\n\\title{Bollinger Bands}\n\\usage{\nBBands(HLC, n = 20, maType, sd = 2, ...)\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices.  If only a univariate series is given, it will be\nused.  See details.}\n\n\\item{n}{Number of periods for moving average.}\n\n\\item{maType}{A function or a string naming the function to be called.}\n\n\\item{sd}{The number of standard deviations to use.}\n\n\\item{\\dots}{Other arguments to be passed to the \\code{maType} function.}\n}\n\\value{\nA object of the same class as \\code{HLC} or a matrix (if\n\\code{try.xts} fails) containing the columns:\n \\describe{\n  \\item{ dn }{ The lower Bollinger Band. }\n  \\item{ mavg }{ The middle Moving Average (see notes). }\n  \\item{ up }{ The upper Bollinger Band. }\n  \\item{ pctB }{ The \\%B calculation. }\n }\n}\n\\description{\nBollinger Bands are a way to compare a security's volatility and price levels\nover a period of time.  Developed by John Bollinger.\n}\n\\details{\nBollinger Bands consist of three lines:\n\nThe middle band is generally a 20-period SMA of the typical price ([high +\nlow + close]/3).  The upper and lower bands are \\code{sd} standard deviations\n(generally 2) above and below the MA.\n\nThe middle band is usually calculated using the typical price, but if a\nunivariate series (e.g. Close, Weighted Close, Median Price, etc.) is\nprovided, it will be used instead.\n}\n\\note{\nUsing any moving average other than SMA will result in inconsistencies\nbetween the moving average calculation and the standard deviation\ncalculation.  Since, by definition, a rolling standard deviation uses a\nsimple moving average.\n}\n\\examples{\n\n ## The examples below show the differences between using a\n ## High-Low-Close series, and just a close series when\n ## calculating Bollinger Bands.\n data(ttrc)\n bbands.HLC <- BBands( ttrc[,c(\"High\",\"Low\",\"Close\")] )\n bbands.close <- BBands( ttrc[,\"Close\"] )\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://www.fmlabs.com/reference/Bollinger.htm}\\cr\n\\url{https://www.fmlabs.com/reference/BollingerWidth.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=36}\\cr\n\\url{https://www.linnsoft.com/techind/bollinger-bands}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:bollinger_bands}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:bollinger_band_width}\\cr\n}\n\\seealso{\nSee \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\noptions; and note Warning section.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/chaikinAD.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/chaikinAD.R\n\\name{chaikinAD}\n\\alias{chaikinAD}\n\\title{Chaikin Accumulation / Distribution}\n\\usage{\nchaikinAD(HLC, volume)\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices.}\n\n\\item{volume}{Vector or matrix of volume observations corresponding to the\n\\code{HLC} object.}\n}\n\\value{\nA object of the same class as \\code{HLC} and \\code{volume} or a\nvector (if \\code{try.xts} fails) containing the accumulation / distribution\nvalues.\n}\n\\description{\nThe Chaikin Accumulation / Distribution (AD) line is a measure of the money\nflowing into or out of a security.  It is similar to On Balance Volume (OBV).\nDeveloped by Marc Chaikin.\n}\n\\details{\nThe AD line is similar to OBV; the difference is that OBV sums volume\nmultiplied by +/- 1 if the close is higher/lower than the previous close,\nwhile the AD line multiplies volume by the close location value (CLV).\n}\n\\note{\nThe Accumulation/Distribution Line is interpreted by looking for a\ndivergence in the direction of the indicator relative to price.\n}\n\\examples{\n\n data(ttrc)\n ad <- chaikinAD(ttrc[,c(\"High\",\"Low\",\"Close\")], ttrc[,\"Volume\"])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://www.fmlabs.com/reference/AccumDist.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=27}\\cr\n\\url{https://www.linnsoft.com/techind/accumulation-distribution}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:accumulation_distribution_line}\\cr\n}\n\\seealso{\nSee \\code{\\link{OBV}}, and \\code{\\link{CLV}}.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/chaikinVolatility.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/chaikinVolatility.R\n\\name{chaikinVolatility}\n\\alias{chaikinVolatility}\n\\title{Chaikin Volatility}\n\\usage{\nchaikinVolatility(HL, n = 10, maType, ...)\n}\n\\arguments{\n\\item{HL}{Object that is coercible to xts or matrix and contains High-Low\nprices.}\n\n\\item{n}{Number of periods for moving average.}\n\n\\item{maType}{A function or a string naming the function to be called.}\n\n\\item{\\dots}{Other arguments to be passed to the \\code{maType} function.}\n}\n\\value{\nA object of the same class as \\code{HL} or a vector (if\n\\code{try.xts} fails) containing the Chaikin Volatility values.\n}\n\\description{\nChaikin Volatility measures the rate of change of the security's trading\nrange.  Developed by Marc Chaikin.\n}\n\\details{\nThe Chaikin Volatility indicator defines volatility as an increase in the\ndifference between the high and low.\n}\n\\note{\nA rapid increase in Chaikin Volatility indicates an approaching bottom.\nA slow decrease in Chaikin Volatility indicates an approaching top.\n}\n\\examples{\n\n data(ttrc)\n volatility <- chaikinVolatility(ttrc[,c(\"High\",\"Low\")])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://www.fmlabs.com/reference/ChaikinVolatility.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=120}\\cr\n}\n\\seealso{\nSee \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\noptions; and note Warning section.  See \\code{\\link{TR}} for another\nvolatility measure.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/changes.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/changes.R\n\\name{ROC}\n\\alias{ROC}\n\\alias{changes}\n\\alias{momentum}\n\\title{Rate of Change / Momentum}\n\\usage{\nROC(x, n = 1, type = c(\"continuous\", \"discrete\"), na.pad = TRUE)\n\nmomentum(x, n = 1, na.pad = TRUE)\n}\n\\arguments{\n\\item{x}{Price, volume, etc. series that is coercible to xts or matrix.}\n\n\\item{n}{Number of periods to use.}\n\n\\item{type}{Compounding type; either \\code{\"continuous\"} (the default) or\n\\code{\"discrete\"}.}\n\n\\item{na.pad}{Should periods prior to \\code{n} be appended?  Default is\n\\code{TRUE}.}\n}\n\\value{\nA object of the same class as \\code{x} or a vector (if \\code{try.xts}\nfails) containing the rate-of-change (or return) values for \\code{ROC} or a\nvector containing the differenced price series for \\code{momentum}.\n}\n\\description{\nCalculate the (rate of) change of a series over \\code{n} periods.\n}\n\\details{\nThe ROC indicator provides the percentage difference of a series over two\nobservations, while the momentum indicator simply provides the difference.\n}\n\\examples{\n\n data(ttrc)\n roc <- ROC(ttrc[,\"Close\"])\n mom <- momentum(ttrc[,\"Close\"])\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/keltnerChannels.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/keltnerChannels.R\n\\name{keltnerChannels}\n\\alias{keltnerChannels}\n\\title{Keltner Channels}\n\\usage{\nkeltnerChannels(HLC, n = 20, maType, atr = 2, ...)\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices. If only a univariate series is given, it will be used.\nSee details.}\n\n\\item{n}{Number of periods for moving average.}\n\n\\item{maType}{A function or a string naming the function to be called.}\n\n\\item{atr}{The number of average true range distances to apply.}\n\n\\item{...}{Other arguments to be passed to the maType function.}\n}\n\\value{\nA object of the same class as \\code{HLC} or a matrix (if\n\\code{try.xts} fails) containing the columns:\n \\describe{\n    \\item{SMA}{ Simple moving average. }\n    \\item{EMA}{ Exponential moving average. }\n }\n\n\\item{dn}{ The lower Keltner Channel. }\n\\item{mavg}{ The middle moving average. }\n\\item{up}{ The upper Keltner Channel. }\n}\n\\description{\nKeltner Channels are volatility-based envelopes set above and below a moving\naverage. This indicator is similar to Bollinger Bands, but Keltner Channels\nuse the Average True Range (ATR) to set channel distance.\n}\n\\details{\nKeltner Channels are a trend following indicator, and can also be used to\nidentify overbought and oversold levels when there is no trend.\n\nChester Keltner is credited with the original version of Keltner Channels in\nhis 1960 book. Linda Bradford Raschke introduced the newer version of\nKeltner Channels in the 1980s.\n}\n\\section{Details }{\n Keltner Channels consist of three lines:\nThe middle band is generally a 20-period EMA of the typical price\n([high + low + close]/3). The upper and lower bands are multiples of average\ntrue range (usually 2) above and below the MA.\n\nThe middle band is usually calculated using the typical price, but if a\nunivariate series (e.g. Close, Weighted Close, Median Price, etc.) is\nprovided, it will be used instead.\n}\n\n\\examples{\n\ndata(ttrc)\nkc <- keltnerChannels(ttrc[,c(\"High\",\"Low\",\"Close\")])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:keltner_channels}\\cr\n\\url{https://www.linnsoft.com/techind/keltner-channels-keltu-keltd}\\cr\n\\url{https://www.investopedia.com/terms/k/keltnerchannel.asp}\\cr\n}\n\\seealso{\nSee \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\noptions; and note Warning section.\n}\n\\author{\nNick Procyk, Joshua Ulrich\n\nReferences\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/priceBands.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/priceBands.R\n\\name{PBands}\n\\alias{PBands}\n\\alias{priceBands}\n\\title{Construct (optionally further smoothed and centered ) volatility bands around\nprices}\n\\usage{\nPBands(\n  prices,\n  n = 20,\n  maType = \"SMA\",\n  sd = 2,\n  ...,\n  fastn = 2,\n  centered = FALSE,\n  lavg = FALSE\n)\n}\n\\arguments{\n\\item{prices}{A univariate series of prices.}\n\n\\item{n}{Number of periods to average over.}\n\n\\item{maType}{A function or a string naming the function to be called.}\n\n\\item{sd}{The number of standard deviations to use.}\n\n\\item{\\dots}{any other pass-thru parameters, usually for function named by\n\\code{maType}.}\n\n\\item{fastn}{Number of periods to use for smoothing higher-frequency 'noise'.}\n\n\\item{centered}{Whether to center the bands around a series adjusted for high\nfrequency noise, default \\code{FALSE}.}\n\n\\item{lavg}{Whether to use a longer \\code{(n*2)} smoothing period for\ncentering, default \\code{FALSE}.}\n}\n\\value{\nA object of the same class as \\code{prices} or a matrix (if\n\\code{try.xts} fails) containing the columns:\n \\describe{\n    \\item{ dn }{ The lower price volatility Band. }\n    \\item{ center }{ The smoothed centerline (see details). }\n    \\item{ up }{ The upper price volatility Band. }\n }\n}\n\\description{\nJohn Bollinger's famous adaptive volatility bands most often use the typical\nprice of an HLC series, or may be calculated on a univariate price series\n(see \\code{\\link{BBands}}).\n}\n\\details{\nThis function applies a second moving average denoted by \\code{fastn} to\nfilter out higher-frequency noise, making the bands somewhat more stable to\ntemporary fluctuations and spikes.\n\nIf \\code{centered} is \\code{TRUE}, the function also further smoothes and\ncenters the bands around a centerline adjusted to remove this higher\nfrequency noise.  If \\code{lavg} is also \\code{TRUE}, the smoothing applied\nfor the middle band (but not the volatility bands) is doubled to further\nsmooth the price-response function.\n\nIf you have multiple different price series in \\code{prices}, and want to use\nthis function, call this functions using \\code{lapply(prices,PBands,...)}.\n}\n\\examples{\n\n   data(ttrc)\n   pbands.close <- PBands( ttrc[,\"Close\"] )\n\n}\n\\seealso{\n\\code{\\link{BBands}}\n}\n\\author{\nBrian G. Peterson\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/rollFun.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/rollFun.R\n\\name{rollSFM}\n\\alias{rollSFM}\n\\alias{rollFun}\n\\title{Analysis of Running/Rolling/Moving Windows}\n\\usage{\nrollSFM(Ra, Rb, n = 60)\n}\n\\arguments{\n\\item{Ra}{Object coercible to xts or matrix, containing the excess\nreturn for an individual security}\n\n\\item{Rb}{Object coercible to xts or matrix, containing the market\n/ benchmark return}\n\n\\item{n}{Number of periods to use in the window}\n}\n\\value{\nA object of the same class as \\code{Ra} (and \\code{Rb}?) or a vector\n(if \\code{try.xts} fails).\n \\describe{\n  \\item{rollSFM}{returns single-factor model parameters and R-squared\n    over a n-period moving window.}\n }\n}\n\\description{\nVarious functions to analyze data over a moving window of periods.\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\n\\url{https://en.wikipedia.org/wiki/Simple_linear_regression}\\cr\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/runFun.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/runFun.R\n\\name{runSum}\n\\alias{runSum}\n\\alias{runFun}\n\\alias{runMin}\n\\alias{runMax}\n\\alias{runRange}\n\\alias{runMean}\n\\alias{runMedian}\n\\alias{runCov}\n\\alias{runCor}\n\\alias{runVar}\n\\alias{runSD}\n\\alias{runMAD}\n\\alias{wilderSum}\n\\title{Analysis of Running/Rolling/Moving Windows}\n\\usage{\nrunSum(x, n = 10, cumulative = FALSE)\n\nrunMin(x, n = 10, cumulative = FALSE)\n\nrunMax(x, n = 10, cumulative = FALSE)\n\nrunRange(x, n = 10, cumulative = FALSE)\n\nrunMean(x, n = 10, cumulative = FALSE)\n\nrunMedian(x, n = 10, non.unique = \"mean\", cumulative = FALSE)\n\nrunCov(x, y, n = 10, use = \"all.obs\", sample = TRUE, cumulative = FALSE)\n\nrunCor(x, y, n = 10, use = \"all.obs\", sample = TRUE, cumulative = FALSE)\n\nrunVar(x, y = NULL, n = 10, sample = TRUE, cumulative = FALSE)\n\nrunSD(x, n = 10, sample = TRUE, cumulative = FALSE)\n\nrunMAD(\n  x,\n  n = 10,\n  center = NULL,\n  stat = \"median\",\n  constant = 1.4826,\n  non.unique = \"mean\",\n  cumulative = FALSE\n)\n\nwilderSum(x, n = 10)\n}\n\\arguments{\n\\item{x}{Object coercible to xts or matrix.}\n\n\\item{n}{Number of periods to use in the window or, if\n\\code{cumulative=TRUE}, the number of observations to use before the first\nresult is returned. Must be between 1 and \\code{nrow(x)}, inclusive.}\n\n\\item{cumulative}{Logical, use from-inception calculation?}\n\n\\item{non.unique}{One of 'mean', 'max', or 'min'; which compute their\nrespective statistics for the two middle values of even-sized samples.}\n\n\\item{y}{Object coercible to xts or matrix.}\n\n\\item{use}{Only \\code{\"all.obs\"} currently implemented.}\n\n\\item{sample}{Logical, sample covariance if \\code{TRUE} (denominator of\n\\code{n-1})}\n\n\\item{center}{The values to use as the measure of central tendency, around\nwhich to calculate deviations. The default (\\code{NULL}) uses the median.}\n\n\\item{stat}{Statistic to calculate, one of 'median' or 'mean' (e.g. median\nabsolute deviation or mean absolute deviation, respectively.)}\n\n\\item{constant}{Scale factor applied to approximate the standard deviation.}\n}\n\\value{\nA object of the same class as \\code{x} and \\code{y} or a vector (if\n\\code{try.xts} fails).\n \\describe{\n  \\item{runSum}{returns sums over a n-period moving window.}\n  \\item{runMin}{returns minimums over a n-period moving window.}\n  \\item{runMax}{returns maximums over a n-period moving window.}\n  \\item{runRange}{returns a maxtrix with min and max values for x over a n-period moving window.}\n  \\item{runMean}{returns means over a n-period moving window.}\n  \\item{runMedian}{returns medians over a n-period moving window.}\n  \\item{runCov}{returns covariances over a n-period moving window.}\n  \\item{runCor}{returns correlations over a n-period moving window.}\n  \\item{runVar}{returns variances over a n-period moving window.}\n  \\item{runSD}{returns standard deviations over a n-period moving window.}\n  \\item{runMAD}{returns median/mean absolute deviations over a n-period moving window.}\n  \\item{wilderSum}{retuns a Welles Wilder style weighted sum over a n-period moving window.}\n }\n}\n\\description{\nVarious functions to analyze data over a moving window of periods.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/runPercentRank.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/percentRank.R\n\\name{runPercentRank}\n\\alias{runPercentRank}\n\\alias{percentRank}\n\\alias{PercentRank}\n\\title{Percent Rank over a Moving Window}\n\\usage{\nrunPercentRank(x, n = 260, cumulative = FALSE, exact.multiplier = 0.5)\n}\n\\arguments{\n\\item{x}{Object coercible to xts or matrix.}\n\n\\item{n}{Number of periods to use in the window or, if\n\\code{cumulative=TRUE}, the number of observations to use before the first\nresult is returned. Must be between 1 and \\code{nrow(x)}, inclusive.}\n\n\\item{cumulative}{Logical, use from-inception calculation?}\n\n\\item{exact.multiplier}{The weight applied to identical values in the window.\nMust be between 0 and 1, inclusive. See details.}\n}\n\\value{\nA object of percent ranks over a n-period moving window of the same\nclass as \\code{x} and \\code{y} or a vector (if \\code{try.xts} fails).\n}\n\\description{\nThis function computes a running/rolling percentage rank.\n}\n\\details{\nThe computation for a percentage rank can vary depending on the weight given\nto values in the window that are equal to the value being ranked. This weight\ncan be set using the \\code{exact.multiplier} argument which defaults to 0.5.\n\n\\code{exact.multiplier = 0} scores equal values in the lookback window as\nalways being greater than the value being ranked. \\code{exact.multiplier = 1}\nscores equal values as being below the value being ranked. Any multiplier\nbetween 0 and 1 counts that proportion of the equal values as being below\nthe value being ranked.\n\nThe value of \\code{exact.multiplier} has the most impact when the window is\nrelatively small or when the number of discrete values in the window is\nsmall. For non-repeating values, changing \\code{exact.multiplier = 0} to\n\\code{exact.multiplier = 1} for a window of size \\code{N} will shift the\nresulting percentile rankings by \\code{1/N}. It is equivalent to changing\nthe question from, \"how many values are < the value\" to \"how many values\nare <= the value\".\n}\n\\note{\nThis computation is different from the one used in Microsoft Excel's\n\\code{PERCENTRANK} formula. Excel's computation is rather strange and gives\ninconsistent results as it uses interpolation to rank values that are not\nfound within the lookback window.\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr \\url{https://en.wikipedia.org/wiki/Percentile_rank}\\cr\n}\n\\author{\nCharlie Friedemann\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/stochastics.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/stochastics.R\n\\name{stoch}\n\\alias{stoch}\n\\alias{stochastics}\n\\alias{stochastic}\n\\alias{SMI}\n\\alias{\\%K}\n\\alias{\\%D}\n\\title{Stochastic Oscillator / Stochastic Momentum Index}\n\\usage{\nstoch(\n  HLC,\n  nFastK = 14,\n  nFastD = 3,\n  nSlowD = 3,\n  maType,\n  bounded = TRUE,\n  smooth = 1,\n  ...\n)\n\nSMI(HLC, n = 13, nFast = 2, nSlow = 25, nSig = 9, maType, bounded = TRUE, ...)\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices.  If only a univariate series is given, it will be\nused.  See details.}\n\n\\item{nFastK}{Number of periods for fast \\%K (i.e. the number of past periods\nto use).}\n\n\\item{nFastD}{Number of periods for fast \\%D (i.e. the number smoothing\nperiods to apply to fast \\%K).}\n\n\\item{nSlowD}{Number of periods for slow \\%D (i.e. the number smoothing\nperiods to apply to fast \\%D).}\n\n\\item{maType}{Either:\n\\enumerate{\n  \\item A function or a string naming the function to be called.\n  \\item A \\emph{list} with the first component like (1) above, and\n    additional parameters specified as \\emph{named} components.\n    See Examples.\n}}\n\n\\item{bounded}{Logical, should current period's values be used in the\ncalculation?}\n\n\\item{smooth}{Number of internal smoothing periods to be applied before\ncalculating FastK. See Details.}\n\n\\item{\\dots}{Other arguments to be passed to the \\code{maType} function in\ncase (1) above.}\n\n\\item{n}{Number of periods to use.}\n\n\\item{nFast}{Number of periods for initial smoothing.}\n\n\\item{nSlow}{Number of periods for double smoothing.}\n\n\\item{nSig}{Number of periods for signal line.}\n}\n\\value{\nA object of the same class as \\code{HLC} or a matrix (if\n\\code{try.xts} fails) containing the columns:\n \\describe{\n    \\item{ fastK }{ Stochastic Fast \\%K }\n    \\item{ fastD }{ Stochastic Fast \\%D }\n    \\item{ slowD }{ Stochastic Slow \\%D }\n    \\item{ SMI }{ Stochastic Momentum Index }\n    \\item{ signal }{ Stochastic Momentum Index signal line }\n }\n}\n\\description{\nThe stochastic oscillator is a momentum indicator that relates the location\nof each day's close relative to the high/low range over the past \\code{n}\nperiods.  Developed by George C.  Lane in the late 1950s.  The SMI relates\nthe close to the midpoint of the high/low range.  Developed by William Blau\nin 1993.\n}\n\\details{\nIf a High-Low-Close series is provided, the indicator is calculated using the\nhigh/low values.  If a vector is provided, the calculation only uses that\nseries.  This allows stochastics to be calculated for: (1) series that have\nno HLC definition (e.g. foreign exchange), and (2) stochastic indicators\n(e.g. stochastic RSI - see examples).\n\nThe \\code{smooth} argument is the number of periods of internal smoothing to\napply to the differences in the high-low-close range before calculating Fast\nK.  Thanks to Stanley Neo for the suggestion.\n}\n\\note{\nThe calculation for William's \\%R is similar to that of stochastics'\nfast \\%K.\n\nThe value for fast \\%K will be 0.5 whenever the highest high and\nlowest low are the same over the last \\code{n} periods.\n\nThe stochastic oscillator and SMI calculate relative value of the close\nversus the high/low range and the midpoint of the high/low range,\nrespectively.\n\nThe stochastic oscillator and the stochastic momentum index are interpreted\nsimilarly.  Readings below 20 (above 80) are considered oversold\n(overbought).  However, readings below 20 (above 80) are not necessarily\nbearish (bullish).  Lane believed some of the best sell (buy) signals\noccurred when the oscillator moved from overbought (oversold) back below 80\n(above 20).\n\nFor the stochastic oscillator, buy (sell) signals can also be given when \\%K\ncrosses above (below) \\%D.  Crossover signals are quite frequent however,\nwhich may result in whipsaws.\n}\n\\examples{\n\n data(ttrc)\n stochOSC <- stoch(ttrc[,c(\"High\",\"Low\",\"Close\")])\n stochWPR <- WPR(ttrc[,c(\"High\",\"Low\",\"Close\")])\n\n plot(tail(stochOSC[,\"fastK\"], 100), type=\"l\",\n     main=\"Fast \\%K and Williams \\%R\", ylab=\"\",\n     ylim=range(cbind(stochOSC, stochWPR), na.rm=TRUE) )\n lines(tail(stochWPR, 100), col=\"blue\")\n lines(tail(1-stochWPR, 100), col=\"red\", lty=\"dashed\")\n\n stoch2MA <- stoch( ttrc[,c(\"High\",\"Low\",\"Close\")],\n     maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA)) )\n\n SMI3MA <- SMI(ttrc[,c(\"High\",\"Low\",\"Close\")],\n     maType=list(list(SMA), list(EMA, wilder=TRUE), list(SMA)) )\n\n stochRSI <- stoch( RSI(ttrc[,\"Close\"]) )\n}\n\\references{\nThe following site(s) were used to code/document these\nindicators:\n\\cr Stochastic Oscillator:\\cr\n\\url{https://www.fmlabs.com/reference/StochasticOscillator.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=106}\\cr\n\\url{https://www.linnsoft.com/techind/stochastics}\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:stochastic_oscillator_fast_slow_and_full}\\cr\n\\cr SMI:\\cr\n\\url{https://www.fmlabs.com/reference/default.htm?url=SMI.htm}\\cr\n}\n\\seealso{\nSee \\code{\\link{EMA}}, \\code{\\link{SMA}}, etc. for moving average\noptions; and note Warning section.  See \\code{\\link{WPR}} to compare it's\nresults to fast \\%K.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/ttrc.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/TTR-package.R\n\\docType{data}\n\\name{ttrc}\n\\alias{ttrc}\n\\title{Technical Trading Rule Composite data}\n\\format{\nThe format is: \\tabular{lll}{ Date: \\tab Class 'Date' \\tab 5480 5481\n5482 5485 5486 ...\\cr Open: \\tab num \\tab 3.18 3.09 3.11 3.09 3.10 ...\\cr\nHigh: \\tab num \\tab 3.18 3.15 3.12 3.12 3.12 ...\\cr Low: \\tab num \\tab 3.08\n3.09 3.08 3.07 3.08 ...\\cr Close: \\tab num \\tab 3.08 3.11 3.09 3.10 3.11\n...\\cr Volume: \\tab num \\tab 1870906 3099506 2274157 2086758 2166348 ...\\cr }\n}\n\\source{\nRandomly generated.\n}\n\\description{\nHistorical Open, High, Low, Close, and Volume data for the periods January 2,\n1985 to December 31, 2006. Randomly generated.\n}\n\\details{\nThese data do not represent an actual security.  They are provided so\nexamples do not necessitate an internet connection.\n}\n\\examples{\n\n data(ttrc)\n plot(tail(ttrc[,\"Close\"],100), type=\"l\")\n}\n\\keyword{datasets}\n"
  },
  {
    "path": "man/ultimateOscillator.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/ultimateOscillator.R\n\\name{ultimateOscillator}\n\\alias{ultimateOscillator}\n\\title{The Ultimate Oscillator}\n\\usage{\nultimateOscillator(HLC, n = c(7, 14, 28), wts = c(4, 2, 1))\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices.}\n\n\\item{n}{A vector of the number of periods to use for each average calculation.}\n\n\\item{wts}{The weights applied to each average.}\n}\n\\description{\nThe Ultimate Oscillator is a momentum oscillator designed to capture momentum across three\ndifferent time frames.\n}\n\\details{\nCreated by Larry Williams in 1976.\n}\n\\examples{\n\ndata(ttrc)\nult.osc <- ultimateOscillator(ttrc[,c(\"High\",\"Low\",\"Close\")])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://school.stockcharts.com/doku.php?id=technical_indicators:ultimate_oscillator}\\cr\n}\n\\author{\nIvan Popivanov\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/volatility.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/volatility.R\n\\name{volatility}\n\\alias{volatility}\n\\alias{garman.klass}\n\\alias{parkinson}\n\\alias{rogers.satchell}\n\\alias{gk.yz}\n\\alias{yang.zhang}\n\\title{Volatility}\n\\usage{\nvolatility(OHLC, n = 10, calc = \"close\", N = 260, mean0 = FALSE, ...)\n}\n\\arguments{\n\\item{OHLC}{Object that is coercible to xts or matrix and contains\nOpen-High-Low-Close prices (or only Close prices, if \\code{calc=\"close\"}).}\n\n\\item{n}{Number of periods for the volatility estimate.}\n\n\\item{calc}{The calculation (type) of estimator to use.}\n\n\\item{N}{Number of periods per year.}\n\n\\item{mean0}{Use a mean of 0 rather than the sample mean.}\n\n\\item{\\dots}{Arguments to be passed to/from other methods.}\n}\n\\value{\nA object of the same class as \\code{OHLC} or a vector (if\n\\code{try.xts} fails) containing the chosen volatility estimator values.\n}\n\\description{\nSelected volatility estimators/indicators; various authors.\n}\n\\details{\n\\itemize{\n\\item Close-to-Close Volatility (\\code{calc=\"close\"})\\cr\n\\deqn{ \\sigma_{cl} = \\sqrt{\\frac{N}{n-2} \\sum_{i=1}^{n-1}(r_i-\\bar{r})^2}\n}{sqrt(N) * runSD(ROC(Cl), n-1)}\n\\deqn{where\\;\\; r_i = \\log \\left(\\frac{C_i}{C_{i-1}}\\right) }\n\\deqn{and\\;\\; \\bar{r} = \\frac{r_1+r_2+\\ldots +r_{n-1}}{n-1} }\n\n\\item OHLC Volatility: Garman and Klass (\\code{calc=\"garman.klass\"})\\cr The\nGarman and Klass estimator for estimating historical volatility assumes\nBrownian motion with zero drift and no opening jumps (i.e. the opening =\nclose of the previous period). This estimator is 7.4 times more efficient\nthan the close-to-close estimator.\\cr\n\\deqn{ \\sigma = \\sqrt{ \\frac{N}{n} \\sum\n  \\left[ \\textstyle\\frac{1}{2}\\displaystyle\n    \\left( \\log \\frac{H_i}{L_i} \\right)^2  - (2\\log 2-1)\n    \\left( \\log \\frac{C_i}{O_i} \\right)^2 \\right] }\n}{sqrt(N/n * runSum(0.5 * log(Hi/Lo)^2 -\n           (2*log(2)-1) * log(Cl/Op)^2, n))}\n\n\\item High-Low Volatility: Parkinson (\\code{calc=\"parkinson\"})\\cr\nThe Parkinson formula for estimating the historical volatility of\nan underlying based on high and low prices.\\cr\n\\deqn{ \\sigma = \\sqrt{ \\frac{N}{4 n \\times \\log 2} \\sum_{i=1}^{n}\n  \\left(\\log \\frac{H_i}{L_i}\\right)^2}\n}{sqrt(N/(4*n*log(2)) * runSum(log(Hi/Lo)^2, n))}\n\n\\item OHLC Volatility: Rogers and Satchell (\\code{calc=\"rogers.satchell\"})\\cr\nThe Roger and Satchell historical volatility estimator allows for non-zero\ndrift, but assumed no opening jump.\\cr\n\\deqn{ \\sigma = \\sqrt{ \\textstyle\\frac{N}{n} \\sum \\left[\n  \\log \\textstyle\\frac{H_i}{C_i} \\times \\log \\textstyle\\frac{H_i}{O_i} +\n  \\log \\textstyle\\frac{L_i}{C_i} \\times \\log \\textstyle\\frac{L_i}{O_i} \\right] }\n}{sqrt(N/n * runSum(log(Hi/Cl) * log(Hi/Op) +\n                    log(Lo/Cl) * log(Lo/Op), n))}\n\n\\item OHLC Volatility: Garman and Klass - Yang and Zhang\n(\\code{calc=\"gk.yz\"})\\cr This estimator is a modified version of the Garman\nand Klass estimator that allows for opening gaps.\\cr\n\\deqn{ \\sigma = \\sqrt{ \\textstyle\\frac{N}{n} \\sum \\left[\n  \\left( \\log \\textstyle\\frac{O_i}{C_{i-1}} \\right)^2  +\n    \\textstyle\\frac{1}{2}\\displaystyle\n  \\left( \\log \\textstyle\\frac{H_i}{L_i} \\right)^2 - (2 \\times \\log 2-1)\n  \\left( \\log \\textstyle\\frac{C_i}{O_i} \\right)^2 \\right] }\n}{sqrt(N/n * runSum(log(Op/lag(Cl,1))^2 +\n  0.5 * log(Hi/Lo)^2 - (2*log(2)-1) * log(Cl/Op)^2 , n))}\n\n\\item OHLC Volatility: Yang and Zhang (\\code{calc=\"yang.zhang\"})\\cr The Yang\nand Zhang historical volatility estimator has minimum estimation error, and\nis independent of drift and opening gaps.  It can be interpreted as a\nweighted average of the Rogers and Satchell estimator, the close-open\nvolatility, and the open-close volatility.\n\nUsers may override the default values of \\eqn{\\alpha} (1.34 by default) or\n\\eqn{k} used in the calculation by specifying \\code{alpha} or \\code{k} in\n\\code{\\dots}, respectively. Specifying \\code{k} will cause \\code{alpha} to be\nignored, if both are provided.\\cr\n\\deqn{ \\sigma^2 = \\sigma_o^2 + k\\sigma_c^2 + (1-k)\\sigma_{rs}^2\n}{ s <- sqrt(s2o + k*s2c + (1-k)*(s2rs^2)) }\n\\deqn{ \\sigma_o^2 =\\textstyle \\frac{N}{n-1} \\sum\n  \\left( \\log \\frac{O_i}{C_{i-1}}-\\mu_o \\right)^2\n}{ s2o <- N * runVar(log(Op/lag(Cl,1)), n=n) }\n\\deqn{ \\mu_o=\\textstyle \\frac{1}{n} \\sum \\log \\frac{O_i}{C_{i-1}} }\n\\deqn{ \\sigma_c^2 =\\textstyle \\frac{N}{n-1} \\sum\n  \\left( \\log \\frac{C_i}{O_i}-\\mu_c \\right)^2\n}{ s2c <- N * runVar(log(Cl/Op), n=n) }\n\\deqn{ \\mu_c=\\textstyle \\frac{1}{n} \\sum \\log \\frac{C_i}{O_i} }\n\\deqn{ \\sigma_{rs}^2 = \\textstyle\\frac{N}{n} \\sum \\left(\n  \\log \\textstyle\\frac{H_i}{C_i} \\times \\log \\textstyle\\frac{H_i}{O_i} +\n  \\log \\textstyle\\frac{L_i}{C_i} \\times \\log \\textstyle\\frac{L_i}{O_i}\n  \\right)\n}{ s2rs <- volatility(OHLC, n, \"rogers.satchell\", N, ...) }\n\\deqn{ k=\\frac{\\alpha-1}{alpha+\\frac{n+1}{n-1}}\n}{ k <- (alpha-1) / (alpha + (n+1)/(n-1)) }\n}\n}\n\\examples{\n\n data(ttrc)\n ohlc <- ttrc[,c(\"Open\",\"High\",\"Low\",\"Close\")]\n vClose <- volatility(ohlc, calc=\"close\")\n vClose0 <- volatility(ohlc, calc=\"close\", mean0=TRUE)\n vGK <- volatility(ohlc, calc=\"garman\")\n vParkinson <- volatility(ohlc, calc=\"parkinson\")\n vRS <- volatility(ohlc, calc=\"rogers\")\n\n}\n\\references{\nThe following sites were used to code/document these\nindicators. All were created by Thijs van den Berg under the GNU Free\nDocumentation License and were retrieved on 2008-04-20. The original\nlinks are dead, but can be accessed via internet archives.\\cr\n\\cr Close-to-Close Volatility (\\code{calc=\"close\"}):\\cr\n\\url{https://web.archive.org/web/20100421083157/http://www.sitmo.com/eq/172}\\cr\n\\cr OHLC Volatility: Garman Klass (\\code{calc=\"garman.klass\"}):\\cr\n\\url{https://web.archive.org/web/20100326172550/http://www.sitmo.com/eq/402}\\cr\n\\cr High-Low Volatility: Parkinson (\\code{calc=\"parkinson\"}):\\cr\n\\url{https://web.archive.org/web/20100328195855/http://www.sitmo.com/eq/173}\\cr\n\\cr OHLC Volatility: Rogers Satchell (\\code{calc=\"rogers.satchell\"}):\\cr\n\\url{https://web.archive.org/web/20091002233833/http://www.sitmo.com/eq/414}\\cr\n\\cr OHLC Volatility: Garman Klass - Yang Zhang (\\code{calc=\"gk.yz\"}):\\cr\n\\url{https://web.archive.org/web/20100326215050/http://www.sitmo.com/eq/409}\\cr\n\\cr OHLC Volatility: Yang Zhang (\\code{calc=\"yang.zhang\"}):\\cr\n\\url{https://web.archive.org/web/20100326215050/http://www.sitmo.com/eq/409}\\cr\n}\n\\seealso{\nSee \\code{\\link{TR}} and \\code{\\link{chaikinVolatility}} for other\nvolatility measures.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "man/williamsAD.Rd",
    "content": "% Generated by roxygen2: do not edit by hand\n% Please edit documentation in R/williamsAD.R\n\\name{williamsAD}\n\\alias{williamsAD}\n\\title{Williams Accumulation / Distribution}\n\\usage{\nwilliamsAD(HLC)\n}\n\\arguments{\n\\item{HLC}{Object that is coercible to xts or matrix and contains\nHigh-Low-Close prices.}\n}\n\\value{\nA object of the same class as \\code{HLC} or a vector (if\n\\code{try.xts} fails) containing the accumulation / distribution values.\n}\n\\description{\nThe Williams Accumulation / Distribution (AD) line is a measure of market\nmomentum.  Developed by Larry Williams.\n}\n\\details{\nThe Williams AD line differs from OBV and chaikinAD in that it doesn't take\nvolume into account.\n}\n\\note{\nThe Accumulation/Distribution Line is interpreted by looking for a\ndivergence in the direction of the indicator relative to price.\n}\n\\examples{\n\n data(ttrc)\n ad <- williamsAD(ttrc[,c(\"High\",\"Low\",\"Close\")])\n\n}\n\\references{\nThe following site(s) were used to code/document this\nindicator:\\cr\n\\url{https://www.fmlabs.com/reference/WilliamsAD.htm}\\cr\n\\url{https://www.metastock.com/Customer/Resources/TAAZ/?p=125}\\cr\n}\n\\seealso{\nSee \\code{\\link{OBV}}, \\code{\\link{chaikinAD}}, and\n\\code{\\link{ATR}}.\n}\n\\author{\nJoshua Ulrich\n}\n\\keyword{ts}\n"
  },
  {
    "path": "src/adjRatios.c",
    "content": "/*\n *  TTR: Technical Trading Rules\n *\n *  Copyright (C) 2007-2013  Joshua M. Ulrich\n *\n *  This program is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 2 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <R.h>\n#include <Rinternals.h>\n\nSEXP adjRatios (SEXP split, SEXP div, SEXP close) {\n\n    /* Initialize REAL pointers to function arguments */\n    double *real_close = REAL(close);\n    double *real_split = REAL(split);\n    double *real_div   = REAL(div);\n    \n    /* Initialize loop and PROTECT counters */\n    int i, P = 0;\n    /* Initialize object length (NOTE: all arguments are the same length) */\n    int N = length(close);\n\n    /* Initialize result R objects */\n    SEXP result;    PROTECT(result  = allocVector(VECSXP, 2)); P++;\n    SEXP s_ratio;   PROTECT(s_ratio = allocVector(REALSXP,N)); P++;\n    SEXP d_ratio;   PROTECT(d_ratio = allocVector(REALSXP,N)); P++;\n    \n    /* Initialize REAL pointers to R objects and set their last value to '1' */\n    double *rs_ratio = REAL(s_ratio);\n    double *rd_ratio = REAL(d_ratio);\n    rs_ratio[N-1] = 1;\n    rd_ratio[N-1] = 1;\n\n    /* Loop over split/div vectors from newest period to oldest */\n    for(i = N-1; i > 0; i--) {\n        /* Carry newer ratio value backward */\n        if(ISNA(real_split[i])) {\n            rs_ratio[i-1] = rs_ratio[i];\n        /* Update split ratio */\n        } else {\n            rs_ratio[i-1] = rs_ratio[i] * real_split[i];\n        }\n        /* Carry newer ratio value backward */\n        if(ISNA(real_div[i])) {\n            rd_ratio[i-1] = rd_ratio[i];\n        } else {\n        /* Update dividend ratio */\n            rd_ratio[i-1] = rd_ratio[i] *\n                (1.0 - real_div[i] / real_close[i-1]);\n        }\n    }\n    \n    /* Assign results to list */\n    SET_VECTOR_ELT(result, 0, s_ratio);\n    SET_VECTOR_ELT(result, 1, d_ratio);\n\n    /* UNPROTECT R objects and return result */\n    UNPROTECT(P);\n    return(result);\n}\n"
  },
  {
    "path": "src/aroon.c",
    "content": "/*\n *  TTR: Technical Trading Rules\n *\n *  Copyright (C) 2007-2013  Joshua M. Ulrich\n *\n *  This program is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 2 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"ttr.h\"\n\nSEXP aroon_max (SEXP x, SEXP n) {\n\n  /* Initialize loop, loc, and PROTECT counters */\n  int i, j, loc=0, P=0;\n\n  /* Ensure x argument is double */\n  if(TYPEOF(x) != REALSXP) {\n    PROTECT(x = coerceVector(x, REALSXP)); P++;\n  }\n\n  /* Pointers to function arguments */\n  double *real_x = REAL(x);\n  int int_n = asInteger(n);\n\n  /* Input object length */\n  int nr = length(x);\n\n  /* Initialize result R object */\n  SEXP result;\n  PROTECT(result = allocVector(REALSXP, nr)); P++;\n  double *real_result = REAL(result);\n\n  /* check for non-leading NAs and get first non-NA location */\n  SEXP first = PROTECT(xts_na_check(x, ScalarLogical(TRUE))); P++;\n  int int_first = asInteger(first);\n  if(int_n + int_first > nr)\n    error(\"not enough non-NA values\");\n\n  double real_max = real_x[0];\n\n  /* set leading NAs and find initial max value */\n  for (i = 0; i < int_first + int_n-1; i++) {\n    real_result[i] = NA_REAL;\n    if(real_x[i] >= real_max) {\n      real_max = real_x[i];  /* set max value */\n      loc = 0;               /* set max location in window */\n    }\n    loc++;\n    continue;\n  }\n\n  /* Loop over non-NA input values */\n  for (i = int_first + int_n-1; i < nr; i++) {\n    /* if the max leaves the window */\n    if(loc > int_n) {\n      /* find the max over the (n+1) window */\n      real_max = real_x[i];\n      loc = 0;\n      //for(j=0; j<int_n; j++) {  // roll_max\n      for(j=1; j<int_n+1; j++) {\n        if(real_x[i-j] > real_max) {\n          real_max = real_x[i-j];\n          loc = j;\n        }\n      }\n    } else {\n      /* if the new value is the new max */\n      if(real_x[i] >= real_max) {\n        real_max = real_x[i];\n        loc = 0;\n      }\n    }\n\n    /* set result, increment location */\n    real_result[i] = (100.0 * (int_n - loc)) / int_n;\n    loc++;\n  }\n\n  /* UNPROTECT R objects and return result */\n  UNPROTECT(P);\n  return(result);\n}\n\n"
  },
  {
    "path": "src/init.c",
    "content": "/*\n *  TTR: Technical Trading Rules\n *\n *  Copyright (C) 2007-2017  Joshua M. Ulrich\n *\n *  This program is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 2 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n/* Includes and defines from WRE Section 5.4.2 */\n#include \"ttr.h\"\n#include <R.h>\n#include <stdlib.h>  /* for NULL */\n#include <R_ext/Rdynload.h>\n\n#define CALLDEF(name, n)  {#name, (DL_FUNC) &name, n}\n\n/* define xts imports */\nSEXP (*xts_na_check)(SEXP,SEXP);\n\nstatic const R_CallMethodDef CallEntries[] = {\n  CALLDEF(adjRatios,            3),\n  CALLDEF(aroon_max,            2),\n  CALLDEF(ema,                  4),\n  CALLDEF(evwma,                3),\n  CALLDEF(sar,                  3),\n  CALLDEF(ttr_rollPercentRank,  4),\n  CALLDEF(ttr_zigzag,           6),\n  CALLDEF(wilderSum,            2),\n  CALLDEF(wma,                  3),\n  CALLDEF(zlema,                3),\n  CALLDEF(runsum,               2),\n  CALLDEF(runrange,             2),\n  CALLDEF(runmedian,            4),\n  CALLDEF(runmad,               6),\n  CALLDEF(runcov,               5),\n  {NULL, NULL, 0}\n};\n\n/* Restrict .Call etc to use only registered symbols */\nvoid R_init_TTR(DllInfo *dll)\n{\n  R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);\n  R_useDynamicSymbols(dll, FALSE);\n  R_forceSymbols(dll, TRUE);\n\n  /* imports from xts C code */\n  xts_na_check = (SEXP(*)(SEXP,SEXP)) R_GetCCallable(\"xts\", \"naCheck\");\n}\n"
  },
  {
    "path": "src/moving_averages.c",
    "content": "/*\n *  TTR: Technical Trading Rules\n *\n *  Copyright (C) 2007-2013  Joshua M. Ulrich\n *\n *  This program is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 2 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"ttr.h\"\n\nSEXP ema (SEXP x, SEXP n, SEXP ratio, SEXP wilder) {\n    \n    /* Initialize loop and PROTECT counters */\n    int i, P=0;\n\n    /* ensure that 'x' is double */\n    if(TYPEOF(x) != REALSXP) {\n      PROTECT(x = coerceVector(x, REALSXP)); P++;\n    }\n    double *d_x = REAL(x);\n\n    if(ncols(x) > 1) {\n      error(\"ncol(x) > 1; EMA only supports univariate 'x'\");\n    }\n\n    int i_n = asInteger(n);\n    double d_ratio = asReal(ratio);\n\n    if(R_NilValue == n || i_n <= 0) {\n      if(R_NilValue == ratio || d_ratio <= 0.0) {\n        error(\"either 'n' or 'ratio' must be specified and > 0\\n'n' is %d and 'ratio' is %1.6f\", i_n, d_ratio);\n      } else {\n        /* If ratio is specified, and n is not, set n to approx 'correct'\n         * value backed out from ratio */\n        i_n  = (int)(2.0 / d_ratio - 1.0);\n      }\n    } else {\n      /* Determine decay ratio */\n      if(R_NilValue == ratio) {\n        int isWilder = asInteger(wilder);\n        d_ratio = (isWilder) ? 1.0 / i_n : 2.0 / (i_n + 1);\n      } else {\n        /* ratio != NULL -> warn that 'n' will be used instead */\n        warning(\"both 'n' and 'ratio' are specified; using 'n'\");\n      }\n    }\n\n    /* Input object length */\n    int nr = nrows(x);\n\n    /* Initialize result R object */\n    SEXP result;\n    PROTECT(result = allocVector(REALSXP,nr)); P++;\n    double *d_result = REAL(result);\n\n    /* check for non-leading NAs and get first non-NA location */\n    SEXP _first = PROTECT(xts_na_check(x, ScalarLogical(TRUE))); P++;\n    int first = INTEGER(_first)[0];\n    if(i_n + first > nr) {\n      error(\"not enough non-NA values\");\n    }\n\n    /* Set leading NAs in output */\n    for(i = 0; i < first; i++) {\n      d_result[i] = NA_REAL;\n    }\n\n    /* Raw mean to start EMA */\n    double seed = 0.0;\n    for(i = first; i < first + i_n; i++) {\n      d_result[i] = NA_REAL;\n      seed += d_x[i] / i_n;\n    }\n    d_result[first + i_n - 1] = seed;\n\n    /* Loop over non-NA input values */\n    for(i = first + i_n; i < nr; i++) {\n        d_result[i] = d_x[i] * d_ratio + d_result[i-1] * (1-d_ratio);\n    }\n\n    /* UNPROTECT R objects and return result */\n    UNPROTECT(P);\n    return(result);\n}\n\nSEXP evwma (SEXP pr, SEXP vo, SEXP n) {\n    \n    /* Initialize loop and PROTECT counters */\n    int i, P=0;\n\n    /* ensure that 'pr' is double */\n    if(TYPEOF(pr) != REALSXP) {\n      PROTECT(pr = coerceVector(pr, REALSXP)); P++;\n    }\n    /* ensure that 'vo' is double */\n    if(TYPEOF(vo) != REALSXP) {\n      PROTECT(vo = coerceVector(vo, REALSXP)); P++;\n    }\n\n    /* Pointers to function arguments */\n    double *d_pr = REAL(pr);\n    double *d_vo = REAL(vo);\n    int i_n = asInteger(n);\n    \n    /* Input object length */\n    int nr = nrows(pr);\n\n    /* Initialize result R object */\n    SEXP result;\n    PROTECT(result = allocVector(REALSXP,nr)); P++;\n    double *d_result = REAL(result);\n\n    /* check for non-leading NAs and get first non-NA location */\n    SEXP _first_pr = PROTECT(xts_na_check(pr, ScalarLogical(TRUE))); P++;\n    int first_pr = asInteger(_first_pr);\n    if(i_n + first_pr > nr) {\n      error(\"not enough non-NA values in 'price'\");\n    }\n    SEXP _first_vo = PROTECT(xts_na_check(vo, ScalarLogical(TRUE))); P++;\n    int first_vo = asInteger(_first_vo);\n    if(i_n + first_vo > nr) {\n      error(\"not enough non-NA values in 'volume'\");\n    }\n\n    int first = first_pr > first_vo ? first_pr : first_vo;\n    int begin = first + i_n - 1;\n\n    /* Set leading NAs in output */\n    for(i = 0; i < begin; i++) {\n      d_result[i] = NA_REAL;\n    }\n\n    /* First non-NA result is the first non-NA value of 'x' */\n    d_result[begin] = d_pr[begin];\n\n    /* Initialize volume sum */\n    double volSum = 0.0;\n    for(i = first; i < begin+1; i++) {\n      volSum += d_vo[i];\n    }\n\n    /* Loop over the rest of the values */\n    for(i = begin + 1; i < nr; i++) {\n        volSum = volSum + d_vo[i] - d_vo[i-i_n];\n        d_result[i] = ((volSum-d_vo[i])*d_result[i-1]+d_vo[i]*d_pr[i])/volSum;\n    }\n\n    /* UNPROTECT R objects and return result */\n    UNPROTECT(P);\n    return(result);\n}\n\nSEXP wma (SEXP x, SEXP w, SEXP n) {\n\n    /* Initialize loop and PROTECT counters */\n    int i, j, P=0;\n\n    /* ensure that 'x' is double */\n    if(TYPEOF(x) != REALSXP) {\n      PROTECT(x = coerceVector(x, REALSXP)); P++;\n    }\n    /* ensure that 'w' is double */\n    if(TYPEOF(w) != REALSXP) {\n      PROTECT(w = coerceVector(w, REALSXP)); P++;\n    }\n    int i_n = asInteger(n);\n\n    /* Pointers to function arguments */\n    double *d_x = REAL(x);\n    double *d_w = REAL(w);\n\n    /* Input object length */\n    int nr = nrows(x);\n\n    /* Initialize result R object */\n    SEXP result;\n    PROTECT(result = allocVector(REALSXP,nr)); P++;\n    double *d_result = REAL(result);\n\n    /* check for non-leading NAs and get first non-NA location */\n    SEXP _first = PROTECT(xts_na_check(x, ScalarLogical(TRUE))); P++;\n    int first = INTEGER(_first)[0];\n    if(i_n + first > nr) {\n      error(\"not enough non-NA values\");\n    }\n\n    int begin = first + i_n - 1;\n    /* Set leading NAs in output */\n    for(i = 0; i < begin; i++) {\n      d_result[i] = NA_REAL;\n    }\n\n    /* Sum of weights (w does not have NA) */\n    double wtsum = 0.0;\n    for(j = 0; j < i_n; j++) {\n      if(ISNA(d_w[j])) {\n          error(\"wts cannot contain NA\");\n      }\n      wtsum += d_w[j];\n    }\n\n    /* Loop over non-NA input values */\n    for(i = begin; i < nr; i++) {\n      double num = 0.0;\n      int ni = i - i_n + 1;\n      for(j = 0; j < i_n; j++) {\n        num += d_x[ni+j] * d_w[j];\n      }\n      d_result[i] = num / wtsum;\n    }\n\n    /* UNPROTECT R objects and return result */\n    UNPROTECT(P);\n    return(result);\n}\n\nSEXP zlema (SEXP x, SEXP n, SEXP ratio) {\n\n    /* Initialize loop and PROTECT counters */\n    int i, P=0;\n\n    /* ensure that 'x' is double */\n    if(TYPEOF(x) != REALSXP) {\n      PROTECT(x = coerceVector(x, REALSXP)); P++;\n    }\n    double *d_x = REAL(x);\n\n    if(ncols(x) > 1) {\n      error(\"ncol(x) > 1; ZLEMA only supports univariate 'x'\");\n    }\n\n    int i_n = asInteger(n);\n    double d_ratio = asReal(ratio);\n\n    if(R_NilValue == n || i_n <= 0) {\n      if(R_NilValue == ratio || d_ratio <= 0.0) {\n        error(\"either 'n' or 'ratio' must be specified and > 0\\n'n' is %d and 'ratio' is %1.6f\", i_n, d_ratio);\n      } else {\n        /* If ratio is specified, and n is not, set n to approx 'correct'\n         * value backed out from ratio */\n        i_n  = (int)(2.0 / d_ratio - 1.0);\n      }\n    } else {\n      /* Determine decay ratio */\n      if(R_NilValue == ratio) {\n        d_ratio = 2.0 / (i_n + 1);\n      } else {\n        /* ratio != NULL -> warn that 'n' will be used instead */\n        warning(\"both 'n' and 'ratio' are specified; using 'n'\");\n      }\n    }\n\n    /* Input object length */\n    int nr = nrows(x);\n\n    /* Initialize result R object */\n    SEXP result;\n    PROTECT(result = allocVector(REALSXP,nr)); P++;\n    double *d_result = REAL(result);\n\n    /* check for non-leading NAs and get first non-NA location */\n    SEXP _first = PROTECT(xts_na_check(x, ScalarLogical(TRUE))); P++;\n    int first = INTEGER(_first)[0];\n    if(i_n + first > nr) {\n      error(\"not enough non-NA values\");\n    }\n\n    /* Set leading NAs in output */\n    for(i = 0; i < first; i++) {\n      d_result[i] = NA_REAL;\n    }\n\n    /* Raw mean to start EMA */\n    double seed = 0.0;\n    for(i = first; i < first + i_n; i++) {\n      d_result[i] = NA_REAL;\n      seed += d_x[i] / i_n;\n    }\n    d_result[first + i_n - 1] = seed;\n\n    double lag = 1.0 / d_ratio;\n    double wt = fmod(lag, 1.0);\n    double w1 = 1.0 - wt;\n    double r1 = 1.0 - d_ratio;\n\n    /* Loop over non-NA input values */\n    for(i = first + i_n; i < nr; i++) {\n      int loc = (int)(i - lag);\n      double value = 2 * d_x[i] - (w1 * d_x[loc] + wt * d_x[loc+1]);\n      d_result[i] = d_ratio * value + r1 * d_result[i-1];\n    }\n\n    /* UNPROTECT R objects and return result */\n    UNPROTECT(P);\n    return(result);\n}\n"
  },
  {
    "path": "src/percent_rank.c",
    "content": "/*\n *  TTR: Technical Trading Rules\n *\n *  Copyright (C) 2012-2017  Charlie Friedemann, Joshua M. Ulrich\n *\n *  This program is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 2 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <R.h>\n#include <Rinternals.h>\n\ndouble calc_n_less(double* x, double mult, int i, int j1)\n{\n  double n_less = mult;\n  /* Loop over window */\n  for (int j = j1; j < i; j++) {\n    double diff = x[j] - x[i];\n    if (diff < 0) {\n      n_less = n_less + 1.0;\n    } else if (fabs(diff) < 1e-8) {\n      n_less = n_less + mult;\n    }\n  }\n  return n_less;\n}\n\n/* Calculate a running/rolling percent rank,\n * or a cumulative version */\nSEXP ttr_rollPercentRank(SEXP _x, SEXP _n, SEXP _cumul, SEXP _mult)\n{\n  int i, P = 0;\n\n  /* ensure correct types */\n  if (TYPEOF(_x) != REALSXP) {\n    PROTECT(_x = coerceVector(_x, REALSXP)); P++;\n  }\n  double *d_x = REAL(_x);\n  int n = asInteger(_n);\n  int cumul = asLogical(_cumul);\n  double mult = asReal(_mult);\n\n  int nr = nrows(_x);\n\n  /* Initialize result R object */\n  SEXP result;\n  PROTECT(result = allocVector(REALSXP, nr)); P++;\n  double *d_result = REAL(result);\n\n  /* Find first non-NA input value */\n  int beg = n - 1;\n  int n_na = 0;\n  for (i = 0; i < beg; i++) {\n    /* first 'n' observations are set to NA */\n    d_result[i] = NA_REAL;\n    /* Account for leading NAs in input */\n    if (ISNA(d_x[i])) {\n      beg++;\n      n_na++;\n      if (beg >= nr) {\n        error(\"runPercentRank input has %d rows, %d NA. Cannot calculate result with n = %d.\",\n            nr, n_na, n);\n      }\n    }\n  }\n\n  /* Loop over non-NA input values */\n  if (cumul) {\n    d_result[beg] = mult;\n    for (i = beg+1; i < nr; i++) {\n      double n_less = calc_n_less(d_x, mult, i, 0);\n      d_result[i] = n_less / (i + 1);\n    }\n  } else {\n    for (i = beg; i < nr; i++) {\n      double n_less = calc_n_less(d_x, mult, i, i-n+1);\n      d_result[i] = n_less / n;\n    }\n  }\n\n  UNPROTECT(P);\n  return(result);\n}\n"
  },
  {
    "path": "src/runfun.c",
    "content": "/*\n *  TTR: Technical Trading Rules\n *\n *  Copyright (C) 2007-2018  Joshua M. Ulrich\n *\n *  This program is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 2 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string.h>  /* for memcpy */\n#include \"ttr.h\"\n\nSEXP runsum(SEXP _x, SEXP _n)\n{\n  int i, P = 0;\n\n  /* ensure that 'x' is double */\n  if (TYPEOF(_x) != REALSXP) {\n    _x = PROTECT(coerceVector(_x, REALSXP)); P++;\n  }\n  double *x = REAL(_x);\n  int n = asInteger(_n);\n\n  /* Input object length */\n  int nr = nrows(_x);\n\n  /* Initialize result R object */\n  SEXP _result = PROTECT(allocVector(REALSXP, nr)); P++;\n  double *result = REAL(_result);\n\n  /* check for non-leading NAs and get first non-NA location */\n  SEXP _first = PROTECT(xts_na_check(_x, ScalarLogical(TRUE))); P++;\n  int first = INTEGER(_first)[0];\n  if (n + first > nr) {\n    error(\"not enough non-NA values\");\n  }\n\n  /* Set leading NAs in output */\n  for (i = 0; i < first; i++) {\n    result[i] = NA_REAL;\n  }\n\n  /* Raw sum to start running sum */\n  double seed = 0.0;\n  for (i = first; i < first + n; i++) {\n    result[i] = NA_REAL;\n    seed += x[i];\n  }\n  result[first + n - 1] = seed;\n\n  /* Loop over non-NA input values */\n  for (i = first + n; i < nr; i++) {\n    result[i] = result[i-1] + x[i] - x[i-n];\n  }\n\n  /* UNPROTECT R objects and return result */\n  UNPROTECT(P);\n  return _result;\n}\n\nSEXP runrange(SEXP _x, SEXP _n)\n{\n    int i, j, P = 0;\n\n    /* ensure x is double */\n    if (TYPEOF(_x) != REALSXP) {\n        _x = PROTECT(coerceVector(_x, REALSXP)); P++;\n    }\n    double *x = REAL(_x);\n    int n = asInteger(_n);\n\n    /* input length */\n    int nr = nrows(_x);\n\n    /* allocate result: 2 columns (min, max) */\n    SEXP _result = PROTECT(allocMatrix(REALSXP, nr, 2)); P++;\n    double *result = REAL(_result);\n\n    \n    /* check for non-leading NAs and get first non-NA location */\n    SEXP _first = PROTECT(xts_na_check(_x, ScalarLogical(TRUE))); P++;\n    int first = INTEGER(_first)[0];\n    if (n + first > nr) {\n      error(\"not enough non-NA values\");\n    }\n\n    /* leading NAs */\n    for (i = 0; i < first; i++) {\n        result[i] = NA_REAL;               /* min */\n        result[i + nr] = NA_REAL;          /* max */\n    }\n\n    /* initialize first window */\n    double lmin = x[first],  lmax = x[first];\n    for (i = first; i < first + n; i++) {\n        result[i] = NA_REAL;\n        result[i + nr] = NA_REAL;\n        if (x[i] < lmin) lmin = x[i];\n        if (x[i] > lmax) lmax = x[i];\n    }\n    result[first + n - 1] = lmin;\n    result[first + n - 1 + nr] = lmax;\n\n    /* main loop */\n    for (i = first + n; i < nr; i++) {\n        lmin = x[i];\n        lmax = x[i];\n        for (j = 1; j < n; j++) {\n            double v = x[i - j];\n            if (v < lmin) lmin = v;\n            if (v > lmax) lmax = v;\n        }\n        result[i] = lmin;\n        result[i + nr] = lmax;\n    }\n\n    UNPROTECT(P);\n    return _result;\n}\n\ntypedef double (*tiebreaker)(const double, const double);\n\nstatic inline double\ntiebreaker_lt(const double a, const double b)\n{\n  return (a < b) ? a : b;\n}\nstatic inline double\ntiebreaker_gt(const double a, const double b)\n{\n  return (a > b) ? a : b;\n}\nstatic inline double\ntiebreaker_eq(const double a, const double b)\n{\n  return (a + b) / 2.0;\n}\n\nstatic inline double\nttr_median(double *x, int i, int n, tiebreaker tie_func)\n{\n  /* NOTE: 'i' and 'n' are 1-based */\n  int N = n-i+1;          // number of observations in the window\n  int flag = N-2*(N/2);   // even number of observations?\n  int mid = (i-1)+N/2-1;  // 0-based index midpoint\n  R_qsort(x, i, n);\n\n  double median = (flag) ? x[mid+1] : tie_func(x[mid] , x[mid+1]);\n  return median;\n}\n\nSEXP runmedian(SEXP _x, SEXP _n, SEXP _tiebreak, SEXP _cumulative)\n{\n  int i, P = 0;\n\n  /* ensure that 'x' is double */\n  if (TYPEOF(_x) != REALSXP) {\n    _x = PROTECT(coerceVector(_x, REALSXP)); P++;\n  }\n  double *x = REAL(_x);\n  int n = asInteger(_n);\n  int tiebreak = asInteger(_tiebreak);\n  int cumulative = asLogical(_cumulative);\n\n  /* Input object length */\n  int nr = nrows(_x);\n\n  /* Initialize result R object */\n  SEXP _result = PROTECT(allocVector(REALSXP, nr)); P++;\n  double *result = REAL(_result);\n\n  /* check for non-leading NAs and get first non-NA location */\n  SEXP _first = PROTECT(xts_na_check(_x, ScalarLogical(TRUE))); P++;\n  int first = INTEGER(_first)[0];\n  if (n + first > nr) {\n    error(\"not enough non-NA values\");\n  }\n\n  /* Set leading NAs in output */\n  for (i = 0; i < first + n; i++) {\n    result[i] = NA_REAL;\n  }\n\n  tiebreaker tie_func = NULL;\n  if (tiebreak == 0) {\n    tie_func = tiebreaker_eq;\n  }\n  else if (tiebreak < 0) {\n    tie_func = tiebreaker_lt;\n  }\n  else if (tiebreak > 0) {\n    tie_func = tiebreaker_gt;\n  }\n\n  SEXP _window;\n  double *window;\n  int first_i = first + n - 1;\n\n  if (cumulative) {\n    _window = PROTECT(duplicate(_x)); P++;\n    window = REAL(_window);\n\n    for (i = first_i; i < nr; i++) {\n      result[i] = ttr_median(window, first+1, i+1, tie_func);\n    }\n  } else {\n    _window = PROTECT(allocVector(REALSXP, n)); P++;\n    window = REAL(_window);\n\n    for (i = first_i; i < nr; i++) {\n      memcpy(window, &x[i-n+1], n * sizeof(double));\n      result[i] = ttr_median(window, 1, n, tie_func);\n    }\n  }\n\n  /* UNPROTECT R objects and return result */\n  UNPROTECT(P);\n  return _result;\n}\n\nstatic inline double\nttr_mean(const double *x, const int n)\n{\n  double mean = x[0] / n;\n  int i;\n  for (i = 1; i < n; i++) {\n    mean += x[i] / n;\n  }\n  return mean;\n}\n\nSEXP runmad(SEXP _x, SEXP _center, SEXP _n, SEXP _type,\n    SEXP _tiebreak, SEXP _cumulative)\n{\n  int i, j, P = 0;\n\n  /* ensure 'x' and 'center' are double */\n  if (TYPEOF(_x) != REALSXP) {\n    _x = PROTECT(coerceVector(_x, REALSXP)); P++;\n  }\n  if (TYPEOF(_center) != REALSXP) {\n    _center = PROTECT(coerceVector(_center, REALSXP)); P++;\n  }\n  double *x = REAL(_x);\n  double *center = REAL(_center);\n  int n = asInteger(_n);\n  int type = asInteger(_type);\n  int tiebreak = asInteger(_tiebreak);\n  int cumulative = asLogical(_cumulative);\n\n  /* Input object length */\n  int nr = nrows(_x);\n  if (nr != nrows(_center)) {\n    error(\"'x' and 'center' must have the same number of observations\");\n  }\n\n  /* Initialize result R object */\n  SEXP _result = PROTECT(allocVector(REALSXP, nr)); P++;\n  double *result = REAL(_result);\n\n  /* check for non-leading NAs and get first non-NA location */\n  SEXP _first = PROTECT(xts_na_check(_x, ScalarLogical(TRUE))); P++;\n  int first = INTEGER(_first)[0];\n  if (n + first > nr) {\n    error(\"not enough non-NA values in 'x'\");\n  }\n\n  /* Set leading NAs in output */\n  for (i = 0; i < first + n; i++) {\n    result[i] = NA_REAL;\n  }\n\n  tiebreaker tie_func = NULL;\n  if (tiebreak == 0) {\n    tie_func = tiebreaker_eq;\n  }\n  else if (tiebreak < 0) {\n    tie_func = tiebreaker_lt;\n  }\n  else if (tiebreak > 0) {\n    tie_func = tiebreaker_gt;\n  }\n\n  SEXP _window;\n  double *window;\n  int first_i = first + n - 1;\n\n  if (cumulative) {\n    _window = PROTECT(duplicate(_x)); P++;\n    window = REAL(_window);\n\n    if (type) {\n      for (i = first_i; i < nr; i++) {\n        int N = i-first+1;\n        for (j = 0; j < N; j++) {\n          window[j] = fabs(x[i-j] - center[i]);\n        }\n        result[i] = ttr_median(window, 1, N, tie_func);\n      }\n    } else {\n      for (i = first_i; i < nr; i++) {\n        for (j = 0; j <= i; j++) {\n          window[j] = fabs(x[i-j] - center[i]);\n        }\n        result[i] = ttr_mean(window, i+1);\n      }\n    }\n  } else {\n    _window = PROTECT(allocVector(REALSXP, n)); P++;\n    window = REAL(_window);\n\n    if (type) {\n      for (i = first_i; i < nr; i++) {\n        for (j = 0; j < n; j++) {\n          window[j] = fabs(x[i-j] - center[i]);\n        }\n        result[i] = ttr_median(window, 1, n, tie_func);\n      }\n    } else {\n      for (i = first_i; i < nr; i++) {\n        for (j = 0; j < n; j++) {\n          window[j] = fabs(x[i-j] - center[i]);\n        }\n        result[i] = ttr_mean(window, n);\n      }\n    }\n  }\n\n  /* UNPROTECT R objects and return result */\n  UNPROTECT(P);\n  return _result;\n}\n\nSEXP runcov(SEXP _x, SEXP _y, SEXP _n, SEXP _sample, SEXP _cumulative)\n{\n  int i, j, P = 0;\n\n  /* ensure 'x' and 'y' are double */\n  if (TYPEOF(_x) != REALSXP) {\n    _x = PROTECT(coerceVector(_x, REALSXP)); P++;\n  }\n  if (TYPEOF(_y) != REALSXP) {\n    _y = PROTECT(coerceVector(_y, REALSXP)); P++;\n  }\n  double *x = REAL(_x);\n  double *y = REAL(_y);\n  int n = asInteger(_n);\n  int cumulative = asLogical(_cumulative);\n  int sample = asLogical(_sample);\n\n  /* Input object length */\n  int nr = nrows(_x);\n  if (nr != nrows(_y)) {\n    error(\"'x' and 'y' must have the same number of observations\");\n  }\n\n  /* Initialize result R object */\n  SEXP _result = PROTECT(allocVector(REALSXP, nr)); P++;\n  double *result = REAL(_result);\n\n  /* check for non-leading NAs and get first non-NA location */\n  SEXP _first_x = PROTECT(xts_na_check(_x, ScalarLogical(TRUE))); P++;\n  int first_x = INTEGER(_first_x)[0];\n  if (n + first_x > nr) {\n    error(\"not enough non-NA values in 'x'\");\n  }\n  SEXP _first_y = PROTECT(xts_na_check(_y, ScalarLogical(TRUE))); P++;\n  int first_y = INTEGER(_first_y)[0];\n  if (n + first_y > nr) {\n    error(\"not enough non-NA values in 'y'\");\n  }\n  int first = (first_x > first_y) ? first_x : first_y;\n  int first_i = first + n - 1;\n\n  /* Set leading NAs in output */\n  for (i = 0; i < first_i; i++) {\n    result[i] = NA_REAL;\n  }\n\n  SEXP _window;\n  double *window, mu_x, mu_y;\n\n  if (cumulative) {\n    double sum_x = 0.0;\n    double sum_y = 0.0;\n\n    // Initialize means\n    for (i = first; i < first_i; i++) {\n      sum_x += x[i];\n      sum_y += y[i];\n    }\n    mu_x = sum_x / (first+1);\n    mu_y = sum_y / (first+1);\n\n    for (i = first_i; i < nr; i++) {\n      double n_window = (double)(i-first_i+n);\n\n      sum_x += x[i];\n      sum_y += y[i];\n\n      mu_x = sum_x / n_window;\n      mu_y = sum_y / n_window;\n\n      result[i] = 0.0;\n      for (j = first; j <= i; j++) {\n        result[i] += (x[j] - mu_x) * (y[j] - mu_y);\n      }\n      result[i] /= sample ? (n_window-1.0) : n_window;\n    }\n    /* Set first non-NA element to NA to match var() and sd()\n     * because var/sd of 1 observation is not defined */\n    result[first] = NA_REAL;\n  } else {\n    double denom = sample ? (n-1) : n;\n\n    if (n == 1) {\n      warning(\"(co-)variance is not defined for one observation; returning NA\");\n      for (i = first_i; i < nr; i++) {\n        result[i] = NA_REAL;\n      }\n    } else {\n      _window = PROTECT(allocVector(REALSXP, n)); P++;\n      window = REAL(_window);\n\n      size_t window_size = n * sizeof(double);\n\n      for (i = first_i; i < nr; i++) {\n        memcpy(window, &x[i-n+1], window_size);\n        mu_x = ttr_mean(window, n);\n        memcpy(window, &y[i-n+1], window_size);\n        mu_y = ttr_mean(window, n);\n\n        result[i] = 0.0;\n        for (j = 0; j < n; j++) {\n          result[i] += (x[i-j] - mu_x) * (y[i-j] - mu_y);\n        }\n        result[i] /= denom;\n      }\n    }\n  }\n\n  /* UNPROTECT R objects and return result */\n  UNPROTECT(P);\n  return _result;\n}\n"
  },
  {
    "path": "src/sar.c",
    "content": "/*\n *  TTR: Technical Trading Rules\n *\n *  Copyright (C) 2007-2013  Joshua M. Ulrich\n *\n *  This program is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 2 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <R.h>\n#include <Rinternals.h>\n#include <math.h>\n\nSEXP sar (SEXP hi, SEXP lo, SEXP xl) {\n\n    /* Initialize loop and PROTECT counters */\n    int i, P=0;\n\n    /* Ensure all arguments are double */\n    if(TYPEOF(hi) != REALSXP) {\n      PROTECT(hi = coerceVector(hi, REALSXP)); P++;\n    }\n    if(TYPEOF(lo) != REALSXP) {\n      PROTECT(lo = coerceVector(lo, REALSXP)); P++;\n    }\n    if(TYPEOF(xl) != REALSXP) {\n      PROTECT(xl = coerceVector(xl, REALSXP)); P++;\n    }\n\n    /* Pointers to function arguments */\n    double *d_hi = REAL(hi);\n    double *d_lo = REAL(lo);\n    double *d_xl = REAL(xl);\n\n    /* check acceleration factors */\n    if(d_xl[0] <= 0) error(\"acceleration factor must be > 0\");\n    if(d_xl[1] <= d_xl[0]) error(\"maximum acceleration must be > acceleration factor\");\n\n    /* Input object length */\n    int nr = nrows(hi);\n\n    /* Initialize result R object */\n    SEXP sar; PROTECT(sar = allocMatrix(REALSXP, nr, 1)); P++;\n    double *d_sar = REAL(sar);\n\n    /* Find first non-NA value */\n    int beg = 1;\n    for(i=0; i < nr; i++) {\n      if( ISNA(d_hi[i]) || ISNA(d_lo[i]) ) {\n        d_sar[i] = NA_REAL;\n        beg++;\n      } else {\n        break;\n      }\n    }\n\n    /* Initialize values needed by the routine */\n    int sig0 = 1, sig1 = 0;\n    double xpt0 = d_hi[beg-1], xpt1 = 0;\n    double af0 = d_xl[0], af1 = 0;\n    double lmin, lmax;\n\n    double hi1 = d_hi[beg-1];\n    double lo1 = d_lo[beg-1];\n    double mu1 = (hi1 + lo1) / 2.0;\n\n    /* Use stdev of first high and low as the initial gap */\n    double initGap = sqrt((hi1-mu1)*(hi1-mu1) + (lo1-mu1)*(lo1-mu1));\n    d_sar[beg-1] = d_lo[beg-1]-initGap;\n\n    for(i=beg; i < nr; i++) {\n      /* Increment signal, extreme point, and acceleration factor */\n      sig1 = sig0;\n      xpt1 = xpt0;\n      af1 = af0;\n\n      /* Local extrema */\n      lmin = fmin(d_lo[i-1], d_lo[i]);\n      lmax = fmax(d_hi[i-1], d_hi[i]);\n\n      /* Create signal and extreme price vectors */\n      if( sig1 == 1 ) {  /* Previous buy signal */\n        sig0 = (d_lo[i] > d_sar[i-1]) ? 1 : -1;  /* New signal */\n        xpt0 = fmax(lmax, xpt1);                 /* New extreme price */\n      } else {           /* Previous sell signal */\n        sig0 = (d_hi[i] < d_sar[i-1]) ? -1 : 1;  /* New signal */\n        xpt0 = fmin(lmin, xpt1);                 /* New extreme price */\n      }\n\n      /*\n       * Calculate acceleration factor (af)\n       * and stop-and-reverse (sar) vector\n       */\n\n      /* No signal change */\n      if( sig0 == sig1 ) {\n        /* Initial calculations */\n        d_sar[i] = d_sar[i-1] + ( xpt1 - d_sar[i-1] ) * af1;\n        af0 = (af1 == d_xl[1]) ? d_xl[1] : (d_xl[0] + af1);\n        /* Current buy signal */\n        if( sig0 == 1 ) {\n          af0 = (xpt0 > xpt1) ? af0 : af1;  /* Update acceleration factor */\n          d_sar[i] = fmin(d_sar[i],lmin);   /* Determine sar value */\n        }\n        /* Current sell signal */\n        else {\n          af0 = (xpt0 < xpt1) ? af0 : af1;  /* Update acceleration factor */\n          d_sar[i] = fmax(d_sar[i],lmax);   /* Determine sar value */\n        }\n      }\n      /* New signal */\n      else {\n        af0 = d_xl[0];    /* reset acceleration factor */\n        d_sar[i] = xpt0;  /* set sar value */\n      }\n    }\n    \n    /* UNPROTECT R objects and return result */\n    UNPROTECT(P);\n    return(sar);\n}\n\n"
  },
  {
    "path": "src/ttr.h",
    "content": "#ifndef _TTR_H_\n#define _TTR_H_\n\n#include <Rinternals.h>\n\n/* declare functions called via .Call() */\nSEXP adjRatios(SEXP, SEXP, SEXP);\nSEXP aroon_max(SEXP, SEXP);\nSEXP ema(SEXP, SEXP, SEXP, SEXP);\nSEXP evwma(SEXP, SEXP, SEXP);\nSEXP sar(SEXP, SEXP, SEXP);\nSEXP ttr_rollPercentRank(SEXP, SEXP, SEXP, SEXP);\nSEXP ttr_zigzag(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);\nSEXP wilderSum(SEXP, SEXP);\nSEXP wma(SEXP, SEXP, SEXP);\nSEXP zlema(SEXP, SEXP, SEXP);\nSEXP runsum(SEXP, SEXP);\nSEXP runrange(SEXP, SEXP);\nSEXP runmedian(SEXP, SEXP, SEXP, SEXP);\nSEXP runmad(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);\nSEXP runcov(SEXP, SEXP, SEXP, SEXP, SEXP);\n\n/* declare xts imports */\nextern SEXP (*xts_na_check)(SEXP, SEXP);\n#endif\n"
  },
  {
    "path": "src/wilderSum.c",
    "content": "/*\n *  TTR: Technical Trading Rules\n *\n *  Copyright (C) 2007-2013  Joshua M. Ulrich\n *\n *  This program is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 2 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <R.h>\n#include <Rinternals.h>\n\nSEXP wilderSum (SEXP x, SEXP n) {\n\n    /* Initialize loop and PROTECT counters */\n    int i, P=0;\n\n    /* assure that 'x' is double */\n    if(TYPEOF(x) != REALSXP) {\n      PROTECT(x = coerceVector(x, REALSXP)); P++;\n    }\n\n    /* Pointers to function arguments */\n    double *d_x = REAL(x);\n    int i_n = asInteger(n);\n\n    /* Input object length */\n    int nr = nrows(x);\n\n    /* Initialize result R object */\n    SEXP result;\n    PROTECT(result = allocVector(REALSXP,nr)); P++;\n    double *d_result = REAL(result);\n\n    /* Find first non-NA input value */\n    int beg = i_n - 1;\n    double sum = 0;\n    for(i = 0; i < beg; i++) {\n        /* Account for leading NAs in input */\n        if(ISNA(d_x[i])) {\n            d_result[i] = NA_REAL;\n            beg++;\n            d_result[beg] = 0;\n            continue;\n        }\n        /* Set leading NAs in output */\n        if(i < beg) {\n            d_result[i] = NA_REAL;\n        }\n        /* Calculate raw sum to start */\n        sum += d_x[i];\n    }\n\n    d_result[beg] = d_x[i] + sum * (i_n-1)/i_n;\n\n    /* Loop over non-NA input values */\n    for(i = beg+1; i < nr; i++) {\n        d_result[i] = d_x[i] + d_result[i-1] * (i_n-1)/i_n;\n    }\n\n    /* UNPROTECT R objects and return result */\n    UNPROTECT(P);\n    return(result);\n}\n"
  },
  {
    "path": "src/zigzag.c",
    "content": "/*\n *  TTR: Technical Trading Rules\n *\n *  Copyright (C) 2007-2017  Joshua M. Ulrich\n *\n *  This program is free software: you can redistribute it and/or modify\n *  it under the terms of the GNU General Public License as published by\n *  the Free Software Foundation, either version 2 of the License, or\n *  (at your option) any later version.\n *\n *  This program is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n *  GNU General Public License for more details.\n *\n *  You should have received a copy of the GNU General Public License\n *  along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <R.h>\n#include <Rinternals.h>\n\n/* price and its array index */\ntypedef struct {\n  double price;\n  int index;\n} price_and_index;\n\nSEXP ttr_zigzag\n(SEXP _high, SEXP _low, SEXP _change, SEXP _percent, SEXP _retrace,\n SEXP _last_extreme)\n{\n  double* high = REAL(_high);\n  double* low = REAL(_low);\n  double change = asReal(_change);\n  int use_percent = asLogical(_percent);\n  int use_retrace = asLogical(_retrace);\n  int use_last_ex = asLogical(_last_extreme);\n\n  if (use_percent)\n    change = change / 100.0;\n\n  int n = length(_high);\n  SEXP _zigzag = PROTECT(allocVector(REALSXP, n));\n  double* zigzag = REAL(_zigzag);\n\n  price_and_index reference, inflection;\n  reference.price = (high[0] + low[0]) / 2;\n  reference.index = 0;\n  inflection.price = (high[1] + low[1]) / 2;\n  inflection.index = 1;\n\n  double extreme_min, extreme_max, local_min, local_max;\n  int signal = 0;\n\n  for (int i = 1; i < n; i++) {\n    /* Initialize all zigzag values to NA */\n    zigzag[i] = NA_REAL;\n\n    if (use_percent) {\n      /* If % change given (absolute move) */\n      extreme_min = inflection.price * (1.0 - change);\n      extreme_max = inflection.price * (1.0 + change);\n    } else {\n      /* If $ change given (only absolute moves make sense) */\n      extreme_min = inflection.price - change;\n      extreme_max = inflection.price + change;\n    }\n    /* Find local maximum and minimum */\n    local_max = inflection.price > high[i] ? inflection.price : high[i];\n    local_min = inflection.price < low[i] ? inflection.price : low[i];\n\n    /* Find first trend */\n    if (signal == 0) {\n      if (use_retrace) {\n        /* Retrace prior move */\n        signal = (inflection.price >= reference.price) ? 1 : -1;\n      } else {\n        /* Absolute move */\n        if (local_min <= extreme_min) {\n          /* Confirmed Downtrend */\n          signal = -1;\n        }\n        if (local_max >= extreme_max) {\n          /* Confirmed Uptrend */\n          signal = 1;\n        }\n      }\n    }\n    /* Downtrend */\n    if (signal == -1) {\n      /* New Minimum */\n      if (low[i] == local_min) {\n        /* Last Extreme */\n        if (use_last_ex) {\n          inflection.price = low[i];\n          inflection.index = i;\n        } else {\n          /* First Extreme */\n          if (low[i] != low[i-1]) {\n            inflection.price = low[i];\n            inflection.index = i;\n          }\n        }\n      }\n      /* Retrace prior move */\n      if (use_retrace) {\n        extreme_max = inflection.price +\n          ((reference.price - inflection.price) * change);\n      }\n      /* Trend Reversal */\n      if (high[i] >= extreme_max) {\n        zigzag[reference.index] = reference.price;\n        reference = inflection;\n        inflection.price = high[i];\n        inflection.index = i;\n        signal = 1;\n        continue;\n      }\n    }\n    /* Uptrend */\n    if (signal == 1) {\n      /* New Maximum */\n      if (high[i] == local_max) {\n        /* Last Extreme */\n        if (use_last_ex) {\n          inflection.price = high[i];\n          inflection.index = i;\n        } else {\n          /* First Extreme */\n          if (high[i] != high[i-1]) {\n            inflection.price = high[i];\n            inflection.index = i;\n          }\n        }\n      }\n      /* Retrace prior move */\n      if (use_retrace) {\n        extreme_min = inflection.price -\n          ((inflection.price - reference.price) * change);\n      }\n      /* Trend Reversal */\n      if (low[i] <= extreme_min) {\n        zigzag[reference.index] = reference.price;\n        reference = inflection;\n        inflection.price = low[i];\n        inflection.index = i;\n        signal = -1;\n        continue;\n      }\n    }\n  }\n  zigzag[reference.index] = reference.price;\n  zigzag[inflection.index] = inflection.price;\n\n  UNPROTECT(1);\n  return _zigzag;\n}\n"
  },
  {
    "path": "tests/tinytest.R",
    "content": "# run package unit tests\nif (requireNamespace(\"tinytest\", quietly = TRUE)) {\n    suppressPackageStartupMessages(library(\"TTR\"))\n    use_color <- as.logical(Sys.getenv(\"_PKG_TINYTEST_COLOR_\", FALSE))\n    verbosity <- as.integer(Sys.getenv(\"_PKG_TINYTEST_VERBOSE_\", 1))\n    cat(\"tinytest colored output:\", use_color,\n        \"\\ntinytest verbosity:\", verbosity, \"\\n\")\n    tinytest::test_package(\"TTR\", color = use_color, verbose = verbosity)\n}\n\n"
  }
]