Tune CoinOX env: drop auto-transfer; map leverage to hedge perp opens.

BTC_LEVERAGE/ALT_LEVERAGE now drive永期永续 default leverage in UI and start fallback.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-14 12:46:14 +08:00
parent 4b1c629d26
commit 4c48c95562
7 changed files with 62 additions and 46 deletions
+9 -11
View File
@@ -74,9 +74,9 @@ DAILY_START_CAPITAL=30
DAILY_LOSS_CAPITAL=20
# 日内盈利后基数(U)
DAILY_PROFIT_CAPITAL=50
# BTC 默认杠杆倍数
# 永期对冲·永续开仓杠杆(env 页「永期·永续杠杆」;页面未填时回退)
BTC_LEVERAGE=10
# 山寨币默认杠杆倍数
# ETH 永续开仓杠杆(键名沿用 ALT_LEVERAGE)
ALT_LEVERAGE=5
# 交易日重置小时(北京时间)
TRADING_DAY_RESET_HOUR=8
@@ -271,16 +271,14 @@ RECONCILE_FLAT_CONFIRM_POLLS=3
FULL_MARGIN_BUFFER_RATIO=0.98
# =============================================================================
# 自动划转(页顶「将 swap 补足到 XU」;与 DAILY_START_CAPITAL 独立,需一致时请设为相同值)
# 自动划转(CoinOX 已禁用,勿开启;保留键仅兼容旧 .env)
# =============================================================================
AUTO_TRANSFER_ENABLED=false
# 交易账户(swap)目标余额 U:每日 8 点(北京)自动划入或划出至 funding;持仓中不划转
AUTO_TRANSFER_AMOUNT=30
AUTO_TRANSFER_FROM=funding
AUTO_TRANSFER_TO=swap
TRANSFER_CCY=USDT
# 北京时间该整点小时内尝试;账簿按 UTC 自然日去重
AUTO_TRANSFER_BJ_HOUR=8
# AUTO_TRANSFER_ENABLED=false
# AUTO_TRANSFER_AMOUNT=30
# AUTO_TRANSFER_FROM=funding
# AUTO_TRANSFER_TO=swap
# TRANSFER_CCY=USDT
# AUTO_TRANSFER_BJ_HOUR=8
# 强制清仓整点(北京时间,默认 0=凌晨00点)
FORCE_CLOSE_BJ_HOUR=0
# 是否启用强制清仓(默认关闭,true 才会在整点执行)
+4 -1
View File
@@ -393,7 +393,8 @@ PRICE_REFRESH_SECONDS = int(os.getenv("PRICE_REFRESH_SECONDS", "5"))
KEY_ALERT_MAX_TIMES = int(os.getenv("KEY_ALERT_MAX_TIMES", "3"))
KEY_ALERT_INTERVAL_MINUTES = int(os.getenv("KEY_ALERT_INTERVAL_MINUTES", "5"))
KEY_BREAKOUT_LIMIT_PCT = float(os.getenv("KEY_BREAKOUT_LIMIT_PCT", "1.5"))
AUTO_TRANSFER_ENABLED = os.getenv("AUTO_TRANSFER_ENABLED", "false").lower() == "true"
# CoinOX 不提供自动划转(env 页已去掉该分区)
AUTO_TRANSFER_ENABLED = False
AUTO_TRANSFER_AMOUNT = float(os.getenv("AUTO_TRANSFER_AMOUNT", "30"))
AUTO_TRANSFER_FROM = os.getenv("AUTO_TRANSFER_FROM", "funding")
AUTO_TRANSFER_TO = os.getenv("AUTO_TRANSFER_TO", "swap")
@@ -6974,6 +6975,8 @@ def render_main_page(page="trade", embed_mode=None):
hedge_plan_option_primary=os.getenv("HEDGE_PLAN_OPTION_PRIMARY", "true").lower()
in ("1", "true", "yes", "on"),
hedge_plan_budget_buffer=float(os.getenv("HEDGE_PLAN_BUDGET_BUFFER") or "0.95"),
hedge_plan_btc_leverage=int(BTC_LEVERAGE or 10),
hedge_plan_eth_leverage=int(ALT_LEVERAGE or 5),
options_trade_budget=OKX_OPTIONS_TRADE_BUDGET_USDC,
options_budget_buffer=float(os.getenv("OKX_OPTIONS_BUDGET_BUFFER") or "0.95"),
options_compound_full_enabled=os.getenv(
+22 -3
View File
@@ -40,6 +40,7 @@
optionPrimary: root.getAttribute("data-option-primary") !== "0",
opLevTouched: false,
opRatioTouched: false,
perpLevTouched: false,
tradingUsdc: null,
fundingUsdc: null,
tradeBudgetUsdc: null,
@@ -377,6 +378,14 @@
};
}
function defaultPerpLeverage(uly) {
const u = (uly || "ETH").toUpperCase();
const btc = Number(root.getAttribute("data-btc-leverage") || 10);
const eth = Number(root.getAttribute("data-eth-leverage") || 5);
if (u === "BTC") return Number.isFinite(btc) && btc > 0 ? btc : 10;
return Number.isFinite(eth) && eth > 0 ? eth : 5;
}
function syncUnderlyingUI() {
const uly = state.underlying || "ETH";
document.querySelectorAll(".hp-uly-btn, .hp-uly-btn-oo").forEach(function (b) {
@@ -388,6 +397,11 @@
if (lab) lab.textContent = uly;
const ooLab = $("hp-oo-uly-label");
if (ooLab) ooLab.textContent = uly;
// 永续开仓杠杆跟随 env(BTC_LEVERAGE / ALT_LEVERAGE=ETH)
const levEl = $("hp-perp-leverage");
if (levEl && !state.perpLevTouched) {
levEl.value = String(defaultPerpLeverage(uly));
}
}
function syncMoneyUI() {
@@ -1664,7 +1678,7 @@
strike_interval: numInput("hp-strike-interval", 15),
min_option_hours: numInput("hp-min-hours", 36),
option_leverage: numInput("hp-opt-leverage", 100),
leverage: numInput("hp-perp-leverage", 100),
leverage: numInput("hp-perp-leverage", defaultPerpLeverage(state.underlying)),
moneyness: opMoneyKind(),
hours_to_expiry: exp ? hoursFromExpMs(exp.exp_time) : null,
};
@@ -1868,6 +1882,11 @@
renderListStrikes();
});
}
if ($("hp-perp-leverage")) {
$("hp-perp-leverage").addEventListener("input", function () {
state.perpLevTouched = true;
});
}
if ($("hp-opt-leverage")) {
$("hp-opt-leverage").addEventListener("input", function () {
state.opLevTouched = true;
@@ -2618,7 +2637,7 @@
strike_interval: numInput("hp-strike-interval", 15),
min_option_hours: numInput("hp-min-hours", 36),
option_leverage: optLev,
leverage: numInput("hp-perp-leverage", 100),
leverage: numInput("hp-perp-leverage", defaultPerpLeverage(state.underlying)),
moneyness: opMoneyKind(),
};
const d = await apiJson("/api/hedge-plan/start", {
@@ -2684,7 +2703,7 @@
ask: state.selected.ask,
index_px: entry,
exchange_symbol: (state.market && state.market.exchange_symbol) || "",
leverage: numInput("hp-perp-leverage", 100),
leverage: numInput("hp-perp-leverage", defaultPerpLeverage(state.underlying)),
option_leverage: numInput("hp-opt-leverage", 100),
premium_budget: numInput("hp-premium-budget", 0),
option_perp_ratio: numInput("hp-opt-perp-ratio", 2),
+12 -19
View File
@@ -119,7 +119,7 @@ _SHARED_SECTIONS: list[dict[str, Any]] = [
},
]
# CoinOX env 页:去掉关键位/AI复盘/永续手工单等无关项
# CoinOX env 页:去掉关键位/AI复盘/自动划转等无关项
_COINOX_SHARED_SECTIONS: list[dict[str, Any]] = [
{
"title": "企业微信",
@@ -129,14 +129,18 @@ _COINOX_SHARED_SECTIONS: list[dict[str, Any]] = [
],
},
{
"title": "资金与杠杆",
"title": "永期·永续杠杆",
"fields": [
("POSITION_SIZING_MODE", "计仓模式", "切换须无仓后重启"),
("RISK_PERCENT", "以损定仓风险%", "单笔风险占资金比例"),
("FULL_MARGIN_BUFFER_RATIO", "全仓资金缓冲比例", "如 0.98"),
("BTC_LEVERAGE", "BTC 默认杠杆", ""),
("ALT_LEVERAGE", "山寨默认杠杆", ""),
("TRADING_DAY_RESET_HOUR", "交易日切点(北京时间)", "整点,默认 8"),
(
"BTC_LEVERAGE",
"BTC 永续开仓杠杆",
"永期对冲开永续腿时用;页面未填杠杆时回退本值",
),
(
"ALT_LEVERAGE",
"ETH 永续开仓杠杆",
"永期对冲开 ETH-USDT 永续时用;页面未填杠杆时回退本值",
),
],
},
{
@@ -147,17 +151,6 @@ _COINOX_SHARED_SECTIONS: list[dict[str, Any]] = [
("SIM_FEE_RATE", "模拟手续费率", "默认 0.0005"),
],
},
{
"title": "自动划转",
"fields": [
("AUTO_TRANSFER_ENABLED", "启用自动划转", ""),
("AUTO_TRANSFER_AMOUNT", "目标余额(U)", "交易账户目标 USDT"),
("AUTO_TRANSFER_FROM", "划出账户", "余额不足时从此账户划入交易账户"),
("AUTO_TRANSFER_TO", "划入账户", "目标余额所在账户,一般为 swap"),
("AUTO_TRANSFER_BJ_HOUR", "执行整点(北京时间)", ""),
("TRANSFER_CCY", "划转币种", ""),
],
},
]
_MODE_SECTION: dict[str, Any] = {
+8 -7
View File
@@ -845,18 +845,19 @@ def register_hedge_plan_routes(app: Flask, cfg: dict[str, Any]) -> None:
err = validate_start_body(plan_type, body)
if err:
return jsonify({"ok": False, "msg": err, "gates": gates}), 400
# 补齐永续杠杆(以期权为主默认 100;保险模式 BTC/ETH 用 btc_leverage)
# 补齐永续杠杆:页面未填时用 env(BTC_LEVERAGE / ALT_LEVERAGE=ETH)
if plan_type == "perp_options" and not body.get("leverage"):
from lib.hedge_plan.hedge_plan_option_primary_lib import is_option_primary
if is_option_primary(body):
base = str(body.get("underlying") or "ETH").upper()
if base == "BTC":
body["leverage"] = int(cfg.get("btc_leverage") or 10)
elif base == "ETH":
body["leverage"] = int(cfg.get("alt_leverage") or cfg.get("btc_leverage") or 10)
elif is_option_primary(body):
body["leverage"] = 100
else:
base = str(body.get("underlying") or "ETH").upper()
if base in ("BTC", "ETH"):
body["leverage"] = int(cfg.get("btc_leverage") or 10)
else:
body["leverage"] = int(cfg.get("alt_leverage") or 5)
body["leverage"] = int(cfg.get("alt_leverage") or 5)
# 以期权为主:策略启动=盯盘,不现场开仓
if plan_type == "perp_options":
from lib.hedge_plan.hedge_plan_option_primary_lib import is_option_primary
@@ -7,6 +7,8 @@
data-oo-close-mode-enabled="{{ '1' if hedge_plan_oo_close_mode_enabled else '0' }}"
data-option-primary="{{ '1' if hedge_plan_option_primary|default(true) else '0' }}"
data-budget-buffer="{{ hedge_plan_budget_buffer | default(0.95) }}"
data-btc-leverage="{{ hedge_plan_btc_leverage | default(10) }}"
data-eth-leverage="{{ hedge_plan_eth_leverage | default(5) }}"
data-sizing-mode="{{ position_sizing_mode | default('risk') }}"
data-is-full-margin="{{ '1' if position_sizing_mode == 'full_margin' else '0' }}">
{% if not hedge_plan_enabled %}
@@ -96,8 +98,8 @@
<input type="number" step="any" id="hp-premium-budget" placeholder="预算(执行×0.95)" autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
</label>
<label class="hp-po-field">
<span class="hp-po-field-lab">永续杠杆</span>
<input type="number" step="1" id="hp-perp-leverage" value="100" autocomplete="off" inputmode="numeric" data-lpignore="true" data-1p-ignore="true" data-form-type="other" />
<span class="hp-po-field-lab">永续杠杆 <em>开仓</em></span>
<input type="number" step="1" id="hp-perp-leverage" value="{{ hedge_plan_eth_leverage | default(5) }}" autocomplete="off" inputmode="numeric" data-lpignore="true" data-1p-ignore="true" data-form-type="other" title="默认取 env 永期·永续杠杆;可按标的切换" />
</label>
<label class="hp-po-field">
<span class="hp-po-field-lab">期权杠杆 <em>启动校验</em></span>
@@ -405,4 +407,4 @@
</div>
</div>
</div>
<script src="/static/hedge_plan.js?v=49"></script>
<script src="/static/hedge_plan.js?v=50"></script>
+2 -2
View File
@@ -23,7 +23,7 @@ DEFAULT_INSTANCE_DISPLAY: dict[str, bool] = {
"show_nav_options": True,
"show_nav_options_review": True,
"show_nav_hedge_plan": True,
"show_settings_transfer": True,
"show_settings_transfer": False, # CoinOX 不需要永续自动划转
"show_settings_export": True,
"show_settings_password": True,
"show_settings_options_swap": False, # CoinOX 已移除 USDT↔USDC 兑换
@@ -87,6 +87,7 @@ def normalize_display_prefs(raw: dict | None) -> dict[str, bool]:
out["show_nav_strategy_records"] = False
out["show_nav_system_guide"] = False
out["show_settings_options_swap"] = False
out["show_settings_transfer"] = False
return out
@@ -138,7 +139,6 @@ def display_meta_for_ui() -> list[dict[str, Any]]:
"show_nav_env_config",
]
settings_keys = [
"show_settings_transfer",
"show_settings_export",
"show_settings_password",
"show_settings_options_transfer",