mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-30 22:11:55 +00:00
* [Release] Merge 4.4.0 Release From Main Into Develop (#7027) * add snowflake integration video (#6339) * [HotFix] Fix broken URLs in docs page. (#6368) * Fix broken URLs * use full URL to other docs pages. * [Release] 4.2.0 (#6422) * [Docs] Remove Reference to `to_chart` in OBBject. (#6096) * remove reference to to_chart in OBBject. * put chart description back in OBBject properties * [Feature] - Create openbb assets folder (#6101) * create openbb assets folder * fix unittest * rebuild --------- Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> * [BugFix] Fixes to_df() where the date series contains multiple TZ-offsets. (#6099) * allow mixed utc offset in a tz-aware date column * enforce ascending from all providers for price.historical * fix tests * add comments and apply treatment to basemodel_from_df before JSON output * yfinance consistency * add unit test * add unit test * better test * ruff --------- Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> * Update the quantitative extension to make more sense (#6087) * Split out a rolling submenu for the rolling functions * Make a performance and a stats submenu. * Test the statistics functions * lint * lint * dupe test * pylint * ruff * Try tests quick * black magic signature funcs * fix my custom tests * Fix the existing imports/urls * push the api update * okay I figured out whats going on * this should be all of them * Correct docstringing examples --------- Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * [BugFix] Fix ECB Yield Curve (#6108) * fix ecb yield curve * standard model update * Update unit-test workflow to check for changes to openbb_platform (#6109) * [Bug fix] - Fix package mypy (#6110) * fix: package mypy * types * black * [Feature] - Equity router descriptions & examples (#6103) * feat: equity/calendar * feat: compare router * fix descriptions * darkpool + discovery * fix paragraph issues * fix descriptions * fundamental part 1 * fundamental part2 * transcipts * ownership * fix * price * shorts * Update darkpool_router.py * minor fix * shorts examples * examples * ruff * black --------- Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> * [Feature] - Add `exception_handler` decorator to static (#6112) * add exception handler decorator * add exception handler decorator code * updated static * rebuild to fix docstring indentation --------- Co-authored-by: Diogo Sousa <montezdesousa@gmail.com> * update extensions list (#6114) * add missing field descriptions to yfinance equity price historical (#6116) Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> * remove charting extension env var (#6118) * [BugFix] Fix Company News (#6111) * fix company news * update tests * multiple symbols for polygon * don't include pageSize in Benzinga querystring, fixed as 100 * remove extra space * black * unused imports * make benzinga test cassette smaller * missing params * clear empty strings --------- Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> * [BugFix] Allow Multiple Symbols in `equity.fundamental.metrics()` from `yfinance` (#6124) * allow multiple symbols in key_metrics from yfinance * field order thing * remove unnecessary function (#6125) * [Docs] Update OpenBB Copilot docs (#6106) * WIP: Tweak description. * WIP: Experimenting with react-player * WIP: Add copilot docs. * fixes videos width/height * WIP: Refine videos and copy. * WIP: Add last videos and sections. * Add bring-your-own-copilot section. * Tweak grammar. * Add copilot link. * Fix typos. --------- Co-authored-by: jose-donato <43375532+jose-donato@users.noreply.github.com> * [Enhancement] Add Previous Close to DATA_DESCRIPTIONS (#6120) * add data description for previous close * ..just the one * update the model tripped by this change --------- Co-authored-by: montezdesousa <79287829+montezdesousa@users.noreply.github.com> * added australia as a country also (#6131) * [Bug fix] - Fix regulator cik map standard model (#6129) * Fix regulator cik map standard model * fix description * Update cik_map.py * increase timeout to 30 (#6115) Co-authored-by: James Maslek <jmaslek11@gmail.com> * clean up some v3 deps (#6105) * clean up some v3 deps * forgot we need to do the requirements txt files * not sure it matters, but run ruff + black * am addicted to bug fixes --------- Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * [Bug fix] - explicit multiple items docstring (#6127) * explicit multiple items docstring * rebuiild * rebuild again --------- Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * [Feature] Pretty Pydantic `ValidationError` exceptions (#6130) * fix validator in fmp IndexHistorical model * make ValidationError pretty * modify arg error * linting fmp IndexHistorical * black * remove unused code * tmx etf info (#6132) Co-authored-by: montezdesousa <79287829+montezdesousa@users.noreply.github.com> * [Feature] - Platform V4 Markdown Generator V2 (#6094) * add recent `openapi.json` * fix data types in models * removed `openapi.json` * set default date value as None in PolygonCurrencyPairs class * add function to generate reference.json file * reworked function to improve readability * reword function to add seo metadata * add functions for creating markdown sections * add code to extract data card markdown title * add additional functions for generating index and data models file * extract first sentence of the description for cards * code cleanup and documentation * linting * linting polygon models * add openbb import statement in create_reference_markdown_examples function * add POST method functions * cleanup; reworked generate_reference_index_files function * moved development section to 7th position in the sidebar * fix POST function params default value add standard flag to QueryParams and Data fields cleanup * add type expansion from package_builder.MethodDefinition * sort data models cards alphabetically make printing less verbose * make MAX_CARDS global display less content in cards in Commannds section * cleanup * Remove '_' from the cards under Commands section * " to ' in econometrics/causality * replace ' with " in ReferenceCard for reference dir index files * remove extra . from the quantile function description * shoutout to @deeleeramone for finding POST method description bug! * set correct value for standard field * handle BaseModel types in provider data fields * unit tests for the platform markdown generator v2 * yeet 'Default' and 'Optional' columns in the 'Data' section * last minute bug fix * add info for multiple symbols * make multiple items info same as platform static * organize sections properly * sort reference sub-directories alphabetically * extra space in 'OBBject extra' description * add type expansion for fields with multiple items POST method cleanup --------- Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> * [Docs] Adds Example Notebook for the Implied Earnings Move (#6128) * adds example notebook for the implied earnings move * remove commented out line --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> * [Feature] - Sync with new openapi.json (#6137) * feat: create data tabs * fix: uncomment * fix: remove unecessary comment * sort side bar * comment * uncomment * use .dev functions.json + clean traverse * fix futures example * fix example * point to .co * Fix the v3 markdown generation workflow (#6138) * fix workflow * debug time * see if the docs generate at least * ahhhh i found it * getting there * put the test first * some keys cleanup * small change to error message * update functions.json (#6140) * fix intraday check in charting ta_class (#6119) Co-authored-by: Henrique Joaquim <h.joaquim@campus.fct.unl.pt> * [BugFix] Display EconDB as source for macro (#6143) * [BugFix] Disable Intrinio `InstitutionalOwnership` model (#6142) * disable fetcher in init and fetcher tests * disable provider test params from equity python and api tests * updated static * add more examples into findSymbols (#6139) Co-authored-by: James Maslek <jmaslek11@gmail.com> * [BugFix] Fix SEC ETF Holdings Parsing Exception (#6121) * fix etf holdings * linting * black --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> * Docs/update xl docs (#6145) * remove print * update obb.get docs * example * md lint * fix get reference (#6147) * [BugFix] Filter OECD data using `start_date` and `end_date` parameters (#6144) * move constant dicts to constants.py filter by start_date and end_date * black * black again again * Merge 'main' into 'develop' (#6151) * Release/3.2.4 (#5696) * test * ultima description (#5541) * Updating showcase page (#5543) * updating showcase page * use sdk instead * add new bot command autopost docs (#5530) add new bot command autopost docs to docs.openbb.co Co-authored-by: James Maslek <jmaslek11@gmail.com> * Hotfix/ultima improvements (#5553) * tweaks for monetization * fix linting issue * fix: Modify 'load' behavior to append data to existing sheet (#5503) * fix: Modify 'load' behavior to append data to existing sheet Details: - Added logic to detect existing sheet and append data if present. - There is no direct way to append on the sheet, so I am reading the sheet to get the last row number and then writing after that row number. Resolves: #5472 * Fixed 'worksheet not found' error during export to an existing sheet * Changes: * Now if the sheet exists in the xlsx file it will ask the user if he wants to replace/append/create new sheet --------- Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * added platform API integration test to Nightly build (#5571) * Add columns to `stocks/search` (#5565) * Add columns to `stocks/search` isin, cusip, figi, composite_figi, shareclass_figi * Update test_search[False].txt * Update test_search[True].txt * Delete tests/openbb_terminal/stocks/cassettes/test_stocks_helper/test_search.yaml * Create test_search.yaml --------- Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * updating ultima urls (#5587) * fix: A value is trying to be set on a copy of a slice from a DataFrame #5582 (#5591) * Update README.md (#5598) * Hotfix/econometrics export filename fix (#5508) * fix: Modify 'load' behavior to append data to existing sheet Details: - Added logic to detect existing sheet and append data if present. - There is no direct way to append on the sheet, so I am reading the sheet to get the last row number and then writing after that row number. Resolves: #5472 * Added --export option for exporting to a desired file in /econometrics menu * Added a -f/--file option to provide the filename for export. Made -t/--type and -f/--file mutually exclusive. If -f is not given, -t is required and the filename will be generated based on the time and module. * Revert `helper_funcs.py` to original state * Made some arguments not required. * Minor changes asked by @deeleeramone * No sheet name * black --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * FIX #5600 Updated the Twitter logo to X logo (#5601) * Change Ultima paragraph (#5624) * change ultima paragraph * remove old paragraph * Update CONTRIBUTING.md (#5623) * mobile line-brake fixed (#5604) In the mobile view (media max 400px ), the text line "Installation >>" appears broken into smaller segments. Co-authored-by: James Maslek <jmaslek11@gmail.com> * Docs/terminalpro and improvement (#5622) * add first iteration of content for Terminal Pro * Update index.md * Update dashboards.md * Update folders.md * Update grouping.md * Update report.md * Update templates.md * Update quick-start.md * Update index.md * Update index.md * Update home.md * Update news.md * Update index.md * Update index.md * Update index.md * Update data-provider.md * Update chat-with-widget.md * Update data-manipulation.md * Update forecasting.md * fix: images self closing tags * fix: only pro visitors can see pro * inter font * improve SEO content and restructuring * add new package for toggle on tutorials * move folder around * improve main page of each prod * small updates and improvements * fix logo above * small improvement in headtitle for portfolio funcs * fix typos from OpenAI's GPT-4 * fix _category_ json * remove generic SEO words * add script that generates SEO for documentation * add missing file * remove sdk warning message * fix links for andrew --------- Co-authored-by: jose-donato <zmcdonato@gmail.com> Co-authored-by: jose-donato <43375532+jose-donato@users.noreply.github.com> Co-authored-by: andrewkenreich <andrew.kenreich@gmail.com> * Add light blue banner, blue when clicking sidebar + fix link in docusaurus.config.js (#5627) * typo * pro docs tab coloring * sidebar selection blue * redirecting missing * fix docs (#5646) * Fix the redirect for intro to the correct url for docs (#5658) * fix the redirect for intro to the correct url for docs * fix code linting --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> * Improve Pro documentation further (#5641) * small improvement * Fix TutorialVideo for mobile view * main page terminal pro docs * jose whelp * placeholder index file that needs to be removed * fix: fixes sidebar, removes unused index.md * update link to api keys * update api keys link * fix hyperlinks in terminal helper * fix a few more links * fix some more links * linter * black linter * improve main docs page for each product * small refactor * header to take to main page of product * run OpenAI script to generate SEO for pro content --------- Co-authored-by: jose-donato <43375532+jose-donato@users.noreply.github.com> * Update folders.md * Update integrate-your-own-backend.md * Update index.md * Update settings.md (#5665) * fix front matter (#5667) * #5633 adding comma every 1000 (#5652) * #5633 adding comma every 1000 * pylint --------- Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * Hotfix/reports model render report sanitize inputs (#5669) * Adding more robust special character handling to create_output_path().Addresses https://github.com/OpenBB-finance/OpenBBTerminal/issues/5299 * Running black linter on code to conform to OBB style guides. --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * hotfix/fix-gov-histcont: Fix #5650 - /stocks/gov/histcont (#5676) * fix histcont * some cleanup * remove sort line * 12-31 not 12-12 * columns_keep_types * remove space in regex (#5675) * Pin openai (#5685) * Clarified stocks/ta empty recom object message (#5468) * Clarified stocks/ta empty recom object message * black * lint --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> * improved market cap value extraction (#5169) * improved market cap value extraction * pylint --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> * 3.2.3->3.2.4 * Changelogs * new changelog --------- Co-authored-by: Henrique Joaquim <h.joaquim@campus.fct.unl.pt> Co-authored-by: Andrew <andrew.kenreich@gmail.com> Co-authored-by: Adi Sai <adithya.sairam1@gmail.com> Co-authored-by: Sandip Saha <sandipsmoto@gmail.com> Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> Co-authored-by: Luqman <luqazino@gmail.com> Co-authored-by: Adwait <111136306+AdwaitSalankar@users.noreply.github.com> Co-authored-by: Abhishek Amar <66067391+abhishek-amar@users.noreply.github.com> Co-authored-by: DidierRLopes <dro.lopes@campus.fct.unl.pt> Co-authored-by: professssor <62937125+professssor@users.noreply.github.com> Co-authored-by: Farookh Zaheer Siddiqui <129654632+FarukhS52@users.noreply.github.com> Co-authored-by: MAX SHESTOV <57421753+maxxsh@users.noreply.github.com> Co-authored-by: jose-donato <zmcdonato@gmail.com> Co-authored-by: jose-donato <43375532+jose-donato@users.noreply.github.com> Co-authored-by: Mohamad Fadil <fadil.parves@gmail.com> Co-authored-by: Ramazan <guvencramazan@outlook.com> Co-authored-by: joshuabuildsthings <joshuabuildsthings@users.noreply.github.com> Co-authored-by: wojda <114031148+polooner@users.noreply.github.com> Co-authored-by: Bim Phomthong <118195204+bimbolimbo@users.noreply.github.com> * Release/4.0.1 (#5840) * test * ultima description (#5541) * Updating showcase page (#5543) * updating showcase page * use sdk instead * add new bot command autopost docs (#5530) add new bot command autopost docs to docs.openbb.co Co-authored-by: James Maslek <jmaslek11@gmail.com> * Hotfix/ultima improvements (#5553) * tweaks for monetization * fix linting issue * fix: Modify 'load' behavior to append data to existing sheet (#5503) * fix: Modify 'load' behavior to append data to existing sheet Details: - Added logic to detect existing sheet and append data if present. - There is no direct way to append on the sheet, so I am reading the sheet to get the last row number and then writing after that row number. Resolves: #5472 * Fixed 'worksheet not found' error during export to an existing sheet * Changes: * Now if the sheet exists in the xlsx file it will ask the user if he wants to replace/append/create new sheet --------- Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * added platform API integration test to Nightly build (#5571) * Add columns to `stocks/search` (#5565) * Add columns to `stocks/search` isin, cusip, figi, composite_figi, shareclass_figi * Update test_search[False].txt * Update test_search[True].txt * Delete tests/openbb_terminal/stocks/cassettes/test_stocks_helper/test_search.yaml * Create test_search.yaml --------- Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * updating ultima urls (#5587) * fix: A value is trying to be set on a copy of a slice from a DataFrame #5582 (#5591) * Update README.md (#5598) * Hotfix/econometrics export filename fix (#5508) * fix: Modify 'load' behavior to append data to existing sheet Details: - Added logic to detect existing sheet and append data if present. - There is no direct way to append on the sheet, so I am reading the sheet to get the last row number and then writing after that row number. Resolves: #5472 * Added --export option for exporting to a desired file in /econometrics menu * Added a -f/--file option to provide the filename for export. Made -t/--type and -f/--file mutually exclusive. If -f is not given, -t is required and the filename will be generated based on the time and module. * Revert `helper_funcs.py` to original state * Made some arguments not required. * Minor changes asked by @deeleeramone * No sheet name * black --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * FIX #5600 Updated the Twitter logo to X logo (#5601) * Change Ultima paragraph (#5624) * change ultima paragraph * remove old paragraph * Update CONTRIBUTING.md (#5623) * mobile line-brake fixed (#5604) In the mobile view (media max 400px ), the text line "Installation >>" appears broken into smaller segments. Co-authored-by: James Maslek <jmaslek11@gmail.com> * Docs/terminalpro and improvement (#5622) * add first iteration of content for Terminal Pro * Update index.md * Update dashboards.md * Update folders.md * Update grouping.md * Update report.md * Update templates.md * Update quick-start.md * Update index.md * Update index.md * Update home.md * Update news.md * Update index.md * Update index.md * Update index.md * Update data-provider.md * Update chat-with-widget.md * Update data-manipulation.md * Update forecasting.md * fix: images self closing tags * fix: only pro visitors can see pro * inter font * improve SEO content and restructuring * add new package for toggle on tutorials * move folder around * improve main page of each prod * small updates and improvements * fix logo above * small improvement in headtitle for portfolio funcs * fix typos from OpenAI's GPT-4 * fix _category_ json * remove generic SEO words * add script that generates SEO for documentation * add missing file * remove sdk warning message * fix links for andrew --------- Co-authored-by: jose-donato <zmcdonato@gmail.com> Co-authored-by: jose-donato <43375532+jose-donato@users.noreply.github.com> Co-authored-by: andrewkenreich <andrew.kenreich@gmail.com> * Add light blue banner, blue when clicking sidebar + fix link in docusaurus.config.js (#5627) * typo * pro docs tab coloring * sidebar selection blue * redirecting missing * fix docs (#5646) * Fix the redirect for intro to the correct url for docs (#5658) * fix the redirect for intro to the correct url for docs * fix code linting --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> * Improve Pro documentation further (#5641) * small improvement * Fix TutorialVideo for mobile view * main page terminal pro docs * jose whelp * placeholder index file that needs to be removed * fix: fixes sidebar, removes unused index.md * update link to api keys * update api keys link * fix hyperlinks in terminal helper * fix a few more links * fix some more links * linter * black linter * improve main docs page for each product * small refactor * header to take to main page of product * run OpenAI script to generate SEO for pro content --------- Co-authored-by: jose-donato <43375532+jose-donato@users.noreply.github.com> * Update folders.md * Update integrate-your-own-backend.md * Update index.md * Update settings.md (#5665) * fix front matter (#5667) * #5633 adding comma every 1000 (#5652) * #5633 adding comma every 1000 * pylint --------- Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * Hotfix/reports model render report sanitize inputs (#5669) * Adding more robust special character handling to create_output_path().Addresses https://github.com/OpenBB-finance/OpenBBTerminal/issues/5299 * Running black linter on code to conform to OBB style guides. --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * hotfix/fix-gov-histcont: Fix #5650 - /stocks/gov/histcont (#5676) * fix histcont * some cleanup * remove sort line * 12-31 not 12-12 * columns_keep_types * remove space in regex (#5675) * Pin openai (#5685) * Clarified stocks/ta empty recom object message (#5468) * Clarified stocks/ta empty recom object message * black * lint --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> * improved market cap value extraction (#5169) * improved market cap value extraction * pylint --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> * Release/3.2.4 (#5704) * 3.2.3->3.2.4 * Changelogs * new changelog * OpenBB Platform v4 (#5225) * change location * check something * add cache * fixed auth w/@IgorWounds and @montezdesousa * fixes for econometrics * include Darren auth suggestions * some routers included if dev + chg hub backend var * coverage router should not be here * update docker readme * forgot to check auth here * Change extension imports * update docstrings and readme * headers function wasnt being called, just referenced * relative import * econometrics add headers everywhere * Fix QA * Fix TA * Fix test * Fix python interface QA and TA * Lint * Cleanup * Change path * make the changes and some etf models * tests for command_runner * ruff * solving naming issues on pytest * Update some docstrings, fix typos and lint * solving econometrics instantiating wrong openbb * chaging the way pytest runs * messing around with the imports * ruff * Change template to add platform considerations (#5533) * change template to add platform considerations * @the-praxs suggestions * solving __pycache__ issue * removing typo * ci yml * making linters happy (i guess) * Improve Omega Ratio and docstrings * chaging pro validation hash * ruff * Fix OLS Summary and lint * Add OECD Provider for economy extension (#5534) * Add record to docs * update a couple of cboe models * Fix econometrics bugs. Make tests pass. Lint. * black * ruff * pydantic v2: remove deprecated Extra * pydantic v2: self.dict -> self.model_dump * revert pydantic * revert the revert * try 1: pin urllib3 < 2 * Revert "try 1: pin urllib3 < 2" This reverts commit3736c311cb. * Revert dep * Fix * re-lock * Skip all tests when doing cspell in pre-commit * Resolve linter errors * Add OECD to install script * Add OECD * Resolve more linter errors * Exclude static files of v4 python from ruff * More linting * Another attempt to resolve even more linting errors * Change how Literal is used * ticker. symbol. consistent. @piiq * change ticker field in Stock Search to is_symbol * Update Cboe model for stocks_search -> is_symbol parameter. * Fix issue * Lint * Small QA to rename SDK to Platform (#5544) * SDK -> Platform in docs * renamed in core * renamed in openbb `init` * `sdk` variable renamed as `platform` --------- Co-authored-by: hjoaquim <h.joaquim@campus.fct.unl.pt> * `validator` -> `field_validator` in standard models * Standard convention for multi-ticker symbols (#5549) * standardize symbol input param in forex and crypto historical data * static * linting * Fix stock_search integration test params * Update dependencies and linting on the CI (#5550) * Remove ruff and black from platform dependencies * Update codespell configuration * Lint python code * Add toml and tomli to root dev dependencies * Update requirements.txt files * Fix buggy docstring in python package methods (#5548) * fix buggy docstring for methods * remove space * fix typing * avoid name collision with validator * Revert "avoid name collision with validator" This reverts commit8a30a44555. * typing * rebuild * python 3.8, ParamSpec not available * lint * ruff noqa * Merge with develop (#5551) * Charting extension integration tests (#5547) * initial proposal for integration tests on the charting extension * int tests for charting generation * python generator * ruff * boilerplate templates * python tests * tests for the api * using body instead so data don't get redefined * unit tests for coverage * ruff * docstrings * unnecessary access to keys() * Add trading economics economic calendar * dev install * Data Models disposition on the website (#5538) * pydantic v4 * flat structure * md files * Revert "md files" This reverts commitbd2170e2ad. * improve command descriptions * nice title and description * human readble data model names on left panel * implementation details section * content markdown files * markdown versioned files * showcase page * updates --------- Co-authored-by: tehcoderer <me@tehcoderer.com> * everything except tests * fix `datetime.date` import in fetcher test * modified url to remove `api_key` placeholder * record test * api key is called c here * fixed fetcher test for api key * recorded tests * refactor * life is ruff * codespell * Make Intrinio options chains great again (#5540) * add multithreading * cleanup * linting * use dateutil.parser * removed `TICKER_EXCEPTIONS` * modified `date` and `type` fields in standard model * set alias for `date` and `type` to match standards * static * static * Hotfix/fix post tests (#5555) * Fix econometrics * Fix ta * Fix qa. Remove intrinio to not be rate limited * Lint * Fix typo * obbject tests (#5558) * obbject tests * ruff * fix dev_install * fix unittests * black on nox * black on nox * nox * fix fetcher test so it can compare dates * fix intrinio tests * ruff * change to model_dum() instead (#5561) * Passing tests (#5560) * Passing tests * fix options * Fix most tests and bugs * fix forex missing params * make symbol upper in polygon fx pairs * fix fixedincome integration tests (#5564) * Fixing charting api integration tests (#5562) * fixing charting api integration tests * black * fix stocks less five API fails * fix the 5 failing stocks integration tests * recapture fmp stock news unit test * fix fmp forex api test * couple more forex integration fixes * changing the request to always use the legacy session. @jmaslek this is was broken for 3.8 and 3.9; with this change apparently all versions work - lemme know if you see any issue with this change * ruff * fix ta * add missing param * fix testers for the api * fix globalnews to use images instead of image * remove unncessary pandas import * econcal int tests * update gitignore * fix get_querystring to support lists * add missing parameters --------- Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> Co-authored-by: Henrique Joaquim <h.joaquim@campus.fct.unl.pt> * Stock Historical standardization and UX improvements (#5457) * polygon add interval standard param * attempt at standardization * Alpha Vantage params standardization * rename `get_intervals` and fixed bug for extracting wrong value * missed changing it in `extract_data` * linting * polygon cleanup * modified `start_date` & `end_date` type to `datetime` from `dateType` * standardized intrinio stock historical params * fixed yfinance * linting * revert start and end date to dateType from datetime * fix alpha vantage * changed param * fix intrinio infinite loop * `validator` is `field_validator` * revert time params and fixed intervals * `outputsize` alias set in `Field` * set interval description using in-build dict * yfinance stock param standardization * static * intrinio cleanup * Polygon add api params as `PrivateAttr` * modified yfinance params to `PrivateAttr` * intrinio remove overriding date params * fixed description for AV adjusted param * fix alpha vantage intraday not working * re-record and pass unit tests * pass integration tests * Update test --------- Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> * Fix econcal endpoint (#5567) * fix econcal for python interface * fix econcal tests * fix non supported json output * Fixes FMP index endpoint to get 1 day interval data (#5535) * fix FMP endpoint for getting index data for `1day` interval * fix `open` type to prevent validation error * modifed `validator` to `field_validator` * type of fields is `StrictFloat` * re-record and pass test * linting * `validator` -> `field_validator`, a3'd everything * Fix regression in tests. Lint * updating the integration test actions * Fix typo * Fix typo * Fix import * Publish versions `a3` to Pypi (#5568) * bump versions and script to publish * small improvements * uncomment exception * openbb * publishing guidelines * improve docs * add providers to economy api * make symbol required in stock_quote * Fix keys * Fix oecd * add comma * revert * Add quotes * Sleep * Improve tests * Improve * Feature/query transform (#5566) * inject query into transform_data * swap query and data * update missing fetchers * last test failing * sig test fetcher * black * av add `query` to `transform_data` call * transform_data: missing refactoring * fix uvicorn command in the doc * Automated examples (#5576) * Automated examples * Fix bug * Lint * static assets built on 3.8 * Revert "static assets built on 3.8" This reverts commitfb82ff7bd9. * remove assets * static assets on 3.8 * static assets on 3.8 * Wrap in quotes * Improve wrap * minor fix * rebuild 3.8 * Fix bug * Fix edge case * Lint * rebuild --------- Co-authored-by: hjoaquim <h.joaquim@campus.fct.unl.pt> Co-authored-by: Diogo Sousa <montezdesousa@gmail.com> * use SecretStr for sensitive fields (#5578) * use SecretStr for sensitive fields * fix * docstring * Add tests for provider (#5583) * Add tests for provider * Test standard models * Lint * Fix standard model issues. Co-authored-by: @the-praxs * linting * `symbol` -> `is_symbol` in `economy.index_search` * static --------- Co-authored-by: Pratyush Shukla <ps4534@nyu.edu> * feature/v4-biztoc-provider: Adds Biztoc provider and GlobalNews (#5546) * add biztoc provider * duplicate field * black * request headers * recapture test * move stuff around * add integration tests * duplicate OECD entry in dev_install * duplicate entry for oecd in pyproject.toml * Add Biztoc to workflow * update readme: credentials * Add Preferences to README * improve tests * fix biztoc * obbject pylint * Bug fix: serializ SecretStr before dumping to json * export credentials as json (#5592) * Check for wrong, changed, or outdated params. (#5597) * Improving `economy.cpi` for the FRED data (#5602) * remove multiindex using coding magic * Update field descriptions --------- Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> * Improve error message. * Improve * Test tests (#5607) * Test tests * Add test * 4.0.0a4 PyPI publishing (#5608) * changes to publish * fix mini conflict * typo * cleaned `descriptions.py` * fix description in `cpi.py` * Add ETF extension to v4 (#5609) * Add etf extension with search data model * Add FMP ETF search * Add fetcher tests * Add ETF historical price from yfinance (#5610) * Add etf extension with search data model * Add FMP ETF search * Add fetcher tests * Add etf historical price standard model and route * Add etf historical data from yfinance * Add unit tests * Fix linter error. Organize imports * Update test data * Revert common descriptions erased by CPI PR * remove `symbol` from data for `stocks.ca.peers` * Test docstrings (#5613) * Test docstrings * fix minor bugs w/@IgorWounds * static only w/@IgorWounds * fix `importance` param in `economy.econcal` * right static only w/@IgorWounds * Fix econcal and add tests to noxfile * fix econcal static * re-record --------- Co-authored-by: Pratyush Shukla <ps4534@nyu.edu> * Clean up the newly created ETF extension (#5611) * Add ETF to dev_install bundle * Add integration tests for openbb-etf * Patch integration test generator scripts to produce lintable code * Add py.typed markers for extensions * user preferences descriptions (#5593) * user preferences descriptions * typo * Feature/v4-sec-provider: Add SEC provider to V4 (#5556) * coerce string type, add default=None * add sec provider and FTD function * update description * ruff * data model definitions in standard model already * duplicate oecd entries in dev_install and pyproject * actually commit * integration test * add stock search to SEC * add company filings for SEC provider * integration tests * remove duplicated line * ruff * **kwargs in Transform Data * some helper functions for later * black * add helper for mutual fund and etf lookup * add some SEC lookup helpers to a new regulators extension * black * ruff * fix test param * take institution filter out of sec stock_search * ruff * remove URL that codespell doesn't like * add cik-to-ticker map * add litigations rss feed * make openbb-regulators a dependency of openbb-sec * add SIC search * improve ftd and remove BeautifulSoup from SEC dependencies * fix parsing the zip files pre-2009 * ruff * update descriptions * recapture ftd test * tests params * typo * change limit param to 1 in test_sec_stock_ftd * Add didiers to_records method (#5588) * Add didiers to_records * unused import * Bring back polars + do what igor suggested * Make the output consistent with what it was. * Black ? * spelling. oops. almost like we have a pre commit or something * Feature/v4-price-performance: % returns for various horizons, comparable across multiple tickers. (#5618) * coerce string type, add default=None * add price_performance endpoint from FMP * black * extra period in docstring * ruff * forgot one file * Feature/ipo-calendar: V4 IPO Calendar (#5605) * coerce string type, add default=None * add intrinio ipo calendar * fix typo * sort __init__ * fix description * make requested changes * update test params * black * test updates * etf integration * Add disc router and WSJ provider * OBBject extensions (#5612) * changes to core * bug? * docstring * doc * Update credentials.py * fix model_dump * create extensions * fix docstring * doc * revert change query_exc * doc * fix container test * redirect obbject test patch * doc * rename method * move decorator to extension file * rename method extend_obbject * changes in creds model * avoid credential racing * doc * rename prop * doc * doc * remove comment * comment some code * free extension names * docstring * doc * docs * Hotfix/fix-v4-economic-calendar: Add FMP to Econ Calendar and fix some TE bugs (#5580) * coerce string type, add default=None * adds fmp to economic calendar and fixes some things with TE * ruff * etf integration test * missing provider for test * rename te cassette to economic_calendar * fix test * rename tests --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> * Add stocks disc endpoints (#5630) * Add stocks disc endpoints * Explicit * Lint * Add tests * Bump timeout * Feature/disc router (#5616) * Add disc router and WSJ provider * Lint * Lint * Move endpoints under ETF router * Update etf_performance.py * Add ETF info and sector exposure from FMP (#5620) * Add ETF info from FMP * Add integration tests * Add unit tests * Add etf sectors endpoint * Add etf sectors fmp endpoint * Omit nested sector list from fmp info data * Update tests and test data * Update test data * Specify provider explicitly in integration tests * Update tests * Skip yfinance etf historical test * Fix linter errors after the merge * Fix more linter errors * Fix failing and add missing tests * Fix integration tests * Fix calendar ipo tests * Add ETF holdings and holding report dates from FMP (#5629) * Add ETF info from FMP * Add integration tests * Add unit tests * Add etf sectors endpoint * Add etf sectors fmp endpoint * Omit nested sector list from fmp info data * Update tests and test data * Update test data * Specify provider explicitly in integration tests * Update tests * Skip yfinance etf historical test * Add etf holdings and holdings date routes and standard models * Add fmp holdings and holding dates fetchers * Update holdings fetcher to properly handle date object inputs * Add unit tests * Add integration tests * Black after merge * Fix test input data format * Disc router for equities. (#5640) * Disc router for equities. * add tests * Bug fixes in financial statements (#5537) * `validator` to `field_validator` in standard models * Polygon add `ttm` to `period` param * Revert "Polygon add `ttm` to `period` param" * Polygon add `ttm` to param `period` * `EarningsCallTranscript` standard model removed `quarter` param * use `tag` instead of `name` for correct field name * fix url for intrinio income statement * modified intrinio cash flow `transform_data` function * set optional data fields and validate dates * fix insider trading not fetching recent data * linting * refactoring * refactoring * set param alias in fmp stock insider provider model * get all quarter data for intrinio * add `limit` param to `stocks.fa.ins` * refactoring and linting * removed additional comment * linting * re-recorded and fix tests * cash flow standard model field type to `StrictFloat` * Intrinio cash flow model fixed to get all quarters' data * linting * refactoring * financial statement standard model field type to `StrictFloat` * Intrinio financial statement model get all quarter data * set `period` type to `Optional[str]` * add `period` param to balance sheet provider models * add `period` param to cash flow provider models * use alias in model dump * remove `ttm` from `period` param * revamped intrinio financials * fixed incorrect description for `limit` param * modified tests for `balance`, `cash` and `income` * re-recorded tests * skipped intrinio financial statement fetcher tests * Add ETF county weighting command with FMP data (#5645) * Remove code that wrongfully infers the filing date as end of quarter * Add etf countries command with fmp data * Add countries command to etf router * Update sector and country weighting fmp models * Fix docstring typo * Add unit tests and update mock data * Add integration tests for etf.countries * Bring back missing integration tests * Fix economic calendar integration tests * fix missing data in intrinio financials * removed inutile params from Polygon financial statement models * Intrinio IPO overhaul * tests fixed and re-recorded * Add ETF holdings performance with FMP data (#5659) * Add etf holdings performance endpoint * Add tests * Fix failing polygon fetcher tests * Split long holdings lists into chunks and update test data * Change chunk length to 500 tickers * Add stock search from FMP (#5642) Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> * Feature/v4 pypi (#5579) * improvements to the publish script * move scripts * initial script that builds the package * adjustments on the docs * test pypi workflow * add hour and minute to version * black * ruff * duplicate file * moving files instead * build throught the script instead * update nox file * integration tests workflow * change workflow * fix dev_install * fix in sed cmd * testing the platform only * commenting out the publishing * fix run commands * improvements to the publish script and doc * fix publish script * updating the script and the workflow * feature/v4-pypi nightly (#5589) * init * Update nightly.py * cleanup * init file * not referencing dev_utils * updating obb platform key * revert * Increase warmup time * project name on pyproject and adding the --pre flag on readme * moving to the build folder * fix noxfile * reflecting the moves on the import statements * fix pyproject path * ruff * fix paths * fix super typo * update workflows * moving the pypi terminal files into its folder --------- Co-authored-by: teh_coderer <me@tehcoderer.com> Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> * economy.calendar nasdaq (#5628) * add quandl econcal * unittest * add integration tests * replace   * fix bug TE importance * small fix * remove stuff from quandl * add nasdaq provider * add nasdaq to install files * Update test_economy_api.py * test * quandl leftovers * remove quandl econcal test * lint * replace   * ruff * lint * update nasdaq gmt * validate countries * here * no need for this * fix calendar tests * static * static * remove error * static * readme + website * readme * remove changes TE * typo * fix unittest * fix tests * Update __init__.py * Update economic_calendar.py * revamped model and added helpers for date range --------- Co-authored-by: Pratyush Shukla <ps4534@nyu.edu> * Feature/v4-dividend-calendar: Adds Nasdaq dividend calendar and moves the command out of fundamental_analysis (#5672) * add nasdaq dividend calendar and move out of fundamental_analysis * black * ruff * add random-user-agent to pyproject.toml * add nasdaq ipo calendar * add nasdaq flag for SPO to IPO calendar * add spo test param * black * dividend test * fix transform_query - nasdaq_calendar_ipo * bring back different headers for ipo calendar * remove references to test * Add disc endpoints (#5660) * Add Quandl top retail * Add tests * Add Seeking Alpha * Add Filings * Change Provider * Fix test * Add dev_install * static * static correct * y u forget me * updated deps * static --------- Co-authored-by: Pratyush Shukla <ps4534@nyu.edu> * using dev install (#5673) * Expanding the `fixedincome` menu (#5655) * models and fetcher * making the fetcher visible * std model * adding the command * improvements to the models * typo * adding the command * imrpovements to dwpcr * standard model for ecb int rates * adding the fetcher for fred * standard model of ice bofa * add ice_bofa command * ruff * ice bofa fetcher * moody std model * moody * std model * add cp command * unused import * cp * spot * ruff * hqm * tmc * ffrmc * tbffr * ruff * typing fixes * buggy dates * fred fetcher tests * ruff * adding ecb as a provider * adding new provider related stuff * adding the new command eu_ycvr * models * test for ecb fetcher * Feature/v4 fixedincome int tests (#5661) * integration tests * happy ruff * mini adjustment * ruff * typo * verbose type * fix tests * docstrings everywhere and an happy pydocstyle * fix tests * Feature/user-cache-dir: Add User Preference for the Cache Directory (#5621) * add user preference for storing cached data * ruff * fix tests? * fix test key error..? * etf integration test fix * add cache dir to SEC * black * improve docs structure for V4 (#5586) * improve docs structure for V4 * moving over changes * Add Docs to the navbar * add some, re-order sidebar * fix sentence * add docs install to source instructions * insert a couple of links, fix a typo * big terminal docs usage revamps * improve toggle component for tutorials * get rid of TOCs for all terminal docs for consistency and simplicity * improve platform docs * improve bot docs content structure * remove index from bot docs * improve ON THIS PAGE to only display TOC if at least 1 element * make edit this page text and icon on same line * add author and date to docs * add basic syntax page to usage * sidebar order for usage section * move api start command to the top with the import python import * some install page additions * small improvement * refactor routines section * Update introduction-to-routines.md * Update pipeline-of-commands.md * Update introduction-to-routines.md * Update routines-for-power-users.md * Update community-routines.md * update keyboard hotkey macros * askobb page * Update askobb-feature.md * Update index.md * Update index.md * Update index.md * Update index.md * fix images * remove HeadTitle from all files where it exist * get rid of extra spacing in markdown * small update * small edit * need index at the start because of main path when homepage of docs * use openAI to create SEO for front matter on my behalf * remove table of content from sdk page * finish improving metadata SEO for SDK docs * update duplicate header * update HeadTitle to be more specific on product * remove index from bot telegram reference * delete duplicated title for platform reference * another update * Hotfix/econometrics export filename fix (#5508) * fix: Modify 'load' behavior to append data to existing sheet Details: - Added logic to detect existing sheet and append data if present. - There is no direct way to append on the sheet, so I am reading the sheet to get the last row number and then writing after that row number. Resolves: #5472 * Added --export option for exporting to a desired file in /econometrics menu * Added a -f/--file option to provide the filename for export. Made -t/--type and -f/--file mutually exclusive. If -f is not given, -t is required and the filename will be generated based on the time and module. * Revert `helper_funcs.py` to original state * Made some arguments not required. * Minor changes asked by @deeleeramone * No sheet name * black --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * FIX #5600 Updated the Twitter logo to X logo (#5601) * Change Ultima paragraph (#5624) * change ultima paragraph * remove old paragraph * Update CONTRIBUTING.md (#5623) * mobile line-brake fixed (#5604) In the mobile view (media max 400px ), the text line "Installation >>" appears broken into smaller segments. Co-authored-by: James Maslek <jmaslek11@gmail.com> * start PR so screenshots can get attached via GitHub website * Update qa.md * Docs/terminalpro and improvement (#5622) * add first iteration of content for Terminal Pro * Update index.md * Update dashboards.md * Update folders.md * Update grouping.md * Update report.md * Update templates.md * Update quick-start.md * Update index.md * Update index.md * Update home.md * Update news.md * Update index.md * Update index.md * Update index.md * Update data-provider.md * Update chat-with-widget.md * Update data-manipulation.md * Update forecasting.md * fix: images self closing tags * fix: only pro visitors can see pro * inter font * improve SEO content and restructuring * add new package for toggle on tutorials * move folder around * improve main page of each prod * small updates and improvements * fix logo above * small improvement in headtitle for portfolio funcs * fix typos from OpenAI's GPT-4 * fix _category_ json * remove generic SEO words * add script that generates SEO for documentation * add missing file * remove sdk warning message * fix links for andrew --------- Co-authored-by: jose-donato <zmcdonato@gmail.com> Co-authored-by: jose-donato <43375532+jose-donato@users.noreply.github.com> Co-authored-by: andrewkenreich <andrew.kenreich@gmail.com> * Add light blue banner, blue when clicking sidebar + fix link in docusaurus.config.js (#5627) * typo * pro docs tab coloring * sidebar selection blue * redirecting missing * Update crypto introduction.md * titles * another title * Update crypto dd.md * Update defi.md * Update disc.md * Update nft.md * Update onchain.md * Update ov.md * Update introduction.md updates URL * Update introduction.md add HeadTitle * Update ba.md * Update comparison.md * Update dark-pool-shorts.md * Update disc.md * fix docs (#5646) * Update fa.md * Update gov.md * Update ins.md * Update tradinghours.md * Delete website/content/terminal/menus/stocks/options/screener.md * Update Options introduction.md * Update screener head title * Update screener TOC * Update econometrics.md * Update economy head title * Update etf.md * codespell * Fix the redirect for intro to the correct url for docs (#5658) * fix the redirect for intro to the correct url for docs * fix code linting --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> * Contributing guidelines (#5615) * intro section * what's expected sections * improve sections * improve sections and move how to add a data point * moving qa under contributor * better intro * moving the sharing section * better expectations * small intro to the contributor guidelines * moving things under the contributor section * there is no pre commits on the platform yet * dependency management * best practices for extensions * typo * collapse options subfolder * codespell * Improve Pro documentation further (#5641) * small improvement * Fix TutorialVideo for mobile view * main page terminal pro docs * jose whelp * placeholder index file that needs to be removed * fix: fixes sidebar, removes unused index.md * update link to api keys * update api keys link * fix hyperlinks in terminal helper * fix a few more links * fix some more links * linter * black linter * improve main docs page for each product * small refactor * header to take to main page of product * run OpenAI script to generate SEO for pro content --------- Co-authored-by: jose-donato <43375532+jose-donato@users.noreply.github.com> * Update folders.md * Update integrate-your-own-backend.md * Update index.md * Update fixedincome.md * url * Update forecast.md * Update settings.md (#5665) * Update forex.md * fix front matter (#5667) * Fix conflict markers that got into markdown during previous merges * Fix front matter list formatting * Fix typo * small thing * fix hyperlinks * Update .codespell.ignore * output_type options * Architectural considerations * Update sidebar to hide pro section by default * Minor copy changes * TET pattern * import statements * clarification on preferences * Minor copy changes * Lint markdown and python * fix: open index on collapsible root elements * remove old content * options title * Fix linting errors * Refactor sidebar label to url mapping condition --------- Co-authored-by: andrewkenreich <andrew.kenreich@gmail.com> Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> Co-authored-by: hjoaquim <h.joaquim@campus.fct.unl.pt> Co-authored-by: Sandip Saha <sandipsmoto@gmail.com> Co-authored-by: James Maslek <jmaslek11@gmail.com> Co-authored-by: professssor <62937125+professssor@users.noreply.github.com> Co-authored-by: Farookh Zaheer Siddiqui <129654632+FarukhS52@users.noreply.github.com> Co-authored-by: MAX SHESTOV <57421753+maxxsh@users.noreply.github.com> Co-authored-by: jose-donato <zmcdonato@gmail.com> Co-authored-by: jose-donato <43375532+jose-donato@users.noreply.github.com> Co-authored-by: Mohamad Fadil <fadil.parves@gmail.com> Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> * Add multi-ticker support to etf_countries (#5670) * add multi-ticker support to etf_countries * remove commented-out lines * normalized percent points * percent -> percentage * Fix Nasdaq Econ Calendar Fetcher (#5668) * fix nasdaq econ cal request * more html tags * add random-user-agent to pyproject * another edge case - 24H -> 00:00 * Feature/v4-unusual-options: Adds unusual options endpoint. (#5677) * add unusual options fro Intrinio * test params * move sorting * Change type * update FMP fetcher to use the V4 endpoint (#5681) * Fix price performance not parsed correctly when there is only 1 ticker (#5678) * Add crypto search standard model and FMP data for it (#5679) * Apply renaming to news data (#5684) * inegration complete * reformatted for black * fix ruff issues * revised integration * changes to versions in pyproject.toml and updated lock files * Rename models * Update tests * Fix typos here and there * Update routers * Apply rename to ultima * Properly mock api key * Mock ultima api key --------- Co-authored-by: Adi Sai <adithya.sairam1@gmail.com> * Feature/v4-market-snapshots: Adds full market snapshots (#5473) * add stocks market snapshots from fmp * add fmp fetcher test * unused imports * add polygon to market_snapshots * update fmp market_snapshots * black * pydantic2 things * updates * change validate_obj to model_validate * polygon cleanup * tests * descriptions * black * data description * minor adjustments, using less local variables, improving readability and removing pandas * better structure * minor adjustments * lint * fix int tests --------- Co-authored-by: hjoaquim <h.joaquim@campus.fct.unl.pt> * Add NBBO Quotes, with historical, to `obb.stocks.quote()` (#5617) * coerce string type, add default=None * add polygon stock quote * limit cleanup * add greater/less than to params * limit param * black * tests * fix tests * test_etf * rename model and function to NBBO * add standard model for nbbo * improve standardization * not redifining builtin max * fix input params * integration test params * removing unused import Co-authored-by: Pratyush Shukla <ps4534@nyu.edu> * revamped code * re-recorded nbbo test * added symbol validator * added alias in field * Stock news -> Company news --------- Co-authored-by: hjoaquim <h.joaquim@campus.fct.unl.pt> Co-authored-by: Pratyush Shukla <ps4534@nyu.edu> Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> * hotfix/update-quandl-to-nasdaq: Merge Quandl + Nasdaq (#5682) * merge quandl nd nasdaq * dev_install.py * test param name * economy python integration test * Add more input types to data processing commands (#5453) * adding more supported types to data processing commands * ruff * removing unused import * docstrings * data processing types covertion * data description * test filters * ruff * fix package builder tests * ruff * removing print * Add stocks/dps module (#5638) * short volume * pyproject missed * add sec short interest with days to cover * Add FINRA OTC endopoint * some tests * rest of unit tests * Integratin test scripts * dev install * linters caught by pre commit * lines too long * Last test files * maybe it needs a lock file? * thanks pratty * Maybe ill actually listen to pratty next time * sec test date freeze * I cant hit buttons * re record tests * tests 3 * Stockgrid test * regen int test * more testing * lint * moved these fns * dis killing me * one more test * last one * Update integration tests * Fix tests picking up wrong dps route --------- Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> * Rename Forex to Currency (#5687) * restore fields as optional (#5686) * Rename Crypto (#5689) * added `crypto.price.historical` * static * fix tests * fix incorrect label * Move model from sec to finra (#5692) * Update toml * fixed deps * add openbb-etf lock file * cleanup * cleanup (#5694) * Rename Fixed Income (#5695) * Rename Fixed Income * Add routers * Rename stocks to equity (#5688) * Rename stocks folder * Rename openbb_stocks package * Rename routers * Reroute equity menu * Update routes based on feedback * StockNews -> EquityNews * StockInfo -> EquityProfile * Rename Equity calendars * Equity peers rename * Rename discovery * Rename fundamental * Rename price command models * Rename shorts * Update charting router * Fix seeking alpha upcoming release date * Fix linting errors * Update tests * Fix tests * Skip econometrics api tests because it's python only * Update integration tests and test data * Historical analyst estimates * Skip cboe options chain test. Unable to record vcr cassette * re-record cboe cassettes * Document CBOE unit test creation caveats --------- Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * Feature/files-for-igor: Adding a few standard models for Igor (#5699) * add some standard models for Igor * codespell * update descriptions * Add devtools metapackage (#5703) * Add openbb-devtools metapackage * adding devtools to the dev_install script --------- Co-authored-by: hjoaquim <h.joaquim@campus.fct.unl.pt> * Rename econometrics commands to be more verbose (#5702) * Expose command to model map (#5706) * Rename ta qa (#5708) * Rename ta folder * Rename ta to technical * Rename qa folder * Rename qa to quantitative * Rename the actual routes in quantitative * Equity cleanup (#5707) * cleanup * static * renaming to equity cc @the-praxs * Proof reading --------- Co-authored-by: hjoaquim <h.joaquim@campus.fct.unl.pt> Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> * Don't enforce imperative for first word of the docstring * Remove ultima from default extensions * Rename `economy` and create `index` extension (#5705) * renamed economy and re-recorded tests * static * market indices * european indices * fred indices * index constituents * tests * correct package name * oops * static * linting * Move COT commands to regulators * Rename economy.list to available_indices * Rename GDP models and clean up * Fix charting tests * Drop _indices from available_indices command * Fix obbject to_dict test --------- Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> * Rename etf/disc (#5715) * Docs/v4-working-docs: PR to Work on V4 Docs (#5693) * Revert changes related to pydantic2 made into v3 code * Revert fred model changes in v3 * Revert pydantic2 databento model changes in v2 * Update some names and v3 lock file * Clean up openbb/package before the beta release * Platform publishing procedure (#5701) * update instructions * introducing the version script * publish message * fix platform path * reflecting version changes * getting version from installed packages instead * removing toml from dependencies * Changes to get `a7` out (#5697) * changes to get a7 out * etf menu on the pyproject.toml * poetry lock * bump `openbb-etf` to `a5` to match version * updated deps * removing ultima * removing references to a4 cc @the-praxs * Bump index menu version * poetry lock --------- Co-authored-by: Pratyush Shukla <ps4534@nyu.edu> Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> * Update publishing instructions * Bump core dependencies in extensions and providers * Add changes to the publish script following the beta release * Update the versions in static extension map and openbb metapackage --------- Co-authored-by: James Maslek <jmaslek11@gmail.com> Co-authored-by: Pratyush Shukla <ps4534@nyu.edu> Co-authored-by: hjoaquim <h.joaquim@campus.fct.unl.pt> Co-authored-by: Diogo Sousa <montezdesousa@gmail.com> Co-authore… * bump yFinance version (#7037) * [Feature] Use Forked Release Of Pandas-TA To Support Numpy2 (#7032) * use forked version of pandas-ta to unblock numpy2 * commented out line * delete old version of plotly.js * remove commented out lines * too-many-positional-arguments * one more file * update locks * [Feature] Align Python Interface With API - Stop Requiring `OBBject` As Output Type In `PackageBuilder` As Default (#7031) * stop enforcing OBBject as output type in PackageBuilder * mypy * reverse output of wrapper to check if object is OBBject (#7039) * [Feature] Allow Arbitrary Credentials From `user_settings.json` To Populate Credentials Model (#7040) * allow arbitrary credentials to be created from user_settings.json * test_hub_service * add factory flag to openbb-api launcher (#7030) * add factory flag to openbb-api launcher * linting * linting * more practical default sizes for metric and pdf widgets * use CWD for widgets-path, templates-path, and copilots-path when not an absolute path * mock_widgets.json * entry point at widget.data in response model * path thing * find a missing schema * mock_widgets.json * add x-widget_config entry point to provider query model in __json_schema_extra__ * deep merge on param choices * sort unique_general_choices * add exclude for both query and data * handle another data schema not being found * add formatters in options data where appropriate * potential access before assignment * lint * add label check to query schema * mock widgets * allow top-level references from the Data response model via '$.' * clean up factory detect * add importable response models for metric and widget * filename optional * refetch interval as false for pdf * docstsring * move import * typo * lint * lint * refetchInterval is top-level * pylint * response model filename place --------- Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> * [Feature] `openbb-sec` & `openbb-regulators`: Add New Path: `regulators.sec.filing_headers` (#7034) * add filing_headers endpoint to regulators.sec path * better 12b securities * linting * mypy * more lint * add htm/html file downloader * deletes example notebooks for V3 API (#7041) * [BugFix] Fix Coverage Router (#7036) * fixes unserializable output in coverage router * add conditional to adding router_coverage * lint * [BugFix] Surface FMP Error Message In `etf.info` (#7044) * surface FMP error message * gotta stage it before the commit.. * [Release] Patch Release `openbb-platform-api` With New Runtime Flags & Readme (#7045) * patch release openbb-platform-api with new features and readme * lint * add PDF to TO_CAPS_STRINGS * some duplicated thing * grammar * add a url to the intro text * readme syntax linting * more grammar * docs: fix typo (#7047) * upload-artifact? (#7049) * [BugFix] `openbb-platform-api` - Fix `$.` References Being Deleted Outside Of Loop (#7046) * fix $. references being deleted outside of loop * non-provider query params x-widget_config * don't send empty provider dict * lint * update readme --------- Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> * downgrade plotly for JSON output formatting (#7048) Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> * [Feature] Custom Serializer For OptionsChainsData For Outputting List Of Records (#7035) * add a custom serializer to OptionsChainsData to convert model output to list of dictionaries * unused items --------- Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> * Release/openbb core 1.4.2 (#7051) * patch release of openbb-core * found an edge case in ExtensionLoader * Small bugfix on launch args (#7028) * Fix CLI arguments * extra space --------- Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * make release for 4.4.1 --------- Co-authored-by: montezdesousa <79287829+montezdesousa@users.noreply.github.com> Co-authored-by: Igor Radovanovic <74266147+IgorWounds@users.noreply.github.com> Co-authored-by: James Maslek <jmaslek11@gmail.com> Co-authored-by: Luqman <luqazino@gmail.com> Co-authored-by: Pratyush Shukla <ps4534@nyu.edu> Co-authored-by: Henrique Joaquim <h.joaquim@campus.fct.unl.pt> Co-authored-by: Michael Struwig <mnicstruwig@gmail.com> Co-authored-by: jose-donato <43375532+jose-donato@users.noreply.github.com> Co-authored-by: capital0 <72140796+capital0@users.noreply.github.com> Co-authored-by: Ben Van Doren <benvandoren@users.noreply.github.com> Co-authored-by: Andrew <andrew.kenreich@gmail.com> Co-authored-by: Adi Sai <adithya.sairam1@gmail.com> Co-authored-by: Sandip Saha <sandipsmoto@gmail.com> Co-authored-by: Adwait <111136306+AdwaitSalankar@users.noreply.github.com> Co-authored-by: Abhishek Amar <66067391+abhishek-amar@users.noreply.github.com> Co-authored-by: DidierRLopes <dro.lopes@campus.fct.unl.pt> Co-authored-by: professssor <62937125+professssor@users.noreply.github.com> Co-authored-by: Farookh Zaheer Siddiqui <129654632+FarukhS52@users.noreply.github.com> Co-authored-by: MAX SHESTOV <57421753+maxxsh@users.noreply.github.com> Co-authored-by: jose-donato <zmcdonato@gmail.com> Co-authored-by: Mohamad Fadil <fadil.parves@gmail.com> Co-authored-by: Ramazan <guvencramazan@outlook.com> Co-authored-by: joshuabuildsthings <joshuabuildsthings@users.noreply.github.com> Co-authored-by: wojda <114031148+polooner@users.noreply.github.com> Co-authored-by: Bim Phomthong <118195204+bimbolimbo@users.noreply.github.com> Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com> Co-authored-by: tehcoderer <me@tehcoderer.com> Co-authored-by: Ramazan <guvencramazan@yandex.com> Co-authored-by: omahs <73983677+omahs@users.noreply.github.com> Co-authored-by: minhhoang1023 <40023817+minhhoang1023@users.noreply.github.com> Co-authored-by: Ayrton Parkinson <ayrton.parkinson1@gmail.com> Co-authored-by: northern-64bit <75195383+northern-64bit@users.noreply.github.com> Co-authored-by: Luqman <luqman.bello@openbb.finance> Co-authored-by: Eric Li <38477812+EricLi-Dev@users.noreply.github.com> Co-authored-by: Colin Delahunty <72827203+colin99d@users.noreply.github.com> Co-authored-by: Henrique Joaquim <henriquecjoaquim@gmail.com> Co-authored-by: Disorder AA <disorrder@gmail.com> Co-authored-by: Diogo Sousa <montezdesousa@gmail.com> Co-authored-by: Jingyi Z <zhao.elton@gmail.com> Co-authored-by: Elias Rad <146735585+nnsW3@users.noreply.github.com> Co-authored-by: mmistroni <mmistroni@gmail.com> Co-authored-by: JC (Jonathan Chen) <jc@dijonkitchen.org>
1917 lines
65 KiB
Python
1917 lines
65 KiB
Python
"""Technical Analysis Router."""
|
|
|
|
# pylint: disable=too-many-lines,unused-import,too-many-arguments,too-many-positional-arguments
|
|
|
|
from typing import Any, Dict, List, Literal, Optional
|
|
|
|
from openbb_core.app.model.example import APIEx, PythonEx
|
|
from openbb_core.app.model.obbject import OBBject
|
|
from openbb_core.app.router import Router
|
|
from openbb_core.app.utils import (
|
|
basemodel_to_df,
|
|
df_to_basemodel,
|
|
get_target_column,
|
|
get_target_columns,
|
|
)
|
|
from openbb_core.provider.abstract.data import Data
|
|
from pydantic import NonNegativeFloat, NonNegativeInt, PositiveFloat, PositiveInt
|
|
|
|
from openbb_technical.helpers import (
|
|
calculate_cones,
|
|
calculate_fib_levels,
|
|
clenow_momentum,
|
|
validate_data,
|
|
)
|
|
from openbb_technical.relative_rotation import (
|
|
RelativeRotationData,
|
|
RelativeRotationFetcher,
|
|
RelativeRotationQueryParams,
|
|
)
|
|
|
|
# TODO: Split this into multiple files
|
|
router = Router(prefix="", description="Technical Analysis tools.")
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Calculate the Relative Strength Ratio and Relative Strength Momentum"
|
|
+ " for a group of symbols against a benchmark.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical("
|
|
+ "symbol='AAPL,MSFT,GOOGL,META,AMZN,TSLA,SPY', start_date='2022-01-01', provider='yfinance')",
|
|
"rr_data = obb.technical.relative_rotation(data=stock_data.results, benchmark='SPY')",
|
|
"rs_ratios = rr_data.results.rs_ratios",
|
|
"rs_momentum = rr_data.results.rs_momentum",
|
|
],
|
|
),
|
|
PythonEx(
|
|
description="When the assets are not traded 252 days per year,"
|
|
+ "adjust the momentum and volatility periods accordingly.",
|
|
code=[
|
|
"crypto_data = obb.crypto.price.historical("
|
|
+ " symbol='BTCUSD,ETHUSD,SOLUSD', start_date='2021-01-01', provider='yfinance')",
|
|
"rr_data = obb.technical.relative_rotation(data=crypto_data.results, benchmark='BTC-USD',"
|
|
+ " long_period=365, short_period=30, window=30, trading_periods=365)",
|
|
],
|
|
),
|
|
],
|
|
)
|
|
async def relative_rotation(
|
|
data: List[Data],
|
|
benchmark: str,
|
|
study: Literal["price", "volume", "volatility"] = "price",
|
|
long_period: Optional[int] = 252,
|
|
short_period: Optional[int] = 21,
|
|
window: Optional[int] = 21,
|
|
trading_periods: Optional[int] = 252,
|
|
chart_params: Optional[Dict[str, Any]] = None,
|
|
) -> OBBject[RelativeRotationData]:
|
|
"""Calculate the Relative Strength Ratio and Relative Strength Momentum for a group of symbols against a benchmark.
|
|
|
|
Parameters
|
|
----------
|
|
data : list[Data]
|
|
The data to be used for the relative rotation calculations.
|
|
This should be the multi-symbol output from the 'equity.price.historical' endpoint, or similar.
|
|
Or a pivot table with the 'date' column as the index, the symbols as the columns, and the 'study' as the values.
|
|
It is recommended to use the 'equity.price.historical' endpoint to get the data, and feed the results as-is.
|
|
benchmark : str
|
|
The symbol to be used as the benchmark.
|
|
study : Literal[price, volume, volatility]
|
|
The data point for the calculations. If 'price', the closing price will be used.
|
|
If 'volatility', the standard deviation of the closing price will be used.
|
|
If 'data' is supplied as a pivot table,
|
|
the 'study' will assume the values are the closing price and 'volume' will be ignored.
|
|
long_period : int, optional
|
|
The length of the long period for momentum calculation, by default 252.
|
|
Adjust this value when supplying a time series with an interval that is not daily.
|
|
For example, if the data is monthly, the long period should be 12.
|
|
short_period : int, optional
|
|
The length of the short period for momentum calculation, by default 21.
|
|
Adjust this value when supplying a time series with an interval that is not daily.
|
|
window : int, optional
|
|
The length of window for the standard deviation calculation, by default 21.
|
|
Adjust this value when supplying a time series with an interval that is not daily.
|
|
trading_periods : int, optional
|
|
The number of trading periods per year, for the standard deviation calculation, by default 252.
|
|
Adjust this value when supplying a time series with an interval that is not daily.
|
|
chart_params : dict[str, Any], optional
|
|
Additional parameters to pass when `chart=True` and the `openbb-charting` extension is installed.
|
|
Parameters can be passed again to redraw the chart using the charting.to_chart() method of the response.
|
|
|
|
ChartParams
|
|
-----------
|
|
date : str, optional
|
|
A target end date within the data to use for the chart, by default is the last date in the data.
|
|
show_tails : bool
|
|
Show the tails on the chart, by default True.
|
|
tail_periods : int
|
|
Number of periods to show in the tails, by default 16.
|
|
tail_interval : Literal[day, week, month]
|
|
Interval to show the tails, by default 'week'.
|
|
title : str, optional
|
|
Title of the chart.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[RelativeRotationData]
|
|
results : RelativeRotationData
|
|
symbols : list[str]:
|
|
The symbols that are being compared against the benchmark.
|
|
benchmark : str
|
|
The benchmark symbol.
|
|
study : Literal[price, volume, volatility]
|
|
The data point for the selected.
|
|
long_period : int
|
|
The length of the long period for momentum calculation, as entered by the user.
|
|
short_period : int
|
|
The length of the short period for momentum calculation, as entered by the user.
|
|
window : int
|
|
The length of window for the standard deviation calculation.
|
|
trading_periods : int
|
|
The number of trading periods per year, for the standard deviation calculation.
|
|
start_date : str
|
|
The start date of the data after adjusting the length of the data for the calculations.
|
|
end_date : str
|
|
The end date of the data.
|
|
symbols_data : list[Data]
|
|
The data representing the selected 'study' for each symbol.
|
|
benchmark_data : list[Data]
|
|
The data representing the selected 'study' for the benchmark.
|
|
rs_ratios : list[Data]
|
|
The normalized relative strength ratios data.
|
|
rs_momentum : list[Data]
|
|
The normalized relative strength momentum data.
|
|
"""
|
|
params = RelativeRotationQueryParams(
|
|
data=data,
|
|
benchmark=benchmark,
|
|
study=study,
|
|
long_period=long_period,
|
|
short_period=short_period,
|
|
window=window,
|
|
trading_periods=trading_periods,
|
|
chart_params=chart_params,
|
|
)
|
|
|
|
return OBBject(
|
|
results=RelativeRotationFetcher.transform_data(
|
|
params, RelativeRotationFetcher.extract_data(params, {})
|
|
)
|
|
)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Average True Range.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"atr_data = obb.technical.atr(data=stock_data.results)",
|
|
],
|
|
),
|
|
APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def atr(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
length: PositiveInt = 14,
|
|
mamode: Literal["rma", "ema", "sma", "wma"] = "rma",
|
|
drift: NonNegativeInt = 1,
|
|
offset: int = 0,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Average True Range.
|
|
|
|
Used to measure volatility, especially volatility caused by gaps or limit moves.
|
|
The ATR metric helps understand how much the values in your data change on average,
|
|
giving insights into the stability or unpredictability during a certain period.
|
|
It's particularly useful for spotting trends of increase or decrease in variations,
|
|
without getting into technical trading details.
|
|
The method considers not just the day-to-day changes but also accounts for any
|
|
sudden jumps or drops, ensuring you get a comprehensive view of movement.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to apply the indicator to.
|
|
index : str, optional
|
|
Index column name, by default "date"
|
|
length : PositiveInt, optional
|
|
It's period, by default 14
|
|
mamode : Literal["rma", "ema", "sma", "wma"], optional
|
|
Moving average mode, by default "rma"
|
|
drift : NonNegativeInt, optional
|
|
The difference period, by default 1
|
|
offset : int, optional
|
|
How many periods to offset the result, by default 0
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
List of data with the indicator applied.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, length)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_columns(df, ["high", "low", "close"])
|
|
df_atr = pd.DataFrame(
|
|
df_target.ta.atr(length=length, mamode=mamode, drift=drift, offset=offset)
|
|
)
|
|
|
|
output = pd.concat([df, df_atr], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Bollinger Band Width.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"fib_data = obb.technical.fib(data=stock_data.results, period=120)",
|
|
],
|
|
),
|
|
APIEx(parameters={"data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def fib(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
close_column: Literal["close", "adj_close"] = "close",
|
|
period: PositiveInt = 120,
|
|
start_date: Optional[str] = None,
|
|
end_date: Optional[str] = None,
|
|
) -> OBBject[List[Data]]:
|
|
"""Create Fibonacci Retracement Levels.
|
|
|
|
This method draws from a classic technique to pinpoint significant price levels
|
|
that often indicate where the market might find support or resistance.
|
|
It's a tool used to gauge potential turning points in the data by applying a
|
|
mathematical approach rooted in nature's patterns. Is used to get insights into
|
|
where prices could head next, based on historical movements.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to apply the indicator to.
|
|
index : str, optional
|
|
Index column name, by default "date"
|
|
period : PositiveInt, optional
|
|
Period to calculate the indicator, by default 120
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
List of data with the indicator applied.
|
|
"""
|
|
df = basemodel_to_df(data, index=index)
|
|
|
|
(
|
|
df_fib,
|
|
min_date,
|
|
max_date,
|
|
min_pr,
|
|
max_pr,
|
|
lvl_text,
|
|
) = calculate_fib_levels(
|
|
data=df,
|
|
close_col=close_column,
|
|
limit=period,
|
|
start_date=start_date,
|
|
end_date=end_date,
|
|
)
|
|
|
|
df_fib["min_date"] = min_date
|
|
df_fib["max_date"] = max_date
|
|
df_fib["min_pr"] = min_pr
|
|
df_fib["max_pr"] = max_pr
|
|
df_fib["lvl_text"] = lvl_text
|
|
|
|
results = df_to_basemodel(df_fib)
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the On Balance Volume (OBV).",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"obv_data = obb.technical.obv(data=stock_data.results, offset=0)",
|
|
],
|
|
),
|
|
APIEx(parameters={"data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def obv(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
offset: int = 0,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the On Balance Volume (OBV).
|
|
|
|
Is a cumulative total of the up and down volume. When the close is higher than the
|
|
previous close, the volume is added to the running total, and when the close is
|
|
lower than the previous close, the volume is subtracted from the running total.
|
|
|
|
To interpret the OBV, look for the OBV to move with the price or precede price moves.
|
|
If the price moves before the OBV, then it is a non-confirmed move. A series of rising peaks,
|
|
or falling troughs, in the OBV indicates a strong trend. If the OBV is flat, then the market
|
|
is not trending.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to apply the indicator to.
|
|
index : str, optional
|
|
Index column name, by default "date"
|
|
offset : int, optional
|
|
How many periods to offset the result, by default 0.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
List of data with the indicator applied.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_columns(df, ["close", "volume"])
|
|
df_obv = pd.DataFrame(df_target.ta.obv(offset=offset))
|
|
|
|
output = pd.concat([df, df_obv], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Perform the Fisher Transform.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"fisher_data = obb.technical.fisher(data=stock_data.results, length=14, signal=1)",
|
|
],
|
|
),
|
|
APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def fisher(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
length: PositiveInt = 14,
|
|
signal: PositiveInt = 1,
|
|
) -> OBBject[List[Data]]:
|
|
"""Perform the Fisher Transform.
|
|
|
|
A technical indicator created by John F. Ehlers that converts prices into a Gaussian
|
|
normal distribution. The indicator highlights when prices have moved to an extreme,
|
|
based on recent prices.
|
|
This may help in spotting turning points in the price of an asset. It also helps
|
|
show the trend and isolate the price waves within a trend.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to apply the indicator to.
|
|
index : str, optional
|
|
Index column name, by default "date"
|
|
length : PositiveInt, optional
|
|
Fisher period, by default 14
|
|
signal : PositiveInt, optional
|
|
Fisher Signal period, by default 1
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
List of data with the indicator applied.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, [length, signal])
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_columns(df, ["high", "low"])
|
|
df_fisher = pd.DataFrame(df_target.ta.fisher(length=length, signal=signal))
|
|
|
|
output = pd.concat([df, df_fisher], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Accumulation/Distribution Oscillator.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"adosc_data = obb.technical.adosc(data=stock_data.results, fast=3, slow=10, offset=0)",
|
|
],
|
|
),
|
|
APIEx(parameters={"fast": 2, "slow": 4, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def adosc(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
fast: PositiveInt = 3,
|
|
slow: PositiveInt = 10,
|
|
offset: int = 0,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Accumulation/Distribution Oscillator.
|
|
|
|
Also known as the Chaikin Oscillator.
|
|
|
|
Essentially a momentum indicator, but of the Accumulation-Distribution line
|
|
rather than merely price. It looks at both the strength of price moves and the
|
|
underlying buying and selling pressure during a given time period. The oscillator
|
|
reading above zero indicates net buying pressure, while one below zero registers
|
|
net selling pressure. Divergence between the indicator and pure price moves are
|
|
the most common signals from the indicator, and often flag market turning points.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
fast : PositiveInt, optional
|
|
Number of periods to be used for the fast calculation, by default 3.
|
|
slow : PositiveInt, optional
|
|
Number of periods to be used for the slow calculation, by default 10.
|
|
offset : int, optional
|
|
Offset to be used for the calculation, by default 0.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, [fast, slow])
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_columns(df, ["open", "high", "low", "close", "volume"])
|
|
df_adosc = pd.DataFrame(df_target.ta.adosc(fast=fast, slow=slow, offset=offset))
|
|
|
|
output = pd.concat([df, df_adosc], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Chande Momentum Oscillator.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"bbands_data = obb.technical.bbands(data=stock_data.results, target='close', length=50, std=2, mamode='sma')", # noqa: E501
|
|
],
|
|
),
|
|
APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def bbands(
|
|
data: List[Data],
|
|
target: str = "close",
|
|
index: str = "date",
|
|
length: int = 50,
|
|
std: NonNegativeFloat = 2,
|
|
mamode: Literal["sma", "ema", "wma", "rma"] = "sma",
|
|
offset: int = 0,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Bollinger Bands.
|
|
|
|
Consist of three lines. The middle band is a simple moving average (generally 20
|
|
periods) of the typical price (TP). The upper and lower bands are F standard
|
|
deviations (generally 2) above and below the middle band.
|
|
The bands widen and narrow when the volatility of the price is higher or lower,
|
|
respectively.
|
|
|
|
Bollinger Bands do not, in themselves, generate buy or sell signals;
|
|
they are an indicator of overbought or oversold conditions. When the price is near the
|
|
upper or lower band it indicates that a reversal may be imminent. The middle band
|
|
becomes a support or resistance level. The upper and lower bands can also be
|
|
interpreted as price targets. When the price bounces off of the lower band and crosses
|
|
the middle band, then the upper band becomes the price target.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
target : str
|
|
Target column name.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
length : int, optional
|
|
Number of periods to be used for the calculation, by default 50.
|
|
std : NonNegativeFloat, optional
|
|
Standard deviation to be used for the calculation, by default 2.
|
|
mamode : Literal["sma", "ema", "wma", "rma"], optional
|
|
Moving average mode to be used for the calculation, by default "sma".
|
|
offset : int, optional
|
|
Offset to be used for the calculation, by default 0.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, length)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_column(df, target).to_frame()
|
|
bbands_df = pd.DataFrame(
|
|
df_target.ta.bbands(
|
|
length=length,
|
|
std=std,
|
|
mamode=mamode,
|
|
offset=offset,
|
|
close=target,
|
|
prefix=target,
|
|
)
|
|
)
|
|
|
|
output = pd.concat([df, bbands_df], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Chande Momentum Oscillator.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"zlma_data = obb.technical.zlma(data=stock_data.results, target='close', length=50, offset=0)",
|
|
],
|
|
),
|
|
APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def zlma(
|
|
data: List[Data],
|
|
target: str = "close",
|
|
index: str = "date",
|
|
length: int = 50,
|
|
offset: int = 0,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the zero lag exponential moving average (ZLEMA).
|
|
|
|
Created by John Ehlers and Ric Way. The idea is do a
|
|
regular exponential moving average (EMA) calculation but
|
|
on a de-lagged data instead of doing it on the regular data.
|
|
Data is de-lagged by removing the data from "lag" days ago
|
|
thus removing (or attempting to) the cumulative effect of
|
|
the moving average.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
target : str
|
|
Target column name.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
length : int, optional
|
|
Number of periods to be used for the calculation, by default 50.
|
|
offset : int, optional
|
|
Offset to be used for the calculation, by default 0.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, length)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_column(df, target).to_frame()
|
|
zlma_df = pd.DataFrame(
|
|
df_target.ta.zlma(
|
|
length=length,
|
|
offset=offset,
|
|
close=target,
|
|
prefix=target,
|
|
)
|
|
).dropna()
|
|
|
|
output = pd.concat([df, zlma_df], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Chande Momentum Oscillator.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"aaron_data = obb.technical.aroon(data=stock_data.results, length=25, scalar=100)",
|
|
],
|
|
),
|
|
APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def aroon(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
length: int = 25,
|
|
scalar: float = 100,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Aroon Indicator.
|
|
|
|
The word aroon is Sanskrit for "dawn's early light." The Aroon
|
|
indicator attempts to show when a new trend is dawning. The indicator consists
|
|
of two lines (Up and Down) that measure how long it has been since the highest
|
|
high/lowest low has occurred within an n period range.
|
|
|
|
When the Aroon Up is staying between 70 and 100 then it indicates an upward trend.
|
|
When the Aroon Down is staying between 70 and 100 then it indicates an downward trend.
|
|
A strong upward trend is indicated when the Aroon Up is above 70 while the Aroon Down is below 30.
|
|
Likewise, a strong downward trend is indicated when the Aroon Down is above 70 while
|
|
the Aroon Up is below 30. Also look for crossovers. When the Aroon Down crosses above
|
|
the Aroon Up, it indicates a weakening of the upward trend (and vice versa).
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
index: str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
length : int, optional
|
|
Number of periods to be used for the calculation, by default 25.
|
|
scalar : float, optional
|
|
Scalar to be used for the calculation, by default 100.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, length)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_columns(df, ["high", "low", "close"])
|
|
df_aroon = pd.DataFrame(df_target.ta.aroon(length=length, scalar=scalar)).dropna()
|
|
|
|
output = pd.concat([df, df_aroon], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Chande Momentum Oscillator.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"sma_data = obb.technical.sma(data=stock_data.results, target='close', length=50, offset=0)",
|
|
],
|
|
),
|
|
APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def sma(
|
|
data: List[Data],
|
|
target: str = "close",
|
|
index: str = "date",
|
|
length: int = 50,
|
|
offset: int = 0,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Simple Moving Average (SMA).
|
|
|
|
Moving Averages are used to smooth the data in an array to
|
|
help eliminate noise and identify trends. The Simple Moving Average is literally
|
|
the simplest form of a moving average. Each output value is the average of the
|
|
previous n values. In a Simple Moving Average, each value in the time period carries
|
|
equal weight, and values outside of the time period are not included in the average.
|
|
This makes it less responsive to recent changes in the data, which can be useful for
|
|
filtering out those changes.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
target : str
|
|
Target column name.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
length : int, optional
|
|
Number of periods to be used for the calculation, by default 50.
|
|
offset : int, optional
|
|
Offset from the current period, by default 0.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, length)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_column(df, target).to_frame()
|
|
sma_df = pd.DataFrame(
|
|
df_target.ta.sma(
|
|
length=length,
|
|
offset=offset,
|
|
close=target,
|
|
prefix=target,
|
|
).dropna()
|
|
)
|
|
|
|
output = pd.concat([df, sma_df], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Demark Sequential Indicator.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"demark_data = obb.technical.demark(data=stock_data.results, offset=0)",
|
|
],
|
|
),
|
|
APIEx(parameters={"data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def demark(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
target: str = "close",
|
|
show_all: bool = True,
|
|
asint: bool = True,
|
|
offset: int = 0,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Demark sequential indicator.
|
|
|
|
This indicator offers a strategic way to spot potential reversals in market trends.
|
|
It's designed to highlight moments when the current trend may be running out of steam,
|
|
suggesting a possible shift in direction. By focusing on specific patterns in price movements, it provides
|
|
valuable insights for making informed decisions on future changes and identifies trend exhaustion points
|
|
with precision.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
target : str, optional
|
|
Target column name, by default "close".
|
|
show_all : bool, optional
|
|
Show 1 - 13. If set to False, show 6 - 9
|
|
asint : bool, optional
|
|
If True, fill NAs with 0 and change type to int, by default True.
|
|
offset : int, optional
|
|
How many periods to offset the result
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data, with fields: [{index}, {target}, "up", "down"]
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas_ta as ta # noqa
|
|
from pandas import concat
|
|
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_column(df, target).to_frame()
|
|
_demark = ta.exhc(df_target[target], asint=asint, show_all=show_all, offset=offset)
|
|
demark_df = concat([df[[target]], _demark], axis=1).reset_index()
|
|
demark_df = demark_df.rename(columns={"EXHC_DNa": "down", "EXHC_UPa": "up"})
|
|
results = df_to_basemodel(demark_df)
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Volume Weighted Average Price (VWAP).",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"vwap_data = obb.technical.vwap(data=stock_data.results, anchor='D', offset=0)",
|
|
],
|
|
),
|
|
APIEx(parameters={"data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def vwap(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
anchor: str = "D",
|
|
offset: int = 0,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Volume Weighted Average Price (VWAP).
|
|
|
|
Measures the average typical price by volume.
|
|
It is typically used with intraday charts to identify general direction.
|
|
It helps to understand the true average price factoring in the volume of transactions,
|
|
and serves as a benchmark for assessing the market's direction over short periods, such as a single trading day.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
anchor : str, optional
|
|
Anchor period to use for the calculation, by default "D".
|
|
See Timeseries Offset Aliases below for additional options:
|
|
https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#timeseries-offset-aliases
|
|
offset : int, optional
|
|
Offset from the current period, by default 0.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
df = basemodel_to_df(data, index=index)
|
|
if index == "date":
|
|
df.index = pd.to_datetime(df.index)
|
|
df_target = get_target_columns(df, ["high", "low", "close", "volume"])
|
|
df_vwap = pd.DataFrame(df_target.ta.vwap(anchor=anchor, offset=offset).dropna())
|
|
|
|
output = pd.concat([df, df_vwap], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Moving Average Convergence Divergence (MACD).",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"macd_data = obb.technical.macd(data=stock_data.results, target='close', fast=12, slow=26, signal=9)",
|
|
],
|
|
),
|
|
APIEx(
|
|
description="Example with mock data.",
|
|
parameters={
|
|
"fast": 2,
|
|
"slow": 3,
|
|
"signal": 1,
|
|
"data": APIEx.mock_data("timeseries"),
|
|
},
|
|
),
|
|
],
|
|
)
|
|
def macd(
|
|
data: List[Data],
|
|
target: str = "close",
|
|
index: str = "date",
|
|
fast: int = 12,
|
|
slow: int = 26,
|
|
signal: int = 9,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Moving Average Convergence Divergence (MACD).
|
|
|
|
Difference between two Exponential Moving Averages. The Signal line is an
|
|
Exponential Moving Average of the MACD.
|
|
|
|
The MACD signals trend changes and indicates the start of new trend direction.
|
|
High values indicate overbought conditions, low values indicate oversold conditions.
|
|
Divergence with the price indicates an end to the current trend, especially if the
|
|
MACD is at extreme high or low values. When the MACD line crosses above the
|
|
signal line a buy signal is generated. When the MACD crosses below the signal line a
|
|
sell signal is generated. To confirm the signal, the MACD should be above zero for a buy,
|
|
and below zero for a sell.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
target : str
|
|
Target column name.
|
|
fast : int, optional
|
|
Number of periods for the fast EMA, by default 12.
|
|
slow : int, optional
|
|
Number of periods for the slow EMA, by default 26.
|
|
signal : int, optional
|
|
Number of periods for the signal EMA, by default 9.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, [fast, slow, signal])
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_column(df, target).to_frame()
|
|
macd_df = pd.DataFrame(
|
|
df_target.ta.macd(
|
|
fast=fast,
|
|
slow=slow,
|
|
signal=signal,
|
|
close=target,
|
|
prefix=target,
|
|
).dropna()
|
|
)
|
|
output = pd.concat([df, macd_df], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Calculate HMA with historical stock data.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"hma_data = obb.technical.hma(data=stock_data.results, target='close', length=50, offset=0)",
|
|
],
|
|
),
|
|
],
|
|
)
|
|
def hma(
|
|
data: List[Data],
|
|
target: str = "close",
|
|
index: str = "date",
|
|
length: int = 50,
|
|
offset: int = 0,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Hull Moving Average (HMA).
|
|
|
|
Solves the age old dilemma of making a moving average more responsive to current
|
|
price activity whilst maintaining curve smoothness.
|
|
In fact the HMA almost eliminates lag altogether and manages to improve smoothing
|
|
at the same time.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
target : str
|
|
Target column name.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
length : int, optional
|
|
Number of periods for the HMA, by default 50.
|
|
offset : int, optional
|
|
Offset of the HMA, by default 0.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, length)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_column(df, target).to_frame()
|
|
hma_df = pd.DataFrame(
|
|
df_target.ta.hma(
|
|
length=length,
|
|
offset=offset,
|
|
close=target,
|
|
prefix=target,
|
|
).dropna()
|
|
)
|
|
|
|
output = pd.concat([df, hma_df], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Donchian Channels.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"donchian_data = obb.technical.donchian(data=stock_data.results, lower_length=20, upper_length=20, offset=0)", # noqa: E501
|
|
],
|
|
),
|
|
APIEx(
|
|
parameters={
|
|
"lower_length": 1,
|
|
"upper_length": 3,
|
|
"data": APIEx.mock_data("timeseries"),
|
|
}
|
|
),
|
|
],
|
|
)
|
|
def donchian(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
lower_length: PositiveInt = 20,
|
|
upper_length: PositiveInt = 20,
|
|
offset: int = 0,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Donchian Channels.
|
|
|
|
Three lines generated by moving average calculations that comprise an indicator
|
|
formed by upper and lower bands around a midrange or median band. The upper band
|
|
marks the highest price of a security over N periods while the lower band
|
|
marks the lowest price of a security over N periods. The area
|
|
between the upper and lower bands represents the Donchian Channel.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
lower_length : PositiveInt, optional
|
|
Number of periods for the lower band, by default 20.
|
|
upper_length : PositiveInt, optional
|
|
Number of periods for the upper band, by default 20.
|
|
offset : int, optional
|
|
Offset of the Donchian Channel, by default 0.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, [lower_length, upper_length])
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_columns(df, ["high", "low"])
|
|
donchian_df = pd.DataFrame(
|
|
df_target.ta.donchian(
|
|
lower_length=lower_length, upper_length=upper_length, offset=offset
|
|
).dropna()
|
|
)
|
|
|
|
output = pd.concat([df, donchian_df], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Ichimoku Cloud.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"ichimoku_data = obb.technical.ichimoku(data=stock_data.results, conversion=9, base=26, lookahead=False)",
|
|
],
|
|
),
|
|
],
|
|
)
|
|
def ichimoku(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
conversion: PositiveInt = 9,
|
|
base: PositiveInt = 26,
|
|
lagging: PositiveInt = 52,
|
|
offset: PositiveInt = 26,
|
|
lookahead: bool = False,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Ichimoku Cloud.
|
|
|
|
Also known as Ichimoku Kinko Hyo, is a versatile indicator that defines support and
|
|
resistance, identifies trend direction, gauges momentum and provides trading
|
|
signals. Ichimoku Kinko Hyo translates into "one look equilibrium chart". With
|
|
one look, chartists can identify the trend and look for potential signals within
|
|
that trend.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
conversion : PositiveInt, optional
|
|
Number of periods for the conversion line, by default 9.
|
|
base : PositiveInt, optional
|
|
Number of periods for the base line, by default 26.
|
|
lagging : PositiveInt, optional
|
|
Number of periods for the lagging span, by default 52.
|
|
offset : PositiveInt, optional
|
|
Number of periods for the offset, by default 26.
|
|
lookahead : bool, optional
|
|
drops the Chikou Span Column to prevent potential data leak
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
validate_data(data, [conversion, base, lagging])
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_columns(df, ["high", "low", "close"])
|
|
df_ichimoku, df_span = df_target.ta.ichimoku(
|
|
tenkan=conversion,
|
|
kijun=base,
|
|
senkou=lagging,
|
|
offset=offset,
|
|
lookahead=lookahead,
|
|
)
|
|
|
|
df_result = df.join(df_span.add_prefix("span_"), how="left")
|
|
df_result = df_result.join(df_ichimoku, how="left")
|
|
|
|
results = df_to_basemodel(df_result.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Clenow Volatility Adjusted Momentum.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"clenow_data = obb.technical.clenow(data=stock_data.results, period=90)",
|
|
],
|
|
),
|
|
APIEx(parameters={"period": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def clenow(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
target: str = "close",
|
|
period: PositiveInt = 90,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Clenow Volatility Adjusted Momentum.
|
|
|
|
The Clenow Volatility Adjusted Momentum is a sophisticated approach to understanding market momentum with a twist.
|
|
It adjusts for volatility, offering a clearer picture of true momentum by considering how price movements are
|
|
influenced by their volatility over a set period. It helps in identifying stronger, more reliable trends.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
target : str, optional
|
|
Target column name, by default "close".
|
|
period : PositiveInt, optional
|
|
Number of periods for the momentum, by default 90.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, period)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_column(df, target)
|
|
|
|
r2, coef, _ = clenow_momentum(df_target, period)
|
|
|
|
df_clenow = pd.DataFrame.from_dict(
|
|
{
|
|
"r^2": f"{r2:.5f}",
|
|
"fit_coef": f"{coef:.5f}",
|
|
"factor": f"{coef * r2:.5f}",
|
|
},
|
|
orient="index",
|
|
).transpose()
|
|
|
|
output = pd.concat([df, df_clenow], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Accumulation/Distribution Line.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"ad_data = obb.technical.ad(data=stock_data.results, offset=0)",
|
|
],
|
|
),
|
|
APIEx(parameters={"data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def ad(data: List[Data], index: str = "date", offset: int = 0) -> OBBject[List[Data]]:
|
|
"""Calculate the Accumulation/Distribution Line.
|
|
|
|
Similar to the On Balance Volume (OBV).
|
|
Sums the volume times +1/-1 based on whether the close is higher than the previous
|
|
close. The Accumulation/Distribution indicator, however multiplies the volume by the
|
|
close location value (CLV). The CLV is based on the movement of the issue within a
|
|
single bar and can be +1, -1 or zero.
|
|
|
|
|
|
The Accumulation/Distribution Line is interpreted by looking for a divergence in
|
|
the direction of the indicator relative to price. If the Accumulation/Distribution
|
|
Line is trending upward it indicates that the price may follow. Also, if the
|
|
Accumulation/Distribution Line becomes flat while the price is still rising (or falling)
|
|
then it signals an impending flattening of the price.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
offset : int, optional
|
|
Offset of the AD, by default 0.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_columns(df, ["high", "low", "close", "volume"])
|
|
ad_df = pd.DataFrame(df_target.ta.ad(offset=offset).dropna())
|
|
|
|
output = pd.concat([df, ad_df], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Average Directional Index (ADX).",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"adx_data = obb.technical.adx(data=stock_data.results, length=50, scalar=100.0, drift=1)",
|
|
],
|
|
),
|
|
APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def adx(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
length: int = 50,
|
|
scalar: float = 100.0,
|
|
drift: int = 1,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Average Directional Index (ADX).
|
|
|
|
The ADX is a Welles Wilder style moving average of the Directional Movement Index (DX).
|
|
The values range from 0 to 100, but rarely get above 60. To interpret the ADX, consider
|
|
a high number to be a strong trend, and a low number, a weak trend.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
List of data to be used for the calculation.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
length : int, optional
|
|
Number of periods for the ADX, by default 50.
|
|
scalar : float, optional
|
|
Scalar value for the ADX, by default 100.0.
|
|
drift : int, optional
|
|
Drift value for the ADX, by default 1.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, length)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_columns(df, ["close", "high", "low"])
|
|
df_adx = pd.DataFrame(
|
|
df_target.ta.adx(length=length, scalar=scalar, drift=drift).dropna()
|
|
)
|
|
|
|
output = pd.concat([df, df_adx], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Average True Range (ATR).",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"wma_data = obb.technical.wma(data=stock_data.results, target='close', length=50, offset=0)",
|
|
],
|
|
),
|
|
APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def wma(
|
|
data: List[Data],
|
|
target: str = "close",
|
|
index: str = "date",
|
|
length: int = 50,
|
|
offset: int = 0,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Weighted Moving Average (WMA).
|
|
|
|
A Weighted Moving Average puts more weight on recent data and less on past data.
|
|
This is done by multiplying each bar's price by a weighting factor. Because of its
|
|
unique calculation, WMA will follow prices more closely than a corresponding Simple
|
|
Moving Average.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
The data to use for the calculation.
|
|
target : str
|
|
Target column name.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
length : int, optional
|
|
The length of the WMA, by default 50.
|
|
offset : int, optional
|
|
The offset of the WMA, by default 0.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The WMA data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, length)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_column(df, target).to_frame()
|
|
df_wma = pd.DataFrame(
|
|
df_target.ta.wma(
|
|
length=length,
|
|
offset=offset,
|
|
close=target,
|
|
prefix=target,
|
|
).dropna()
|
|
)
|
|
|
|
output = pd.concat([df, df_wma], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Commodity Channel Index (CCI).",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"cci_data = obb.technical.cci(data=stock_data.results, length=14, scalar=0.015)",
|
|
],
|
|
),
|
|
APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def cci(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
length: PositiveInt = 14,
|
|
scalar: PositiveFloat = 0.015,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Commodity Channel Index (CCI).
|
|
|
|
The CCI is designed to detect beginning and ending market trends.
|
|
The range of 100 to -100 is the normal trading range. CCI values outside of this
|
|
range indicate overbought or oversold conditions. You can also look for price
|
|
divergence in the CCI. If the price is making new highs, and the CCI is not,
|
|
then a price correction is likely.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
The data to use for the CCI calculation.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
length : PositiveInt, optional
|
|
The length of the CCI, by default 14.
|
|
scalar : PositiveFloat, optional
|
|
The scalar of the CCI, by default 0.015.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The CCI data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, length)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_columns(df, ["close", "high", "low"])
|
|
cci_df = pd.DataFrame(df_target.ta.cci(length=length, scalar=scalar).dropna())
|
|
|
|
output = pd.concat([df, cci_df], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Relative Strength Index (RSI).",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"rsi_data = obb.technical.rsi(data=stock_data.results, target='close', length=14, scalar=100.0, drift=1)",
|
|
],
|
|
),
|
|
APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def rsi(
|
|
data: List[Data],
|
|
target: str = "close",
|
|
index: str = "date",
|
|
length: int = 14,
|
|
scalar: float = 100.0,
|
|
drift: int = 1,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Relative Strength Index (RSI).
|
|
|
|
RSI calculates a ratio of the recent upward price movements to the absolute price
|
|
movement. The RSI ranges from 0 to 100.
|
|
The RSI is interpreted as an overbought/oversold indicator when
|
|
the value is over 70/below 30. You can also look for divergence with price. If
|
|
the price is making new highs/lows, and the RSI is not, it indicates a reversal.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
The data to use for the RSI calculation.
|
|
target : str
|
|
Target column name.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date"
|
|
length : int, optional
|
|
The length of the RSI, by default 14
|
|
scalar : float, optional
|
|
The scalar to use for the RSI, by default 100.0
|
|
drift : int, optional
|
|
The drift to use for the RSI, by default 1
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The RSI data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, length)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_column(df, target).to_frame()
|
|
rsi_df = pd.DataFrame(
|
|
df_target.ta.rsi(
|
|
length=length,
|
|
scalar=scalar,
|
|
drift=drift,
|
|
close=target,
|
|
prefix=target,
|
|
).dropna()
|
|
)
|
|
|
|
output = pd.concat([df, rsi_df], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Stochastic Oscillator.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"stoch_data = obb.technical.stoch(data=stock_data.results, fast_k_period=14, slow_d_period=3, slow_k_period=3)", # noqa: E501 # pylint: disable=line-too-long
|
|
],
|
|
),
|
|
],
|
|
)
|
|
def stoch(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
fast_k_period: NonNegativeInt = 14,
|
|
slow_d_period: NonNegativeInt = 3,
|
|
slow_k_period: NonNegativeInt = 3,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Stochastic Oscillator.
|
|
|
|
The Stochastic Oscillator measures where the close is in relation
|
|
to the recent trading range. The values range from zero to 100. %D values over 75
|
|
indicate an overbought condition; values under 25 indicate an oversold condition.
|
|
When the Fast %D crosses above the Slow %D, it is a buy signal; when it crosses
|
|
below, it is a sell signal. The Raw %K is generally considered too erratic to use
|
|
for crossover signals.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
The data to use for the Stochastic Oscillator calculation.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date".
|
|
fast_k_period : NonNegativeInt, optional
|
|
The fast %K period, by default 14.
|
|
slow_d_period : NonNegativeInt, optional
|
|
The slow %D period, by default 3.
|
|
slow_k_period : NonNegativeInt, optional
|
|
The slow %K period, by default 3.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The Stochastic Oscillator data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, [fast_k_period, slow_d_period, slow_k_period])
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_columns(df, ["close", "high", "low"])
|
|
stoch_df = pd.DataFrame(
|
|
df_target.ta.stoch(
|
|
fast_k_period=fast_k_period,
|
|
slow_d_period=slow_d_period,
|
|
slow_k_period=slow_k_period,
|
|
).dropna()
|
|
)
|
|
|
|
output = pd.concat([df, stoch_df], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Keltner Channels.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"kc_data = obb.technical.kc(data=stock_data.results, length=20, scalar=20, mamode='ema', offset=0)",
|
|
],
|
|
),
|
|
APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def kc(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
length: PositiveInt = 20,
|
|
scalar: PositiveFloat = 20,
|
|
mamode: Literal["ema", "sma", "wma", "hma", "zlma"] = "ema",
|
|
offset: NonNegativeInt = 0,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Keltner Channels.
|
|
|
|
Keltner Channels are volatility-based bands that are placed
|
|
on either side of an asset's price and can aid in determining
|
|
the direction of a trend.The Keltner channel uses the average
|
|
true range (ATR) or volatility, with breaks above or below the top
|
|
and bottom barriers signaling a continuation.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
The data to use for the Keltner Channels calculation.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date"
|
|
length : PositiveInt, optional
|
|
The length of the Keltner Channels, by default 20
|
|
scalar : PositiveFloat, optional
|
|
The scalar to use for the Keltner Channels, by default 20
|
|
mamode : Literal["ema", "sma", "wma", "hma", "zlma"], optional
|
|
The moving average mode to use for the Keltner Channels, by default "ema"
|
|
offset : NonNegativeInt, optional
|
|
The offset to use for the Keltner Channels, by default 0
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The Keltner Channels data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, length)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_columns(df, ["high", "low", "close"])
|
|
kc_df = pd.DataFrame(
|
|
df_target.ta.kc(
|
|
length=length,
|
|
scalar=scalar,
|
|
mamode=mamode,
|
|
offset=offset,
|
|
).dropna()
|
|
)
|
|
output = pd.concat([df, kc_df], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Center of Gravity (CG).",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"cg_data = obb.technical.cg(data=stock_data.results, length=14)",
|
|
],
|
|
),
|
|
APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def cg(
|
|
data: List[Data], index: str = "date", length: PositiveInt = 14
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Center of Gravity.
|
|
|
|
The Center of Gravity indicator, in short, is used to anticipate future price movements
|
|
and to trade on price reversals as soon as they happen. However, just like other oscillators,
|
|
the COG indicator returns the best results in range-bound markets and should be avoided when
|
|
the price is trending. Traders who use it will be able to closely speculate the upcoming
|
|
price change of the asset.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
The data to use for the COG calculation.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date"
|
|
length : PositiveInt, optional
|
|
The length of the COG, by default 14
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The COG data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, length)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_columns(df, ["high", "low", "close"])
|
|
cg_df = pd.DataFrame(df_target.ta.cg(length=length).dropna())
|
|
|
|
output = pd.concat([df, cg_df], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Realized Volatility Cones.",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='yfinance')",
|
|
"cones_data = obb.technical.cones(data=stock_data.results, lower_q=0.25, upper_q=0.75, model='std')",
|
|
],
|
|
),
|
|
APIEx(parameters={"data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def cones(
|
|
data: List[Data],
|
|
index: str = "date",
|
|
lower_q: float = 0.25,
|
|
upper_q: float = 0.75,
|
|
model: Literal[
|
|
"std",
|
|
"parkinson",
|
|
"garman_klass",
|
|
"hodges_tompkins",
|
|
"rogers_satchell",
|
|
"yang_zhang",
|
|
] = "std",
|
|
is_crypto: bool = False,
|
|
trading_periods: Optional[int] = None,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the realized volatility quantiles over rolling windows of time.
|
|
|
|
The cones indicator is designed to map out the ebb and flow of price movements through a detailed analysis of
|
|
volatility quantiles. By examining the range of volatility within specific time frames, it offers a nuanced view of
|
|
market behavior, highlighting periods of stability and turbulence.
|
|
|
|
The model for calculating volatility is selectable and can be one of the following:
|
|
- Standard deviation
|
|
- Parkinson
|
|
- Garman-Klass
|
|
- Hodges-Tompkins
|
|
- Rogers-Satchell
|
|
- Yang-Zhang
|
|
|
|
Read more about it in the model parameter description.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
The data to use for the calculation.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date"
|
|
lower_q : float, optional
|
|
The lower quantile value for calculations
|
|
upper_q : float, optional
|
|
The upper quantile value for calculations
|
|
model : Literal["std", "parkinson", "garman_klass", "hodges_tompkins", "rogers_satchell", "yang_zhang"], optional
|
|
The model used to calculate realized volatility
|
|
|
|
Standard deviation measures how widely returns are dispersed from the average return.
|
|
It is the most common (and biased) estimator of volatility.
|
|
|
|
Parkinson volatility uses the high and low price of the day rather than just close to close prices.
|
|
It is useful for capturing large price movements during the day.
|
|
|
|
Garman-Klass volatility extends Parkinson volatility by taking into account the opening and closing price.
|
|
As markets are most active during the opening and closing of a trading session;
|
|
it makes volatility estimation more accurate.
|
|
|
|
Hodges-Tompkins volatility is a bias correction for estimation using an overlapping data sample.
|
|
It produces unbiased estimates and a substantial gain in efficiency.
|
|
|
|
Rogers-Satchell is an estimator for measuring the volatility with an average return not equal to zero.
|
|
Unlike Parkinson and Garman-Klass estimators, Rogers-Satchell incorporates a drift term,
|
|
mean return not equal to zero.
|
|
|
|
Yang-Zhang volatility is the combination of the overnight (close-to-open volatility).
|
|
It is a weighted average of the Rogers-Satchell volatility and the open-to-close volatility.
|
|
is_crypto : bool, optional
|
|
Whether the data is crypto or not. If True, volatility is calculated for 365 days instead of 252
|
|
trading_periods : Optional[int] [default: 252]
|
|
Number of trading periods in a year.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The cones data.
|
|
"""
|
|
if lower_q > upper_q:
|
|
lower_q, upper_q = upper_q, lower_q
|
|
|
|
df = basemodel_to_df(data, index=index)
|
|
df_cones = calculate_cones(
|
|
data=df,
|
|
lower_q=lower_q,
|
|
upper_q=upper_q,
|
|
model=model,
|
|
is_crypto=is_crypto,
|
|
trading_periods=trading_periods,
|
|
)
|
|
results = df_to_basemodel(df_cones)
|
|
|
|
return OBBject(results=results)
|
|
|
|
|
|
@router.command(
|
|
methods=["POST"],
|
|
examples=[
|
|
PythonEx(
|
|
description="Get the Exponential Moving Average (EMA).",
|
|
code=[
|
|
"stock_data = obb.equity.price.historical(symbol='TSLA', start_date='2023-01-01', provider='fmp')",
|
|
"ema_data = obb.technical.ema(data=stock_data.results, target='close', length=50, offset=0)",
|
|
],
|
|
),
|
|
APIEx(parameters={"length": 2, "data": APIEx.mock_data("timeseries")}),
|
|
],
|
|
)
|
|
def ema(
|
|
data: List[Data],
|
|
target: str = "close",
|
|
index: str = "date",
|
|
length: int = 50,
|
|
offset: int = 0,
|
|
) -> OBBject[List[Data]]:
|
|
"""Calculate the Exponential Moving Average (EMA).
|
|
|
|
EMA is a cumulative calculation, including all data. Past values have
|
|
a diminishing contribution to the average, while more recent values have a greater
|
|
contribution. This method allows the moving average to be more responsive to changes
|
|
in the data.
|
|
|
|
Parameters
|
|
----------
|
|
data : List[Data]
|
|
The data to use for the calculation.
|
|
target : str
|
|
Target column name.
|
|
index : str, optional
|
|
Index column name to use with `data`, by default "date"
|
|
length : int, optional
|
|
The length of the calculation, by default 50.
|
|
offset : int, optional
|
|
The offset of the calculation, by default 0.
|
|
|
|
Returns
|
|
-------
|
|
OBBject[List[Data]]
|
|
The calculated data.
|
|
"""
|
|
# pylint: disable=import-outside-toplevel
|
|
import pandas as pd
|
|
import pandas_ta as ta # noqa
|
|
|
|
validate_data(data, length)
|
|
df = basemodel_to_df(data, index=index)
|
|
df_target = get_target_column(df, target).to_frame()
|
|
ema_df = pd.DataFrame(
|
|
df_target.ta.ema(
|
|
length=length, offset=offset, close=target, prefix=target
|
|
).dropna()
|
|
)
|
|
|
|
output = pd.concat([df, ema_df], axis=1)
|
|
results = df_to_basemodel(output.reset_index())
|
|
|
|
return OBBject(results=results)
|