
Mit einem umfassenden Update der API-Schnittstelle der quantitativen Handelsplattform wurden die Parameter der Strategieschnittstelle, die interaktiven Steuerelemente und andere Funktionen der Plattform angepasst und viele neue Funktionen hinzugefügt. Im vorherigen Artikel wurden die Aktualisierungen der Schnittstellenparameter und interaktiven Steuerelemente ausführlich vorgestellt. In diesem Artikel wird weiterhin die Anwendung der neu eingeführten Statusleistenschaltfläche von FMZ.COM untersucht.
Jeder Strategieentwickler möchte eine Benutzeroberfläche erstellen, die benutzerfreundlich, leistungsstark und einfach im Design ist. Um diesen Standard zu erreichen, unternimmt FMZ.COM keine Mühen, die Plattformfunktionen zu aktualisieren und das Benutzererlebnis zu verbessern. Die Gestaltung interaktiver Steuerelemente direkt in der Statusleiste der Strategieseite ist eine Weiterentwicklung dieser Nachfrage.
Als Nächstes betrachten wir die Anwendung in einem Szenario mit verschiedenen Strategien.
Egal ob es sich um eine vollautomatische Multi-Varietät-Arbitrage-Strategie oder eine halbmanuelle Multi-Varietät-Timing-Strategie handelt. Die Strategie-Benutzeroberfläche muss über einige funktionale interaktive Schaltflächen verfügen, wie etwa Take-Profit, Stop-Loss, Liquidation, geplante Betrauung usw. für ein bestimmtes Produkt.
Lassen Sie uns anschließend die neuen Funktionen der Statusleistenschaltfläche anhand eines einfachsten Anwendungsszenarios erkunden. Nehmen wir an, dass unsere Strategie mehrere Symbole handelt:
BTC_USDT Unbefristeter Vertrag, ETH_USDT Unbefristeter Vertrag, LTC_USDT Unbefristeter Vertrag, BNB_USDT Unbefristeter Vertrag, SOL_USDT Unbefristeter Vertrag
Während die Strategie den automatischen Handel ausführt, möchten wir in der Statusleiste der Strategieschnittstelle eine Schaltfläche zum Öffnen für jedes Produkt entwerfen. Dieser Button zum Öffnen von Positionen erfordert jedoch eine Reihe detaillierter Einstellungen, beispielsweise:
Vor diesem Plattform-Upgrade löste die Statusleistenschaltfläche lediglich eine Schaltflächeninteraktionsnachricht aus. Es gibt keine Möglichkeit, eine Reihe von Steuerelementen zu binden, um komplexe Nachrichten einzurichten. Dieses Upgrade der Interaktion löst dieses Bedürfnis. Werfen wir einen Blick auf den Codeentwurf. Dem Code werden detaillierte Kommentare hinzugefügt, um das Verständnis der Erstellung einer solchen Funktion zu erleichtern.
Designbeispiele:
// 设置操作的各个品种 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)
}
}
Schauen wir uns zunächst den Laufeffekt an und erläutern dann das Design der Tastensteuerung im Detail. Der Strategiecode wird wie folgt ausgeführt:

Klicken Sie auf eine Schaltfläche. Ein Popup-Fenster zum Konfigurieren der spezifischen Bestellinformationen wird angezeigt:

Nach dem Ausfüllen der von uns gestalteten Eröffnungsinformationen.

