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
54 changes: 28 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
Quant system on LongPort OpenAPI and Google Cloud Run.

This repository uses `QuantPlatformKit` for LongPort token handling, context bootstrap, account snapshot access, market data, and order submission. Cloud Run deploys this repository directly.
The LongBridge runtime can execute all seven live `us_equity` profiles from `UsEquityStrategies`; `LongBridgePlatform` keeps the LongPort runtime, token refresh, execution, and notification flow.
The LongBridge runtime can execute all eight live `us_equity` profiles from `UsEquityStrategies`; `LongBridgePlatform` keeps the LongPort runtime, token refresh, execution, and notification flow.

Full strategy documentation now lives in [`UsEquityStrategies`](https://github.com/QuantStrategyLab/UsEquityStrategies). The sections below focus on LongBridge runtime behavior, profile enablement, deployment, and credentials.
This runtime matrix is the authoritative enablement source for LongBridge. `UsEquityStrategies` carries strategy-layer logic, cadence, compatibility, and metadata.
Expand All @@ -29,15 +29,16 @@ Platform execution no longer depends on `strategy/allocation.py` or hard-coded s

**LongBridge profile status**

| Canonical profile | Display name | Eligible | Enabled | Default | Rollback | Domain | Runtime note |
| --- | --- | --- | --- | --- | --- | --- | --- |
| `global_etf_rotation` | Global ETF Rotation | Yes | Yes | No | No | `us_equity` | enabled weight-mode rotation line |
| `russell_1000_multi_factor_defensive` | Russell 1000 Multi-Factor | Yes | Yes | No | No | `us_equity` | enabled feature-snapshot stock baseline |
| `mega_cap_leader_rotation_dynamic_top20` | Mega Cap Leader Rotation Dynamic Top20 | Yes | Yes | No | No | `us_equity` | selectable monthly feature-snapshot leader rotation |
| `dynamic_mega_leveraged_pullback` | Dynamic Mega Leveraged Pullback | Yes | Yes | No | No | `us_equity` | selectable 2x mega-cap pullback line |
| `soxl_soxx_trend_income` | SOXL/SOXX Semiconductor Trend Income | Yes | Yes | Yes | Yes | `us_equity` | current LongBridge default |
| `tqqq_growth_income` | TQQQ Growth Income | Yes | Yes | No | No | `us_equity` | current SG dry-run line |
| `tech_communication_pullback_enhancement` | Tech/Communication Pullback Enhancement | Yes | Yes | No | No | `us_equity` | current HK feature-snapshot line |
| Canonical profile | Display name | Eligible | Enabled | Domain | Runtime note |
| --- | --- | --- | --- | --- | --- |
| `global_etf_rotation` | Global ETF Rotation | Yes | Yes | `us_equity` | enabled weight-mode rotation line |
| `russell_1000_multi_factor_defensive` | Russell 1000 Multi-Factor | Yes | Yes | `us_equity` | enabled feature-snapshot stock baseline |
| `mega_cap_leader_rotation_aggressive` | Mega Cap Leader Rotation Aggressive | Yes | Yes | `us_equity` | selectable aggressive monthly feature-snapshot leader rotation |
| `mega_cap_leader_rotation_dynamic_top20` | Mega Cap Leader Rotation Dynamic Top20 | Yes | Yes | `us_equity` | selectable monthly feature-snapshot leader rotation |
| `dynamic_mega_leveraged_pullback` | Dynamic Mega Leveraged Pullback | Yes | Yes | `us_equity` | selectable 2x mega-cap pullback line |
| `soxl_soxx_trend_income` | SOXL/SOXX Semiconductor Trend Income | Yes | Yes | `us_equity` | current SG deployment |
| `tqqq_growth_income` | TQQQ Growth Income | Yes | Yes | `us_equity` | selectable growth line |
| `tech_communication_pullback_enhancement` | Tech/Communication Pullback Enhancement | Yes | Yes | `us_equity` | current HK feature-snapshot line |

Check the current matrix locally:

Expand All @@ -63,7 +64,7 @@ Telegram notifications include structured execution and heartbeat messages, with
| `LONGPORT_APP_SECRET` | Yes | LongPort OpenAPI app secret (for token refresh); recommended to inject from the region-specific Secret Manager secret for this deployment, such as `longport-app-secret-hk` / `longport-app-secret-sg` |
| `LONGPORT_SECRET_NAME` | No | Secret Manager secret name for LongPort token (default: `longport_token_hk`) |
| `ACCOUNT_PREFIX` | No | Alert/log prefix for account/environment (default: `DEFAULT`) |
| `STRATEGY_PROFILE` | No | Strategy profile selector (default: `soxl_soxx_trend_income`; enabled values include `dynamic_mega_leveraged_pullback`, `global_etf_rotation`, `mega_cap_leader_rotation_dynamic_top20`, `russell_1000_multi_factor_defensive`, `soxl_soxx_trend_income`, `tech_communication_pullback_enhancement`, and `tqqq_growth_income`) |
| `STRATEGY_PROFILE` | Yes | Strategy profile selector. Set explicitly per deployment; enabled values include `dynamic_mega_leveraged_pullback`, `global_etf_rotation`, `mega_cap_leader_rotation_aggressive`, `mega_cap_leader_rotation_dynamic_top20`, `russell_1000_multi_factor_defensive`, `soxl_soxx_trend_income`, `tech_communication_pullback_enhancement`, and `tqqq_growth_income` |
| `ACCOUNT_REGION` | No | Account region marker for platform-style deployment (e.g. `HK`, `SG`; defaults to `ACCOUNT_PREFIX` / `DEFAULT`) |
| `LONGBRIDGE_DRY_RUN_ONLY` | No | Set to `true` to keep the selected deployment in dry-run mode. |
| `INCOME_THRESHOLD_USD` | No | Optional override for the `tqqq_growth_income` income-layer threshold. Leave unset to use the strategy package default. |
Expand All @@ -89,7 +90,7 @@ Deploy the same codebase as multiple Cloud Run services (e.g. `HK` and `SG`) by

- `LONGPORT_SECRET_NAME`: point to different secrets (e.g. `longport_token_hk`, `longport_token_sg`)
- `ACCOUNT_PREFIX`: e.g. `HK`, `SG` (all Telegram/log alerts will include `[ACCOUNT_PREFIX]`)
- `STRATEGY_PROFILE`: set per service; current live examples are `tech_communication_pullback_enhancement` on HK and `tqqq_growth_income` on SG
- `STRATEGY_PROFILE`: set per service; current live examples are `tech_communication_pullback_enhancement` on HK and `soxl_soxx_trend_income` on SG
- Current strategy domain is `us_equity`. `STRATEGY_PROFILE` now goes through a platform capability matrix plus a rollout allowlist derived from `runtime_enabled` strategy metadata: `eligible` means the platform can run it in theory, `enabled` means the current rollout really allows it.
- `ACCOUNT_REGION`: explicitly mark the deployed account region (`HK` / `SG`); if unset, the app falls back to `ACCOUNT_PREFIX` or `DEFAULT`
- `LONGBRIDGE_DRY_RUN_ONLY`: set per service when that deployment should stay dry-run
Expand All @@ -116,7 +117,7 @@ Recommended setup:
- **GitHub Environment: `longbridge-sg`**
- Variables: `CLOUD_RUN_REGION`, `CLOUD_RUN_SERVICE`, `ACCOUNT_PREFIX`, `ACCOUNT_REGION`, `STRATEGY_PROFILE`, `LONGPORT_SECRET_NAME`, `LONGPORT_APP_KEY_SECRET_NAME`, `LONGPORT_APP_SECRET_SECRET_NAME`
- Optional variables: `LONGBRIDGE_FEATURE_SNAPSHOT_PATH`, `LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH`, `LONGBRIDGE_STRATEGY_CONFIG_PATH`, `LONGBRIDGE_DRY_RUN_ONLY`, `INCOME_THRESHOLD_USD`, `QQQI_INCOME_RATIO`
- Current live example: `STRATEGY_PROFILE=tqqq_growth_income`
- Current live example: `STRATEGY_PROFILE=soxl_soxx_trend_income`
- Recommended secret-name values: `longport-app-key-sg`, `longport-app-secret-sg`

On every push to `main`, the workflow updates both Cloud Run services with the shared and per-environment values above, and removes `TELEGRAM_CHAT_ID` from each Cloud Run service.
Expand Down Expand Up @@ -157,7 +158,7 @@ IAM: the Cloud Run service account needs **Secret Manager Admin** (or Secret Acc
基于 LongPort OpenAPI 和 Google Cloud Run 的量化交易系统。

这个仓库通过 `QuantPlatformKit` 复用 LongPort token 处理、上下文初始化、账户快照、行情读取和下单逻辑。Cloud Run 直接部署这个仓库。
`LongBridgePlatform` 现在可直接执行 `UsEquityStrategies` 里的全部 7 条 live `us_equity` 策略:`dynamic_mega_leveraged_pullback`、`global_etf_rotation`、`mega_cap_leader_rotation_dynamic_top20`、`russell_1000_multi_factor_defensive`、`soxl_soxx_trend_income`、`tqqq_growth_income` 和 `tech_communication_pullback_enhancement`;仓库本身继续保留 LongPort 运行时、token 刷新、执行和通知流程。
`LongBridgePlatform` 现在可直接执行 `UsEquityStrategies` 里的全部 8 条 live `us_equity` 策略:`dynamic_mega_leveraged_pullback`、`global_etf_rotation`、`mega_cap_leader_rotation_aggressive`、`mega_cap_leader_rotation_dynamic_top20`、`russell_1000_multi_factor_defensive`、`soxl_soxx_trend_income`、`tqqq_growth_income` 和 `tech_communication_pullback_enhancement`;仓库本身继续保留 LongPort 运行时、token 刷新、执行和通知流程。

完整策略说明现在放在 [`UsEquityStrategies`](https://github.com/QuantStrategyLab/UsEquityStrategies)。下面这些章节只保留 LongBridge 运行时、profile 启用状态、部署和凭据说明。

Expand All @@ -174,15 +175,16 @@ IAM: the Cloud Run service account needs **Secret Manager Admin** (or Secret Acc

**LongBridge profile status**

| Canonical profile | Display name | Eligible | Enabled | Default | Rollback | Domain | Runtime note |
| --- | --- | --- | --- | --- | --- | --- | --- |
| `global_etf_rotation` | Global ETF Rotation | Yes | Yes | No | No | `us_equity` | 已启用的 weight-mode 轮动线 |
| `russell_1000_multi_factor_defensive` | Russell 1000 Multi-Factor | Yes | Yes | No | No | `us_equity` | 已启用的 feature-snapshot 个股基线 |
| `mega_cap_leader_rotation_dynamic_top20` | Mega Cap Leader Rotation Dynamic Top20 | Yes | Yes | No | No | `us_equity` | 可选的月度 feature-snapshot 龙头轮动线 |
| `dynamic_mega_leveraged_pullback` | Dynamic Mega Leveraged Pullback | Yes | Yes | No | No | `us_equity` | 可选的 2x 龙头回调线 |
| `soxl_soxx_trend_income` | SOXL/SOXX 半导体趋势收益 | Yes | Yes | Yes | Yes | `us_equity` | 当前 LongBridge 默认回退线 |
| `tqqq_growth_income` | TQQQ 增长收益 | Yes | Yes | No | No | `us_equity` | 当前 SG dry-run 线路 |
| `tech_communication_pullback_enhancement` | 科技通信回调增强 | Yes | Yes | No | No | `us_equity` | 当前 HK feature-snapshot 线路 |
| Canonical profile | Display name | Eligible | Enabled | Domain | Runtime note |
| --- | --- | --- | --- | --- | --- |
| `global_etf_rotation` | Global ETF Rotation | Yes | Yes | `us_equity` | 已启用的 weight-mode 轮动线 |
| `russell_1000_multi_factor_defensive` | Russell 1000 Multi-Factor | Yes | Yes | `us_equity` | 已启用的 feature-snapshot 个股基线 |
| `mega_cap_leader_rotation_aggressive` | Mega Cap Leader Rotation Aggressive | Yes | Yes | `us_equity` | 可选的激进月度 feature-snapshot 龙头轮动线 |
| `mega_cap_leader_rotation_dynamic_top20` | Mega Cap Leader Rotation Dynamic Top20 | Yes | Yes | `us_equity` | 可选的月度 feature-snapshot 龙头轮动线 |
| `dynamic_mega_leveraged_pullback` | Dynamic Mega Leveraged Pullback | Yes | Yes | `us_equity` | 可选的 2x 龙头回调线 |
| `soxl_soxx_trend_income` | SOXL/SOXX 半导体趋势收益 | Yes | Yes | `us_equity` | 当前 SG 部署线路 |
| `tqqq_growth_income` | TQQQ 增长收益 | Yes | Yes | `us_equity` | 可选增长线路 |
| `tech_communication_pullback_enhancement` | 科技通信回调增强 | Yes | Yes | `us_equity` | 当前 HK feature-snapshot 线路 |

本地可直接查看当前矩阵:

Expand All @@ -208,7 +210,7 @@ Telegram 通知包含结构化的调仓和心跳消息,支持中英文切换
| `LONGPORT_APP_SECRET` | 是 | LongPort OpenAPI 应用密钥(用于刷新 Token);建议从当前部署对应区域的 Secret Manager 密钥注入,例如 `longport-app-secret-hk` / `longport-app-secret-sg` |
| `LONGPORT_SECRET_NAME` | 否 | Secret Manager 中的密钥名称(默认: `longport_token_hk`) |
| `ACCOUNT_PREFIX` | 否 | 通知/日志前缀,区分账户环境(默认: `DEFAULT`) |
| `STRATEGY_PROFILE` | | 策略档位选择(默认: `soxl_soxx_trend_income`;已启用值还包括 `dynamic_mega_leveraged_pullback`、`global_etf_rotation`、`mega_cap_leader_rotation_dynamic_top20`、`russell_1000_multi_factor_defensive`、`soxl_soxx_trend_income`、`tech_communication_pullback_enhancement` 和 `tqqq_growth_income` |
| `STRATEGY_PROFILE` | | 策略档位选择。每个部署都要显式设置;已启用值包括 `dynamic_mega_leveraged_pullback`、`global_etf_rotation`、`mega_cap_leader_rotation_aggressive`、`mega_cap_leader_rotation_dynamic_top20`、`russell_1000_multi_factor_defensive`、`soxl_soxx_trend_income`、`tech_communication_pullback_enhancement` 和 `tqqq_growth_income` |
| `ACCOUNT_REGION` | 否 | 平台化部署时的账户区域标记(如 `HK`、`SG`;默认按 `ACCOUNT_PREFIX` / `DEFAULT` 推断) |
| `LONGBRIDGE_DRY_RUN_ONLY` | 否 | 设为 `true` 时,该部署保持 dry-run。 |
| `INCOME_THRESHOLD_USD` | 否 | 可选的 `tqqq_growth_income` 收入层启动阈值覆盖。不填时使用策略包默认值。 |
Expand All @@ -234,7 +236,7 @@ Secret Manager 中需存在 `LONGPORT_SECRET_NAME` 指定的密钥(默认: `lo

- `LONGPORT_SECRET_NAME`: 指向不同密钥(如 `longport_token_hk`、`longport_token_sg`)
- `ACCOUNT_PREFIX`: 如 `HK`、`SG`(所有通知/日志将包含 `[ACCOUNT_PREFIX]`)
- `STRATEGY_PROFILE`: 按服务分别设置;当前线上 HK 用 `tech_communication_pullback_enhancement`,SG 用 `tqqq_growth_income`
- `STRATEGY_PROFILE`: 按服务分别设置;当前线上 HK 用 `tech_communication_pullback_enhancement`,SG 用 `soxl_soxx_trend_income`
- 当前策略域是 `us_equity`。`STRATEGY_PROFILE` 现在会先经过平台能力矩阵,再经过从 `runtime_enabled` 策略元数据派生的 rollout allowlist:`eligible` 表示平台理论可跑,`enabled` 表示当前 rollout 真正放开。
- `ACCOUNT_REGION`: 显式标记部署账户区域(`HK` / `SG`);未设置时会回退到 `ACCOUNT_PREFIX` 或 `DEFAULT`
- `LONGBRIDGE_DRY_RUN_ONLY`: 需要保持模拟运行时按服务单独设置
Expand All @@ -261,7 +263,7 @@ Secret Manager 中需存在 `LONGPORT_SECRET_NAME` 指定的密钥(默认: `lo
- **GitHub Environment: `longbridge-sg`**
- Variables: `CLOUD_RUN_REGION`、`CLOUD_RUN_SERVICE`、`ACCOUNT_PREFIX`、`ACCOUNT_REGION`、`STRATEGY_PROFILE`、`LONGPORT_SECRET_NAME`、`LONGPORT_APP_KEY_SECRET_NAME`、`LONGPORT_APP_SECRET_SECRET_NAME`
- 可选 Variables: `LONGBRIDGE_FEATURE_SNAPSHOT_PATH`、`LONGBRIDGE_FEATURE_SNAPSHOT_MANIFEST_PATH`、`LONGBRIDGE_STRATEGY_CONFIG_PATH`、`LONGBRIDGE_DRY_RUN_ONLY`、`INCOME_THRESHOLD_USD`、`QQQI_INCOME_RATIO`
- 当前线上示例:`STRATEGY_PROFILE=tqqq_growth_income`
- 当前线上示例:`STRATEGY_PROFILE=soxl_soxx_trend_income`
- 建议的 secret-name 值:`longport-app-key-sg`、`longport-app-secret-sg`

每次 push 到 `main` 时,这个 workflow 会分别更新两个 Cloud Run 服务,把共享和各自隔离的变量同步进去,并删除旧的 `TELEGRAM_CHAT_ID`。
Expand Down
2 changes: 0 additions & 2 deletions runtime_config_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@

from quant_platform_kit.common.strategies import derive_strategy_artifact_paths
from strategy_registry import (
DEFAULT_STRATEGY_PROFILE as PLATFORM_DEFAULT_STRATEGY_PROFILE,
LONGBRIDGE_PLATFORM,
resolve_strategy_definition,
resolve_strategy_metadata,
)
from us_equity_strategies import get_strategy_catalog

DEFAULT_ACCOUNT_REGION = "DEFAULT"
DEFAULT_STRATEGY_PROFILE = PLATFORM_DEFAULT_STRATEGY_PROFILE
DEFAULT_LONGPORT_SECRET_NAME = "longport_token_hk"


Expand Down
2 changes: 0 additions & 2 deletions scripts/print_strategy_profile_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ def _print_table(rows: list[dict[str, object]]) -> None:
"requires_strategy_config_path",
"eligible",
"enabled",
"is_default",
"is_rollback",
"domain",
)
widths = {
Expand Down
31 changes: 20 additions & 11 deletions strategy_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@

LONGBRIDGE_PLATFORM = "longbridge"

DEFAULT_STRATEGY_PROFILE = "soxl_soxx_trend_income"
ROLLBACK_STRATEGY_PROFILE = DEFAULT_STRATEGY_PROFILE

LONGBRIDGE_ROLLOUT_ALLOWLIST = get_runtime_enabled_profiles()

PLATFORM_SUPPORTED_DOMAINS: dict[str, frozenset[str]] = {
Expand Down Expand Up @@ -71,11 +68,17 @@
platform_id=LONGBRIDGE_PLATFORM,
supported_domains=PLATFORM_SUPPORTED_DOMAINS[LONGBRIDGE_PLATFORM],
enabled_profiles=LONGBRIDGE_ENABLED_PROFILES,
default_profile=DEFAULT_STRATEGY_PROFILE,
rollback_profile=ROLLBACK_STRATEGY_PROFILE,
default_profile="",
rollback_profile="",
require_explicit_profile=True,
)

SUPPORTED_STRATEGY_PROFILES = LONGBRIDGE_ENABLED_PROFILES
_SELECTION_ROLE_FIELDS = frozenset({"is_default", "is_rollback"})


def _without_selection_role_fields(row: dict[str, object]) -> dict[str, object]:
return {key: value for key, value in row.items() if key not in _SELECTION_ROLE_FIELDS}


def get_eligible_profiles_for_platform(platform_id: str) -> frozenset[str]:
Expand All @@ -89,15 +92,21 @@ def get_supported_profiles_for_platform(platform_id: str) -> frozenset[str]:


def get_platform_profile_matrix() -> list[dict[str, object]]:
return build_platform_profile_matrix(STRATEGY_CATALOG, policy=PLATFORM_POLICY)
return [
_without_selection_role_fields(row)
for row in build_platform_profile_matrix(STRATEGY_CATALOG, policy=PLATFORM_POLICY)
]


def get_platform_profile_status_matrix() -> list[dict[str, object]]:
return build_platform_profile_status_matrix(
STRATEGY_CATALOG,
policy=PLATFORM_POLICY,
eligible_profiles=ELIGIBLE_STRATEGY_PROFILES,
)
return [
_without_selection_role_fields(row)
for row in build_platform_profile_status_matrix(
STRATEGY_CATALOG,
policy=PLATFORM_POLICY,
eligible_profiles=ELIGIBLE_STRATEGY_PROFILES,
)
]


def resolve_strategy_definition(
Expand Down
Loading