{"id":23673026,"url":"https://github.com/dmotte/smartchg","last_synced_at":"2025-04-11T00:22:24.345Z","repository":{"id":269357669,"uuid":"907158689","full_name":"dmotte/smartchg","owner":"dmotte","description":"🐍 DCA-based asset exchange algorithm","archived":false,"fork":false,"pushed_at":"2025-02-01T16:15:01.000Z","size":46,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-20T10:39:19.934Z","etag":null,"topics":["algorithm","apy","asset","averaging","calculator","change","command","csv","dca","exchange","invest","package","pip","pypi","python","return","smart","smartchg","value","yield"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/smartchg/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dmotte.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":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-23T00:53:23.000Z","updated_at":"2025-02-01T16:15:04.000Z","dependencies_parsed_at":"2024-12-23T02:15:19.430Z","dependency_job_id":"648acfdd-cf73-4c02-865b-0d93cf6c42f8","html_url":"https://github.com/dmotte/smartchg","commit_stats":null,"previous_names":["dmotte/smartchg"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmotte%2Fsmartchg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmotte%2Fsmartchg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmotte%2Fsmartchg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmotte%2Fsmartchg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dmotte","download_url":"https://codeload.github.com/dmotte/smartchg/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248318930,"owners_count":21083751,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["algorithm","apy","asset","averaging","calculator","change","command","csv","dca","exchange","invest","package","pip","pypi","python","return","smart","smartchg","value","yield"],"created_at":"2024-12-29T11:34:25.780Z","updated_at":"2025-04-11T00:22:24.325Z","avatar_url":"https://github.com/dmotte.png","language":"Python","readme":"# smartchg\n\n[![GitHub main workflow](https://img.shields.io/github/actions/workflow/status/dmotte/smartchg/main.yml?branch=main\u0026logo=github\u0026label=main\u0026style=flat-square)](https://github.com/dmotte/smartchg/actions)\n[![PyPI](https://img.shields.io/pypi/v/smartchg?logo=python\u0026style=flat-square)](https://pypi.org/project/smartchg/)\n\n:snake: DCA-based **asset exchange algorithm**.\n\nInspired by **PAC** (_Pre-Authorized Contribution_ plan) and [Smart PAC](https://www.youtube.com/watch?v=kSThDk39pjU).\n\n## Installation\n\nThis utility is available as a Python package on **PyPI**:\n\n```bash\npython3 -mpip install smartchg\n```\n\n## Usage\n\nThere are some files in the [`example`](example) directory of this repo that can be useful to demonstrate how this tool works, so let's change directory first:\n\n```bash\ncd example/\n```\n\nWe need a Python **virtual environment** (\"venv\") with some packages to do the demonstration:\n\n```bash\npython3 -mvenv venv\nvenv/bin/python3 -mpip install -r requirements.txt\n```\n\n\u003e **Note**: we refer to the **source asset** with the **generic ticker symbol** `SRC`, and to the **destination asset** with `DST`.\n\nNow we need to **fetch data** related to some asset. To do that, we can use https://github.com/dmotte/misc/blob/main/python-scripts/ohlcv-fetchers/yahoo-finance.py.\n\n\u003e **Note**: in the following commands, replace the local path of the `invoke.sh` script with the correct one.\n\n```bash\n~/git/misc/python-scripts/ohlcv-fetchers/invoke.sh yahoo-finance '^GSPC' -i1d -d2020-01-01T00Z -f'{:.6f}' \u003e ohlcv-SPX500.csv\n```\n\nNow that we have the data, we can **compute the output data and values**:\n\n```bash\nrate=$(tail -1 ohlcv-SPX500.csv | cut -d, -f6)\npython3 -msmartchg -a.15 -r\"$rate\" -t1000 --fmt-src='{:.2f}' --fmt-dst='{:.4f}' --fmt-{rate,simil}='{:.6f}' {ohlcv,smartchg,values}-SPX500.csv\ngrep '^sugg_' values-SPX500.csv\n```\n\n\u003e **Note**: each **output value** and **entry field** is described with a comment in the `compute_stuff` function's code. You can search for the strings `# - entry` and `# - values` in the [`smartchg/cli.py`](smartchg/cli.py) file to get an overview.\n\nAnd finally display some nice **plots** using the [`plots.py`](example/plots.py) script (which uses the [_Plotly_](https://github.com/plotly/plotly.py) Python library):\n\n```bash\nvenv/bin/python3 plots.py -ros {smartchg,values}-SPX500.csv\n```\n\nFor more details on how to use this command, you can also refer to its help message (`--help`).\n\n## Algorithm\n\nThe algorithm is based on the assumption that one **need to exchange** some amount of one asset (e.g. `EUR`) for another asset (e.g. `SPX500`) **regularly** (e.g. once a month, every month). Also, they cannot decide **when** to make the exchange (e.g. always on the same day of the month). Therefore, the only controllable variable is \"**how much**\" to exchange, that is, the quantity of assets to be exchanged.\n\nThis algorithm tries to **optimize the quantity** of assets to be exchanged based on the **trend** of the historical **exchange rate** values, in order to determine whether the current exchange rate is **convenient** (and therefore we should exchange **more**) or **unconvenient** (and therefore we should exchange **less**). In one simple sentence, the motto is: [_\"Buy more when low!\"_](https://www.investopedia.com/ask/answers/04/052704.asp)\n\n\u003e **Note**: the following explanation is for illustration purposes only. Please refer to the [Python code](smartchg/cli.py) for any details.\n\n| Symbol     | Variable          |\n| ---------- | ----------------- |\n| $a$        | `apy`             |\n| $m$        | `multiplier`      |\n| $t$        | `target`          |\n| $n$        | `len(data)`       |\n| $d_i$      | `entry['days']`   |\n| $r_i$      | `entry['rate']`   |\n| $p_i$      | `entry['pred']`   |\n| $\\delta_i$ | `entry['offset']` |\n| $s_i$      | `entry['simil']`  |\n| $S$        | `sugg_src`        |\n\nFirst of all, we need to calculate the exchange rate **prediction** and **offset**:\n\n$$\n    p_i = r_1 (1 + a)^{d_i/365}\n    \\quad \\quad\n    \\delta_i = r_i - p_i\n$$\n\nThen we need the **mean** and **standard deviation** of the offset values:\n\n$$\n    \\mu_\\delta = \\frac{1}{n} \\sum_{i=1}^{n} \\delta_i\n    \\quad \\quad\n    \\sigma_\\delta = \\sqrt{\\frac{1}{n-1} \\sum_{i=1}^{n} \\left( \\delta_i - \\mu_\\delta \\right) ^ 2}\n$$\n\nThe **similarity** values are calculated using the following formula:\n\n$$\n    s_i = \\frac{\\delta_i - \\mu_\\delta}{2 \\sigma_\\delta}\n$$\n\nFinally, we need to compute the **suggested `SRC` amount**, taking the **multiplier** value into account:\n\n$$ S = t (1 - s_n m) $$\n\nFor example, if $t=500$, $s_n=-1$, and $m=0.10$, we have:\n\n$$ S = 500 \\cdot (1 - (-1) \\cdot 0.10) = 500 \\cdot 1.1 = 550 $$\n\n## Development\n\nIf you want to contribute to this project, you can install the package in **editable** mode:\n\n```bash\npython3 -mpip install -e . --user\n```\n\nThis will just link the package to the original location, basically meaning any changes to the original package would reflect directly in your environment ([source](https://stackoverflow.com/a/35064498)).\n\nIf you want to run the tests, you'll have to install the `pytest` package and then run:\n\n```bash\npython3 -mpytest test\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmotte%2Fsmartchg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmotte%2Fsmartchg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmotte%2Fsmartchg/lists"}