In den vorangegangenen Artikeln haben wir die Ideen und die Codeimplementierung der ursprünglichen Spot-Version der High-Frequency Profit Harvester-Strategie analysiert.
Analyse der Gewinngewinnung (1) Profit Harvester-Analyse (2)
Viele Nutzer im kreativen Kryptowährungskreis sind sehr besorgt über die von einem Meister namensGeld drucken. Die Strategie derGeld druckenAus der Beobachtung und Analyse vieler Follower lässt sich erkennen, dass die Hochfrequenzstrategie dem Prinzip des Gewinnsammlers ähnelt (Meister Xiaocao sagte auch, dass das Prinzip der Hochfrequenzstrategie dem Gewinnsammler ähnelt).
Daher war ich so aufgeregt, dass ich nicht anders konnte, als die Strategie magisch zu modifizieren, selbst das magisch modifizierte Strategieergebnis und die Wirkung waren nichts im Vergleich zu den von den Meistern entwickelten Strategien. Aber es ist auch eine Lernpraxis für Hochfrequenzstrategie. Interessierte FMZer können darüber gemeinsam diskutieren und lernen.
var TickInterval = 100
function LeeksReaper() {
var self = {}
self.numTick = 0
self.lastTradeId = 0
self.vol = 0
self.askPrice = 0
self.bidPrice = 0
self.orderBook = {
Asks: [],
Bids: []
}
self.prices = []
self.tradeOrderId = 0
self.account = null
self.buyPrice = 0
self.sellPrice = 0
self.state = 0
self.depth = null
self.updateTrades = function() {
var trades = _C(exchange.GetTrades)
if (self.prices.length == 0) {
while (trades.length == 0) {
trades = trades.concat(_C(exchange.GetTrades))
}
for (var i = 0; i < 15; i++) {
self.prices[i] = trades[trades.length - 1].Price
}
}
self.vol = 0.7 * self.vol + 0.3 * _.reduce(trades, function(mem, trade) {
// Huobi not support trade.Id
if ((trade.Id > self.lastTradeId) || (trade.Id == 0 && trade.Time > self.lastTradeId)) {
self.lastTradeId = Math.max(trade.Id == 0 ? trade.Time : trade.Id, self.lastTradeId)
mem += trade.Amount
}
return mem
}, 0)
}
self.updateOrderBook = function() {
var orderBook = _C(exchange.GetDepth)
self.depth = orderBook
self.buyPrice = orderBook.Bids[pendingLevel].Price
self.sellPrice = orderBook.Asks[pendingLevel].Price
self.orderBook = orderBook
if (orderBook.Bids.length < 3 || orderBook.Asks.length < 3) {
return
}
self.bidPrice = orderBook.Bids[0].Price * 0.618 + orderBook.Asks[0].Price * 0.382 + 0.01
self.askPrice = orderBook.Bids[0].Price * 0.382 + orderBook.Asks[0].Price * 0.618 - 0.01
self.prices.shift()
self.prices.push(_N((orderBook.Bids[0].Price + orderBook.Asks[0].Price) * 0.15 +
(orderBook.Bids[1].Price + orderBook.Asks[1].Price) * 0.1 +
(orderBook.Bids[2].Price + orderBook.Asks[2].Price) * 0.1 +
(orderBook.Bids[3].Price + orderBook.Asks[3].Price) * 0.075 +
(orderBook.Bids[4].Price + orderBook.Asks[4].Price) * 0.05 +
(orderBook.Bids[5].Price + orderBook.Asks[5].Price) * 0.025))
}
self.updateAccount = function() {
var account = exchange.GetAccount()
if (!account) {
return
}
self.account = account
LogProfit(parseFloat(account.Info.totalWalletBalance), account)
}
self.CancelAll = function() {
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)
}
Sleep(100)
}
}
self.poll = function() {
self.numTick++
self.updateTrades()
self.updateOrderBook()
var pos = _C(exchange.GetPosition)
var burstPrice = self.prices[self.prices.length - 1] * burstThresholdPct
var bull = false
var bear = false
LogStatus(_D(), "\n", 'Tick:', self.numTick, 'self.vol:', self.vol, ', lastPrice:', self.prices[self.prices.length - 1], ', burstPrice: ', burstPrice)
if (self.numTick > 2 && (
self.prices[self.prices.length - 1] - _.max(self.prices.slice(-6, -1)) > burstPrice ||
self.prices[self.prices.length - 1] - _.max(self.prices.slice(-6, -2)) > burstPrice && self.prices[self.prices.length - 1] > self.prices[self.prices.length - 2]
)) {
bull = true
} else if (self.numTick > 2 && (
self.prices[self.prices.length - 1] - _.min(self.prices.slice(-6, -1)) < -burstPrice ||
self.prices[self.prices.length - 1] - _.min(self.prices.slice(-6, -2)) < -burstPrice && self.prices[self.prices.length - 1] < self.prices[self.prices.length - 2]
)) {
bear = true
}
if (pos.length != 0) {
if (pos[0].Type == PD_LONG) {
self.state = 1
} else {
self.state = 2
}
} else {
self.state = 0
}
if ((!bull && !bear)) {
return
}
if (bull) {
var price = (self.state == 0 || self.state == 1) ? self.buyPrice : self.depth.Bids[coverPendingLevel].Price
var amount = (self.state == 0 || self.state == 1) ? pendingAmount : pos[0].Amount
exchange.SetDirection("buy")
exchange.Buy(price, amount)
} else if (bear) {
var price = (self.state == 0 || self.state == 2) ? self.sellPrice : self.depth.Asks[coverPendingLevel].Price
var amount = (self.state == 0 || self.state == 2) ? pendingAmount : pos[0].Amount
exchange.SetDirection("sell")
exchange.Sell(price, amount)
}
self.numTick = 0
Sleep(TickInterval)
self.CancelAll()
self.updateAccount()
}
while (!self.account) {
self.updateAccount()
Sleep(500)
}
Log("self.account:", self.account)
return self
}
function main() {
LogProfitReset()
exchange.SetPrecision(pricePrecision, amountPrecision)
exchange.SetContractType("swap")
var reaper = LeeksReaper()
while (true) {
reaper.poll()
Sleep(100)
}
}
Die Strategie soll auf dem Binance USDT-Kontraktmarkt gehandelt werden, der einseitige Positionen unterstützt. Daher wird die Strategie entsprechend den Eigenschaften von einseitigen Positionen modifiziert und konzipiert (einseitige Positionen sind für die Strategieänderung bequemer), und Sie müssen nur Kauf und Verkauf in Betracht ziehen, keine Notwendigkeit, über Schließpositionen nachzudenken. Diese Denkweise ist auch näher an der Spot-Version des Gewinnsammlers.
Die Strategie behält grundsätzlich das ursprüngliche kurzfristige Preistrend-Breakout-Kriterium bei, und der kurzfristige Preisbreakout-Bereich wird durch den ParameterburstThresholdPct
. Nach dem Kriterium, nach dem zu bestimmen ist, ob der kurzfristige Preisbull
oderbear
.
Die Strategie entfernt einige Module aus dem Original, wie z.B. das Balance-Modul. Eine ziemlich große Änderung besteht darin, das Platzieren von Aufträgen in ausstehende Aufträge im Auftragsbuch zu ändern und auf die Ausführung zu warten. Es wird erwartet, dass die Aktie am chaotischen Markt mit einem heftigen Long-Short-Spiel Positionen zu vergleichsweise niedrigen Kosten eröffnet, dem kurzfristigen Trend folgt und Positionen schließt, wenn sich der kurzfristige Trend umkehrt, und anschließend die ausstehenden Aufträge und offenen Positionen umgekehrt fortsetzt.
Die Strategie entfernt anderen nutzlosen Code, so dass es sehr kurz und einfach ist. Obwohl die Strategie eine unrentable Strategie ist, auch mit Verlusten, ist es ein sehr einfaches und nützliches Modell für einen FMZer, um Hochfrequenzstrategien zu lernen, die Aktionen von Hochfrequenzstrategien zu beobachten, die mikroskopischen Regeln des Marktes zu beobachten, etc. Programmiertes und quantitatives Trading muss auf viel Praxis, Erfahrung und Theorien basieren.
Es ist offensichtlich, dass es schwieriger ist, Positionen zu eröffnen und zu schließen, wenn die Marktlage nicht aktiv ist.
Derzeit ist keine gute Optimierungsrichtung gefunden worden. Interessierte Schüler können sich aktiv äußern und gemeinsam darüber diskutieren.
Strategieadresse:https://www.fmz.com/strategy/260806
Die Strategie ist nur für die Studie; wenn der Markt flach ist, kann es im Bot zu Verlusten führen.