Type/to search
8
Follow
1361
Followers
Conception d'un système de gestion de synchronisation des commandes basé sur la quantification FMZ (1)
Original
Created 2022-02-14 19:46:30  Updated 2025-05-16 16:36:53
 11
 2243

img

Conception d'un système de gestion de synchronisation des commandes basé sur la quantification FMZ (1)

Dans les articles précédents de la bibliothèque FMZ, nous avons conçu plusieurs stratégies de synchronisation des commandes et des positions.

Il s'agit de regrouper le compte de référence et le compte de synchronisation dans une seule stratégie pour gérer et synchroniser les commandes et les positions. Aujourd'hui, nous allons essayer une conception différente. En nous basant sur la puissante interface API étendue de la plateforme de trading quantitative FMZ, nous allons concevoir un système de gestion de la synchronisation des commandes.

Idées de conception

Tout d’abord, nous avons besoin de bonnes suggestions et de bons besoins. Les deux stratégies de synchronisation des ordres et des positions ci-dessus présentent plusieurs problèmes évidents. Examinons-les ensemble :

    1. L'implémenteur de la stratégie de synchronisation doit disposer de la CLÉ API d'échange du compte de référence et de la CLÉ API d'échange du compte de synchronisation.
      Le scénario d'utilisation de cette question est le suivant : il n'y a aucun problème pour vos autres comptes d'échange de suivre l'un de vos propres comptes. Mais cela sera gênant si le compte de référence et le compte de synchronisation n’ont pas le même propriétaire. Parfois, pour des raisons de sécurité, le propriétaire d'un compte synchronisé ne souhaite pas fournir la CLÉ API de son compte d'échange. Mais comment puis-je passer des commandes de manière synchrone sans fournir de clé API ?

    Solution:
    En utilisant l'interface API étendue de FMZ, le propriétaire du compte de synchronisation (follower) n'a besoin que d'enregistrer la plateforme de trading quantitative FMZ, puis d'exécuter une stratégie (dans le système conçu dans cet article :订单同步管理系统(Synchronous Server)Stratégie marché réel). Fournissez ensuite la clé API étendue FMZ (attention, pas la clé API du compte d'échange) et l'ID en temps réel du système de gestion de synchronisation des commandes (Synchronous Server) au propriétaire du compte de référence (la personne qui passe la commande) .
    Lorsqu'il s'agit de la commande réelle du propriétaire du compte (celui avec la commande) (dans le système conçu dans cet article)订单同步管理系统类库(Single Server)) envoie un signal, le compte réel du propriétaire du compte synchronisé recevra le signal de trading et passera automatiquement une commande par la suite.

    1. De nombreux développeurs ont de meilleures stratégies, mais ne peuvent pas utiliser les deux stratégies de synchronisation des ordres et des positions passées décrites ci-dessus. Parce que cela nécessiterait d’intégrer sa propre stratégie à ces stratégies de synchronisation, et la stratégie pourrait devoir être révisée, ce qui serait long et laborieux. Existe-t-il un bon moyen de mettre à niveau certaines de mes stratégies matures directement vers la fonction de synchronisation des commandes ?
      Solution:
      Vous pouvez concevoir une bibliothèque de modèles de synchronisation de commandes (dans le système conçu dans cet article)订单同步管理系统类库(Single Server)Stratégie), permettant au propriétaire du compte de référence (la personne qui prend la commande) d'intégrer directement cette bibliothèque de modèles dans sa propre stratégie pour réaliser la fonction de synchronisation des commandes et des positions.
    1. Réduisez d’un ordre réel supplémentaire.
      Le dernier problème survient si vous utilisez les deux stratégies de synchronisation des commandes et des positions passées décrites ci-dessus. Il est nécessaire d'ouvrir un compte réel supplémentaire pour suivre les positions du compte de référence (avec un seul compte).
      Solution:
      Utilisez la bibliothèque de modèles pour intégrer des fonctionnalités dans les stratégies de compte de référence.

Ce système se compose donc de 2 parties :

  1. Bibliothèque de classes du système de gestion de la synchronisation des commandes (serveur unique)
  2. Commandez le système de gestion synchrone (serveur synchrone)

Maintenant que les exigences sont claires, commençons la conception !

Conception 1 : Bibliothèque de classes du système de gestion de la synchronisation des commandes (serveur unique)

Notez que ce n’est pas une stratégie. Il s'agit d'une bibliothèque de classes de modèles de FMZ. Le concept de bibliothèque de classes de modèles peut être recherché dans la documentation de l'API FMZ, je n'entrerai donc pas dans les détails ici.

Code de la bibliothèque de modèles :

