repo hygiene: track the PINK launcher import closure
67 production .py modules that the running PINK service imports but which were never committed: prod/bingx/ (HTTP client, market/user streams, journal, config), prod/clean_arch/ adapters/persistence/runtime/dita/dita_v2 production modules and their co-located tests. Rule going forward: every module imported by launch_dolphin_pink.py / pink_direct.py must appear in git ls-files. Excludes _backup dirs, __pycache__, and non-code files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
83
prod/bingx/leverage.py
Normal file
83
prod/bingx/leverage.py
Normal file
@@ -0,0 +1,83 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from decimal import Decimal
|
||||
from decimal import ROUND_HALF_EVEN
|
||||
from typing import Any
|
||||
|
||||
|
||||
CONVICTION_MIN = 0.5
|
||||
CONVICTION_MAX = 9.0
|
||||
EXCHANGE_LEV_MIN = 1
|
||||
EXCHANGE_LEV_MAX = 3
|
||||
LEVERAGE_MAPPING_RULE = "round_half_even_linear_0.5_to_9.0_to_1_to_exchange_cap"
|
||||
|
||||
|
||||
def _clamp_exchange_bounds(exchange_min: Any, exchange_max: Any) -> tuple[int, int]:
|
||||
lower = int(Decimal(str(exchange_min)))
|
||||
upper = int(Decimal(str(exchange_max)))
|
||||
if lower < 1:
|
||||
lower = 1
|
||||
if upper < lower:
|
||||
upper = lower
|
||||
return lower, upper
|
||||
|
||||
|
||||
def normalize_bingx_leverage_value(
|
||||
leverage: Any,
|
||||
*,
|
||||
exchange_min: Any = EXCHANGE_LEV_MIN,
|
||||
exchange_max: Any = EXCHANGE_LEV_MAX,
|
||||
) -> int:
|
||||
"""
|
||||
BingX exchange leverage is integer-only and conservatively capped.
|
||||
"""
|
||||
lower, upper = _clamp_exchange_bounds(exchange_min, exchange_max)
|
||||
desired = int(
|
||||
Decimal(str(leverage)).quantize(Decimal("1"), rounding=ROUND_HALF_EVEN)
|
||||
)
|
||||
if desired < lower:
|
||||
return lower
|
||||
if desired > upper:
|
||||
return upper
|
||||
return desired
|
||||
|
||||
|
||||
def map_internal_conviction_to_exchange_leverage_target(
|
||||
leverage: Any,
|
||||
*,
|
||||
exchange_min: Any = EXCHANGE_LEV_MIN,
|
||||
exchange_max: Any = EXCHANGE_LEV_MAX,
|
||||
) -> float:
|
||||
"""
|
||||
Map engine conviction/sizing into BingX exchange leverage.
|
||||
|
||||
The engine retains the fractional conviction signal internally. The exchange
|
||||
receives a leverage target derived from that signal.
|
||||
"""
|
||||
lower, upper = _clamp_exchange_bounds(exchange_min, exchange_max)
|
||||
internal = float(Decimal(str(leverage)))
|
||||
internal = max(CONVICTION_MIN, min(CONVICTION_MAX, internal))
|
||||
return float(lower + (
|
||||
(internal - CONVICTION_MIN) / (CONVICTION_MAX - CONVICTION_MIN)
|
||||
) * (upper - lower))
|
||||
|
||||
|
||||
def map_internal_conviction_to_exchange_leverage(
|
||||
leverage: Any,
|
||||
*,
|
||||
exchange_min: Any = EXCHANGE_LEV_MIN,
|
||||
exchange_max: Any = EXCHANGE_LEV_MAX,
|
||||
) -> int:
|
||||
"""
|
||||
Backwards-compatible integer exchange leverage mapper.
|
||||
"""
|
||||
target = map_internal_conviction_to_exchange_leverage_target(
|
||||
leverage,
|
||||
exchange_min=exchange_min,
|
||||
exchange_max=exchange_max,
|
||||
)
|
||||
return normalize_bingx_leverage_value(
|
||||
target,
|
||||
exchange_min=exchange_min,
|
||||
exchange_max=exchange_max,
|
||||
)
|
||||
Reference in New Issue
Block a user