Split OO budget per leg and size Call/Put independently.

Each half of the risk budget buys its own qty from ask; equal qty no longer forced.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-07 17:08:05 +08:00
parent 24943adf13
commit 24a860ad3f
11 changed files with 210 additions and 110 deletions
+30 -13
View File
@@ -743,18 +743,19 @@ class BinanceLiveExecutor(Matcher):
s = live_settings()
client = self._client()
opt_qty = self.ledger.get_setting_float("option_qty_eth", s.option_qty_eth)
call_qty = self.ledger.get_setting_float("option_qty_eth", s.option_qty_eth)
put_qty = self.ledger.get_setting_float("oo_put_qty_eth", call_qty)
call_ct = self._ct_mult(call_inst_id)
put_ct = self._ct_mult(put_inst_id)
call_contracts = contracts_for_eth(opt_qty, call_ct)
put_contracts = contracts_for_eth(opt_qty, put_ct)
call_contracts = contracts_for_eth(call_qty, call_ct)
put_contracts = contracts_for_eth(put_qty, put_ct)
stamp_opening_intent(
self.db,
group_id=group_id,
option_inst_id=call_inst_id,
option_side="call",
perp_side=f"oo_put:{put_inst_id}",
option_qty_eth=opt_qty,
option_qty_eth=call_qty,
option_qty_contracts=float(call_contracts),
entry_index_px=entry_index_px,
)
@@ -771,8 +772,8 @@ class BinanceLiveExecutor(Matcher):
if call_fill.sz and call_fill.sz > 0
else float(call_contracts)
)
opt_qty = eth_from_contracts(call_contracts, call_ct)
put_contracts = contracts_for_eth(opt_qty, put_ct)
call_qty = eth_from_contracts(call_contracts, call_ct)
put_contracts = contracts_for_eth(put_qty, put_ct)
try:
put_fill = client.place_option_market(
symbol=put_inst_id, side="BUY", quantity=put_contracts
@@ -798,9 +799,9 @@ class BinanceLiveExecutor(Matcher):
)
of_px = float(call_fill.avg_px)
pf_px = float(put_fill.avg_px)
qty2 = eth_from_contracts(put_contracts, put_ct)
call_prem = of_px * opt_qty
put_prem = pf_px * qty2
put_qty = eth_from_contracts(put_contracts, put_ct)
call_prem = of_px * call_qty
put_prem = pf_px * put_qty
now = int(time.time() * 1000)
with self.db._lock:
self.db._conn.execute(
@@ -834,8 +835,24 @@ class BinanceLiveExecutor(Matcher):
),
)
for leg, inst, contracts, fill_px, fee, ts, q in (
("option", call_inst_id, call_contracts, of_px, getattr(call_fill, "fee", 0), now, opt_qty),
("option2", put_inst_id, put_contracts, pf_px, getattr(put_fill, "fee", 0), now + 1, qty2),
(
"option",
call_inst_id,
call_contracts,
of_px,
getattr(call_fill, "fee", 0),
now,
call_qty,
),
(
"option2",
put_inst_id,
put_contracts,
pf_px,
getattr(put_fill, "fee", 0),
now + 1,
put_qty,
),
):
self.db._conn.execute(
"""INSERT INTO fills(group_id, leg, action, side, inst_id, qty_eth, qty_contracts,
@@ -870,13 +887,13 @@ class BinanceLiveExecutor(Matcher):
(
group_id,
call_inst_id,
opt_qty,
call_qty,
call_contracts,
of_px,
entry_index_px,
call_prem,
put_inst_id,
qty2,
put_qty,
put_contracts,
pf_px,
float(put_strike),
+33 -16
View File
@@ -771,18 +771,19 @@ class OkxLiveExecutor(Matcher):
s = live_settings()
client = self._client()
opt_qty = self.ledger.get_setting_float("option_qty_eth", s.option_qty_eth)
call_qty = self.ledger.get_setting_float("option_qty_eth", s.option_qty_eth)
put_qty = self.ledger.get_setting_float("oo_put_qty_eth", call_qty)
call_ct = self._ct_mult(call_inst_id)
put_ct = self._ct_mult(put_inst_id)
call_contracts = contracts_for_eth(opt_qty, call_ct)
put_contracts = contracts_for_eth(opt_qty, put_ct)
call_contracts = contracts_for_eth(call_qty, call_ct)
put_contracts = contracts_for_eth(put_qty, put_ct)
stamp_opening_intent(
self.db,
group_id=group_id,
option_inst_id=call_inst_id,
option_side="call",
perp_side=f"oo_put:{put_inst_id}",
option_qty_eth=opt_qty,
option_qty_eth=call_qty,
option_qty_contracts=float(call_contracts),
entry_index_px=entry_index_px,
)
@@ -804,8 +805,9 @@ class OkxLiveExecutor(Matcher):
if call_fill.sz and call_fill.sz > 0
else float(int(round(call_contracts)))
)
opt_qty = eth_from_contracts(call_contracts, call_ct)
put_contracts = contracts_for_eth(opt_qty, put_ct)
call_qty = eth_from_contracts(call_contracts, call_ct)
# Put 用独立定仓数量,不跟 Call 成交量对齐
put_contracts = contracts_for_eth(put_qty, put_ct)
try:
put_fill = client.place_market(
inst_id=put_inst_id,
@@ -838,10 +840,10 @@ class OkxLiveExecutor(Matcher):
)
of_px = float(call_fill.avg_px)
pf_px = float(put_fill.avg_px)
call_prem = of_px * opt_qty
put_prem = pf_px * eth_from_contracts(put_contracts, put_ct)
# 等量:以 Call 成交名义为准
qty2 = eth_from_contracts(put_contracts, put_ct)
call_qty = eth_from_contracts(call_contracts, call_ct)
put_qty = eth_from_contracts(put_contracts, put_ct)
call_prem = of_px * call_qty
put_prem = pf_px * put_qty
now = int(time.time() * 1000)
with self.db._lock:
self.db._conn.execute(
@@ -874,11 +876,26 @@ class OkxLiveExecutor(Matcher):
put_prem,
),
)
for leg, inst, contracts, fill_px, fee, ts in (
("option", call_inst_id, call_contracts, of_px, getattr(call_fill, "fee", 0), now),
("option2", put_inst_id, put_contracts, pf_px, getattr(put_fill, "fee", 0), now + 1),
for leg, inst, contracts, fill_px, fee, ts, q in (
(
"option",
call_inst_id,
call_contracts,
of_px,
getattr(call_fill, "fee", 0),
now,
call_qty,
),
(
"option2",
put_inst_id,
put_contracts,
pf_px,
getattr(put_fill, "fee", 0),
now + 1,
put_qty,
),
):
q = opt_qty if leg == "option" else qty2
self.db._conn.execute(
"""INSERT INTO fills(group_id, leg, action, side, inst_id, qty_eth, qty_contracts,
base_px, fill_px, fee, slip, notional, ts_ms, exec_mode)
@@ -912,13 +929,13 @@ class OkxLiveExecutor(Matcher):
(
group_id,
call_inst_id,
opt_qty,
call_qty,
call_contracts,
of_px,
entry_index_px,
call_prem,
put_inst_id,
qty2,
put_qty,
put_contracts,
pf_px,
float(put_strike),