Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 36 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
# InteractiveBrokersPlatform

<!-- qsl-doc-overview:start -->

> ⚠️ 投资有风险,不构成投资建议,仅供学习交流用途。
> ⚠️ Investing involves risk. This project does not provide investment advice and is for educational and research purposes only.

## Open-source overview / 开源项目入口

| Item | Description |
| --- | --- |
| Project type | execution platform |
| What it does | Interactive Brokers execution platform for QuantStrategyLab US/HK equity strategies with Cloud Run dispatch and dry-run controls. |
| 中文说明 | IBKR 执行平台,负责加载策略、处理账户/市场输入,并通过 Cloud Run/调度执行 dry-run 或实盘路径。 |
| Current status | Execution platform. Treat all live credentials, account IDs and order paths as production-sensitive. |

### Quick start

- `python -m pip install -e '.[test]'`
- `python -m pytest -q`

### Deploy / operate safely

Start from dry-run GitHub Actions/Cloud Run deployment, verify secrets and account group config, then enable live execution only per account.

### Strategy performance / evidence boundary

Strategy performance is not owned here; review UsEquityStrategies, HkEquityStrategies and their snapshot pipeline evidence before enabling a profile.

> Detailed runbooks, migration notes, workflow internals, and historical decisions are kept below. Start with this overview before using the lower-level operational sections.

<!-- qsl-doc-overview:end -->

> Risk warning: this project is not investment advice and is provided for study and engineering validation only.

