Dans le dernier article, nous avons parlé de scripts de trading programmatiques. En fait, la stratégie de trading est un programme de script de trading. L'article parle principalement de la nécessité d'un support matériel pour le programme de script de trading (où le programme s'exécute), et le programme de trading de script peut être écrit dans quel type de langage de programmation informatique (trois langages de programmation utilisés sur la plateforme de trading FMZ Quant sont énumérés. Bien sûr, vous pouvez utiliser n'importe quel langage de programmation pour mettre en œuvre des stratégies de trading programmatique).
Types de stratégie de négociation Les débutants dans le trading programmé et le trading quantitatif peuvent être confus par des termes tels que diverses stratégies de tendance, stratégies d'arbitrage, stratégies à haute fréquence, stratégies de grille, etc. En fait, les types communs de stratégies dans le trading programmé et le trading quantitatif sont simplement plusieurs directions.
Ce qui précède est divisé du point de vue des stratégies de négociation. Du point de vue de la conception de la stratégie sur la plateforme de négociation FMZ Quant, les stratégies peuvent également être divisées en:
Interface de l'API d'échange
Comment le script de trading programmatique fonctionne le compte de change?
Alors, quels types d'interfaces sont ouvertes aux échanges? Dans l'article précédent, nous avons parlé de l'échange ont des interfaces REST et Websocket généralement dans la section
Interfaces qui ne nécessitent pas de vérification
Généralement appelé API KEY
(si vous oubliez ce qu'est la clé API, vous pouvez vous tourner vers l'article précédent). Ce type d'interface est l'interface de marché en général, comme la requête de prix de marché en profondeur, la requête de données de ligne K, la requête de taux de financement, la requête d'informations sur les variétés de trading, la requête des horodatages des serveurs d'échange, etc.
En termes simples, l'interface qui n'est pas liée à votre compte peut être déterminée à peu près comme une interface publique (pas de vérification requise)
Sur la plateforme de trading FMZ Quant, lors de l'appel d'une fonction API non vérifiée (encapsulant l'interface non vérifiée de l'échange, l'interface publique), même si la configuration API KEY est incorrecte, les données renvoyées par l'interface peuvent être obtenues normalement (en raison de la non-vérification).
Interfaces nécessitant une vérification En termes simples, c'est l'interface qui doit être vérifiée (via API KEY), ce type d'interface est appelée une interface privée. Elle est généralement liée à certaines opérations ou informations de votre compte, telles que la requête des actifs du compte, la requête des positions du compte, la requête des ordres en attente, la requête des transferts, le transfert de devises, l'ajustement du levier, le réglage du mode de position, etc. Il faut vérifier toutes ces opérations. Sur la plateforme de trading FMZ Quant, lors de l'appel de la fonction API qui doit être vérifiée (l'interface qui doit être vérifiée pour l'échange encapsulé, interface privée), si la CLAVE API est configurée incorrectement, une erreur sera signalée lors de l'appel de l'interface et une valeur nulle sera renvoyée.
Comment ces interfaces sont-elles utilisées sur la plateforme de trading FMZ Quant?
La plateforme de négociation quantitative FMZ encapsule le comportement d'échange et les interfaces avec des définitions cohérentes (telles que l'interface K-line, l'interface de marché approfondie, l'interface de requête d'actif en cours, l'interface d'ordre, l'interface d'annulation d'ordre, etc.), ces interfaces sont appelées fonctions de l'API de la plateforme de négociation quantitative FMZ sur la plateforme de négociation quantitative FMZ, et elle peut être consultée à partir de la documentation de l'API (https://www.fmz.com/api).
Alors, comment certaines des interfaces d'échange avec différents comportements et définitions sont-elles utilisées sur la plateforme de trading quantique FMZ?
Ces interfaces d'échange comprennent: transfert d'actifs, ordre conditionnel, placement d'ordres par lots, annulation d'ordres par lots, modification d'ordres, etc. Certaines bourses ont ces interfaces, d'autres non, et leurs fonctions et détails d'utilisation peuvent être très différents, de sorte que ces interfaces peuvent être consultées via leexchange.IO
fonction sur la plateforme de négociation quantitative FMZ (pour plus de détails, veuillez consulter la documentation de l'API de la plateforme de négociation quantitative FMZ:https://www.fmz.com/api#exchange.io..Il y a aussi quelques exemples pratiques de stratégies d'OI sur le carré de stratégie de la plateforme de trading quantique FMZ.
Toutes les fonctions d'API du document API de la plateforme de négociation quantique FMZ génèrent-elles des demandes réseau?
Tout d'abord, l'interface API de l'échange a des restrictions de fréquence d'accès (telles que 5 fois par seconde), et l'accès ne peut pas être trop fréquent, sinon il signalera une erreur http 429, et l'accès sera refusé (la plupart des échanges signalent 429). Toutes les fonctions d'API de la plateforme de trading FMZ Quant ne génèrent pas de requêtes réseau. Certaines d'entre elles ne modifient que certains paramètres locaux, tels que la définition de la paire de trading en cours, la définition du code de contrat, la fonction de calcul de l'indicateur et l'obtention du nom de l'objet d'échange, etc. Généralement, on peut juger si une demande de réseau se produit à partir de l'objectif de la fonction.
Parlons de certains problèmes et expériences courants lors de l'utilisation des fonctions API sur la plateforme de trading quantique FMZ
Tolérance aux erreurs C'est l'erreur la plus courante, qui a troublé d'innombrables débutants.
Lors de l'écriture d'une stratégie, nous devons tous juger et vérifier les données renvoyées par l'interface.var ticker = exchange. GetTicker()
, si nous avons besoin d' utiliser leLast
(dernier prix) données dans leticker
variable (se référer à la structure renvoyée par la fonction GetTicker), nous devons utiliservar newPrice = ticker.Last
Pour obtenir des données comme celle-ci (qu'est-ce que newPrice? new: latest, Price: price, yes!GetTicker()
fonction retourne aux données normales, c'est OK, mais s'il y a une demande de temps d'arrêt, erreur de réseau, l'échange tire le câble réseau, le câble est coupé, le gamin tire l'interrupteur électrique, etc...GetTicker()
fonction à revenir ànull
À l'heure actuelle,ticker
estnull
, et si je vais accéder à sonLast
, une exception de programme se produira et le programme de stratégie s'arrêtera.
Il semble que l'échec de l'appel de l'interface (l'appel GetTicker échoue et renvoie null) n'est pas la raison directe de l'arrêt de la stratégienull
Le rapport d'erreur de l'interface d'appel d'échec ne provoquera pas l'arrêt du bot réel (en-tête).
Alors, que pouvons-nous faire pour éviter l'arrêt anormal du vrai robot?
La réponse est d'effectuer un traitement tolérant aux erreurs sur les données renvoyées par l'interface.null
(un exemple de langage JavaScript, d'autres langages sont généralement les mêmes)
Écrivez un court segment de code pour la description (ce n'est qu'une description, vous ne pouvez pas l'exécuter directement!)
var ticker = exchange.GetTicker()
if (ticker) {
var newPrice = ticker.Last
Log("Print the latest price:", newPrice)
} else {
// The data is null, there will be no problem if no operation is performed
}
Non seulement leGetTicker
l'interface doit être tolérante aux erreurs, mais l'interface avec les requêtes réseau doit être tolérante aux erreurs pour la valeur de retour (si vous utilisez la valeur de retour de la fonction)
Il existe de nombreuses méthodes de tolérance aux défauts, vous pouvez utiliser le_C()
fonction (voir la documentation de l'API FMZ) pour écrire une fonction tolérante aux pannes et concevoir vous-même un mécanisme et une logique tolérants aux pannes.
En ce qui concerne l'utilisation de la_C()
Il faut noter que le paramètre de l'interface utilisateur_C()
fonction est une référence de fonction, pas un appel de fonction._C(funcName, param1, param2)
, l'appel est correct, funcName est sans parenthèses, et param1 et param2 sont les paramètres à passer à la fonction funcName._C(funcName(param1, param2))
, l'appel est incorrect, généralement écrit par des débutants qui ne lisent pas sérieusement la documentation de l'API FMZ.
Quantité de l'ordre de l'ordre d'achat sur le marché au comptant
La quantité d'ordre de l'ordre d'achat du marché au comptant est également facile à faire des erreurs par les débutants, comme mentionné dans l'article précédent, la quantité d'ordre de l'ordre d'achat du marché au comptant est généralement le montant (très peu d'échanges peuvent être d'autres paramètres, en général, ces paramètres d'échange spéciaux sur FMZ seront expliqués dans le document FMZ API), par exemple, j'utilise OKEX V5 démo pour tester:
La paire de négociation est définie comme suit:LTC_USDT
function main() {
exchange.IO("simulate", true) // Switch to the demo of OKEX exchange
exchange.Buy(-1, 1) // The price is -1, indicating that the order placed is a market order, and the quantity is 1, indicating that the order amount is 1USDT
}
Étant donné que les bourses ont généralement une limite sur le montant de la commande, les commandes inférieures à cette limite ne seront pas passées (par exemple, Binance Spot nécessite chaque commande supérieure à 5USDT avant de pouvoir être passée avec succès).Par conséquent, il signalera une erreur si vous passez une commande comme celle-ci:
Error Buy(-1, 1): map[code:1 data:[map[clOrdId: ordId: sCode:51020 sMsg:Order amount should be greater than the min available amount. tag:]] msg:]
Direction à suivre pour les futures commandes Lorsque vous élaborez des stratégies de contrats à terme, la direction de la passation des ordres est souvent faite par des débutants, ce qui conduit à des problèmes. Regardons d'abord la description sur la documentation de l'API:https://www.fmz.com/api#exchange.setdirection...
Comme la fonction d'ordre est seulementBuy
, Sell
Cependant, les contrats à terme (bien sûr, il n'y a pas de problème avec le spot, le spot est seulement acheté et vendu) ont les directions d'ouverture longue, de fermeture longue, d'ouverture courte et de fermeture courte, il est donc évident que Buy/Sell ne peut pas exprimer les opérations dans autant de directions.exchange.SetDirection()
, qui détermine l'orientation des transactions à terme.
À FMZ,exchange.SetDirection("buy")
(définir la direction en premier) est utilisé en conjonction avecexchange.Buy
, cela signifie que l'ordre passé est un ordre d'ouverture d'une position longue.
Et ainsi de suite:exchange.SetDirection("sell")
est utilisé en association avecexchange.Sell
, cela signifie que l'ordre passé est un ordre d'ouverture d'une position courte.exchange.SetDirection("closebuy")
est utilisé en association avecexchange.Sell
, cela signifie que l'ordre passé est un ordre de clôture d'une position longue.exchange.SetDirection("closesell")
est utilisé en association avecexchange.Buy
, cela signifie que l'ordre passé est un ordre de clôture d'une position courte.
Les débutants utilisent généralementexchange.SetDirection("sell")
en conjonction avecexchange.Buy
, ou d'autres combinaisons erronées. Une erreur est alors signalée (le backtesting peut ne pas signaler d'erreur, mais il s'agit évidemment d'une erreur logique, le trouble obsessionnel-compulsif ne peut pas être toléré...).
Une autre erreur commune des débutants
function main() {
exchange.SetContractType("quarter") // Set the current contract as a quarterly contract
exchange.SetDirection("sell")
var id = exchange.Sell(-1, 1)
Log("See my market order is placed and the transaction is completed, there is a position", exchange.GetPosition())
exchange.SetDirection("closebuy") // closebuy is used in conjunction with Sell, yes~
exchange.Sell(-1, 1)
}
Vous pourriez vous demander:
Sortie du journal, affichage des informations sur les transactions
La conception de stratégies de trading programmées et quantitatives est inséparable de la conception de l'interaction homme-ordinateur, comme l'affichage des données et la sortie du journal des opérations.
Par exemple:
utilisation de pythonprint
- Je ne sais pas.
utilisation de javascriptconsole.log
Je suis désolée.
Utilisation du golangfmt.Println()
Je suis désolée.
Utilisation de C++cout
Parlons de l'affichage de l'information sur la plateforme FMZ, sur la plateforme FMZ Quant Trading, il y a deux endroits principaux où l'information est affichée.
Colonne de statut Une fois le vrai bot exécuté, la vraie page du bot est comme indiqué sur la figure:
La partie d'affichage est l'information de la colonne d'état. La colonne d'état est principalement utilisée pour afficher des données changeantes en temps réel (parce que les changements en temps réel doivent être observés en temps réel et ne peuvent pas être imprimés en tant que journal à chaque fois, ce type de données peut être affiché dans la colonne d'état. Le journal répète beaucoup de données en double et sans sens, ce qui affecte la requête si chaque journal est imprimé).
Les données affichées dans la colonne d'état utilisent leLogStatus
Pour plus de détails, veuillez consulter la documentation de l'API FMZ.
Colonne de log Également désactivé sur la page du vrai bot, comme indiqué sur la figure:
La partie affichée est la colonne de journal. La colonne de journal est principalement utilisée pour enregistrer certaines données à un certain moment en permanence, ou pour enregistrer une opération d'une certaine stratégie à un certain moment. Il existe différents types de bûches:
Log commun, les stratégies sur FMZ adoptent la fonction Log pour la sortie et l'impression dans le log de stratégie.
Journaux des commandes, utilisationexchange.Sell
/exchange.Buy
Dans la stratégie FMZ
Le journal des annulations,exchange.CancelOrder
est utilisé dans la stratégie FMZ
Journal des erreurs, lorsque la stratégie sur FMZ est en cours d'exécution, une erreur d'appel se produit sur l'interface qui fait une demande réseau, une exception est lancée (comme une déclaration de lancement), le journal des erreurs est publié dans le journal automatiquement.
Les fonctions d'API sur FMZ, les fonctions qui peuvent générer une sortie de journal comme Log ((...), exchange.Buy ((Price, Amount), exchange.CancelOrder ((Id), etc., peuvent toutes être suivies par des paramètres de sortie supplémentaires après les paramètres nécessaires, tels que: exchange. CancelOrder ((ordres[j].Id, orders[j]), c'est-à-dire pour produire les informations de commande lorsque l'ordre des commandes[j] est annulé.
function main() {
Log("data1", "data2", "data3", "...")
var data2 = 200
var id = exchange.Sell(100000, 0.1, "Attached data1", data2, "...")
exchange.CancelOrder(id, "Attached data1", data2, "...")
LogProfit(100, "Attached data1", data2, "...")
}
Utilisation des fonctions d'indicateur
Avant de parler de la fonction d'indicateur, comprenons d'abord ce qu'est un indicateur.
Q: D'où proviennent ces indicateurs?
R: Bien sûr que c'est calculé.
Q: Quelle est la base du calcul?
R: Calcul basé sur les données de la ligne K.
Q: Prenez un exemple?
R: En prenant comme exemple l'indicateur de moyenne mobile de l'indicateur le plus simple, si nous utilisons les données quotidiennes de la ligne K (c'est-à-dire une ligne positive ou négative représente un jour) comme source de données pour le calcul de l'indicateur.
Q: L'indicateur de moyenne mobile peut-il être calculé si le nombre de BAR de la ligne K est inférieur à 10?
R: Non seulement l'indicateur de moyenne mobile ne peut pas être calculé, mais aucun indicateur ne peut calculer la valeur effective de l'indice lorsque le nombre de données BAR de ligne K ne répond pas au paramètre de la période de l'indicateur, et la position correspondante du tableau calculé sera remplie de valeurs vides, par exemple,JavaScript
La stratégie linguistique afficheranull
lors de l'impression des données de l'indicateur calculé.
Il arrive qu'il y ait un exemple de tutoriel dans le carré de stratégie:https://www.fmz.com/strategy/125770En recourant à la stratégie de l'exemple de tutoriel, nous pouvons voir le graphique généré par le système de backtesting et la moyenne mobile à 10 périodes:
Des dessins personnalisés de la stratégie, des lignes K dessinées ainsi que des graphiques de moyennes mobiles.
Q: Et si je voulais une moyenne mobile sur 10 heures? R: Utiliser les données de la ligne K avec les données de la ligne K de la période horaire sera très bien.
En termes simples, la ligne K que nous voyons est un tableau après l'avoir numérisé (vous pouvez demander à Baidu si vous ne comprenez pas le concept de tableau), dont chaque élément est une colonne de ligne K, qui est disposée dans l'ordre, le premier élément du tableau est le plus éloigné de l'heure actuelle, et le dernier élément du tableau est le plus proche de l'heure actuelle. En règle générale, la dernière barre des données de la ligne K est la barre de la période en cours, qui change en temps réel et elle est incomplète (vous pouvez observer les changements en vous connectant à une page d'échange et en observant la ligne K). Les indicateurs calculés sont également en correspondance avec les barres de la ligne K. Dans l'exemple ci-dessus, nous pouvons voir qu'une valeur d'indicateur correspond à une barre de la ligne K. Notez que la dernière barre de la ligne K change en temps réel, et l'indicateur calculé changera également avec le changement de la barre de la ligne K.
Sur la plateforme de trading FMZ Quant, nous pouvons utiliser la bibliothèque TA (la bibliothèque mise en œuvre par la plateforme FMZ, intégrée dans le docker, et divers langages peuvent être utilisés directement) ou la bibliothèque talib (l'ancienne bibliothèque d'indicateurs talib, JS, intégration C ++, Python doit être installée par vous-même). Par exemple, pour calculer la moyenne mobile dans l'exemple ci-dessus: Utilisez la bibliothèque TA:
function main() {
var records = exchange.GetRecords()
var ma = TA.MA(records, 10)
Log(ma) // print moving average
}
Utilisez la bibliothèque talib:
function main() {
var records = exchange.GetRecords()
var ma = talib.MA(records, 10)
Log(ma) // print moving average
}
L'indicateur de données calculé ma est une matrice, et chaque élément correspond à la matrice de ligne K (enregistrements) un à un, c'est-à-dire,ma[ma.length -1]
correspond àrecords[records.length - 1]
, et ainsi de suite.
Il en va de même pour d'autres indicateurs complexes, et nous devons prêter attention à des indicateurs tels que le MACD.
var macd = TA.MACD(records) // In this way, only the K-line data is passed in, not the indicator parameters. The indicator parameters use the default values, and the same goes for other indicator functions.
À ce stade, la variable macd est un tableau bidimensionnel (vous pouvez demander à Baidu si vous ne comprenez pas le concept). Q: Pourquoi les données de l'indicateur MACD sont-elles un tableau bidimensionnel? R: Parce que l'indicateur macd est composé de deux lignes (ligne dif, ligne dea) et d'un ensemble de barres de volume (barre de volume macd, en fait, ces données de barres de volume peuvent également être considérées comme une ligne).
var dif = macd[0]
var dea = macd[1]
var macdColumn = macd[2]
Voici également un exemple de tutoriel prêt à l'emploi, si vous êtes intéressé, vous pouvez étudier à:https://www.fmz.com/strategy/151972