Compare commits

..

No commits in common. "1ca36eaba9fea9a09af1e1fb450bbf0353be0ea5" and "f592bf77a67981e6c0603f1244f3b5dfe46f7060" have entirely different histories.

3 changed files with 4 additions and 32 deletions

View File

@ -2,29 +2,4 @@
[![Build Status](https://drone.deadbeef.codes/api/badges/steven/ynab-portfolio-monitor/status.svg)](https://drone.deadbeef.codes/steven/ynab-portfolio-monitor) [![Build Status](https://drone.deadbeef.codes/api/badges/steven/ynab-portfolio-monitor/status.svg)](https://drone.deadbeef.codes/steven/ynab-portfolio-monitor)
Track your securities in YNAB for account types and update your balance automatically. For each configured account, it will update the balance from your broker in YNAB every 6 hours by creating / editing a transaction named "Capital Gains or Losses". On days that exchanges are closed, it will not do anything. The end result is that there will be transaction each day with payee "Capital Gains or Losses" in YNAB for each account you configure, which allows tracking your account balance over time. Track your securities in YNAB for account types and update your balance automatically.
### Example docker-compose.yml
The values below are examples only. You can configure as many account pairings as you want using environment variables in a continuous series starting from 0 as shown below. Two example accounts are configured ending in _0 and _1 but a third can be added by adding account numbers/ID with _2.
```yaml
version: '3.8'
services:
ynab-portfolio-monitor:
image: registry.deadbeef.codes/ynab-portfolio-monitor:latest
restart: always
environment:
- questrade_refresh_token=4dsO6652dS3cxtcctscd3ds4Df2E0
- questrade_account_0=51000001 # TFSA
- questrade_account_1=51000002 # RRSP
- questrade_ynab_account_0=731af51e-cb40-4d4a-8094-8654e59e11fc # TFSA
- questrade_ynab_account_1=78e76e45-2fbe-4ab1-84e9-64ba0996d015 # RRSP
- ynab_budget_id=76566452-67ff-4642-99d1-47d752216fb3
- ynab_secret=98Q_J655F_TAyGnhCCDS4uqRe4R5654DT2d-ZXdssZ
volumes:
- /data/ynab-portfolio-monitor-data:/data
```

View File

@ -71,9 +71,7 @@ func main() {
// Questrade authentication needs to be refreshed and persistentData written to disk in case app restarts // Questrade authentication needs to be refreshed and persistentData written to disk in case app restarts
questradeClient, err = questrade.NewClient(persistentData.QuestradeRefreshToken) questradeClient, err = questrade.NewClient(persistentData.QuestradeRefreshToken)
if err != nil { if err != nil {
log.Printf("failed to create questrade client: %v", err) log.Fatalf("failed to create questrade client: %v", err)
time.Sleep(time.Minute * 5) // prevent multiple fast login failures
continue
} }
persistentData.QuestradeRefreshToken = questradeClient.Credentials.RefreshToken persistentData.QuestradeRefreshToken = questradeClient.Credentials.RefreshToken

View File

@ -31,7 +31,7 @@ type BaseTransaction struct {
Deleted bool `json:"deleted,omitempty"` Deleted bool `json:"deleted,omitempty"`
} }
// Used for single transaction responses // Used for single transaction requests / responses
type Transaction struct { type Transaction struct {
Data struct { Data struct {
TransactionIDs []string `json:"transaction_ids,omitempty"` TransactionIDs []string `json:"transaction_ids,omitempty"`
@ -40,7 +40,6 @@ type Transaction struct {
} }
} }
// Used for single transaction requests
type TransactionRequest struct { type TransactionRequest struct {
Transaction BaseTransaction `json:"transaction,omitempty"` Transaction BaseTransaction `json:"transaction,omitempty"`
} }
@ -105,7 +104,7 @@ func (c *Client) CreateTodayYNABCapitalGainsTransaction(accountID string, amount
return nil return nil
} }
// Accepts a YNAB account ID, transaction ID and transaction amount and updates the YNAB transaction with the matching ID // Accepts a YNAB account ID and transaction amount and creates a new YNAB transaction
func (c *Client) UpdateTodayYNABCapitalGainsTransaction(accountID string, transactionID string, amount int) error { func (c *Client) UpdateTodayYNABCapitalGainsTransaction(accountID string, transactionID string, amount int) error {
transaction := TransactionRequest{} transaction := TransactionRequest{}
transaction.Transaction.AccountID = accountID transaction.Transaction.AccountID = accountID