vous pouvez utiliser Python pour écrire directement dans la base de données.
function onexit(){
_G('profit', profit)
}
function main(){
_G("num", 1); // Set a global variable num, with a value of 1 second
_G("num", "ok"); // Change a global variable num, whose value is the string "ok"
_G("num", null); // Delete the global variable num
_G("num"); // Return the value of the global variable num; if it does not exist, return null
var profit = 0
if(_G('profit')){
profit = _G('profit')
}
}
Lors de la passation d'un ordre, les précisions du prix et du volume doivent normalement être contrôlées; FMZ a intégré la fonction _N pour déterminer les décimales à enregistrer; par exemple, le résultat de_N(4.253,2)
est de 4,25.
L'appel de l'API de la plateforme ne peut pas garantir que l'accès est réussi à chaque fois, et _C est une fonction de réessayage automatique._C(exchange.GetTicker)
, avec l'intervalle de réessayage par défaut de 3 secondes, et vous pouvez appeler la fonction _CDelay pour contrôler l'intervalle de réessayage, par exemple _CDelay(1000), ce qui signifie changer l'intervalle de réessayage de la fonction _C à 1 seconde.GetTicker()
, exchange.GetDepth
, GetTrade
, GetRecords
, GetAccount
, GetOrders
etGetOrder
pour empêcher l'interruption du programme causée par la défaillance d'accès.
CancelOrder
ne peut pas utiliser la fonction _C, car il existe diverses raisons pour l'échec d'annuler une commande. Si une commande a été exécutée, l'annulation de l'ordre renverra un échec, et l'utilisation de la fonction _C entraînera une nouvelle tentative tout le temps.
La fonction _C peut également transmettre des paramètres et est également utilisée dans des fonctions personnalisées.
function main(){
var ticker = _C(exchange.GetTicker)
var depth = _C(exchange.GetDepth)
var records = _C(exchange.GetRecords, PERIOD_D1) // Pass in the parameters
}
Je vous appelle_D()
retourne directement la chaîne de temps courante, telle que:2019-08-15 03:46:14
. Si elle est appelée pendant le backtest, le temps de backtest sera retourné. Vous pouvez utiliser la fonction _D pour juger du temps, par exemple:_D().slice(11) > '09:00:00':
.
_D(timestamp, fmt)
, convertira l'horodatage ms en une chaîne de temps, telle que_D(1565855310002)
. Le paramètre fmt est le format de temps, et la valeur par défaut estyyyy-MM-dd hh:mm:ss
.
Pour certaines fonctions d'indicateur couramment utilisées, telles que MA\MACD\KDJ\BOLL et autres indicateurs courants, qui ont été intégrés directement par la plateforme FMZ, et les indicateurs spécifiques pris en charge peuvent être trouvés dans le document API.
Avant d'utiliser les fonctions d'indicateur, il est préférable de juger de la longueur de la ligne K. Lorsque la longueur de la ligne K précédente ne peut pas répondre à la période requise pour le calcul, le résultat estnull
Par exemple, si la longueur de la ligne K d'entrée est de 100 et la période pour calculer MA est de 10, alors les 9 premières valeurs sont toutes nulles, et le calcul après les valeurs de la forme 9 sera fait normalement.
JavaScript prend également en charge le talib complet, en tant que bibliothèque tierce partie, avec une méthode d'invocation telle quetalib.CCI(records)
Veuillez consulterhttp://ta-lib.org/function.html. Pour Python, vous pouvez installer la bibliothèque talib par vous-même. En raison de la nécessité de compilation, vous ne pouvez pas simplement utiliser pip pour installer. Vous pouvez rechercher la méthode d'installation par vous-même.
Les fonctions d'indicateur peuvent non seulement passer les données de ligne K, mais aussi passer n'importe quel tableau
function main(){
var records = exchange.GetRecords(PERIOD_M30)
if (records && records.length > 9) {
var ma = TA.MA(records, 14)
Log(ma)
}
}
Ici, nous introduisons quelques fonctions JavaScript couramment utilisées dans les robots.
Date.now()
renvoie l'horodatage actuel;parseFloat()
transfère des chaînes en nombres, commeparseFloat("123.21")
;parseInt()
transférer des chaînes en nombres entiers;num.toString()
transfère les nombres en chaînes, avec la variable num;JSON.parse()
les formats des chaînes Json, tels queJSON.parse(exchange.GetRawJSON())
;Math.max()
, Math.abs()
et ainsi de suite; référence:https://www.w3school.com.cn/jsref/jsref_obj_math.asp ;Il y a beaucoup de situations qui doivent être prises en compte lors de l'écriture d'une fonction de stratégie de bot. Par exemple, une fonction simple telle que l'achat de 5 pièces, nous devons considérer: Le solde actuel est-il suffisant? Quel est le prix de l'ordre? Quelle est la précision? Avez-vous besoin de diviser les commandes pour éviter d'avoir un impact sur le marché? Comment traiter les commandes inachevées? Et quelques détails comme ça. Dans différentes stratégies, ces fonctions sont les mêmes, vous pouvez donc les créer en un modèle. Suivant les modèles officiels, les utilisateurs peuvent également écrire leurs propres stratégies de modèle. Ici, nous allons introduire plusieurs bibliothèques de classes de modèles très couramment utilisées officiellement publiées par FMZ, afin que les utilisateurs puissent rapidement écrire leurs propres stratégies.
La bibliothèque de trading de crypto-monnaie JavaScript et la bibliothèque de trading de contrats à terme sur matières premières sont intégrées par défaut et n'ont pas besoin d'être copiées.https://www.fmz.com/square/20/1) Copiez et enregistrez la bibliothèque de modèles et vérifiez la bibliothèque à utiliser pour créer votre propre stratégie.
Toutes les fonctions de modèle JavaScript commencent par$
, alors que les Python commencent tous parext
.
Adresse du code source:https://www.fmz.com/strategy/10989, qui a déjà été intégré, il n'est donc pas nécessaire de copier.
Obtenez le compte:
$.GetAccount(e)
Log($.GetAccount()); // Obtain the account information, with fault tolerance function
Log($.GetAcccount(exchanges[1]));
Commande et annulation:
$.Buy/Sell(e, amount)
$.Buy(0.3); // The main platform buys 0.3 coin
$.Sell(0.2); // The main platform sells 0.2 coin
$.Sell(exchanges[1], 0.1); // The secondary platform sells 0.1 coin
$.CancelPendingOrders(e, orderType)
$.CancelPendingOrders(); // Cancel all entrusted orders of the main platform
$.CancelPendingOrders(ORDER_TYPE_BUY); // Cancel all buy orders of the main platform
$.CancelPendingOrders(exchanges[1]); // Cancel all orders of the secondary platform
$.CancelPendingOrders(exchanges[1], ORDER_TYPE_SELL); // Cancel all sell orders of the secondary platforom
Jugez la croix:
$.Cross(periodA, periodB) / $.Cross(arr1, arr2);
var n = $.Cross(15, 30);
var m = $.Cross([1,2,3,2.8,3.5], [3,1.9,2,5,0.6])
If n = 0, it means that the current prices of exactly 15-period EMA and 30-period EMA are equal.
If n > 0, such as 5, it means that the 15-period EMA up-crosses the 30-period EMA by 5 periods (Bar)
If n < 0, such as -12, it means that the 15-period EMA down-crosses the 30-period EMA by 12 periods (Bar)
If it is not an array passed to the Cross, the function automatically obtains the K-line for moving average calculation.
If an array is passed to Cross, compare directly.
.retrait (e, devise, adresse, montant, frais, mot de passe) fonction:
$.withdraw(exchange, "btc", "0x.........", 1.0, 0.0001, "***")
Pour l'utilisation de la bibliothèque de négociation de contrats à terme sur matières premières est très stable, il est recommandé.https://www.fmz.com/strategy/12961, qui a déjà été intégré, il n'est donc pas nécessaire de copier.
Bibliothèque du CTA
function main() {
$.CTA("rb000,M000", function(r, mp) {
if (r.length < 20) {
return
}
var emaSlow = TA.EMA(r, 20)
var emaFast = TA.EMA(r, 5)
var cross = $.Cross(emaFast, emaSlow);
if (mp <= 0 && cross > 2) {
Log("Golden cross period", cross, "the moment position", mp);
return 1
} else if (mp >= 0 && cross < -2) {
Log("Death cross period", cross, "the moment position", mp);
return -1
}
});
}
Invocation Exemple de bibliothèque
function main() {
var p = $.NewPositionManager();
p.OpenShort("MA609", 1);
p.OpenShort("MA701", 1);
Log(p.GetPosition("MA609", PD_SHORT));
Log(p.GetAccount());
Log(p.Account());
Sleep(60000 * 10);
p.CoverAll("MA609");
LogProfit(p.Profit());
Log($.IsTrading("MA609"));
// Multiple varieties use the trading queue to complete the non-blocking trading task
var q = $.NewTaskQueue();
q.pushTask(exchange, "MA701", "buy", 3, function(task, ret) {
Log(task.desc, ret)
})
while (true) {
// Call "poll" to execute the unfinished tasks in the spare time
q.poll()
Sleep(1000)
}
}
Pour les fonctions brutes pour le dessin sont très compliquées, qui seront introduites dans le prochain tutoriel, nous recommandons aux débutants d'utiliser la bibliothèque de dessin, pour dessiner des graphiques de lignes très simples et des graphiques de lignes k, etc. La bibliothèque de dessin simple a été construite dans FMZ, qui peut être vu sur la page de modification de stratégie; si la bibliothèque n'est pas encore intégrée, les utilisateurs doivent copier et enregistrer, pour vérifier et utiliser la bibliothèque dans la stratégie.
Adresse de copie de la bibliothèque de dessins de la version Javascript:https://www.fmz.com/strategy/27293Adresse de copie de la bibliothèque de dessins de la version Python:https://www.fmz.com/strategy/39066
Exemple spécifique:
function main() {
while (true) {
var ticker = exchange.GetTicker()
if (ticker) {
$.PlotLine('Last', ticker.Last) // You can draw two lines at the samw time, "Last" is the name of the line
$.PlotLine('Buy', ticker.Buy)
}
Sleep(6000)
}
}
Sous le
Il est très facile de comprendre le type de chaîne et le type de nombre. qui sont des types très couramment utilisés. La boîte de combo affichera les options dans la boîte sur l'interface de paramètres. Par exemple, vous pouvez définir le paramètre SYMBOL commeBTC|USDT|ETH
dans la case à cocher; si vous choisissez USDT dans la case de la page, la valeur SYMBOL dans la stratégie est l'indice USDT 1.
Il y a plus de paramètres pour les paramètres; référence:https://www.fmz.com/api.
Lorsque la quantification d'une stratégie est terminée, vous pouvez la tester à l'aide des données historiques, pour vérifier la situation des bénéfices de la stratégie à la date historique. Bien sûr, le résultat du backtest est uniquement à titre de référence. Le backtest Javascript est exécuté sur le navigateur; le backtest Python est sur le docker, et notre plateforme fournit des dockers publics pour les utilisateurs.
Le mécanisme de backtest on-bar est basé sur la ligne K, c'est-à-dire que chaque ligne K générera un point dans le temps pour le backtest. À ce moment-là, vous pouvez obtenir les informations, y compris les prix d'ouverture, de clôture, les prix les plus élevés et les plus bas et le volume de négociation de la ligne K actuelle, ainsi que les informations de l'historique de la ligne K avant le point. L'inconvénient de ce type de mécanisme est très évident: un seul achat peut être généré sur une ligne K; généralement, le prix référencé est le prix de clôture de la ligne K. De plus, une ligne K ne peut obtenir que quatre prix, à savoir les prix de clôture, d'ouverture, les prix les plus élevés et les plus bas; les informations, y compris comment les prix changent dans une ligne K et si le prix le plus élevé ou le prix le plus bas change en premier, ne peuvent pas être obtenues. Prenez le bot de test de la ligne K d'une heure comme exemple.
Le backtest sur FMZ contient deux types, à savoir le backtest au niveau de la simulation et le backtest au niveau du marché réel. Le backtest au niveau de la simulation peut générer le tick simulé en fonction des périodes de ligne K sous-couche, et chaque période de ligne K sous-couche générera 14 points de temps de backtest.Cependant, le backtest au niveau du marché réel recueillera réellement des ticks, toutes les quelques secondes, et maintenant il prend en charge la profondeur réelle (y compris 20 niveaux) et l'exécution réelle du commerce par tarde.Le volume de date est assez énorme, et la vitesse de backtest est très lente, de sorte que le backtest ne peut pas être exécuté dans un long temps.https://www.fmz.com/bbs-topic/9126.
Le framework de backtest et de bot sont les mêmes, tous deux une boucle infinie. Parce que le backtest est de sauter à différents points de backtest, le backtest peut être exécuté sans utiliser Sleep(10)
, pour éviter d'être coincé.
Le moteur de backtest correspondra au prix de l'ordre placé par l'utilisateur et au prix du marché au moment du backtest. Si le prix d'achat est supérieur à celui de la vente, celui de la vente sera exécuté. Si la transaction ne peut pas être exécutée, un ordre en attente sera généré. Le glissement doit être ajouté pour assurer la transaction. Si la position ne peut pas être ouverte ou fermée pendant le backtest, vérifiez si la position est gelée en raison d'ordres inachevés.
GetRecords()
fonction; vous pouvez également spécifier un paramètre de période dans le code;Comme nous l'avons mentionné plus tôt, l'utilisation d'une interface API dans le bot peut échouer à accéder et retournernull
; si vous utilisez toujours les données de celui-ci, une erreur sera signalée et le bot s'arrêtera.
Causes courantes:
Erreur de réseau d'accès à l'API; le délai d'accès à l'interface renvoie nunll et une erreur sera signalée.
erreur de limitation de la plateforme, telle que la limitation de l'adresse IP, la précision des ordres, la fréquence d'accès, l'erreur de paramètre, la déficience des actifs, l'échec des transactions sur le marché, l'annulation des ordres exécutés, etc.; les détails peuvent être consultés dans le document API selon les codes incorrects.
Erreur de retour des données de la plateforme; cela arrive parfois, comme la retour de profondeur nulle, des informations de compte retardées et un statut de commande retardé, etc.
Erreur logique du programme.
Avant d'utiliser les données retournées d'API, vous devez juger si les données sont nulles, et les méthodes communes sont introduites comme suit:
//1.judge the data is null and handle
var ticker = exchange.GetTicker();
while(ticker == null){
Log('ticker obtain error');
ticker = exchange.GetTicker();
}
Log(ticker.Last);
// 2. judge the data is not null, and use
var ticker = exchange.GetTicker();
if(!ticker){
Log(ticker.Last);
}
// 3.retry _C() function
var ticker = _C(exchange.GetTicker);
Log(ticker.Last);
// 4.try cache fault tolerance
try{
var ticker = exchange.GetTicker();
Log(ticker.Last);
}
catch(err){
Log('ticker obtain error');
}
Si vous souhaitez obtenir des informations sur les erreurs, vous pouvez utiliserGetLastError()
, et les chaînes de l'information d'erreur de la dernière fois seront renvoyées, et les erreurs peuvent être traitées par des différences.
Résumé des erreurs courantes dans les premiers messages des forums:https://www.fmz.com/bbs-topic/9158. Ici nous l'introduisons brièvement; vous pouvez utiliser ctrl + F pour rechercher, lorsque vous avez des problèmes.
Comment déployer le docker?
Il y a une introduction détaillée à ce sujet dans la section sur l'ajout d'un docker.
Je peux demander à quelqu'un de rédiger des stratégies pour moi?
surhttps://www.fmz.com/markets, il y a des personnes qui fournissent des services de rédaction de stratégies pour d'autres, ou vous pouvez demander dans les groupes de discussion; notez que ce type de services doit être contacté par vous-même, et vous devez être conscient que le risque doit également être supporté par vous-même.
Toutes les interfaces demandent un temps d'arrêt lors de l'accès
Il s'agit du temps d'arrêt de l'interface de la plateforme à laquelle on accède; si le temps d'arrêt survient de temps en temps, ce n'est pas un problème; si le temps d'arrêt est demandé tout le temps, cela signifie que tous les réseaux ne peuvent pas être consultés et qu'un serveur étranger est nécessaire.
Le numéro d'identification est le numéro d'identification de l'établissement.
Si le backtest signale une erreur, il s'agit généralement d'une erreur d'écriture; lorsque vous essayez de placer un ordre pour fermer une position, lorsqu'il n'y a pas de position ou que le volume de position n'est pas suffisant, une erreur sera signalée.
Symbole non défini
Il n'y a pas de contrat défini dans le code, pendant les tests de rétroaction des plateformes de contrats à terme.
BITMEX 429error,{
error :{ message : Limit de débit dépassé en 1 seconde...... }}
La fréquence d'accès de l'interface de la plateforme est trop élevée.
L'heure est hors de portée.
L'horodatage du serveur dépasse la plage de temps de mise à jour du serveur et le temps dépassé ne peut pas être trop long.
GetOrder ((455284455): Erreur: ID de commande invalide ou commande annulée.
Si l'ordre d'une plateforme est annulé, la plateforme ne conservera plus les informations relatives à l'ordre, de sorte que ces informations ne peuvent être obtenues.
Je suis désolée. Je suis désolée.
Paire de trading invalide; vérifiez si le réglage de la paire de trading est incorrect.
Déchiffrement de clé secrète échoué
L'analyse APIKEY échoue. Si le mot de passe FMZ a été modifié après la configuration de l'APIKEY, essayez d'ajouter une page de plateforme sur FMZ et reconfigurez l'APIKEY de plateforme.
Signature non valide: heure de présentation non valide ou format d'heure incorrect
Je vous suggère d'utiliser un serveur Linux, ou d'installer un logiciel de synchronisation temporelle sur ces systèmes Windows où ce problème se produit.
Pourquoi le docker ne peut toujours pas accéder à l'API de la plateforme quand un proxy global est configuré?
Le proxy global n'a pas de port réseau de docker proxy. En raison du problème de retard, il est préférable de déployer le docker d'un serveur étranger.
Comment sauvegarder une stratégie localement, sans la télécharger sur FMZ?
En utilisant Python, et vous pouvez importer des fichiers locaux, enregistrer la stratégie normalement écrite par l'API FMZ comme un fichier et le mettre dans le chemin d'exécution sur votre propre serveur, et vous pouvez directement lire et l'exécuter.
#!python2.7
def run(runfile):
with open(runfile,"r") as f:
exec(f.read())
def main():
run('my.py')
Comment tester le réseau d'une plateforme ou comment changer l'adresse de base de l'API?
Utilisez exchange.SetBase() pour passer directement à l'adresse de base de l'API correspondante.
exchange.SetBase("https://www.okex.me")