{"id":13739808,"url":"https://github.com/coding-kitties/investing-algorithm-framework","last_synced_at":"2026-02-06T23:07:36.149Z","repository":{"id":40410199,"uuid":"228824550","full_name":"coding-kitties/investing-algorithm-framework","owner":"coding-kitties","description":"Framework for developing, backtesting, and deploying automated trading algorithms and trading bots.","archived":false,"fork":false,"pushed_at":"2026-01-18T22:48:26.000Z","size":38316,"stargazers_count":646,"open_issues_count":29,"forks_count":89,"subscribers_count":12,"default_branch":"main","last_synced_at":"2026-01-19T07:09:26.730Z","etag":null,"topics":["algorithmic-trading","backtesting","backtesting-trading-strategies","cryptocurrency","python","quantitative","quantitative-analysis","quantitative-finance","quantitative-trading","trade","trading","trading-bot","trading-bots","trading-strategies"],"latest_commit_sha":null,"homepage":"https://coding-kitties.github.io/investing-algorithm-framework/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/coding-kitties.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-12-18T11:20:36.000Z","updated_at":"2026-01-18T22:48:30.000Z","dependencies_parsed_at":"2023-12-14T17:44:10.792Z","dependency_job_id":"b6d02e83-a8cb-4a60-9315-4a436ba7b172","html_url":"https://github.com/coding-kitties/investing-algorithm-framework","commit_stats":{"total_commits":501,"total_committers":5,"mean_commits":100.2,"dds":0.5169660678642715,"last_synced_commit":"bbbaee371c1559136547770db964ac9af5d42514"},"previous_names":[],"tags_count":250,"template":false,"template_full_name":null,"purl":"pkg:github/coding-kitties/investing-algorithm-framework","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coding-kitties%2Finvesting-algorithm-framework","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coding-kitties%2Finvesting-algorithm-framework/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coding-kitties%2Finvesting-algorithm-framework/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coding-kitties%2Finvesting-algorithm-framework/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coding-kitties","download_url":"https://codeload.github.com/coding-kitties/investing-algorithm-framework/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coding-kitties%2Finvesting-algorithm-framework/sbom","scorecard":{"id":298170,"data":{"date":"2025-08-11","repo":{"name":"github.com/coding-kitties/investing-algorithm-framework","commit":"9c2fad69715541ebd315e4d486bc141acbb8e858"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Maintained","score":10,"reason":"30 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/publish.yml:11","Warn: no topLevel permission defined: .github/workflows/publish.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: third-party GitHubAction not pinned by hash: .github/workflows/publish.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/coding-kitties/investing-algorithm-framework/publish.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/coding-kitties/investing-algorithm-framework/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/coding-kitties/investing-algorithm-framework/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/coding-kitties/investing-algorithm-framework/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/coding-kitties/investing-algorithm-framework/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:55: update your workflow using https://app.stepsecurity.io/secureworkflow/coding-kitties/investing-algorithm-framework/test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/coding-kitties/investing-algorithm-framework/test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:81: update your workflow using https://app.stepsecurity.io/secureworkflow/coding-kitties/investing-algorithm-framework/test.yml/main?enable=pin","Warn: pipCommand not pinned by hash: investing_algorithm_framework/cli/templates/aws_lambda_dockerfile.template:16","Warn: pipCommand not pinned by hash: investing_algorithm_framework/cli/templates/aws_lambda_dockerfile.template:17","Warn: pipCommand not pinned by hash: .github/workflows/test.yml:34","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   3 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 1 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"37 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-wf5p-g6vw-rhxx","Warn: Project is vulnerable to: GHSA-jr5f-v2jv-69x6","Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-jchw-25xp-jwwc","Warn: Project is vulnerable to: GHSA-cxjh-pqwp-8mfp","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-c7qv-q95q-8v27","Warn: Project is vulnerable to: GHSA-4www-5p9h-95mh","Warn: Project is vulnerable to: GHSA-9gqv-wp59-fq42","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-76c9-3jph-rj3q","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-x7hr-w5r2-h6wg","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-76p7-773f-r4q5","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-w5p7-h5w8-2hfq","Warn: Project is vulnerable to: GHSA-4vvj-4cpr-p986","Warn: Project is vulnerable to: GHSA-wr3j-pwj9-hqq6","Warn: Project is vulnerable to: GHSA-4v9v-hfq4-rm2v","Warn: Project is vulnerable to: GHSA-9jgg-88mc-972h","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-9548-qrrj-x5pj","Warn: Project is vulnerable to: GHSA-43qf-4rqw-9q2g","Warn: Project is vulnerable to: GHSA-7rxf-gvfg-47g4","Warn: Project is vulnerable to: GHSA-8vgw-p6qm-5gr7","Warn: Project is vulnerable to: GHSA-33p9-3p43-82vq"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T20:03:06.941Z","repository_id":40410199,"created_at":"2025-08-17T20:03:06.942Z","updated_at":"2025-08-17T20:03:06.942Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28618797,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T22:24:05.405Z","status":"ssl_error","status_checked_at":"2026-01-20T22:20:31.342Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithmic-trading","backtesting","backtesting-trading-strategies","cryptocurrency","python","quantitative","quantitative-analysis","quantitative-finance","quantitative-trading","trade","trading","trading-bot","trading-bots","trading-strategies"],"created_at":"2024-08-03T04:00:37.846Z","updated_at":"2026-01-20T23:16:40.971Z","avatar_url":"https://github.com/coding-kitties.png","language":"Python","readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003e⚡ Investing Algorithm Framework\u003c/h1\u003e\n  \n  \u003cp style=\"font-size: 18px; font-weight: 600; margin: 15px 0;\"\u003e\n    🚀 \u003cb\u003eBuild. Backtest. Deploy.\u003c/b\u003e Quantitative Trading Strategies at Scale\n  \u003c/p\u003e\n  \n  \u003cp style=\"font-size: 14px; color: #666; margin-bottom: 25px;\"\u003e\n    The fastest way to go from trading idea to production-ready trading bot\n  \u003c/p\u003e\n\n  \u003c!-- Quick Links --\u003e\n  \u003cdiv style=\"margin: 20px 0;\"\u003e\n    \u003ca target=\"_blank\" href=\"https://coding-kitties.github.io/investing-algorithm-framework/\"\u003e\n      \u003cimg src=\"https://img.shields.io/badge/📖_Documentation-blue?style=for-the-badge\"\u003e\n    \u003c/a\u003e\n    \u0026nbsp;\n    \u003ca href=\"https://coding-kitties.github.io/investing-algorithm-framework/Getting%20Started/installation\"\u003e\n      \u003cimg src=\"https://img.shields.io/badge/🚀_Quick_Start-green?style=for-the-badge\"\u003e\n    \u003c/a\u003e\n  \u003c/div\u003e\n\n  \u003c!-- Badges --\u003e\n  \u003cdiv style=\"margin-bottom: 20px;\"\u003e\n    \u003ca target=\"_blank\" href=\"https://discord.gg/dQsRmGZP\"\u003e\u003cimg src=\"https://img.shields.io/discord/1345358169777635410.svg?color=7289da\u0026label=Discord\u0026logo=discord\u0026style=flat-square\" alt=\"Discord\"\u003e\u003c/a\u003e\n    \u0026nbsp;\n    \u003ca href=\"https://github.com/coding-kitties/investing-algorithm-framework/actions/workflows/test.yml\"\u003e\u003cimg src=\"https://github.com/coding-kitties/investing-algorithm-framework/actions/workflows/test.yml/badge.svg?style=flat-square\" alt=\"Tests\"\u003e\u003c/a\u003e\n    \u0026nbsp;\n    \u003ca href=\"https://pypi.org/project/investing-algorithm-framework/\"\u003e\u003cimg src=\"https://img.shields.io/pypi/v/investing-algorithm-framework.svg?style=flat-square\" alt=\"PyPI\"\u003e\u003c/a\u003e\n    \u0026nbsp;\n    \u003ca href=\"https://pepy.tech/project/investing-algorithm-framework\"\u003e\u003cimg src=\"https://pepy.tech/badge/investing-algorithm-framework/month?style=flat-square\" alt=\"Downloads\"\u003e\u003c/a\u003e\n    \u0026nbsp;\n    \u003ca href=\"https://github.com/coding-kitties/investing-algorithm-framework/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/coding-kitties/investing-algorithm-framework?style=flat-square\" alt=\"Stars\"\u003e\u003c/a\u003e\n  \u003c/div\u003e\n\n  \u003cimg src=\"static/showcase.svg\" alt=\"Investing Algorithm Framework\" style=\"height: 400px; max-width: 100%; margin: 30px 0;\"\u003e\n\n  \u003chr style=\"margin: 30px 0; border: none; border-top: 2px solid #ddd;\"\u003e\n\n  \u003e ⭐ **If you like this project, please consider [starring](https://github.com/coding-kitties/investing-algorithm-framework) it!** Your support helps us build better tools for the community.\n\n\u003c/div\u003e\n\n---\n\n## 💡 Why Investing Algorithm Framework?\n\nStop wasting time on boilerplate. The **Investing Algorithm Framework** handles all the heavy lifting:\n\n✨ **From Idea to Production** — Write your strategy once, deploy everywhere  \n📊 **Accurate Backtesting** — Event-driven and vectorized engines for realistic results  \n⚡ **Lightning Fast** — Optimized for speed and efficiency  \n🔧 **Extensible** — Connect any exchange, broker, or data source  \n📈 **Production Ready** — Built for real money trading\n\n## Sponsors\n\n\u003ca href=\"https://www.finterion.com/\" target=\"_blank\"\u003e\n    \u003cpicture style=\"height: 30px;\"\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"static/sponsors/finterion-dark.png\"\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"static/sponsors/finterion-light.png\"\u003e\n    \u003cimg src=\"static/sponsors/finterion-light.png\" alt=\"Finterion Logo\" width=\"200px\" height=\"50px\"\u003e\n    \u003c/picture\u003e\n\u003c/a\u003e\n\n\n## 🔌 Plugins \u0026 Integrations\n\nExtend your trading bot with powerful plugins:\n\n| Plugin | Description                                                                 |\n|--------|-----------------------------------------------------------------------------|\n| 🎯 **[PyIndicators](https://github.com/coding-kitties/PyIndicators)** | Technical analysis indicators for strategy development                      |\n| 🏪 **[Finterion Plugin](https://github.com/Finterion/finterion-investing-algorithm-framework-plugin)** | Monetize \u0026 share your strategies with the public on Finterion's marketplace |\n\n## 🌟 Powerful Features\n\n| Feature | Description |\n|---------|-------------|\n| 🐍 **Python 3.10+** | Cross-platform support for Windows, macOS, and Linux |\n| ⚙️ **Event-Driven Backtest** | Accurate, realistic backtesting with event-driven architecture |\n| ⚡ **Vectorized Backtest** | Lightning-fast signal research and prototyping |\n| 📊 **Advanced Metrics** | CAGR, Sharpe ratio, max drawdown, win rate, and 50+ more metrics |\n| 📈 **Backtest Reports** | Generate detailed, comparison-ready reports |\n| 🎯 **Statistical Testing** | Permutation testing for strategy significance evaluation |\n| 💱 **Live Trading** | Real-time execution across multiple exchanges (via CCXT) |\n| 💼 **Portfolio Management** | Full position and trade management with persistence |\n| 📉 **Market Data** | OHLCV, tickers, custom data — Polars \u0026 Pandas native |\n| 🔗 **Data Integrations** | PyIndicators, multiple data sources, custom providers |\n| ☁️ **Cloud Deployment** | Azure Functions, AWS Lambda, and more |\n| 🌐 **Web API** | REST API for bot interaction and monitoring |\n| 🧩 **Fully Extensible** | Custom strategies, data providers, order executors |\n| 🏗️ **Modular Design** | Build with reusable, composable components |\n\n\n\n## 🚀 Quickstart\n\n### 📦 Installation\n\nInstall the framework via [PyPI](https://pypi.org/project/investing-algorithm-framework/):\n\n```bash\npip install investing-algorithm-framework\n```\n\n### 🎯 Initialize Your Project\n\nRun the following command to scaffold a new trading bot:\n\n```bash\ninvesting-algorithm-framework init\n```\n\nFor an AWS Lambda-ready project:\n\n```bash\ninvesting-algorithm-framework init --type aws_lambda\n```\n\nThis creates:\n- **app.py** — Your bot's entry point (keep as-is)\n- **strategy.py** — Your trading strategy (customize this!)\n\n\u003e 💡 **Tip:** You can also create `default_web` or `azure_function` projects\n\n## 📈 Example: A Simple Trading Bot\nThe following example trading bot implements a simple moving average strategy.\nThe strategy will use data from bitvavo exchange and will calculate \nthe 20, 50 and 100 period exponential moving averages (EMA) and the \n14 period relative strength index (RSI).\n\n\u003e This example uses [PyIndicators](https://github.com/coding-kitties/pyindicators) for technical analysis.\n\u003e This dependency is not part of the framework, but is used to perform technical analysis on the dataframes.\n\u003e You can install it using pip: pip install pyindicators.\n\n```python\nfrom typing import Dict, Any\nfrom datetime import datetime, timezone\n\nimport pandas as pd\nfrom pyindicators import ema, rsi, crossover, crossunder\n\nfrom investing_algorithm_framework import TradingStrategy, DataSource, \\\n    TimeUnit, DataType, PositionSize, create_app, RESOURCE_DIRECTORY, \\\n    BacktestDateRange, BacktestReport, TakeProfitRule, StopLossRule\n\n\nclass RSIEMACrossoverStrategy(TradingStrategy):\n    time_unit = TimeUnit.HOUR\n    interval = 2\n    symbols = [\"BTC\"]\n    position_sizes = [\n        PositionSize(\n            symbol=\"BTC\", percentage_of_portfolio=20.0\n        ),\n        PositionSize(\n            symbol=\"ETH\", percentage_of_portfolio=20.0\n        )\n    ]\n    take_profits = [\n        TakeProfitRule(\n            symbol=\"BTC\",\n            percentage_threshold=10,\n            trailing=True,\n            sell_percentage=100\n        ),\n        TakeProfitRule(\n            symbol=\"ETH\",\n            percentage_threshold=10,\n            trailing=True,\n            sell_percentage=100\n        )\n    ]\n    stop_losses = [\n        StopLossRule(\n            symbol=\"BTC\",\n            percentage_threshold=5,\n            trailing=False,\n            sell_percentage=100\n        ),\n        StopLossRule(\n            symbol=\"ETH\",\n            percentage_threshold=5,\n            trailing=False,\n            sell_percentage=100\n        )\n    ]\n\n    def __init__(\n        self,\n        time_unit: TimeUnit,\n        interval: int,\n        market: str,\n        rsi_time_frame: str,\n        rsi_period: int,\n        rsi_overbought_threshold,\n        rsi_oversold_threshold,\n        ema_time_frame,\n        ema_short_period,\n        ema_long_period,\n        ema_cross_lookback_window: int = 10\n    ):\n        self.rsi_time_frame = rsi_time_frame\n        self.rsi_period = rsi_period\n        self.rsi_result_column = f\"rsi_{self.rsi_period}\"\n        self.rsi_overbought_threshold = rsi_overbought_threshold\n        self.rsi_oversold_threshold = rsi_oversold_threshold\n        self.ema_time_frame = ema_time_frame\n        self.ema_short_result_column = f\"ema_{ema_short_period}\"\n        self.ema_long_result_column = f\"ema_{ema_long_period}\"\n        self.ema_crossunder_result_column = \"ema_crossunder\"\n        self.ema_crossover_result_column = \"ema_crossover\"\n        self.ema_short_period = ema_short_period\n        self.ema_long_period = ema_long_period\n        self.ema_cross_lookback_window = ema_cross_lookback_window\n        data_sources = []\n\n        for symbol in self.symbols:\n            full_symbol = f\"{symbol}/EUR\"\n            data_sources.append(\n                DataSource(\n                    identifier=f\"{symbol}_rsi_data\",\n                    data_type=DataType.OHLCV,\n                    time_frame=self.rsi_time_frame,\n                    market=market,\n                    symbol=full_symbol,\n                    pandas=True,\n                    window_size=800\n                )\n            )\n            data_sources.append(\n                DataSource(\n                    identifier=f\"{symbol}_ema_data\",\n                    data_type=DataType.OHLCV,\n                    time_frame=self.ema_time_frame,\n                    market=market,\n                    symbol=full_symbol,\n                    pandas=True,\n                    window_size=800\n                )\n            )\n\n        super().__init__(\n            data_sources=data_sources, \n            time_unit=time_unit, \n            interval=interval\n        )\n\n    def _prepare_indicators(\n        self,\n        rsi_data,\n        ema_data\n    ):\n        \"\"\"\n        Helper function to prepare the indicators \n        for the strategy. The indicators are calculated\n        using the pyindicators library: https://github.com/coding-kitties/PyIndicators\n        \"\"\"\n        ema_data = ema(\n            ema_data,\n            period=self.ema_short_period,\n            source_column=\"Close\",\n            result_column=self.ema_short_result_column\n        )\n        ema_data = ema(\n            ema_data,\n            period=self.ema_long_period,\n            source_column=\"Close\",\n            result_column=self.ema_long_result_column\n        )\n        # Detect crossover (short EMA crosses above long EMA)\n        ema_data = crossover(\n            ema_data,\n            first_column=self.ema_short_result_column,\n            second_column=self.ema_long_result_column,\n            result_column=self.ema_crossover_result_column\n        )\n        # Detect crossunder (short EMA crosses below long EMA)\n        ema_data = crossunder(\n            ema_data,\n            first_column=self.ema_short_result_column,\n            second_column=self.ema_long_result_column,\n            result_column=self.ema_crossunder_result_column\n        )\n        rsi_data = rsi(\n            rsi_data,\n            period=self.rsi_period,\n            source_column=\"Close\",\n            result_column=self.rsi_result_column\n        )\n\n        return ema_data, rsi_data\n\n    def generate_buy_signals(self, data: Dict[str, Any]) -\u003e Dict[str, pd.Series]:\n        \"\"\"\n        Generate buy signals based on the moving average crossover.\n\n        data (Dict[str, Any]): Dictionary containing all the data for\n            the strategy data sources.\n\n        Returns:\n            Dict[str, pd.Series]: A dictionary where keys are symbols and values\n                are pandas Series indicating buy signals (True/False).\n        \"\"\"\n\n        signals = {}\n\n        for symbol in self.symbols:\n            ema_data_identifier = f\"{symbol}_ema_data\"\n            rsi_data_identifier = f\"{symbol}_rsi_data\"\n            ema_data, rsi_data = self._prepare_indicators(\n                data[ema_data_identifier].copy(),\n                data[rsi_data_identifier].copy()\n            )\n\n            # crossover confirmed\n            ema_crossover_lookback = ema_data[\n                self.ema_crossover_result_column].rolling(\n                window=self.ema_cross_lookback_window\n            ).max().astype(bool)\n\n            # use only RSI column\n            rsi_oversold = rsi_data[self.rsi_result_column] \\\n                \u003c self.rsi_oversold_threshold\n\n            buy_signal = rsi_oversold \u0026 ema_crossover_lookback\n            buy_signals = buy_signal.fillna(False).astype(bool)\n            signals[symbol] = buy_signals\n        return signals\n\n    def generate_sell_signals(self, data: Dict[str, Any]) -\u003e Dict[str, pd.Series]:\n        \"\"\"\n        Generate sell signals based on the moving average crossover.\n\n        Args:\n            data (Dict[str, Any]): Dictionary containing all the data for\n                the strategy data sources.\n\n        Returns:\n            Dict[str, pd.Series]: A dictionary where keys are symbols and values\n                are pandas Series indicating sell signals (True/False).\n        \"\"\"\n\n        signals = {}\n        for symbol in self.symbols:\n            ema_data_identifier = f\"{symbol}_ema_data\"\n            rsi_data_identifier = f\"{symbol}_rsi_data\"\n            ema_data, rsi_data = self._prepare_indicators(\n                data[ema_data_identifier].copy(),\n                data[rsi_data_identifier].copy()\n            )\n\n            # Confirmed by crossover between short-term EMA and long-term EMA\n            # within a given lookback window\n            ema_crossunder_lookback = ema_data[\n                self.ema_crossunder_result_column].rolling(\n                window=self.ema_cross_lookback_window\n            ).max().astype(bool)\n\n            # use only RSI column\n            rsi_overbought = rsi_data[self.rsi_result_column] \\\n               \u003e= self.rsi_overbought_threshold\n\n            # Combine both conditions\n            sell_signal = rsi_overbought \u0026 ema_crossunder_lookback\n            sell_signal = sell_signal.fillna(False).astype(bool)\n            signals[symbol] = sell_signal\n        return signals\n\n\nif __name__ == \"__main__\":\n    app = create_app()\n    app.add_strategy(\n        RSIEMACrossoverStrategy(\n            time_unit=TimeUnit.HOUR,\n            interval=2,\n            market=\"bitvavo\",\n            rsi_time_frame=\"2h\",\n            rsi_period=14,\n            rsi_overbought_threshold=70,\n            rsi_oversold_threshold=30,\n            ema_time_frame=\"2h\",\n            ema_short_period=12,\n            ema_long_period=26,\n            ema_cross_lookback_window=10\n        )\n    )\n\n    # Market credentials for coinbase for both the portfolio connection and data sources will\n    # be read from .env file, when not registering a market credential object in the app.\n    app.add_market(\n        market=\"bitvavo\",\n        trading_symbol=\"EUR\",\n    )\n    backtest_range = BacktestDateRange(\n        start_date=datetime(2023, 1, 1, tzinfo=timezone.utc),\n        end_date=datetime(2024, 6, 1, tzinfo=timezone.utc)\n    )\n    backtest = app.run_backtest(\n        backtest_date_range=backtest_range, initial_amount=1000\n    )\n    report = BacktestReport(backtest)\n    report.show(backtest_date_range=backtest_range, browser=True)\n```\n\n\u003e You can find more examples [here](./examples) folder.\n\n## 📚 Documentation\nComprehensive documentation is available at [github pages](https://coding-kitties.github.io/investing-algorithm-framework/).\n\n## 🛠️ Development\n\n### Setup\n\nClone the repository and install dependencies using Poetry:\n\n\u003e Make sure you have [Poetry](https://python-poetry.org/docs/#installation) installed.\n\n```bash\ngit clone https://github.com/coding-kitties/investing-algorithm-framework.git\ncd investing-algorithm-framework\npoetry install\n```\n\n### Running Tests\n\n```bash\n# Run all tests\npython -m unittest discover -s tests\n\n# Run specific test\npython -m unittest tests.services.test_trade_service.TestTradeService\n```\n\n## ⚠️ Risk Disclaimer\n\n🚨 **Use at Your Own Risk**\n\nIf you use this framework for your investments, **do not risk money which you are afraid to lose** until you have a clear understanding of how the framework works. \n\n**BEFORE YOU START USING MONEY WITH THE FRAMEWORK:**\n- ✅ Test your strategies thoroughly with backtesting\n- ✅ Review the source code of any plugins you use\n- ✅ Start with small amounts on paper trading first\n- ✅ Understand the risks involved\n\n**We assume no responsibility for your investment results. The authors and all affiliates disclaim any liability for losses.**\n\n---\n\n## 🤝 Contributing\n\nThe investing algorithm framework is a **community-driven project**. We welcome contributions at all levels:\n\n- 🐛 **Found a bug?** [Open an issue](https://github.com/coding-kitties/investing-algorithm-framework/issues/new)\n- 💡 **Have an idea?** [Share it with us](https://github.com/coding-kitties/investing-algorithm-framework/issues/new)\n- 🔧 **Want to code?** Check the [project board](https://github.com/coding-kitties/investing-algorithm-framework/projects?query=is%3Aopen)\n\n**Guidelines:**\n- Read the [Contributing Guide](https://coding-kitties.github.io/investing-algorithm-framework/Contributing%20Guide/contributing)\n- Always create PRs against the `develop` branch, not `main`\n- Open an issue before starting major feature work\n\n---\n\n## 📚 Documentation\n\nComprehensive documentation is available at [GitHub Pages](https://coding-kitties.github.io/investing-algorithm-framework/)\n\n---\n\n## 📬 Community\n\nJoin us and connect with other traders and developers:\n\n* 💬 [Discord Community](https://discord.gg/dQsRmGZP) — Real-time chat and support\n* 🔗 [Reddit Community](https://www.reddit.com/r/InvestingBots/) — Share strategies and discuss\n* 📖 [Documentation](https://coding-kitties.github.io/investing-algorithm-framework/) — Guides and API references\n\n---\n\n## 🏆 Acknowledgements\n\nWe want to thank all contributors to this project. A full list can be found in [AUTHORS.md](https://github.com/coding-kitties/investing-algorithm-framework/blob/master/AUTHORS.md)\n\n### Report Issues\n\nIf you discover a bug in the framework, please [search our issue tracker](https://github.com/coding-kitties/investing-algorithm-framework/issues?q=is%3Aissue) first. If it hasn't been reported, please [create a new issue](https://github.com/coding-kitties/investing-algorithm-framework/issues/new).\n\n---\n\n\u003cdiv align=\"center\"\u003e\n  \u003cp\u003e\n    \u003ca href=\"https://github.com/coding-kitties/investing-algorithm-framework/stargazers\"\u003e⭐ Star us on GitHub\u003c/a\u003e · \n    \u003ca href=\"https://discord.gg/dQsRmGZP\"\u003e💬 Join Discord\u003c/a\u003e · \n    \u003ca href=\"https://github.com/coding-kitties/investing-algorithm-framework/issues/new\"\u003e🐛 Report Bug\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n","funding_links":[],"categories":["Python"],"sub_categories":["Trading \u0026 Backtesting","交易与回测"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoding-kitties%2Finvesting-algorithm-framework","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoding-kitties%2Finvesting-algorithm-framework","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoding-kitties%2Finvesting-algorithm-framework/lists"}