Expand default strike rows and add hedge fund transfer / sell-coin.
Show the default five chain rows without a scroll box, add funding transfer under manual pick, and wire sell-back-coin above positions via hedge APIs. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+166
-20
@@ -1431,8 +1431,12 @@
|
|||||||
} else if (acct.trading_usdc != null && acct.trading_usdc !== "") {
|
} else if (acct.trading_usdc != null && acct.trading_usdc !== "") {
|
||||||
state.tradingUsdt = Number(acct.trading_usdc);
|
state.tradingUsdt = Number(acct.trading_usdc);
|
||||||
}
|
}
|
||||||
if (acct.funding_usdc != null && acct.funding_usdc !== "") {
|
if (acct.funding_usdt != null && acct.funding_usdt !== "") {
|
||||||
|
state.fundingUsdt = Number(acct.funding_usdt);
|
||||||
|
state.fundingUsdc = Number(acct.funding_usdt);
|
||||||
|
} else if (acct.funding_usdc != null && acct.funding_usdc !== "") {
|
||||||
state.fundingUsdc = Number(acct.funding_usdc);
|
state.fundingUsdc = Number(acct.funding_usdc);
|
||||||
|
state.fundingUsdt = Number(acct.funding_usdc);
|
||||||
}
|
}
|
||||||
if (chain && chain.trade_budget_usdc != null && chain.trade_budget_usdc !== "") {
|
if (chain && chain.trade_budget_usdc != null && chain.trade_budget_usdc !== "") {
|
||||||
state.tradeBudgetUsdc = Number(chain.trade_budget_usdc);
|
state.tradeBudgetUsdc = Number(chain.trade_budget_usdc);
|
||||||
@@ -1461,11 +1465,19 @@
|
|||||||
const tradeEl = $("hp-oo-trading-usdc");
|
const tradeEl = $("hp-oo-trading-usdc");
|
||||||
if (fundEl) fundEl.textContent = fmt(acct.funding_usdt != null ? acct.funding_usdt : acct.funding_usdc, 2);
|
if (fundEl) fundEl.textContent = fmt(acct.funding_usdt != null ? acct.funding_usdt : acct.funding_usdc, 2);
|
||||||
if (tradeEl) tradeEl.textContent = equityTxt;
|
if (tradeEl) tradeEl.textContent = equityTxt;
|
||||||
|
const poFund = $("hp-po-funding-usdt");
|
||||||
|
const poTrade = $("hp-po-trading-usdt");
|
||||||
|
if (poFund) poFund.textContent = fmt(acct.funding_usdt != null ? acct.funding_usdt : acct.funding_usdc, 2);
|
||||||
|
if (poTrade) poTrade.textContent = equityTxt;
|
||||||
|
state.fundingEth = acct.funding_eth != null ? Number(acct.funding_eth) : null;
|
||||||
|
state.tradingEth = acct.trading_eth != null ? Number(acct.trading_eth) : null;
|
||||||
|
state.fundingBtc = acct.funding_btc != null ? Number(acct.funding_btc) : null;
|
||||||
|
state.tradingBtc = acct.trading_btc != null ? Number(acct.trading_btc) : null;
|
||||||
autoFillOoSheets();
|
autoFillOoSheets();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setOoXferMsg(text, kind) {
|
function setXferMsg(prefix, text, kind) {
|
||||||
const el = $("hp-oo-xfer-msg");
|
const el = $(prefix + "-xfer-msg");
|
||||||
if (!el) return;
|
if (!el) return;
|
||||||
el.textContent = text || "";
|
el.textContent = text || "";
|
||||||
el.classList.toggle("is-err", kind === "err");
|
el.classList.toggle("is-err", kind === "err");
|
||||||
@@ -1473,31 +1485,131 @@
|
|||||||
el.classList.toggle("muted", !kind);
|
el.classList.toggle("muted", !kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setOoXferMsg(text, kind) {
|
||||||
|
setXferMsg("hp-oo", text, kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPoXferMsg(text, kind) {
|
||||||
|
setXferMsg("hp-po", text, kind);
|
||||||
|
}
|
||||||
|
|
||||||
function ooXferDir() {
|
function ooXferDir() {
|
||||||
const sel = $("hp-oo-xfer-dir");
|
const sel = $("hp-oo-xfer-dir");
|
||||||
return (sel && sel.value) || "funding_to_trading";
|
return (sel && sel.value) || "funding_to_trading";
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitOoUsdcTransfer(amount) {
|
function poXferDir() {
|
||||||
const dir = ooXferDir();
|
const sel = $("hp-po-xfer-dir");
|
||||||
|
return (sel && sel.value) || "funding_to_trading";
|
||||||
|
}
|
||||||
|
|
||||||
|
function poXferCcy() {
|
||||||
|
const sel = $("hp-po-xfer-ccy");
|
||||||
|
return ((sel && sel.value) || "USDT").toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
function xferAvailFor(ccy, fromAcct) {
|
||||||
|
const c = String(ccy || "USDT").toUpperCase();
|
||||||
|
const from = String(fromAcct || "funding").toLowerCase();
|
||||||
|
if (c === "USDT") {
|
||||||
|
if (from === "trading") {
|
||||||
|
return Number(
|
||||||
|
state.tradingUsdt != null
|
||||||
|
? state.tradingUsdt
|
||||||
|
: state.tradingUsdc != null
|
||||||
|
? state.tradingUsdc
|
||||||
|
: 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Number(
|
||||||
|
state.fundingUsdt != null
|
||||||
|
? state.fundingUsdt
|
||||||
|
: state.fundingUsdc != null
|
||||||
|
? state.fundingUsdc
|
||||||
|
: 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (c === "ETH") {
|
||||||
|
return Number(from === "trading" ? state.tradingEth || 0 : state.fundingEth || 0);
|
||||||
|
}
|
||||||
|
if (c === "BTC") {
|
||||||
|
return Number(from === "trading" ? state.tradingBtc || 0 : state.fundingBtc || 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function submitHedgeTransfer(opts) {
|
||||||
|
const prefix = opts.prefix || "hp-oo";
|
||||||
|
const dir = opts.dir || "funding_to_trading";
|
||||||
|
const ccy = String(opts.ccy || "USDT").toUpperCase();
|
||||||
|
const amount = Number(opts.amount || 0);
|
||||||
|
const setMsg = prefix === "hp-po" ? setPoXferMsg : setOoXferMsg;
|
||||||
const from = dir === "trading_to_funding" ? "trading" : "funding";
|
const from = dir === "trading_to_funding" ? "trading" : "funding";
|
||||||
const to = dir === "trading_to_funding" ? "funding" : "trading";
|
const to = dir === "trading_to_funding" ? "funding" : "trading";
|
||||||
setOoXferMsg("划转中…", null);
|
if (!(amount > 0)) {
|
||||||
|
setMsg("请输入有效数量", "err");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setMsg("划转中…", null);
|
||||||
try {
|
try {
|
||||||
const d = await apiJson("/api/options/transfer", {
|
const d = await apiJson("/api/hedge-plan/transfer", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({ ccy: "USDT", from: from, to: to, amount: amount }),
|
body: JSON.stringify({ ccy: ccy, from: from, to: to, amount: amount }),
|
||||||
});
|
});
|
||||||
if (!d.ok) {
|
if (!d.ok) {
|
||||||
setOoXferMsg(d.msg || "划转失败", "err");
|
setMsg(d.msg || "划转失败", "err");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setOoXferMsg("划转成功", "ok");
|
setMsg("划转成功", "ok");
|
||||||
if ($("hp-oo-xfer-amount")) $("hp-oo-xfer-amount").value = "";
|
const amtEl = $(prefix + "-xfer-amount");
|
||||||
|
if (amtEl) amtEl.value = "";
|
||||||
await loadChain();
|
await loadChain();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setOoXferMsg(e.message || "划转失败", "err");
|
setMsg(e.message || "划转失败", "err");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function submitOoUsdcTransfer(amount) {
|
||||||
|
return submitHedgeTransfer({ prefix: "hp-oo", dir: ooXferDir(), ccy: "USDT", amount: amount });
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSellCoinMsg(text, kind) {
|
||||||
|
const el = $("hp-sell-coin-msg");
|
||||||
|
if (!el) return;
|
||||||
|
el.textContent = text || "";
|
||||||
|
el.classList.toggle("is-err", kind === "err");
|
||||||
|
el.classList.toggle("is-ok", kind === "ok");
|
||||||
|
el.classList.toggle("muted", !kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function submitSellCoin() {
|
||||||
|
const uly = String(state.underlying || "ETH").toUpperCase();
|
||||||
|
if (!window.confirm("确认市价卖出交易账户全部可用 " + uly + " 换回 USDT?")) return;
|
||||||
|
setSellCoinMsg("卖回中…", null);
|
||||||
|
const btn = $("hp-sell-coin-btn");
|
||||||
|
if (btn) btn.disabled = true;
|
||||||
|
try {
|
||||||
|
const d = await apiJson("/api/hedge-plan/sell-coin", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ underlying: uly }),
|
||||||
|
});
|
||||||
|
if (!d.ok) {
|
||||||
|
setSellCoinMsg(d.msg || "卖回失败", "err");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const sold =
|
||||||
|
d.sell && d.sell.coin_sold != null
|
||||||
|
? "已卖 " + d.sell.coin_sold + " " + uly
|
||||||
|
: d.msg || "卖回成功";
|
||||||
|
setSellCoinMsg(sold, "ok");
|
||||||
|
await loadChain();
|
||||||
|
void loadLivePositions();
|
||||||
|
} catch (e) {
|
||||||
|
setSellCoinMsg(e.message || "卖回失败", "err");
|
||||||
|
} finally {
|
||||||
|
if (btn) btn.disabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2901,18 +3013,14 @@
|
|||||||
if ($("hp-oo-xfer-btn")) {
|
if ($("hp-oo-xfer-btn")) {
|
||||||
$("hp-oo-xfer-btn").addEventListener("click", function () {
|
$("hp-oo-xfer-btn").addEventListener("click", function () {
|
||||||
const amount = Number(($("hp-oo-xfer-amount") && $("hp-oo-xfer-amount").value) || 0);
|
const amount = Number(($("hp-oo-xfer-amount") && $("hp-oo-xfer-amount").value) || 0);
|
||||||
if (!(amount > 0)) {
|
void submitHedgeTransfer({ prefix: "hp-oo", dir: ooXferDir(), ccy: "USDT", amount: amount });
|
||||||
setOoXferMsg("请输入有效数量", "err");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void submitOoUsdcTransfer(amount);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if ($("hp-oo-xfer-all")) {
|
if ($("hp-oo-xfer-all")) {
|
||||||
$("hp-oo-xfer-all").addEventListener("click", function () {
|
$("hp-oo-xfer-all").addEventListener("click", function () {
|
||||||
const dir = ooXferDir();
|
const dir = ooXferDir();
|
||||||
const max =
|
const from = dir === "trading_to_funding" ? "trading" : "funding";
|
||||||
dir === "trading_to_funding" ? Number(state.tradingUsdc || 0) : Number(state.fundingUsdc || 0);
|
const max = xferAvailFor("USDT", from);
|
||||||
if (!(max > 0)) {
|
if (!(max > 0)) {
|
||||||
setOoXferMsg("划出账户可用余额不足", "err");
|
setOoXferMsg("划出账户可用余额不足", "err");
|
||||||
return;
|
return;
|
||||||
@@ -2925,11 +3033,49 @@
|
|||||||
amtEl.removeAttribute("readonly");
|
amtEl.removeAttribute("readonly");
|
||||||
amtEl.value = String(amt);
|
amtEl.value = String(amt);
|
||||||
}
|
}
|
||||||
void submitOoUsdcTransfer(amt);
|
void submitHedgeTransfer({ prefix: "hp-oo", dir: dir, ccy: "USDT", amount: amt });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if ($("hp-po-xfer-btn")) {
|
||||||
|
$("hp-po-xfer-btn").addEventListener("click", function () {
|
||||||
|
const amount = Number(($("hp-po-xfer-amount") && $("hp-po-xfer-amount").value) || 0);
|
||||||
|
void submitHedgeTransfer({
|
||||||
|
prefix: "hp-po",
|
||||||
|
dir: poXferDir(),
|
||||||
|
ccy: poXferCcy(),
|
||||||
|
amount: amount,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if ($("hp-po-xfer-all")) {
|
||||||
|
$("hp-po-xfer-all").addEventListener("click", function () {
|
||||||
|
const dir = poXferDir();
|
||||||
|
const ccy = poXferCcy();
|
||||||
|
const from = dir === "trading_to_funding" ? "trading" : "funding";
|
||||||
|
const max = xferAvailFor(ccy, from);
|
||||||
|
if (!(max > 0)) {
|
||||||
|
setPoXferMsg("划出账户可用余额不足", "err");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const amt = ccy === "USDT" ? Math.floor(max * 100) / 100 : Math.floor(max * 1e6) / 1e6;
|
||||||
|
const label = dir === "trading_to_funding" ? "交易 → 资金" : "资金 → 交易";
|
||||||
|
if (!window.confirm("确认全部划转?\n币种:" + ccy + "\n方向:" + label + "\n数量:" + amt)) return;
|
||||||
|
const amtEl = $("hp-po-xfer-amount");
|
||||||
|
if (amtEl) {
|
||||||
|
amtEl.removeAttribute("readonly");
|
||||||
|
amtEl.value = String(amt);
|
||||||
|
}
|
||||||
|
void submitHedgeTransfer({ prefix: "hp-po", dir: dir, ccy: ccy, amount: amt });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if ($("hp-sell-coin-btn")) {
|
||||||
|
$("hp-sell-coin-btn").addEventListener("click", function () {
|
||||||
|
void submitSellCoin();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
hardenAmountAutofill([
|
hardenAmountAutofill([
|
||||||
"hp-oo-xfer-amount",
|
"hp-oo-xfer-amount",
|
||||||
|
"hp-po-xfer-amount",
|
||||||
"hp-entry",
|
"hp-entry",
|
||||||
"hp-contracts",
|
"hp-contracts",
|
||||||
"hp-tp",
|
"hp-tp",
|
||||||
|
|||||||
@@ -3864,12 +3864,13 @@ html[data-theme="light"] .opt-be-dist-down {
|
|||||||
.hedge-plan-page-wrap #hp-po-fields-option-primary[hidden] {
|
.hedge-plan-page-wrap #hp-po-fields-option-primary[hidden] {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
/* 默认约 5 档全部展开,不设滚动框(展开全部时随内容增高) */
|
||||||
.hedge-plan-page-wrap .hp-strike-table-wrap--6 {
|
.hedge-plan-page-wrap .hp-strike-table-wrap--6 {
|
||||||
max-height: 280px;
|
max-height: none;
|
||||||
min-height: 200px;
|
min-height: 0;
|
||||||
overflow-y: auto;
|
overflow: visible;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
flex: 1 1 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
.hedge-plan-page-wrap .hp-po-field {
|
.hedge-plan-page-wrap .hp-po-field {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -4101,13 +4102,13 @@ html[data-theme="light"] .opt-be-dist-down {
|
|||||||
min-height: 26px;
|
min-height: 26px;
|
||||||
font-size: 0.72rem;
|
font-size: 0.72rem;
|
||||||
}
|
}
|
||||||
/* 永期期权列表:视口约 5 行 + 表头,超出滚动 */
|
/* 永期期权列表:默认档位全部展开,无下滑框 */
|
||||||
.hedge-plan-page-wrap .hp-strike-table-wrap--5 {
|
.hedge-plan-page-wrap .hp-strike-table-wrap--5 {
|
||||||
max-height: 248px;
|
max-height: none;
|
||||||
min-height: 248px;
|
min-height: 0;
|
||||||
overflow-y: auto;
|
overflow: visible;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
flex: 1 1 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
/* 期期 T 型:默认 3+3 一页展示,无下滑框 */
|
/* 期期 T 型:默认 3+3 一页展示,无下滑框 */
|
||||||
.hedge-plan-page-wrap .hp-oo-table-wrap {
|
.hedge-plan-page-wrap .hp-oo-table-wrap {
|
||||||
@@ -4342,8 +4343,8 @@ html[data-theme="light"] .opt-be-dist-down {
|
|||||||
}
|
}
|
||||||
.hedge-plan-page-wrap .hp-po-left-stack > .hp-opt-card .hp-strike-table-wrap--6,
|
.hedge-plan-page-wrap .hp-po-left-stack > .hp-opt-card .hp-strike-table-wrap--6,
|
||||||
.hedge-plan-page-wrap .hp-po-select-card .hp-strike-table-wrap--6 {
|
.hedge-plan-page-wrap .hp-po-select-card .hp-strike-table-wrap--6 {
|
||||||
flex: 1 1 auto;
|
flex: 0 0 auto;
|
||||||
min-height: 220px;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
.hedge-plan-page-wrap .hp-po-pair-hint,
|
.hedge-plan-page-wrap .hp-po-pair-hint,
|
||||||
.hedge-plan-page-wrap .hp-po-chain-hint {
|
.hedge-plan-page-wrap .hp-po-chain-hint {
|
||||||
|
|||||||
@@ -1244,6 +1244,80 @@ def register_hedge_plan_routes(app: Flask, cfg: dict[str, Any]) -> None:
|
|||||||
conn.close()
|
conn.close()
|
||||||
return jsonify(out)
|
return jsonify(out)
|
||||||
|
|
||||||
|
@app.route("/api/hedge-plan/transfer", methods=["POST"])
|
||||||
|
@lr
|
||||||
|
def api_hedge_transfer():
|
||||||
|
"""账户内划转(资金↔交易);USDT/ETH/BTC.本仓不依赖单独期权 UI."""
|
||||||
|
if not _hedge_enabled():
|
||||||
|
return jsonify({"ok": False, "msg": "对冲模块未启用"}), 400
|
||||||
|
ex = cfg.get("exchange_options") or cfg.get("exchange")
|
||||||
|
if ex is None:
|
||||||
|
return jsonify({"ok": False, "msg": "交易所未配置"}), 400
|
||||||
|
data = request.get_json(silent=True) or {}
|
||||||
|
ccy = str(data.get("ccy") or "USDT").strip().upper()
|
||||||
|
if ccy not in ("USDT", "ETH", "BTC"):
|
||||||
|
return jsonify({"ok": False, "msg": "币种仅支持 USDT/ETH/BTC"}), 400
|
||||||
|
from_acct = str(data.get("from") or "funding").strip().lower()
|
||||||
|
to_acct = str(data.get("to") or "trading").strip().lower()
|
||||||
|
if from_acct not in ("funding", "trading") or to_acct not in ("funding", "trading"):
|
||||||
|
return jsonify({"ok": False, "msg": "账户仅支持 funding/trading"}), 400
|
||||||
|
if from_acct == to_acct:
|
||||||
|
return jsonify({"ok": False, "msg": "划出与划入账户不能相同"}), 400
|
||||||
|
try:
|
||||||
|
amount = float(data.get("amount"))
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
return jsonify({"ok": False, "msg": "数量无效"}), 400
|
||||||
|
if amount <= 0:
|
||||||
|
return jsonify({"ok": False, "msg": "数量须大于 0"}), 400
|
||||||
|
from lib.exchange.okx_options_lib import transfer_ccy
|
||||||
|
|
||||||
|
result = transfer_ccy(ex, ccy, amount, from_acct, to_acct)
|
||||||
|
if result.get("ok"):
|
||||||
|
try:
|
||||||
|
from lib.exchange.okx_options_lib import invalidate_options_balance_cache
|
||||||
|
|
||||||
|
invalidate_options_balance_cache()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return jsonify(result)
|
||||||
|
|
||||||
|
@app.route("/api/hedge-plan/sell-coin", methods=["POST"])
|
||||||
|
@lr
|
||||||
|
def api_hedge_sell_coin():
|
||||||
|
"""手动卖回币:市价卖出交易账户全部可用标的币换 USDT."""
|
||||||
|
if not _hedge_enabled():
|
||||||
|
return jsonify({"ok": False, "msg": "对冲模块未启用"}), 400
|
||||||
|
ex = cfg.get("exchange_options") or cfg.get("exchange")
|
||||||
|
if ex is None:
|
||||||
|
return jsonify({"ok": False, "msg": "交易所未配置"}), 400
|
||||||
|
data = request.get_json(silent=True) or {}
|
||||||
|
underlying = str(data.get("underlying") or cfg.get("default_underly") or "ETH").strip().upper()
|
||||||
|
if underlying not in ("ETH", "BTC"):
|
||||||
|
return jsonify({"ok": False, "msg": "标的仅支持 ETH/BTC"}), 400
|
||||||
|
conn = cfg["get_db"]()
|
||||||
|
try:
|
||||||
|
from lib.options.options_db import init_options_tables
|
||||||
|
from lib.options.options_spot_bridge_lib import sell_residual_after_option_flat
|
||||||
|
|
||||||
|
init_options_tables(conn)
|
||||||
|
out = sell_residual_after_option_flat(
|
||||||
|
conn,
|
||||||
|
ex,
|
||||||
|
underlying=underlying,
|
||||||
|
inst_id=(str(data.get("inst_id") or "").strip() or None),
|
||||||
|
)
|
||||||
|
if out.get("ok"):
|
||||||
|
conn.commit()
|
||||||
|
try:
|
||||||
|
from lib.exchange.okx_options_lib import invalidate_options_balance_cache
|
||||||
|
|
||||||
|
invalidate_options_balance_cache()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return jsonify(out)
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
@app.route("/api/hedge-plan/monitor-tick", methods=["POST"])
|
@app.route("/api/hedge-plan/monitor-tick", methods=["POST"])
|
||||||
@lr
|
@lr
|
||||||
def api_hedge_monitor_tick():
|
def api_hedge_monitor_tick():
|
||||||
@@ -1479,6 +1553,10 @@ def _options_account_snapshot(cfg: dict[str, Any]) -> dict[str, Any]:
|
|||||||
"funding_usdt": pack.get("funding_usdt"),
|
"funding_usdt": pack.get("funding_usdt"),
|
||||||
"trading_usdt_avail": pack.get("trading_usdt_avail", pack.get("trading_usdt")),
|
"trading_usdt_avail": pack.get("trading_usdt_avail", pack.get("trading_usdt")),
|
||||||
"perp_margin_usdt": pack.get("perp_margin_usdt"),
|
"perp_margin_usdt": pack.get("perp_margin_usdt"),
|
||||||
|
"funding_eth": pack.get("funding_eth"),
|
||||||
|
"trading_eth": pack.get("trading_eth"),
|
||||||
|
"funding_btc": pack.get("funding_btc"),
|
||||||
|
"trading_btc": pack.get("trading_btc"),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
@@ -101,6 +101,32 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div id="hp-opt-bal-line" class="muted hp-po-meta hp-opt-bal-line"></div>
|
<div id="hp-opt-bal-line" class="muted hp-po-meta hp-opt-bal-line"></div>
|
||||||
|
<div class="hp-oo-transfer hp-oo-transfer--compact" id="hp-po-transfer">
|
||||||
|
<div class="hp-oo-transfer-bals muted">
|
||||||
|
<span>资金 <strong id="hp-po-funding-usdt">—</strong></span>
|
||||||
|
<span class="hp-oo-transfer-sep">·</span>
|
||||||
|
<span>交易 <strong id="hp-po-trading-usdt">—</strong></span>
|
||||||
|
<span class="hp-oo-transfer-unit">USDT</span>
|
||||||
|
<span class="muted" id="hp-po-xfer-msg"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-row hp-oo-transfer-form" autocomplete="off">
|
||||||
|
<input type="text" name="username" autocomplete="username" tabindex="-1" aria-hidden="true"
|
||||||
|
style="position:absolute;left:-9999px;width:1px;height:1px;opacity:0" value="">
|
||||||
|
<select id="hp-po-xfer-ccy" aria-label="币种" autocomplete="off">
|
||||||
|
<option value="USDT" selected>USDT</option>
|
||||||
|
<option value="ETH">ETH</option>
|
||||||
|
<option value="BTC">BTC</option>
|
||||||
|
</select>
|
||||||
|
<select id="hp-po-xfer-dir" aria-label="划转方向" autocomplete="off">
|
||||||
|
<option value="funding_to_trading" selected>资金 → 交易</option>
|
||||||
|
<option value="trading_to_funding">交易 → 资金</option>
|
||||||
|
</select>
|
||||||
|
<input type="number" id="hp-po-xfer-amount" name="cm_hp_po_xfer_amt" min="0.01" step="any" placeholder="数量"
|
||||||
|
autocomplete="off" inputmode="decimal" data-lpignore="true" data-1p-ignore="true" data-bwignore="true" data-form-type="other" readonly />
|
||||||
|
<button type="button" class="btn-secondary btn-sm" id="hp-po-xfer-all">全部</button>
|
||||||
|
<button type="button" class="btn-primary btn-sm" id="hp-po-xfer-btn">划转</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 弹窗下单:宽屏左测算 / 右下单 -->
|
<!-- 弹窗下单:宽屏左测算 / 右下单 -->
|
||||||
<div id="hp-order-panel-host" class="opt-order-backdrop" hidden aria-hidden="true">
|
<div id="hp-order-panel-host" class="opt-order-backdrop" hidden aria-hidden="true">
|
||||||
@@ -208,9 +234,11 @@
|
|||||||
<div class="options-pos-head">
|
<div class="options-pos-head">
|
||||||
<h2>持仓</h2>
|
<h2>持仓</h2>
|
||||||
<div class="options-pos-head-actions">
|
<div class="options-pos-head-actions">
|
||||||
|
<button type="button" class="btn-secondary" id="hp-sell-coin-btn" title="市价卖出交易账户全部可用标的币(当前选中 ETH/BTC)换回 USDT">手动卖回币</button>
|
||||||
<button type="button" class="btn-secondary" id="hp-pos-refresh" title="刷新持仓与历史">刷新</button>
|
<button type="button" class="btn-secondary" id="hp-pos-refresh" title="刷新持仓与历史">刷新</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="muted" id="hp-sell-coin-msg" style="font-size:.72rem;margin:0 0 6px"></div>
|
||||||
<div class="options-pos-tabs" role="tablist" aria-label="永期持仓面板">
|
<div class="options-pos-tabs" role="tablist" aria-label="永期持仓面板">
|
||||||
<button type="button" class="btn-secondary opt-pos-tab hp-pos-tab active" data-hp-pos-tab="live" role="tab" aria-selected="true">当前持仓</button>
|
<button type="button" class="btn-secondary opt-pos-tab hp-pos-tab active" data-hp-pos-tab="live" role="tab" aria-selected="true">当前持仓</button>
|
||||||
<button type="button" class="btn-secondary opt-pos-tab hp-pos-tab" data-hp-pos-tab="plans" role="tab" aria-selected="false">对冲计划</button>
|
<button type="button" class="btn-secondary opt-pos-tab hp-pos-tab" data-hp-pos-tab="plans" role="tab" aria-selected="false">对冲计划</button>
|
||||||
@@ -466,4 +494,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="/static/hedge_plan.js?v=60"></script>
|
<script src="/static/hedge_plan.js?v=61"></script>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
|
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
|
||||||
<link rel="stylesheet" href="/static/account_risk_badge.css?v=4">
|
<link rel="stylesheet" href="/static/account_risk_badge.css?v=4">
|
||||||
<link rel="stylesheet" href="/static/instance_page.css?v=13">
|
<link rel="stylesheet" href="/static/instance_page.css?v=13">
|
||||||
<link rel="stylesheet" href="/static/instance_theme.css?v=120">
|
<link rel="stylesheet" href="/static/instance_theme.css?v=121">
|
||||||
<script src="/static/account_risk_badge.js?v=4"></script>
|
<script src="/static/account_risk_badge.js?v=4"></script>
|
||||||
<script src="/static/open_submit_gate.js?v=1"></script>
|
<script src="/static/open_submit_gate.js?v=1"></script>
|
||||||
<meta name="theme-color" content="#0b0d14">
|
<meta name="theme-color" content="#0b0d14">
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<link rel="manifest" href="/static/icons/manifest.webmanifest">
|
<link rel="manifest" href="/static/icons/manifest.webmanifest">
|
||||||
<title>{{ pwa_app_name }}</title>
|
<title>{{ pwa_app_name }}</title>
|
||||||
<link rel="stylesheet" href="/static/instance_page.css?v=13">
|
<link rel="stylesheet" href="/static/instance_page.css?v=13">
|
||||||
<link rel="stylesheet" href="/static/instance_theme.css?v=120">
|
<link rel="stylesheet" href="/static/instance_theme.css?v=121">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body
|
<body
|
||||||
|
|||||||
Reference in New Issue
Block a user