Skip to content

Commit 2b4da94

Browse files
committed
Require explicit strategy profile selection
1 parent 5e9581a commit 2b4da94

5 files changed

Lines changed: 54 additions & 49 deletions

File tree

README.md

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,23 @@ The mainline runtime now follows one path only:
3939
- `tqqq_growth_income`
4040
- `soxl_soxx_trend_income`
4141
- `tech_communication_pullback_enhancement`
42+
- `mega_cap_leader_rotation_aggressive`
4243
- `mega_cap_leader_rotation_dynamic_top20`
4344
- `dynamic_mega_leveraged_pullback`
4445

4546

4647
**IBKR profile status**
4748

48-
| Canonical profile | Display name | Eligible | Enabled | Default | Rollback | Domain | Runtime note |
49-
| --- | --- | --- | --- | --- | --- | --- | --- |
50-
| `global_etf_rotation` | Global ETF Rotation | Yes | Yes | Yes | Yes | `us_equity` | current rollback line |
51-
| `russell_1000_multi_factor_defensive` | Russell 1000 Multi-Factor | Yes | Yes | No | No | `us_equity` | defensive stock baseline |
52-
| `tqqq_growth_income` | TQQQ Growth Income | Yes | Yes | No | No | `us_equity` | enabled value-mode alternative |
53-
| `soxl_soxx_trend_income` | SOXL/SOXX Semiconductor Trend Income | Yes | Yes | No | No | `us_equity` | current IBKR live line |
54-
| `tech_communication_pullback_enhancement` | Tech/Communication Pullback Enhancement | Yes | Yes | No | No | `us_equity` | enabled feature-snapshot alternative |
55-
| `mega_cap_leader_rotation_dynamic_top20` | Mega Cap Leader Rotation Dynamic Top20 | Yes | Yes | No | No | `us_equity` | enabled concentrated leader rotation |
56-
| `dynamic_mega_leveraged_pullback` | Dynamic Mega Leveraged Pullback | Yes | Yes | No | No | `us_equity` | enabled 2x mega-cap pullback line |
49+
| Canonical profile | Display name | Eligible | Enabled | Domain | Runtime note |
50+
| --- | --- | --- | --- | --- | --- |
51+
| `global_etf_rotation` | Global ETF Rotation | Yes | Yes | `us_equity` | enabled weight-mode rotation line |
52+
| `russell_1000_multi_factor_defensive` | Russell 1000 Multi-Factor | Yes | Yes | `us_equity` | defensive stock baseline |
53+
| `tqqq_growth_income` | TQQQ Growth Income | Yes | Yes | `us_equity` | enabled value-mode alternative |
54+
| `soxl_soxx_trend_income` | SOXL/SOXX Semiconductor Trend Income | Yes | Yes | `us_equity` | current IBKR live line |
55+
| `tech_communication_pullback_enhancement` | Tech/Communication Pullback Enhancement | Yes | Yes | `us_equity` | enabled feature-snapshot alternative |
56+
| `mega_cap_leader_rotation_aggressive` | Mega Cap Leader Rotation Aggressive | Yes | Yes | `us_equity` | enabled aggressive leader rotation |
57+
| `mega_cap_leader_rotation_dynamic_top20` | Mega Cap Leader Rotation Dynamic Top20 | Yes | Yes | `us_equity` | enabled concentrated leader rotation |
58+
| `dynamic_mega_leveraged_pullback` | Dynamic Mega Leveraged Pullback | Yes | Yes | `us_equity` | enabled 2x mega-cap pullback line |
5759

5860
Check the current matrix locally:
5961

