策略
StrategiesWidget 显示正在运行的策略列表:每个策略一行,包含其状态、交易模式、持仓、订单和成交计数、盈利以及控制按钮。控件标识符为 strategies(ControlTypes.Strategies),也可通过静态属性 StrategiesWidget.TYPE 获取。

创建和更新
import {
StrategiesWidget,
StrategyStates,
type TradingHost,
} from '@stocksharp/trading-controls';
declare const host: TradingHost;
let strategies!: StrategiesWidget;
strategies = StrategiesWidget.create(
document.querySelector<HTMLElement>('#strategies')!,
{},
{
host,
tradingModes: ['Disabled', 'CancelOrders', 'ReducePosition', 'Full'],
start: id => console.log('start', id),
stop: id => console.log('stop', id),
closePosition: id => console.log('flatten', id),
openStrategy: id => console.log('open', id),
riskRules: id => console.log('risk', id),
setTradingMode: (id, mode) => console.log('mode', id, mode),
},
);
strategies.update([{
id: 'sma-1',
name: 'SMA crossover',
state: StrategyStates.Started,
online: true,
tradingMode: 'Full',
portfolio: 'Demo',
security: 'BTC@IMEX',
position: 0.25,
ordersCount: 12,
tradesCount: 8,
pnlChange: 105,
realized: 20,
unrealized: 85,
pnl: [
{ time: 1, value: 0 },
{ time: 2, value: 60 },
{ time: 3, value: 105 },
],
}]);
update 接收完整的数据行集合并用它替换表格:不在所传列表中的策略被视为已删除,其数据行会消失。控件没有单行的流式更新——新状态以整个列表的形式到达。
create 的第二个参数是实例的已保存状态。控件既不读取它,自己也不保存任何东西:既不写 host.preferences 中的键,也不调用 host.persistState。
StrategyStates 对象导出 Stopped、Starting、Started 和 Stopping 状态。
依赖
只有宿主是必填的。宿主的完整性在创建时由 assertHost 函数检查,因此不完整的 TradingHost 会导致抛出异常并指出缺失成员的名称,而不是留下一个不起作用的按钮。
| 依赖 | 是否必填 | 默认行为 |
|---|---|---|
host |
必填 | — |
start(id) |
可选 | 不创建启动按钮。 |
stop(id) |
可选 | 不创建停止按钮。 |
closePosition(id) |
可选 | 持仓列中只保留数字。 |
openStrategy(id) |
可选 | 不创建跳转到策略的按钮。 |
riskRules(id) |
可选 | 不创建风险规则按钮。 |
setTradingMode(id, mode) |
可选 | 交易模式以文本形式显示。 |
tradingModes |
可选 | 空列表,不创建模式下拉框。 |
这样的组合允许搭建一个只读面板:如果不传入任何操作函数,表格就只显示数据,而不显示任何按钮。
tradingModes 中的字符串会经过 host.t,也就是说它们是翻译键。它们属于宿主而不是本包,因此它们不出现在 translation-keys.json 中是正常的,翻译由宿主完成。
状态与操作
状态单元格由一个圆点和一个词组成:圆点便于快速浏览列表,词则区分 Starting 和 Started。如果行中填写了 error 字段,错误文本会同时出现在圆点和词的工具提示中,而因故障停止的策略会用“错误”而不是“已停止”标注。
行内按钮只为宿主传入的函数创建,并且只在状态允许的地方启用:
- 启动 — 仅对处于
Stopped状态的策略; - 停止 — 仅对处于
Started状态的策略; - 平仓 — 仅对持仓不为零的运行中策略;
- 风险规则和跳转到策略 — 始终可用。
交易模式下拉框只在策略已停止时可用:模式决定策略将以什么方式启动,而不是交易过程中的一个操纵杆。修改模式会调用 setTradingMode;控件自身不会改变行中的值,而是等待下一次 update。
列与外观
表格中显示状态、操作、在线标志、交易模式、名称、投资组合、标的、持仓、订单数和成交数、盈利变化、盈利图表、已实现和未实现盈利、错误。在线标志是综合性的:只有当策略既已构建又已连接时才算在线,这由数据提供方决定。
持仓、盈利变化以及两个盈利数值的颜色类由 host.presentation.pnlClass 返回。盈利变化还会额外标注方向箭头;变化为零时没有箭头。
图表列在 140 × 26 CSS 像素的区域内,按 pnl 中的点绘制累计盈利曲线。画布创建时考虑了 devicePixelRatio,因此在高像素密度屏幕上线条依然锐利。颜色取自 host.presentation.canvasPalette(),曲线按运行的最终结果着色:一个曾冲到高点又把一切回吐的策略会显示为亏损。没有 pnl 点时单元格保持为空。
默认排序是按名称升序:人们自上而下阅读列表来寻找某个具体策略,而随盈利变动重排行会妨碍这种阅读。面板还支持多行选择、上下文菜单、筛选和导出为 XLSX。
留给宿主的部分
控件不会启动或停止策略,不发送订单,也不平仓——它只调用传入的函数,然后等待新的数据行列表。
pnlChange 的值控件按原样接收:起算点由数据提供方选择。这样,重启后的策略就不会继续从重启之前的时刻开始计算变化。
面板的关闭按钮调用 host.close(),导出会生成 strategies 文件。实例在创建时向宿主注册,并在 dispose 中注销。
公共方法
StrategiesWidget.create(hostEl, state, deps)— 构建面板并把它添加到容器中。update(rows)— 替换整个策略列表。dispose()— 注销、删除表格并释放资源。