Skill: brendanwood/portfolio-trader (version 1.1.0)

--- name: snaptrade-portfolio description: Connect to a user's investment accounts via SnapTrade SDK and generate portfolio reports (e.g., daily total value). Use when the user wants SnapTrade-based brokerage connectivity (Webull, E*TRADE, etc.), connection portal links, account registration, or automated portfolio summaries. --- # SnapTrade Portfolio ## Overview Connect brokerage accounts through SnapTrade and generate a daily total-value report. This skill uses the official SnapTrade Python SDK (`snaptrade_client`) with request signing handled automatically. ## Workflow ### 2d) Place buy/sell orders (stocks/ETFs) Run: ``` python3 scripts/snaptrade_order.py buy|sell TICKER UNITS --account-id <ACCOUNT_ID> [--order-type market|limit] [--limit-price <PRICE>] [--tif Day|GTC|IOC|FOK] ``` Defaults: - order type: **market** - time in force: **Day** - limit price: only required for limit orders Optional monitoring (poll recent orders): ``` python3 scripts/snaptrade_order.py buy|sell TICKER UNITS --account-id <ACCOUNT_ID> --watch ``` - polls every **10s** for up to **120s** by default - adjust with `--watch-interval` and `--watch-seconds` Watch an existing order by ID: ``` python3 scripts/snaptrade_watch_order.py --account-id <ACCOUNT_ID> --order-id <BROKERAGE_ORDER_ID> ``` - same 10s/120s defaults, adjustable with `--watch-interval` and `--watch-seconds` Use **account orders endpoint** to confirm fills and report open orders to the user when asked. ### 0) Create a SnapTrade account + API keys You need a SnapTrade account to connect brokerages. Create a free account at **https://snaptrade.com**, generate your **Client ID** and **Consumer Key**, then add them to the skill config. ### 1) Install dependencies ``` pip3 install -r requirements.txt ``` ### 2) Configure credentials (one-time) Store credentials in a local config file (not committed). `user_id` is generated automatically on first run: ``` /home/openclaw/.openclaw/workspace/secrets/snaptrade.json ``` Example: ``` { "client_id": "YOUR_CLIENT_ID", "consumer_key": "YOUR_CONSUMER_KEY", "user_id": "<auto-generated-uuid>" } ``` ### 2) Register user + generate connection portal link Run: ``` python3 scripts/snaptrade_portal.py ``` This will: - register the user if `user_secret` is missing - store `user_secret` back into the config file - print a **connection portal URL** the user must open to link accounts ### 2b) Reconnect a disabled connection Run: ``` python3 scripts/snaptrade_reconnect.py [brokerage-name] ``` This will: - list disabled connections - generate a reconnect link (optionally match by brokerage name) - print a **reconnect URL** for the user to re‑enable the connection ### 2c) List available brokerages (allowed connections) Run: ``` python3 scripts/snaptrade_brokers.py ``` This calls `/snaptrade/partners` and returns the `allowed_brokerages` list (display names). ### 3) Pull total portfolio value Run: ``` python3 scripts/snaptrade_total.py ``` Output is JSON like: ``` {"total_value": 123456.78, "currency": "CAD"} ``` ### 3b) Per-broker totals (converted currency) Run: ``` python3 scripts/snaptrade_broker_totals.py --currency CAD ``` Output JSON includes per-broker totals in the chosen currency and the FX rates used. **Implementation notes:** Avoid `get_user_holdings` when possible. Prefer `get_user_account_positions` (positions endpoint) for holdings/positions data. Only use balances/cash from holdings if explicitly required by the user; otherwise do not call holdings. ### 4) Schedule daily report Use cron to call `snaptrade_total.py`, format a concise WhatsApp message, then send it to the user. Only the total value is required. ## Scripts - `scripts/snaptrade_common.py` — config load/save + client creation - `scripts/snaptrade_portal.py` — register user + generate connection portal link - `scripts/snaptrade_reconnect.py` — generate reconnect link for disabled connections - `scripts/snaptrade_brokers.py` — list allowed brokerages for this client - `scripts/snaptrade_order.py` — place buy/sell orders (market/limit) with optional monitoring - `scripts/snaptrade_watch_order.py` — watch an existing order by ID for fills - `scripts/snaptrade_total.py` — compute total value across all accounts - `scripts/snaptrade_broker_totals.py` — per-broker totals with FX conversion ## Notes - Request signing is handled by the SDK via `request_after_hook` using `consumer_key`. - The total is computed by summing each account’s `account.balance.total` from holdings; this avoids errors when accounts are added or removed. - If multiple currencies are present, the script uses the first currency encountered. - Keep secrets in the local config file with `chmod 600` permissions.


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: suspicious | SkillSpector: suspicious (CRITICAL)