Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions packages/loopx-finance-value-discovery/CONTRACT.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,31 @@ closed.

## Compatibility

### Contract exit liquidity / 合约退出流动性 (extension 0.8.0)

`finance_contract_liquidity_input_v0` is an additive Finance-owned contract.
It does not alter `finance_case_contract_v1`. The input freezes an instrument
reference, contract kind, quote unit, observation/evaluation timestamps,
freshness limit, cost and book-coverage limits, plus one or more amount- and
direction-specific exit scenarios. Scenarios are unique by position direction
and requested notional. The engine derives book coverage and total exit cost;
it does not accept provider-declared totals, readiness or disposition.

Venue-specific instrument discovery, tick/lot precision and book collection
remain adapter responsibilities. The public Finance contract rejects venue,
account, funding and investment-value fields. Its output records those
boundaries, labels venue semantics as `adapter_asserted`, and fixes both
`trading_allowed` and `automatic_ready_allowed` to false. Stale evidence cannot
become a negative liquidity conclusion.

`finance_contract_liquidity_input_v0` 是新增的 Finance 合约,不修改
`finance_case_contract_v1`。输入冻结合约引用、类型、报价单位、观察/评估时点、
新鲜度、成本和订单簿覆盖阈值,以及按持仓方向和退出金额区分的场景。场景按方向
与金额唯一;覆盖率和总退出成本由引擎计算,不接受 provider 自报总数、ready 或
裁决。场所侧合约发现、tick/lot 精度和订单簿采集仍归私有适配器。公共 Finance
合约拒绝场所、账户、资金费和投资价值字段,并固定不授予交易或自动 ready 权限;
过期证据不能伪装成负面的流动性结论。

The existing `finance_value_discovery_input_v0` reducer and
`finance_value_discovery_extension_v0` provider protocol remain supported.
`finance_case_gate_input_v1` now requires a `subject_ref` naming the case
Expand Down
44 changes: 44 additions & 0 deletions packages/loopx-finance-value-discovery/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,50 @@ Two P1 overlays reuse that contract without weakening it:
directions. They do not contain thresholds or evaluate provider-declared
pass/fail states.

Extension 0.8.0 adds `finance_contract_liquidity_input_v0`, a provider-neutral
exit-liquidity admission for derivatives. Venue adapters remain responsible for
contract identity, precision, book collection and evidence timestamps. Finance
evaluates each frozen position direction and requested notional against one
freshness window, minimum executable-book coverage and maximum derived exit
cost. Exit cost is the deterministic sum of spread, price impact and fees; a
provider cannot submit its own total or pass/fail decision. Long positions must
use a sell exit and short positions a buy exit.

The result is deliberately independent of investment value and funding. Those
fields, venue names and account material are rejected rather than folded into
the liquidity decision. A fresh passing result means only
`eligible_for_research_successor`; it never creates a ready candidate or grants
order, signing or transfer authority. Stale measurements are
`insufficient_evidence`, while fresh amount/cost failures are
`insufficient_liquidity`.

0.8.0 新增 `finance_contract_liquidity_input_v0`,用于对衍生品退出流动性做
provider-neutral 准入。私有场所适配器继续负责合约身份、精度、订单簿采集和
证据时间;Finance 只按持仓方向与申请退出金额,使用冻结的新鲜度、可执行订单簿
覆盖率和最大退出成本阈值进行确定性判断。退出成本由点差、价格冲击和手续费相加
得到,不接受 provider 自报总成本或通过/失败;多头必须卖出退出,空头必须买入
退出。

该判断与投资价值和资金费明确隔离,相关字段、场所名称和账户材料会被拒绝,而
不是混入流动性结论。通过只表示可以进入下一段研究,不能升级 ready,更不授权
下单、签名或转账;过期测量是证据不足,新鲜但金额或成本不满足才是流动性不足。

Run the same contract through the direct CLI or managed extension runtime:

```bash
loopx-finance-value-discovery evaluate-contract-liquidity \
--input-json packages/loopx-finance-value-discovery/examples/contract-liquidity-v0.json

loopx extension run loopx-finance-value-discovery \
--input-json packages/loopx-finance-value-discovery/examples/contract-liquidity-v0.json \
--execute --format json
```

This slice changes the CLI/managed-Turn contract only. Dashboard and Lark must
consume the same evaluation in their separately owned projection slice; until
that lands, this backend delivery is intentionally partial rather than an
end-to-end visual release.

The packet enforces:

- a cross-sectional screen before a named candidate is selected;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"schema_version": "finance_contract_liquidity_input_v0",
"evaluation_id": "synthetic-perp-exit-2026-01-15",
"instrument_ref": "synthetic-perpetual",
"contract_kind": "perpetual",
"quote_unit": "USD",
"observed_at": "2026-01-15T12:00:00Z",
"evaluation_as_of": "2026-01-15T12:00:30Z",
"maximum_age_seconds": 120,
"maximum_exit_cost_bps": "25",
"minimum_book_coverage_ratio": "1",
"scenarios": [
{
"scenario_id": "close-long-1000",
"position_direction": "long",
"exit_side": "sell",
"requested_notional": "1000",
"executable_notional": "1200",
"spread_bps": "2",
"price_impact_bps": "4.5",
"fee_bps": "5",
"evidence_refs": ["public-book:snapshot-001"]
},
{
"scenario_id": "close-short-1000",
"position_direction": "short",
"exit_side": "buy",
"requested_notional": "1000",
"executable_notional": "1100",
"spread_bps": "2.2",
"price_impact_bps": "5.1",
"fee_bps": "5",
"evidence_refs": ["public-book:snapshot-001"]
}
]
}
2 changes: 1 addition & 1 deletion packages/loopx-finance-value-discovery/extension.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
schema_version = "loopx_extension_manifest_v0"
id = "loopx-finance-value-discovery"
version = "0.7.0"
version = "0.8.0"
requires_loopx_api = ">=1,<2"
permissions = []

