修复gate盈亏比
This commit is contained in:
@@ -1827,6 +1827,10 @@ def calc_pnl(direction, trigger_price, exit_price, margin_capital, leverage):
|
|||||||
|
|
||||||
|
|
||||||
def calc_rr_ratio(direction, entry_price, stop_loss, take_profit):
|
def calc_rr_ratio(direction, entry_price, stop_loss, take_profit):
|
||||||
|
"""
|
||||||
|
计划盈亏比 = 盈利空间 / 亏损空间(展示为 X:1,即 reward:risk)。
|
||||||
|
做多:止损须低于入场、止盈须高于入场;做空相反。
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
entry = float(entry_price)
|
entry = float(entry_price)
|
||||||
sl = float(stop_loss)
|
sl = float(stop_loss)
|
||||||
@@ -1846,6 +1850,17 @@ def calc_rr_ratio(direction, entry_price, stop_loss, take_profit):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def active_sl_tp_for_rr(stop_loss, initial_stop_loss, take_profit):
|
||||||
|
"""展示/校验用:优先当前 stop_loss(委托改价后),否则回落 initial_stop_loss。"""
|
||||||
|
sl = stop_loss if stop_loss not in (None, "") else initial_stop_loss
|
||||||
|
return sl, take_profit
|
||||||
|
|
||||||
|
|
||||||
|
def calc_planned_rr_ratio(direction, entry_price, stop_loss, initial_stop_loss, take_profit):
|
||||||
|
sl, tp = active_sl_tp_for_rr(stop_loss, initial_stop_loss, take_profit)
|
||||||
|
return calc_rr_ratio(direction, entry_price, sl, tp)
|
||||||
|
|
||||||
|
|
||||||
def calc_risk_fraction(direction, entry_price, stop_loss):
|
def calc_risk_fraction(direction, entry_price, stop_loss):
|
||||||
try:
|
try:
|
||||||
entry = float(entry_price)
|
entry = float(entry_price)
|
||||||
@@ -2009,10 +2024,11 @@ def enrich_order_item(raw_item, current_capital):
|
|||||||
ratio = round(margin / current_capital * 100, 2) if current_capital else 0
|
ratio = round(margin / current_capital * 100, 2) if current_capital else 0
|
||||||
item["notional_value"] = notional
|
item["notional_value"] = notional
|
||||||
item["position_ratio"] = ratio
|
item["position_ratio"] = ratio
|
||||||
item["rr_ratio"] = calc_rr_ratio(
|
item["rr_ratio"] = calc_planned_rr_ratio(
|
||||||
item.get("direction") or "long",
|
item.get("direction") or "long",
|
||||||
item.get("trigger_price"),
|
item.get("trigger_price"),
|
||||||
item.get("initial_stop_loss") or item.get("stop_loss"),
|
item.get("stop_loss"),
|
||||||
|
item.get("initial_stop_loss"),
|
||||||
item.get("take_profit"),
|
item.get("take_profit"),
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
@@ -4980,7 +4996,13 @@ def api_price_snapshot():
|
|||||||
entry = float(r["trigger_price"] or 0)
|
entry = float(r["trigger_price"] or 0)
|
||||||
pnl = calc_pnl(r["direction"], entry, price, margin, leverage) if entry > 0 else 0
|
pnl = calc_pnl(r["direction"], entry, price, margin, leverage) if entry > 0 else 0
|
||||||
pnl_pct = round((pnl / margin * 100), 4) if margin > 0 else 0
|
pnl_pct = round((pnl / margin * 100), 4) if margin > 0 else 0
|
||||||
rr_ratio = calc_rr_ratio(r["direction"], entry, r["initial_stop_loss"] or r["stop_loss"], r["take_profit"])
|
rr_ratio = calc_planned_rr_ratio(
|
||||||
|
r["direction"],
|
||||||
|
entry,
|
||||||
|
r["stop_loss"],
|
||||||
|
r["initial_stop_loss"],
|
||||||
|
r["take_profit"],
|
||||||
|
)
|
||||||
ex_sym = resolve_monitor_exchange_symbol(r)
|
ex_sym = resolve_monitor_exchange_symbol(r)
|
||||||
prow = _select_live_position_row(all_swap_positions, ex_sym, r["direction"])
|
prow = _select_live_position_row(all_swap_positions, ex_sym, r["direction"])
|
||||||
lev_row = r["leverage"] if "leverage" in r.keys() else None
|
lev_row = r["leverage"] if "leverage" in r.keys() else None
|
||||||
@@ -5095,13 +5117,16 @@ def api_order_defaults():
|
|||||||
exchange_symbol = normalize_okx_symbol(symbol)
|
exchange_symbol = normalize_okx_symbol(symbol)
|
||||||
leverage = get_synced_leverage(exchange_symbol, direction) or infer_leverage(symbol)
|
leverage = get_synced_leverage(exchange_symbol, direction) or infer_leverage(symbol)
|
||||||
available = get_available_trading_usdt()
|
available = get_available_trading_usdt()
|
||||||
|
last_price = get_price(symbol)
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"ok": True,
|
"ok": True,
|
||||||
"symbol": symbol,
|
"symbol": symbol,
|
||||||
"exchange_symbol": exchange_symbol,
|
"exchange_symbol": exchange_symbol,
|
||||||
"direction": direction,
|
"direction": direction,
|
||||||
"leverage": leverage,
|
"leverage": leverage,
|
||||||
"available_trading_usdt": round(available, 4) if available is not None else None
|
"available_trading_usdt": round(available, 4) if available is not None else None,
|
||||||
|
"last_price": round(float(last_price), 8) if last_price is not None else None,
|
||||||
|
"price": round(float(last_price), 8) if last_price is not None else None,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1865,17 +1865,19 @@ if(addOrderForm){
|
|||||||
}
|
}
|
||||||
const sl = Number((document.getElementById("order-sl")||{}).value);
|
const sl = Number((document.getElementById("order-sl")||{}).value);
|
||||||
const tp = Number((document.getElementById("order-tp")||{}).value);
|
const tp = Number((document.getElementById("order-tp")||{}).value);
|
||||||
let entry = sl;
|
|
||||||
if(!symbol){
|
if(!symbol){
|
||||||
if(rejectManualOrderRr(calcClientRr(direction, entry, sl, tp))) return;
|
alert("请先填写币种,以便按市价校验盈亏比");
|
||||||
allowManualOrderSubmit(addOrderForm);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fetch(`/api/order_defaults?symbol=${encodeURIComponent(symbol)}&direction=${encodeURIComponent(direction)}`)
|
fetch(`/api/order_defaults?symbol=${encodeURIComponent(symbol)}&direction=${encodeURIComponent(direction)}`)
|
||||||
.then(r=>r.json())
|
.then(r=>r.json())
|
||||||
.then(data=>{
|
.then(data=>{
|
||||||
const px = data.last_price || data.price;
|
const px = data.last_price ?? data.price;
|
||||||
if(px) entry = Number(px);
|
const entry = Number(px);
|
||||||
|
if(!Number.isFinite(entry) || entry <= 0){
|
||||||
|
alert("无法获取市价,请稍后重试");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(rejectManualOrderRr(calcClientRr(direction, entry, sl, tp))) return;
|
if(rejectManualOrderRr(calcClientRr(direction, entry, sl, tp))) return;
|
||||||
allowManualOrderSubmit(addOrderForm);
|
allowManualOrderSubmit(addOrderForm);
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -143,7 +143,8 @@ function paintOrder(order){
|
|||||||
document.getElementById("m-entry").innerText = fmt(order.trigger_price, 8);
|
document.getElementById("m-entry").innerText = fmt(order.trigger_price, 8);
|
||||||
document.getElementById("m-sl").innerText = fmt(order.stop_loss, 8);
|
document.getElementById("m-sl").innerText = fmt(order.stop_loss, 8);
|
||||||
document.getElementById("m-tp").innerText = fmt(order.take_profit, 8);
|
document.getElementById("m-tp").innerText = fmt(order.take_profit, 8);
|
||||||
document.getElementById("m-rr").innerText = (order.rr_ratio === null || typeof order.rr_ratio === "undefined") ? "-" : `1:${Number(order.rr_ratio).toFixed(2)}`;
|
const rr = order.rr_ratio;
|
||||||
|
document.getElementById("m-rr").innerText = (rr === null || typeof rr === "undefined") ? "-:1" : `${Number(rr).toFixed(2)}:1`;
|
||||||
document.getElementById("m-price").innerText = fmt(order.current_price, 8);
|
document.getElementById("m-price").innerText = fmt(order.current_price, 8);
|
||||||
const pnlEl = document.getElementById("m-pnl");
|
const pnlEl = document.getElementById("m-pnl");
|
||||||
pnlEl.innerText = `${fmt(order.float_pnl, 4)}U (${fmt(order.float_pct, 2)}%)`;
|
pnlEl.innerText = `${fmt(order.float_pnl, 4)}U (${fmt(order.float_pct, 2)}%)`;
|
||||||
|
|||||||
@@ -143,7 +143,8 @@ function paintOrder(order){
|
|||||||
document.getElementById("m-entry").innerText = fmt(order.trigger_price, 8);
|
document.getElementById("m-entry").innerText = fmt(order.trigger_price, 8);
|
||||||
document.getElementById("m-sl").innerText = fmt(order.stop_loss, 8);
|
document.getElementById("m-sl").innerText = fmt(order.stop_loss, 8);
|
||||||
document.getElementById("m-tp").innerText = fmt(order.take_profit, 8);
|
document.getElementById("m-tp").innerText = fmt(order.take_profit, 8);
|
||||||
document.getElementById("m-rr").innerText = (order.rr_ratio === null || typeof order.rr_ratio === "undefined") ? "-" : `1:${Number(order.rr_ratio).toFixed(2)}`;
|
const rr = order.rr_ratio;
|
||||||
|
document.getElementById("m-rr").innerText = (rr === null || typeof rr === "undefined") ? "-:1" : `${Number(rr).toFixed(2)}:1`;
|
||||||
document.getElementById("m-price").innerText = fmt(order.current_price, 8);
|
document.getElementById("m-price").innerText = fmt(order.current_price, 8);
|
||||||
const pnlEl = document.getElementById("m-pnl");
|
const pnlEl = document.getElementById("m-pnl");
|
||||||
pnlEl.innerText = `${fmt(order.float_pnl, 4)}U (${fmt(order.float_pct, 2)}%)`;
|
pnlEl.innerText = `${fmt(order.float_pnl, 4)}U (${fmt(order.float_pct, 2)}%)`;
|
||||||
|
|||||||
Reference in New Issue
Block a user