交易终端
平台提供模块化、可定制的交易终端页面:可以自由添加行情、交易等各种模块,模块可以拖动、缩放,可以修改模块绑定的交易所、交易对,同一类模块可以添加多个,方便手动交易和半程序化交易。
交易终端还支持交易插件:自己编写一段代码作为模块,在选定的托管者上执行,辅助手动交易。
插件原理与编写
原理
交易插件是一段在托管者上执行的短代码:在交易终端页面点击「执行」时,平台把插件代码和模块选定的交易所账户发送到选定的托管者执行,执行结束后把返回值显示在模块中。下面几个入口使用同一种执行机制:
| 入口 | 执行的代码 | 说明 |
|---|---|---|
| 交易终端插件 | 策略库中类型为「交易插件」的策略 | 在交易终端页面添加、执行 |
| 调试工具(开发工具) | 页面中临时编写的JavaScript代码 | 用于测试API调用 |
扩展API接口PluginRun | 请求中的source,或账号中已有的策略 | 供程序调用 |
MCP的plugin_*工具 | 平台内置的查询行情、下单等函数 | 供AI助手调用,按trade权限授权,见AI接入 |
这种执行方式不创建实盘、不计费,单次执行最长5分钟,超时中断。适合辅助手动交易的简单任务,例如冰山委托、批量挂单撤单、计算;需要长期运行的逻辑应创建实盘。
编写
在新建策略页面把策略类型设置为「交易插件」即可创建交易插件。交易插件、调试工具和PluginRun都只支持JavaScript。
插件的入口是main(),返回值就是执行结果:返回表格对象、图表对象时,在模块中显示为表格、图表(示例见插件示例)。插件中Log()输出的日志不会在模块中显示。
使用
- 添加:在交易终端页面打开模块添加菜单,账号策略库中的交易插件会出现在列表中,选择需要的插件添加。
- 执行:点击插件模块中的「执行」运行插件。
数据目录
插件和调试工具在托管者上执行时,以托管者运行目录下的logs/storage/p<数字>/为工作目录(每个平台账号一个以p开头的目录,第一次执行后创建)。如果交易终端使用的交易所账户以密钥文件路径(file:///xxx.txt)的方式配置密钥,需要把密钥文件放在这个目录中。
插件示例
插件可以在一段时间内执行代码,完成一些简单的操作,例如冰山委托、挂单、撤单、计算等。插件用return返回结果,返回表格、图表对象时直接显示为表格、图表。下面是两个例子,更多范例可以在策略广场中查找,例如逐笔小量买入/卖出。
返回深度快照
以表格显示当前盘口前15档:
javascript
// 返回深度快照
function main() {
var tbl = {
type: 'table',
title: '深度快照 @ ' + _D(),
cols: ['#', 'Amount', 'Ask', 'Bid', 'Amount'],
rows: []
}
var d = exchange.GetDepth()
var n = Math.min(d.Asks.length, d.Bids.length, 15)
for (var i = 0; i < n; i++) {
tbl.rows.push([i, d.Asks[i].Amount, d.Asks[i].Price + '#ff0000', d.Bids[i].Price + '#0000ff', d.Bids[i].Amount])
}
return tbl
}
画跨期差价
期货交易所对象上,取季度合约与当周合约的5分钟K线,画出收盘价差:
javascript
// 画跨期差价
var chart = {
__isStock: true,
title: {text: '差价分析图'},
xAxis: {type: 'datetime'},
yAxis: {
title: {text: '差价'},
opposite: false
},
series: [
{name: "diff", data: []}
]
}
function main() {
exchange.SetContractType('quarter')
var recordsA = exchange.GetRecords(PERIOD_M5)
exchange.SetContractType('this_week')
var recordsB = exchange.GetRecords(PERIOD_M5)
var n = Math.min(recordsA.length, recordsB.length)
for (var i = 0; i < n; i++) {
var a = recordsA[recordsA.length - n + i]
var b = recordsB[recordsB.length - n + i]
chart.series[0].data.push([a.Time, a.Close - b.Close])
}
return chart
}