📝 docs(tsl-api): resolve backtesting return contract
This commit is contained in:
@@ -30,7 +30,7 @@ end;
|
|||||||
|
|
||||||
function MyBackTesting.GetTradeOrder(vEndT); override;
|
function MyBackTesting.GetTradeOrder(vEndT); override;
|
||||||
begin
|
begin
|
||||||
return -1;
|
return array(); // 占位:实际策略替换为目标持仓或交易明细
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function RunBackTest(begT, endT);
|
function RunBackTest(begT, endT);
|
||||||
@@ -54,8 +54,9 @@ end;
|
|||||||
返回规则:
|
返回规则:
|
||||||
|
|
||||||
- `GetTradeOrder(vEndT)` 返回二维数组:表示当前时点的目标持仓或交易明细。
|
- `GetTradeOrder(vEndT)` 返回二维数组:表示当前时点的目标持仓或交易明细。
|
||||||
- `GetTradeOrder(vEndT)` 返回空数组:比例类组合表示完全清仓。
|
- 数量类组合返回空数组:表示当前时点没有交易。
|
||||||
- `GetTradeOrder(vEndT)` 返回 `-1`:表示当前时点不调仓或不交易。
|
- 比例类组合返回空数组:表示完全清仓。
|
||||||
|
- 比例类某个调仓日不调仓:返回非数组控制值。
|
||||||
|
|
||||||
## 回测开发流程
|
## 回测开发流程
|
||||||
|
|
||||||
@@ -76,21 +77,25 @@ end;
|
|||||||
|
|
||||||
## 交易数据字段
|
## 交易数据字段
|
||||||
|
|
||||||
|
下表把标准字段要求与框架允许的省略默认分开:`标准非空` 表示标准输入形状要求,`配置/省略规则` 表示配置替代或兼容默认。
|
||||||
|
|
||||||
### 比例类组合字段
|
### 比例类组合字段
|
||||||
|
|
||||||
`FGroupType := 1` 时,`GetTradeOrder(vEndT)` 返回目标持仓和目标比例。
|
`FGroupType := 1` 时,`GetTradeOrder(vEndT)` 返回目标持仓和目标比例。
|
||||||
|
|
||||||
| 字段 | 必填 | 接收类型 | 说明 |
|
| 字段 | 标准非空 | 接收类型 | 配置/省略规则 |
|
||||||
| --------------- | ---- | ---------- | -------------------------------------------------------- |
|
| --------------- | -------- | ---------- | -------------------------------------------------------- |
|
||||||
| `截止日` | 是 | `DateTime` | 通常等于 `vEndT` |
|
| `截止日` | 是 | `DateTime` | 通常等于 `vEndT` |
|
||||||
| `代码` | 是 | 字符串 | 目标持仓证券代码 |
|
| `代码` | 是 | 字符串 | 目标持仓证券代码 |
|
||||||
| `方向` | 是 | 整数 | `1` 多单;`0` 空单;缺省时按多单处理 |
|
| `方向` | 是 | 整数 | `1` 多单;`0` 空单;兼容省略时默认多单 |
|
||||||
| `比例(%)` | 是 | 数值 | 目标持仓比例;`FRateType <> -1` 时可由框架按配比方式计算 |
|
| `比例(%)` | 是 | 数值 | `FRateType := -1` 时必须提供;其它配比方式由框架计算 |
|
||||||
| `成交价` | 否 | 数值 | 比例类通常由 `FPriceType` 或 `FPriceRateTo0` 决定 |
|
| `成交价` | 否 | 数值 | 通常由 `FPriceType` 获取;自定义成交价时必须提供 |
|
||||||
| `乘数` | 否 | 数值 | 默认 `1` |
|
| `乘数` | 否 | 数值 | 省略时按品种或默认 `1` |
|
||||||
| `保证金比例(%)` | 否 | 数值 | 默认 `100` |
|
| `保证金比例(%)` | 否 | 数值 | 省略时按品种或默认 `100` |
|
||||||
| `开仓费率(%)` | 是 | 数值 | 开仓费率;股票、基金常见默认 `0.1` |
|
| `开仓费率(%)` | 是 | 数值 | 省略时使用品种默认费率 |
|
||||||
| `平仓费率(%)` | 是 | 数值 | 平仓费率;期货常见默认 `0.01` |
|
| `平仓费率(%)` | 是 | 数值 | 省略时使用品种默认费率 |
|
||||||
|
|
||||||
|
`名称` 可出现在用户导入数据或示例中,但不属于比例类必需契约字段。
|
||||||
|
|
||||||
比例类方向值:
|
比例类方向值:
|
||||||
|
|
||||||
@@ -111,21 +116,23 @@ end;
|
|||||||
|
|
||||||
`FGroupType := 2` 时,`GetTradeOrder(vEndT)` 返回交易明细。
|
`FGroupType := 2` 时,`GetTradeOrder(vEndT)` 返回交易明细。
|
||||||
|
|
||||||
| 字段 | 必填 | 接收类型 | 说明 |
|
| 字段 | 标准非空 | 接收类型 | 配置/省略规则 |
|
||||||
| ----------------- | -------- | ---------- | -------------------------------------------------- |
|
| ----------------- | -------- | ---------- | ------------------------------------------------------------ |
|
||||||
| `截止日` | 是 | `DateTime` | 通常等于 `vEndT` |
|
| `截止日` | 是 | `DateTime` | 通常等于 `vEndT` |
|
||||||
| `代码` | 是 | 字符串 | 交易证券代码 |
|
| `代码` | 是 | 字符串 | 交易证券代码 |
|
||||||
| `方向` | 是 | 整数 | `1` 多单;`0` 空单;缺省时按多单处理 |
|
| `方向` | 是 | 整数 | `1` 多单;`0` 空单;兼容省略时默认多单 |
|
||||||
| `动作` | 是 | 整数 | `0` 开仓;`1` 平仓;缺省时按开仓处理 |
|
| `动作` | 是 | 整数 | `0` 开仓;`1` 平仓;兼容省略时默认开仓 |
|
||||||
| `成交量` | 条件必填 | 数值 | `FOpenVolType := 1` 或 `FCloseVolType := 1` 时提供 |
|
| `成交量` | 是 | 数值 | 固定成交量时提供;期权动作 `0`、`32`、`33` 必须提供 |
|
||||||
| `资金` | 条件必填 | 数值 | `FOpenVolType := 2` 时提供 |
|
| `成交价` | 是 | 数值 | 标准交易明细应提供;系统价可由 `FPriceType` 取得,自定义时必须提供 |
|
||||||
| `剩余资金占比(%)` | 条件必填 | 数值 | `FOpenVolType := 3` 时提供 |
|
| `乘数` | 否 | 数值 | 省略时按品种或默认值处理 |
|
||||||
| `平仓数量占比(%)` | 条件必填 | 数值 | `FCloseVolType := 2` 时提供 |
|
| `保证金比例(%)` | 否 | 数值 | 省略时按品种或默认值处理 |
|
||||||
| `成交价` | 是 | 数值 | 交易成交价 |
|
| `费率(%)` | 是 | 数值 | `FFeeType := 1`;省略时使用品种默认费率 |
|
||||||
| `乘数` | 否 | 数值 | 默认 `1` |
|
| `资金` | 条件 | 数值 | 开仓且 `FOpenVolType := 2` |
|
||||||
| `保证金比例(%)` | 否 | 数值 | 默认 `100` |
|
| `剩余资金占比(%)` | 条件 | 数值 | 开仓且 `FOpenVolType := 3` |
|
||||||
| `费率(%)` | 条件必填 | 数值 | `FFeeType := 1` 时提供 |
|
| `平仓数量占比(%)` | 条件 | 数值 | 平仓且 `FCloseVolType := 2` |
|
||||||
| `费用` | 条件必填 | 数值 | `FFeeType := 2` 时提供;只适合数量类 |
|
| `费用` | 条件 | 数值 | `FFeeType := 2` 时直接提供单笔费用;只适合数量类 |
|
||||||
|
|
||||||
|
`FOpenVolType`/`FCloseVolType` 决定成交量替代字段:开仓模式为 `2/3` 时分别提供 `资金`/`剩余资金占比(%)`,平仓模式为 `2` 时提供 `平仓数量占比(%)`,这些模式下不再把 `成交量` 作为用户输入列。`名称` 只属于常见导入/展示列,不是数量类必需契约字段。
|
||||||
|
|
||||||
数量类方向和动作:
|
数量类方向和动作:
|
||||||
|
|
||||||
@@ -151,17 +158,19 @@ end;
|
|||||||
|
|
||||||
| 字段 | 必填 | 接收类型 | 说明 |
|
| 字段 | 必填 | 接收类型 | 说明 |
|
||||||
| ------------------- | -------- | ---------- | -------------------------------------------------------- |
|
| ------------------- | -------- | ---------- | -------------------------------------------------------- |
|
||||||
| `组 ID` | 是 | 字符串 | 同一组合内成分合约使用同一个组 ID |
|
| `组 ID` | 是 | 字符串 | 未构成组合时为空;同一组合内成分合约使用同一个组 ID |
|
||||||
| `截止日` | 是 | `DateTime` | 交易时点 |
|
| `截止日` | 是 | `DateTime` | 交易时点 |
|
||||||
| `代码` | 是 | 字符串 | 期权或期货合约代码 |
|
| `代码` | 是 | 字符串 | 期权或期货合约代码 |
|
||||||
| `方向` | 是 | 整数 | `1` 权利仓或多单;`0` 义务仓或空单 |
|
| `方向` | 是 | 整数 | `1` 权利仓或多单;`0` 义务仓或空单 |
|
||||||
| `动作` | 是 | 整数 | `0` 开仓;`1` 平仓;`32` 构建期权组合;`33` 解锁期权组合 |
|
| `动作` | 是 | 整数 | `0` 开仓;`1` 平仓;`32` 构建期权组合;`33` 解锁期权组合 |
|
||||||
| `成交价` | 是 | 数值 | 构建、解锁交易中可为任意大于 `0` 的实数 |
|
| `成交价` | 是 | 数值 | 构建、解锁交易中可为任意大于 `0` 的实数 |
|
||||||
| `成交量` | 是 | 数值 | 合约数量 |
|
| `成交量` | 条件必填 | 数值 | 动作 `0`、`32`、`33` 必须提供;动作 `1` 可改用平仓占比 |
|
||||||
| `费率(%)` 或 `费用` | 条件必填 | 数值 | 由 `FFeeType` 决定 |
|
| `费率(%)` 或 `费用` | 条件字段 | 数值 | 由 `FFeeType` 决定;动作 `32/33` 时对应值为 `0` |
|
||||||
| `乘数` | 否 | 数值 | 按品种设置 |
|
| `乘数` | 否 | 数值 | 按品种设置 |
|
||||||
| `保证金比例(%)` | 否 | 数值 | 按品种设置 |
|
| `保证金比例(%)` | 否 | 数值 | 按品种设置 |
|
||||||
| `组合类型` | 条件必填 | 字符串 | 组合策略标识,如 `CNSJC`、`STD` 等 |
|
| `组合类型` | 否 | 字符串 | 组合策略标识,如 `CNSJC`、`STD`;单腿或未识别时可为空 |
|
||||||
|
|
||||||
|
同一组合必须返回全部成分合约,且各行的 `组 ID`、`动作`、`成交量` 相同。
|
||||||
|
|
||||||
期权组合动作:
|
期权组合动作:
|
||||||
|
|
||||||
@@ -232,6 +241,7 @@ end;
|
|||||||
| `5` | 等股数 | 按等股数分配 |
|
| `5` | 等股数 | 按等股数分配 |
|
||||||
| `6` | 流通市值平方根加权 | 按流通市值平方根分配 |
|
| `6` | 流通市值平方根加权 | 按流通市值平方根分配 |
|
||||||
| `7` | 总市值平方根加权 | 按总市值平方根分配 |
|
| `7` | 总市值平方根加权 | 按总市值平方根分配 |
|
||||||
|
| `8` | 剩余资金等比例分配 | 先处理平仓,再把剩余资金等分给开仓证券 |
|
||||||
|
|
||||||
`FPriceRateTo0` 取值:
|
`FPriceRateTo0` 取值:
|
||||||
|
|
||||||
@@ -396,7 +406,7 @@ obj.FBMOption := 0;
|
|||||||
用途:获取当前时点目标持仓或交易明细。
|
用途:获取当前时点目标持仓或交易明细。
|
||||||
|
|
||||||
参数个数:1
|
参数个数:1
|
||||||
返回值:二维数组、空数组或 `-1`。
|
返回值:通常为二维数组;比例类当前调仓日不调仓时,可返回非数组控制值。
|
||||||
|
|
||||||
| 参数位置 | 参数名 | 必填 | 接收类型 | 说明 |
|
| 参数位置 | 参数名 | 必填 | 接收类型 | 说明 |
|
||||||
| -------- | ------- | ---- | ---------- | ----------------------------------------------------------------- |
|
| -------- | ------- | ---- | ---------- | ----------------------------------------------------------------- |
|
||||||
@@ -407,6 +417,8 @@ obj.FBMOption := 0;
|
|||||||
- 必须在子类中重写。
|
- 必须在子类中重写。
|
||||||
- 不要在 `GetTradeOrder(vEndT)` 中修改 `vEndT`。
|
- 不要在 `GetTradeOrder(vEndT)` 中修改 `vEndT`。
|
||||||
- 如果要使用历史区间,从 `vEndT` 推导,例如 `stockzf(incMonth(vEndT, -1), vEndT)`。
|
- 如果要使用历史区间,从 `vEndT` 推导,例如 `stockzf(incMonth(vEndT, -1), vEndT)`。
|
||||||
|
- 数量类空数组表示当前时点无交易;比例类空数组表示完全清仓。
|
||||||
|
- 比例类当前调仓日不调仓时返回非数组控制值。
|
||||||
|
|
||||||
### 可重写方法
|
### 可重写方法
|
||||||
|
|
||||||
@@ -606,7 +618,7 @@ obj.FBMOption := 0;
|
|||||||
|
|
||||||
| 情况 | 生成处理 |
|
| 情况 | 生成处理 |
|
||||||
| ------------------------------ | ----------------------------------------------------------------- |
|
| ------------------------------ | ----------------------------------------------------------------- |
|
||||||
| 只有“写回测框架”,没有策略逻辑 | 生成 `TSBackTesting` 子类骨架,`GetTradeOrder(vEndT)` 先返回 `-1` |
|
| 只有“写回测框架”,没有策略逻辑 | 生成 `TSBackTesting` 子类骨架,比例类 `GetTradeOrder(vEndT)` 使用空数组占位 |
|
||||||
| 没有证券池、调仓规则或交易明细 | 只生成框架和参数入口,不生成具体交易信号 |
|
| 没有证券池、调仓规则或交易明细 | 只生成框架和参数入口,不生成具体交易信号 |
|
||||||
| 没有期权需求 | 使用比例类或数量类普通字段,不加入期权组合字段 |
|
| 没有期权需求 | 使用比例类或数量类普通字段,不加入期权组合字段 |
|
||||||
| `FGroupType := 1` | `GetTradeOrder(vEndT)` 返回目标持仓和目标比例字段 |
|
| `FGroupType := 1` | `GetTradeOrder(vEndT)` 返回目标持仓和目标比例字段 |
|
||||||
|
|||||||
@@ -98,11 +98,46 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"api": "tsBackTesting.FGroupType",
|
"api": "tsBackTesting.FGroupType",
|
||||||
"role": "candidate_mode_discriminator",
|
"role": "return_schema_discriminator",
|
||||||
"contract_evidence_required": true,
|
"contract_evidence_required": true,
|
||||||
"evidence": [
|
"evidence": [
|
||||||
"module/ts-backtesting.md#fgrouptype"
|
"module/ts-backtesting.md#fgrouptype"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"api": "tsBackTesting.FRateType",
|
||||||
|
"role": "ratio_allocation_mode",
|
||||||
|
"evidence": [
|
||||||
|
"module/ts-backtesting.md#fratetype"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"api": "tsBackTesting.FPriceType",
|
||||||
|
"role": "execution_price_mode",
|
||||||
|
"evidence": [
|
||||||
|
"module/ts-backtesting.md#fpricetype"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"api": "tsBackTesting.FFeeType",
|
||||||
|
"role": "fee_input_mode",
|
||||||
|
"evidence": [
|
||||||
|
"module/ts-backtesting.md#ffeetype"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"api": "tsBackTesting.FOpenVolType",
|
||||||
|
"role": "quantity_open_size_mode",
|
||||||
|
"evidence": [
|
||||||
|
"module/ts-backtesting.md#fopenvoltype"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"api": "tsBackTesting.FCloseVolType",
|
||||||
|
"role": "quantity_close_size_mode",
|
||||||
|
"evidence": [
|
||||||
|
"module/ts-backtesting.md#fclosevoltype"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"hooks": [
|
"hooks": [
|
||||||
@@ -198,10 +233,394 @@
|
|||||||
"contracts": [
|
"contracts": [
|
||||||
{
|
{
|
||||||
"id": "ts-backtesting-trade-order",
|
"id": "ts-backtesting-trade-order",
|
||||||
"status": "incomplete",
|
"status": "resolved",
|
||||||
"callback": "tsBackTesting.GetTradeOrder",
|
"callback": "tsBackTesting.GetTradeOrder",
|
||||||
"reason": "The reference states target holdings or trade details but does not yet define the mode-specific record fields.",
|
"mode_discriminator": {
|
||||||
"required_next_step": "Resolve the configuration-to-return-schema mapping before generating callback fields.",
|
"api": "tsBackTesting.FGroupType"
|
||||||
|
},
|
||||||
|
"return_schemas": [
|
||||||
|
{
|
||||||
|
"id": "ratio-target-holdings",
|
||||||
|
"when": {
|
||||||
|
"FGroupType": "1"
|
||||||
|
},
|
||||||
|
"result_kind": "target_holdings",
|
||||||
|
"record_shape": "table_array",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "截止日",
|
||||||
|
"type": "date_time",
|
||||||
|
"required": true,
|
||||||
|
"pdf_non_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "代码",
|
||||||
|
"type": "string",
|
||||||
|
"required": true,
|
||||||
|
"pdf_non_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "方向",
|
||||||
|
"type": "integer",
|
||||||
|
"required": false,
|
||||||
|
"default": "1",
|
||||||
|
"pdf_non_empty": true,
|
||||||
|
"values": {
|
||||||
|
"0": "short",
|
||||||
|
"1": "long"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "比例(%)",
|
||||||
|
"type": "numeric",
|
||||||
|
"pdf_non_empty": true,
|
||||||
|
"required_when": [
|
||||||
|
{
|
||||||
|
"field": "FRateType",
|
||||||
|
"equals": [
|
||||||
|
"-1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "成交价",
|
||||||
|
"type": "numeric",
|
||||||
|
"pdf_non_empty": false,
|
||||||
|
"required_when": [
|
||||||
|
{
|
||||||
|
"field": "FPriceType",
|
||||||
|
"equals": [
|
||||||
|
"-1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Provide when FPriceType=-1; otherwise the framework selects the execution price."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "乘数",
|
||||||
|
"type": "numeric",
|
||||||
|
"required": false,
|
||||||
|
"pdf_non_empty": false,
|
||||||
|
"default": "1_or_instrument_default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "保证金比例(%)",
|
||||||
|
"type": "numeric",
|
||||||
|
"required": false,
|
||||||
|
"pdf_non_empty": false,
|
||||||
|
"default": "100_or_instrument_default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "开仓费率(%)",
|
||||||
|
"type": "numeric",
|
||||||
|
"required": false,
|
||||||
|
"pdf_non_empty": true,
|
||||||
|
"used_when": [
|
||||||
|
{
|
||||||
|
"field": "FFeeType",
|
||||||
|
"equals": [
|
||||||
|
"1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fallback": "tsBackTesting.StockFee"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "平仓费率(%)",
|
||||||
|
"type": "numeric",
|
||||||
|
"required": false,
|
||||||
|
"pdf_non_empty": true,
|
||||||
|
"used_when": [
|
||||||
|
{
|
||||||
|
"field": "FFeeType",
|
||||||
|
"equals": [
|
||||||
|
"1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fallback": "tsBackTesting.StockFee"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"alternate_returns": [
|
||||||
|
{
|
||||||
|
"type": "empty_array",
|
||||||
|
"meaning": "clear_all_positions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "non_array",
|
||||||
|
"meaning": "skip_current_rebalance",
|
||||||
|
"documented_examples": [
|
||||||
|
-1,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"evidence": [
|
||||||
|
"module/ts-backtesting.md#gettradeorderv_end_t"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "quantity-trade-details",
|
||||||
|
"when": {
|
||||||
|
"FGroupType": "2"
|
||||||
|
},
|
||||||
|
"result_kind": "trade_details",
|
||||||
|
"record_shape": "table_array",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "截止日",
|
||||||
|
"type": "date_time",
|
||||||
|
"required": true,
|
||||||
|
"pdf_non_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "代码",
|
||||||
|
"type": "string",
|
||||||
|
"required": true,
|
||||||
|
"pdf_non_empty": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "方向",
|
||||||
|
"type": "integer",
|
||||||
|
"required": false,
|
||||||
|
"default": "1",
|
||||||
|
"pdf_non_empty": true,
|
||||||
|
"values": {
|
||||||
|
"0": "short",
|
||||||
|
"1": "long"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "动作",
|
||||||
|
"type": "integer",
|
||||||
|
"required": true,
|
||||||
|
"compat_default": "0",
|
||||||
|
"pdf_non_empty": true,
|
||||||
|
"values": {
|
||||||
|
"0": "open",
|
||||||
|
"1": "close",
|
||||||
|
"32": "build_option_group",
|
||||||
|
"33": "unlock_option_group"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "成交量",
|
||||||
|
"type": "numeric",
|
||||||
|
"pdf_non_empty": true,
|
||||||
|
"required_when": [
|
||||||
|
{
|
||||||
|
"field": "FOpenVolType",
|
||||||
|
"equals": [
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"record_when": {
|
||||||
|
"动作": [
|
||||||
|
"0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "FCloseVolType",
|
||||||
|
"equals": [
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
"record_when": {
|
||||||
|
"动作": [
|
||||||
|
"1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"record_required_when": {
|
||||||
|
"动作": [
|
||||||
|
"32",
|
||||||
|
"33"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "成交价",
|
||||||
|
"type": "numeric",
|
||||||
|
"pdf_non_empty": true,
|
||||||
|
"required_when": [
|
||||||
|
{
|
||||||
|
"field": "FPriceType",
|
||||||
|
"equals": [
|
||||||
|
"-1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"record_required_when": {
|
||||||
|
"动作": [
|
||||||
|
"32",
|
||||||
|
"33"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"record_constraint_when": {
|
||||||
|
"动作": {
|
||||||
|
"32": "greater_than_zero",
|
||||||
|
"33": "greater_than_zero"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "资金",
|
||||||
|
"type": "numeric",
|
||||||
|
"required_when": [
|
||||||
|
{
|
||||||
|
"field": "FOpenVolType",
|
||||||
|
"equals": [
|
||||||
|
"2"
|
||||||
|
],
|
||||||
|
"record_when": {
|
||||||
|
"动作": [
|
||||||
|
"0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "剩余资金占比(%)",
|
||||||
|
"type": "numeric",
|
||||||
|
"required_when": [
|
||||||
|
{
|
||||||
|
"field": "FOpenVolType",
|
||||||
|
"equals": [
|
||||||
|
"3"
|
||||||
|
],
|
||||||
|
"record_when": {
|
||||||
|
"动作": [
|
||||||
|
"0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "平仓数量占比(%)",
|
||||||
|
"type": "numeric",
|
||||||
|
"required_when": [
|
||||||
|
{
|
||||||
|
"field": "FCloseVolType",
|
||||||
|
"equals": [
|
||||||
|
"2"
|
||||||
|
],
|
||||||
|
"record_when": {
|
||||||
|
"动作": [
|
||||||
|
"1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "乘数",
|
||||||
|
"type": "numeric",
|
||||||
|
"required": false,
|
||||||
|
"pdf_non_empty": false,
|
||||||
|
"default": "1_or_instrument_default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "保证金比例(%)",
|
||||||
|
"type": "numeric",
|
||||||
|
"required": false,
|
||||||
|
"pdf_non_empty": false,
|
||||||
|
"default": "100_or_instrument_default"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "费率(%)",
|
||||||
|
"type": "numeric",
|
||||||
|
"pdf_non_empty": true,
|
||||||
|
"used_when": [
|
||||||
|
{
|
||||||
|
"field": "FFeeType",
|
||||||
|
"equals": [
|
||||||
|
"1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"record_value_when": {
|
||||||
|
"动作": {
|
||||||
|
"32": 0,
|
||||||
|
"33": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fallback": "tsBackTesting.StockFee"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "费用",
|
||||||
|
"type": "numeric",
|
||||||
|
"pdf_non_empty": false,
|
||||||
|
"required_when": [
|
||||||
|
{
|
||||||
|
"field": "FFeeType",
|
||||||
|
"equals": [
|
||||||
|
"2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"record_value_when": {
|
||||||
|
"动作": {
|
||||||
|
"32": 0,
|
||||||
|
"33": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "组 ID",
|
||||||
|
"type": "string",
|
||||||
|
"pdf_non_empty": true,
|
||||||
|
"required": false,
|
||||||
|
"applies_when": "option_group_strategy",
|
||||||
|
"required_in_extension": true,
|
||||||
|
"description": "Required as a non-empty shared identifier for option-group rows; empty for ungrouped single-leg rows."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "组合类型",
|
||||||
|
"type": "string",
|
||||||
|
"pdf_non_empty": false,
|
||||||
|
"required": false,
|
||||||
|
"applies_when": "option_group_strategy",
|
||||||
|
"description": "Option strategy identifier such as CNSJC or STD; may be empty for single-leg or unrecognized combinations."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"record_rules": [
|
||||||
|
{
|
||||||
|
"when": "option_group_strategy",
|
||||||
|
"rule": "Return all component contracts for a group; rows in the same group share 组 ID, 动作, and 成交量."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {
|
||||||
|
"动作": [
|
||||||
|
"0",
|
||||||
|
"32",
|
||||||
|
"33"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rule": "Option-group opening, construction, and unlock records use a concrete 成交量; action 1 may instead use 平仓数量占比(%)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"when": {
|
||||||
|
"动作": [
|
||||||
|
"0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rule": "Option-group opening (action 0) uses FOpenVolType=1; fixed-amount and remaining-funds modes are not supported for this action."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"alternate_returns": [
|
||||||
|
{
|
||||||
|
"type": "empty_array",
|
||||||
|
"meaning": "no_trade_at_current_time"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"evidence": [
|
||||||
|
"module/ts-backtesting.md#gettradeorderv_end_t"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"evidence": [
|
"evidence": [
|
||||||
"module/ts-backtesting.md#gettradeorderv_end_t"
|
"module/ts-backtesting.md#gettradeorderv_end_t"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2658,6 +2658,7 @@ FClearCycle module ts-timing-evaluation FClearCycle module/ts-timing-evaluation.
|
|||||||
FClose_N1 module ts-statistical-arbitrage FClose_N1 module/ts-statistical-arbitrage.md fclose_n1 上侧平仓标准差倍数 field instance public tsStatisticalArbitrage tsStatisticalArbitrage.FClose_N1
|
FClose_N1 module ts-statistical-arbitrage FClose_N1 module/ts-statistical-arbitrage.md fclose_n1 上侧平仓标准差倍数 field instance public tsStatisticalArbitrage tsStatisticalArbitrage.FClose_N1
|
||||||
FClose_N2 module ts-statistical-arbitrage FClose_N2 module/ts-statistical-arbitrage.md fclose_n2 下侧平仓标准差倍数 field instance public tsStatisticalArbitrage tsStatisticalArbitrage.FClose_N2
|
FClose_N2 module ts-statistical-arbitrage FClose_N2 module/ts-statistical-arbitrage.md fclose_n2 下侧平仓标准差倍数 field instance public tsStatisticalArbitrage tsStatisticalArbitrage.FClose_N2
|
||||||
FCloseFeeRate module ts-timing-evaluation FCloseFeeRate module/ts-timing-evaluation.md fclosefeerate 平仓费率(%) 0 field instance public tsTimingEvaluation tsTimingEvaluation.FCloseFeeRate
|
FCloseFeeRate module ts-timing-evaluation FCloseFeeRate module/ts-timing-evaluation.md fclosefeerate 平仓费率(%) 0 field instance public tsTimingEvaluation tsTimingEvaluation.FCloseFeeRate
|
||||||
|
FCloseVolType module ts-backtesting FCloseVolType module/ts-backtesting.md fclosevoltype 数量类组合平仓数量模式 1:固定成交量法;2:可平仓数量占比法 field instance public tsBackTesting tsBackTesting.FCloseVolType
|
||||||
FcLowestFee module ts-backtesting FcLowestFee module/ts-backtesting.md fclowestfee 平仓最低费用 5.0 field instance public tsBackTesting tsBackTesting.FcLowestFee
|
FcLowestFee module ts-backtesting FcLowestFee module/ts-backtesting.md fclowestfee 平仓最低费用 5.0 field instance public tsBackTesting tsBackTesting.FcLowestFee
|
||||||
FCombinations module ts-backtest-overfit-prob FCombinations module/ts-backtest-overfit-prob.md fcombinations 生成的子集组合 field instance public tsBacktestOverfitProb tsBacktestOverfitProb.FCombinations
|
FCombinations module ts-backtest-overfit-prob FCombinations module/ts-backtest-overfit-prob.md fcombinations 生成的子集组合 field instance public tsBacktestOverfitProb tsBacktestOverfitProb.FCombinations
|
||||||
FComFactorArr module ts-hg-data-process FComFactorArr module/ts-hg-data-process.md fcomfactorarr 合成因子库 array() field instance public ts_HGDataProcess ts_HGDataProcess.FComFactorArr
|
FComFactorArr module ts-hg-data-process FComFactorArr module/ts-hg-data-process.md fcomfactorarr 合成因子库 array() field instance public ts_HGDataProcess ts_HGDataProcess.FComFactorArr
|
||||||
@@ -2782,7 +2783,7 @@ FFaRet module ts-factor-portfolio-optimizer FFaRet module/ts-factor-portfolio-op
|
|||||||
FFaRets module ts-factor-portfolio-optimizer FFaRets module/ts-factor-portfolio-optimizer.md ffarets 因子收益序列 field instance public tsFactorPortfolioOptimizer tsFactorPortfolioOptimizer.FFaRets
|
FFaRets module ts-factor-portfolio-optimizer FFaRets module/ts-factor-portfolio-optimizer.md ffarets 因子收益序列 field instance public tsFactorPortfolioOptimizer tsFactorPortfolioOptimizer.FFaRets
|
||||||
FFeature module ts-persistence-of-fund FFeature module/ts-persistence-of-fund.md ffeature 基金业绩指标 field instance public ts_PersistenceOfFund ts_PersistenceOfFund.FFeature
|
FFeature module ts-persistence-of-fund FFeature module/ts-persistence-of-fund.md ffeature 基金业绩指标 field instance public ts_PersistenceOfFund ts_PersistenceOfFund.FFeature
|
||||||
FFeeRate module derivatives-analysis FFeeRate module/derivatives-analysis/option-delta-hedging.md ffeerate 交易费率百分比,默认值为 0 field instance public opDeltaHedging opDeltaHedging.FFeeRate
|
FFeeRate module derivatives-analysis FFeeRate module/derivatives-analysis/option-delta-hedging.md ffeerate 交易费率百分比,默认值为 0 field instance public opDeltaHedging opDeltaHedging.FFeeRate
|
||||||
FFeeType module ts-backtesting FFeeType module/ts-backtesting.md ffeetype 费用类别 1:费率法 field instance public tsBackTesting tsBackTesting.FFeeType
|
FFeeType module ts-backtesting FFeeType module/ts-backtesting.md ffeetype 费用类别 1:费率法;2:费用法。比例类只能使用费率法;数量类可使用费率法或费用法 field instance public tsBackTesting tsBackTesting.FFeeType
|
||||||
FFeeType2 module ts-backtesting FFeeType2 module/ts-backtesting.md ffeetype2 比例类费率 1: 历史明细中查找开、 平仓费率 field instance public tsBackTesting tsBackTesting.FFeeType2
|
FFeeType2 module ts-backtesting FFeeType2 module/ts-backtesting.md ffeetype2 比例类费率 1: 历史明细中查找开、 平仓费率 field instance public tsBackTesting tsBackTesting.FFeeType2
|
||||||
FfhExchangeRatetype module ts-backtesting FfhExchangeRatetype module/ts-backtesting.md ffhexchangeratetype 分红汇率类型 2:对应市场结算汇率中间价 field instance public tsBackTesting tsBackTesting.FfhExchangeRatetype
|
FfhExchangeRatetype module ts-backtesting FfhExchangeRatetype module/ts-backtesting.md ffhexchangeratetype 分红汇率类型 2:对应市场结算汇率中间价 field instance public tsBackTesting tsBackTesting.FfhExchangeRatetype
|
||||||
ffi_es dotnet financial ffi_es(w_p, x, f, delta, confidence_interval) dotnet/financial/financial_engineering-risk_model-application-risk_analysis-algorithm_layer.md ffi_es 金融 金融工程 风险模型 应用 风险分析 算法层 返回 获取 ES 返回期望损失ES function ffi_es
|
ffi_es dotnet financial ffi_es(w_p, x, f, delta, confidence_interval) dotnet/financial/financial_engineering-risk_model-application-risk_analysis-algorithm_layer.md ffi_es 金融 金融工程 风险模型 应用 风险分析 算法层 返回 获取 ES 返回期望损失ES function ffi_es
|
||||||
@@ -2824,7 +2825,7 @@ fgRight builtin graph fgRight() builtin/graph.md fgright 图形对象 图形 图
|
|||||||
fgRightDown builtin graph fgRightDown() builtin/graph.md fgrightdown 图形对象 图形 图表 graph 对象 实例 object 右下 function fgRightDown
|
fgRightDown builtin graph fgRightDown() builtin/graph.md fgrightdown 图形对象 图形 图表 graph 对象 实例 object 右下 function fgRightDown
|
||||||
fgRightUp builtin graph fgRightUp() builtin/graph.md fgrightup 图形对象 图形 图表 graph 对象 实例 object 右上 function fgRightUp
|
fgRightUp builtin graph fgRightUp() builtin/graph.md fgrightup 图形对象 图形 图表 graph 对象 实例 object 右上 function fgRightUp
|
||||||
FGroups module ts-multi-factor FGroups module/ts-multi-factor.md fgroups 五分位 field instance public tsMultiFactor tsMultiFactor.FGroups
|
FGroups module ts-multi-factor FGroups module/ts-multi-factor.md fgroups 五分位 field instance public tsMultiFactor tsMultiFactor.FGroups
|
||||||
FGroupType module ts-backtesting FGroupType module/ts-backtesting.md fgrouptype 组合类型 1:比例类组合 field instance public tsBackTesting tsBackTesting.FGroupType
|
FGroupType module ts-backtesting FGroupType module/ts-backtesting.md fgrouptype 组合类型 1:比例类组合;2:数量类组合。期权不支持比例类回测 field instance public tsBackTesting tsBackTesting.FGroupType
|
||||||
FGroupType module ts-multi-factor FGroupType module/ts-multi-factor.md fgrouptype 分组方式 1:百分位 field instance public tsMultiFactor tsMultiFactor.FGroupType
|
FGroupType module ts-multi-factor FGroupType module/ts-multi-factor.md fgrouptype 分组方式 1:百分位 field instance public tsMultiFactor tsMultiFactor.FGroupType
|
||||||
fgUp builtin graph fgUp() builtin/graph.md fgup 图形对象 图形 图表 graph 对象 实例 object 上 function fgUp
|
fgUp builtin graph fgUp() builtin/graph.md fgup 图形对象 图形 图表 graph 对象 实例 object 上 function fgUp
|
||||||
Fh dotnet math Fh dotnet/math/optimization.md fh 二次型 field instance public tsOptimizer tsOptimizer.Fh
|
Fh dotnet math Fh dotnet/math/optimization.md fh 二次型 field instance public tsOptimizer tsOptimizer.Fh
|
||||||
@@ -3149,6 +3150,7 @@ footerValue dotnet base footerValue(t, from_col, tocol, average_col_field, _type
|
|||||||
FOpen_N1 module ts-statistical-arbitrage FOpen_N1 module/ts-statistical-arbitrage.md fopen_n1 上侧开仓标准差倍数 field instance public tsStatisticalArbitrage tsStatisticalArbitrage.FOpen_N1
|
FOpen_N1 module ts-statistical-arbitrage FOpen_N1 module/ts-statistical-arbitrage.md fopen_n1 上侧开仓标准差倍数 field instance public tsStatisticalArbitrage tsStatisticalArbitrage.FOpen_N1
|
||||||
FOpen_N2 module ts-statistical-arbitrage FOpen_N2 module/ts-statistical-arbitrage.md fopen_n2 下侧开仓标准差倍数 field instance public tsStatisticalArbitrage tsStatisticalArbitrage.FOpen_N2
|
FOpen_N2 module ts-statistical-arbitrage FOpen_N2 module/ts-statistical-arbitrage.md fopen_n2 下侧开仓标准差倍数 field instance public tsStatisticalArbitrage tsStatisticalArbitrage.FOpen_N2
|
||||||
FOpenFeeRate module ts-timing-evaluation FOpenFeeRate module/ts-timing-evaluation.md fopenfeerate 开仓费率(%) 0 field instance public tsTimingEvaluation tsTimingEvaluation.FOpenFeeRate
|
FOpenFeeRate module ts-timing-evaluation FOpenFeeRate module/ts-timing-evaluation.md fopenfeerate 开仓费率(%) 0 field instance public tsTimingEvaluation tsTimingEvaluation.FOpenFeeRate
|
||||||
|
FOpenVolType module ts-backtesting FOpenVolType module/ts-backtesting.md fopenvoltype 数量类组合开仓数量模式 1:固定成交量法;2:固定金额法;3:剩余资金占比法 field instance public tsBackTesting tsBackTesting.FOpenVolType
|
||||||
FOPMaturityDate module derivatives-analysis FOPMaturityDate module/derivatives-analysis/option-instrument-indicators.md fopmaturitydate 到期月份序号;0 为全部,1 为近月,2 为次近月,依次类推 field instance public ts_Options_Screening ts_Options_Screening.FOPMaturityDate
|
FOPMaturityDate module derivatives-analysis FOPMaturityDate module/derivatives-analysis/option-instrument-indicators.md fopmaturitydate 到期月份序号;0 为全部,1 为近月,2 为次近月,依次类推 field instance public ts_Options_Screening ts_Options_Screening.FOPMaturityDate
|
||||||
FOPPZID module derivatives-analysis FOPPZID module/derivatives-analysis/option-instrument-indicators.md foppzid 期权品种或标的代码;空字符串表示不按品种筛选 field instance public ts_Options_Screening ts_Options_Screening.FOPPZID
|
FOPPZID module derivatives-analysis FOPPZID module/derivatives-analysis/option-instrument-indicators.md foppzid 期权品种或标的代码;空字符串表示不按品种筛选 field instance public ts_Options_Screening ts_Options_Screening.FOPPZID
|
||||||
FOpsId module ts-ops FOpsId module/ts-ops.md fopsid 服务标识 TS-OPS 服务 ID property instance public opsServer opsServer.FOpsId
|
FOpsId module ts-ops FOpsId module/ts-ops.md fopsid 服务标识 TS-OPS 服务 ID property instance public opsServer opsServer.FOpsId
|
||||||
@@ -3189,7 +3191,7 @@ FPriceRateTo0 module ts-backtesting FPriceRateTo0 module/ts-backtesting.md fpric
|
|||||||
FPriceStep module bond-research FPriceStep module/bond-research/bond-price-segmentation.md fpricestep 价格频数分布步长,单位为元,默认 10 field instance public cb_PriceAndDeadlineData cb_PriceAndDeadlineData.FPriceStep
|
FPriceStep module bond-research FPriceStep module/bond-research/bond-price-segmentation.md fpricestep 价格频数分布步长,单位为元,默认 10 field instance public cb_PriceAndDeadlineData cb_PriceAndDeadlineData.FPriceStep
|
||||||
FPriceType module bond-research FPriceType module/bond-research/bond-price-segmentation.md fpricetype 统计最高价和最低价时使用的价格类型;0 为收盘价,1 为当日最高价或最低价 field instance public cb_PriceAndDeadlineData cb_PriceAndDeadlineData.FPriceType
|
FPriceType module bond-research FPriceType module/bond-research/bond-price-segmentation.md fpricetype 统计最高价和最低价时使用的价格类型;0 为收盘价,1 为当日最高价或最低价 field instance public cb_PriceAndDeadlineData cb_PriceAndDeadlineData.FPriceType
|
||||||
FPriceType module factor-research FPriceType module/factor-research/index-chip-factors.md fpricetype 指数均价算法;支持算术平均、成交量加权、成交金额加权及调整后的成交量加权 field instance public ts_IndexChipDistribution ts_IndexChipDistribution.FPriceType
|
FPriceType module factor-research FPriceType module/factor-research/index-chip-factors.md fpricetype 指数均价算法;支持算术平均、成交量加权、成交金额加权及调整后的成交量加权 field instance public ts_IndexChipDistribution ts_IndexChipDistribution.FPriceType
|
||||||
FPriceType module ts-backtesting FPriceType module/ts-backtesting.md fpricetype 成交价类别 3:日均价 field instance public tsBackTesting tsBackTesting.FPriceType
|
FPriceType module ts-backtesting FPriceType module/ts-backtesting.md fpricetype 成交价类别 -1:用户自定义;1:时点价格;2:收盘价;3:日均价;4:开盘价;5:系统昨收 field instance public tsBackTesting tsBackTesting.FPriceType
|
||||||
FpriceType module ts-multi-factor FpriceType module/ts-multi-factor.md fpricetype 成交价类别 2:收盘价 field instance public tsMultiFactor tsMultiFactor.FpriceType
|
FpriceType module ts-multi-factor FpriceType module/ts-multi-factor.md fpricetype 成交价类别 2:收盘价 field instance public tsMultiFactor tsMultiFactor.FpriceType
|
||||||
FPrincDZ module ts-hg-risk-pca FPrincDZ module/ts-hg-risk-pca.md fprincdz 主成分对照 见 FPrincDZ 默认值 field instance public ts_HGRiskPCA ts_HGRiskPCA.FPrincDZ
|
FPrincDZ module ts-hg-risk-pca FPrincDZ module/ts-hg-risk-pca.md fprincdz 主成分对照 见 FPrincDZ 默认值 field instance public ts_HGRiskPCA ts_HGRiskPCA.FPrincDZ
|
||||||
FPurchaseRatio module fund-research FPurchaseRatio module/fund-research/fixed-amount-investment.md fpurchaseratio 申购费率,单位为百分比 field instance public ts_AIPBackTesting ts_AIPBackTesting.FPurchaseRatio
|
FPurchaseRatio module fund-research FPurchaseRatio module/fund-research/fixed-amount-investment.md fpurchaseratio 申购费率,单位为百分比 field instance public ts_AIPBackTesting ts_AIPBackTesting.FPurchaseRatio
|
||||||
@@ -3229,7 +3231,7 @@ frameStocksMark_GetGrouptail module strategy-selection-tools frameStocksMark_Get
|
|||||||
frameupdate dotnet base frameupdate(left, right, ons, type) dotnet/base/array.md frameupdate 数组 数据表 更新 缺失值 merge update table 按键字段用右表补充或更新左表中的缺失值,并直接修改左表 function frameupdate
|
frameupdate dotnet base frameupdate(left, right, ons, type) dotnet/base/array.md frameupdate 数组 数据表 更新 缺失值 merge update table 按键字段用右表补充或更新左表中的缺失值,并直接修改左表 function frameupdate
|
||||||
framevaluecounts dotnet base framevaluecounts(data, countfieldname, iforder) dotnet/base/array.md framevaluecounts 数据表-计数 function framevaluecounts
|
framevaluecounts dotnet base framevaluecounts(data, countfieldname, iforder) dotnet/base/array.md framevaluecounts 数据表-计数 function framevaluecounts
|
||||||
FRateType module quick-back-testing FRateType module/quick-back-testing.md fratetype 比例类组合资金分配方式 4:等权重 field instance public quickBackTesting quickBackTesting.FRateType
|
FRateType module quick-back-testing FRateType module/quick-back-testing.md fratetype 比例类组合资金分配方式 4:等权重 field instance public quickBackTesting quickBackTesting.FRateType
|
||||||
FRateType module ts-backtesting FRateType module/ts-backtesting.md fratetype 比例类组合资金分配方式 4:等权重 field instance public tsBackTesting tsBackTesting.FRateType
|
FRateType module ts-backtesting FRateType module/ts-backtesting.md fratetype 比例类组合资金分配方式;-1:用户自定义比例;0/1/4/5/6/7 为系统配比;8:剩余资金等比例分配;默认 4:等权重 field instance public tsBackTesting tsBackTesting.FRateType
|
||||||
FRateType module ts-future-multifactor FRateType module/ts-future-multifactor.md fratetype 比例类型 4(等权) field instance public tsFutureMultiFactor tsFutureMultiFactor.FRateType
|
FRateType module ts-future-multifactor FRateType module/ts-future-multifactor.md fratetype 比例类型 4(等权) field instance public tsFutureMultiFactor tsFutureMultiFactor.FRateType
|
||||||
FRateType module ts-multi-factor FRateType module/ts-multi-factor.md fratetype 个股资金分配方法 4:等权重 field instance public tsMultiFactor tsMultiFactor.FRateType
|
FRateType module ts-multi-factor FRateType module/ts-multi-factor.md fratetype 个股资金分配方法 4:等权重 field instance public tsMultiFactor tsMultiFactor.FRateType
|
||||||
FRatio module tinysoft-strategies FRatio module/tinysoft-strategies/market-cap-rotation.md fratio 买卖费率百分比,默认值为 0.1 field instance public tsLargeAndSmallTurning tsLargeAndSmallTurning.FRatio
|
FRatio module tinysoft-strategies FRatio module/tinysoft-strategies/market-cap-rotation.md fratio 买卖费率百分比,默认值为 0.1 field instance public tsLargeAndSmallTurning tsLargeAndSmallTurning.FRatio
|
||||||
|
|||||||
|
Can't render this file because it is too large.
|
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
声明:field
|
声明:field
|
||||||
|
|
||||||
组合类型 1:比例类组合
|
组合类型 1:比例类组合;2:数量类组合。期权不支持比例类回测
|
||||||
|
|
||||||
可见性:`public`
|
可见性:`public`
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
|
|
||||||
声明:field
|
声明:field
|
||||||
|
|
||||||
成交价类别 3:日均价
|
成交价类别 -1:用户自定义;1:时点价格;2:收盘价;3:日均价;4:开盘价;5:系统昨收
|
||||||
|
|
||||||
可见性:`public`
|
可见性:`public`
|
||||||
|
|
||||||
@@ -92,7 +92,27 @@
|
|||||||
|
|
||||||
声明:field
|
声明:field
|
||||||
|
|
||||||
费用类别 1:费率法
|
费用类别 1:费率法;2:费用法。比例类只能使用费率法;数量类可使用费率法或费用法
|
||||||
|
|
||||||
|
可见性:`public`
|
||||||
|
|
||||||
|
类型:integer
|
||||||
|
|
||||||
|
### `FOpenVolType`
|
||||||
|
|
||||||
|
声明:field
|
||||||
|
|
||||||
|
数量类组合开仓数量模式 1:固定成交量法;2:固定金额法;3:剩余资金占比法
|
||||||
|
|
||||||
|
可见性:`public`
|
||||||
|
|
||||||
|
类型:integer
|
||||||
|
|
||||||
|
### `FCloseVolType`
|
||||||
|
|
||||||
|
声明:field
|
||||||
|
|
||||||
|
数量类组合平仓数量模式 1:固定成交量法;2:可平仓数量占比法
|
||||||
|
|
||||||
可见性:`public`
|
可见性:`public`
|
||||||
|
|
||||||
@@ -102,7 +122,7 @@
|
|||||||
|
|
||||||
声明:field
|
声明:field
|
||||||
|
|
||||||
比例类组合资金分配方式 4:等权重
|
比例类组合资金分配方式;-1:用户自定义比例;0/1/4/5/6/7 为系统配比;8:剩余资金等比例分配;默认 4:等权重
|
||||||
|
|
||||||
可见性:`public`
|
可见性:`public`
|
||||||
|
|
||||||
@@ -631,7 +651,67 @@ return ret;
|
|||||||
| --------- | --------- | -------------- |
|
| --------- | --------- | -------------- |
|
||||||
| `v_end_t` | date_time | 日期,当前时点 |
|
| `v_end_t` | date_time | 日期,当前时点 |
|
||||||
|
|
||||||
返回:array
|
返回:通常为 `array`;比例类当前调仓日不调仓时,可返回非数组控制值
|
||||||
|
|
||||||
|
返回契约
|
||||||
|
|
||||||
|
`GetTradeOrder(v_end_t)` 的返回值是框架回调输入,不是固定列集合;记录字段由
|
||||||
|
`FGroupType` 及数量、费用和成交价配置共同决定。每行是二维数组中的一条记录。
|
||||||
|
|
||||||
|
比例类组合(`FGroupType := 1`)返回目标持仓记录:
|
||||||
|
|
||||||
|
| 字段 | 类型 | 标准非空 | 配置/省略规则 |
|
||||||
|
| --------------- | ---------- | -------- | ------------------------------------------------------ |
|
||||||
|
| `截止日` | `date_time` | 是 | 当前调仓时点,通常等于 `v_end_t` |
|
||||||
|
| `代码` | `string` | 是 | 目标持仓证券代码 |
|
||||||
|
| `方向` | `integer` | 是 | `1` 多单;`0` 空单;兼容省略时默认多单 |
|
||||||
|
| `比例(%)` | `numeric` | 是 | `FRateType := -1` 必须提供;系统配比时由框架计算 |
|
||||||
|
| `成交价` | `numeric` | 否 | 通常由 `FPriceType` 获取;自定义成交价时必须提供 |
|
||||||
|
| `乘数` | `numeric` | 否 | 省略时按品种或默认 `1` |
|
||||||
|
| `保证金比例(%)` | `numeric` | 否 | 省略时按品种或默认 `100` |
|
||||||
|
| `开仓费率(%)` | `numeric` | 是 | 省略时使用品种默认费率 |
|
||||||
|
| `平仓费率(%)` | `numeric` | 是 | 省略时使用品种默认费率 |
|
||||||
|
|
||||||
|
`名称` 可出现在用户导入数据或范例中,但不属于比例类必需契约字段。
|
||||||
|
|
||||||
|
数量类组合(`FGroupType := 2`)返回交易明细记录:
|
||||||
|
|
||||||
|
| 字段 | 类型 | 标准非空 | 配置/省略规则 |
|
||||||
|
| ------------------- | ---------- | -------- | ------------------------------------------------------ |
|
||||||
|
| `截止日` | `date_time` | 是 | 当前交易时点,通常等于 `v_end_t` |
|
||||||
|
| `代码` | `string` | 是 | 交易证券代码 |
|
||||||
|
| `方向` | `integer` | 是 | `1` 多单;`0` 空单;兼容省略时默认多单 |
|
||||||
|
| `动作` | `integer` | 是 | `0` 开仓;`1` 平仓;兼容省略时默认开仓 |
|
||||||
|
| `成交量` | `numeric` | 是 | 固定成交量时提供;期权动作 `0/32/33` 必须提供 |
|
||||||
|
| `成交价` | `numeric` | 是 | 标准交易明细应提供;系统价 `FPriceType` 可代取,自定义时必须提供 |
|
||||||
|
| `乘数` | `numeric` | 否 | 省略时按品种或默认值处理 |
|
||||||
|
| `保证金比例(%)` | `numeric` | 否 | 省略时按品种或默认值处理 |
|
||||||
|
| `费率(%)` | `numeric` | 是 | `FFeeType := 1`;省略时使用品种默认费率 |
|
||||||
|
| `资金` | `numeric` | 条件 | 开仓且 `FOpenVolType := 2` |
|
||||||
|
| `剩余资金占比(%)` | `numeric` | 条件 | 开仓且 `FOpenVolType := 3` |
|
||||||
|
| `平仓数量占比(%)` | `numeric` | 条件 | 平仓且 `FCloseVolType := 2` |
|
||||||
|
| `费用` | `numeric` | 条件 | `FFeeType := 2`;只适合数量类,直接提供单笔费用 |
|
||||||
|
|
||||||
|
`FOpenVolType`/`FCloseVolType` 决定成交量替代字段:开仓模式为 `2/3` 时分别提供 `资金`/`剩余资金占比(%)`,平仓模式为 `2` 时提供 `平仓数量占比(%)`。这些模式下不应再把 `成交量` 当作用户输入列。
|
||||||
|
|
||||||
|
`名称` 可出现在导入数据或范例中,但不属于数量类必需契约字段。
|
||||||
|
|
||||||
|
期权组合扩展(数量类专用):
|
||||||
|
|
||||||
|
| 字段 | 类型 | 规则 |
|
||||||
|
| ---------- | -------- | ---- |
|
||||||
|
| `组 ID` | `string` | 组合策略数据必有;未构成组合时为空字符串;同一组合的所有成分合约使用同一值 |
|
||||||
|
| `组合类型` | `string` | 组合策略标识,如 `CNSJC`、`STD`;未识别或单腿时可为空 |
|
||||||
|
|
||||||
|
- `动作 := 32` 表示申请构建组合,`动作 := 33` 表示组合解锁;框架后续可能标准化为 `34/35` 调入/调出数据。
|
||||||
|
- 对一个组合必须提供所有成分合约,且这些行的 `组 ID`、`动作`、`成交量` 相同。
|
||||||
|
- 期权动作 `0`、`32`、`33` 使用固定成交量法;动作 `1` 可使用固定成交量或可平仓数量占比法。
|
||||||
|
- 采用费率法时动作 `32/33` 的 `费率(%)` 为 `0`;采用费用法时对应 `费用` 为 `0`。
|
||||||
|
|
||||||
|
控制返回:
|
||||||
|
|
||||||
|
- 数量类在当前时点无交易时返回空数组。
|
||||||
|
- 比例类返回空数组表示完全清仓;比例类某个调仓日不调仓时返回非数组控制值,不要将其解释为交易字段。
|
||||||
|
|
||||||
### `GetTA(v_end_t)`
|
### `GetTA(v_end_t)`
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"""Library for validating and resolving evidence-backed framework profiles."""
|
"""Library for validating and resolving evidence-backed framework profiles."""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
from copy import deepcopy
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from lookup import (
|
from lookup import (
|
||||||
@@ -87,6 +88,17 @@ def validate_source_ids(data, rows):
|
|||||||
errors.append(
|
errors.append(
|
||||||
f"{section}[{entry_index}].evidence references unknown source {source}"
|
f"{section}[{entry_index}].evidence references unknown source {source}"
|
||||||
)
|
)
|
||||||
|
if section == "contracts" and isinstance(entry, dict):
|
||||||
|
for schema_index, schema in enumerate(
|
||||||
|
entry.get("return_schemas", [])
|
||||||
|
):
|
||||||
|
for source in evidence_set(schema):
|
||||||
|
if source not in known_sources:
|
||||||
|
errors.append(
|
||||||
|
f"contracts[{entry_index}].return_schemas"
|
||||||
|
f"[{schema_index}].evidence references unknown source "
|
||||||
|
f"{source}"
|
||||||
|
)
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|
||||||
@@ -209,6 +221,54 @@ def validate_framework(framework, rows, codegen_root, index):
|
|||||||
f"{framework['qualified_name']}.contracts[{contract_index}] "
|
f"{framework['qualified_name']}.contracts[{contract_index}] "
|
||||||
f"references unknown source {source}"
|
f"references unknown source {source}"
|
||||||
)
|
)
|
||||||
|
if not isinstance(contract, dict) or contract.get("status") != "resolved":
|
||||||
|
continue
|
||||||
|
discriminator = contract.get("mode_discriminator")
|
||||||
|
if not isinstance(discriminator, dict) or not discriminator.get("api"):
|
||||||
|
errors.append(
|
||||||
|
f"{framework['qualified_name']}.contracts[{contract_index}] resolved "
|
||||||
|
"contracts must contain mode_discriminator.api"
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
configured_apis = {
|
||||||
|
normalize(entry.get("api", ""))
|
||||||
|
for entry in framework.get("configuration", [])
|
||||||
|
if isinstance(entry, dict)
|
||||||
|
}
|
||||||
|
if normalize(discriminator["api"]) not in configured_apis:
|
||||||
|
errors.append(
|
||||||
|
f"{framework['qualified_name']}.contracts[{contract_index}]."
|
||||||
|
f"mode_discriminator.api {discriminator['api']!r} is not a "
|
||||||
|
"configuration member"
|
||||||
|
)
|
||||||
|
schemas = contract.get("return_schemas")
|
||||||
|
if not isinstance(schemas, list) or not schemas:
|
||||||
|
errors.append(
|
||||||
|
f"{framework['qualified_name']}.contracts[{contract_index}] resolved "
|
||||||
|
"contracts must contain return_schemas"
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
discriminator_field = discriminator["api"].rsplit(".", 1)[-1]
|
||||||
|
seen_values = set()
|
||||||
|
for schema_index, schema in enumerate(schemas):
|
||||||
|
path = (
|
||||||
|
f"{framework['qualified_name']}.contracts[{contract_index}]."
|
||||||
|
f"return_schemas[{schema_index}]"
|
||||||
|
)
|
||||||
|
if not isinstance(schema, dict):
|
||||||
|
errors.append(f"{path} must be an object")
|
||||||
|
continue
|
||||||
|
value = schema.get("when", {}).get(discriminator_field)
|
||||||
|
if value is None or str(value).strip() == "":
|
||||||
|
errors.append(f"{path}.when must select {discriminator_field}")
|
||||||
|
elif str(value) in seen_values:
|
||||||
|
errors.append(f"{path}.when duplicates {discriminator_field}={value}")
|
||||||
|
else:
|
||||||
|
seen_values.add(str(value))
|
||||||
|
if not isinstance(schema.get("fields"), list) or not schema["fields"]:
|
||||||
|
errors.append(f"{path}.fields must be a non-empty array")
|
||||||
|
if not evidence_set(schema):
|
||||||
|
errors.append(f"{path}.evidence must contain at least one source id")
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|
||||||
@@ -225,6 +285,47 @@ def validate_index(data, rows, codegen_root):
|
|||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|
||||||
|
def contract_mode_mapping(contract, configuration_api):
|
||||||
|
discriminator = contract.get("mode_discriminator", {})
|
||||||
|
return (
|
||||||
|
contract.get("status") == "resolved"
|
||||||
|
and normalize(discriminator.get("api", "")) == normalize(configuration_api)
|
||||||
|
and isinstance(contract.get("return_schemas"), list)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def resolved_contract_packet(contract, config):
|
||||||
|
packet = deepcopy(contract)
|
||||||
|
discriminator = packet.get("mode_discriminator")
|
||||||
|
packet["selected_return_schema"] = None
|
||||||
|
if not isinstance(discriminator, dict) or not discriminator.get("api"):
|
||||||
|
return packet
|
||||||
|
|
||||||
|
field = discriminator["api"].rsplit(".", 1)[-1]
|
||||||
|
schemas = packet.get("return_schemas", [])
|
||||||
|
values = [
|
||||||
|
str(schema.get("when", {}).get(field))
|
||||||
|
for schema in schemas
|
||||||
|
if schema.get("when", {}).get(field) is not None
|
||||||
|
]
|
||||||
|
packet["mode_discriminator"] = {
|
||||||
|
**discriminator,
|
||||||
|
"field": field,
|
||||||
|
"values": values,
|
||||||
|
}
|
||||||
|
if field in config:
|
||||||
|
requested = str(config[field])
|
||||||
|
packet["selected_return_schema"] = next(
|
||||||
|
(
|
||||||
|
schema
|
||||||
|
for schema in schemas
|
||||||
|
if str(schema.get("when", {}).get(field)) == requested
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
return packet
|
||||||
|
|
||||||
|
|
||||||
def scaffold_packet(framework, config):
|
def scaffold_packet(framework, config):
|
||||||
configured_names = {
|
configured_names = {
|
||||||
entry["api"].rsplit(".", 1)[-1]
|
entry["api"].rsplit(".", 1)[-1]
|
||||||
@@ -245,7 +346,15 @@ def scaffold_packet(framework, config):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
for entry in framework["configuration"]:
|
for entry in framework["configuration"]:
|
||||||
if entry.get("contract_evidence_required") and entry["api"].rsplit(".", 1)[-1] in config:
|
field = entry["api"].rsplit(".", 1)[-1]
|
||||||
|
if not entry.get("contract_evidence_required") or field not in config:
|
||||||
|
continue
|
||||||
|
mapped_contracts = [
|
||||||
|
contract
|
||||||
|
for contract in framework["contracts"]
|
||||||
|
if contract_mode_mapping(contract, entry["api"])
|
||||||
|
]
|
||||||
|
if not mapped_contracts:
|
||||||
diagnostics.append(
|
diagnostics.append(
|
||||||
{
|
{
|
||||||
"code": "CONTRACT_MODE_UNRESOLVED",
|
"code": "CONTRACT_MODE_UNRESOLVED",
|
||||||
@@ -258,6 +367,29 @@ def scaffold_packet(framework, config):
|
|||||||
"source_ids": entry.get("evidence", []),
|
"source_ids": entry.get("evidence", []),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
continue
|
||||||
|
requested = str(config[field])
|
||||||
|
available = {
|
||||||
|
str(schema.get("when", {}).get(field))
|
||||||
|
for contract in mapped_contracts
|
||||||
|
for schema in contract.get("return_schemas", [])
|
||||||
|
if schema.get("when", {}).get(field) is not None
|
||||||
|
}
|
||||||
|
if requested not in available:
|
||||||
|
diagnostics.append(
|
||||||
|
{
|
||||||
|
"code": "CONTRACT_MODE_UNKNOWN",
|
||||||
|
"severity": "error",
|
||||||
|
"message": (
|
||||||
|
f"{entry['api']}={requested!r} has no recorded return schema."
|
||||||
|
),
|
||||||
|
"next_action": (
|
||||||
|
"Use one of the documented mode values: "
|
||||||
|
+ ", ".join(sorted(available))
|
||||||
|
),
|
||||||
|
"source_ids": entry.get("evidence", []),
|
||||||
|
}
|
||||||
|
)
|
||||||
contract_status = "resolved"
|
contract_status = "resolved"
|
||||||
for contract in framework["contracts"]:
|
for contract in framework["contracts"]:
|
||||||
if contract.get("status") != "resolved":
|
if contract.get("status") != "resolved":
|
||||||
@@ -271,6 +403,15 @@ def scaffold_packet(framework, config):
|
|||||||
"source_ids": contract.get("evidence", []),
|
"source_ids": contract.get("evidence", []),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
contracts = [
|
||||||
|
resolved_contract_packet(contract, config)
|
||||||
|
for contract in framework["contracts"]
|
||||||
|
]
|
||||||
|
if any(
|
||||||
|
diagnostic["code"] in {"CONTRACT_MODE_UNKNOWN", "CONTRACT_MODE_UNRESOLVED"}
|
||||||
|
for diagnostic in diagnostics
|
||||||
|
):
|
||||||
|
contract_status = "incomplete"
|
||||||
return {
|
return {
|
||||||
"status": "resolved",
|
"status": "resolved",
|
||||||
"scaffold_status": "resolved",
|
"scaffold_status": "resolved",
|
||||||
@@ -285,6 +426,7 @@ def scaffold_packet(framework, config):
|
|||||||
"state_apis": framework["state_apis"],
|
"state_apis": framework["state_apis"],
|
||||||
"execution": framework["execution"],
|
"execution": framework["execution"],
|
||||||
"result_apis": framework["result_apis"],
|
"result_apis": framework["result_apis"],
|
||||||
|
"contracts": contracts,
|
||||||
"diagnostics": diagnostics,
|
"diagnostics": diagnostics,
|
||||||
"evidence": framework.get("evidence", []),
|
"evidence": framework.get("evidence", []),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ python <this-skill-dir>/scripts/class_lookup.py \
|
|||||||
- `scaffold_status=resolved` 只表示生命周期和成员引用完整。
|
- `scaffold_status=resolved` 只表示生命周期和成员引用完整。
|
||||||
- `contract_status` 不是 `resolved` 时,必须按 `diagnostics` 补齐模式与返回 schema 证据,
|
- `contract_status` 不是 `resolved` 时,必须按 `diagnostics` 补齐模式与返回 schema 证据,
|
||||||
并停止生成回调字段。
|
并停止生成回调字段。
|
||||||
|
- `contract_status=resolved` 时,`contracts[].return_schemas` 给出全部已验证模式;传入
|
||||||
|
`--config` 命中模式后,`contracts[].selected_return_schema` 给出当前配置对应的字段契约。
|
||||||
|
|
||||||
Framework Profile 只描述 API 协议,不定义 TSL 语法或代码结构。解析后的 Framework
|
Framework Profile 只描述 API 协议,不定义 TSL 语法或代码结构。解析后的 Framework
|
||||||
Contract Packet 仅作为已验证的 API 事实输出。
|
Contract Packet 仅作为已验证的 API 事实输出。
|
||||||
|
|||||||
@@ -633,7 +633,7 @@ class TslApiFrameworkTests(unittest.TestCase):
|
|||||||
packet = json.loads(result.stdout)
|
packet = json.loads(result.stdout)
|
||||||
self.assertEqual("resolved", packet["profile_status"])
|
self.assertEqual("resolved", packet["profile_status"])
|
||||||
self.assertEqual("resolved", packet["profile"]["scaffold_status"])
|
self.assertEqual("resolved", packet["profile"]["scaffold_status"])
|
||||||
self.assertEqual("incomplete", packet["profile"]["contract_status"])
|
self.assertEqual("resolved", packet["profile"]["contract_status"])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
["construct", "configure", "schedule", "callback", "execute", "inspect"],
|
["construct", "configure", "schedule", "callback", "execute", "inspect"],
|
||||||
[phase["phase"] for phase in packet["profile"]["lifecycle"]],
|
[phase["phase"] for phase in packet["profile"]["lifecycle"]],
|
||||||
@@ -770,7 +770,7 @@ class TslApiFrameworkTests(unittest.TestCase):
|
|||||||
packet = json.loads(result.stdout)
|
packet = json.loads(result.stdout)
|
||||||
profile = packet["profile"]
|
profile = packet["profile"]
|
||||||
self.assertEqual("resolved", profile["scaffold_status"])
|
self.assertEqual("resolved", profile["scaffold_status"])
|
||||||
self.assertEqual("incomplete", profile["contract_status"])
|
self.assertEqual("resolved", profile["contract_status"])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
["construct", "configure", "schedule", "callback", "execute", "inspect"],
|
["construct", "configure", "schedule", "callback", "execute", "inspect"],
|
||||||
[phase["phase"] for phase in profile["lifecycle"]],
|
[phase["phase"] for phase in profile["lifecycle"]],
|
||||||
@@ -779,12 +779,21 @@ class TslApiFrameworkTests(unittest.TestCase):
|
|||||||
["tsBackTesting.GetTradeOrder"],
|
["tsBackTesting.GetTradeOrder"],
|
||||||
[hook["api"] for hook in profile["hooks"] if hook["required"]],
|
[hook["api"] for hook in profile["hooks"] if hook["required"]],
|
||||||
)
|
)
|
||||||
|
self.assertEqual([], profile["diagnostics"])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
"CONTRACT_INCOMPLETE",
|
["tsBackTesting.GetTradeOrder"],
|
||||||
profile["diagnostics"][0]["code"],
|
[contract["callback"] for contract in profile["contracts"]],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
{
|
||||||
|
"api": "tsBackTesting.FGroupType",
|
||||||
|
"field": "FGroupType",
|
||||||
|
"values": ["1", "2"],
|
||||||
|
},
|
||||||
|
profile["contracts"][0]["mode_discriminator"],
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_candidate_discriminator_does_not_invent_a_mode(self):
|
def test_candidate_discriminator_resolves_ratio_schema(self):
|
||||||
result = run_script(
|
result = run_script(
|
||||||
CLASS_LOOKUP,
|
CLASS_LOOKUP,
|
||||||
"--class",
|
"--class",
|
||||||
@@ -799,12 +808,124 @@ class TslApiFrameworkTests(unittest.TestCase):
|
|||||||
packet = json.loads(result.stdout)
|
packet = json.loads(result.stdout)
|
||||||
profile = packet["profile"]
|
profile = packet["profile"]
|
||||||
self.assertEqual({"FGroupType": "1"}, profile["configured_values"])
|
self.assertEqual({"FGroupType": "1"}, profile["configured_values"])
|
||||||
self.assertEqual("incomplete", profile["contract_status"])
|
self.assertEqual("resolved", profile["contract_status"])
|
||||||
|
self.assertEqual([], profile["diagnostics"])
|
||||||
|
schema = profile["contracts"][0]["selected_return_schema"]
|
||||||
|
self.assertEqual("1", schema["when"]["FGroupType"])
|
||||||
|
self.assertEqual(
|
||||||
|
["截止日", "代码"],
|
||||||
|
[field["name"] for field in schema["fields"] if field.get("required")],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
[-1, 1],
|
||||||
|
schema["alternate_returns"][1]["documented_examples"],
|
||||||
|
)
|
||||||
|
self.assertTrue(
|
||||||
|
all(
|
||||||
|
field.get("pdf_non_empty")
|
||||||
|
for field in schema["fields"]
|
||||||
|
if field["name"] in {"截止日", "代码", "方向", "比例(%)"}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
"FRateType",
|
||||||
|
next(
|
||||||
|
field["required_when"]
|
||||||
|
for field in schema["fields"]
|
||||||
|
if field["name"] == "比例(%)"
|
||||||
|
)[0]["field"],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_candidate_discriminator_resolves_quantity_schema(self):
|
||||||
|
result = run_script(
|
||||||
|
CLASS_LOOKUP,
|
||||||
|
"--class",
|
||||||
|
"tsBackTesting",
|
||||||
|
"--config",
|
||||||
|
"FGroupType=2",
|
||||||
|
"--format",
|
||||||
|
"json",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(0, result.returncode, result.stderr)
|
||||||
|
profile = json.loads(result.stdout)["profile"]
|
||||||
|
self.assertEqual("resolved", profile["contract_status"])
|
||||||
|
self.assertEqual([], profile["diagnostics"])
|
||||||
|
schema = profile["contracts"][0]["selected_return_schema"]
|
||||||
|
self.assertEqual("2", schema["when"]["FGroupType"])
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"CONTRACT_MODE_UNRESOLVED",
|
"动作",
|
||||||
|
[field["name"] for field in schema["fields"] if field.get("required")],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
["empty_array"],
|
||||||
|
[item["type"] for item in schema["alternate_returns"]],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
{"组 ID", "组合类型"},
|
||||||
|
{
|
||||||
|
field["name"]
|
||||||
|
for field in schema["fields"]
|
||||||
|
if field["name"] in {"组 ID", "组合类型"}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
action = next(field for field in schema["fields"] if field["name"] == "动作")
|
||||||
|
self.assertEqual("0", action["compat_default"])
|
||||||
|
volume = next(field for field in schema["fields"] if field["name"] == "成交量")
|
||||||
|
self.assertEqual(
|
||||||
|
["32", "33"],
|
||||||
|
volume["record_required_when"]["动作"],
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
"FOpenVolType",
|
||||||
|
next(
|
||||||
|
field["required_when"]
|
||||||
|
for field in schema["fields"]
|
||||||
|
if field["name"] == "资金"
|
||||||
|
)[0]["field"],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_unknown_discriminator_value_is_reported(self):
|
||||||
|
result = run_script(
|
||||||
|
CLASS_LOOKUP,
|
||||||
|
"--class",
|
||||||
|
"tsBackTesting",
|
||||||
|
"--config",
|
||||||
|
"FGroupType=3",
|
||||||
|
"--format",
|
||||||
|
"json",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(0, result.returncode, result.stderr)
|
||||||
|
profile = json.loads(result.stdout)["profile"]
|
||||||
|
self.assertEqual("incomplete", profile["contract_status"])
|
||||||
|
self.assertIsNone(profile["contracts"][0]["selected_return_schema"])
|
||||||
|
self.assertIn(
|
||||||
|
"CONTRACT_MODE_UNKNOWN",
|
||||||
{item["code"] for item in profile["diagnostics"]},
|
{item["code"] for item in profile["diagnostics"]},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_get_trade_order_reference_records_mode_specific_fields(self):
|
||||||
|
result = run_script(
|
||||||
|
API_LOOKUP,
|
||||||
|
"--name",
|
||||||
|
"tsBackTesting.GetTradeOrder",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(0, result.returncode, result.stderr)
|
||||||
|
self.assertIn("FGroupType := 1", result.stdout)
|
||||||
|
self.assertIn("FGroupType := 2", result.stdout)
|
||||||
|
self.assertIn("`比例(%)`", result.stdout)
|
||||||
|
self.assertIn("`剩余资金占比(%)`", result.stdout)
|
||||||
|
self.assertIn("非数组", result.stdout)
|
||||||
|
|
||||||
|
def test_quantity_mode_discriminators_are_indexed_members(self):
|
||||||
|
for name in ("tsBackTesting.FOpenVolType", "tsBackTesting.FCloseVolType"):
|
||||||
|
with self.subTest(name=name):
|
||||||
|
result = run_script(API_LOOKUP, "--name", name)
|
||||||
|
self.assertEqual(0, result.returncode, result.stderr)
|
||||||
|
self.assertNotIn("No TSL API named", result.stdout)
|
||||||
|
|
||||||
def test_unknown_configuration_is_reported(self):
|
def test_unknown_configuration_is_reported(self):
|
||||||
result = run_script(
|
result = run_script(
|
||||||
CLASS_LOOKUP,
|
CLASS_LOOKUP,
|
||||||
|
|||||||
Reference in New Issue
Block a user