From a4c0a142e3dd1586a92b649b09c6b2acc43a4548 Mon Sep 17 00:00:00 2001 From: Chris Berkhout Date: Thu, 12 Aug 2021 16:30:53 +0200 Subject: [PATCH] Expand README. --- README.md | 269 ++++++++++++++++++++++++++++++++++++++++---- example-gnuplot.png | Bin 0 -> 32357 bytes 2 files changed, 246 insertions(+), 23 deletions(-) create mode 100644 example-gnuplot.png diff --git a/README.md b/README.md index 601f2f9..8d02e6a 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,13 @@ pipx install pricehist - **`gnucash-sql`**: [GnuCash](https://www.gnucash.org/) SQL - **`ledger`**: [Ledger](https://www.ledger-cli.org/) and [hledger](https://hledger.org/) -## Examples +## Usage -Show usage information: +The following sections demonstrate different uses of `pricehist`. + +### Online help + +The `-h` option will show usage information: ```bash pricehist -h @@ -58,7 +62,7 @@ commands: fetch fetch prices ``` -Show usage information for the `fetch` command: +Here's the usage information for the `fetch` command: ``` pricehist fetch -h @@ -94,28 +98,48 @@ optional arguments: --fmt-csvdelim CHAR field delimiter for CSV output (default: ',') ``` -Fetch prices after 2021-01-04, ending 2021-01-15, as CSV: +### Fetching prices + +Fetch prices by choosing a source, a pair and, optionally, a time interval: ```bash -pricehist fetch ecb EUR/AUD -sx 2021-01-04 -e 2021-01-15 -o csv +pricehist fetch ecb EUR/AUD -s 2021-01-04 -e 2021-01-08 ``` ``` date,base,quote,amount,source,type +2021-01-04,EUR,AUD,1.5928,ecb,reference 2021-01-05,EUR,AUD,1.5927,ecb,reference 2021-01-06,EUR,AUD,1.5824,ecb,reference 2021-01-07,EUR,AUD,1.5836,ecb,reference 2021-01-08,EUR,AUD,1.5758,ecb,reference -2021-01-11,EUR,AUD,1.5783,ecb,reference -2021-01-12,EUR,AUD,1.5742,ecb,reference -2021-01-13,EUR,AUD,1.5734,ecb,reference -2021-01-14,EUR,AUD,1.5642,ecb,reference -2021-01-15,EUR,AUD,1.568,ecb,reference ``` -In Ledger format: +The default output format is CSV, which is suitable for use in spreadsheets and +with other tools. For example, on the command line using +[gnuplot](http://www.gnuplot.info/) we can chart Bitcoin prices: ```bash -pricehist fetch ecb EUR/AUD -s 2021-01-01 -o ledger | head +pricehist fetch coindesk BTC/USD -s 2021-01-01 | \ + cut -d, -f1,4 | \ + sed 1d | \ + gnuplot -p -e ' + set datafile separator ","; + set xdata time; + set timefmt "%Y-%m-%d"; + set format x "%b\n%Y"; + plot "/dev/stdin" using 1:2 with lines title "BTC/USD" + ' +``` + +![BTC/USD prices](example-gnuplot.png) + +### Choosing and customizing the output format + +You can choose a different output format: `ledger`, `beancount` or +`gnucash-sql`. + +```bash +pricehist fetch ecb EUR/AUD -s 2021-01-04 -e 2021-01-08 -o ledger ``` ``` P 2021-01-04 00:00:00 EUR 1.5928 AUD @@ -123,14 +147,28 @@ P 2021-01-05 00:00:00 EUR 1.5927 AUD P 2021-01-06 00:00:00 EUR 1.5824 AUD P 2021-01-07 00:00:00 EUR 1.5836 AUD P 2021-01-08 00:00:00 EUR 1.5758 AUD -P 2021-01-11 00:00:00 EUR 1.5783 AUD -P 2021-01-12 00:00:00 EUR 1.5742 AUD -P 2021-01-13 00:00:00 EUR 1.5734 AUD -P 2021-01-14 00:00:00 EUR 1.5642 AUD -P 2021-01-15 00:00:00 EUR 1.568 AUD ``` -Generate SQL for a GnuCash database and apply it immediately: +The formatting options let you control certain details of the output. The +following example removes the time of day (to make it suitable for hledger) and +makes a few other adjustments. + +```bash +pricehist fetch ecb EUR/AUD -s 2021-01-04 -e 2021-01-08 -o ledger \ + --fmt-time '' --fmt-datesep / --fmt-base € --fmt-quote $ --fmt-symbol left +``` +``` +P 2021/01/04 € $1.5928 +P 2021/01/05 € $1.5927 +P 2021/01/06 € $1.5824 +P 2021/01/07 € $1.5836 +P 2021/01/08 € $1.5758 +``` + +### GnuCash SQL output + +You can generate SQL for a GnuCash database and apply it immediately with one +of the following commands: ```bash pricehist fetch ecb EUR/AUD -s 2021-01-01 -o gnucash-sql | sqlite3 Accounts.gnucash @@ -138,12 +176,197 @@ pricehist fetch ecb EUR/AUD -s 2021-01-01 -o gnucash-sql | mysql -u username -p pricehist fetch ecb EUR/AUD -s 2021-01-01 -o gnucash-sql | psql -U username -d databasename -v ON_ERROR_STOP=1 ``` -## Design choices +Beware that the GnuCash project itself does not support integration at the +database level, so there is a risk that the SQL generated by `pricehist` will +be ineffective or even damaging for some new version of GnuCash. -To keep things simple, at least for now, `pricehist` provides only univariate -time series of daily historical prices. It doesn't provide other types of -market, financial or economic data, real-time prices, or other temporal -resolutions. Multiple or multivariate series require multiple invocations. +In practice, this strategy has been used successfully by other projects. +Reviewing the SQL and keeping regular database backups is recommended. + +### Source information + +Some basic information about each source is available: + +```bash +pricehist source ecb +``` +``` +ID : ecb +Name : European Central Bank +Description : European Central Bank Euro foreign exchange reference rates +URL : https://www.ecb.europa.eu/stats/exchange/eurofxref/html/index.en.html +Start : 1999-01-04 +Types : reference +``` + +Symbol information can be listed for most sources, either as full pairs or as +separate base and quote symbols that work in particular combinations: + +```bash +pricehist source ecb --symbols +``` +``` +EUR/AUD Euro against Australian Dollar +EUR/BGN Euro against Bulgarian Lev +EUR/BRL Euro against Brazilian Real +EUR/CAD Euro against Canadian Dollar +EUR/CHF Euro against Swiss Franc +... +``` + +It may also be possible to search for symbols: + +```bash +pricehist source alphavantage --search Tesla +``` +``` +TL0.DEX Tesla, Equity, XETRA, EUR +TL0.FRK Tesla, Equity, Frankfurt, EUR +TSLA34.SAO Tesla, Equity, Brazil/Sao Paolo, BRL +TSLA Tesla Inc, Equity, United States, USD +TXLZF Tesla Exploration Ltd, Equity, United States, USD +``` + +### Inspecting source interactions + +You can see extra information, including `curl` commands to reproduce each +request to a source, by adding the verbose option (`--verbose` or `-vvv`): + +```bash +pricehist fetch coindesk BTC/USD -s 2021-01-01 -e 2021-01-05 -vvv +``` +``` +DEBUG Began pricehist run at 2021-08-12 14:38:26.630357. +DEBUG Starting new HTTPS connection (1): api.coindesk.com:443 +DEBUG https://api.coindesk.com:443 "GET /v1/bpi/historical/close.json?currency=USD&start=2021-01-01&end=2021-01-05 HTTP/1.1" 200 319 +DEBUG curl -X GET -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Connection: keep-alive' -H 'User-Agent: python-requests/2.25.1' --compressed 'https://api.coindesk.com/v1/bpi/historical/close.json?currency=USD&start=2021-01-01&end=2021-01-05' +DEBUG Available data covers the interval [2021-01-01--2021-01-05], as requested. +date,base,quote,amount,source,type +2021-01-01,BTC,USD,29391.775,coindesk,close +2021-01-02,BTC,USD,32198.48,coindesk,close +2021-01-03,BTC,USD,33033.62,coindesk,close +2021-01-04,BTC,USD,32017.565,coindesk,close +2021-01-05,BTC,USD,34035.0067,coindesk,close +DEBUG Ended pricehist run at 2021-08-12 14:38:26.709428. +``` + +You can run a logged `curl` command to see exactly what data is returned by the +source: + +```bash +pricehist fetch coindesk BTC/USD -s 2021-01-01 -e 2021-01-05 -vvv 2>&1 \ + | grep 'DEBUG curl' | sed 's/^DEBUG //' | bash | jq . +``` +```json +{ + "bpi": { + "2021-01-01": 29391.775, + "2021-01-02": 32198.48, + "2021-01-03": 33033.62, + "2021-01-04": 32017.565, + "2021-01-05": 34035.0067 + }, + "disclaimer": "This data was produced from the CoinDesk Bitcoin Price Index. BPI value data returned as USD.", + "time": { + "updated": "Jan 6, 2021 00:03:00 UTC", + "updatedISO": "2021-01-06T00:03:00+00:00" + } +} +``` + +### Use as a library + +While not yet optimized for use as a library, you may find `pricehist`'s source +classes useful in your own scripts: + +```python +$ python +Python 3.9.6 (default, Jun 30 2021, 10:22:16) +[GCC 11.1.0] on linux +Type "help", "copyright", "credits" or "license" for more information. +>>> from pricehist.series import Series +>>> from pricehist.sources.ecb import ECB +>>> series = ECB().fetch(Series("EUR", "AUD", "reference", "2021-01-04", "2021-01-08")) +>>> series.prices +[Price(date='2021-01-04', amount=Decimal('1.5928')), Price(date='2021-01-05', amount=Decimal('1.5927')), Price(date='2021-01-06', amount=Decimal('1.5824')), Price(date='2021-01-07', amount=Decimal('1.5836')), Price(date='2021-01-08', amount=Decimal('1.5758'))] +``` + +A subclass of `pricehist.exceptions.SourceError` will be raised for any error. + +## Terminology + +A **source** is the upstream service that can provide a series of prices. + +Each **series** of prices is for one pair and price type. + +The [**pair**](https://en.wikipedia.org/wiki/Currency_pair) is made up of a +base and a quote, each given as a symbol. Sometimes you will give the base +only, and the quote will be determined with information from the source. The +available pairs, the symbols used in them and the available price types all +depend on the particular source used. + +The **base** is the currency or commodity being valued. Each price expresses +the value of one unit of the base. + +The **quote** is the unit used to express the value of the base. + +A **symbol** is a code or abbreviation for a currency or commodity. + +The **prices** in a series each have a date and an amount. + +The **amount** is the number of units of the quote that are equal to one unit +of the base. + +Consider the following command: + +```bash +pricehist fetch coindesk BTC/USD --type close +``` + +- **`coindesk`** is the ID of the CoinDesk Bitcoin Price Index source. +- **`BTC`** is the symbol for Bitcoin. +- **`USD`** is the symbol for the United States Dollar. +- **`BTC/USD`** is the pair Bitcoin against United States Dollar. +- **`close`** is the price type for last price of each day. + +A BTC/USD price of the amount 29,391.775 can be written as +"BTC/USD = 29391.775" or "BTC 29391.775 USD", and means that one Bitcoin is +worth 29,391.775 United States Dollars. + +## Initial design choices + +To keep things simple, `pricehist` provides only univariate time series of +daily historical prices. It doesn't provide other types of market, financial or +economic data, real-time prices, or other temporal resolutions. Multiple or +multivariate series require multiple invocations. + +## Future potential features + +While the following features are relatively low value or beyond `pricehist`'s +primary use case, they could be built upon the foundation it has established. + +- **Time of day**: Sources sometimes provide specific times for each day's + high/low prices and these could be preserved for output. This would require + changes to how dates are handled internally, clarification of time zone + handling and extension of the time formatting option. +- **Alternate resolutions**: Some sources can provide higher or lower + resolution data, such as hourly or weekly. These could be supported where + available. For other cases an option could be provided for downsampling data + before output. +- **Real-time prices**: These generally come from different soruce endpoints + than the historical data. Real-time prices will usually have a different + price type, such as `last`, `bid` or `ask`. Support for real-time prices + would allow adding sources that don't provide historical data. Start and end + times are irrelevant when requesting real-time prices. A "follow" option + could continuously poll for new prices. +- **Related non-price data**: Trading volume, spreads, split and dividend + events and other related data could be supported. The base/quote/type model + used for prices would work for some of this. Other things may require + extending the model. +- **Multivariate series**: Would allow, for example, fetching + high/low/open/close prices in a single invocation. +- **`format` command**: A command for rewriting existing CSV data into one of + the other output formats. ## Alternatives diff --git a/example-gnuplot.png b/example-gnuplot.png new file mode 100644 index 0000000000000000000000000000000000000000..f73ca28f39cbbfd48fdd15c9da0f9884eee184b5 GIT binary patch literal 32357 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