feat: 账户方向与币种白名单 env 开关(三所)

Per-instance TRADE_DIRECTION / TRADE_SYMBOL_WHITELIST restricts UI and API for manual orders, key monitors, and strategies; includes sync script for deployment profiles.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-05 00:30:49 +08:00
parent 65b911994c
commit c0ad50a7b5
22 changed files with 814 additions and 35 deletions
+90
View File
@@ -0,0 +1,90 @@
"""账户方向 / 币种白名单 env 策略。"""
from lib.trade.trade_policy_lib import (
assert_direction_allowed,
assert_symbol_allowed,
assert_trade_policy_open,
load_trade_policy,
parse_symbol_whitelist,
symbol_base_coin,
trade_policy_badge_parts,
)
def test_default_policy_unrestricted():
p = load_trade_policy({})
assert not p.direction_restrict_enabled
assert not p.symbol_restrict_enabled
assert p.allows_long and p.allows_short
def test_long_only_blocks_short():
p = load_trade_policy(
{
"TRADE_DIRECTION_RESTRICT_ENABLED": "true",
"TRADE_DIRECTION": "long_only",
}
)
ok, msg = assert_direction_allowed(p, "short")
assert not ok
assert "仅做多" in msg
ok2, _ = assert_direction_allowed(p, "long")
assert ok2
def test_symbol_whitelist_btc_eth():
p = load_trade_policy(
{
"TRADE_SYMBOL_RESTRICT_ENABLED": "true",
"TRADE_SYMBOL_WHITELIST": "BTC,ETH",
}
)
ok, _ = assert_symbol_allowed(p, "BTC/USDT")
assert ok
ok2, msg = assert_symbol_allowed(p, "SOL")
assert not ok2
assert "SOL" in msg
def test_symbol_whitelist_without_list_disables_restrict():
p = load_trade_policy(
{
"TRADE_SYMBOL_RESTRICT_ENABLED": "true",
"TRADE_SYMBOL_WHITELIST": "",
}
)
assert not p.symbol_restrict_enabled
def test_combined_open_validation():
p = load_trade_policy(
{
"TRADE_DIRECTION_RESTRICT_ENABLED": "1",
"TRADE_DIRECTION": "",
"TRADE_SYMBOL_RESTRICT_ENABLED": "yes",
"TRADE_SYMBOL_WHITELIST": "BTC,ETH",
}
)
ok, _ = assert_trade_policy_open(p, "ETH", "long")
assert ok
ok2, msg = assert_trade_policy_open(p, "ETH", "short")
assert not ok2
ok3, msg3 = assert_trade_policy_open(p, "BNB", "long")
assert not ok3
assert "BNB" in msg3
def test_parse_whitelist_and_base_coin():
assert parse_symbol_whitelist("btc, eth") == ("BTC", "ETH")
assert symbol_base_coin("btc/usdt:usdt") == "BTC"
def test_badge_parts():
p = load_trade_policy(
{
"TRADE_DIRECTION_RESTRICT_ENABLED": "true",
"TRADE_DIRECTION": "long_only",
"TRADE_SYMBOL_RESTRICT_ENABLED": "true",
"TRADE_SYMBOL_WHITELIST": "BTC,ETH",
}
)
assert trade_policy_badge_parts(p) == ("仅多", "BTC/ETH")