随着量化交易平台API接口的一次重大更新,平台的策略界面参数、交互控件等功能进行了调整,并新增了许多功能。之前的文章详细介绍了界面参数和交互控件的更新内容。本篇继续探讨FMZ.COM新引入的状态栏按钮的应用。
每位策略开发者都希望构建一个简单易用、功能强大且设计简约的UI界面。为了实现这一标准,FMZ.COM不遗余力地升级平台功能,提升用户体验。直接在策略页面状态栏中设计交互控件,正是基于这一需求的升级。
Tiếp theo, hãy xem các ứng dụng trong các kịch bản chiến lược đa dạng.
Bất kể chính sách nhiều giống hoàn toàn tự động hay chính sách nhiều giống chọn thời gian bán thủ công. Các giao diện UI chính sách sẽ yêu cầu một số nút tương tác chức năng, chẳng hạn như dừng, dừng thiệt hại, dọn dẹp toàn bộ, ủy quyền kế hoạch, v.v. cho một giống cố định.
Sau đó, chúng ta sẽ khám phá các tính năng mới của nút trạng thái trong một kịch bản sử dụng đơn giản nhất. Giả sử chiến lược của chúng ta là giao dịch nhiều loại:
Hợp đồng bất biến BTC_USDT, Hợp đồng bất biến ETH_USDT, Hợp đồng bất biến LTC_USDT, Hợp đồng bất biến BNB_USDT, Hợp đồng bất biến SOL_USDT
Cùng với việc thực hiện giao dịch tự động, chúng tôi muốn thiết kế nút mở cho mỗi giống trong thanh trạng thái của giao diện chiến lược.
Trước khi nâng cấp nền tảng này, nút trạng thái chỉ kích hoạt một thông báo tương tác nút. Không có cách nào để gắn một loạt các điều khiển để thiết lập thông báo phức tạp.
Một ví dụ về thiết kế:
// 设置操作的各个品种 BTC_USDT.swap 为FMZ平台定义的品种格式,表示BTC的U本位永续合约
var symbols = ["BTC_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "BNB_USDT.swap", "SOL_USDT.swap"]
// 根据按钮模板构造按钮
function createBtn(tmp, group) {
var btn = JSON.parse(JSON.stringify(tmp))
_.each(group, function(eleByGroup) {
btn["group"].unshift(eleByGroup)
})
return btn
}
function main() {
LogReset(1)
var arrManager = []
_.each(symbols, function(symbol) {
arrManager.push({
"symbol": symbol,
})
})
// Btn
var tmpBtnOpen = {
"type": "button",
"cmd": "open",
"name": "开仓下单",
"group": [{
"type": "selected",
"name": "tradeType",
"label": "下单类型",
"description": "市价单、限价单",
"default": 0,
"group": "交易设置",
"settings": {
"options": ["市价单", "限价单"],
"required": true,
}
}, {
"type": "selected",
"name": "direction",
"label": "交易方向",
"description": "买入、卖出",
"default": "buy",
"group": "交易设置",
"settings": {
"render": "segment",
"required": true,
"options": [{"name": "买入", "value": "buy"}, {"name": "卖出", "value": "sell"}],
}
}, {
"type": "number",
"name": "price",
"label": "价格",
"description": "订单的价格",
"group": "交易设置",
"filter": "tradeType==1",
"settings": {
"required": true,
}
}, {
"type": "number",
"name": "amount",
"label": "下单量",
"description": "订单的下单量",
"group": "交易设置",
"settings": {
"required": true,
}
}],
}
while (true) {
var tbl = {"type": "table", "title": "dashboard", "cols": ["symbol", "actionOpen"], "rows": []}
_.each(arrManager, function(m) {
var btnOpen = createBtn(tmpBtnOpen, [{"type": "string", "name": "symbol", "label": "交易品种", "default": m["symbol"], "settings": {"required": true}}])
tbl["rows"].push([m["symbol"], btnOpen])
})
var cmd = GetCommand()
if (cmd) {
Log("收到交互:", cmd)
// 解析交互消息: open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111}
// 根据第一个冒号:之前的指令判断是哪种按钮模板触发的消息
var arrCmd = cmd.split(":", 2)
if (arrCmd[0] == "open") {
var msg = JSON.parse(cmd.slice(5))
Log("交易品种:", msg["symbol"], ",交易方向:", msg["direction"], ",订单类型:", msg["tradeType"] == 0 ? "市价单" : "限价单", msg["tradeType"] == 0 ? ",订单价格:当前市价" : ",订单价格:" + msg["price"], ",订单数量:", msg["amount"])
}
}
// 输出状态栏信息
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
Sleep(1000)
}
}
Trước tiên, hãy xem hiệu ứng chạy, để làm chi tiết về thiết kế của điều khiển nút.
Nhấp vào một nút, bạn sẽ thấy một hộp gạch để cài đặt thông tin đặt hàng cụ thể:
Sau khi điền vào thông tin mở cửa chúng tôi đã thiết kế.
Bạn có thể thấy rằng chính sách đã nhận được tin nhắn, và trong mã, chúng tôi đã phân tích tin nhắn này và cài đặt để xuất lệnh này.
Đầu tiên, chúng ta xác định một template nút, một đối tượng JSON, và chúng ta gán giá trị cho biến tmpBtnOpen.
{
"type": "button", // 状态栏输出控件的类型,目前仅支持按钮
"cmd": "open", // 当按钮触发时,策略中GetCommand函数收到的消息前缀,例如这个例子:open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111}
"name": "开仓下单", // 策略界面,状态栏上的按钮上显示的内容,参考上图
"group": [{ // 当按钮触发时,弹框中的控件配置设置,这一层的group字段值是一个数组,弹框中的控件根据这个数组顺序自上而下排列
"type": "selected", // 第一个控件类型是:selected ,下拉框
"name": "tradeType", // 当状态栏按钮触发时,消息中包含该控件的设置内容,tradeType就是当前这个下拉框控件输入的值的键名。如果选择第一个选项「市价单」GetCommand函数收到的消息中就包含 "tradeType":0 的键值对信息。
"label": "下单类型", // 按钮触发时,弹框中当前控件的标题
"description": "市价单、限价单", // 当前控件的说明信息,鼠标放在控件右侧“小问号”图标上就会显示这个说明信息。
"default": 0, // 当前控件的默认值,例如当前是下拉框控件,如果不做选择,默认为下拉框第一个选项,通常下拉框的默认值指的是下拉框选项的索引,即第一个是0,然后是1,以此类推。如果下拉框的选项options是key-value形式则默认值指的是value。
"group": "交易设置", // 弹框中的控件如果很多,可以分组,这个字段可以设置分组信息
"settings": { // 当前这个下拉框的具体设置
"options": ["市价单", "限价单"], // options和下拉框相关的设置,用于设置下拉框中的选项,这个字段值是一个数组,依次排列下拉框中的选项。
"required": true, // required表示是否设置为必选(必填)内容。
}
}, {
"type": "selected", // 这也是一个下拉框类型
"name": "direction",
"label": "交易方向",
"description": "买入、卖出",
"default": "buy",
"group": "交易设置",
"settings": {
"render": "segment", // 和默认下拉框控件不同的是,通过render字段可以把下拉框替换为“分段选择器”,如上图中的“买入/卖出”控件。
"required": true,
"options": [{"name": "买入", "value": "buy"}, {"name": "卖出", "value": "sell"}], // 使用 key-value方式设置options
}
}, {
"type": "number", // 数值输入框类型控件
"name": "price",
"label": "价格",
"description": "订单的价格",
"group": "交易设置",
"filter": "tradeType==1", // 过滤器,可以用于确定是否显示当前控件,当tradeType==1时,表示是市价单,所以不需要该控件设置价格,所以不显示。
"settings": {
"required": true, // 当该控件激活显示时为必选(必填)
}
}, {
"type": "number",
"name": "amount",
"label": "下单量",
"description": "订单的下单量",
"group": "交易设置",
"settings": {
"required": true,
}
}],
}
nhóm
Vì đây chỉ là một ví dụ, trong thiết kế thực tế có thể có nhiều yêu cầu hơn, không giới hạn trong hướng, giá, số lượng, loại lệnh được thiết lập khi bắt đầu giao dịch.group
Các lĩnh vực, dễ dàng để tập hợp một nhóm các điều khiển trong khung hình, ví dụ như "Cách chọn giao dịch" trong hình ảnh trên.
required
Trong cấu trúc nútgroup
Các điều khiển được thiết lập trong trường đã được thêm vàorequired
Thiết lập các trường để thiết lập xem có phải là bắt buộc hay không, nếu được thiết lập là bắt buộc nhưng không được điền trong khi sử dụng, bạn không thể nhấp vào nút xác định để gửi thông báo tương tác và có thông báo gợi ý màu đỏ.
filter
Tăngfilter
Các trường được sử dụng để thiết lập độ phụ thuộc lọc, ví dụ như trong ví dụ trên nếu bạn chọn loại danh sách thị trường, thì giá đặt hàng là không cần thiết, bạn có thể thay đổi điều nàytype
"Số" nghĩa là "số".name
Điều khiển "price" được ẩn.
render
Các loại điều khiển cơ bản (setting type field): number, string, selected, boolean.render
Để thiết lập trình chiếu điều khiển, mỗi điều khiển có nhiều thành phần hiển thị riêng. Ví dụ, trong ví dụ trên, bạn có thể chọn trình chiếu điều khiển kéo xuống này là "chọn phân đoạn" bởi vì bạn cần nhấp hai lần vào khung kéo xuống (lần đầu tiên mở khung kéo xuống, lần thứ hai chọn tùy chọn), sử dụng các thành phần chọn phân đoạn, chỉ cần nhấp vào, bạn có thể chọn tùy chọn cần thiết.
Một người đọc cẩn thận cuối cùng có thể hỏi, trong hình ảnh trên, bạn không thấy thông tin điều khiển trong hộp hộp "Lịch sử giao dịch" và "Lịch sử giao dịch" không nằm trong nhóm "Lịch sử giao dịch" (tức là:
"group": "交易设置"
Điều này đã được thực hiện.)
Đây là một thiết kế cho phép nút trong bảng trạng thái gắn với thông tin khác trong bảng trạng thái, sử dụngcreateBtn
Chức năng dựa trên mẫutmpBtnOpen
Xây dựng cấu trúc nút cuối cùng, viết các thông tin khác vào cấu trúc nút khi xây dựng.
// 构造按钮的时候,绑定当前行的品种名称等信息,给按钮的弹框增加一个控件,并排在首位
var btnOpen = createBtn(tmpBtnOpen, [{"type": "string", "name": "symbol", "label": "交易品种", "default": m["symbol"], "settings": {"required": true}}])
Vì vậy, kết quả cuối cùng là khi bạn nhấp vào thanh trạng thái trên giao diện chính sách.symbol
ĐểBNB_USDT.swap
Khi nút trên dòng này được nhấn, hộp nhập "transaction variety" trong hộp nhấp chuột sẽ được tự động điền.BNB_USDT.swap
。
Bài viết này chỉ giới thiệu một phần nhỏ các ứng dụng của phiên bản UI mới, và vì tổng thể không thể quá dài, chúng tôi sẽ tiếp tục thảo luận về thiết kế cho các kịch bản nhu cầu khác trong bài viết tiếp theo.
Cảm ơn sự ủng hộ của bạn!