Skip to content

Commit 3dae275

Browse files
authored
Adopt IBKR runtime target JSON wiring (#52)
* Pin dynamic RSI strategy dependencies * Adopt runtime target assembly * Fix runtime target env sync wiring * Fix runtime target import wiring * Fix Cloud Run env sync JSON encoding * Require IBKR runtime target JSON * Pin UsEquityStrategies runtime target dependency * Update IBKR tests for runtime target JSON
1 parent 8cdcb3c commit 3dae275

20 files changed

Lines changed: 428 additions & 357 deletions

.github/workflows/sync-cloud-run-env.yml

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@ jobs:
2121
CLOUD_RUN_REGION: ${{ vars.CLOUD_RUN_REGION }}
2222
CLOUD_RUN_SERVICE: ${{ vars.CLOUD_RUN_SERVICE }}
2323
TELEGRAM_TOKEN_SECRET_NAME: ${{ vars.TELEGRAM_TOKEN_SECRET_NAME }}
24-
STRATEGY_PROFILE: ${{ vars.STRATEGY_PROFILE }}
24+
RUNTIME_TARGET_JSON: ${{ vars.RUNTIME_TARGET_JSON }}
2525
ACCOUNT_GROUP: ${{ vars.ACCOUNT_GROUP }}
2626
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME: ${{ vars.IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME }}
2727
IBKR_FEATURE_SNAPSHOT_PATH: ${{ vars.IBKR_FEATURE_SNAPSHOT_PATH }}
2828
IBKR_FEATURE_SNAPSHOT_MANIFEST_PATH: ${{ vars.IBKR_FEATURE_SNAPSHOT_MANIFEST_PATH }}
2929
IBKR_STRATEGY_CONFIG_PATH: ${{ vars.IBKR_STRATEGY_CONFIG_PATH }}
3030
IBKR_RECONCILIATION_OUTPUT_PATH: ${{ vars.IBKR_RECONCILIATION_OUTPUT_PATH }}
3131
IBKR_DRY_RUN_ONLY: ${{ vars.IBKR_DRY_RUN_ONLY }}
32+
# Strategy-owned defaults continue to come from UsEquityStrategies; this workflow only syncs platform/runtime inputs.
3233
EXECUTION_REPORT_GCS_URI: ${{ vars.EXECUTION_REPORT_GCS_URI }}
3334
IB_GATEWAY_ZONE: ${{ vars.IB_GATEWAY_ZONE }}
3435
IB_GATEWAY_IP_MODE: ${{ vars.IB_GATEWAY_IP_MODE }}
@@ -78,9 +79,13 @@ jobs:
7879
import sys
7980
from us_equity_strategies import resolve_canonical_profile
8081
81-
profile = os.environ.get("STRATEGY_PROFILE", "").strip().lower()
82+
raw_runtime_target = os.environ.get("RUNTIME_TARGET_JSON", "").strip()
83+
if not raw_runtime_target:
84+
raise SystemExit("RUNTIME_TARGET_JSON is required")
85+
runtime_target = json.loads(raw_runtime_target)
86+
profile = str(runtime_target.get("strategy_profile") or "").strip().lower()
8287
if not profile:
83-
raise SystemExit("STRATEGY_PROFILE is required")
88+
raise SystemExit("RUNTIME_TARGET_JSON.strategy_profile is required")
8489
canonical_profile = resolve_canonical_profile(profile)
8590
8691
raw_status = subprocess.check_output(
@@ -112,6 +117,7 @@ jobs:
112117
output.write(
113118
f"reconciliation_output_policy={str(selected.get('reconciliation_output_policy') or 'none')}\n"
114119
)
120+
output.write(f"runtime_target_json={json.dumps(runtime_target, sort_keys=True)}\n")
115121
PY
116122
117123
- name: Validate env sync inputs
@@ -122,13 +128,13 @@ jobs:
122128
REQUIRES_STRATEGY_CONFIG_PATH: ${{ steps.strategy_requirements.outputs.requires_strategy_config_path }}
123129
CONFIG_SOURCE_POLICY: ${{ steps.strategy_requirements.outputs.config_source_policy }}
124130
RECONCILIATION_OUTPUT_POLICY: ${{ steps.strategy_requirements.outputs.reconciliation_output_policy }}
131+
RUNTIME_TARGET_JSON: ${{ steps.strategy_requirements.outputs.runtime_target_json }}
125132
run: |
126133
set -euo pipefail
127134
128135
required_vars=(
129136
CLOUD_RUN_REGION
130137
CLOUD_RUN_SERVICE
131-
STRATEGY_PROFILE
132138
ACCOUNT_GROUP
133139
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME
134140
GLOBAL_TELEGRAM_CHAT_ID
@@ -151,6 +157,10 @@ jobs:
151157
required_vars+=(IBKR_RECONCILIATION_OUTPUT_PATH)
152158
fi
153159
160+
if [ -z "${RUNTIME_TARGET_JSON:-}" ]; then
161+
required_vars+=(RUNTIME_TARGET_JSON)
162+
fi
163+
154164
missing_vars=()
155165
for var_name in "${required_vars[@]}"; do
156166
if [ -z "${!var_name:-}" ]; then
@@ -209,15 +219,32 @@ jobs:
209219
210220
- name: Sync Cloud Run environment
211221
if: steps.config.outputs.enabled == 'true'
222+
env:
223+
RUNTIME_TARGET_JSON: ${{ steps.strategy_requirements.outputs.runtime_target_json }}
212224
run: |
213225
set -euo pipefail
214226
227+
join_by_delimiter() {
228+
local delimiter="$1"
229+
shift
230+
local output=""
231+
local item
232+
for item in "$@"; do
233+
if [ -z "${output}" ]; then
234+
output="${item}"
235+
else
236+
output="${output}${delimiter}${item}"
237+
fi
238+
done
239+
printf '%s' "${output}"
240+
}
241+
215242
env_pairs=(
216243
"GLOBAL_TELEGRAM_CHAT_ID=${GLOBAL_TELEGRAM_CHAT_ID}"
217244
"NOTIFY_LANG=${NOTIFY_LANG}"
218-
"STRATEGY_PROFILE=${STRATEGY_PROFILE}"
219245
"ACCOUNT_GROUP=${ACCOUNT_GROUP}"
220246
"IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=${IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME}"
247+
"RUNTIME_TARGET_JSON=${RUNTIME_TARGET_JSON}"
221248
)
222249
secret_pairs=()
223250
@@ -292,7 +319,7 @@ jobs:
292319
--concurrency 1
293320
--max-instances 1
294321
--remove-env-vars "$(IFS=,; echo "${remove_env_vars[*]}")"
295-
--update-env-vars "$(IFS=,; echo "${env_pairs[*]}")"
322+
--update-env-vars "^|^$(join_by_delimiter "|" "${env_pairs[@]}")"
296323
)
297324
298325
if [ "${#remove_secret_vars[@]}" -gt 0 ]; then

README.md

Lines changed: 24 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,10 @@
1212
<a id="english"></a>
1313
## English
1414

15-
IBKR runtime for shared `us_equity` strategy profiles from `UsEquityStrategies`. It supports the `us_equity` profiles listed in the IBKR profile status table below. Strategy logic, cadence, asset universes, parameters, and research/backtest notes live in `UsEquityStrategies`.
15+
IBKR runtime for shared `us_equity` strategy profiles from `UsEquityStrategies`. Strategy logic, cadence, asset universes, parameters, and research/backtest notes live there.
16+
The runtime carries a structured `RuntimeTarget` / `RUNTIME_TARGET_JSON` for the running service identity. Strategy-owned defaults come from `UsEquityStrategies`; platform variables are only explicit overrides.
1617

17-
Current strategy implementations are sourced from `UsEquityStrategies`.
18-
19-
Full strategy documentation now lives in [`UsEquityStrategies`](https://github.com/QuantStrategyLab/UsEquityStrategies). This README focuses on IBKR runtime behavior, profile enablement, deployment, and credentials.
20-
This runtime matrix is the authoritative enablement source for IBKR. `UsEquityStrategies` carries strategy-layer logic, cadence, compatibility, and metadata.
18+
Full strategy documentation now lives in [`UsEquityStrategies`](https://github.com/QuantStrategyLab/UsEquityStrategies). This README focuses on IBKR runtime behavior, profile enablement, deployment, and credentials, and this profile matrix remains the authoritative IBKR enablement source.
2119

2220
### Execution boundary
2321

@@ -91,6 +89,7 @@ Telegram alerts support English/Chinese execution and heartbeat messages. Strate
9189
### Runtime env vars
9290

9391
The selected `ACCOUNT_GROUP` is now the runtime identity. Keep broker-specific identity in the account-group config payload, not in Cloud Run env vars.
92+
For IBKR, keep `paper` as a single account-group entry. If you later add live accounts, split them into separate live groups; do not mix paper and live in one account-group entry.
9493

9594
| Variable | Required | Description |
9695
|----------|----------|-------------|
@@ -131,7 +130,7 @@ For the current first rollout, keep GitHub / Cloud Run focused on service-level
131130

132131
```bash
133132
STRATEGY_PROFILE=global_etf_rotation
134-
ACCOUNT_GROUP=default
133+
ACCOUNT_GROUP=paper
135134
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups
136135
GLOBAL_TELEGRAM_CHAT_ID=<telegram-chat-id>
137136
NOTIFY_LANG=zh
@@ -145,7 +144,7 @@ For the snapshot-based stock profiles:
145144

146145
```bash
147146
STRATEGY_PROFILE=russell_1000_multi_factor_defensive
148-
ACCOUNT_GROUP=default
147+
ACCOUNT_GROUP=paper
149148
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups
150149
IBKR_FEATURE_SNAPSHOT_PATH=/var/data/r1000_feature_snapshot.csv
151150
GLOBAL_TELEGRAM_CHAT_ID=<telegram-chat-id>
@@ -154,7 +153,7 @@ NOTIFY_LANG=zh
154153

155154
```bash
156155
STRATEGY_PROFILE=tech_communication_pullback_enhancement
157-
ACCOUNT_GROUP=default
156+
ACCOUNT_GROUP=paper
158157
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups
159158
IBKR_FEATURE_SNAPSHOT_PATH=/var/data/tech_communication_pullback_enhancement_feature_snapshot_latest.csv
160159
IBKR_FEATURE_SNAPSHOT_MANIFEST_PATH=/var/manifests/tech_communication_pullback_enhancement_feature_snapshot_latest.csv.manifest.json
@@ -169,7 +168,7 @@ NOTIFY_LANG=zh
169168

170169
```bash
171170
STRATEGY_PROFILE=mega_cap_leader_rotation_top50_balanced
172-
ACCOUNT_GROUP=default
171+
ACCOUNT_GROUP=paper
173172
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups
174173
IBKR_FEATURE_SNAPSHOT_PATH=/var/data/mega_cap_leader_rotation_top50_balanced_feature_snapshot_latest.csv
175174
IBKR_FEATURE_SNAPSHOT_MANIFEST_PATH=/var/manifests/mega_cap_leader_rotation_top50_balanced_feature_snapshot_latest.csv.manifest.json
@@ -184,29 +183,22 @@ Recommended account-group config payload:
184183
```json
185184
{
186185
"groups": {
187-
"default": {
186+
"paper": {
188187
"ib_gateway_instance_name": "interactive-brokers-quant-instance",
189188
"ib_gateway_zone": "us-central1-c",
190189
"ib_gateway_mode": "paper",
191190
"ib_gateway_ip_mode": "internal",
192191
"ib_client_id": 1,
193192
"service_name": "interactive-brokers-quant-service",
194193
"account_ids": ["DU1234567"]
195-
},
196-
"ira": {
197-
"ib_gateway_instance_name": "interactive-brokers-quant-instance",
198-
"ib_gateway_zone": "us-central1-c",
199-
"ib_gateway_mode": "paper",
200-
"ib_gateway_ip_mode": "internal",
201-
"ib_client_id": 7,
202-
"service_name": "interactive-brokers-quant-ira-service",
203-
"account_ids": ["U1234567"]
204194
}
205195
}
206196
}
207197
```
208198

209-
See [`docs/examples/ibkr-account-groups.default.json`](docs/examples/ibkr-account-groups.default.json) for a ready-to-edit starter example, and [`docs/ibkr_runtime_rollout.md`](docs/ibkr_runtime_rollout.md) for the exact rollout steps to get `ACCOUNT_GROUP=default` running.
199+
If you later add live, keep it as a separate live group such as `live-main` with `ib_gateway_mode=live` and its own `account_ids`.
200+
201+
See [`docs/examples/ibkr-account-groups.paper.json`](docs/examples/ibkr-account-groups.paper.json) for a ready-to-edit starter example, and [`docs/ibkr_runtime_rollout.md`](docs/ibkr_runtime_rollout.md) for the exact rollout steps to get `ACCOUNT_GROUP=paper` running.
210202

211203
Current behavior is fail-fast:
212204

@@ -217,7 +209,7 @@ Current behavior is fail-fast:
217209

218210
### GitHub-managed Cloud Run env sync
219211

220-
If code deployment still uses Google Cloud Trigger, but you want GitHub to be the single source of truth for runtime env vars, this repo now includes `.github/workflows/sync-cloud-run-env.yml`.
212+
If code deployment still uses Google Cloud Trigger, but you want GitHub to be the single source of truth for runtime env vars, this repo now includes `.github/workflows/sync-cloud-run-env.yml`. The workflow now also emits `RUNTIME_TARGET_JSON`, so the control plane carries a structured runtime target alongside the legacy `STRATEGY_PROFILE` selector.
221213

222214
Recommended setup:
223215

@@ -227,7 +219,7 @@ Recommended setup:
227219
- `CLOUD_RUN_SERVICE`
228220
- `TELEGRAM_TOKEN_SECRET_NAME` (recommended when Cloud Run already uses Secret Manager for `TELEGRAM_TOKEN`)
229221
- `STRATEGY_PROFILE` (set explicitly to one enabled profile, such as `soxl_soxx_trend_income`)
230-
- `ACCOUNT_GROUP` (recommended: `default`)
222+
- `ACCOUNT_GROUP` (recommended: `paper`)
231223
- `IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME`
232224
- `GLOBAL_TELEGRAM_CHAT_ID`
233225
- `NOTIFY_LANG`
@@ -239,7 +231,7 @@ Recommended setup:
239231

240232
On every push to `main`, the workflow updates the existing Cloud Run service with the values above and removes legacy env vars that should now live in the account-group config (`IB_CLIENT_ID`, `IB_GATEWAY_INSTANCE_NAME`, `IB_GATEWAY_MODE`) plus the older transport vars (`IB_GATEWAY_HOST`, `IB_GATEWAY_PORT`, `TELEGRAM_CHAT_ID`). If `IB_GATEWAY_ZONE` or `IB_GATEWAY_IP_MODE` are blank in GitHub, the workflow also removes them from Cloud Run to avoid drift.
241233

242-
`STRATEGY_PROFILE` is now resolved from a platform capability matrix plus a rollout allowlist derived from `runtime_enabled` strategy metadata. The current strategy domain is `us_equity`, and the repo keeps the runtime registry thin: `eligible` means the platform can run the strategy in theory, while `enabled` means the current rollout really allows it. `ACCOUNT_GROUP` now selects one account-group config entry, and the service fails fast if that runtime identity is incomplete.
234+
`STRATEGY_PROFILE` is resolved from a platform capability matrix plus a rollout allowlist derived from `runtime_enabled` strategy metadata. The current strategy domain is `us_equity`: `eligible` means the platform can run the strategy in theory, while `enabled` means the current rollout really allows it. `ACCOUNT_GROUP` selects one account-group config entry, and the service fails fast if that runtime identity is incomplete. `RUNTIME_TARGET_JSON` carries the structured runtime identity; strategy defaults continue to come from `UsEquityStrategies`.
243235

244236
Important:
245237

@@ -261,7 +253,7 @@ Important:
261253

262254
1. **GCE**: Set up IB Gateway (paper or live) on a GCE instance. Ensure API access is enabled, remote clients are allowed when needed, and use `4001` for `live` or `4002` for `paper`.
263255
2. **VPC / Subnet**: Put Cloud Run and GCE in the same VPC. For cleaner firewall rules, reserve a dedicated subnet for Cloud Run Direct VPC egress.
264-
3. **Cloud Run**: Deploy or update this Flask app with Direct VPC egress. Set `STRATEGY_PROFILE`, `ACCOUNT_GROUP`, and `IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME`. Keep `IB_GATEWAY_ZONE` / `IB_GATEWAY_IP_MODE` only as transition fallbacks if the selected account-group payload does not already contain them. The runtime service account needs `roles/secretmanager.secretAccessor` and, for instance-name resolution, `roles/compute.viewer`.
256+
3. **Cloud Run**: Deploy or update this Flask app with Direct VPC egress. Set `STRATEGY_PROFILE`, `ACCOUNT_GROUP`, and `IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME`. Keep `IB_GATEWAY_ZONE` / `IB_GATEWAY_IP_MODE` only as transition fallbacks if the selected account-group payload does not already contain them. The workflow emits `RUNTIME_TARGET_JSON` to describe the structured deployment target. The runtime service account needs `roles/secretmanager.secretAccessor` and, for instance-name resolution, `roles/compute.viewer`.
265257
- For Cloud Run source deploy, also grant `roles/storage.objectViewer` on `gs://run-sources-${PROJECT_ID}-${REGION}` to the build service account, the deploy service account, and `${PROJECT_NUMBER}-compute@developer.gserviceaccount.com`.
266258
4. **Firewall**: Allow TCP `4001` (`live`) or `4002` (`paper`) from the Cloud Run egress subnet CIDR to the GCE instance.
267259
5. **Cloud Scheduler**: Create a job that POSTs to the Cloud Run URL. Choose the cron from the strategy-layer cadence in `UsEquityStrategies`; daily profiles can still use a near-close weekday schedule such as `45 15 * * 1-5` in `America/New_York`.
@@ -279,7 +271,7 @@ gcloud run deploy interactive-brokers-quant-service \
279271
--network default \
280272
--subnet cloudrun-direct-egress \
281273
--vpc-egress private-ranges-only \
282-
--set-env-vars STRATEGY_PROFILE=global_etf_rotation,ACCOUNT_GROUP=default,IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups,GLOBAL_TELEGRAM_CHAT_ID=123456789,NOTIFY_LANG=zh
274+
--set-env-vars STRATEGY_PROFILE=global_etf_rotation,ACCOUNT_GROUP=paper,IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups,GLOBAL_TELEGRAM_CHAT_ID=123456789,NOTIFY_LANG=zh
283275
```
284276

285277
If the service already exists and your CI only updates source/image, you can patch networking separately:
@@ -302,9 +294,7 @@ gcloud run services update ibkr-quant \
302294

303295
IBKR runtime 负责把共享的 `us_equity` 策略档位部署到 GCP Cloud Run,并连接 GCE 上的 IB Gateway 执行。策略逻辑、策略频率、标的池、参数和研究/回测说明都放在 `UsEquityStrategies`;这个仓库只维护 IBKR 运行时、账号组、Gateway 连接、下单和通知。
304296

305-
当前可运行的 `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` 的策略实现都来自 `UsEquityStrategies`
306-
307-
完整策略说明现在放在 [`UsEquityStrategies`](https://github.com/QuantStrategyLab/UsEquityStrategies)。这个 README 只保留 IBKR 运行时、profile 启用状态、部署和凭据说明。
297+
完整策略说明放在 [`UsEquityStrategies`](https://github.com/QuantStrategyLab/UsEquityStrategies)。这个 README 只保留 IBKR 运行时、profile 启用状态、部署和凭据说明。
308298

309299
### 执行边界
310300

@@ -378,7 +368,7 @@ IBKR 账户
378368

379369
```bash
380370
STRATEGY_PROFILE=soxl_soxx_trend_income
381-
ACCOUNT_GROUP=default
371+
ACCOUNT_GROUP=paper
382372
IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups
383373
GLOBAL_TELEGRAM_CHAT_ID=<telegram-chat-id>
384374
NOTIFY_LANG=zh
@@ -395,29 +385,20 @@ IB_GATEWAY_IP_MODE=internal
395385
```json
396386
{
397387
"groups": {
398-
"default": {
388+
"paper": {
399389
"ib_gateway_instance_name": "interactive-brokers-quant-instance",
400390
"ib_gateway_zone": "us-central1-c",
401391
"ib_gateway_mode": "paper",
402392
"ib_gateway_ip_mode": "internal",
403393
"ib_client_id": 1,
404394
"service_name": "interactive-brokers-quant-service",
405395
"account_ids": ["DU1234567"]
406-
},
407-
"ira": {
408-
"ib_gateway_instance_name": "interactive-brokers-quant-instance",
409-
"ib_gateway_zone": "us-central1-c",
410-
"ib_gateway_mode": "paper",
411-
"ib_gateway_ip_mode": "internal",
412-
"ib_client_id": 7,
413-
"service_name": "interactive-brokers-quant-ira-service",
414-
"account_ids": ["U1234567"]
415396
}
416397
}
417398
}
418399
```
419400

420-
仓库里也提供了一个可以直接改的默认样例[`docs/examples/ibkr-account-groups.default.json`](docs/examples/ibkr-account-groups.default.json)。如果你要按 `ACCOUNT_GROUP=default` 先落地,直接看 [`docs/ibkr_runtime_rollout.md`](docs/ibkr_runtime_rollout.md)
401+
仓库里也提供了一个可以直接改的起始样例[`docs/examples/ibkr-account-groups.paper.json`](docs/examples/ibkr-account-groups.paper.json)。如果你要按 `ACCOUNT_GROUP=paper` 先落地,直接看 [`docs/ibkr_runtime_rollout.md`](docs/ibkr_runtime_rollout.md)
421402

422403
当前行为改成了 fail-fast:
423404

@@ -438,7 +419,7 @@ IB_GATEWAY_IP_MODE=internal
438419
- `CLOUD_RUN_SERVICE`
439420
- `TELEGRAM_TOKEN_SECRET_NAME`(如果 Cloud Run 上的 `TELEGRAM_TOKEN` 已经改成 Secret Manager,建议配置)
440421
- `STRATEGY_PROFILE`(显式设置为任一已启用 profile,例如 `soxl_soxx_trend_income`
441-
- `ACCOUNT_GROUP`(建议设为 `default`
422+
- `ACCOUNT_GROUP`(建议设为 `paper`
442423
- `IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME`
443424
- `GLOBAL_TELEGRAM_CHAT_ID`
444425
- `NOTIFY_LANG`
@@ -450,7 +431,7 @@ IB_GATEWAY_IP_MODE=internal
450431

451432
每次 push 到 `main` 时,这个 workflow 会把上面这些值同步到现有 Cloud Run 服务里,并清掉已经转移到账号组配置里的旧 env(`IB_CLIENT_ID``IB_GATEWAY_INSTANCE_NAME``IB_GATEWAY_MODE`)以及更早的传输层 env(`IB_GATEWAY_HOST``IB_GATEWAY_PORT``TELEGRAM_CHAT_ID`)。如果 GitHub 里没有配置 `IB_GATEWAY_ZONE``IB_GATEWAY_IP_MODE`,workflow 也会把 Cloud Run 上这两个旧值一起删除,避免双配置源漂移。
452433

453-
`STRATEGY_PROFILE` 现在由平台能力矩阵和从 `runtime_enabled` 策略元数据派生的 rollout allowlist 一起决定。当前策略域仍是 `us_equity``eligible` 表示平台理论上能跑,`enabled` 表示当前 rollout 真正放开。`ACCOUNT_GROUP` 是严格必填项,并会选中一份账号组配置。运行身份不完整时,服务会直接失败,不再静默回退。
434+
`STRATEGY_PROFILE` 由平台能力矩阵和从 `runtime_enabled` 策略元数据派生的 rollout allowlist 一起决定。当前策略域仍是 `us_equity``eligible` 表示平台理论上能跑,`enabled` 表示当前 rollout 真正放开。`ACCOUNT_GROUP` 是严格必填项,并会选中一份账号组配置。运行身份不完整时,服务会直接失败,不再静默回退。
454435

455436
注意:
456437

@@ -490,7 +471,7 @@ gcloud run deploy interactive-brokers-quant-service \
490471
--network default \
491472
--subnet cloudrun-direct-egress \
492473
--vpc-egress private-ranges-only \
493-
--set-env-vars STRATEGY_PROFILE=global_etf_rotation,ACCOUNT_GROUP=default,IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups,GLOBAL_TELEGRAM_CHAT_ID=123456789,NOTIFY_LANG=zh
474+
--set-env-vars STRATEGY_PROFILE=global_etf_rotation,ACCOUNT_GROUP=paper,IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME=ibkr-account-groups,GLOBAL_TELEGRAM_CHAT_ID=123456789,NOTIFY_LANG=zh
494475
```
495476

496477
如果服务已经存在,而你们的 CI 只是更新代码/镜像,可以单独补一次网络配置:

0 commit comments

Comments
 (0)