diff --git a/tests/strategy_switch_worker_validation.mjs b/tests/strategy_switch_worker_validation.mjs index 79914ee..824a9fa 100644 --- a/tests/strategy_switch_worker_validation.mjs +++ b/tests/strategy_switch_worker_validation.mjs @@ -69,9 +69,9 @@ const accountOptions = __test.normalizeAccountOptionsPayload( "test_account_options", ); -assert.deepEqual(accountOptions.longbridge[0].supported_domains, ["hk_equity"]); -assert.deepEqual(accountOptions.longbridge[1].supported_domains, ["us_equity"]); -assert.deepEqual(accountOptions.ibkr[0].supported_domains, ["us_equity"]); +assert.deepEqual(accountOptions.longbridge[0].supported_domains, ["us_equity", "hk_equity"]); +assert.deepEqual(accountOptions.longbridge[1].supported_domains, ["us_equity", "hk_equity"]); +assert.deepEqual(accountOptions.ibkr[0].supported_domains, ["us_equity", "hk_equity"]); const longbridgeHk = __test.assertConfiguredAccount( { @@ -111,13 +111,38 @@ __test.assertStrategyAllowedForAccount( ibkrAccount, strategyProfiles, ); +__test.assertStrategyAllowedForAccount( + { + platform: "ibkr", + strategy_profile: "hk_low_vol_dividend_quality_snapshot", + }, + ibkrAccount, + strategyProfiles, +); + +const schwabAccount = __test.assertConfiguredAccount( + { + platform: "schwab", + target_name: "default", + strategy_profile: "tqqq_growth_income", + }, + accountOptions, +); +__test.assertStrategyAllowedForAccount( + { + platform: "schwab", + strategy_profile: "tqqq_growth_income", + }, + schwabAccount, + strategyProfiles, +); assert.throws( () => __test.assertStrategyAllowedForAccount( { - platform: "ibkr", + platform: "schwab", strategy_profile: "hk_low_vol_dividend_quality_snapshot", }, - ibkrAccount, + schwabAccount, strategyProfiles, ), /not supported/, diff --git a/web/strategy-switch-console/README.md b/web/strategy-switch-console/README.md index cfea933..8c152cb 100644 --- a/web/strategy-switch-console/README.md +++ b/web/strategy-switch-console/README.md @@ -104,7 +104,7 @@ Each account item supports: "account_scope": "live-u1599-tqqq", "service_name": "interactive-brokers-live-u1599-tqqq-service", "default_strategy_profile": "tqqq_growth_income", - "supported_domains": ["us_equity"] + "supported_domains": ["us_equity", "hk_equity"] } ``` @@ -124,6 +124,7 @@ When adding or renaming a strategy profile: - Run `python3 scripts/sync_strategy_switch_page_asset.py` so `strategy_profiles_asset.js` is regenerated. - Set `domain` on each strategy profile. Current values are `us_equity` and `hk_equity`. - Set each affected account's `default_strategy_profile` and `supported_domains` in `account-options.example.json` and the deployed KV account config. +- Use `["us_equity", "hk_equity"]` for LongBridge and IBKR accounts unless you intentionally want to narrow a specific account. - Update the deployed KV `strategy_profiles` key from `strategy-profiles.example.json`. - Make sure the platform repository's current `RUNTIME_TARGET_JSON.strategy_profile` or account-specific `CLOUD_RUN_SERVICE_TARGETS_JSON` uses the same id. - Use lower-case ids with letters, numbers, dot, underscore, dash, or equals only. Do not encode account names or secrets in profile ids. diff --git a/web/strategy-switch-console/README.zh-CN.md b/web/strategy-switch-console/README.zh-CN.md index 784db01..dc27575 100644 --- a/web/strategy-switch-console/README.zh-CN.md +++ b/web/strategy-switch-console/README.zh-CN.md @@ -111,7 +111,7 @@ wrangler secret put STRATEGY_SWITCH_ACCOUNT_OPTIONS_JSON < /tmp/strategy-switch- "account_scope": "live-u1599-tqqq", "service_name": "interactive-brokers-live-u1599-tqqq-service", "default_strategy_profile": "tqqq_growth_income", - "supported_domains": ["us_equity"] + "supported_domains": ["us_equity", "hk_equity"] } ``` @@ -131,6 +131,7 @@ Worker 会校验 dispatch 参数必须匹配这里的某个账号项,也会校 - 运行 `python3 scripts/sync_strategy_switch_page_asset.py` 重新生成 `strategy_profiles_asset.js`。 - 给每个策略 profile 设置 `domain`。当前支持 `us_equity` 和 `hk_equity`。 - 在 `account-options.example.json` 和已部署的 KV 账号配置里更新对应账号的 `default_strategy_profile` 和 `supported_domains`。 +- LongBridge 和 IBKR 账号默认写 `["us_equity", "hk_equity"]`,除非你明确要把某个账号限制成单市场。 - 用 `strategy-profiles.example.json` 更新已部署 KV 的 `strategy_profiles` key。 - 确认平台仓库当前的 `RUNTIME_TARGET_JSON.strategy_profile` 或账号级 `CLOUD_RUN_SERVICE_TARGETS_JSON` 使用同一个 id。 - profile id 只使用小写字母、数字、点、下划线、短横线或等号。不要把账号名、密码、token、密钥信息写进 profile id。 diff --git a/web/strategy-switch-console/account-options.example.json b/web/strategy-switch-console/account-options.example.json index 629006e..4ff027b 100644 --- a/web/strategy-switch-console/account-options.example.json +++ b/web/strategy-switch-console/account-options.example.json @@ -6,7 +6,7 @@ "target_name": "hk", "account_selector": "HK", "default_strategy_profile": "hk_low_vol_dividend_quality_snapshot", - "supported_domains": ["hk_equity"] + "supported_domains": ["us_equity", "hk_equity"] }, { "key": "sg", @@ -14,7 +14,7 @@ "target_name": "sg", "account_selector": "SG", "default_strategy_profile": "tqqq_growth_income", - "supported_domains": ["us_equity"] + "supported_domains": ["us_equity", "hk_equity"] }, { "key": "paper", @@ -22,7 +22,7 @@ "target_name": "paper", "account_selector": "PAPER", "default_strategy_profile": "mega_cap_leader_rotation_top50_balanced", - "supported_domains": ["us_equity"] + "supported_domains": ["us_equity", "hk_equity"] } ], "ibkr": [ @@ -35,7 +35,7 @@ "account_scope": "live-u1599-tqqq", "service_name": "interactive-brokers-live-u1599-tqqq-service", "default_strategy_profile": "tqqq_growth_income", - "supported_domains": ["us_equity"] + "supported_domains": ["us_equity", "hk_equity"] }, { "key": "u16608560", @@ -46,7 +46,7 @@ "account_scope": "live-u1660-soxl", "service_name": "interactive-brokers-live-u1660-soxl-service", "default_strategy_profile": "soxl_soxx_trend_income", - "supported_domains": ["us_equity"] + "supported_domains": ["us_equity", "hk_equity"] }, { "key": "u18336562", @@ -57,7 +57,7 @@ "account_scope": "live-u1833-smart-dca", "service_name": "interactive-brokers-live-u1833-smart-dca-service", "default_strategy_profile": "nasdaq_sp500_smart_dca", - "supported_domains": ["us_equity"] + "supported_domains": ["us_equity", "hk_equity"] } ], "schwab": [ diff --git a/web/strategy-switch-console/index.html b/web/strategy-switch-console/index.html index 671ffa8..8f1eeec 100644 --- a/web/strategy-switch-console/index.html +++ b/web/strategy-switch-console/index.html @@ -628,9 +628,9 @@

切换摘要

const defaultAccountOptions = { longbridge: [ - { key: "hk", label: "hk", target_name: "hk", account_selector: "HK", default_strategy_profile: "hk_low_vol_dividend_quality_snapshot", supported_domains: ["hk_equity"] }, - { key: "sg", label: "sg", target_name: "sg", account_selector: "SG", default_strategy_profile: "tqqq_growth_income", supported_domains: ["us_equity"] }, - { key: "paper", label: "paper", target_name: "paper", account_selector: "PAPER", default_strategy_profile: "mega_cap_leader_rotation_top50_balanced", supported_domains: ["us_equity"] }, + { key: "hk", label: "hk", target_name: "hk", account_selector: "HK", default_strategy_profile: "hk_low_vol_dividend_quality_snapshot", supported_domains: ["us_equity", "hk_equity"] }, + { key: "sg", label: "sg", target_name: "sg", account_selector: "SG", default_strategy_profile: "tqqq_growth_income", supported_domains: ["us_equity", "hk_equity"] }, + { key: "paper", label: "paper", target_name: "paper", account_selector: "PAPER", default_strategy_profile: "mega_cap_leader_rotation_top50_balanced", supported_domains: ["us_equity", "hk_equity"] }, ], ibkr: [ { @@ -642,7 +642,7 @@

切换摘要

account_scope: "live-u1599-tqqq", service_name: "interactive-brokers-live-u1599-tqqq-service", default_strategy_profile: "tqqq_growth_income", - supported_domains: ["us_equity"], + supported_domains: ["us_equity", "hk_equity"], }, { key: "u16608560", @@ -653,7 +653,7 @@

切换摘要

account_scope: "live-u1660-soxl", service_name: "interactive-brokers-live-u1660-soxl-service", default_strategy_profile: "soxl_soxx_trend_income", - supported_domains: ["us_equity"], + supported_domains: ["us_equity", "hk_equity"], }, { key: "u18336562", @@ -664,7 +664,7 @@

切换摘要

account_scope: "live-u1833-smart-dca", service_name: "interactive-brokers-live-u1833-smart-dca-service", default_strategy_profile: "nasdaq_sp500_smart_dca", - supported_domains: ["us_equity"], + supported_domains: ["us_equity", "hk_equity"], }, ], schwab: [ @@ -852,20 +852,8 @@

切换摘要

} function inferSupportedDomains(platform, account) { - const tokens = [ - account?.key, - account?.label, - account?.target_name, - account?.account_selector, - account?.account_scope, - account?.deployment_selector, - account?.service_name, - ] - .join(" ") - .toLowerCase() - .split(/[^a-z0-9]+/) - .filter(Boolean); - if (platform === "longbridge" && tokens.includes("hk")) return ["hk_equity"]; + void account; + if (platform === "longbridge" || platform === "ibkr") return ["us_equity", "hk_equity"]; return ["us_equity"]; } diff --git a/web/strategy-switch-console/page_asset.js b/web/strategy-switch-console/page_asset.js index b5370b3..14839c9 100644 --- a/web/strategy-switch-console/page_asset.js +++ b/web/strategy-switch-console/page_asset.js @@ -1,2 +1,2 @@ // Generated by scripts/sync_strategy_switch_page_asset.py; do not edit by hand. -export const PAGE_HTML = "\n\n\n \n \n \n QuantRuntimeSettings Strategy Switch\n \n\n\n
\n
\n

策略切换

\n

选平台、目标账号和策略,一次执行完成切换。

\n
\n
\n \n \n \n
\n
\n\n
\n \n\n
\n
\n
\n 当前平台\n

LongBridge

\n
\n\n
\n \n\n \n\n
\n 模式\n
\n \n \n
\n
\n
\n\n
\n \n

登录后才可执行切换。

\n

\n
\n
\n\n \n
\n
\n\n \n\n\n"; +export const PAGE_HTML = "\n\n\n \n \n \n QuantRuntimeSettings Strategy Switch\n \n\n\n
\n
\n

策略切换

\n

选平台、目标账号和策略,一次执行完成切换。

\n
\n
\n \n \n \n
\n
\n\n
\n \n\n
\n
\n
\n 当前平台\n

LongBridge

\n
\n\n
\n \n\n \n\n
\n 模式\n
\n \n \n
\n
\n
\n\n
\n \n

登录后才可执行切换。

\n

\n
\n
\n\n \n
\n
\n\n \n\n\n"; diff --git a/web/strategy-switch-console/worker.js b/web/strategy-switch-console/worker.js index c380444..000f54f 100644 --- a/web/strategy-switch-console/worker.js +++ b/web/strategy-switch-console/worker.js @@ -785,20 +785,8 @@ function supportedDomainsForAccount(platform, option) { } function inferAccountSupportedDomains(platform, option) { - const tokens = [ - option?.key, - option?.label, - option?.target_name, - option?.account_selector, - option?.account_scope, - option?.deployment_selector, - option?.service_name, - ] - .join(" ") - .toLowerCase() - .split(/[^a-z0-9]+/) - .filter(Boolean); - if (platform === "longbridge" && tokens.includes("hk")) return ["hk_equity"]; + void option; + if (platform === "longbridge" || platform === "ibkr") return ["us_equity", "hk_equity"]; return ["us_equity"]; }