Files
quant-os/schemas/broker_snapshot.schema.json

237 lines
5.4 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://boat.local/quant60/schemas/broker_snapshot.schema.json",
"title": "Quant60 broker snapshot",
"description": "A point-in-time broker fact used for pre-trade and reconciliation.",
"type": "object",
"additionalProperties": false,
"required": [
"schema_version",
"snapshot_id",
"signal_as_of",
"next_trading_session",
"first_executable_window",
"observation_as_of",
"as_of",
"source_time",
"broker",
"account_hash",
"cash",
"total_asset",
"positions",
"open_orders"
],
"properties": {
"schema_version": {
"const": "1.0"
},
"snapshot_id": {
"type": "string",
"minLength": 1
},
"as_of": {
"type": "string",
"format": "date-time",
"description": "Broker observation completion time. This may be later than the signal close when the snapshot is queried on the next executable session."
},
"observation_as_of": {
"type": "string",
"format": "date-time",
"description": "Explicit observation-clock alias for as_of. Account-bound decision paths require the two instants to be equal."
},
"signal_as_of": {
"type": "string",
"format": "date-time",
"description": "Required completed signal-close clock this snapshot is intended to bind."
},
"next_trading_session": {
"type": "string",
"format": "date",
"description": "The unique adjacent trading session from the verified decision calendar."
},
"first_executable_window": {
"$ref": "#/$defs/first_executable_window"
},
"broker": {
"type": "string",
"minLength": 1
},
"account_hash": {
"type": "string",
"minLength": 8,
"description": "One-way account identifier; never store the raw account number."
},
"cash": {
"type": "number",
"minimum": 0
},
"total_asset": {
"type": "number",
"minimum": 0
},
"market_value": {
"type": "number",
"minimum": 0
},
"positions": {
"type": "array",
"items": {
"$ref": "#/$defs/position"
}
},
"open_orders": {
"type": "array",
"items": {
"$ref": "#/$defs/open_order"
}
},
"source_time": {
"type": "string",
"format": "date-time",
"description": "Timestamp assigned to the broker facts; it must not predate the bound signal and must remain fresh relative to the observation clock."
},
"metadata": {
"type": "object"
}
},
"$defs": {
"first_executable_window": {
"type": "object",
"additionalProperties": false,
"required": [
"session",
"timezone",
"start",
"end",
"boundary",
"purpose"
],
"properties": {
"session": {
"type": "string",
"format": "date"
},
"timezone": {
"const": "Asia/Shanghai"
},
"start": {
"type": "string",
"format": "date-time"
},
"end": {
"type": "string",
"format": "date-time"
},
"boundary": {
"const": "[start,end)"
},
"purpose": {
"const": "PRE_OPEN_BROKER_OBSERVATION"
}
}
},
"canonical_symbol": {
"type": "string",
"pattern": "^[0-9]{6}\\.(XSHG|XSHE|XBSE)$"
},
"position": {
"type": "object",
"additionalProperties": false,
"required": [
"symbol",
"quantity",
"sellable_quantity"
],
"properties": {
"symbol": {
"$ref": "#/$defs/canonical_symbol"
},
"quantity": {
"type": "integer",
"minimum": 0
},
"sellable_quantity": {
"type": "integer",
"minimum": 0
},
"average_cost": {
"type": [
"number",
"null"
],
"minimum": 0
},
"market_value": {
"type": [
"number",
"null"
],
"minimum": 0
}
}
},
"open_order": {
"type": "object",
"additionalProperties": false,
"required": [
"order_id",
"broker_order_id",
"symbol",
"side",
"quantity",
"filled_quantity",
"status",
"limit_price",
"order_type",
"time_in_force"
],
"properties": {
"order_id": {
"type": "string",
"minLength": 1
},
"broker_order_id": {
"type": "string",
"minLength": 1
},
"symbol": {
"$ref": "#/$defs/canonical_symbol"
},
"side": {
"enum": [
"BUY",
"SELL"
]
},
"quantity": {
"type": "integer",
"minimum": 1
},
"filled_quantity": {
"type": "integer",
"minimum": 0
},
"status": {
"enum": [
"NEW",
"ACCEPTED",
"PARTIALLY_FILLED",
"CANCEL_PENDING",
"UNKNOWN"
]
},
"limit_price": {
"type": "number",
"exclusiveMinimum": 0
},
"order_type": {
"const": "LIMIT"
},
"time_in_force": {
"const": "DAY"
}
}
}
}
}