dans les 10 derniers journaux et effacer le reste
LogReset (Réinitialiser le journal)
}
```Python
def main():
LogReset(10)
void main() {
LogReset(10);
}
LogVacuum()
, après avoir appelé leLogReset()
fonction de nettoyage du journal, récupère l'espace de stockage occupé parSQLiteLa fonction ne renvoie aucune valeur.
La raison en est queSQLite
ne récupère pas l'espace occupé lors de la suppression des données, vous devez donc effectuerVACUUM
Lorsque cette fonction est appelée, l'opération de déplacement de fichier se produira avec un grand retard. Il est recommandé de l'appeler à un intervalle de temps approprié.
Les principales fonctions de l'interface de marché sont les suivantes:
Nom de la fonction | Définition |
---|---|
GetTicker | Obtenez les données des guillemets |
Obtenez des enregistrements | Obtenez les données de la ligne K. |
Obtenez la profondeur | Obtenir les données du carnet de commandes (données de profondeur de commande) |
GetTrades | Obtenez les derniers dossiers de négociation sur le marché |
Les fonctions suivantes peuvent être appelées viaexchange
ouexchanges[0]
les objets; par exemple: les fonctions, commeexchange.GetTicker();
ouexchanges[0].GetTicker();
, renvoie les cotations de marché des paires de négociation en cours et les contrats de fixation.
Conseils importants pour appeler des fonctions API avec accès au réseau:Lors de l'appel d'une fonction API qui accède à une interface de plateforme (commeexchange.GetTicker()
, exchange.Buy(Price, Amount)
, exchange.CancelOrder(Id)
Il est donc nécessaire d'effectuer un traitement tolérant aux erreurs pour l'appel de ces fonctions.exchange.GetTicker()
La fonction d'obtention des données de marché peut, en raison de problèmes de serveur de plateforme et de problèmes de transmission de réseau, etc., entraîner que la valeur de retour de la plateforme soit inférieure ou égale à la valeur de retour de la plateforme.exchange.GetTicker()
la fonction estnull
. Ensuite, la valeur de retour deexchange.GetTicker()
doivent être traités par un traitement tolérant aux erreurs.
Les données renvoyées par leexchange.GetTicker()
Le code suivant est attribué à la fonctionticker
La valeur de l'échantillon est variable, et nous devons nous occuper de la tolérance à la défaillance avant d'utiliser leticker
variable.
function main() {
var ticker = exchange.GetTicker()
if(!ticker){
// Recall once, or use other processing logic
ticker = exchange.GetTicker()
}
}
def main():
ticker = exchange.GetTicker()
if not ticker:
ticker = exchange.GetTicker()
void main() {
auto ticker = exchange.GetTicker();
if(!ticker.Valid) {
ticker = exchange.GetTicker();
Log("Test");
}
}
En outre, pour les tests de performance de la stratégie en matière de tolérance aux défauts, la FMZ a spécifiquement ajouté unemode tolérant aux défautsLe système de backtest peut retourner aléatoirement certains appels API qui se produiront lorsque le réseau est accédé selon les paramètres définis, et retourner les valeurs de retour de certains appels échoués. Vous pouvez rapidement tester la robustesse du programme dans le bot.
Passez à la page du système de backtest sur la page d'édition de stratégie, cliquez sur letriangle inverséle contrôle déroulant sur le côté droit du bouton
exchange.GetTicker()
obtient les cotations de marché actuelles des paires et contrats de négociation en cours, avec la valeur de rendement:Ticker
la structure.
Dans le système de backtest, leTicker
Les données renvoyées par leexchange.GetTicker()
fonction, oùHigh
etLow
sont des valeurs simulées, prises à partir du moment actuel de Tick
interface.
function main(){
var ticker = exchange.GetTicker()
/*
The platform interface may not be accessible due to network problems (even if the device's docker program can open the platform website, the API may not be accessible)
At this time, ticker is null, when accessing ticker. When it is "High", it will cause an error; so when testing, ensure that you can access the platform interface
*/
Log("High:", ticker.High, "Low:", ticker.Low, "Sell:", ticker.Sell, "Buy:", ticker.Buy, "Last:", ticker.Last, "Volume:", ticker.Volume)
}
def main():
ticker = exchange.GetTicker()
Log("High:", ticker["High"], "Low:", ticker["Low"], "Sell:", ticker["Sell"], "Buy:", ticker["Buy"], "Last:", ticker["Last"], "Volume:", ticker["Volume"])
void main() {
auto ticker = exchange.GetTicker();
Log("High:", ticker.High, "Low:", ticker.Low, "Sell:", ticker.Sell, "Buy:", ticker.Buy, "Last:", ticker.Last, "Volume:", ticker.Volume);
}
Dans le vrai bot (pas backtest), leInfo
attribut dans la valeur de retour de laexchange.GetTicker()
La fonction stocke les données originales renvoyées lorsque l'interface est appelée.
exchange.GetDepth()
obtient les données du carnet des ordres de change des paires et contrats de négociation en cours.Depth
structure.
Depth
La structure contient deux ensembles de structures, à savoirAsks[]
etBids[]
, Asks
etBids
contiennent les variables de structure suivantes:
Type de données | Nom de la variable | Définition |
---|---|---|
Numéro | Le prix | prix |
Numéro | Montant | Le montant |
Par exemple, si je veux obtenir le prix de vente actuel, je peux écrire le code comme ceci:
function main(){
var depth = exchange.GetDepth()
/*
The platform interface may not be accessible due to network reasons (even if the device's docker program can open the platform website, the API may not be accessible)
At this time, depth is null. When accessing depth.Asks[1].Price, it will cause an error; so when testing, ensure that you can access the platform interface
*/
var price = depth.Asks[1].Price
Log("Sell 2 price is:", price)
}
def main():
depth = exchange.GetDepth()
price = depth["Asks"][1]["Price"]
Log("Sell 2 price is:", price)
void main() {
auto depth = exchange.GetDepth();
auto price = depth.Asks[1].Price;
Log("Sell 2 price is:", price);
}
exchange.GetTrades()
obtient l'historique des transactions sur la plateforme (pas le vôtre).Trade
Les données spécifiques renvoyées dépendent des enregistrements de négociation dans la plage, selon des circonstances spécifiques.
Les données renvoyées sont un tableau, où la séquence temporelle de chaque élément est la même que la séquence de données renvoyées de laexchange.GetRecords
fonction, c'est-à-dire que le dernier élément du tableau est les données les plus proches de l'heure actuelle.
// In the simulated backtest, the data is empty; to have a trading history, there must be a real bot running
function main(){
var trades = exchange.GetTrades()
/*
The platform interface may not be accessible due to network reasons (even if the device's docker program can open the platform website, the API may not be accessible)
At this time, "trades" is null. When accessing trades[0].Id, it will cause an error; so when testing, ensure that you can access the platform interface
*/
Log("id:", trades[0].Id, "time:", trades[0].Time, "Price:", trades[0].Price, "Amount:", trades[0].Amount, "type:", trades[0].Type)
}
def main():
trades = exchange.GetTrades()
Log("id:", trades[0]["Id"], "time:", trades[0]["Time"], "Price:", trades[0]["Price"], "Amount:", trades[0]["Amount"], "type:", trades[0]["Type"])
void main() {
auto trades = exchange.GetTrades();
Log("id:", trades[0].Id, "time:", trades[0].Time, "Price:", trades[0].Price, "Amount:", trades[0].Amount, "type:", trades[0].Type);
}
exchange.GetRecords(Period)
retourne les données de ligne K. La période de ligne K est spécifiée lors de la création du bot; si vous spécifiez les paramètres lorsque leexchange.GetRecords()
si la fonction est appelée, les données obtenues seront les données de ligne K correspondant à la période du paramètre. S'il n'y a pas de paramètre spécifié, les données de ligne K sont renvoyées selon la période de ligne K définie sur les paramètres du bot ou la période de ligne K définie sur la page de backtest.
ParamètrePeriod
:
Period
ne peut passer que les périodes standard définies ci-dessus, mais peut également passer des nombres, en unité de seconde.La valeur de retour deexchange.GetRecords(Period)
fonction:
La valeur retournée est un tableau deRecord
Les données de ligne K renvoyées seront accumulées au fil du temps, la limite supérieure des barres de ligne K accumulées est affectée par leexchange.SetMaxBarLenLa limite supérieure par défaut est de 5000 K-line bars lorsqu'elle n'est pas définie. Lorsque les données K-Line atteignent la limite d'accumulation de la barre K-Line, elles seront mises à jour en ajoutant une barre K-Line et en supprimant la barre K-Line la plus ancienne (par exemple, file d'attente d'entrée/sortie). Certains échanges ne fournissent pas d'interface K-line, puis le docker collecte les données d'enregistrement des transactions de marché en temps réel pour générer des K-lines.
Nombre de barres de ligne K récupérées lorsque leGetRecords
la fonction est initialement appelée.
Pour leexchange.GetRecords(Period)
fonction, le bot et le backtest decrypto-monnaieles deux prennent en charge les périodes personnalisées, et le paramètrePeriod
est le nombre de secondes. Par exemple:
function main() {
// Print K-line data with a K-line period of 120 seconds (2 minutes)
Log(exchange.GetRecords(60 * 2))
// Print K-line data with a K-line period of 5 minutes
Log(exchange.GetRecords(PERIOD_M5))
}
def main():
Log(exchange.GetRecords(60 * 2))
Log(exchange.GetRecords(PERIOD_M5))
void main() {
Log(exchange.GetRecords(60 * 2)[0]);
Log(exchange.GetRecords(PERIOD_M5)[0]);
}
RéglagePeriod
le paramètre 5 est de demander des données de ligne K avec une période de 5 secondes.
Si lePeriod
Le paramètre n'est pas divisé uniformément par 60 (c'est-à-dire que la période représentée est une période de minutes indisponibles), la couche inférieure du système utilise l'interface correspondante deGetTrades
d'obtenir des données sur les enregistrements de négociation et de synthétiser les données de ligne K requises.
Si lePeriod
le paramètre est divisé uniformément par 60, puis les données de ligne K requises sont synthétisées en utilisant au moins des données de ligne K d'une minute (en utilisant une période plus longue pour synthétiser les données de ligne K requises si possible).
function main(){
var records = exchange.GetRecords(PERIOD_H1)
/*
The platform interface may not be accessible due to network reasons (even if the device's docker program can open the platform website, the API may not be accessible)
At this time, "records" is null. When accessing records[0].Time, it will cause an error; so when testing, ensure that you can access the platform interface
*/
Log("The first k-line data is, Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High)
Log("The second k-line data is, Time:", records[1].Time ,"Close:", records[1].Close)
Log("Current K-line (latest)", records[records.length-1], "Current K-line (latest)", records[records.length-2])
}
def main():
records = exchange.GetRecords(PERIOD_H1)
Log("The first k-line data is, Time:", records[0]["Time"], "Open:", records[0]["Open"], "High:", records[0]["High"])
Log("The second k-line data is, Time:", records[1]["Time"], "Close:", records[1]["Close"])
Log("Current K-line (latest)", records[-1], "Current K-line (latest)", records[-2])
void main() {
auto records = exchange.GetRecords(PERIOD_H1);
Log("The first k-line data is, Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High);
Log("The second k-line data is, Time:", records[1].Time, "Close:", records[1].Close);
Log("Current K-line (latest)", records[records.size() - 1], "Current K-line (latest)", records[records.size() - 2]);
}
exchange.GetRecords()
La fonction a deux conditions pour obtenir des données de ligne K:
L'échange fournit une interface de données en ligne K. Dans ce cas, les données acquises sont les données directement renvoyées par l'échange.
L'échange ne fournit pas d'interface de données en ligne K. Le programme FMZ docker obtient les derniers enregistrements de trading de l'échange à chaque fois que le programme de stratégie appelleexchange.GetRecords()
, c'est-à-dire qu'il appelle leexchange.GetTrades()
fonction d'obtention de données et de synthèse de données de ligne K.
Le backtest au niveau de la simulation dans le système doit définir lepériode sous-jacente de la ligne K(lorsque le système de backtesting simule le niveau de backtesting, les données de ligne K correspondantes sont utilisées pour générer des données de tick selon l'ensemblepériode sous-jacente de la ligne K); il convient de noter que la période des données de ligne K obtenues dans la stratégie ne peut être inférieure àla période sous-jacente de la ligne KParce que dans le backtest de niveau de simulation, les données de ligne K de chaque période sont synthétisées par les données de ligne K correspondant aux périodes de ligne K sous-jacentes dans le système de backtest.
Danscpp
langage, si vous avez besoin de construire vos propres données de ligne K, il y a les exemples de code suivants:
#include <sstream>
void main() {
Records r;
r.Valid = true;
for (auto i = 0; i < 10; i++) {
Record ele;
ele.Time = i * 100000;
ele.High = i * 10000;
ele.Low = i * 1000;
ele.Close = i * 100;
ele.Open = i * 10;
ele.Volume = i * 1;
r.push_back(ele);
}
// Output display: Records[10]
Log(r);
auto ma = TA.MA(r,10);
// Output display: [nan,nan,nan,nan,nan,nan,nan,nan,nan,450]
Log(ma);
}
Leexchange.GetPeriod()
La fonction renvoie la période de ligne K définie sur la page du site Web de la plateforme FMZ lors de l'exécution de stratégies danstest de retouretle robot. La valeur de retour est un entier dans l'unité de seconde.
function main() {
// For example, in the backtest and bot, set the K-line period on the website page of FMZ platform to 1 hour
var period = exchange.GetPeriod()
Log("K-line period:", period / (60 * 60), "hour")
}
def main():
period = exchange.GetPeriod()
Log("K-line period:", period / (60 * 60), "hour")
void main() {
auto period = exchange.GetPeriod();
Log("K-line period:", period / (60 * 60.0), "hour");
}
Leexchange.SetMaxBarLen(Len)
la fonction affecte deux aspects au cours de l'exécution de la stratégie de crypto-monnaie:
function main() {
exchange.SetMaxBarLen(50)
var records = exchange.GetRecords()
Log(records.length, records)
}
def main():
exchange.SetMaxBarLen(50)
r = exchange.GetRecords()
Log(len(r), r)
void main() {
exchange.SetMaxBarLen(50);
auto r = exchange.GetRecords();
Log(r.size(), r[0]);
}
exchange.GetRawJSON()
renvoie le contenu brut (chaînes) renvoyé par la dernièreRESTdemande, qui peut être utilisée pour analyser les données par vous-même. Valeur de retour: type de chaîne, valable uniquement dans l'environnement de trading en direct de crypto-monnaie. Backtest ne prend pas en charge la fonction.
Stratégies danscpp
Le langage ne supporte pas la fonction.
function main(){
exchange.GetAccount();
var obj = JSON.parse(exchange.GetRawJSON());
Log(obj);
}
import json
def main():
exchange.GetAccount()
obj = json.loads(exchange.GetRawJSON())
Log(obj)
void main() {
auto obj = exchange.GetAccount();
// C++ doe not support "GetRawJSON" function
Log(obj);
}
exchange.GetRate()
renvoie les taux de change de la devise actuellement utilisée dans l'échange et la devise de tarification actuellement affichée, et une valeur renvoyée de 1 indique que la conversion des taux de change est désactivée.
Note: le numéro de série
exchange.SetRate()
n'a pas été appelé à fixer le taux de change, la valeur du taux de change renvoyée parexchange.GetRate()
est 1 par défaut, c'est-à-dire que la conversion du taux de change actuellement affichée n'a pas été échangée.exchange.SetRate()
a été utilisé pour fixer une valeur de taux de change, par exemple:exchange.SetRate(7)
, toutes les informations relatives aux prix de l'objet d'échange en cours représentant la monnaie en circulation de la plateforme de négociation, telles que les cotations, la profondeur, les prix des ordres, etc., seront multipliées par le taux de change 7 préalablement fixé pour la conversion.exchange
correspond à un échange avec USD comme monnaie de tarification, après avoir appeléexchange.SetRate(7)
, tous les prix du bot seront convertis en prix proches du CNY en multipliant par 7.exchange.GetRate()
est 7.exchange.GetUSDCNY()
renvoie le dernier taux de change du dollar américain (source de données fournie paryahoo
La valeur renvoyée est de type numérique.
Leexchange.SetData(Key, Value)
La fonction est utilisée pour définir les données chargées au moment où la stratégie est en cours d'exécution, ce qui peut être n'importe quel indicateur économique, données de l'industrie, indice pertinent, etc. Elle peut être utilisée pour quantifier toutes les informations quantifiables pour les stratégies de trading et également pour soutenir l'utilisation dans le système de backtest.
Méthode d'appel deexchange.SetData(Key, Value)
fonction:
Écrire les données directement dans la stratégie
Le format de données est requis en tant quedata
variable dans l'exemple suivant.
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
function main() {
var data = [
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]
exchange.SetData("test", data)
while(true) {
Log(exchange.GetData("test"))
Sleep(1000)
}
}
'''backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
'''
def main():
data = [
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]
exchange.SetData("test", data)
while True:
Log(exchange.GetData("test"))
Sleep(1000)
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
void main() {
json data = R"([
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
])"_json;
exchange.SetData("test", data);
while(true) {
Log(exchange.GetData("test"));
Sleep(1000);
}
}
Lorsque le code d'essai ci-dessus est exécuté, les données correspondantes sont obtenues au moment correspondant, comme indiqué sur la figure:
Comme nous pouvons le voir, l'heure correspondante de l'horodatage1579622400000
est2020-01-22 00: 00: 00
; lorsque le programme de stratégie s'exécute après cette heure, avant le prochain horodatage des données1579708800000
, c'est-à-dire avant le2020-01-23 00: 00: 00
Appelez leexchange.GetData(Source)
Les données sont fournies en fonction de la fonction d'obtention.[1579622400000, 123]
Au fur et à mesure que le programme continue à fonctionner et que le temps change, obtenir des données pièce par pièce comme ceci.
Demander des données par le biais de liens externes
Format de données demandé
{
"schema":["time","data"],
"data":[
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]
}
Où?schema
est le format de données de chaque enregistrement dans le corps principal des données chargées, le format est fixé comme["time", "data"]
, correspondant à ladata
Le format d'attribut des données un par un.data
L'attribut stocke le corps principal des données, et chaque élément des données est composé d'horodatages et de contenu de données au niveau des millisecondes (le contenu des données peut être n'importe quelle donnée codée JSON).
Le programme de service pour les tests est écrit enGo
langue:
package main
import (
"fmt"
"net/http"
"encoding/json"
)
func Handle (w http.ResponseWriter, r *http.Request) {
defer func() {
fmt.Println("req:", *r)
ret := map[string]interface{}{
"schema": []string{"time","data"},
"data": []interface{}{
[]interface{}{1579536000000, "abc"},
[]interface{}{1579622400000, 123},
[]interface{}{1579708800000, map[string]interface{}{"price":123}},
[]interface{}{1579795200000, []interface{}{"abc", 123, map[string]interface{}{"price":123}}},
},
}
b, _ := json.Marshal(ret)
w.Write(b)
}()
}
func main () {
fmt.Println("listen http://localhost:9090")
http.HandleFunc("/data", Handle)
http.ListenAndServe(":9090", nil)
}
Après avoir reçu la demande, le programme répond aux données:
{
"schema":["time","data"],
"data":[
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]
}
Code de stratégie de test:
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
function main() {
while(true) {
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
Sleep(1000)
}
}
'''backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
'''
def main():
while True:
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
Sleep(1000)
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
void main() {
while(true) {
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"));
Sleep(1000);
}
}
Leexchange.GetData(Source)
fonction est utilisée pour obtenir les données chargées par leexchange.SetData(Key, Value)
Les données sont obtenues en une seule fois pendant le backtest, et les données sont mises en cache pendant une minute pendant la négociation réelle.
Obtention de la méthode d'appel des données écrites directement
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
function main() {
exchange.SetData("test", [[1579536000000, _D(1579536000000)], [1579622400000, _D(1579622400000)], [1579708800000, _D(1579708800000)]])
while(true) {
Log(exchange.GetData("test"))
Sleep(1000 * 60 * 60 * 24)
}
}
'''backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
'''
def main():
exchange.SetData("test", [[1579536000000, _D(1579536000000/1000)], [1579622400000, _D(1579622400000/1000)], [1579708800000, _D(1579708800000/1000)]])
while True:
Log(exchange.GetData("test"))
Sleep(1000 * 60 * 60 * 24)
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
void main() {
json arr = R"([[1579536000000, ""], [1579622400000, ""], [1579708800000, ""]])"_json;
arr[0][1] = _D(1579536000000);
arr[1][1] = _D(1579622400000);
arr[2][1] = _D(1579708800000);
exchange.SetData("test", arr);
while(true) {
Log(exchange.GetData("test"));
Sleep(1000 * 60 * 60 * 24);
}
}
Méthode d'appel de données à partir de liens externes
function main() {
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"))
}
def main():
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"))
void main() {
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"));
Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"));
}
Utiliser les données fondamentales du centre de données de la plateforme
Utilisez leexchange.GetData(Source)
fonction à obtenirDonnées fondamentales.
Lorsque vous appelez leexchange.GetData(Source)
Dans le système de backtest, lors de l'utilisation de l'interface d'accès pour demander des données, le système de backtest ajoutera automatiquement des paramètres
Les fonctions suivantes peuvent être appelées par leexchange
ouexchanges[0]
Par exemple:exchange.Sell(100, 1);
indique que l'ordre suivant est un ordre de vente avec un prix de 100 et une quantité de 1 sur la bourse.
exchange.Buy(Price, Amount)
est utilisé pour passer un ordre d'achat et renvoyer un identifiant d'ordre. Valeur du paramètre:Price
est le prix de la commande en type de numéro, etAmount
est le montant de la commande en type de numéro. Valeur de retour: type de chaîne ou type numérique (le type spécifique dépend du type de retour de chaque plateforme d'échange).
Le numéro de commande retourné peut être utilisé pour interroger les informations de commande et annuler les commandes.
function main() {
var id = exchange.Buy(100, 1);
Log("id:", id);
}
def main():
id = exchange.Buy(100, 1)
Log("id:", id)
void main() {
auto id = exchange.Buy(100, 1);
Log("id:", id);
}
Commande à terme
Lors de la passation d'ordres pour les contrats à terme, nous devons faire attention à savoir si la direction de négociation est correctement définie. Si la direction de négociation et la fonction de négociation ne correspondent pas, une erreur sera signalée. Le nombre d'ordres passés sur un échange de contrats à terme de crypto-monnaie est le nombre de contrats, sauf indication contraire. Par exemple:
// The following is the wrong call
function main() {
exchange.SetContractType("quarter")
// Set short direction
exchange.SetDirection("sell")
// Place a buy order, and you will get an error, so you can only sell short
var id = exchange.Buy(50, 1)
// Set short direction
exchange.SetDirection("buy")
// Place a sell order, and you will get an error, so you can only buy long
var id2 = exchange.Sell(60, 1)
// Set close long position direction
exchange.SetDirection("closebuy")
// Place a buy order, and you will get an error, so you can only sell short
var id3 = exchange.Buy(-1, 1)
// Set close short position direction
exchange.SetDirection("closesell")
// Place a sell order, and you will get an error, so you can only buy long
var id4 = exchange.Sell(-1, 1)
}
# The following is the wrong call
def main():
exchange.SetContractType("quarter")
exchange.SetDirection("sell")
id = exchange.Buy(50, 1)
exchange.SetDirection("buy")
id2 = exchange.Sell(60, 1)
exchange.SetDirection("closebuy")
id3 = exchange.Buy(-1, 1)
exchange.SetDirection("closesell")
id4 = exchange.Sell(-1, 1)
// The following is the wrong call
void main() {
exchange.SetContractType("quarter");
exchange.SetDirection("sell");
auto id = exchange.Buy(50, 1);
exchange.SetDirection("buy");
auto id2 = exchange.Sell(60, 1);
exchange.SetDirection("closebuy");
auto id3 = exchange.Buy(-1, 1);
exchange.SetDirection("closesell");
auto id4 = exchange.Sell(-1, 1);
}
Messages d' erreur:
direction is sell, invalid order type Buy
direction is buy, invalid order type Sell
direction is closebuy, invalid order type Buy
direction is closesell, invalid order type Sell
L'ordre du marché
Note: L'interface d'ordre d'échange est nécessaire pour prendre en charge les ordres de marché (lorsque le type d'ordre est un ordre d'achat, le paramètre de montant de l'ordre est le montant en devise de cotation), et la méthode d'ordre de marché des contrats à terme de crypto-monnaie est utilisée pour passer des ordres, et l'unité du paramètre de quantité est lenombre de contratsQuelques échanges de transactions en direct pour les monnaies numériques ne prennent pas en charge les interfaces d'ordre de marché.
// For example, trading pairs: ETH_BTC, bought in by market order
function main() {
// Buy a market order, and buy ETH coins equal to 0.1 BTC (quote currency)
exchange.Buy(-1, 0.1)
}
def main():
exchange.Buy(-1, 0.1)
void main() {
exchange.Buy(-1, 0.1);
}
exchange.Sell(Price, Amount)
place un ordre de vente et renvoie un identifiant d'ordre. Valeur du paramètre:Price
est le prix de commande, de type numérique.Amount
est le montant de la commande, type numérique. Valeur de retour: type de chaîne ou type numérique (le type spécifique dépend du type de retour de chaque échange).
Numéro de commande retourné, qui peut être utilisé pour interroger les informations de commande et annuler les commandes.
function main(){
var id = exchange.Sell(100, 1)
Log("id:", id)
}
def main():
id = exchange.Sell(100, 1)
Log("id:", id)
void main() {
auto id = exchange.Sell(100, 1);
Log("id:", id);
}
Commande à terme
Lorsque vous passez des ordres pour des contrats à terme, vous devez faire attention à ce que la direction de négociation soit correctement définie. Si la direction de négociation et la fonction de négociation ne correspondent pas, une erreur sera signalée. Le montant de la commande des plateformes de contrats à terme de crypto-monnaie est le nombre de contrats, sauf indication contraire.
Les ordres de marché
Remarque: l'interface de placement d'ordres de la plateforme est nécessaire pour prendre en charge les ordres de marché. (Lorsque le type d'ordre est un ordre de vente, le paramètre de montant de l'ordre est le nombre de pièces d'exploitation vendues), et les contrats à terme de crypto-monnaie sont placés par formulaire d'ordre de marché, et l'unité de paramètre de montant de l'ordre est lenombre de contrats. Quelques échanges de devises numériques dans le commerce réel ne prennent pas en charge les interfaces d'ordre de marché.
// For example, trading pairs: ETH_BTC, sold out by market order
function main() {
// Note: Sell by a market order, and sell 0.2 ETH coins
exchange.Sell(-1, 0.2)
}
def main():
exchange.Sell(-1, 0.2)
void main() {
exchange.Sell(-1, 0.2);
}
exchange.CancelOrder(orderId)
, cette fonction a pour but d'annuler une commande avec Id. Valeur du paramètre:Id
est le numéro de commande, en type chaîne ou en type numérique (le type spécifique dépend du type de retour lors de la passation d'un ordre sur chaque plateforme); valeur de retour: type bool.
Retourner le résultat de l'opération;true
signifie que la demande d'annulation de commande a été envoyée avec succès;false
signifie que la demande d'ordre d'annulation n'est pas envoyée (la valeur de retour indique seulement si la demande d'envoi est réussie ou non, il est donc préférable d'appelerexchange.GetOrders()
pour vérifier si la plateforme annule l'ordre).
function main(){
var id = exchange.Sell(99999, 1)
exchange.CancelOrder(id)
}
def main():
id = exchange.Sell(99999, 1)
exchange.CancelOrder(id)
void main() {
auto id = exchange.Sell(99999, 1);
exchange.CancelOrder(id);
}
La fonction API de FMZ, qui peut générer des fonctions de sortie de log, telles queLog(...)
, exchange.Buy(Price, Amount)
etexchange.CancelOrder(Id)
. Vous pouvez suivre les paramètres nécessaires avec quelques paramètres de sortie supplémentaires, tels queexchange.CancelOrder(orders[j].Id, orders[j])
De cette façon, il annuleorders[j]
commande qui est accompagnée de la sortie de cette commande informations, à savoir leOrder
structure deorders[j]
.
function main() {
Log("data1", "data2", "data3", "...")
var data2 = 200
var id = exchange.Sell(100000, 0.1, "Incidental data1", data2, "...")
exchange.CancelOrder(id, "Incidental data1", data2, "...")
LogProfit(100, "Incidental data1", data2, "...")
}
def main():
Log("data1", "data2", "data3", "...")
data2 = 200
id = exchange.Sell(100000, 0.1, "Incidental data1", data2, "...")
exchange.CancelOrder(id, "Incidental data1", data2, "...")
LogProfit(100, "Incidental data1", data2, "...")
void main() {
Log("data1", "data2", "data3", "...");
int data2 = 200;
auto id = exchange.Sell(100000, 0.1, "Incidental data1", data2, "...");
exchange.CancelOrder(id, "Incidental data1", data2, "...");
LogProfit(100, "Incidental data1", data2, "...");
}
exchange.GetOrder(orderId)
obtient les détails de la commande selon le numéro de commande.Id
est le numéro d'ordre à obtenir, etId
est de type chaîne ou numérique (le type spécifique dépend du type de retour de chaque échange).Order
la structure.
(Non pris en charge par certaines bourses)
Order
la structureAvgPrice
indique le prix moyen exécuté (certaines bourses ne prennent pas en charge ce champ; le régler sur 0 si elles ne le prennent pas en charge).function main(){
var id = exchange.Sell(1000, 1)
// The parameter id is the order number, you need to fill in the number of the order you want to query
var order = exchange.GetOrder(id)
Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:",
order.DealAmount, "Status:", order.Status, "Type:", order.Type)
}
def main():
id = exchange.Sell(1000, 1)
order = exchange.GetOrder(id)
Log("Id:", order["Id"], "Price:", order["Price"], "Amount:", order["Amount"], "DealAmount:",
order["DealAmount"], "Status:", order["Status"], "Type:", order["Type"])
void main() {
auto id = exchange.Sell(1000, 1);
auto order = exchange.GetOrder(id);
Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:",
order.DealAmount, "Status:", order.Status, "Type:", order.Type);
}
exchange.GetOrders()
Returne la valeur:Order
la structure de l'ensemble.
PourOrder
structure, voirexchange.GetOrder()
Lorsque le compte représenté par l'objet d'échangeexchange
n'a pas d'ordre en attente, appelleexchange.GetOrders()
pour retourner un tableau vide, à savoir:[]
.
function main(){
exchange.Sell(1000, 1)
exchange.Sell(1000, 1)
var orders = exchange.GetOrders()
Log("Information for unfinished order 1, ID:", orders[0].Id, "Price:", orders[0].Price, "Amount:", orders[0].Amount,
"DealAmount:", orders[0].DealAmount, "type:", orders[0].Type)
Log("Information for unfinished order 2, ID:", orders[1].Id, "Price:", orders[1].Price, "Amount:", orders[1].Amount,
"DealAmount:", orders[1].DealAmount, "type:", orders[1].Type)
}
def main():
exchange.Sell(1000, 1)
exchange.Sell(1000, 1)
orders = exchange.GetOrders()
Log("Information for unfinished order 1, ID:", orders[0]["Id"], "Price:", orders[0]["Price"], "Amount:", orders[0]["Amount"],
"DealAmount:", orders[0]["DealAmount"], "type:", orders[0]["Type"])
Log("Information for unfinished order 2, ID:", orders[1]["Id"], "Price:", orders[1]["Price"], "Amount:", orders[1]["Amount"],
"DealAmount:", orders[1]["DealAmount"], "type:", orders[1]["Type"])
void main() {
exchange.Sell(1000, 1);
exchange.Sell(1000, 1);
auto orders = exchange.GetOrders();
Log("Information for unfinished order 1, ID:", orders[0].Id, "Price:", orders[0].Price, "Amount:", orders[0].Amount,
"DealAmount:", orders[0].DealAmount, "type:", orders[0].Type);
Log("Information for unfinished order 2, ID:", orders[1].Id, "Price:", orders[1].Price, "Amount:", orders[1].Amount,
"DealAmount:", orders[1].DealAmount, "type:", orders[1].Type);
}
Leexchange.GetOrders()
fonction obtient les informations de commande inachevées du jeu actuelpaire de négociationIl convient de noter que les contrats à terme de crypto-monnaie ont des différences non seulement entre les paires de négociation, mais aussi entre les codes de contrat.
// Test OKX contract tradings, to know whether "GetOrders" gets all unfinished contract orders
function main(){
// The next weekly buy order; the price of the order minus 50 guarantees no execution; pending orders
exchange.SetContractType("this_week")
exchange.SetDirection("buy")
var ticker = exchange.GetTicker()
Log(ticker)
exchange.Buy(ticker.Last - 50, 1)
// The next quarterly sell order; the price plus 50 guarantees that it will not be executed, and the pending order has been switched to a quarterly contract
exchange.SetContractType("quarter")
exchange.SetDirection("sell")
ticker = exchange.GetTicker()
Log(ticker)
exchange.Sell(ticker.Last + 50, 1)
// Get the unfinished orders
Log("orders", exchange.GetOrders())
}
def main():
exchange.SetContractType("this_week")
exchange.SetDirection("buy")
ticker = exchange.GetTicker()
Log(ticker)
exchange.Buy(ticker["Last"] - 50, 1)
exchange.SetContractType("quarter")
exchange.SetDirection("sell")
ticker = exchange.GetTicker()
Log(ticker)
exchange.Sell(ticker["Last"] + 50, 1)
Log("orders", exchange.GetOrders())
void main() {
exchange.SetContractType("this_week");
exchange.SetDirection("buy");
auto ticker = exchange.GetTicker();
Log(ticker);
exchange.Buy(ticker.Last - 50, 1);
exchange.SetContractType("quarter");
exchange.SetDirection("sell");
ticker = exchange.GetTicker();
Log(ticker);
exchange.Sell(ticker.Last + 50, 1);
Log("orders", exchange.GetOrders());
}
Les informations obtenues sur les commandes inachevées:
[{"Id":17116430886,"Amount":1,"Price":808.4,"DealAmount":0,"AvgPrice":0,"Status":0,"Type":1,"ContractType":"quarter"}]
On peut voir que dans le commerce de crypto-monnaie, les ordres obtenus parexchange.GetOrders()
ne sont que les commandes inachevées du contrat actuellement établi.
exchange.SetPrecision(PricePrecision, AmountPrecision)
définit la précision décimale du prix et le montant de l'ordre du symbole; il sera tronqué automatiquement après la configuration.PricePrecision
est de type numérique, utilisé pour contrôler le nombre de décimales dans les données sur les prix;AmountPrecision
est de type numérique, utilisé pour contrôler la virgule décimale après le montant de l'ordre.PricePrecision
etAmountPrecision
Le backtest ne prend pas en charge la fonction, et la précision numérique du backtest sera traitée automatiquement.
function main(){
// Set the decimal precision of the price to 2 digits, and set the precision of the quantity of the symbol order to 3 digits
exchange.SetPrecision(2, 3)
}
def main():
exchange.SetPrecision(2, 3)
void main() {
exchange.SetPrecision(2, 3);
}
exchange.SetRate(Rate)
fixe le taux de change de la monnaie en circulation à la bourse.Rate
est denumber
Retour de la valeur:number
type.
function main(){
Log(exchange.GetTicker())
// Set the exchange rate conversion
exchange.SetRate(7)
Log(exchange.GetTicker())
// Set to 1, without conversion
exchange.SetRate(1)
}
def main():
Log(exchange.GetTicker())
exchange.SetRate(7)
Log(exchange.GetTicker())
exchange.SetRate(1)
void main() {
Log(exchange.GetTicker());
exchange.SetRate(7);
Log(exchange.GetTicker());
exchange.SetRate(1);
}
Note: le numéro de série
Si vous avez défini une valeur de change en utilisantexchange.SetRate(Rate)
, par exemple 7, alors, toutes les informations sur les prix, y compris le prix de marché, la profondeur et le prix des commandes actuels, de la monnaie en circulation représentée par le prix actuel.exchange
Le taux de change fixé pour la conversion est de 7.
Par exemple,exchange
est un taux de change libellé en dollars américains.exchange.SetRate(7)
Si le taux de change est appelé, tous les prix du commerce réel seront multipliés par 7 et convertis en prix proches du yuan.
exchange.IO("api", httpMethod, resource, params, raw)
, appeler d'autres interfaces fonctionnelles de l'échange. Valeur du paramètre:httpMehod
est de type chaîne; il remplit le type de demande, tel quePOST
ouGET
. resource
est de type chaîne, il remplit le chemin de requête.params
est de type chaîne, il remplit les paramètres de demande.raw
est le paramètre de chaîne JSON original et peut être omis.exchange.IO("api", httpMethod, resource, params, raw)
l'appel de la fonction accède à l'interface d'échange.GetTicker()
etGetAccount()
, etc., renvoie des valeurs nulles lorsque les appels échouent).exchange.IO("api", ...)
function.
Pour l'exemple de l'ordre des lots OKX, utilisez le paramètreraw
pour passer les paramètres d'ordre:
function main() {
var arrOrders = [
{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"},
{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"}
]
// Call exchange.IO to directly access the platform batch ordering interface
var ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", JSON.stringify(arrOrders))
Log(ret)
}
import json
def main():
arrOrders = [
{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"},
{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"}
]
ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", json.dumps(arrOrders))
Log(ret)
void main() {
json arrOrders = R"([
{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"},
{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"}
])"_json;
auto ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", arrOrders.dump());
Log(ret);
}
Pour utiliser cette fonction, vous devez aller à l'échange pour comprendre leAPI
l'interface de l'échange pour étendre les fonctions que FMZ n'a pas ajouté (vous n'avez pas à vous soucier du processus de chiffrement des paramètres, la signature et la vérification lorsque vous soumettez unPOST
FMZ a traité complètement à la couche inférieure, vous n'avez donc qu'à remplir les paramètres correspondants).
Note: le numéro de série
Si la valeur clé dans leparams
paramètre (c'est-à-dire le paramètre de demande HTTP) est une chaîne, il doit être enveloppé avec des guillemets (symbole'
) des deux côtés de la valeur du paramètre.
Par exemple:bitfinex
exchange.
var amount = 1
var price = 10
var basecurrency = "ltc"
function main () {
// Notice that amount.toString() and price.toString() both have a ' character on the left and right
var message = "symbol=" + basecurrency + "&amount='" + amount.toString() + "'&price='" + price.toString() + "'&side=buy" + "&type=limit"
var id = exchange.IO("api", "POST", "/v1/order/new", message)
}
amount = 1
price = 10
basecurrency = "ltc"
def main():
message = "symbol=" + basecurrency + "&amount='" + str(amount) + "'&price='" + str(price) + "'&side=buy" + "&type=limit"
id = exchange.IO("api", "POST", "/v1/order/new", message)
void main() {
auto amount = 1.0;
auto price = 10.0;
auto basecurrency = "ltc";
string message = format("symbol=%s&amount=\"%.1f\"&price=\"%.1f\"&side=buy&type=limit", basecurrency, amount, price);
auto id = exchange.IO("api", "POST", "/v1/order/new", message);
}
Exemple d'accèsOKX
l'interface
function main(){
var ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT")
Log(ret)
}
def main():
ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT")
Log(ret)
void main() {
auto ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT");
Log(ret);
}
Données renvoyées lors des essais:
{"code":"0","data":[],"msg":""}
Autres réglages duexchange.IO
fonction:
Changez les paires de négociation de la bourse en cours
exchange.IO("currency", "ETH_BTC")
function main() {
// For example, set the current trading pair of the exchange object on the bot to BTC_USDT, and print the current trading pair market
Log(exchange.GetTicker())
// Switch trading pair to LTC_BTC
exchange.IO("currency", "LTC_BTC")
Log(exchange.GetTicker())
}
def main():
Log(exchange.GetTicker())
exchange.IO("currency", "LTC_BTC")
Log(exchange.GetTicker())
void main() {
Log(exchange.GetTicker());
exchange.IO("currency", "LTC_BTC");
Log(exchange.GetTicker());
}
Il s'agit d'unpaires de négociationconfiguréquand le bot est ajoutéoule backtest est exécutéseront passés par les codes.
Note: le numéro de série
ETH_BTC
, qui ne peut être basculé qu' àLTC_BTC
, pasLTC_USDT
.websocket
le mode protocole est allumé sur les objets d'échange Huobi spot, vous ne pouvez pas utiliserexchange.IO("currency", "XXX_YYY")
pour échanger des devises.exchange.SetCurrency(Symbol)
fonction de basculer des paires de négociation, et utiliserexchange.IO("currency","XXX_YYY")
méthode pour maintenir la compatibilité.exchange.IO
fonction de commutation de l'adresse de base de l'API de l'échange (contrat RESET; certains échanges ne le prennent pas en charge).
L'utilisation deexchange.SetBase(Base)
fonction a été prise en charge pour changer l'adresse de base de l'API d'échange, et utiliserexchange.IO("base","https://xxx.xxx.xxx")
méthode pour maintenir la compatibilité.
Par exemple: lorsque l'objet d'échange est encapsulé, l'adresse de base par défaut esthttps://api.huobipro.com
, pour passer à:https://api.huobi.pro
, utilisez le code suivant.
function main () {
// exchanges[0] is the first exchange object added when the bot is added
exchanges[0].IO("base", "https://api.huobi.pro")
}
def main():
exchanges[0].IO("base", "https://api.huobi.pro")
void main() {
exchanges[0].IO("base", "https://api.huobi.pro");
}
Changez l'adresse de base à:https://api.huobipro.com
.
function main () {
exchanges[0].IO("base", "https://api.huobipro.com")
}
def main():
exchanges[0].IO("base", "https://api.huobipro.com")