javascript
// 全局变量 var keyName_label = "label" var keyName_robotId = "robotId" var keyName_extendAccessKey = "extendAccessKey" var keyName_extendSecretKey = "extendSecretKey" var fmzExtendApis = parseConfigs([config1, config2, config3, config4, config5]) var mapInitRefPosAmount = {} function parseConfigs(configs) { var arr = [] _.each(configs, function(config) { if (config == "") { return } var strArr = config.split(",") if (strArr.length != 4) { throw "configs error!" } var obj = {} obj[keyName_label] = strArr[0] obj[keyName_robotId] = strArr[1] obj[keyName_extendAccessKey] = strArr[2] obj[keyName_extendSecretKey] = strArr[3] arr.push(obj) }) return arr } function getPosAmount(pos, ct) { var longPosAmount = 0 var shortPosAmount = 0 _.each(pos, function(ele) { if (ele.ContractType == ct && ele.Type == PD_LONG) { longPosAmount = ele.Amount } else if (ele.ContractType == ct && ele.Type == PD_SHORT) { shortPosAmount = ele.Amount } }) var timestamp = new Date().getTime() return {ts: timestamp, long: longPosAmount, short: shortPosAmount} } function sendCommandRobotMsg (robotId, accessKey, secretKey, msg) { // https://www.fmz.com/api/v1?access_key=xxx&secret_key=yyyy&method=CommandRobot&args=[186515,"ok12345"] var url = "https://www.fmz.com/api/v1?access_key=" + accessKey + "&secret_key=" + secretKey + "&method=CommandRobot&args=[" + robotId + ',"' + msg + '"]' Log(url) var ret = HttpQuery(url) return ret } function follow(nowPosAmount, symbol, ct, type, delta) { var msg = "" var nowAmount = type == PD_LONG ? nowPosAmount.long : nowPosAmount.short if (delta > 0) { // 开仓 var tradeDirection = type == PD_LONG ? "buy" : "sell" // 发送信号 msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta) } else if (delta < 0) { // 平仓 var tradeDirection = type == PD_LONG ? "closebuy" : "closesell" if (nowAmount <= 0) { Log("未检测到持仓") return } // 发送信号 msg = symbol + "," + ct + "," + tradeDirection + "," + Math.abs(delta) } else { throw "错误" } if (msg) { _.each(fmzExtendApis, function(extendApiConfig) { var ret = sendCommandRobotMsg(extendApiConfig[keyName_robotId], extendApiConfig[keyName_extendAccessKey], extendApiConfig[keyName_extendSecretKey], msg) Log("调用CommandRobot接口,", "label:", extendApiConfig[keyName_label], ", msg:", msg, ", ret:", ret) Sleep(1000) }) } } $.PosMonitor = function(exIndex, symbol, ct) { var ts = new Date().getTime() var ex = exchanges[exIndex] // 判断ex类型 var exName = ex.GetName() var isFutures = exName.includes("Futures_") var exType = isFutures ? "futures" : "spot" if (!isFutures) { throw "仅支持期货跟单" } if (exType == "futures") { // 缓存 symbol ct var buffSymbol = ex.GetCurrency() var buffCt = ex.GetContractType() // 切换到对应的交易对、合约代码 ex.SetCurrency(symbol) if (!ex.SetContractType(ct)) { throw "SetContractType failed" } // 监控持仓 var keyInitRefPosAmount = "refPos-" + exIndex + "-" + symbol + "-" + ct // refPos-exIndex-symbol-contractType var initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount] if (!initRefPosAmount) { // 没有初始化数据,初始化 mapInitRefPosAmount[keyInitRefPosAmount] = getPosAmount(_C(ex.GetPosition), ct) initRefPosAmount = mapInitRefPosAmount[keyInitRefPosAmount] } // 监控 var nowRefPosAmount = getPosAmount(_C(ex.GetPosition), ct) // 计算仓位变动 var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short // 检测变动 if (!(longPosDelta == 0 && shortPosDelta == 0)) { // 执行多头动作 if (longPosDelta != 0) { Log(ex.GetName(), ex.GetLabel(), symbol, ct, "执行多头跟单,变动量:", longPosDelta) follow(nowRefPosAmount, symbol, ct, PD_LONG, longPosDelta) } // 执行空头动作 if (shortPosDelta != 0) { Log(ex.GetName(), ex.GetLabel(), symbol, ct, "执行空头跟单,变动量:", shortPosDelta) follow(nowRefPosAmount, symbol, ct, PD_SHORT, shortPosDelta) } // 执行跟单操作后,更新 mapInitRefPosAmount[keyInitRefPosAmount] = nowRefPosAmount } // 恢复 symbol ct ex.SetCurrency(buffSymbol) ex.SetContractType(buffCt) } else if (exType == "spot") { // 现货 } } $.getTbl = function() { var tbl = { "type" : "table", "title" : "同步数据", "cols" : [], "rows" : [] } // 构造表头 tbl.cols.push("监控账户:refPos-exIndex-symbol-contractType") tbl.cols.push(`监控持仓:{"时间戳":xxx,"多头持仓量":xxx,"空头持仓量":xxx}`) _.each(fmzExtendApis, function(extendApiData, index) { tbl.cols.push(keyName_robotId + "-" + index) }) // 写入数据 _.each(mapInitRefPosAmount, function(initRefPosAmount, key) { var arr = [key, JSON.stringify(initRefPosAmount)] _.each(fmzExtendApis, function(extendApiData) { arr.push(extendApiData[keyName_robotId]) }) tbl.rows.push(arr) }) return tbl } // 引用该模板类库的策略调用范例 function main() { // 清除所有日志 LogReset(1) // 切换到OKEX 模拟盘测试 exchanges[0].IO("simulate", true) // 设置合约 exchanges[0].SetCurrency("ETH_USDT") exchanges[0].SetContractType("swap") // 定时交易时间间隔 var tradeInterval = 1000 * 60 * 3 // 三分钟交易一次,用于观察跟单信号 var lastTradeTS = new Date().getTime() while (true) { // 策略其它逻辑... // 用于测试的模拟交易触发 var ts = new Date().getTime() if (ts - lastTradeTS > tradeInterval) { Log("模拟带单策略发生交易,持仓变化", "#FF0000") exchanges[0].SetDirection("buy") exchanges[0].Buy(-1, 1) lastTradeTS = ts } // 使用模板的接口函数 $.PosMonitor(0, "ETH_USDT", "swap") // 可以设置多个监控,监控带单策略上的不同的exchange对象 var tbl = $.getTbl() // 显示状态栏 LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`") Sleep(1000) } }