@@ -98,8 +100,8 @@ The selected `ACCOUNT_GROUP` is now the runtime identity. Keep broker-specific i
98100
|----------|----------|-------------|
99101
| `IB_GATEWAY_ZONE` | Optional fallback | GCE zone (for example `us-central1-a`). Recommended to keep in the selected account-group entry; this env var is only a transition fallback. |
100102
| `IB_GATEWAY_IP_MODE` | Optional fallback | `internal` (default) or `external`. Recommended to keep in the selected account-group entry; this env var is only a transition fallback. |
101-
| `STRATEGY_PROFILE` | Yes | Strategy profile selector. Supported `us_equity` values: `global_etf_rotation`, `russell_1000_multi_factor_defensive`, `tqqq_growth_income`, `soxl_soxx_trend_income`, `tech_communication_pullback_enhancement`, `mega_cap_leader_rotation_dynamic_top20`, `dynamic_mega_leveraged_pullback` |
102-
| `ACCOUNT_GROUP` | Yes | Account-group selector. No default fallback. |
103+
| `STRATEGY_PROFILE` | Yes | Strategy profile selector. Supported `us_equity` values: `global_etf_rotation`, `russell_1000_multi_factor_defensive`, `tqqq_growth_income`, `soxl_soxx_trend_income`, `tech_communication_pullback_enhancement`, `mega_cap_leader_rotation_aggressive`, `mega_cap_leader_rotation_dynamic_top20`, `dynamic_mega_leveraged_pullback` |
104+
| `ACCOUNT_GROUP` | Yes | Account-group selector. Set explicitly for each deployment. |
103105
| `IBKR_FEATURE_SNAPSHOT_PATH` | Conditionally required | Required for snapshot-backed profiles such as `russell_1000_multi_factor_defensive`, `tech_communication_pullback_enhancement`, and `mega_cap_leader_rotation_dynamic_top20`. Path to the latest feature snapshot file (`.csv`, `.json`, `.jsonl`, `.parquet`). |
104106
| `IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME` | Yes for Cloud Run | Secret Manager secret name for account-group config JSON. Recommended production source. |
105107
| `IB_ACCOUNT_GROUP_CONFIG_JSON` | No | Local/dev JSON fallback for account-group config. Not recommended for production Cloud Run. |
@@ -218,7 +220,7 @@ Recommended setup:
218220
- `CLOUD_RUN_REGION`
219221
- `CLOUD_RUN_SERVICE`
220222
- `TELEGRAM_TOKEN_SECRET_NAME` (recommended when Cloud Run already uses Secret Manager for `TELEGRAM_TOKEN`)
221-
- `STRATEGY_PROFILE` (recommended: `global_etf_rotation`)
223+
- `STRATEGY_PROFILE` (set explicitly to one enabled profile, such as `soxl_soxx_trend_income`)
222224
- `ACCOUNT_GROUP` (recommended: `default`)
223225
- `IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME`
224226
- `GLOBAL_TELEGRAM_CHAT_ID`
@@ -288,7 +290,7 @@ gcloud run services update ibkr-quant \
288290

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

291-
当前 `global_etf_rotation``russell_1000_multi_factor_defensive``tqqq_growth_income``soxl_soxx_trend_income``tech_communication_pullback_enhancement``mega_cap_leader_rotation_dynamic_top20` 的策略实现都来自 `UsEquityStrategies`
293+
当前 `global_etf_rotation``russell_1000_multi_factor_defensive``tqqq_growth_income``soxl_soxx_trend_income``tech_communication_pullback_enhancement``mega_cap_leader_rotation_aggressive``mega_cap_leader_rotation_dynamic_top20``dynamic_mega_leveraged_pullback` 的策略实现都来自 `UsEquityStrategies`
292294

