Vor kurzem wurden in der offiziellen FMZ-Gruppe viele Martingale-Strategien diskutiert, und es gibt nicht viele Martingale-Strategien von Kryptowährungsverträgen auf der Plattform. Daher nutzte ich diese Gelegenheit, um eine einfache Martingale-Strategie für Kryptowährungs-Futures zu entwerfen. Warum wird sie eine Martingale-Strategie genannt? Weil die potenziellen Risiken der Martin-Strategie in der Tat nicht klein sind, ist sie nicht genau nach der Martin-Strategie konzipiert. Diese Art von Strategie hat jedoch immer noch viele Risiken, und die Parameter-Einstellungen der Martin-Art-Strategie hängen eng mit dem Risiko zusammen, und das Risiko sollte nicht ignoriert werden.
Dieser Artikel erläutert hauptsächlich und lernt aus dem Design von Martin-artigen Strategien. Da die Strategieidee sehr klar ist, betrachten wir als Benutzer von FMZ das Strategiedesign mehr.
Das Gesamtkapital wird häufig bei der Gestaltung von Kryptowährungs-Futures-Strategien verwendet. Dies liegt daran, dass die Renditen berechnet werden müssen, insbesondere wenn Sie schwimmende Renditen berechnen müssen. Da die Position mit Marge besetzt ist, wird auch die ausstehende Order besetzt. Zu diesem Zeitpunkt wird die API-Schnittstelleexchange.GetAccount()
In der Tat liefern die meisten Kryptowährungs-Futures-Börsen die Daten des Gesamtkapitals, aber dieses Attribut ist nicht einheitlich auf FMZ verpackt.
Wir entwerfen also Funktionen, um diese Daten nach verschiedenen Austausch zu erhalten:
// OKEX V5 obtain total equity
function getTotalEquity_OKEX_V5() {
var totalEquity = null
var ret = exchange.IO("api", "GET", "/api/v5/account/balance", "ccy=USDT")
if (ret) {
try {
totalEquity = parseFloat(ret.data[0].details[0].eq)
} catch(e) {
Log("failed to obtain the total equity of the account!")
return null
}
}
return totalEquity
}
// Binance futures
function getTotalEquity_Binance() {
var totalEquity = null
var ret = exchange.GetAccount()
if (ret) {
try {
totalEquity = parseFloat(ret.Info.totalWalletBalance)
} catch(e) {
Log("failed to obtain the total equity of the account!")
return null
}
}
return totalEquity
}
DietotalEquity
Dann schreiben wir eine Funktion als Call-Eintrag und rufen die entsprechende Funktion nach dem Namen der Börse an.
function getTotalEquity() {
var exName = exchange.GetName()
if (exName == "Futures_OKCoin") {
return getTotalEquity_OKEX_V5()
} else if (exName == "Futures_Binance") {
return getTotalEquity_Binance()
} else {
throw "This exchange is not supported"
}
}
Bevor wir die Hauptfunktion und die Hauptlogik entwerfen, müssen wir einige Vorbereitungen treffen und einige Hilfsfunktionen entwerfen.
Alle laufenden Bestellungen stornieren
function cancelAll() {
while (1) {
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
break
}
for (var i = 0 ; i < orders.length ; i++) {
exchange.CancelOrder(orders[i].Id, orders[i])
Sleep(500)
}
Sleep(500)
}
}
Diese Funktion ist denen bekannt, die oft den Strategiebeispielcode auf dem FMZ-Strategie-Feld lesen, und viele Strategien haben ähnliche Designs verwendet.
Positionsgeschäfte für Futures
function trade(distance, price, amount) {
var tradeFunc = null
if (distance == "buy") {
tradeFunc = exchange.Buy
} else if (distance == "sell") {
tradeFunc = exchange.Sell
} else if (distance == "closebuy") {
tradeFunc = exchange.Sell
} else {
tradeFunc = exchange.Buy
}
exchange.SetDirection(distance)
return tradeFunc(price, amount)
}
function openLong(price, amount) {
return trade("buy", price, amount)
}
function openShort(price, amount) {
return trade("sell", price, amount)
}
function coverLong(price, amount) {
return trade("closebuy", price, amount)
}
function coverShort(price, amount) {
return trade("closesell", price, amount)
}
Es gibt vier Richtungen für den Futures-Handel: openLong, openShort, coverLong und coverShort. Also haben wir vier Auftragsfunktionen entworfen, die diesen Operationen entsprechen. Wenn Sie nur die Order betrachten, dann gibt es mehrere notwendige Faktoren: Richtung, Auftragspreis und Auftragsvolumen.
Also haben wir auch eine Funktion namens:trade
Um die Operation zu bearbeiten, wenndistance
, price
, amount
sind spezifiziert.
Die Funktionsanrufe auf openLong, openShort, coverLong und coverShort werden letztendlich durch dentrade
Funktion, d. h. Aufgabe einer Bestellung an einer Futures-Börse auf der Grundlage der festgelegten Entfernung, des Preises und der Menge.
Die Strategieidee ist sehr einfach, nehmen Sie den aktuellen Preis als Basislinie und platzieren Sie Verkaufs- (Short) und Kauf- (Long) Aufträge auf einer bestimmten Entfernung nach oben oder unten. Sobald die Transaktion abgeschlossen ist, werden alle verbleibenden Aufträge storniert, und dann wird eine neue Schließorder an einer bestimmten Entfernung nach dem Preis der Position platziert, und eine Erhöhungsorder wird zum aktualisierten aktuellen Preis platziert, aber das Auftragsvolumen wird nicht für zusätzliche Positionen verdoppelt.
Erste Arbeiten Aufgrund des ausstehenden Auftrags brauchen wir zwei globale Variablen, um die Auftrags-ID aufzuzeichnen.
var buyOrderId = null
var sellOrderId = null
Dann sind die Strategie-Schnittstellenparameter so konzipiert, dass sie die OKEX_V5 simulierte Bot-Option verwenden, so dass einige Verarbeitungen im Code durchgeführt werden müssen:
var exName = exchange.GetName()
// Switch OKEX V5 simulated bot
if (isSimulate && exName == "Futures_OKCoin") {
exchange.IO("simulate", true)
}
Es gibt auch die Möglichkeit, alle Informationen in den Schnittstellenparametern zurückzusetzen, sodass die entsprechende Verarbeitung im Code erfolgen sollte:
if (isReset) {
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("reset all data", "#FF0000")
}
Wir führen nur dauerhafte Verträge, also ist die Schrift hier fixiert und nur auf dauerhaft eingestellt.
exchange.SetContractType("swap")
Dann müssen wir auch die Genauigkeit des Auftragspreises und des Auftragsbetrags berücksichtigen. Wenn die Genauigkeit nicht ordnungsgemäß eingestellt ist, geht die Genauigkeit während des Strategieberechnungsvorgangs verloren. Wenn die Daten eine große Anzahl von Dezimalstellen haben, kann es leicht sein, dass die Bestellung von der Austauschoberfläche abgelehnt wird.
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("set precision", pricePrecision, amountPrecision)
Einfache Datenwiederherstellung durch Design
if (totalEq == -1 && !IsVirtual()) {
var recoverTotalEq = _G("totalEq")
if (!recoverTotalEq) {
var currTotalEq = getTotalEquity()
if (currTotalEq) {
totalEq = currTotalEq
_G("totalEq", currTotalEq)
} else {
throw "failed to obtain initial equity"
}
} else {
totalEq = recoverTotalEq
}
}
Wenn Sie das anfängliche Gesamtkapital des Kontos angeben möchten, wenn die Strategie ausgeführt wird, können Sie den ParametertotalEq
. Wenn dieser Parameter auf -1 gesetzt ist, wird die Strategie die gespeicherten Gesamtkapitaldaten auslesen. Wenn keine gespeicherten Gesamtkapitaldaten vorliegen, wird das aktuelle gelesenen Gesamtkapital als das anfängliche Gesamtkapital der laufenden Strategie verwendet. Danach zeigt eine Erhöhung des Gesamtkapitals einen Gewinn an und eine Abnahme des Gesamtkapitals einen Verlust an. Wenn die Gesamtkapitaldaten gelesen werden, wird die Strategie weiterhin mit diesen Daten ausgeführt.
Hauptlogik Nach der ersten Arbeit sind wir endlich zum logischen Teil der Strategie gekommen.
while (1) { // The main logic of the strategy is designed as an infinite loop
var ticker = _C(exchange.GetTicker) // Read the current market information first, mainly using the latest transaction price
var pos = _C(exchange.GetPosition) // Read current position data
if (pos.length > 1) { // Judging the position data, because of the logic of this strategy, it is unlikely that long and short positions will appear at the same time, so if there are long and short positions at the same time, an error will be thrown
Log(pos)
throw "Simultaneous long and short positions" // Throw an error to stop the strategy
}
//Depends on status
if (pos.length == 0) { // Make different operations according to the position status, when there is no position, pos.length == 0
// If you have not held a position, count the profit once
if (!IsVirtual()) {
var currTotalEq = getTotalEquity()
if (currTotalEq) {
LogProfit(currTotalEq - totalEq, "current total equity:", currTotalEq)
}
}
buyOrderId = openLong(ticker.Last - targetProfit, amount) // Open a buy order for a long position
sellOrderId = openShort(ticker.Last + targetProfit, amount) // Open a short sell order
} else if (pos[0].Type == PD_LONG) { // For long positions, the position and quantity of pending orders are different
var n = 1
var price = ticker.Last
buyOrderId = openLong(price - targetProfit * n, amount)
sellOrderId = coverLong(pos[0].Price + targetProfit, pos[0].Amount)
} else if (pos[0].Type == PD_SHORT) { // For short positions, the position and quantity of pending orders are different
var n = 1
var price = ticker.Last
buyOrderId = coverShort(pos[0].Price - targetProfit, pos[0].Amount)
sellOrderId = openShort(price + targetProfit * n, amount)
}
if (!sellOrderId || !buyOrderId) { // If one side of the pending order fails, cancel all pending orders and start over
cancelAll()
buyOrderId = null
sellOrderId = null
continue
}
while (1) { // The pending order is completed, start monitoring the order
var isFindBuyId = false
var isFindSellId = false
var orders = _C(exchange.GetOrders)
for (var i = 0 ; i < orders.length ; i++) {
if (buyOrderId == orders[i].Id) {
isFindBuyId = true
}
if (sellOrderId == orders[i].Id) {
isFindSellId = true
}
}
if (!isFindSellId && !isFindBuyId) { // Detected that both buy and sell orders have been filled
cancelAll()
break
} else if (!isFindBuyId) { // Detected buy order closing
Log("buy order closing")
cancelAll()
break
} else if (!isFindSellId) { // Detected sell order closing
Log("sell order closing")
cancelAll()
break
}
LogStatus(_D())
Sleep(3000)
}
Sleep(500)
}
Die ganze Logik und das Design werden erklärt.
Lassen Sie die Strategie durch einen Markt am 19. Mai gehen.
Es ist zu sehen, daß die Martingale-Strategie noch gewisse Risiken birgt.
Der echte Bot kann mit dem OKEX V5 Simulationsbot ausgeführt werden
Strategieadresse:https://www.fmz.com/strategy/294957
Strategien werden hauptsächlich zum Lernen verwendet, und echtes Geld sollte mit Vorsicht verwendet werden~!