La conception est très simple, cette bibliothèque de classes a 2 fonctions fonctionnelles. Lorsqu'une stratégie de trading programmatique sur la plateforme FMZ fait référence订单同步管理系统类库(Single Server)Après la bibliothèque de modèles. Cette stratégie peut être implémentée à l’aide de la fonction suivante.

  • $.PosMonitor
    La fonction est de surveiller les changements de position de l'objet d'échange dans la stratégie, puis d'envoyer des signaux de trading au marché réel défini dans les paramètres du modèle : Bibliothèque de classes du système de gestion de la synchronisation des ordres (serveur unique).

  • $.getTbl
    Renvoie les données de synchronisation surveillées.

L'exemple d'utilisation est dans : Bibliothèque de classes du système de gestion de la synchronisation des commandes (modèle de serveur unique)mainDans la fonction :

javascript
// 引用该模板类库的策略调用范例 function main() { // 清除所有日志 LogReset(1) // 切换到OKEX 模拟盘测试 exchanges[0].IO("simulate", true) // 设置合约 exchanges[0].SetCurrency("ETH_USDT") exchanges[0].SetContractType("swap") // 定时交易时间间隔 var tradeInterval = 1000 * 60 * 3 // 三分钟交易一次,用于观察跟单信号 var lastTradeTS = new Date().getTime() while (true) { // 策略其它逻辑... // 用于测试的模拟交易触发 var ts = new Date().getTime() if (ts - lastTradeTS > tradeInterval) { Log("模拟带单策略发生交易,持仓变化", "#FF0000") exchanges[0].SetDirection("buy") exchanges[0].Buy(-1, 1) lastTradeTS = ts } // 使用模板的接口函数 $.PosMonitor(0, "ETH_USDT", "swap") // 可以设置多个监控,监控带单策略上的不同的exchange对象 var tbl = $.getTbl() // 显示状态栏 LogStatus(_D(), "\n" + "`" + JSON.stringify(tbl) + "`") Sleep(1000) } }

Une bibliothèque de modèles elle-même peut également créer de véritables stratégies, qui sont généralement utilisées pour tester la bibliothèque de modèles. Par exemple, un test de ce modèle. Vous pouvez comprendre le modèlemainUne fonction est une stratégie qui vous est propre.mainfonction.

