[TOC] Dieses Tutorial enthält die Grundkenntnisse zum Schreiben von Strategien, einschließlich API-Einführung, Rückmeldung, Diagramm usw. Nach Abschluss dieses Grundkurses wird der Benutzer in der Lage sein, die grundlegenden APIs zu benutzen und stabile Festplattenstrategien zu schreiben.Einführung in die FMZ-Erfinder-Quantifizierungsplattform 。
Das ist eine alte Version des Tutorials:Inventor Quantify (FMZ.COM) Strategien zur Erstellung eines vollständig verwendbaren Handbuchs 2.0 (Tutorial)In diesem Tutorial finden Sie eine Vielzahl von Inhalten, die Sie sich auch ansehen sollten.
Programmierte Transaktionen sind solche, bei denen Programme über eine API mit einer Börse verbunden sind, um automatische Kauf- und Verkaufsprozesse oder andere Funktionen zu realisieren. Die API ist eine Application Programming Interface.
Derzeit gibt es zwei Hauptinterface-Protokolle für Digitalwährungsbörsen: REST und Websocket. Die REST-Protokolle benötigt einen Zugriff für jeden Dateneintrag. Zum Beispiel die API der Simulationsbörse wex.app, die https://api.wex.app/api/v1/public/ticker?market=BTC_USDT direkt im Browser öffnet, erhält folgende Ergebnisse:
{"data:{"buy":"11351.73","high":"11595.77","last":"11351.85","low":"11118.45","open":"11358.74","quoteVol":"95995607137.00903936","sell":"11356.02","time":1565593489318,"vol":"3552.5153"}}
Dies zeigt den aktuellen Stand der Transaktionen mit dem BTC_USDT-Trading-Paar, der sich bei jeder Aktualisierung ändert.market=Anschließend folgen die spezifischen Parameter für die Paare, die geändert werden können, um Daten für andere Paare zu erhalten. Für öffentliche Schnittstellen, wie z. B. die Marktbewegung, ist jeder zugänglich, so dass keine Verifizierung erforderlich ist, während einige Schnittstellen wie Bestell- und Acquire-Konten die Benutzeridentität feststellen müssen, wobei der API-KEY verwendet werden muss. Websocket ist ein Subskriptionsmodus, nach dem die erforderlichen Inhalte gesendet werden, senden die Börsen die aktualisierten Daten an das Programm und müssen nicht jedes Mal erneut aufgerufen werden.
Die FMZ-Quantitative Trading-Plattform enthält die REST-Schnittstelle für die einzelnen Börsen und verwendet einheitliche Aufrufe und Datenformate, um die Programmierung von Strategien zu vereinfachen und zu verbreiten. Die FMZ-Plattform unterstützt Websocket, das im nächsten Tutorial detailliert beschrieben wird.
Die API-Dokumentation der FMZ-Plattform basiert zum größten Teil auf JavaScript, jedoch gibt es kaum Unterschiede zwischen den verschiedenen Sprachen aufgrund der Verpackung. Es ist nur auf Grammatik zu achten. C++ ist etwas spezifisch und wird in späteren Tutorials speziell vorgestellt.
Da es verschiedene Versionen von Python gibt, können sie zu Beginn des Programms angegeben werden, z. B.#!Python2,#!Python3Es ist wichtig zu beachten, dass JavaScript kürzlich auf die ES6-Grammatik aufgerüstet wurde. Im Folgenden werden Python- und Javascript-Codes gezeigt, die dieselben Funktionen bieten, nur die Grammatik unterscheidet sich, so dass die API-Dokumentation nur Beispiele für Javascript enthält. Dieses Tutorial berücksichtigt auch spezielle Anwendungsfälle für Python.
#python代码
def main():
while True:
Log(exchange.GetAccount().Balance)
Sleep(2000)
#相应的Js代码
function main(){
while(true){
Log(exchange.GetAccount().Balance)
Sleep(2000)
}
}
Die Debug-Tool für die Debug-API-Schnittstelle wird von der FMZ-Quantitative Plattform bereitgestellt. Die Debug-Tool unterstützt nur JavaScript und kann nur für eine gewisse Zeit ausgeführt werden. Die Debug-Tool kann ohne die Erstellung einer Festplatte ausgeführt werden.

Das besondere an der Strategie ist, dass, wie bei normalen Programmen, sie in der Codefolge ausgeführt werden muss. Da die Strategie ununterbrochen ausgeführt werden muss, ist in der Regel ein Loop plus eine Ruhezeit erforderlich. Da die Häufigkeit der Zugriffe auf alle Handels-APIs begrenzt ist, ist eine entsprechende Schlafzeit erforderlich. Diese Architektur ist typisch für die Festintervall-Ausführung.
Weitere spezielle Funktionen sind:
function onTick(){
var ticker = exchange.GetTicker()
var account = exchange.GetAccount()
//在这里写策略逻辑,将会每6s调用一次
}
function main(){
while(true){
onTick()
Sleep(6000)
}
}
Wenn ein Fehler beim Zugriff auf das Netzwerk dazu führen kann, dass die Strategie direkt gestoppt wird, kann die Festplattenstrategie mit dem try catch-fehlerbewussten Hauptzyklus (nicht mit dem try-retrieve) wiederhergestellt werden, wenn eine ähnliche Strategie wie der automatische Neustart nicht gestoppt wird. Natürlich wird diese Handlung nur empfohlen, wenn die Strategie stabil ist, da sonst alle Fehler nicht gemeldet werden und es schwierig ist, die Probleme der Strategie zu überprüfen.
function onTick(){
var ticker = exchange.GetTicker()
var account = exchange.GetAccount()
//在这里写策略逻辑,将会每6s调用一次
}
function main(){
try{
while(true){
onTick()
Sleep(6000)
}
}catch(err){
Log(err)
}
}
Bei Anrufen einer beliebigen Exchange-bezogenen API müssen die Exchanges und die Paare festgelegt werden.exchangeDas ist ein Beispiel dafür, wieexchange.GetTicker()Das Ergebnis ist der Ticker für den Handel mit diesem Handelspartner.
Die FMZ-Plattform unterstützt das gleichzeitige Hinzufügen von mehreren Exchange-Trading-Pairs, z. B. BTC und ETH, die gleichzeitig auf demselben Exchange-Konto gehandhabt werden können. Es ist zu beachten, dass verschiedene Accounts auf demselben Exchange gleichzeitig hinzugefügt werden können, die sich an den Label-Distinguishments auf der FMZ-Website orientieren.exchangesDie Arrays werden in der Reihenfolge der Erstellung der Festplatte alsexchanges[0]、exchanges[1]…und so weiter. Das Format der Paare ist:BTC_USDTBTC ist die Handelswährung und USDT die Kurswährung.

Offensichtlich ist diese Methode problematisch, wenn wir mit vielen Paaren handeln, und wir können SetCurrency verwenden, um Paare zu wechseln, wieexchange.SetCurrency("BTC_USDT")Zu diesem ZeitpunktexchangeDie gebundenen Paare werden zuBTC_USDTDie Anrufe werden bis zum nächsten Aufruf der Wechselpaare gültig sein.Die neueste Unterstützung für Wechselpaare ist die Rückmessung.Hier ist ein konkretes Beispiel:
var symbols = ["BTC_USDT", "LTC_USDT", "EOS_USDT", "ETH_USDT"]
var buyValue = 1000
function main(){
for(var i=0;i<symbols.length;i++){
exchange.SetCurrency(symbols[i])
var ticker = exchange.GetTicker()
var amount = _N(buyValue/ticker.Sell, 3)
exchange.Buy(ticker.Sell, amount)
Sleep(1000)
}
}
Wie bereits erwähnt, sind die Handelsschnittstellen im Allgemeinen öffentliche Schnittstellen, die für alle zugänglich sind. Die üblichen Handelsschnittstellen sind: Erhalten von Handelsticker, Erhalten von Tiefentiefe, Erhalten von K-Linie-Aufzeichnungen, Erhalten von Transaktions-Aufzeichnungen.
Die Schnittstellen sind in der RegelInfoFeld, das die ursprüngliche Datenstring, die von der Börse zurückgegeben wird, anzeigt, kann verwendet werden, um zusätzliche Informationen zu ergänzen, die zuvor analysiert werden mussten, JavaScript verwendetJSON.parse()Die json-bibliothek wird in python verwendet.TimeDas Feld zeigt die Zeitspanne der Anfrage an, die zur Beurteilung der Verzögerung verwendet werden kann.
Es ist möglich, dass der Zugriff auf die API-Schnittstelle auf der Festplatte fehlschlägt und zurückkehrt.nullPython ist zurück.NoneEs ist sehr wichtig, dass die Daten fehlerfrei sind, da diese Daten fehlerhaft sind und die Festplatte zum Stillstand bringen.
Die aktuelle Marktlage ist wahrscheinlich die am häufigsten verwendete Schnittstelle, die Informationen über den letzten Handelspreis, den Kauf- und Verkaufspreis, den jüngsten Handelsvolumen usw. enthält. Der Handelspreis kann anhand von Ticker-Informationen vor dem Auftrag festgelegt werden.{"Info:{}, "High":5226.69, "Low":5086.37,"Sell":5210.63, "Buy":5208.5, "Last":5208.51, "Volume":1703.1245, "OpenInterest":0, "Time":1554884195976}。
function main() {
var ticker = exchange.GetTicker()
Log(ticker) //在调试工具中 return ticker 。可以看到具体的结果。
Log('上次成交价: ',ticker.Last, '买一价: ', ticker.Buy)
}
Obwohl GetTicker eine Kauf- und Verkaufsplattform enthält, können Sie diese Schnittstelle verwenden, um die nächsten 200 Anleihen zu finden. Sie können diese Schnittstelle verwenden, um den Stoßpreis zu berechnen.
{
"Info":null,
"Asks":[
{"Price":5866.38,"Amount":0.068644},
{"Price":5866.39,"Amount":0.263985},
......
]
"Bids":[
{"Price":5865.13,"Amount":0.001898},
{"Price":5865,"Amount":0.085575},
......
],
"Time":1530241857399
}
Beispiele für die Verwendung von Deep Access für Kauf- und Verkaufsscheine:
function main() {
var depth = exchange.GetDepth()
Log('买一价个: ', depth.Bids[0].Price, '卖一价格: ', depth.Asks[0].Price)
}
K-Linien, eine der am häufigsten verwendeten Schnittstellen, die langfristige Preisinformationen zur Berechnung der Basis für verschiedene Indikatoren auf einmal zurückgeben. K-Linien-Zyklen können nicht angegeben werden, wenn nicht die Standard-Zyklen angegeben sind, die zum Hinzufügen von Festplatten verwendet werden. Die K-Linien-Länge kann nicht angegeben werden, sie erhöht sich mit der Zeit, bis zu 2000 Wurzeln, wobei die ersten Anrufe von etwa 200 Wurzeln (andere Börsen) zurückgegeben werden.
exchange.SetMaxBarLen(Len)Die Anzahl der K-Linien, die zum ersten Mal erworben werden können (unterstützt von einigen Börsen) und die maximale Anzahl der K-Linien werden festgelegt.Zum Beispiel:exchange.SetMaxBarLen(500)
GetRecords kann Perioden angeben: PERIOD_M1:1 Minuten, PERIOD_M5:5 Minuten, PERIOD_M15:15 Minuten, PERIOD_M30:30 Minuten, PERIOD_H1:1 Stunden, PERIOD_D1:1 Tage.exchange.GetRecords(PERIOD_M1)。 Nach dem Upgrade auf den neuesten Host wird die Unterstützung von Custom Cycles unterstützt, die Sekundenzahl der Zyklen wird als Parameter verwendet, die Minuteneinstellung wird auf der Grundlage von 1-minütigen K-Linien synthetisiert, die K-Linien unter 1 Minute werden über GetTrades () synthetisiert, und die Wareneinheiten werden auf der Grundlage von tick synthetisiert.。Das ist eine sehr schwierige Aufgabe.PERIOD_M1Diese globalen Variablen sind die Standard-Variablen der FMZ, die von Interessenten selbst registriert werden können.
Rückgabe von Daten:
[
{"Time":1526616000000,"Open":7995,"High":8067.65,"Low":7986.6,"Close":8027.22,"Volume":9444676.27669432},
{"Time":1526619600000,"Open":8019.03,"High":8049.99,"Low":7982.78,"Close":8027,"Volume":5354251.80804935},
{"Time":1526623200000,"Open":8027.01,"High":8036.41,"Low":7955.24,"Close":7955.39,"Volume":6659842.42025361},
......
]
Ein Beispiel für eine iterative K-Linie:
function main(){
var close = []
var records = exchange.GetRecords(PERIOD_H1)
Log('total bars: ', records.length)
for(var i=0;i<records.length;i++){
close.push(records[i].Close)
}
return close
}
Die Anwendbarkeit der Daten erfolgt über einen bestimmten Zeitrahmen (nicht über eigene Transaktionen).
Da diese Schnittstellen mit den Accounts verbunden sind und nicht direkt zugänglich sind, müssen sie mit API-KEY-Signaturen versehen werden. Die FMZ-Plattform hat die automatische Verarbeitung im Hintergrund vereinheitlicht und kann direkt verwendet werden.
Erhalten Sie die Kontoinformationen. Eine der am häufigsten verwendeten Schnittstellen, die vor der Bestellung aufgerufen werden muss, um zu vermeiden, dass der Kontostand nicht ausreicht.{"Stocks":0.38594816,"FrozenStocks":0,"Balance":542.858308,"FrozenBalance":0,"Info":{}}❚ wobei Stocks die verfügbare Währung des Handelspares sind, FrozenStocks die eingefrorene Währung des Auftrags, der noch nicht ausgeführt wurde, Balance die verfügbare Währung des Kurses und FrozenBalance die eingefrorene Währung.BTC_USDTWenn Sie Bitcoin (BTC) als Wertpapier bezeichnen, dann ist das Wertpapier BTC, wenn Sie Bitcoin (BTC) als Wertpapier bezeichnen, dann ist es USDT.
Es wird darauf hingewiesen, dass die zurückgegebenen Ergebnisse die Ergebnisse der angegebenen Paare sind. Die Informationen zu anderen Währungen in den Handelskonten werden in den Info-Feldern angezeigt.
Eine Festplatte, auf der der Gesamtwert der aktuellen Paare gedruckt wird:
function main(){
while(true){
var ticker = exchange.GetTicker()
var account = exchange.GetAccount()
var price = ticker.Buy
var stocks = account.Stocks + account.FrozenStocks
var balance = account.Balance + account.FrozenBalance
var value = stocks*price + balance
Log('Account value is: ', value)
LogProfit(value)
Sleep(3000)//sleep 3000ms(3s), A loop must has a sleep, or the rate-limit of the exchange will be exceed
//when run in debug tool, add a break here
}
}
Hier sind die Gebühren.exchange.Buy(Price, Amount)oderexchange.Buy(Price, Amount, Msg)Der Name “Price” steht für “Preis”, “Amount” für “Menge”, “Msg” ist eine zusätzliche Zeichenfolge, die in der Festplattenlogik angezeigt werden kann, aber nicht notwendig ist.null, um den Zustand der Bestellung zu überprüfen.
Wenn man einen Preis nach dem Marktpreis kaufen will, dann ist der Preis -1, der Betrag der Auftragswert, wieexchange.Buy(-1, 0.5)Der Handel ist korrekt.ETH_BTCDie Börsen unterstützen keine Marktpreisliste und keine Futures-Retracing.
Alle Preise und Mengen für Teiltransaktionen sind verfügbar_N()Die Präzisionsfunktion ist die Steuerung. Für den Futures-Handel Buy und Sell gibt es weitere Bedeutungen, die separat dargestellt werden.
Ein Beispiel für einen Kauf, der den entsprechenden Preis erreicht:
function main(){
while(true){
var ticker = exchange.GetTicker()
var price = ticker.Sell
if(price >= 7000){
exchange.Buy(_N(price+5,2), 1, 'BTC-USDT')
break
}
Sleep(3000)//Sleep 3000ms
}
Log('done')
}
Die Parameter der Preisliste sind unterschiedlich, und die Preisliste ist wie folgt:exchange.Sell(-1, 0.2), die den Marktpreis von 0,2 ETH darstellt.
Auf der Grundlage der Bestell-id erhalten Sie die Bestellinformationen.exchange.GetOrder(OrderId),OrderId ist die Bestell-ID, die bei der Bestellung zurückgegeben wird.Beachtung der AuftragsartTypeFelder und BestellstatusStatusDie tatsächlichen Werte sind Zahlen, die verschiedene Bedeutungen repräsentieren, aber nicht für das Gedächtnis geeignet sind. Die FMZ repräsentiert diese Werte mit globalen Konstanten, wie z. B. bei unerledigten Aufträgen.StatusDas ist der Wert von 0.ORDER_STATE_PENDINGAlle diese globalen Konstanten sind in der Dokumentation zu finden.◦ Rückgabe von Ergebnissen:
{
"Id":125723661, //订单id
"Amount":0.01, //订单数量
"Price":7000, //订单价格
"DealAmount":0, //已成交数量
"AvgPrice":0, //成交均价
"Status":0, // 0:未完全成交, 1:已成交, 2:已撤单
"Type":1,// 订单类型,0:买单, 1:卖单
"ContractType":"",//合约类型,用于期货交易
"Info":{} //交易所返回原始信息
}
}
Eine Strategie zum Kauf einer bestimmten Anzahl von Coins:
function main(){
while(true){
var amount = exchange.GetAccount().Stocks
var ticker = exchange.GetTicker()
var id = null
if(5-amount>0.01){
id = exchange.Buy(ticker.Sell, Math.min(5-amount,0.2))
}else{
Log('Job completed')
return //return the main function, bot will stop
}
Sleep(3000) //Sleep 3000ms
if(id){
var status = exchange.GetOrder(id).Status
if(status == 0){ //这里也可以用 status == ORDER_STATE_PENDING 来判断。
exchange.CancelOrder(id)
}
}
}
}
Erhalten Sie eine Liste aller unerledigten Bestellungen für den aktuellen Handel. Wenn keine unerledigten Bestellungen zurückgegeben werden, wird ein leeres Array zurückgegeben. Die Bestellliste enthält spezifische Ergebnisse wie GetOrder.
Beispiele für den Widerruf eines laufenden Geschäfts für alle Bestellungen:
function CancelAll(){
var orders = exchange.GetOrders()
for(var i=0;i<orders.length;i++){
exchange.CancelOrder(orders[i].Id) // cancel order by orderID
}
}
function main(){
CancelAll()
while(true){
//do something
Sleep(10000)
}
}
Rücktritt der Bestellung gemäß der Bestellung.exchange.CancelOrder(OrderId)。 Rücktritt erfolgreich zurückgibt true, andernfalls zurückgibt false。 Bitte beachten Sie, dass ein vollständig ausgelieferter Auftrag zurückgezogen wird.
Die oben beschriebene Funktion für den Bargeldhandel ist für den Handel mit Futures und Einfachfutures etwas anders. Bevor Sie mit der Programmierung von Futures handeln, müssen Sie sich mit den grundlegenden Konzepten wie Positionseröffnung, Niedrigstellung, Volllagerung, Niederlagerung, Leverage, Niedriglagerung, Verlust, Floating Profit, Garantiegeld und den entsprechenden Berechnungsformeln vertraut machen.
Der Terminkontrakt ist ähnlich wie der Futures-Kontrakt, nur dass es keine gleichzeitige Besitzung von mehreren Leerpositionen gibt.
Wenn die Börse gleichzeitig Futures-Cash wie OKEX und Huobi-Futures unterstützt, müssen Sie die OKEX-Futures- und die Huobi-Futures-Felder separat in der Börsen-Oberfläche auswählen, um sie als andere Börsen als Cash in der FMZ zu betrachten.
Der erste Schritt beim Futures-Handel besteht darin, den zu handelnden Kontrakt einzurichten, beispielsweise bei OKEX-Futures, um ein BTC-Handelspaar zu erstellen, das bei der Erstellung von Festplatten oder Retrospektiven ausgewählt wird. Außerdem muss der Code als Kontrakt für die aktuelle Woche, die nächste Woche oder den Quartal eingestellt werden.invalid contract type。Im Gegensatz zu Cash-Trading-Paaren werden Futures-Kontrakte oft mit Handelstransaktionswährungen wie BTC als Sicherung gedeckt. Die BTC_USD-Trading-Paare, die BTC als Sicherung hinzufügen, werden in der Regel als BTC_USD-Trading-Paare dargestellt. Wenn es Futures gibt, die USDT als Sicherung hinzufügen, muss eine virtuelle BTC_USDT-Trading-Paare erstellt werden.Nach der Einrichtung des Handelspares müssen auch bestimmte Vertragstypen wie dauerhaft, wöchentlich, wöchentlich und wöchentlich eingerichtet werden. Nach der Einrichtung des Vertrages können Handlungen wie Kauf und Verkauf vorgenommen werden.
Es gibt Kontrakte wie Coinbase, OKEX, HuobiDM und andere, bei denen es sich um Coinbase und USDT handelt. Es ist erforderlich, bei der Hinzufügung von Festplattenkontrakten zu unterscheiden. Die spezifischen Einstellungen sind wie folgt.
//OKEX期货
exchange.SetContractType("swap") // 设置为永续合约
exchange.SetContractType("this_week") // 设置为当周合约
exchange.SetContractType("next_week") // 设置为次周合约
exchange.SetContractType("quarter") // 设置为季度合约
//HuobiDM
exchange.SetContractType("this_week") // 设置为当周合约
exchange.SetContractType("next_week") // 设置为次周合约
exchange.SetContractType("quarter") // 设置为季度合约
exchange.SetContractType("swap") // 设置为永续合约
//币安期货
exchange.SetContractType("swap") // 设置为永续合约,注意币本位和USDT本位都存在永续
exchange.SetContractType("quarter") // 设置为当季合约
exchange.SetContractType("next_quarter") // 设置为次季合约
//BitMEX
exchange.SetContractType("XBTUSD") // 设置为永续合约
exchange.SetContractType("XBTM19") // 具体某个时间结算的合约,详情登录BitMEX查询各个合约代码
//GateIO
exchange.SetContractType("swap") // 设置为永续合约,不设置默认为swap永续合约。
//Deribit
exchange.SetContractType("BTC-27APR18") // 具体某个时间结算的合约,详情参看Deribit官网。
Eine Liste mit aktuellen Positionsinformationen, OKEX(OKCOIN) -Futures, die in ein Parameter eingegeben werden können, das den gewünschten Vertragstyp angibt. Wenn keine Positionen vorhanden sind, wird die leere Liste zurückgegeben[]Die Rückgabe von Haltungsdaten ist wie folgt: Es gibt viele konkrete Informationen, die in Verbindung mit der Analyse von Transaktionen benötigt werden.
| Datentyp | Variablen-Namen | veranschaulichen |
|---|
Die ursprüngliche Struktur, die von der Object HDID Info HDID Exchange zurückgegeben wurde Die Margin-Level-Schaufel-Größe, OKCoin ist 10 oder 20, OK-Futures-Volllagermodus gibt eine feste 10 zurück, da die native API dies nicht unterstützt “Amount” ist die Anzahl der Aktien, die OKCoin hält. “Amount” ist die Anzahl der Aktien, die OKCoin hält. “FrozenAmount” und “FrozenAmount” “Nummer und Preis und Lagerpreis” “Die Anzahl der Margin-Garantie ist eingefroren”. [number] [Profit] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] [number] Die Konst-Typologie enthält PD_LONG für die mehrfache Position (in CTP mit closebuy_today), PD_SHORT für die offene Position (in CTP mit closesell_today), PD_LONG_YD für die mehrfache Position (in CTP mit closebuy) und PD_SHORT_YD für die offene Position (in CTP mit closesell_today). String oder ContractType oder Futures als Vertragskodex oder Aktien als Börsenkodex.
function main(){
exchange.SetContractType("this_week");
var position = exchange.GetPosition();
if(position.length>0){ //特别要注意引用前要先判断position长度再引用,否则会出错
Log("Amount:", position[0].Amount, "FrozenAmount:", position[0].FrozenAmount, "Price:",
position[0].Price, "Profit:", position[0].Profit, "Type:", position[0].Type,"ContractType:", position[0].ContractType)
}
}
Es ist wichtig zu wissen, wie man die Lever-Größe und die Aufrufart einstellt:exchange.SetMarginLevel(10)Wenn Sie die Anzahl der Aktien, die Sie an der Börse anbieten möchten, mit 10 multiplizieren möchten, können Sie die Größe der unterstützten Leverage an der entsprechenden Börse anzeigen.Beachten Sie, dass der Leverage bei der Börse eingestellt werden muss, und der Code muss mit der Börse übereinstimmen, sonst wird ein Fehler gemacht│ oder auch nicht eingestellt, und benutzt die Standardhebel│
Es gibt eine Reihe von Möglichkeiten, wie Sie den Handel ausführen können:exchange.SetDirection(Direction)Das ist eine sehr schwierige Aufgabe.Im Gegensatz zu Futures, wenn ein Perpetual-Kontrakt nicht gleichzeitig mit dem Konzept der Leerstellung gehalten wird, d.h. keine Positionen für einzelne Positionen erlaubt sind, wird die Leerstellung von Leerpositionen automatisch gelöscht, und alle müssen nur eingestellt werdenbuyUndsellVerfügbar. Sollte eine Zwei-Wege-Position unterstützt werden, ist eine Einstellung erforderlich.closebuy,closebuy。Spezifische Beziehungen
| Bedienung | Parameter für SetDirection | Auftragsfunktion |
|---|---|---|
| Eröffnung von Positionen | exchange.SetDirection(“buy”) | exchange.Buy() |
| Pinto-Positionen | exchange.SetDirection(“closebuy”) | exchange.Sell() |
| Leerstand | exchange.SetDirection(“sell”) | exchange.Sell() |
| Leerlauf | exchange.SetDirection(“closesell”) | exchange.Buy() |
Schließlich gibt es einen spezifischen Code für die Eröffnung und Schließung von Positionen. Die Auftragsmenge variiert je nach Börse, z. B. Huobi-Futures sind nach Anzahl der Positionen, eine 100 US-Dollar.
function main(){
exchange.SetContractType("this_week") // 举例设置 为OKEX期货 当周合约
price = exchange.GetTicker().Last
exchange.SetMarginLevel(10) //设置杠杆为10倍
exchange.SetDirection("buy") //设置下单类型为做多
exchange.Buy(price+10, 20) // 合约数量为20下单
pos = exchange.GetPosition()
Log(pos)
Log(exchange.GetOrders()) //查看是否有未成交订单
exchange.SetDirection("closebuy"); //如果是永续合约,直接设置exchange.SetDirection("sell")
exchange.Sell(price-10, 20)
}
Im Folgenden finden Sie ein Beispiel für eine konkrete Strategie für eine vollständige Niederlage.
function main(){
while(true){
var pos = exchange.GetPosition()
var ticker = exchange.GetTicekr()
if(!ticker){
Log('无法获取ticker')
return
}
if(!pos || pos.length == 0 ){
Log('已无持仓')
return
}
for(var i=0;i<pos.length;i++){
if(pos[i].Type == PD_LONG){
exchange.SetContractType(pos[i].ContractType)
exchange.SetDirection('closebuy')
exchange.Sell(ticker.Buy, pos[i].Amount - pos[i].FrozenAmount)
}
if(pos[i].Type == PD_SHORT){
exchange.SetContractType(pos[i].ContractType)
exchange.SetDirection('closesell')
exchange.Buy(ticker.Sell, pos[i].Amount - pos[i].FrozenAmount)
}
}
var orders = exchange.Getorders()
Sleep(500)
for(var j=0;j<orders.length;j++){
if(orders[i].Status == ORDER_STATE_PENDING){
exchange.CancelOrder(orders[i].Id)
}
}
}
}
Die Einzahlung erfolgt auf der Grundlage der in der Code enthaltenen Anweisungen.
Um in den Margin-Konto-Modus zu wechseln, werden die Konto-Assets über die Leverage-Schnittstelle der Börse aufgerufen. Wechseln Sie mit exchange.IO (“trade_normal”) zurück in den Standard-Account-Modus.
Unterstützte Börsen:
Es gibt einen großen Unterschied zwischen Commodity Futures Trading und Digital Currency Futures Trading. Zunächst ist die Handelszeit für Commodity Futures sehr kurz, die Digital Currency 24h-Handel; die Vereinbarung für Commodity Futures ist auch keine übliche REST API; die Handelsfrequenz und die Begrenzung der Anzahl der Bestellungen für Commodity Futures sind sehr locker, die Digital Currencies sind sehr locker usw. Daher gibt es viele Bereiche, an denen der Handel mit Commodity Futures besondere Aufmerksamkeit erfordert.
FMZ Quantitative Plattform als programmierter Handel Anbieter an die einzelnen Futures-Server Software-Lizenz, die Benutzer können ohne Antrags direkt verwenden, in der Add-Futures-Forex-Suchschrauber ist die Liste der FMZ bereits beantragt zu sehen. Spezifische Referenz-Post: https://www.fmz.com/bbs-topic/3860 ❚ Wenn Ihr Terminlieferant nicht mehr in der Liste, kann nur selbst beantragen, oder wieder in unterstützten Handel Öffner, in der Regel 2 Tage.
Aufgrund der Vorteile der FMZ-Plattform-Architektur können Benutzer auch mehrere Futures-Händler-Konten hinzufügen und einige Funktionen, die andere Commodity-Futures-Programmierungshandelssoftware nicht kann, wie die Synthese von Hochfrequenzticks, Referenz: https://www.fmz.com/bbs-topic/1184
Zunächst einmal, da es sich nicht um einen 24-Stunden-Transaktionsprozess handelt und ein Login erforderlich ist, muss der Linkstatus beurteilt werden, bevor ein Transaktionsprozess durchgeführt wird.exchange.IO("status")fürtrueWenn die Anmeldung nicht erfolgreich ist, wird die API aufgerufen, und es wird nicht gefragt, ‘not login’. Sie können nach dem Beginn der Strategie schlafen ((2000), eine bestimmte Zeit für die Anmeldung geben. Sie können auch erneut mit dem Abonnement versuchen._C(exchange.SetContractType,"MA888")Die Landung wurde von einem Flugzeug aus dem Vereinigten Königreich durchgeführt.
Die Codes für den Erwerb und den Handel von Commodity-Futures sind identisch mit denen von Digital-Currency-Futures. Hier werden die Unterschiede und die Notwendigen Punkte beschrieben.
function main(){
_C(exchange.SetContractType,"MA888") //没登陆成功是无法订阅合约的,最好重试一下
while(true){
if(exchange.IO("status")){
var ticker = exchange.GetTicker()
Log("MA888 ticker:", ticker)
LogStatus(_D(), "已经连接CTP !")//_D获取事件
} else {
LogStatus(_D(), "未连接CTP !")
Sleep(1000)
}
}
}
Es wird empfohlen, Commodity Futures Trading zu verwenden (siehe unten), da der Code sehr einfach ist und keine aufwendigen Details zu verarbeiten.
function main() {
// 使用了商品期货类库的CTA策略框架
$.CTA(Symbols, function(st) {
var r = st.records
var mp = st.position.amount
var symbol = st.symbol
/*
r为K线, mp为当前品种持仓数量, 正数指多仓, 负数指空仓, 0则不持仓, symbol指品种名称
返回值如为n:
n = 0 : 指全部平仓(不管当前持多持空)
n > 0 : 如果当前持多仓,则加n个多仓, 如果当前为空仓则平n个空仓,如果n大于当前持仓, 则反手开多仓
n < 0 : 如果当前持空仓,则加n个空仓, 如果当前为多仓则平n个多仓,如果-n大于当前持仓, 则反手开空仓
无返回值表示什么也不做
*/
if (r.length < SlowPeriod) {
return
}
var cross = _Cross(TA.EMA(r, FastPeriod), TA.EMA(r, SlowPeriod));
if (mp <= 0 && cross > ConfirmPeriod) {
Log(symbol, "金叉周期", cross, "当前持仓", mp);
return Lots * (mp < 0 ? 2 : 1)
} else if (mp >= 0 && cross < -ConfirmPeriod) {
Log(symbol, "死叉周期", cross, "当前持仓", mp);
return -Lots * (mp > 0 ? 2 : 1)
}
});
}
Die Commodity Futures verwenden das CTP-Protokoll, bei dem alle Trades und Auftragsgeschäfte nur mit Änderungen benachrichtigt werden, während die Abfrage von Orders, Konten und Positionen eine aktive Abfrage ist. Daher ist die Hochfrequenz-Strategie für das schreiben von Ereignissen geeignet. Die Standardmodus-Schnittstelle für den Zugriff auf Trades wieGetTicker、GetDepth、GetRecordsDie Strategie kann also ohne Schlaf verwendet werden. Wenn sich die Situation ändert, werden Tickers, Tiefen und Aufzeichnungen aktualisiert. Der Aufruf einer beliebigen Schnittstelle wird sofort zurückgegeben. Der Aufruf der Schnittstelle wird in den Wartemodus gesetzt.
Wenn Sie immer wieder Daten abrufen wollen, auch wenn es sich um alte Daten handelt, können Sie in den Modus der sofortigen Aktualisierung umschalten.exchange.IO("mode", 0)❚ Die Strategie kann dann nicht als ereignisgesteuert geschrieben werden, sondern muss mit einem SLeep-Ereignis versehen werden, um eine schnelle Todesspirale zu vermeiden. ❚ Einige nicht hochfrequente Strategien können dieses Modell verwenden, die Strategie ist einfach zu entwerfen.exchange.IO("mode", 1)Die Cache-Modus-Default kann zurückgeschaltet werden.
Bei der Bedienung einzelner Verträge kann der Standardmodus verwendet werden. Bei mehreren Verträgen besteht jedoch die Möglichkeit, dass ein Vertrag nicht aktualisiert wird, was dazu führt, dass die Benutzeroberfläche blockiert wird und die Benutzeroberfläche anderer Verträge nicht aktualisiert wird. Um dieses Problem zu lösen, kann der Sofort-Aktualisierungsmodus verwendet werden, ohne jedoch eine Hochfrequenzstrategie zu schreiben.exchange.IO("wait")Wenn mehrere Exchange-Objekte hinzugefügt werden, was bei Commodity-Futures selten ist, könnenexchange.IO("wait_any")Der Index, der dann zurückgegeben wird, zeigt den zurückgegebenen Börsenindex an.
Die Aktion tick ändert sich weiter{Event:"tick", Index:交易所索引(按实盘上交易所添加顺序), Nano:事件纳秒级时间, Symbol:合约名称}
Bestellungen weitergeleitet:{Event:"order", Index:交易所索引, Nano:事件纳秒级时间, Order:订单信息(与GetOrder获取一致)}
An diesem Punkt kann die Strategiestruktur wie folgt geschrieben werden:
function on_tick(symbol){
Log("symbol update")
exchange.SetContractType(symbol)
Log(exchange.GetTicker())
}
function on_order(order){
Log("order update", order)
}
function main(){
while(true){
if(exchange.IO("status")){ //判断链接状态
exchange.IO("mode", 0)
_C(exchange.SetContractType, "MA888")//订阅MA,只有第一次是真正的发出订阅请求,接下来都是程序切换,不耗时间。
_C(exchange.SetContractType, "rb888")//订阅rb
while(true){
var e = exchange.IO("wait")
if(e){
if(e.event == "tick"){
on_tick(e.Symbol)
}else if(e.event == "order"){
on_order(e.Order)
}
}
}
}else{
Sleep(10*1000)
}
}
}
Es ist auch zu beachten, dass die Commodity-Futures von den digitalen Währungsbörsen unterschiedlich sind. Wie GetDepth gibt es tatsächlich nur eine Tiefe ((5 Tiefen sind teuer), und GetTrades erhält keine Transaktionsgeschichte ((sie basieren auf simulierten Positionsänderungen, keine echten Transaktionsunterlagen)).
exchange.IO ((“instruments”): Gibt die Liste aller Verträge der Börse in Wörterbuchform zurück, nur für die Festplatte. exchange.IO ((“products”): Gibt die Liste aller Produkte der Börse im Wörterbuchformat zurück. Nur Festplatten werden unterstützt. exchange.IO ((“subscribed”): Rückgabe eines abonnierten Vertrags im gleichen Format, nur für die Festplatte.
Traditionelle CTP-FuturesContractTypeDas bedeutet, dass die Kontrakt-ID, groß- und kleingeschrieben unterschieden werden soll.exchange.SetContractType("au1506")❚ Die erfolgreiche Einstellung des Vertrags enthält Details über den zurückgegebenen Vertrag, wie zum Beispiel die Mindestkaufmenge, die Handhabungskosten, die Lieferzeit usw. ❚ Bei der Abonnementsbuchung von mehreren Verträgen wird nur das erste Mal eine echte Abonnementsanfrage gesendet, danach wird nur auf der Code-Ebene umgeschaltet, ohne Zeit zu verbrauchen. Die primären Kontinuitätsverträge werden mit einem Code wie 888 wie MA888 und den Kontinuitätsindexverträgen wie 000 wie MA000 nur für den Handel mit virtuellen Verträgen unterstützt.Die Mac-Sprache kann jedoch den Mainstream-Vertrag bearbeiten, und die Programmierung wechselt automatisch die Position, d.h. sie löscht die nicht-mainstream-Position und eröffnet eine neue Position auf der Mainstream-Position.
Ein erfolgreiches Anmelden kann den Vertrag nicht einrichten, aber es wird auch sofort zurückgegeben, so dass man mit _C erneut versuchen kann, in dem Wissen, dass der CTP-Anmelden abgeschlossen ist. Nach erfolgreicher Anmeldung ist das erneute Einrichten des Vertrages nicht zeitaufwendig und erzeugt keinen echten Netzwerkzugriff.
SetDirectionDie Richtungen sind verfügbarbuy, closebuy, sell, closesellVier Parameter, mehr Futuresclosebuy_todayUndclosesell_todayDas ist eine sehr schwierige Aufgabe.closebuy/closesellFür die Ausgleichsposition werden nur die Varianten der letzten Periode unterteilt, was die Gebühren beeinflussen kann. Für die CTP-Klassiker kann ein zweiter Parameter mit 1 Ton oder 2 Ton oder 3 Ton eingestellt werden, der jeweils auf die Spekulationen, die Gewinne und die Sicherheiten bezieht. Es gibt keine Default-Spekulation.Spezifische Operationen wie Kauf und Verkauf, Positionsgewinnung, Ordergewinnung, Rücknahme, Kontogewinnung sind identisch mit dem Handel mit digitalen Währungen.
| Bedienung | Parameter für SetDirection | Auftragsfunktion |
|---|---|---|
| Eröffnung von Positionen | exchange.SetDirection(“buy”) | exchange.Buy() |
| Pinto-Positionen | exchange.SetDirection(“closebuy”) | exchange.Sell() |
| Leerstand | exchange.SetDirection(“sell”) | exchange.Sell() |
| Leerlauf | exchange.SetDirection(“closesell”) | exchange.Buy() |
Das folgende Beispiel ist eine spezifische Playoff-Funktion, beachten Sie, dass dieses Beispiel zu einfach ist, aber auch eine Reihe von Fragen zu berücksichtigen, ob Sie sich in der Handelszeit befinden, wie Sie die Order nicht vollständig abschließen, wie Sie die Order aufheben, wie hoch die maximale Auftragsmenge ist, ob die Häufigkeit zu hoch ist, insbesondere der Kursverlust oder die Börsenöffnung. Nur als Referenz.Für die Festplatte empfiehlt sich die Verwendung einer plattformgebundenen Sammlung, http://www.fmz.com/strategy/12961。 Im Abschnitt Bibliotheken gibt es eine detaillierte Beschreibung und es wird empfohlen, den Quellcode der Bibliotheken zu lernen。
function Cover(contractType, amount, slide) {
for (var i = 0; i < positions.length; i++) {
if (positions[i].ContractType != contractType) {
continue;
}
var depth = _C(e.GetDepth);
if (positions[i].Type == PD_LONG || positions[i].Type == PD_LONG_YD) {
exchange.SetDirection(positions[i].Type == PD_LONG ? "closebuy_today" : "closebuy");
exchange.Sell(depth.Bids[0]-slide, amount, contractType, positions[i].Type == PD_LONG ? "平今" : "平昨", 'Bid', depth.Bids[0]);
} else {
exchange.SetDirection(positions[i].Type == PD_SHORT ? "closesell_today" : "closesell");
exchange.Buy(depth.Asks[0]+slide, amount, contractType, positions[i].Type == PD_SHORT ? "平今" : "平昨", 'Ask', depth.Asks[0]);
}
}
}
Commodity Futures unterstützt benutzerdefinierte Auftragstypen (Festplatte unterstützt, Rückmessung nicht unterstützt), nachträglich die Form des Ladens angeben, die in der Ladung angehängt wird_Die Rückseite der Flasche ist wie
exchange.SetDirection("buy_ioc");
exchange.SetDirection("sell_gtd-20170111")
Die spezifischen Suffixe sind:
Die CTP-Schnittstelle ist bei Commodity Futures Traders standardmäßig geöffnet und kann auf Wunsch umgewandelt werden. Durch die FMZ-Verpackung ist die Aufforderung identisch. Der Unterschied ist, dass Konten, Bestellungen und Lagerhalte im Push-Modus sind, so dass die Treuhänder diese Daten lokal pflegen und sofort zurückkehren, wenn die entsprechende Schnittstelle aufgerufen wird, ohne tatsächlich eine Anfrage zu stellen.
Die EOS-Vereinbarung definiert die folgenden Bestelltypen:
In der Festplatten-Oberfläche wird ein Log, ein @-Zeichen und eine Nachricht in die Push-Queue eingegeben, die direkt nach der Bindung von WeChat oder Telegram verschickt wird.Log('推送到微信@')
Die Farbe des Logs kann auch angepasst werdenLog('这是一个红色字体的日志 #ff0000') 。#ff0000Die 16-Zahlen der RGB-Farben
Alle Logfiles befinden sich in der sqlit-Datenbank auf der Festplatte im Verzeichnis des Verwalters. Sie können mit der Datenbanksoftware heruntergeladen und geöffnet werden. Sie können auch zur Wiederherstellung von Kopien der Backup-Datenbank verwendet werden (der Name der Datenbank und die Festplatte sind identisch).
Erträge werden erfasst und auf der Festplatte-Interface eine Ertragskurve gezeichnet, die auch nach dem Neustart der Festplatte beibehalten werden kann.LogProfit(1000)AchtungLogProfitDie Parameter für die Zahlen sind nicht unbedingt Erträge, sondern beliebige Zahlen, die Sie selbst ausfüllen müssen.
Die Festplatten-Status, da die Log-Log-Dateien gespeichert werden und ständig aktualisiert werden, kann verwendet werden, wenn nur Informationen angezeigt werden müssen, die nicht gespeichert wurden.LogStatusFunktion.LogStatusDie Parameter sind Strings und können auch als Tabelleninformationen verwendet werden.
Ein Beispiel für eine Tabelle, die den Status der Festplatte anzeigt:
var table = {type: 'table', title: '持仓信息', cols: ['列1', '列2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]};
LogStatus('`' + JSON.stringify(table) + '`'); // JSON序列化后两边加上`字符, 视为一个复杂消息格式(当前支持表格)
LogStatus('第一行消息\n`' + JSON.stringify(table) + '`\n第三行消息'); // 表格信息也可以在多行中出现
LogStatus('`' + JSON.stringify([table, table]) + '`'); // 支持多个表格同时显示, 将以TAB显示到一组里
LogStatus('`' + JSON.stringify(tab1) + '`\n' + '`' + JSON.stringify(tab2) + '`\n'); // 上下排列显示多个表
Die Parameter werden in Millisekunden angegeben, z. B.Sleep(1000)Eine Sekunde für die Ruhezeit. Da die Frequenz der Zugriffe auf alle Transaktionen begrenzt ist, wird in der Regel in der Strategie die Ruhezeit in den Todeszyklus aufgenommen.
Wenn die Festplatte neu gestartet wird, wird das Programm neu gestartet._GEs ist sehr praktisch und kann JSON-sequenzierte Inhalte speichern._GDie Funktion wird inonexit()Das bedeutet, dass jedes Mal, wenn die Strategie beendet wird, die benötigten Informationen automatisch gespeichert werden.
Wenn Sie mehr formatierte Daten speichern möchten, dann können Sie diese auf Ihrem Computer speichern._Die G-Funktion ist nicht sehr nützlich, da sie mit Python direkt in die Datenbank geschrieben werden kann.
function onexit(){
_G('profit', profit)
}
function main(){
_G("num", 1); // 设置一个全局变量num, 值为1 s
_G("num", "ok"); // 更改一个全局变量num, 值为字符串ok
_G("num", null); // 删除全局变量 num
_G("num"); // 返回全局变量num的值,如果不存在返回null
var profit = 0
if(_G('profit')){
profit = _G('profit')
}
}
Bei Bestellungen, bei denen oftmals Preise und Mengen genau kontrolliert werden müssen, verwendet die FMZ die Funktion _N, um die Speicherung kleiner Ziffern zu bestimmen, z. B._N(4.253,2)Das Ergebnis ist 4,25.
Es gibt keine Garantie, dass jeder Zugriff erfolgreich ist, und es gibt keine Garantie, dass jeder Zugriff erfolgreich ist._C ist eine Funktion, die automatisch erneut versucht wird. Es wird die angegebene Funktion aufgerufen, bis sie erfolgreich zurückgegeben wird (die Funktion, die null oder false zurückgibt, wird erneut versucht), z. B._C(exchange.GetTicker)Die _CDelay-Funktion kann eingesetzt werden, um die Wiederholungsintervalle zu steuern, z. B. _CDelay(1000), und die Änderung der _C-Funktion wird empfohlen, die Wiederholungsintervalle auf 1 Sekunde festzulegen.GetTicker(),exchange.GetDepth,GetTrade,GetRecords,GetAccount,GetOrders, GetOrderDie C-Fehler sind in C++ erlaubt, um zu verhindern, dass ein fehlgeschlagener Zugriff zu einer Unterbrechung des Programms führt.
CancelOrderDie _C-Funktion kann nicht verwendet werden, da ein Rücktritt aus verschiedenen Gründen fehlschlägt. Wenn eine einzelne Einheit bereits abgeschlossen ist, wird der Rücktritt als Fehlschlag zurückgegeben.
_C-Funktionen können auch in Parameter übertragen werden und werden auch für benutzerdefinierte Funktionen verwendet.
function main(){
var ticker = _C(exchange.GetTicker)
var depth = _C(exchange.GetDepth)
var records = _C(exchange.GetRecords, PERIOD_D1) //传入参数
}
Direktanruf_D()Gibt die aktuelle Zeitstring zurück, z. B.:2019-08-15 03:46:14。 Wenn es sich um einen Aufruf in der Rückmessung handelt, wird die Rückmesszeit zurückgegeben。 Die _D-Funktion kann verwendet werden, um die Zeit zu beurteilen, z. B.:_D().slice(11) > '09:00:00':
_D(timestamp,fmt)Die Zeitmenge wird in einer Zeitstring umgewandelt, wie z.B._D(1565855310002)Das fmt-Parameter ist ein Zeitformat, der Standardformat.yyyy-MM-dd hh:mm:ss
Für einige gängige Kennziffern wie MA\MACD\KDJ\BOLL sind die FMZ-Plattform direkt integriert. Die spezifischen unterstützten Kennziffern finden Sie in der API-Dokumentation.
Bevor Sie die Kennzahl verwenden, sollten Sie die Länge der K-Linien bestimmen. Wenn die vorherige Länge der K-Linien nicht die erforderliche Periode für die Berechnung erfüllt, ist die FolgenullWenn die Länge der eingegebenen K-Strecke 100 ist und die Periode der berechneten MA 10 ist, sind die ersten 9 Werte null und die folgenden werden normal berechnet.
JavaScript unterstützt auch die vollständige Talib, die als eine von Drittanbietern unterstützte Bibliothek bezeichnet wird.talib.CCI(records)❚ Referenz: http://ta-lib.org/function.html ❚ Für Python kann die talib-Bibliothek selbstständig installiert werden, da die Kompilierung erforderlich ist und die einfache Pip-Installation nicht möglich ist.
Die Pointer-Funktion kann in beliebige Arrays übertragen werden, zusätzlich zu den Daten der K-Linie.
function main(){
var records = exchange.GetRecords(PERIOD_M30)
if (records && records.length > 9) {
var ma = TA.MA(records, 14)
Log(ma)
}
}
Hier sind einige der häufigsten JavaScript-Funktionen auf der Festplatte:
Date.now()Zurück zur aktuellen ZeitspanneparseFloat()Umwandlung einer Zeichenkette in eine Zahl, z. B.parseFloat("123.21")parseInt()Umwandlung der Zeichenfolge in eine ganze Zahlnum.toString()Umsetzen von Zahlen in Strings und von num in Zahlen.JSON.parse()Json-String formatiert, wieJSON.parse(exchange.GetRawJSON())Math.max(),Math.abs()Das ist eine sehr einfache Aufgabe, die man sich selbst überlegen kann.Es gibt viele Situationen, in denen eine Strategie-Funktion für die Festplatte zu schreiben ist, zum Beispiel eine einfache Funktion wie den Kauf von 5 Münzen, die wir berücksichtigen müssen: Ist der ak