293295
完整策略说明现在放在 [`UsEquityStrategies`](https://github.com/QuantStrategyLab/UsEquityStrategies)。这个 README 只保留 IBKR 运行时、profile 启用状态、部署和凭据说明。
294296

@@ -329,8 +331,8 @@ IBKR 账户
329331
|------|------|------|
330332
| `IB_GATEWAY_ZONE` | 可选过渡项 | GCE zone(如 `us-central1-a`)。推荐直接放进选中的账号组配置里;这里只保留过渡 fallback。 |
331333
| `IB_GATEWAY_IP_MODE` | 可选过渡项 | `internal`(默认)或 `external`。推荐直接放进选中的账号组配置里;这里只保留过渡 fallback。 |
332-
| `STRATEGY_PROFILE` || 策略档位选择。当前可用的 `us_equity` 值:`global_etf_rotation``russell_1000_multi_factor_defensive``tqqq_growth_income``soxl_soxx_trend_income``tech_communication_pullback_enhancement``mega_cap_leader_rotation_dynamic_top20``dynamic_mega_leveraged_pullback` |
333-
| `ACCOUNT_GROUP` || 账号组选择器,不再提供默认回退|
334+
| `STRATEGY_PROFILE` || 策略档位选择。当前可用的 `us_equity` 值:`global_etf_rotation``russell_1000_multi_factor_defensive``tqqq_growth_income``soxl_soxx_trend_income``tech_communication_pullback_enhancement``mega_cap_leader_rotation_aggressive``mega_cap_leader_rotation_dynamic_top20``dynamic_mega_leveraged_pullback` |
335+
| `ACCOUNT_GROUP` || 账号组选择器,每个部署都要显式设置|
334336
| `IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME` | Cloud Run 建议必填 | 账号组配置 JSON 在 Secret Manager 里的密钥名。生产环境推荐使用。 |
335337
| `IB_ACCOUNT_GROUP_CONFIG_JSON` || 本地开发用的账号组配置 JSON fallback。不建议在生产 Cloud Run 直接使用。 |
336338
| `TELEGRAM_TOKEN` || Telegram 机器人 Token。Cloud Run 上更推荐走 Secret Manager 引用,不要直接写成明文 env。 |
@@ -415,7 +417,7 @@ IB_GATEWAY_IP_MODE=internal
415417
- `CLOUD_RUN_REGION`
416418
- `CLOUD_RUN_SERVICE`
417419
- `TELEGRAM_TOKEN_SECRET_NAME`(如果 Cloud Run 上的 `TELEGRAM_TOKEN` 已经改成 Secret Manager,建议配置)
418-
- `STRATEGY_PROFILE`建议设为 `global_etf_rotation`
420+
- `STRATEGY_PROFILE`显式设置为任一已启用 profile,例如 `soxl_soxx_trend_income`
419421
- `ACCOUNT_GROUP`(建议设为 `default`
420422
- `IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME`
421423
- `GLOBAL_TELEGRAM_CHAT_ID`

runtime_config_support.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@
88

99
from quant_platform_kit.common.strategies import derive_strategy_artifact_paths
1010
from strategy_registry import (
11-
DEFAULT_STRATEGY_PROFILE as PLATFORM_DEFAULT_STRATEGY_PROFILE,
1211
IBKR_PLATFORM,
1312
resolve_strategy_definition,
1413
resolve_strategy_metadata,
1514
)
1615
from us_equity_strategies import get_strategy_catalog
1716

1817
DEFAULT_ACCOUNT_GROUP = "default"
19-
DEFAULT_STRATEGY_PROFILE = PLATFORM_DEFAULT_STRATEGY_PROFILE
2018

2119

2220
@dataclass(frozen=True)

scripts/print_strategy_profile_status.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ def _print_table(rows: list[dict[str, object]]) -> None:
4343
"requires_strategy_config_path",
4444
"eligible",
4545
"enabled",
46-
"is_default",
47-
"is_rollback",
4846
"domain",
4947
)
5048
widths = {

strategy_registry.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222

2323
IBKR_PLATFORM = "ibkr"
2424

25-
DEFAULT_STRATEGY_PROFILE = "global_etf_rotation"
26-
ROLLBACK_STRATEGY_PROFILE = DEFAULT_STRATEGY_PROFILE
27-
2825
IBKR_ROLLOUT_ALLOWLIST = get_runtime_enabled_profiles()
2926

3027
PLATFORM_SUPPORTED_DOMAINS: dict[str, frozenset[str]] = {
@@ -61,12 +58,17 @@
6158
platform_id=IBKR_PLATFORM,
6259
supported_domains=PLATFORM_SUPPORTED_DOMAINS[IBKR_PLATFORM],
6360
enabled_profiles=IBKR_ENABLED_PROFILES,
64-
default_profile=DEFAULT_STRATEGY_PROFILE,
65-
rollback_profile=ROLLBACK_STRATEGY_PROFILE,
61+
default_profile="",
62+
rollback_profile="",
6663
require_explicit_profile=True,
6764
)
6865

6966
SUPPORTED_STRATEGY_PROFILES = IBKR_ENABLED_PROFILES
67+
_SELECTION_ROLE_FIELDS = frozenset({"is_default", "is_rollback"})
68+
69+
70+
def _without_selection_role_fields(row: dict[str, object]) -> dict[str, object]:
71+
return {key: value for key, value in row.items() if key not in _SELECTION_ROLE_FIELDS}
7072

7173

7274
def get_eligible_profiles_for_platform(platform_id: str) -> frozenset[str]:
@@ -80,15 +82,21 @@ def get_supported_profiles_for_platform(platform_id: str) -> frozenset[str]:
8082

8183

8284
def get_platform_profile_matrix() -> list[dict[str, object]]:
83-
return build_platform_profile_matrix(STRATEGY_CATALOG, policy=PLATFORM_POLICY)
85+
return [
86+
_without_selection_role_fields(row)
87+
for row in build_platform_profile_matrix(STRATEGY_CATALOG, policy=PLATFORM_POLICY)
88+
]
8489

8590

8691
def get_platform_profile_status_matrix() -> list[dict[str, object]]:
87-
return build_platform_profile_status_matrix(
88-
STRATEGY_CATALOG,
89-
policy=PLATFORM_POLICY,
90-
eligible_profiles=ELIGIBLE_STRATEGY_PROFILES,
91-
)
92+
return [
93+
_without_selection_role_fields(row)
94+
for row in build_platform_profile_status_matrix(
95+
STRATEGY_CATALOG,
96+
policy=PLATFORM_POLICY,
97+
eligible_profiles=ELIGIBLE_STRATEGY_PROFILES,
98+
)
99+
]
92100

93101

94102
def resolve_strategy_definition(

tests/test_runtime_config_support.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import pytest
77

88
from runtime_config_support import (
9-
DEFAULT_STRATEGY_PROFILE,
109
load_platform_runtime_settings,
1110
parse_account_group_configs,
1211
)
@@ -26,6 +25,7 @@
2625
)
2726
SCRIPT_PATH = Path(__file__).resolve().parents[1] / "scripts" / "print_strategy_profile_status.py"
2827
SWITCH_PLAN_SCRIPT_PATH = Path(__file__).resolve().parents[1] / "scripts" / "print_strategy_switch_env_plan.py"
28+
SAMPLE_STRATEGY_PROFILE = "global_etf_rotation"
2929

3030

3131
def test_load_platform_runtime_settings_requires_strategy_profile(monkeypatch):
@@ -39,7 +39,7 @@ def test_load_platform_runtime_settings_requires_strategy_profile(monkeypatch):
3939

4040

4141
def test_load_platform_runtime_settings_requires_account_group(monkeypatch):
42-
monkeypatch.setenv("STRATEGY_PROFILE", DEFAULT_STRATEGY_PROFILE)
42+
monkeypatch.setenv("STRATEGY_PROFILE", SAMPLE_STRATEGY_PROFILE)
4343
monkeypatch.setenv("IB_ACCOUNT_GROUP_CONFIG_JSON", MINIMAL_GROUP_JSON)
4444
monkeypatch.delenv("ACCOUNT_GROUP", raising=False)
4545

@@ -49,7 +49,7 @@ def test_load_platform_runtime_settings_requires_account_group(monkeypatch):
4949

5050

5151
def test_load_platform_runtime_settings_requires_account_group_config_source(monkeypatch):
52-
monkeypatch.setenv("STRATEGY_PROFILE", DEFAULT_STRATEGY_PROFILE)
52+
monkeypatch.setenv("STRATEGY_PROFILE", SAMPLE_STRATEGY_PROFILE)
5353
monkeypatch.setenv("ACCOUNT_GROUP", "default")
5454
monkeypatch.delenv("IB_ACCOUNT_GROUP_CONFIG_JSON", raising=False)
5555
monkeypatch.delenv("IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME", raising=False)
@@ -63,7 +63,7 @@ def test_load_platform_runtime_settings_requires_account_group_config_source(mon
6363

6464

6565
def test_load_platform_runtime_settings_uses_minimal_group_config(monkeypatch):
66-
monkeypatch.setenv("STRATEGY_PROFILE", DEFAULT_STRATEGY_PROFILE)
66+
monkeypatch.setenv("STRATEGY_PROFILE", SAMPLE_STRATEGY_PROFILE)
6767
monkeypatch.setenv("ACCOUNT_GROUP", "default")
6868
monkeypatch.setenv("IB_ACCOUNT_GROUP_CONFIG_JSON", MINIMAL_GROUP_JSON)
6969
monkeypatch.delenv("IB_GATEWAY_ZONE", raising=False)
@@ -80,7 +80,7 @@ def test_load_platform_runtime_settings_uses_minimal_group_config(monkeypatch):
8080
assert settings.ib_gateway_mode == "paper"
8181
assert settings.ib_gateway_ip_mode == "internal"
8282
assert settings.ib_client_id == 1
83-
assert settings.strategy_profile == DEFAULT_STRATEGY_PROFILE
83+
assert settings.strategy_profile == SAMPLE_STRATEGY_PROFILE
8484
assert settings.strategy_display_name == "Global ETF Rotation"
8585
assert settings.strategy_domain == US_EQUITY_DOMAIN
8686
assert settings.strategy_target_mode == "weight"
@@ -102,7 +102,7 @@ def test_load_platform_runtime_settings_uses_minimal_group_config(monkeypatch):
102102

103103

104104
def test_load_platform_runtime_settings_supports_explicit_group_config_values(monkeypatch):
105-
monkeypatch.setenv("STRATEGY_PROFILE", DEFAULT_STRATEGY_PROFILE)
105+
monkeypatch.setenv("STRATEGY_PROFILE", SAMPLE_STRATEGY_PROFILE)
106106
monkeypatch.setenv("ACCOUNT_GROUP", "taxable_main")
107107
monkeypatch.setenv(
108108
"IB_ACCOUNT_GROUP_CONFIG_JSON",
@@ -123,7 +123,7 @@ def test_load_platform_runtime_settings_supports_explicit_group_config_values(mo
123123
assert settings.ib_gateway_mode == "live"
124124
assert settings.ib_gateway_ip_mode == "external"
125125
assert settings.ib_client_id == 7
126-
assert settings.strategy_profile == DEFAULT_STRATEGY_PROFILE
126+
assert settings.strategy_profile == SAMPLE_STRATEGY_PROFILE
127127
assert settings.strategy_display_name == "Global ETF Rotation"
128128
assert settings.strategy_domain == US_EQUITY_DOMAIN
129129
assert settings.strategy_target_mode == "weight"
@@ -155,6 +155,7 @@ def test_platform_supported_profiles_are_filtered_by_registry():
155155
"tech_communication_pullback_enhancement",
156156
"global_etf_rotation",
157157
"dynamic_mega_leveraged_pullback",
158+
"mega_cap_leader_rotation_aggressive",
158159
"mega_cap_leader_rotation_dynamic_top20",
159160
"russell_1000_multi_factor_defensive",
160161
}
@@ -169,6 +170,7 @@ def test_platform_eligible_profiles_are_exposed_by_capability_matrix():
169170
"tech_communication_pullback_enhancement",
170171
"global_etf_rotation",
171172
"dynamic_mega_leveraged_pullback",
173+
"mega_cap_leader_rotation_aggressive",
172174
"mega_cap_leader_rotation_dynamic_top20",
173175
"russell_1000_multi_factor_defensive",
174176
}
@@ -244,11 +246,11 @@ def test_load_platform_runtime_settings_rejects_legacy_qqq_tech_alias(monkeypatc
244246
load_platform_runtime_settings(project_id_resolver=lambda: "project-1")
245247

246248

247-
def test_platform_profile_matrix_marks_default_and_rollback():
249+
def test_platform_profile_matrix_exposes_profiles_without_selection_roles():
248250
rows = get_platform_profile_matrix()
249251
by_profile = {row["canonical_profile"]: row for row in rows}
250-
assert by_profile["global_etf_rotation"]["is_default"] is True
251-
assert by_profile["global_etf_rotation"]["is_rollback"] is True
252+
assert "is_default" not in by_profile["global_etf_rotation"]
253+
assert "is_rollback" not in by_profile["global_etf_rotation"]
252254
assert by_profile["tech_communication_pullback_enhancement"]["display_name"] == "Tech/Communication Pullback Enhancement"
253255

254256

@@ -263,6 +265,7 @@ def test_platform_profile_status_matrix_matches_current_ibkr_rollout():
263265
"soxl_soxx_trend_income",
264266
"tqqq_growth_income",
265267
"tech_communication_pullback_enhancement",
268+
"mega_cap_leader_rotation_aggressive",
266269
"mega_cap_leader_rotation_dynamic_top20",
267270
}
268271
assert by_profile["global_etf_rotation"] == {
@@ -271,8 +274,6 @@ def test_platform_profile_status_matrix_matches_current_ibkr_rollout():
271274
"domain": "us_equity",
272275
"eligible": True,
273276
"enabled": True,
274-
"is_default": True,
275-
"is_rollback": True,
276277
"platform": "ibkr",
277278
}
278279
assert by_profile["soxl_soxx_trend_income"]["display_name"] == "SOXL/SOXX Semiconductor Trend Income"
@@ -301,8 +302,6 @@ def test_print_strategy_profile_status_json_matches_registry():
301302
"domain",
302303
"eligible",
303304
"enabled",
304-
"is_default",
305-
"is_rollback",
306305
"platform",
307306
)
308307
}
@@ -493,7 +492,7 @@ def test_load_platform_runtime_settings_derives_artifact_paths_from_root(monkeyp
493492

494493

495494
def test_load_platform_runtime_settings_uses_account_group_secret(monkeypatch):
496-
monkeypatch.setenv("STRATEGY_PROFILE", DEFAULT_STRATEGY_PROFILE)
495+
monkeypatch.setenv("STRATEGY_PROFILE", SAMPLE_STRATEGY_PROFILE)
497496
monkeypatch.setenv("ACCOUNT_GROUP", "ira")
498497
monkeypatch.setenv("IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME", "ibkr-account-groups")
499498

@@ -539,7 +538,7 @@ def access_secret_version(self, request):
539538

540539

541540
def test_load_platform_runtime_settings_requires_project_for_secret_source(monkeypatch):
542-
monkeypatch.setenv("STRATEGY_PROFILE", DEFAULT_STRATEGY_PROFILE)
541+
monkeypatch.setenv("STRATEGY_PROFILE", SAMPLE_STRATEGY_PROFILE)
543542
monkeypatch.setenv("ACCOUNT_GROUP", "default")
544543
monkeypatch.setenv("IB_ACCOUNT_GROUP_CONFIG_SECRET_NAME", "ibkr-account-groups")
545544

@@ -552,7 +551,7 @@ def test_load_platform_runtime_settings_requires_project_for_secret_source(monke
552551

553552

554553
def test_load_platform_runtime_settings_rejects_unknown_account_group(monkeypatch):
555-
monkeypatch.setenv("STRATEGY_PROFILE", DEFAULT_STRATEGY_PROFILE)
554+
monkeypatch.setenv("STRATEGY_PROFILE", SAMPLE_STRATEGY_PROFILE)
556555
monkeypatch.setenv("ACCOUNT_GROUP", "missing")
557556
monkeypatch.setenv("IB_ACCOUNT_GROUP_CONFIG_JSON", MINIMAL_GROUP_JSON)
558557

@@ -562,7 +561,7 @@ def test_load_platform_runtime_settings_rejects_unknown_account_group(monkeypatc
562561

563562

564563
def test_load_platform_runtime_settings_requires_key_group_fields(monkeypatch):
565-
monkeypatch.setenv("STRATEGY_PROFILE", DEFAULT_STRATEGY_PROFILE)
564+
monkeypatch.setenv("STRATEGY_PROFILE", SAMPLE_STRATEGY_PROFILE)
566565
monkeypatch.setenv("ACCOUNT_GROUP", "default")
567566
monkeypatch.setenv(
568567
"IB_ACCOUNT_GROUP_CONFIG_JSON",

0 commit comments

Comments
 (0)