Project Overview
Rising Fortune is a cross-platform ETF / ETF-options desktop watcher for personal use, supporting macOS and Windows. It continuously collects market data, identifies market changes worth attention, and reminds the user to check the relevant instrument through system notifications, an in-app floating window and a tray entry.
The project is positioned as a watching-and-alerting analysis tool, not an automated trading system. Signals indicate "it is worth a look right now"; they do not place orders automatically, nor do they package historical statistics as deterministic returns.
- Repository: trade_etf_watcher
- Development: run Python modules directly, or package into a macOS App / Windows EXE via PyInstaller
- Data storage: market data, signals, option snapshots and local config are all stored in SQLite
From Ying+ to a Local Watching Tool
Before Rising Fortune, I independently built Ying+, a multi-client personal investment app:
- trade_ios: a SwiftUI + WidgetKit iOS client with code login, quotes, watchlist, K-lines and home-screen widgets;
- trade_admin: a Vue 3 + TypeScript + Element Plus admin console for managing interfaces, jobs and data;
- trade_backend: a FastAPI + PostgreSQL / TimescaleDB + Redis backend providing auth, quotes, factor data, scheduling and AI content.
Ying+ completed the multi-client technical chain, but continuing to promote it to the public would involve market-data licensing, product distribution and policy-compliance boundaries that a personal project cannot sustain, so I stopped productizing it. The code is kept as a multi-client architecture practice, with "launch and user growth" no longer a goal.
Afterwards I narrowed the requirement into a local desktop tool with no account system, no centralized data hosting and no public operation: solving only the watching, alerting and option-analysis problems I actually face every day. This trade-off moved the project from a "large, all-in-one investment platform" toward a well-bounded personal tool that I can fully deliver.
Current Features
Quotes and Charts
- TDX as the primary quote source and East Money as the backup, with a polling cycle of about 5 seconds;
- Automatically probes available nodes, switching and recovering after a connection failure;
- ECharts renders time-sharing, 1 / 5 / 15 / 30 / 60-minute and daily K-lines;
- Supports MA5 / MA10 / MA20, MACD, zoom, pan and a crosshair;
- K-lines open in a separate window, so they do not crowd the main watching panel.
Market Signals
- 14 volume-price patterns, including volume-follow, volume-buildup launch, squeeze breakout and high-level breakdown;
- Intraday momentum provides an end-of-day direction reference at a fixed time;
- 8 anomaly alerts covering gaps, sharp rises and drops, rebound-from-bottom, pullback-from-high, minute-level changes, and IV and PCR anomalies;
- Each signal keeps its trigger reason and input data, so it can be reviewed rather than only showing "buy" or "sell".
ETF Options Tools
- An option T-quote board covering 9 underlyings and 1200+ contracts;
- Shows bid/ask price and volume, implied volatility, Delta and open interest;
- Provides analysis pages such as volatility smile and surface, open-interest distribution and the IV term structure;
- Includes 7 strategy templates such as spread, straddle, butterfly and covered call;
- Uses Black-Scholes to compute theoretical price and the Greeks, and generates expiry payoff diagrams and time-decay tables;
- Saves a daily option snapshot to accumulate data for IV and open-interest history analysis.
Notifications and Delivery
- macOS native notifications support jumping to the corresponding instrument's K-line on click;
- The in-app floating window and the system tray provide the same jump path;
- The API key is configured via the GUI or a permission file under the user directory, never written into the repository or the installer;
- macOS App packaging and launch have been validated, and the Windows build config is ready.
System Architecture
TDX primary source / East Money backup / Tushare historical data
↓
Background polling and trading calendar
↓
K-line aggregation / volume-price patterns / intraday momentum / anomaly detection
↓ ↓
SQLite quotes and signals Option chain and daily snapshots
↓ ↓
PySide6 desktop shell + Vue 3 / ECharts pages
↓
Native notifications / floating window / system tray
The GUI and the market-collection thread are separated: the background thread handles network requests, computation and persistence, while the main thread only receives immutable results via Qt Signals and updates the UI, so polling never blocks interaction. The front-end pages are built with Vue 3 + TypeScript and embedded in a QWebEngineView, with Python driving data rendering through a controlled bridge.
Key Engineering Decisions
1. Dual data sources are not a simple failure retry
Quote interfaces produce unreachable nodes, intermittent single-IP rejections, temporarily empty fields and intraday data lag. The primary source probes available nodes at startup and records latency, reconnecting on a dropout; the backup source only rate-limits as a fallback when the primary is unavailable, so high-frequency requests do not trigger stricter limits.
Trading days, trading sessions and the lunch-break window are judged in a single calendar module, and all polling jobs reuse the same rules, so each data source does not interpret "should there be new data now" on its own.
2. Signals must be backtested, and failure conclusions must be published too
Volume-price patterns are not set by experience alone. I provided multi-instrument backtesting, parameter sweeps and feature-diagnosis tools for the rules, and included fees and benchmark returns in the validation.
The results show that some volume-price buy patterns have no positive expectation on the current single-stock sample, and that while the intraday momentum direction is statistically significant, the average per-trade magnitude of an instrument may be smaller than the bid-ask spread of ETF options. So the current version positions them as a direction reference and a manual-review reminder, not as a mechanical trading basis.
The project keeps these negative results, because "knowing where a rule does not work" matters more than only showing a few successful signals.
3. The option chain must reconcile real-time and historical semantics
Real-time T-quotes, minute K-lines, historical daily K-lines and contract metadata come from different interfaces, and their codes, expiry dates and price units are not naturally consistent. The system unifies contract coding, time and numeric semantics at the boundary layer, filters out all-zero K-lines produced by zero trades, and selects strategy legs within the same expiry month, so a cross-month combination does not distort the max profit/loss calculation.
Option snapshots are persisted per trading day, so volatility, open interest and the term structure can be compared across days rather than showing only the current instant.
4. AI capability must serve product trust
The project once implemented structured option-strategy suggestions based on DeepSeek, able to combine quotes, technicals, the option chain and historical movement to generate candidate strategies. After a product-boundary evaluation, the current UI actively removed this entry, while the underlying experimental code is kept.
The reason is that model output is easily misread as a deterministic trading suggestion, whereas a watching tool aims to present data, trigger alerts and assist human judgment. For a capability that cannot be reliably validated, I chose to pull it from the UI rather than keep displaying it just to "have AI".
5. Desktop packaging must account for two runtimes, Web and Qt
The app depends on Qt, WebEngine, ECharts and local Python modules at the same time. The PyInstaller config explicitly includes the WebEngine components, the front-end build artifacts and third-party data files; data arriving before the page finishes loading is first deduplicated and queued by render function, and the last copy is resent once the WebView is ready, so the first polling cycle at startup is not silently dropped.
Project Results
- Completed the full chain from market collection, signal analysis, option tools, desktop UI and notifications to local packaging;
- Supports T-quotes and analysis for 9 ETF-options underlyings and 1200+ contracts;
- Built repeatable backtesting, parameter-sweep and data-diagnosis tools, and actively narrowed the signal usage based on negative results;
- The macOS version has been packaged and launch-validated, and Windows keeps a separate build config;
- Distilled the halted Ying+ multi-client practice into a clear technical evolution, rather than continuing to maintain a public platform that cannot be compliantly promoted.
Tech Stack
Python 3.12 · PySide6 · Qt WebEngine · Vue 3 · TypeScript · ECharts · SQLite · pytdx · Tushare · akshare · PyInstaller
Disclaimer
This project is for personal watching, data analysis and technical research only. Market data may be delayed or intermittently unavailable, historical statistics do not represent future performance, and no signal constitutes investment advice.