![Python](https://img.shields.io/badge/Python-3.9%2B-blue)
Expand Down Expand Up @@ -43,7 +74,6 @@ translation.
- `russell_1000_multi_factor_defensive`
- `tqqq_growth_income`
- `soxl_soxx_trend_income`
- `tech_communication_pullback_enhancement`
- `mega_cap_leader_rotation_top50_balanced`
- `nasdaq_sp500_smart_dca`
- `hk_blue_chip_leader_rotation` (architecture scaffold only; eligible but disabled)
Expand All @@ -60,7 +90,6 @@ translation.
| `russell_1000_multi_factor_defensive` | Russell 1000 Multi-Factor | Yes | Yes | `us_equity` | defensive stock baseline |
| `tqqq_growth_income` | TQQQ Growth Income | Yes | Yes | `us_equity` | enabled value-mode alternative |
| `soxl_soxx_trend_income` | SOXL/SOXX Semiconductor Trend Income | Yes | Yes | `us_equity` | current IBKR live line |
| `tech_communication_pullback_enhancement` | Tech/Communication Pullback Enhancement | Yes | Yes | `us_equity` | enabled feature-snapshot alternative |
| `mega_cap_leader_rotation_top50_balanced` | Mega Cap Leader Rotation Top50 Balanced | Yes | Yes | `us_equity` | enabled balanced Top50 leader rotation |
| `nasdaq_sp500_smart_dca` | Nasdaq/S&P 500 Smart DCA | Yes | Yes | `us_equity` | buy-only cash-deployment profile |
| `hk_blue_chip_leader_rotation` | HK Blue Chip Leader Rotation | Yes | No | `hk_equity` | architecture scaffold only; not runtime-enabled |
Expand Down Expand Up @@ -125,15 +154,15 @@ For IBKR, keep `paper` as a single account-group entry. If you later add live ac
| `IBKR_CONNECT_ATTEMPTS` | No | Number of IBKR connection attempts before failing the cycle. Defaults to `3`. |
| `IBKR_CONNECT_RETRY_DELAY_SECONDS` | No | Delay between failed IBKR connection attempts. Defaults to `5`. |
| `IBKR_CLIENT_ID_RETRY_OFFSET` | No | Offset added to the configured `ib_client_id` on each retry, so a timed-out API handshake can retry with a fresh client id. Defaults to `100`. |
| `STRATEGY_PROFILE` | Yes | Strategy profile selector. Enabled values: `global_etf_rotation`, `russell_1000_multi_factor_defensive`, `tqqq_growth_income`, `soxl_soxx_trend_income`, `tech_communication_pullback_enhancement`, `mega_cap_leader_rotation_top50_balanced`, `nasdaq_sp500_smart_dca`, `hk_listed_global_etf_rotation`. `hk_blue_chip_leader_rotation`, `hk_index_mean_reversion`, and `hk_etf_regime_rotation` are not runtime-enabled and are not selectable by the platform status/switch tooling. Cloud Run uses the values configured on the selected service. |
| `STRATEGY_PROFILE` | Yes | Strategy profile selector. Enabled values: `global_etf_rotation`, `russell_1000_multi_factor_defensive`, `tqqq_growth_income`, `soxl_soxx_trend_income`, `mega_cap_leader_rotation_top50_balanced`, `nasdaq_sp500_smart_dca`, `hk_listed_global_etf_rotation`. Tech/Communication and the HK scaffold profiles are not runtime-enabled and are not selectable by the platform status/switch tooling. Cloud Run uses the values configured on the selected service. |
| `ACCOUNT_GROUP` | Yes | Account-group selector. Set explicitly for each deployment. |
| `IBKR_MARKET` | No | Market scope. Defaults to `HK` when `ACCOUNT_GROUP` contains `hk`, otherwise `US`. |
| `IBKR_MARKET_CALENDAR` | No | Market calendar. Defaults to `XHKG` for HK and `NYSE` for US. |
| `IBKR_MARKET_TIMEZONE` | No | Market timezone. Defaults to `Asia/Hong_Kong` for HK and `America/New_York` for US. |
| `IBKR_MARKET_EXCHANGE` | No | Stock contract exchange. Defaults to `SEHK` for HK and `SMART` for US. |
| `IBKR_MARKET_CURRENCY` | No | Stock contract currency and portfolio currency scope. Defaults to `HKD` for HK and `USD` for US. |
| `IBKR_MARKET_DATA_SYMBOL_SUFFIX` | No | Suffix used only for yfinance fallback symbols. Defaults to `.HK` for HK and empty for US. |
| `IBKR_FEATURE_SNAPSHOT_PATH` | Conditionally required | Required for enabled snapshot-backed profiles such as `russell_1000_multi_factor_defensive`, `tech_communication_pullback_enhancement`, and `mega_cap_leader_rotation_top50_balanced`. The HK scaffold will also require this after promotion. Path to the latest feature snapshot file (`.csv`, `.json`, `.jsonl`, `.parquet`). |
| `IBKR_FEATURE_SNAPSHOT_PATH` | Conditionally required | Required for enabled snapshot-backed profiles such as `russell_1000_multi_factor_defensive` and `mega_cap_leader_rotation_top50_balanced`. The HK scaffold will also require this after promotion. Path to the latest feature snapshot file (`.csv`, `.json`, `.jsonl`, `.parquet`). |
| `IBKR_STRATEGY_PLUGIN_MOUNTS_JSON` | No | Optional IBKR-side strategy plugin mount JSON. The plugin artifact controls mode; platform config must not set `mode`. |
| `IBKR_MIN_ORDER_NOTIONAL_USD` | No | Minimum buy notional for limit buys; defaults to `50.0`. |
| `IBKR_MIN_RESERVED_CASH_USD` | No | Platform-level minimum cash reserve in USD. Defaults to `0`; the effective reserve is the max of this floor and the effective cash reserve ratio. |
Expand Down Expand Up @@ -199,11 +228,11 @@ NOTIFY_LANG=zh
```

```bash
STRATEGY_PROFILE=tech_communication_pullback_enhancement
STRATEGY_PROFILE=mega_cap_leader_rotation_top50_balanced
ACCOUNT_GROUP=paper
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups
IBKR_FEATURE_SNAPSHOT_PATH=/var/data/tech_communication_pullback_enhancement_feature_snapshot_latest.csv
IBKR_FEATURE_SNAPSHOT_MANIFEST_PATH=/var/manifests/tech_communication_pullback_enhancement_feature_snapshot_latest.csv.manifest.json
IBKR_FEATURE_SNAPSHOT_PATH=/var/data/mega_cap_leader_rotation_top50_balanced_feature_snapshot_latest.csv
IBKR_FEATURE_SNAPSHOT_MANIFEST_PATH=/var/manifests/mega_cap_leader_rotation_top50_balanced_feature_snapshot_latest.csv.manifest.json
# IBKR_STRATEGY_CONFIG_PATH is optional; the bundled canonical default is used when unset.
IBKR_DRY_RUN_ONLY=true
# IBKR orders run on whole shares only.
Expand Down
4 changes: 2 additions & 2 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ IBKR 账户
| `IBKR_CONNECT_ATTEMPTS` | 否 | IBKR 连接失败前最多尝试次数。默认 `3`。 |
| `IBKR_CONNECT_RETRY_DELAY_SECONDS` | 否 | IBKR 连接重试间隔,单位秒。默认 `5`。 |
| `IBKR_CLIENT_ID_RETRY_OFFSET` | 否 | 每次重试时加到 `ib_client_id` 上的偏移量,用新的 client id 避开超时握手留下的卡住会话。默认 `100`。 |
| `STRATEGY_PROFILE` | 是 | 策略档位选择。当前已启用值:`global_etf_rotation`、`russell_1000_multi_factor_defensive`、`tqqq_growth_income`、`soxl_soxx_trend_income`、`tech_communication_pullback_enhancement`、`mega_cap_leader_rotation_top50_balanced`、`nasdaq_sp500_smart_dca`、`hk_listed_global_etf_rotation`。`hk_blue_chip_leader_rotation`、`hk_index_mean_reversion`、`hk_etf_regime_rotation` 不是 runtime-enabled,不会被平台状态/切换工具列为可选;Cloud Run 使用当前服务上配置的取值 |
| `STRATEGY_PROFILE` | 是 | 策略档位选择。当前已启用值:`global_etf_rotation`、`russell_1000_multi_factor_defensive`、`tqqq_growth_income`、`soxl_soxx_trend_income`、`mega_cap_leader_rotation_top50_balanced`、`nasdaq_sp500_smart_dca`、`hk_listed_global_etf_rotation`。Tech/Communication 和港股 scaffold profiles 不是 runtime-enabled,不会被平台状态/切换工具列为可选;Cloud Run 使用当前服务上配置的取值 |
| `ACCOUNT_GROUP` | 是 | 账号组选择器,每个部署都要显式设置。 |
| `IBKR_MARKET` | 否 | 市场范围。`ACCOUNT_GROUP` 包含 `hk` 时默认 `HK`,其他情况默认 `US`。 |
| `IBKR_MARKET_CALENDAR` | 否 | 市场日历。港股默认 `XHKG`,美股默认 `NYSE`。 |
| `IBKR_MARKET_TIMEZONE` | 否 | 市场时区。港股默认 `Asia/Hong_Kong`,美股默认 `America/New_York`。 |
| `IBKR_MARKET_EXCHANGE` | 否 | 股票合约交易所。港股默认 `SEHK`,美股默认 `SMART`。 |
| `IBKR_MARKET_CURRENCY` | 否 | 股票合约币种和组合现金口径。港股默认 `HKD`,美股默认 `USD`。 |
| `IBKR_MARKET_DATA_SYMBOL_SUFFIX` | 否 | 仅用于 yfinance fallback 的标的后缀。港股默认 `.HK`,美股默认空。 |
| `IBKR_FEATURE_SNAPSHOT_PATH` | 条件必填 | `russell_1000_multi_factor_defensive`、`tech_communication_pullback_enhancement`、`mega_cap_leader_rotation_top50_balanced` 等已启用快照策略需要;港股架构占位后续启用时也会需要。指向最新特征快照文件(`.csv`、`.json`、`.jsonl`、`.parquet`)。 |
| `IBKR_FEATURE_SNAPSHOT_PATH` | 条件必填 | `russell_1000_multi_factor_defensive`、`mega_cap_leader_rotation_top50_balanced` 等已启用快照策略需要;港股架构占位后续启用时也会需要。指向最新特征快照文件(`.csv`、`.json`、`.jsonl`、`.parquet`)。 |
| `IBKR_STRATEGY_PLUGIN_MOUNTS_JSON` | 否 | 可选的 IBKR 侧策略插件挂载 JSON。插件 artifact 自带模式;平台配置不要设置 `mode`。 |
| `IBKR_MIN_ORDER_NOTIONAL_USD` | 否 | 限价买入的最小名义金额;默认 `50.0`。 |
| `IBKR_MIN_RESERVED_CASH_USD` | 否 | 平台级最低预留现金 USD。默认 `0`;实际预留取该下限和有效预留现金比例中的最大值。 |
Expand Down
6 changes: 5 additions & 1 deletion strategy_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

IBKR_PLATFORM = "ibkr"
HK_EQUITY_DOMAIN = "hk_equity"
TECH_COMMUNICATION_PULLBACK_PROFILE = "tech_communication_pullback_enhancement"

PLATFORM_SUPPORTED_DOMAINS: dict[str, frozenset[str]] = {
IBKR_PLATFORM: frozenset({US_EQUITY_DOMAIN, HK_EQUITY_DOMAIN}),
Expand Down Expand Up @@ -95,7 +96,10 @@ def describe_platform_runtime_requirements(profile: str | None, *, platform_id:
STRATEGY_CATALOG = _merge_strategy_catalogs(US_STRATEGY_CATALOG, HK_STRATEGY_CATALOG)
US_STRATEGY_PROFILES = frozenset(US_STRATEGY_CATALOG.definitions)
HK_STRATEGY_PROFILES = frozenset(HK_STRATEGY_CATALOG.definitions)
IBKR_ROLLOUT_ALLOWLIST = get_us_runtime_enabled_profiles() | get_hk_runtime_enabled_profiles()
IBKR_EXCLUDED_LIVE_PROFILES = frozenset({TECH_COMMUNICATION_PULLBACK_PROFILE})
IBKR_ROLLOUT_ALLOWLIST = (
get_us_runtime_enabled_profiles() | get_hk_runtime_enabled_profiles()
) - IBKR_EXCLUDED_LIVE_PROFILES
PLATFORM_CAPABILITY_MATRIX = PlatformCapabilityMatrix(
platform_id=IBKR_PLATFORM,
supported_domains=PLATFORM_SUPPORTED_DOMAINS[IBKR_PLATFORM],
Expand Down
4 changes: 2 additions & 2 deletions tests/test_decision_mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def test_map_strategy_decision_maps_weight_positions_and_safe_haven():

target_weights, signal_desc, is_emergency, status_desc, metadata = map_strategy_decision(
decision,
strategy_profile="tech_communication_pullback_enhancement",
strategy_profile="mega_cap_leader_rotation_top50_balanced",
runtime_metadata={"status_icon": "🧲", "dry_run_only": True},
)

Expand Down Expand Up @@ -49,7 +49,7 @@ def test_map_strategy_decision_returns_noop_when_flagged_no_execute():

target_weights, signal_desc, is_emergency, status_desc, metadata = map_strategy_decision(
decision,
strategy_profile="tech_communication_pullback_enhancement",
strategy_profile="mega_cap_leader_rotation_top50_balanced",
runtime_metadata={
"status_icon": "🛑",
"snapshot_guard_decision": "fail_closed",
Expand Down
Loading