Je suis désolé.
GetExchangeList()
renvoie la liste des échanges pris en charge et les informations de configuration requises.
Paramètre Aucune
Valeur de retour
{
"code": 0,
"data": {
"result": {
"exchanges": [{
"website": "https://www.huobi.pro/",
"name": "Huobi",
"priority": 1,
"meta": "[{"desc": "Access Key", "required": true, "type": "string", "name": "AccessKey", "label": "Access Key"}, {"encrypt": true, "name": "SecretKey", "required": true, "label": "Secret Key", "type": "password", "desc": "Secret Key"}]",
"eid": "Huobi",
"logo": "huobi.png",
"id": 1
}, {
"website": "https://www.kex.com/",
"name": "KEX",
"priority": -99,
"meta": "[{"desc": "Access Key", "required": true, "type": "string", "name": "AccessKey", "label": "Access Key"}, {"encrypt": true, "name": "SecretKey", "required": true, "label": "Secret Key", "type": "password", "desc": "Secret Key"}, {"encrypt": true, "required": true, "type": "password", "name": "Password", "label": "Trading Password"}]",
"eid": "KEX",
"logo": "",
"id": 43
},
...
]
},
"error": null
}
}
DeleteNode(Nid)
supprime le nœud d'accueil (ID
estNid
) correspondant à laAPI KEY
à la demande du compte de la plateforme de négociation FMZ Quant.
ParamètreNid
est de type entier, à savoir le dockerID
.
Retour de valeur
{
"code":0,
"data":{
"result":true,
"error":null
}
}
DeleteRobot(RobotId, DeleteLogs)
supprime le robot avec l'ID spécifié (robotID
: RobotId
) correspondant à laAPI KEY
dans la demande au titre du compte FMZ Quant.
ParamètreRobotId
est de type entier, à savoir le robotID
à supprimer.DeleteLogs
est de type booléen; ensembleDeleteLogs
pour décider de supprimer ou non le journal;true
indique la suppression du journal.
Retour de valeur
// Return value after successful deletion
{
"code": 0,
"data": {
"result": 0,
"error": null
}
}
GetStrategyList()
Il obtient les informations stratégiques correspondant à laAPI KEY
à la demande du compte de la plateforme de négociation FMZ Quant.
Paramètre Aucune
Valeur de retour
{
"code": 0,
"data": {
"result": {
"strategies": [{
"category": 0,
"username": "yifidslei",
"is_owner": true,
"name": "fmz simulation market test strategy",
"language": 0,
"hasToken": false,
"args": "[]",
"is_buy": false,
"public": 0,
"last_modified": "2018-01-18 12:36:03",
"date": "2018-01-17 09:19:32",
"forked": 0,
"id": 63372
}, {
"category": 20,
"username": "bifndslez",
"is_owner": true,
"name": "Line drawing library",
"language": 0,
"hasToken": false,
"args": "[]",
"is_buy": false,
"public": 0,
"last_modified": "2017-05-08 09:44:18",
"date": "2017-04-19 10:38:14",
"forked": 0,
"id": 39677
},
...
],
"all": 20
},
"error": null
}
}
NewRobot(Settings)
crée un nouveau bot selon les paramètres,API KEY
dans la demande du compte FMZ Quant.
ParamètreSettings
est deJSON
type d'objet.Settings
est unJSON
Objet configuré par le bot.
LeSettings
la description est expliquée comme suit:
Settings = {
"name": "hedge test",
/*
Strategy parameters; the order does not have to be in correspondence with the parameter order, but the name must be the same as the parameter name
Note: the second element in the parameter array ["MAType", 0, 75882] is an array including three elements, in which the first one "MAType" is the parameter on the pattern referred by the bot-binding strategy, and the second one "0" is the specific value set by the parameter "MAType", and the third one "75882" is the pattern ID containing the parameter "MAType"
*/
"args": [["Interval", 500], ["MAType", 0, 75882]],
// Strategy ID, which can be obtained by "GetStrategyList" method
"strategy": 25189,
// K-line period parameter; "60" indicates 60 seconds
"period": 60,
// it can be specified to run on which docker; no writing of the attribute will lead to automatic assignment
"node" : 52924,
// custom field
"appid": "member2",
// Specify a bot group
"group": 1122,
"exchanges": [
// ZB; "pid" can be obtained by "GetPlatformList" method
{"pid": 15445, "pair": "ETH_BTC"},
// OKEX
{"pid": 13802, "pair": "BCH_BTC"},
// In addition to the exchanges configured by the FMZ dashboard (pid identification), you can also set exchange configuration information that has not been configured to operate the bot
{"eid": "OKEX", "pair": "ETH_BTC", "meta" :{"AccessKey": "xxx", "SecretKey": "yyy"}},
{"eid": "Huobi", "pair": "BCH_BTC", "meta" :{"AccessKey": "xxx", "SecretKey": "yyy"}}
]
}
Note: le numéro de série
Lorsque vous utilisez des informations sensibles, telles que la plateformeAPI KEY
, y compris"meta":{"AccessKey":"xxx","SecretKey":"yyy"}
dans la configuration deeid
, vous devez savoir que FMZ ne stocke pas les données. Les données seront envoyées directement au programme docker, donc ces informations doivent être configurées à chaque fois que le bot est créé ou redémarré.
Pour redémarrer le bot qui utilise le plugin pour supporter la plate-forme, lors de la configuration duSettings
paramètre, vous devez effectuer les réglages suivants pour leexchanges
attribut:
{"eid": "Exchange", "label" : "testXXX", "pair": "ETH_BTC", "meta" :{"AccessKey": "123", "SecretKey": "1234", "Front" : "http://127.0.0.1:6666/XXX"}}
label
L'attribut est de définir une étiquette pour l'objet d'échange accessible par le protocole général actuel, qui peut être obtenue par leexchange.GetLabel()
Le rôle de l'entreprise dans la stratégie.
Stratégie de test:
Paramètre de stratégieInterval
JavaScript
code de stratégie
function main(){
Log(exchange.GetAccount())
Log(exchange.GetTicker())
Log(exchange.GetDepth())
Log("Interval:", Interval)
}
Valeur de retour
// Create the bot successfully
{
"code": 0,
"data": {
"result": 74260,
"error": null
}
}
PluginRun(Settings)
utilise l'API étendue pour appeleroutil de débogage function.
ParamètreSettings
est unJSON
l'objet, à savoir les paramètres de l'outil de débogage (Settings
contient le code de test écrit dans l'attributsource
).
Code de testPython
Exemple:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import time
import md5
import urllib
import json
# API KEY has been blurred; you can use your own API KEY to test
accessKey = 'f77XXXXXXXXXXXXXXX757'
# API KEY has been blurred; you can use your own API KEY to test
secretKey = 'd8XXXXXXXXXXXXXXXX41ca97ea15'
def api(method, *args):
d = {
'version': '1.0',
'access_key': accessKey,
'method': method,
'args': json.dumps(list(args)),
'nonce': int(time.time() * 1000),
}
d['sign'] = md5.md5('%s|%s|%s|%d|%s' % (d['version'], d['method'], d['args'], d['nonce'], secretKey)).hexdigest()
return json.loads(urllib.urlopen('https://www.fmz.com/api/v1', urllib.urlencode(d)).read())
code = '''
function main() {
Log(exchange.GetTicker())
exchange.SetTimeout(2000);
return exchanges[0].GetTicker()
}
'''
settings = {
# K-line period parameter "60" indicates 60 seconds
"period": 60,
"source": code,
# The docker ID can specify which docker to run the bot on; if the value is -1, it means automatic assignment
"node" : 54913,
"exchanges": [
{"eid": "OKEX", "pair": "ETH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}},
{"eid": "Huobi", "pair": "BCH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}}
]
}
print api("PluginRun", settings)
Note: le numéro de série{"eid": "OKEX", "pair": "ETH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}}
{"eid": "Huobi", "pair": "BCH_BTC", "meta" :{"AccessKey": "123abc", "SecretKey": "123abc"}}
Pour leexchanges
attribut dans leréglages, l'attribut ne doit être défini qu'à 1, lors de l'appel duPluginRun
interface (pour un seul objet d'échange peut être pris en charge lorsque vous utilisez la page
Valeur de retourapi("PluginRun", settings)
résultats retournés:
{
u'code': 0,
u'data': {
u'result': u'{"logs":[{"PlatformId":"","OrderId":"0","LogType":5,"Price":0,"Amount":0,"Extra":"{\\"Info\\":{\\"date\\":\\"1523715057\\",\\"ticker\\":{\\"high\\":\\"0.06400845\\",\\"vol\\":\\"117648.31546800\\",\\"last\\":\\"0.06204514\\",\\"low\\":\\"0.06178666\\",\\"buy\\":\\"0.06200001\\",\\"sell\\":\\"0.06208728\\"}},\\"High\\":0.06400845,\\"Low\\":0.06178666,\\"Sell\\":0.06208728,\\"Buy\\":0.06200001,\\"Last\\":0.06204514,\\"Volume\\":117648.315468,\\"OpenInterest\\":0,\\"Time\\":1523715057726}","Instrument":"","Direction":"","Time":1523715057726}],"result":"{\\"Info\\":{\\"date\\":\\"1523715057\\",\\"ticker\\":{\\"vol\\":\\"117648.31546800\\",\\"last\\":\\"0.06204514\\",\\"low\\":\\"0.06178666\\",\\"buy\\":\\"0.06200001\\",\\"sell\\":\\"0.06208728\\",\\"high\\":\\"0.06400845\\"}},\\"High\\":0.06400845,\\"Low\\":0.06178666,\\"Sell\\":0.06208728,\\"Buy\\":0.06200001,\\"Last\\":0.06204514,\\"Volume\\":117648.315468,\\"OpenInterest\\":0,\\"Time\\":1523715057774}"}\n',
u'error': None
}
}
GetRobotLogs(robotId, logMinId, logMaxId, logOffset, logLimit, profitMinId, profitMaxId, profitOffset, profitLimit, chartMinId, chartMaxId, chartOffset, chartLimit, chartUpdateBaseId, chartUpdateDate, summaryLimit)
obtient les informations du journal du robot (robotID
: robotId
), correspondant à laAPI KEY
dans la demande du compte FMZ Quant.
Paramètre
Nom du paramètre | Le type | Les commentaires |
---|---|---|
robotId | nombre entier | Identifiant du robot |
Tableau journalinterroge les données du journal de la table de base de données:
Nom du paramètre | Le type | Les commentaires |
---|---|---|
LogMinId | nombre entier | Identifiant minimal du journal |
LogMaxId | nombre entier | Identifiant maximal du journal |
LogOffset | nombre entier | Une fois que la plage est déterminée par logMinId et logMaxId, le décalage de logOffset (combien d'enregistrements sont sautés) commence à être utilisé comme position de départ pour l'obtention de données |
LogLimit | nombre entier | Après détermination de la position de départ, le nombre d'enregistrements de données sélectionnés |
Tableau Bénéficeinterroge les données sur les bénéfices du tableau de la base de données:
Nom du paramètre | Le type | Les commentaires |
---|---|---|
Profité | nombre entier | Identifiant minimal de l'enregistrement |
profitMaxId | nombre entier | Identifiant maximal de l'enregistrement |
ProfitOffset | nombre entier | Le décalage (combien d'enregistrements sont sautés) commence à être utilisé comme position de départ |
profit Limite | nombre entier | Après détermination de la position de départ, le nombre d'enregistrements de données sélectionnés |
Tableau graphiqueeffectue des requêtes sur les données du graphique du tableau de la base de données:
Nom du paramètre | Le type | Les commentaires |
---|---|---|
Le tableau de bord | nombre entier | Identifiant minimal de l'enregistrement |
graphique MaxId | nombre entier | Identifiant maximal de l'enregistrement |
graphiqueOffset | nombre entier | Compte rendu |
graphique Limite | nombre entier | le nombre d'enregistrements à obtenir |
Tableau ActualisationBaseId | nombre entier | Rechercher l' ID de base mis à jour |
Tableau Date de mise à jour | nombre entier | L'enregistrement de données met à jour l'horodatage, ce qui filtrera les enregistrements plus grands que cet horodatage |
Résumé Limiteinterroge les données de la barre d'état:
Il interroge les données de la barre d'état du bot. Le type de paramètre est entier. Le réglage à summaryLimit
paramètre pour obtenir toutes les informations de la barre d'état). Les données de la barre d'état sont stockées dans les données retournéessummary
.
Python
Exemple:
api('GetRobotLogs', 63024, 0, 0, 7, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) # For the specific code, please refer to the above content: 4. Simple examples, which will not be repeated here; here only write the call and pass of "GetRobotLogs"
Valeur de retour données renvoyées:
{
"code": 0,
"data": {
"result": {
"status": 1,
"updateTime": 1527049990197,
"wd": 0,
// The first data structure in logs is the log records in the strategy log table in the bot database
"logs": [{
"Max": 3984,
"Arr": [
[3977, 3, "Futures_OKCoin", "", 0, 0, "Sell(688.9, 2): 20016", 1526954372591, "", ""],
[3976, 5, "", "", 0, 0, "OKCoin:this_week too many positions, long: 2", 1526954372410, "", ""]
],
"Total": 1503,
"Min": 2482
}, {
// The second data structure in logs is the log records in the strategy log table in the bot database
"Max": 0,
"Arr": [],
"Total": 0,
"Min": 0
}, {
// The third data structure in logs is the log records in the strategy log table in the bot database
"Max": 0,
"Arr": [],
"Total": 0,
"Min": 0
}],
"chart": "",
"refresh": 1527049988000,
"summary": "...",
"chartTime ": 0,
"node_id ": 50755,
"online ": true
},
"error ": null
}
}
Le tableau du journal de stratégie dans la base de données
LeArr
description de la valeur de l'attribut dans les données de résultat renvoyées ci-dessus:
"Arr": [
[3977, 3, "Futures_OKCoin", "", 0, 0, "Sell(688.9, 2): 20016", 1526954372591, "", ""],
[3976, 5, "", "", 0, 0, "OKCoin:this_week too many positions, long: 2", 1526954372410, "", ""]
],
Nom de l'entreprise | Type de fichier | - Je vous en prie. | commandé | prix | Le montant | en plus | date de sortie | type de contrat | direction |
---|---|---|---|---|---|---|---|---|---|
3977 | 3 | "" | 0 | 0 | 1526954372591 | "" | "" | ||
3976 | 5 | "" | "" | 0 | 0 | 1526954372410 | "" | "" |
extra
est le message joint du journal imprimé.
Types de bûches spécifiques représentés par:logType
valeur:
Type de journal: | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
Signification de logType: | À acheter | VENDE | RETRAIT | ÉVÉNEMENT | Résultats | Le message | Démarrer |
Signification chinoise | Compte de type de commande | Journal des types d'ordres de vente | Retirer | Erreur | Revenu | Le journal | Relancer |
Tableau de journaux du graphique des recettes dans la base de données Les données figurant dans le tableau de journaux du graphique sont cohérentes avec les données figurant dans le tableau de journaux de la stratégie.
"Arr": [
[202, 2515.44, 1575896700315],
[201, 1415.44, 1575896341568]
]
Prenons l'exemple de l'une des données du journal:
[202, 2515.44, 1575896700315]
202
en logID
; 2515.44
en valeur des recettes;1575896700315
comme timbres.
Tableau de journaux des graphiques dans la base de données
"Arr": [
[23637, 0, "{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"],
[23636, 5, "{\"x\":1575960300000,\"y\":3.0735}"]
]
Prenons l'exemple de l'une des données du journal:
[23637, 0, "{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"],
23637
est le journalID
, 0
est l'indice de la série de données du graphique et les dernières données"{\"close\":648,\"high\":650.5,\"low\":647,\"open\":650,\"x\":1575960300000}"
est les données journalières; ces données sont les données de la ligne K sur le graphique.
Afin d'améliorer les fonctions du terminal de négociation et de faciliter la négociation manuelle, une fonction plug-in est désormais disponible.
Le principe est le même que celui de l'outil de débogage: envoyer un morceau de code au docker de la page de terminal
Sur la page Trading Plugin
, qui soutientJavaScript
, Python
, cpp
etMyLanguage
.
Le plugin peut exécuter le code pendant une période de temps, et il peut effectuer des opérations simples, telles quecommandes de glacier, commandes en attente, annulation de commandeetcalcul de la commandeComme leoutil de débogage, il utilisereturn
Voici quelques exemples, et d'autres fonctions peuvent être explorées par vous-même.
Revenir à l'instantané de profondeur
// Return to the depth snapshot
function main() {
var tbl = {
type: 'table',
title: 'snapshot of the order depth @ ' + _D(),
cols: ['#', 'Amount', 'Ask', 'Bid', 'Amount'],
rows: []
}
var d = exchange.GetDepth()
for (var i = 0; i < Math.min(Math.min(d.Asks.length, d.Bids.length), 15); 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
}
def main():
tbl = {
"type": "table",
"title": "snapshot of the order depth @ " + _D(),
"cols": ["#", "Amount", "Ask", "Bid", "Amount"],
"rows": []
}
d = exchange.GetDepth()
for i in range(min(min(len(d["Asks"]), len(d["Bids"])), 15)):
tbl["rows"].append([i, d["Asks"][i]["Amount"], str(d["Asks"][i]["Price"]) + "#FF0000", str(d["Bids"][i]["Price"]) + "#0000FF", d["Bids"][i]["Amount"]])
return tbl
void main() {
json tbl = R"({
"type": "table",
"title": "abc",
"cols": ["#", "Amount", "Ask", "Bid", "Amount"],
"rows": []
})"_json;
tbl["title"] = "snapshot of the order depth @" + _D();
auto d = exchange.GetDepth();
for(int i = 0; i < 5; i++) {
tbl["rows"].push_back({format("%d", i), format("%f", d.Asks[i].Amount), format("%f #FF0000", d.Asks[i].Price), format("%f #0000FF", d.Bids[i].Price), format("%f", d.Bids[i].Amount)});
}
LogStatus("`" + tbl.dump() + "`");
// C++ does not support "return json" to display the table, and you can create a bot to display the table of the status bar
}
Tirer les écarts entre les périodes
// Draw cross-period spreads
var chart = {
__isStock: true,
title : { text : 'spread analysis chart'},
xAxis: { type: 'datetime'},
yAxis : {
title: {text: 'spread'},
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)
for(var i = 0; i < Math.min(recordsA.length, recordsB.length); i++){
var diff = recordsA[recordsA.length - Math.min(recordsA.length, recordsB.length) + i].Close - recordsB[recordsB.length - Math.min(recordsA.length, recordsB.length) + i].Close
chart.series[0].data.push([recordsA[recordsA.length - Math.min(recordsA.length, recordsB.length) + i].Time, diff])
}
return chart
}
chart = {
"__isStock": True,
"title": {"text": "spread analysis chart"},
"xAxis": {"type": "datetime"},
"yAxis": {
"title": {"text": "spread"},
"opposite": False
},
"series": [
{"name": "diff", "data": []}
]
}
def main():
exchange.SetContractType("quarter")
recordsA = exchange.GetRecords(PERIOD_M5)
exchange.SetContractType("this_week")
recordsB = exchange.GetRecords(PERIOD_M5)
for i in range(min(len(recordsA), len(recordsB))):
diff = recordsA[len(recordsA) - min(len(recordsA), len(recordsB)) + i].Close - recordsB[len(recordsB) - min(len(recordsA), len(recordsB)) + i].Close
chart["series"][0]["data"].append([recordsA[len(recordsA) - min(len(recordsA), len(recordsB)) + i]["Time"], diff])
return chart
// C++ does not support "return json" structure drawing
Il y a d'autres exemples dans
Ajouter le module plugin du terminal de trading
Comme indiqué sur la figure, ouvrez le menu ajouter des modules sur la page du terminal
Exécutez le plugin
Cliquez sur
Temps d'exécution du plugin La durée maximale de fonctionnement du plugin est de 3 minutes; et il cessera de fonctionner automatiquement après avoir dépassé 3 minutes.
La formule d'analyse fait référence à la méthode de calcul des cotations de marché utilisée par le public.alpha101
deworldquant
: http://q.fmz.com/chart/doc/101_Formulaic_Alphas.pdf, qui est fondamentalement compatible avec sa grammaire (avec des explications pour les caractéristiques non mises en œuvre), et a été améliorée.
Il est utilisé pour effectuer rapidement des calculs sur des séries temporelles et valider des idées,Utiliser l' adresse.
Introduction à la page:
"{}" ci-dessous représente un espace réservé, toutes les expressions ne sont pas sensibles aux majuscules et
abs(x), log(x), sign(x)
signifie littéralement valeur absolue, logarithme et fonction de signe, respectivement.Les opérateurs suivants, dont+, -, *, /, >, <
, répondent également aux significations de leurs normes;==
représente ||
signifie x? y: z
indique l'opérateur ternaire.
rank(x)
: le classement des sections transversales, en renvoyant le pourcentage de l'emplacement; il est nécessaire de spécifier plusieurs groupes cibles candidats, qui ne peuvent pas être calculés pour un marché unique et renvoient directement le résultat initial.delay(x, d)
: la valeur avant la période d de la séquence.sma(x, d)
: la moyenne mobile simple de la période d de la séquence.correlation(x, y, d)
: le coefficient de corrélation des séries de temps x et y au cours des dernières périodes d.covariance(x, y, d)
: la covariance des séries chronologiques x et y au cours des dernières périodes d.scale(x, a)
: il normalise les données, de sorte quesum(abs(x)) = a
(delta(x, d)
: la valeur actuelle de la série temporelle x moins la valeur avant d périodes.signedpower(x, a)
: x^a
.decay_linear(x, d)
: moyenne mobile pondérée d'une série de temps x, avec des pondérations d, d-1, d-2... 1 (normalisée).indneutralize(x, g)
: le traitement neutre pour la classification industrielle ts_{O}(x, d)
: effectuer des opérations ts_min(x, d)
: la valeur minimale des dernières périodes d.ts_max(x, d)
: la valeur maximale des dernières périodes d.ts_argmax(x, d)
: ts_max(x, d)
position.ts_argmin(x, d)
: ts_min(x, d)
position.ts_rank(x, d)
: tri des valeurs de séries de temps x des périodes passées d (tri en pourcentage).min(x, d)
: ts_min(x, d)
.max(x, d)
: ts_max(x, d)
.sum(x, d)
: la somme des périodes passées d.product(x, d)
: le produit des périodes précédentes d.stddev(x, d)
: l'écart type des dernières périodes d.Les données d'entrée ne sont pas sensibles aux majuscules et minuscules; les données par défaut sont le symbole sélectionné sur la page Web, ou il peut être spécifié directement, commebinance.ada_bnb
returns
: rendement du prix de clôture.open, close, high, low, volume
: à savoir le prix d'ouverture, le prix de clôture, le prix le plus élevé, le prix le plus bas et le volume des transactions au cours de la période.vwap
: prix d'exécution pondéré par volume, non encore mis en œuvre, qui est actuellement le prix de clôture.cap
: valeur de marché totale, pas encore mise en œuvre.IndClass
: classification de l'industrie, pas encore mise en œuvre.La sortie de résultats multiples (exprimés par liste) est prise en charge à la fois; par exemple,[sma(close, 10), sma(high, 30)]
En plus d'entrer des données de séries temporelles, il peut également être utilisé comme une simple calculatrice.
Pour la plateforme de trading FMZ Quant qui n'a pas encore encapsulé l'interface API de l'échange, elle peut être consultée en écrivant un plug-in de protocole général.
REST
le protocole:documentation de référence.FIX
le protocole:point de référence.La différence entreFIX
le protocole plug-in et leREST
le programme de plug-in de protocole est uniquement l'interaction entre le programme de plug-in de protocole et l'interface d'échange. Le programme de plug-in de protocole a le même traitement détaillé de l'interaction du programme docker et du format de données que FMZ Quant. Pour plus de détails, veuillez vous référer aux exemples dans les liens ci-dessus.
La plate-forme de négociation quantitative FMZ fournit une plateforme modulaire et personnalisable
Outil de débogagepage fournit un environnement pour tester rapidement les codes par bot, ne prenant en charge queJavaScript
currently.
Il prend en charge le code de stratégie de synchronisation à distance de l'éditeur local à la plateforme de trading FMZ Quant, et il prend en chargeSublime Text
/Atom
/Vim
/VSCode
sur la page d'édition de stratégie, cliquez sur
Cliquez sur
Les méthodes d'installation des plug-ins de différents éditeurs sont légèrement différentes. Vous pouvez cliquer sur le bouton de téléchargement pour accéder à l'élément spécifique du plug-in de synchronisation à distance.
Lorsque vous exécutez le trading en direct, vous devez enregistrer les données de paramètres de la configuration réelle du bot, vous pouvez cliquer sur le bouton JSON
le fichier, et la configuration du paramètre de stratégie exportée peut également être importée dans le bot réel à nouveau. Cliquez sur le bouton
Télécharger le code source
Exporter le code source de stratégie, et le type du fichier d'exportation est basé sur le langage de programmation de stratégie.js
; la stratégie python exporte les fichiers avec l'extensionpy
; la stratégie C++ exporte les fichiers avec l'extensioncpp
; Mylanguage stratégie exporte les fichiers avec l'extensiontxt
. Notez que seul le code source de la stratégie est exporté, sans inclure les paramètres de la stratégie, les références de modèles, etc.
Stratégie d'exportation
Exporter la stratégie complète, y compris toutes les informations sur la stratégie, telles que le code source de la stratégie et la conception des paramètres.xml
file.
Stratégie d'importation
Utilisez lexml
le fichier exporté par la fonction xml
Pour importer une stratégie complète, vous devez cliquer sur le bouton
Les noms de stratégie et les descriptions des paramètres de stratégie peuvent être écrits enChinese|English
, affichée automatiquement dans la langue reconnue par les pages Web.
Dans d'autres endroits, par exemple:description de la stratégie, instructions d'utilisationet autres textesMarkdown
format, en utilisant[trans]Chinese|English[/trans]
ou[trans]Chinese||English[/trans]
L'effet de l'exemple ci-dessus est illustré sur la figure suivante:
Affichage de la page en chinois:
Affichage de la page en anglais:
Après avoir changé la langue, il prendra effet après avoir rafraîchi la page Web.
Les fonctions qui peuvent écrire des chaînes dans le code de stratégie prennent également en charge la commutation de langage, comme la fonctionLog
, fonctionLogStatus
, etc.
function main() {
Log("[trans]日志|log[/trans]")
var table = {
type: "table",
title: "[trans]操作|option[/trans]",
cols: ["[trans]列1|col1[/trans]", "[trans]列2|col2[/trans]", "[trans]操作|option[/trans]"],
rows: [
["[trans]比特币|BTC[/trans]", "[trans]以太坊|ETH[/trans]", {"type": "button", "cmd": "coverAll", "name": "平仓|cover", "description": "描述|description"}] // Note: It doesn't need to add [trans] tag in the button
]
}
LogStatus("[trans]信息|message[/trans]", "\n`" + JSON.stringify(table) + "`")
throw "[trans]错误|error[/trans]"
}
import json
def main():
Log("[trans]日志|log[/trans]")
table = {
"type": "table",
"title": "[trans]操作|option[/trans]",
"cols": ["[trans]列1|col1[/trans]", "[trans]列2|col2[/trans]", "[trans]操作|option[/trans]"],
"rows": [
["[trans]比特币|BTC[/trans]", "[trans]以太坊|ETH[/trans]", {"type": "button", "cmd": "coverAll", "name": "平仓|cover", "description": "描述|description"}]
]
}
LogStatus("[trans]信息|message[/trans]", "\n`" + json.dumps(table) + "`")
raise Exception("[trans]错误|error[/trans]")
void main() {
Log("[trans]日志|log[/trans]");
json table = R"({
"type": "table",
"title": "[trans]操作|option[/trans]",
"cols": ["[trans]列1|col1[/trans]", "[trans]列2|col2[/trans]", "[trans]操作|option[/trans]"],
"rows": [
["[trans]比特币|BTC[/trans]", "[trans]以太坊|ETH[/trans]", {"type": "button", "cmd": "coverAll", "name": "平仓|cover", "description": "描述|description"}]
]
})"_json;
LogStatus("[trans]信息|message[/trans]", "\n`" + table.dump() + "`");
Panic("[trans]错误|error[/trans]");
}
Après avoir téléchargé le logiciel docker, le fichier exécutable après décompression (nom du fichier:robot
) est le programme docker; les paramètres peuvent être spécifiés pour le programme docker, lors du déploiement du docker.
-v
: vérifiez les informations, y compris la version et l'heure de compilation du programme docker en cours.
La commande d'exécution est basée surApple Mac System
: ./robot -v
.-s
: l'adresse spécifiée pour communiquer avec la plateforme de trading FMZ Quant lors de l'exécution du programme docker.
La commande d'exécution est basée surApple Mac System
: ./robot -s node.fmz.com/xxxxxxx
; xxxxxxx
est l'identifiant d'identification unique de chaque compte sur la plate-forme de négociation quantitative FMZ; après l'exécution de la commande, il sera demandé de saisir le mot de passe du compte de la plate-forme de négociation quantitative correspondante FMZ.-p
: vous pouvez spécifier directement le paramètre dans la commande run pour saisir le mot de passe, ce qui n'est pas recommandé, car le paramètre de mot de passe sera laissé dans l'enregistrement système en cours.node.fmz.com/xxxxxxx
est:abc123456
Je suis désolée.
La commande d'exécution est basée surApple Mac System
: ./robot -s node.fmz.com/xxxxxxx -p abc123456
.-n
: joignez des informations d'étiquette au programme docker en cours d'exécution.
La commande d'exécution est basée surApple Mac System
: ./robot -n macTest -s node.fmz.com/xxxxxxx
Il y aura unmacTest
Étiquette de texte dans les informations du docker sur la page de gestion du docker de la plateforme.-l
: imprimer la liste d'échange prise en charge par le docker actuel.
La commande d'exécution est basée surApple Mac System
: ./robot -l
, c'est-à-dire que les noms des échanges pris en charge peuvent être sortis.exchange.Go
fonction, il n'y a pas de fonction raisonnablewait
d'attendre la fin de la coroutine pendant l'opération, ce qui entraîne un grand nombre de coroutines.Decrypt: Secret key decrypt failed
La raison de l'erreur est que la modification du mot de passe du compte FMZ provoque tous lesAPI KEY
Pour résoudre le problème, leAPI KEY
Il faut reconfigurer et redémarrer le dock.ValueError: bad marshal data (unknown type code)
. Mettre à niveau ou installer l'environnement Python exécuté par la stratégie vers une des versions prises en charge par la stratégie:Python 2.7
, Python 3.5
etPython 3.6
.interrupt
erreur; l'erreur est due au fait que l'utilisateur cliqueArrêtez le bot.bouton sur la page Bot lorsque le programme effectue une opération (comme accéder à l'interface de la plateforme), et le bot arrête et interrompt le message d'erreur imprimé par l'opération en cours.Sur la page
Sous-compte
Après vous être connecté à la plateforme, cliquez sur
Les sous-comptes ont des autorisations limitées; seuls les bots autorisés dans les paramètres deles autorisations disponiblespeuvent être consultées dans les sous-comptes. Le bot autorisé a le pouvoir de modifier les paramètres, d'arrêter et de redémarrer le trading en direct, mais il ne peut pas modifier l'objet d'échange configuré par le bot. Les scénarios d'utilisation des sous-comptes sont généralement:
Vue de négociation en direct
Dans la liste des robots de la plateforme FMZpage du robot, cliquez sur le bouton
À
Partage des stratégies
Partage public
Après avoir cliqué sur le bouton
Partage interne
Après avoir cliqué sur le bouton
Stratégie de location
Vente publique
Après avoir cliqué sur le bouton
Vente interne
Après avoir cliqué sur le bouton
Note importante:
Lors de la création et de la distribution desle jeton de stratégie, s'il vous plaît assurez-vous de confirmer soigneusement s'il s'agit d'un jeton
function returnAnalyze(totalAssets, profits, ts, te, period, yearDays) {
// force by days
period = 86400000
if (profits.length == 0) {
return null
}
var freeProfit = 0.03 // 0.04
var yearRange = yearDays * 86400000
var totalReturns = profits[profits.length - 1][1] / totalAssets
var annualizedReturns = (totalReturns * yearRange) / (te - ts)
// MaxDrawDown
var maxDrawdown = 0
var maxAssets = totalAssets
var maxAssetsTime = 0
var maxDrawdownTime = 0
var maxDrawdownStartTime = 0
var winningRate = 0
var winningResult = 0
for (var i = 0; i < profits.length; i++) {
if (i == 0) {
if (profits[i][1] > 0) {
winningResult++
}
} else {
if (profits[i][1] > profits[i - 1][1]) {
winningResult++
}
}
if ((profits[i][1] + totalAssets) > maxAssets) {
maxAssets = profits[i][1] + totalAssets
maxAssetsTime = profits[i][0]
}
if (maxAssets > 0) {
var drawDown = 1 - (profits[i][1] + totalAssets) / maxAssets
if (drawDown > maxDrawdown) {
maxDrawdown = drawDown
maxDrawdownTime = profits[i][0]
maxDrawdownStartTime = maxAssetsTime
}
}
}
if (profits.length > 0) {
winningRate = winningResult / profits.length
}
// trim profits
var i = 0
var datas = []
var sum = 0
var preProfit = 0
var perRatio = 0
var rangeEnd = te
if ((te - ts) % period > 0) {
rangeEnd = (parseInt(te / period) + 1) * period
}
for (var n = ts; n < rangeEnd; n += period) {
var dayProfit = 0.0
var cut = n + period
while (i < profits.length && profits[i][0] < cut) {
dayProfit += (profits[i][1] - preProfit)
preProfit = profits[i][1]
i++
}
perRatio = ((dayProfit / totalAssets) * yearRange) / period
sum += perRatio
datas.push(perRatio)
}
var sharpeRatio = 0
var volatility = 0
if (datas.length > 0) {
var avg = sum / datas.length;
var std = 0;
for (i = 0; i < datas.length; i++) {
std += Math.pow(datas[i] - avg, 2);
}
volatility = Math.sqrt(std / datas.length);
if (volatility !== 0) {
sharpeRatio = (annualizedReturns - freeProfit) / volatility
}
}
return {
totalAssets: totalAssets,
yearDays: yearDays,
totalReturns: totalReturns,
annualizedReturns: annualizedReturns,
sharpeRatio: sharpeRatio,
volatility: volatility,
maxDrawdown: maxDrawdown,
maxDrawdownTime: maxDrawdownTime,
maxAssetsTime: maxAssetsTime,
maxDrawdownStartTime: maxDrawdownStartTime,
winningRate: winningRate
}
}
Les contrats à terme avec Binance
Il prend en charge le mode de double position des contrats à terme Binance; vous pouvez utiliserexchange.IO
Pour passer:
function main() {
var ret = exchange.IO("api", "POST", "/fapi/v1/positionSide/dual", "dualSidePosition=true")
// ret : {"code":200,"msg":"success"}
Log(ret)
}
def main():
ret = exchange.IO("api", "POST", "/fapi/v1/positionSide/dual", "dualSidePosition=false")
Log(ret)
void main() {
auto ret = exchange.IO("api", "POST", "/fapi/v1/positionSide/dual", "dualSidePosition=true");
Log(ret);
}
Il prend en charge la commutation entre position croisée/position isolée
function main() {
exchange.SetContractType("swap")
exchange.IO("cross", true) // Switch to crossed position
exchange.IO("cross", false) // Switch to isolated position
}
def main():
exchange.SetContractType("swap")
exchange.IO("cross", True)
exchange.IO("cross", False)
void main() {
exchange.SetContractType("swap");
exchange.IO("cross", true);
exchange.IO("cross", false);
}
Les contrats à terme
Il prend en charge la modification de l'adresse de Huobi Futures participant à la signature, qui n'est pas commuté par défaut.exchange.IO("signHost", "")
pour définir une chaîne vide.
Utilisationexchange.IO("signHost", "https://aaa.xxx.xxx")
modifier l'adresse de base de Huobi Futures participant à la vérification de la signature.
Utilisationexchange.IO("base", "https://bbb.xxx.xxx")
ouexchange.SetBase("https://bbb.xxx.xxx")
pour changer l'adresse de base de l'interface de la plateforme.
Lorsque la paire de négociation est réglée surXXX_USDT
, utilisez la fonctionexchange.SetContractType("swap")
pour régler le code du contrat àswap
le contrat perpétuel, en utilisantexchange.IO("cross", true)
peut passer àUSDT
- un contrat perpétuel à marge en mode position croisée.exchange.IO("cross", false)
Le paramètre par défaut initial est le mode de position isolée.
Huobi
Il prend en charge les jetons Huobi au comptant, tels que:LINK*(-3)
; le code défini par la bourse est:link3susdt
, qui est écrit lorsque FMZ définit la paire de négociationLINK3S_USDT
Je suis désolée.
Il est également possible de changer de paire de négociation dans la stratégie:
function main() {
exchange.SetCurrency("LINK3S_USDT")
Log(exchange.GetTicker())
}
def main():
exchange.SetCurrency("LINK3S_USDT")
Log(exchange.GetTicker())
void main() {
exchange.SetCurrency("LINK3S_USDT");
Log(exchange.GetTicker());
}
- Je suis désolé.
L'interface OKX peut basculer vers l'environnement de simulation de test du robot OKX; en utilisantexchange.IO("simulate", true)
Si vous souhaitez passer à l'environnement de trading réel, utilisezexchange.IO("simulate", false)
Le défaut initial est l'environnement commercial réel.
Il prend en charge le changement de mode de marge de compte; utilisationexchange.IO("cross", true)
pour passer en mode position croisée et utiliserexchange.IO("cross", false)
pour passer au mode de position isolée, la valeur par défaut initiale est le mode de position croisée.
Les échanges à terme
Utilisationexchange.IO("cross", true)
pour passer au mode position croisée et utiliserexchange.IO("cross", false)
pour passer au mode de position isolée; le paramètre par défaut initial est le mode de position croisée.
L'échange ne prend pas en charge la requête des ordres en attente actuels et l'interface pour la requête des dossiers de négociation historiques du marché, de sorte que leGetOrders
etGetTrades
les fonctions ne sont pas prises en charge.
Les contrats à terme avec Bitget
Utilisationexchange.IO("cross", true)
pour passer en mode position croisée et utiliserexchange.IO("cross", false)
pour passer au mode de position isolée.
Le montant de la garantie est calculé à partir de la valeur de la garantie.
Utilisationexchange.IO("cross", true)
pour passer en mode position croisée et utiliserexchange.IO("cross", false)
pour passer au mode de position isolée.
Les échanges à terme
Utilisationexchange.IO("cross", true)
pour passer en mode position croisée et utiliser` ` échange.IO("croix",