Skip to content

Commit

Permalink
Move symbol mapping to file (#24)
Browse files Browse the repository at this point in the history
* Move IBKR CATEGORY to Env variable to support self-hosted.

* Update doc

* Make Dockerfile more robust for multi arch support

* Make Dockerfile more robust for multi arch support

* Clean Dockerfile

* Revert reqs back to default

* Add symbol mapping to file

* Forgot mapping file

* Add file to Dockerfile

* Add missing req pyyaml

* Typo for config file

* Updated README

* Fix Req

* Remove file from Dockerfile

* Updated mappings file

* Apply suggestions from code review

* Update README.md

---------

Co-authored-by: Agustin Alexander <[email protected]>
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Jul 10, 2024
1 parent 3388880 commit 912381f
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 9 deletions.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ curl -X POST -H "Content-Type: application/json" \

```docker run -e GHOST_TOKEN=YOUR_GHOST_TOKEN -e IBKR_TOKEN=YOUR-IBKR-TOKEN -e IBKR_QUERY=YOUR-IBKR-QUERY agusalex/ghostfolio-sync```

In Podman

```podman run -e GHOST_TOKEN=YOUR_GHOST_TOKEN -e IBKR_TOKEN=$IBKR_TOKEN -e IBKR_QUERY=$IBKR_QUERY -e GHOST_HOST=http://$GHOST_URL -e GHOST_CURRENCY=EUR -e GHOST_IBKR_PLATFORM=$IBKR_PLATFORM -v ./mapping.yaml:/usr/app/src/mapping.yaml:Z agusalex/ghostfolio-sync```

### Symbol mapping

You can specify the symbol mappings in `mapping.yaml` and you do not need to rebuild the container with the above mount command.

### More Options
| Envs |Description |
|--|--|
Expand All @@ -45,20 +53,21 @@ curl -X POST -H "Content-Type: application/json" \
|**GHOST_KEY** | The key for your ghostfolio account, if this is used you don't need **GHOST_TOKEN** and vice-versa |
|**GHOST_HOST** | (optional) Ghostfolio Host, only add if using custom ghostfolio |
|**GHOST_CURRENCY** | (optional) Ghostfolio Account Currency, only applied if the account doesn't exist |
|**GHOST_IBKR_PLATFORM** | (optional) For self-hosted, specify the Platform ID |
|**CRON** | (optional) To run on a [Cron Schedule](https://crontab.guru/) |
|**OPERATION** | (optional) SYNCIBKR (default) or DELETEALL (will erase all operations of all accounts) |

### Configuring / Retrieving Platform ID

If you are using ghostfolio self-hosted option, you need to go into Ghostfolio and add a platform for IBKR.

Then do a request to `/account` to find the relevant platform ID and store it in the GHOST_IBKR_PLATFORM env variable
Then make a request to `/account` to find the relevant platform ID and store it in the IBKR_PLATFORM env variable

```bash
curl "http://10.0.0.2:3333/api/v1/account" \
-H "Authorization: Bearer $GHOST_TOKEN"

export GHOST_IBKR_PLATFORM=<PUT PLATFORM ID HERE>
export IBKR_PLATFORM=<PUT PLATFORM ID HERE>
```

## Contributing
Expand Down
21 changes: 14 additions & 7 deletions SyncIBKR.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from ibflex import client, parser, FlexQueryResponse, BuySell
from datetime import datetime
import json
import yaml


def get_cash_amount_from_flex(query):
Expand Down Expand Up @@ -55,7 +56,7 @@ class SyncIBKR:
IBKRNAME = "Interactive Brokers"
#IBKRCATEGORY = "66b22c82-a96c-4e4f-aaf2-64b4ca41dda2"

def __init__(self, ghost_host, ibkrtoken, ibkrquery, ghost_key, ghost_token, ghost_currency, ghost_ibkr_platform):
def __init__(self, ghost_host, ibkrtoken, ibkrquery, ghost_key, ghost_token, ghost_currency, ghost_ibkr_platform, mapping_file='mapping.yaml'):
if ghost_token == "" and ghost_key != "":
self.ghost_token = self.create_ghost_token(ghost_host, ghost_key)
else:
Expand All @@ -66,6 +67,13 @@ def __init__(self, ghost_host, ibkrtoken, ibkrquery, ghost_key, ghost_token, gho
self.ibkrquery = ibkrquery
self.ibkrplatform = ghost_ibkr_platform

# Load the configuration file
with open(mapping_file, 'r') as file:
config = yaml.safe_load(file)

# Extract the symbol mapping from the configuration
self.symbol_mapping = config.get('symbol_mapping', {})

def sync_ibkr(self):
print("Fetching Query")
response = client.download(self.ibkrtoken, self.ibkrquery)
Expand All @@ -85,12 +93,11 @@ def sync_ibkr(self):
date = datetime.strptime(str(trade.tradeDate), date_format)
iso_format = date.isoformat()
symbol = trade.symbol
if ".USD-PAXOS" in trade.symbol:
symbol = trade.symbol.replace(".USD-PAXOS", "") + "USD"
elif "VUAA" in trade.symbol:
symbol = trade.symbol + ".L"
elif "V80A" in trade.symbol:
symbol = "VNGA80.MI"
if symbol in self.symbol_mapping:
symbol = self.symbol_mapping[symbol]
print(f"Transformed symbol: {symbol}")
else:
print(f"Symbol {trade.symbol} not found in mapping.")
if trade.buySell == BuySell.BUY:
buysell = "BUY"
elif trade.buySell == BuySell.SELL:
Expand Down
11 changes: 11 additions & 0 deletions mapping.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# mapping.yaml
symbol_mapping:
VUAA: VUAA.L
V80A: VNGA80.MI
.USD-PAXOS: USD
CSPX: SXR8.DE
MEUD: MEUD.PA
EGLN: EGLN.L
IWDA: IWDA.AS
VWCE: VWCE.DE
# Add more mappings here as needed
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ git+https://github.com/agusalex/ibflex
requests==2.28.2
urllib3==1.26.14
requests
pyyaml

0 comments on commit 912381f

Please sign in to comment.