Le code de test est écrit pour utiliser le test du disque de simulation OKEX. Il est nécessaire de configurer la clé API du disque de simulation OKEX sur FMZ comme compte de référence (avec commandes) et de commencer à basculer vers le disque de simulation dans la fonction principale. Définissez ensuite la paire de trading sur ETH_USDT et le contrat sur perpétuel (swap). Entrez ensuite une boucle while. Un ordre est passé toutes les 3 minutes dans le cycle pour simuler le déclenchement du trading de stratégie. La boucle while appelle$.PosMonitor(0, "ETH_USDT", "swap")Le premier paramètre de cette fonction est passé à 0, indiquant la surveillance des échanges[0] Cet objet d'échange surveille la paire de trading ETH_USDT et le contrat de swap. Alors appelle$.getTbl()Pour obtenir des informations sur le graphique, utilisezLogStatus(_D(), "\n" + "" + JSON.stringify(tbl) + "")Permet d'afficher les données du graphique dans la barre d'état.

Donc vous voyez, tant que vous l'utilisez dans une politique qui fait référence à ce modèle$.PosMonitor(0, "ETH_USDT", "swap"), la stratégie peut être équipée de la fonction de surveillance des positions d'un certain produit et d'envoi de messages en fonction des changements de position.

Avant de tester, veuillez expliquer订单同步管理系统类库(Single Server)Conception des paramètres de stratégie :
Je viens de parler de la façon d'utiliser la fonction d'interface de modèle pour permettre à une mise à niveau de stratégie d'avoir une fonction unique. Alors à qui est envoyé le signal lorsque la position change ?
La personne à qui cette question est envoyée est déterminée par订单同步管理系统类库(Single Server)Paramètres à configurer.

img

Vous pouvez voir qu'il y a 5 paramètres, prenant en charge jusqu'à 5 pushs (vous pouvez l'étendre si vous avez besoin de l'augmenter), et le paramètre par défaut est une chaîne vide, ce qui signifie qu'il n'est pas traité. Format de la chaîne de configuration : label, robotId, accessKey, secretKey

  • label
    L'étiquette du compte synchronisé est utilisée pour marquer un certain compte, et le nom peut être défini à volonté.

  • robotId
    ID réel, créé par le propriétaire du compte de synchronisation订单同步管理系统(Synchronous Server)L'ID de la transaction réelle.

  • accessKey
    Accès étendu à l'API FMZKey

  • secretKey
    Clé secrète de l'API étendue de FMZ

Ensuite, nous pouvons faire un test simple.

Bibliothèque de classes du système de gestion de synchronisation des commandes (serveur unique) fonctionnement du disque réel :

img

Le système de gestion de synchronisation des commandes (Synchronous Server) a reçu le signal :
Nous n'avons pas encore terminé la conception du système de gestion de la synchronisation des commandes (Synchronous Server). Commençons d'abord par l'implémenter avec un code simple qui ne fait pas de transactions mais imprime seulement des signaux :

Code temporaire du système de gestion de la synchronisation des commandes (Synchronous Server) :

javascript
function main() { LogReset(1) while (true) { var cmd = GetCommand() if (cmd) { // cmd: ETH_USDT,swap,buy,1 Log("cmd: ", cmd) } Sleep(1000) } }

img

Vous pouvez voir que le compte réel du propriétaire du compte de synchronisation a reçu les informations :ETH_USDT,swap,buy,1
De cette façon, l’étape suivante consiste à suivre automatiquement l’ordre en fonction de la paire de trading, du code du contrat, de la direction de trading et de la quantité dans les informations.

à l'heure actuelle订单同步管理系统(Synchronous Server)Il s'agit simplement d'un code temporaire, nous continuerons à explorer sa conception dans le prochain numéro.

Related Recommendations
Comment
All comments (11)

    要实现跟单,还是需要两个实盘,一个是类库实盘,一个是订单管理系统实盘

    4 years ago

    您可能没看明白文章,这个类库是一个工具,可以在带单者策略行直接嵌入,然后这个策略就有带单功能了,就会给设置好的跟单账户发信息,跟单机器人就会收到消息跟单了。
    简单说就是这样的场景。

    4 years ago

    按教程弄的,显示配置错误

    4 years ago

    要看具体报什么错误信息。

    4 years ago

    错误 configs error!,在订单同步管理系统类库(Single Server)中,把带单者实盘和2个KEY都填进去了,然后再实盘中引用了订单同步管理系统类库(Single Server),报错,错误 configs error!

    4 years ago

    可以看下文章,配置信息: 标签,实盘ID,accesskey,secretkey 。 报这个错误应该就是您信息配置错了,您再检查下。注意使用英文逗号间隔。

    4 years ago

    错误 configs error!

    4 years ago

    反向跟单需要改哪些参数

    4 years ago

    需要改策略。

    4 years ago

    自己跟单自己也要开两个实盘,一个发信号一个收信号,这两个能合并一起实盘用么

    4 years ago

    代码公开的,您可以根据需求修改一下,就可以实现。

    4 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)