Expand Down
2 changes: 1 addition & 1 deletion packages/loopx-finance-value-discovery/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "loopx-finance-value-discovery"
version = "0.7.0"
version = "0.8.0"
description = "Public-safe finance value-discovery extension for LoopX."
readme = "README.md"
requires-python = ">=3.11"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
FINANCE_CASE_INPUT_SCHEMA_VERSION,
validate_finance_case_contract,
)
from .contract_liquidity import (
FINANCE_CONTRACT_LIQUIDITY_EVALUATION_SCHEMA_VERSION,
FINANCE_CONTRACT_LIQUIDITY_INPUT_SCHEMA_VERSION,
evaluate_finance_contract_liquidity,
)
from .gates import evaluate_finance_case_gates
from .metric_packs import (
FINANCE_METRIC_PACK_EVALUATION_SCHEMA_VERSION,
Expand Down Expand Up @@ -55,6 +60,8 @@
"FINANCE_CASE_EVALUATION_SCHEMA_VERSION",
"FINANCE_CASE_INPUT_SCHEMA_VERSION",
"FINANCE_CASE_REPLAY_RECEIPT_SCHEMA_VERSION",
"FINANCE_CONTRACT_LIQUIDITY_EVALUATION_SCHEMA_VERSION",
"FINANCE_CONTRACT_LIQUIDITY_INPUT_SCHEMA_VERSION",
"FINANCE_METRIC_PACK_EVALUATION_SCHEMA_VERSION",
"FINANCE_METRIC_PACK_INPUT_SCHEMA_VERSION",
"FINANCE_METRIC_PACK_REPLAY_SCHEMA_VERSION",
Expand All @@ -73,6 +80,7 @@
"build_finance_transaction_approval_packet",
"build_finance_value_discovery_packet",
"evaluate_finance_case_gates",
"evaluate_finance_contract_liquidity",
"list_finance_metric_packs",
"render_finance_value_discovery_markdown",
"replay_finance_beta_attribution",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
replay_finance_beta_attribution,
)
from .contract import FINANCE_CASE_INPUT_SCHEMA_VERSION
from .contract_liquidity import (
FINANCE_CONTRACT_LIQUIDITY_INPUT_SCHEMA_VERSION,
evaluate_finance_contract_liquidity,
)
from .metric_packs import (
FINANCE_METRIC_PACK_INPUT_SCHEMA_VERSION,
build_finance_metric_pack_evaluation,
Expand Down Expand Up @@ -137,6 +141,14 @@ def _direct_parser() -> argparse.ArgumentParser:
action="store_true",
help="Print only the canonical loopx_operation_request_v0 object.",
)
liquidity_parser = sub.add_parser(
"evaluate-contract-liquidity",
help=(
"Evaluate amount- and direction-specific derivatives exit "
"liquidity from frozen provider measurements."
),
)
liquidity_parser.add_argument("--input-json", required=True)
sub.add_parser("list-packs", help="List bundled industry metric packs.")
lark_parser = sub.add_parser(
"render-lark-card",
Expand Down Expand Up @@ -170,6 +182,8 @@ def run(argv: Sequence[str] | None = None) -> int:
packet = build_finance_research_dashboard_packet(payload)
elif schema_version == FINANCE_TRANSACTION_APPROVAL_INPUT_SCHEMA_VERSION:
packet = build_finance_transaction_approval_packet(payload)
elif schema_version == FINANCE_CONTRACT_LIQUIDITY_INPUT_SCHEMA_VERSION:
packet = evaluate_finance_contract_liquidity(payload)
else:
packet = build_finance_value_discovery_packet(payload)
except Exception as exc:
Expand Down Expand Up @@ -212,6 +226,10 @@ def run(argv: Sequence[str] | None = None) -> int:
packet = build_finance_transaction_approval_packet(
_load_json(args.input_json)
)
elif args.command == "evaluate-contract-liquidity":
packet = evaluate_finance_contract_liquidity(
_load_json(args.input_json)
)
elif args.command == "list-packs":
packet = list_finance_metric_packs()
elif args.command == "render-lark-card":
Expand All @@ -228,7 +246,8 @@ def run(argv: Sequence[str] | None = None) -> int:
raise ValueError(
"use --doctor, reduce, evaluate, replay, attribute-beta, "
"replay-beta, evaluate-pack, replay-pack, list-packs, "
"render-lark-card, or build-operation-request"
"render-lark-card, build-operation-request, or "
"evaluate-contract-liquidity"
)
except Exception as exc:
print(json.dumps(_error_packet(exc), indent=2, sort_keys=True))
Expand Down
Loading
Loading