refactor: 将共用代码迁入 lib/ 模块化目录
统一 strategy、key_monitor、trade、hub 等共用库到 lib/ 子包,并补充 lib-structure 文档,便于四所与中控维护。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,94 +1,94 @@
|
||||
"""子代理持仓:四所标记价字段统一解析。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT / "manual_trading_hub"))
|
||||
|
||||
from agent import _position_mark_price, _ticker_mark_price # noqa: E402
|
||||
|
||||
sys.path.insert(0, str(ROOT))
|
||||
from hub_position_metrics import ( # noqa: E402
|
||||
enrich_ccxt_position_metrics_out,
|
||||
estimate_linear_swap_upnl_usdt,
|
||||
parse_position_unrealized_pnl,
|
||||
resolve_position_display_upnl,
|
||||
)
|
||||
|
||||
|
||||
class TestHubAgentMarkPrice(unittest.TestCase):
|
||||
def test_binance_mark_price(self):
|
||||
px = _position_mark_price({"markPrice": 65880.1, "info": {}})
|
||||
self.assertAlmostEqual(px, 65880.1)
|
||||
|
||||
def test_okx_mark_px(self):
|
||||
px = _position_mark_price({"info": {"markPx": "72.85"}})
|
||||
self.assertAlmostEqual(px, 72.85)
|
||||
|
||||
def test_gate_info_mark(self):
|
||||
px = _position_mark_price({"info": {"mark_price": "0.2241"}})
|
||||
self.assertAlmostEqual(px, 0.2241)
|
||||
|
||||
def test_missing_returns_none(self):
|
||||
self.assertIsNone(_position_mark_price({"info": {}}))
|
||||
|
||||
def test_infer_from_notional_and_contracts(self):
|
||||
p = {"notional": 1000, "contracts": 10, "info": {}}
|
||||
px = _position_mark_price(p)
|
||||
self.assertAlmostEqual(px, 100.0)
|
||||
|
||||
def test_ticker_fallback(self):
|
||||
class _Ex:
|
||||
def fetch_ticker(self, sym):
|
||||
return {"mark": 99.5, "info": {}}
|
||||
|
||||
self.assertAlmostEqual(_ticker_mark_price(_Ex(), "BTC/USDT:USDT"), 99.5)
|
||||
|
||||
def test_gate_unrealised_pnl_in_info(self):
|
||||
pnl = parse_position_unrealized_pnl(
|
||||
{"info": {"unrealised_pnl": "6.81"}, "unrealizedPnl": None}
|
||||
)
|
||||
self.assertAlmostEqual(pnl, 6.81)
|
||||
|
||||
def test_okx_upl_signed(self):
|
||||
pnl = parse_position_unrealized_pnl(
|
||||
{"info": {"upl": "-2.15"}, "unrealizedPnl": None}
|
||||
)
|
||||
self.assertAlmostEqual(pnl, -2.15)
|
||||
|
||||
def test_enrich_aligns_short_gate_metrics(self):
|
||||
pos = {
|
||||
"side": "short",
|
||||
"contracts": 11,
|
||||
"entryPrice": 73.187,
|
||||
"markPrice": 66.038,
|
||||
"info": {"unrealised_pnl": "7.86"},
|
||||
}
|
||||
out = {"unrealized_pnl": 7.86, "mark_price": 66.038}
|
||||
enrich_ccxt_position_metrics_out(pos, out, contract_size=1.0, funds_decimals=2)
|
||||
self.assertGreater(out["unrealized_pnl"], 70.0)
|
||||
|
||||
def test_estimate_short_hype_contract_size(self):
|
||||
upnl = estimate_linear_swap_upnl_usdt(
|
||||
"short", 73.187, 66.038, 11, 0.1
|
||||
)
|
||||
self.assertAlmostEqual(upnl, 7.86, places=1)
|
||||
|
||||
def test_resolve_prefers_computed_when_exchange_off(self):
|
||||
shown = resolve_position_display_upnl(
|
||||
"short", 73.187, 66.038, 11, 1.0, 7.86
|
||||
)
|
||||
self.assertAlmostEqual(shown, 78.64, places=1)
|
||||
|
||||
def test_resolve_keeps_exchange_when_aligned(self):
|
||||
shown = resolve_position_display_upnl(
|
||||
"short", 73.187, 66.038, 11, 0.1, 7.86
|
||||
)
|
||||
self.assertAlmostEqual(shown, 7.86, places=2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
"""子代理持仓:四所标记价字段统一解析。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT / "manual_trading_hub"))
|
||||
|
||||
from agent import _position_mark_price, _ticker_mark_price # noqa: E402
|
||||
|
||||
sys.path.insert(0, str(ROOT))
|
||||
from lib.hub.hub_position_metrics import ( # noqa: E402
|
||||
enrich_ccxt_position_metrics_out,
|
||||
estimate_linear_swap_upnl_usdt,
|
||||
parse_position_unrealized_pnl,
|
||||
resolve_position_display_upnl,
|
||||
)
|
||||
|
||||
|
||||
class TestHubAgentMarkPrice(unittest.TestCase):
|
||||
def test_binance_mark_price(self):
|
||||
px = _position_mark_price({"markPrice": 65880.1, "info": {}})
|
||||
self.assertAlmostEqual(px, 65880.1)
|
||||
|
||||
def test_okx_mark_px(self):
|
||||
px = _position_mark_price({"info": {"markPx": "72.85"}})
|
||||
self.assertAlmostEqual(px, 72.85)
|
||||
|
||||
def test_gate_info_mark(self):
|
||||
px = _position_mark_price({"info": {"mark_price": "0.2241"}})
|
||||
self.assertAlmostEqual(px, 0.2241)
|
||||
|
||||
def test_missing_returns_none(self):
|
||||
self.assertIsNone(_position_mark_price({"info": {}}))
|
||||
|
||||
def test_infer_from_notional_and_contracts(self):
|
||||
p = {"notional": 1000, "contracts": 10, "info": {}}
|
||||
px = _position_mark_price(p)
|
||||
self.assertAlmostEqual(px, 100.0)
|
||||
|
||||
def test_ticker_fallback(self):
|
||||
class _Ex:
|
||||
def fetch_ticker(self, sym):
|
||||
return {"mark": 99.5, "info": {}}
|
||||
|
||||
self.assertAlmostEqual(_ticker_mark_price(_Ex(), "BTC/USDT:USDT"), 99.5)
|
||||
|
||||
def test_gate_unrealised_pnl_in_info(self):
|
||||
pnl = parse_position_unrealized_pnl(
|
||||
{"info": {"unrealised_pnl": "6.81"}, "unrealizedPnl": None}
|
||||
)
|
||||
self.assertAlmostEqual(pnl, 6.81)
|
||||
|
||||
def test_okx_upl_signed(self):
|
||||
pnl = parse_position_unrealized_pnl(
|
||||
{"info": {"upl": "-2.15"}, "unrealizedPnl": None}
|
||||
)
|
||||
self.assertAlmostEqual(pnl, -2.15)
|
||||
|
||||
def test_enrich_aligns_short_gate_metrics(self):
|
||||
pos = {
|
||||
"side": "short",
|
||||
"contracts": 11,
|
||||
"entryPrice": 73.187,
|
||||
"markPrice": 66.038,
|
||||
"info": {"unrealised_pnl": "7.86"},
|
||||
}
|
||||
out = {"unrealized_pnl": 7.86, "mark_price": 66.038}
|
||||
enrich_ccxt_position_metrics_out(pos, out, contract_size=1.0, funds_decimals=2)
|
||||
self.assertGreater(out["unrealized_pnl"], 70.0)
|
||||
|
||||
def test_estimate_short_hype_contract_size(self):
|
||||
upnl = estimate_linear_swap_upnl_usdt(
|
||||
"short", 73.187, 66.038, 11, 0.1
|
||||
)
|
||||
self.assertAlmostEqual(upnl, 7.86, places=1)
|
||||
|
||||
def test_resolve_prefers_computed_when_exchange_off(self):
|
||||
shown = resolve_position_display_upnl(
|
||||
"short", 73.187, 66.038, 11, 1.0, 7.86
|
||||
)
|
||||
self.assertAlmostEqual(shown, 78.64, places=1)
|
||||
|
||||
def test_resolve_keeps_exchange_when_aligned(self):
|
||||
shown = resolve_position_display_upnl(
|
||||
"short", 73.187, 66.038, 11, 0.1, 7.86
|
||||
)
|
||||
self.assertAlmostEqual(shown, 7.86, places=2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user