Vor kurzem wurden in der offiziellen FMZ-Gruppe viele Martingale-Strategien diskutiert, und es gibt nicht viele Martingale-Strategien von Kryptowährungsverträgen auf unserer Plattform. Daher nutzte ich diese Gelegenheit, um eine einfache Kryptowährungs-Futuresmartingale-Strategien zu entwerfen. Warum wird sie eine Martingale-Strategien genannt? Da das potenzielle Risiko der Martingale-Strategie in der Tat nicht klein ist, ist es nicht notwendig, nach der Martingale-Strategie zu entwerfen. Diese Art von Strategien hat jedoch immer noch viele Risiken, und die Parameter-Einstellungen der Martingale-Strategien sind eng mit den Risiken verbunden, und die Risiken dürfen nicht ignoriert werden.
In diesem Artikel erläutern und lernen wir hauptsächlich aus dem Design von Martingale-Art-Strategien.
Das Gesamtkapital wird häufig bei der Gestaltung einer Kryptowährungs-Futures-Strategie verwendet, da wir die Gewinne berechnen wollen, insbesondere wenn wir die schwimmenden Gewinne berechnen müssen.exchange.GetAccount()
In der Tat liefern die meisten Kryptowährungs-Futures-Plattformen die Daten des Gesamtkapitals, aber diese Eigenschaft ist nicht einheitlich auf FMZ verpackt.
Daher entwerfen wir einzelne Funktionen, um die Daten nach verschiedenen Plattformen zu erhalten:
// OKEX V5 obtains the 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("Fail to obtain the total equity of the account!")
return null
}
}
return totalEquity
}
// Binance Ftures
function getTotalEquity_Binance() {
var totalEquity = null
var ret = exchange.GetAccount()
if (ret) {
try {
totalEquity = parseFloat(ret.Info.totalWalletBalance)
} catch(e) {
Log("Fail to obtain the total equity!")
return null
}
}
return totalEquity
}
DietotalEquity
Dann schreiben wir eine Funktion als Aufruf-Eintrag und rufen die entsprechende Funktion nach dem Plattformnamen 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 "Do not support the platform"
}
}
Bevor wir die Hauptfunktion und die Hauptlogik entwerfen, müssen wir auch einige Hilfsfunktionen zur Vorbereitung 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 das ähnliche Design verwendet.
Der Handel mit Futures-Orders
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: offene Long-Position (openLong), offene Short-Position (openShort), schließende Long-Position (coverLong) und schließende Short-Position (coverShort). Daher haben wir vier Orderfunktionen entworfen, um diesen Operationen zu entsprechen. Wenn Sie nur die Platzierung von Aufträgen berücksichtigen, dann gibt es mehrere notwendige Faktoren: Richtung, Auftragspreis und Auftragsbetrag.
Wir haben auch eine Funktion namens:trade
Um die Operation zu bearbeiten, wenndirection (distance)
, order price (price)
undorder amount (amount)
sind spezifiziert.
Die Funktionsaufrufe von offenen Long-Positionen (openLong), offenen Short-Positionen (openShort), geschlossenen Long-Positionen (coverLong) und geschlossenen Short-Positionen (coverShort) werden letztendlich durch dietrade
Funktion, d. h. nach der angegebenen Richtung, Preis und Betrag, Aufträge in den Futures-Plattformen platzieren.
Die Strategieidee ist sehr einfach; nehmen Sie den aktuellen Preis als Basislinie und von einer bestimmten Entfernung über und unter der Basislinie, um Verkaufsoptionen (short) und Kaufoptionen (long) zu platzieren. Wenn die Aufträge einer Seite ausgeführt werden, stornieren Sie alle verbleibenden Aufträge, und dann werden neue Schließoptionen in einer bestimmten Entfernung nach dem Positionpreis platziert und Kaufoptionen werden zum aktualisierten aktuellen Preis platziert, aber die Kaufoptionen verdoppeln nicht den Auftragsbetrag.
Erste Arbeiten Da wir Bestellungen warten lassen wollen, brauchen wir zwei Variablen, um die Bestell-ID aufzuzeichnen.
var buyOrderId = null
var sellOrderId = null
Dann ist die Option, den simulierten Bot OKEX_V5 zu verwenden, in den Strategie-Schnittstellenparametern entworfen, so dass einige Verarbeitungen im Code durchgeführt werden müssen:
var exName = exchange.GetName()
// switch to OKEX V5 simulated bot
if (isSimulate && exName == "Futures_OKCoin") {
exchange.IO("simulate", true)
}
Die Option, alle Informationen zurückzusetzen, ist auch in den Strategieparametern vorgesehen, so dass einige Verarbeitungen im Code durchgeführt werden müssen:
if (isReset) {
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("Reset all data", "#FF0000")
}
Wir führen nur ewige Verträge, also schreiben wir es hier in einer unendlichen Schleife, und wir setzen es nur auf dauerhaften Vertrag.
exchange.SetContractType("swap")
Auch müssen wir die Präzisionsprobleme des Auftragspreises und des Auftragsbetrags berücksichtigen. Wenn die Präzision nicht richtig eingestellt ist, wird sie während des Strategieberechnungsvorgangs verloren gehen. Wenn die Daten eine große Anzahl von Dezimalstellen haben, ist es leicht, dass die Bestellung von der Plattformoberfläche abgelehnt wird.
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("set percision", pricePrecision, amountPrecision)
Die einfache Datenwiederherstellungsfunktion in der Konstruktion
if (totalEq == -1 && !IsVirtual()) {
var recoverTotalEq = _G("totalEq")
if (!recoverTotalEq) {
var currTotalEq = getTotalEquity()
if (currTotalEq) {
totalEq = currTotalEq
_G("totalEq", currTotalEq)
} else {
throw "Fail to obtain the initial equity"
}
} else {
totalEq = recoverTotalEq
}
}
Wenn Sie das anfängliche Gesamtkapital des Kontos beim Ausführen der Strategie angeben möchten, können Sie den ParametertotalEq
. Wenn dieser Parameter auf -1 gesetzt ist, wird die Strategie die gespeicherten Gesamtkapitaldaten auslesen. Wenn keine gespeicherten Gesamtkapitaldaten vorhanden sind, wird das derzeit gelesenen Gesamtkapital als das anfängliche Gesamtkapital in der laufenden Strategie verwendet. Später, wenn das Gesamtkapital steigt, bedeutet dies, dass es einen Gewinn erzielt hat; wenn das Gesamtkapital sinkt, bedeutet dies, dass es einen Verlust gibt. Wenn die Gesamtkapitaldaten gelesen werden, verwenden Sie die Daten, um den Lauf fortzusetzen.
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, in which we mainly use the latest trading price
var pos = _C(exchange.GetPosition) // read the current position data
if (pos.length > 1) { // judge the position data; due to the strategy logic, it is unlikely to have long and short positions at the same time, so if there are long and short positions at the same time, an error will be thrown
Log(pos)
throw "concurrently with long and short positions" // raise an error, and stop the strategy
}
// according to the status
if (pos.length == 0) { // according to the position status, make different operations; if pos.length == 0, it means currently no position
// when there is no position yet, calculate the equity
if (!IsVirtual()) {
var currTotalEq = getTotalEquity()
if (currTotalEq) {
LogProfit(currTotalEq - totalEq, "Current total equity:", currTotalEq)
}
}
buyOrderId = openLong(ticker.Last - targetProfit, amount) // pend buy order of open long position
sellOrderId = openShort(ticker.Last + targetProfit, amount) // pend sell order of open short position
} else if (pos[0].Type == PD_LONG) { // there are long positions; pending position and amount are
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) { // there are short positions; pending position and amount 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 opending orders of one side fails, cancel all pending orders and try again
cancelAll()
buyOrderId = null
sellOrderId = null
continue
}
while (1) { // finish pending the order, and start to monitor 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) { // both buy order and sell order are detected to be executed
cancelAll()
break
} else if (!isFindBuyId) { // a buy order execution is detected
Log("buy order executed")
cancelAll()
break
} else if (!isFindSellId) { // a sell order execution is detected
Log("sell order executed")
cancelAll()
break
}
LogStatus(_D())
Sleep(3000)
}
Sleep(500)
}
Die ganze Logik und das Design sind dann vollständig erklärt.
Lassen Sie die Strategie am 19. Mai 2021 die Marktnotierungen durchqueren.
Wie wir sehen können, birgt die Martingale-ähnliche Strategie noch gewisse Risiken.
Strategieadresse:https://www.fmz.com/strategy/294957
Die Strategie wird hauptsächlich für das Studium verwendet, also bedienen Sie die Strategie nicht in einem echten Bot!