策略

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

带有状态、持仓、PnL 和收益曲线的策略列表

创建和更新

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 对象导出 StoppedStartingStartedStopping 状态。

依赖

只有宿主是必填的。宿主的完整性在创建时由 assertHost 函数检查,因此不完整的 TradingHost 会导致抛出异常并指出缺失成员的名称,而不是留下一个不起作用的按钮。

依赖 是否必填 默认行为
host 必填
start(id) 可选 不创建启动按钮。
stop(id) 可选 不创建停止按钮。
closePosition(id) 可选 持仓列中只保留数字。
openStrategy(id) 可选 不创建跳转到策略的按钮。
riskRules(id) 可选 不创建风险规则按钮。
setTradingMode(id, mode) 可选 交易模式以文本形式显示。
tradingModes 可选 空列表,不创建模式下拉框。

这样的组合允许搭建一个只读面板:如果不传入任何操作函数,表格就只显示数据,而不显示任何按钮。

tradingModes 中的字符串会经过 host.t,也就是说它们是翻译键。它们属于宿主而不是本包,因此它们不出现在 translation-keys.json 中是正常的,翻译由宿主完成。

状态与操作

状态单元格由一个圆点和一个词组成:圆点便于快速浏览列表,词则区分 StartingStarted。如果行中填写了 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() — 注销、删除表格并释放资源。

另请参阅