Sie können sehen, dass die Strategie die Nachricht empfangen hat und wir im Code die Nachricht analysiert und die verschiedenen Einstellungen für die Bestellung ausgegeben haben. Schauen wir uns als Nächstes an, wie diese Schaltfläche aufgebaut ist:
Zuerst definieren wir eine Schaltflächenvorlage, die ein JSON-Objekt ist, und weisen sie der Variable tmpBtnOpen zu. Ich habe die spezifischen Anweisungen direkt in die Codekommentare unten eingefügt.
{
"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,
}
}],
}
group
Da es sich hierbei nur um ein Beispiel handelt, können bei der tatsächlichen Gestaltung und Verwendung weitere Anforderungen gelten, die nicht auf die beim Öffnen einer Position festgelegte Auftragsrichtung, den Preis, die Menge und den Auftragstyp beschränkt sind. Möglicherweise sind auch Ausstiegsregeln wie Take-Profit- und Stop-Loss-Planaufträge vorgesehen. Die neue Benutzeroberfläche unterstütztgroupFeld, mit dem sich eine Gruppe von Steuerelementen im Popup-Fenster bequem zur Anzeige zusammenfassen lässt, wie z. B. die reduzierte Einstellung „Transaktionseinstellungen“ im obigen Screenshot.
required
TastenstrukturgroupDie im Feld festgelegten Kontrollen wurden erhöhtrequiredÜber das Einstellungsfeld wird festgelegt, ob es obligatorisch (erforderlich) ist. Wenn es auf obligatorisch (erforderlich) eingestellt ist, aber während der Verwendung nicht ausgefüllt (ausgewählt) wird, können Sie nicht auf die Schaltfläche OK klicken, um die interaktiven Informationen zu senden, und ein rotes Es wird eine Eingabeaufforderungsmeldung angezeigt.
filter
HinzugefügtfilterDas Feld wird verwendet, um Filterabhängigkeiten festzulegen. Wenn im obigen Beispiel beispielsweise der Marktauftragstyp ausgewählt ist, ist der Auftragspreis nicht erforderlich.typeist “Zahl”,nameDie Bedienelemente für „Preis“ sind ausgeblendet.
render
Für diese grundlegenden Steuerelementtypen (Typfeldeinstellungen): Zahl, Zeichenfolge, Auswahl, Boolescher Wert. Hinzugefügte FelderrenderWird zum Einstellen der Steuerelementdarstellung verwendet. Jedes Steuerelement verfügt über mehrere eigene Darstellungskomponenten. Im obigen Beispiel ist es beispielsweise angemessener, das ausgewählte Dropdown-Feld-Steuerelement als “Segmentauswahl” darzustellen, da das Dropdown-Feld zweimal angeklickt werden muss (das erste Mal, um das Dropdown-Feld zu erweitern , und das zweite Mal, um eine Option auszuwählen). Verwenden Sie die Segmentauswahlkomponente , klicken Sie einfach und wählen Sie die gewünschte Option aus.
Abschließend werden aufmerksame Leser fragen: Im obigen Screenshot sehe ich die Kontrollinformationen nicht in dem Popup-Fenster, in dem Sie „Handelstyp“ geschrieben haben, und dieser „Handelstyp“ gehört nicht zur Gruppe „Handelseinstellungen“ (dh:
"group": "交易设置"Diese Einstellung implementiert).
Hier ist eine Demonstration eines Designs, das die Schaltflächen in der Statusleistentabelle an andere Informationen in der Statusleiste bindet.createBtnFunktion basierend auf VorlagetmpBtnOpenKonstruieren Sie die endgültige Schaltflächenstruktur und schreiben Sie während der Konstruktion weitere Informationen in die Schaltflächenstruktur.
// 构造按钮的时候,绑定当前行的品种名称等信息,给按钮的弹框增加一个控件,并排在首位
var btnOpen = createBtn(tmpBtnOpen, [{"type": "string", "name": "symbol", "label": "交易品种", "default": m["symbol"], "settings": {"required": true}}])
Der endgültige Effekt ist, dass Sie, wenn Sie auf die Statusleiste auf der Strategieoberfläche klicken,symbolfürBNB_USDT.swapWenn Sie auf die Schaltfläche in dieser Zeile klicken, wird das Eingabefeld „Handelsart“ im Popup-Fenster automatisch ausgefüllt.BNB_USDT.swap。
Dieser Artikel stellt nur einen kleinen Teil der Anwendung der neuen Version der Benutzeroberfläche vor. Da die Gesamtlänge nicht zu lang sein kann, werden wir im nächsten Artikel das Design anderer Anforderungsszenarien weiter diskutieren.
Danke für Ihre Unterstützung!