Mari kita lanjutkan penjelasan isi dari bab terakhir (https://www.fmz.com/bbs-topic/9725).
Fungsi ketiga yang ditambahkan:
self.balanceAccount = function() {
var account = exchange.GetAccount()
if (!account) {
return
}
self.account = account
var now = new Date().getTime()
if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {
self.preCalc = now
var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks))
if (net != self.preNet) {
self.preNet = net
LogProfit(net)
}
}
self.btc = account.Stocks
self.cny = account.Balance
self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)
var balanced = false
if (self.p < 0.48) {
Log ( \"\" Start Balance \"\", self. P)
self.cny -= 300
if (self.orderBook.Bids.length >0) {
exchange.Buy(self.orderBook.Bids[0].Price + 0.00, 0.01)
exchange.Buy(self.orderBook.Bids[0].Price + 0.01, 0.01)
exchange.Buy(self.orderBook.Bids[0].Price + 0.02, 0.01)
}
} else if (self.p > 0.52) {
Log ( \"\" Start Balance \"\", self. P)
self.btc -= 0.03
if (self.orderBook.Asks.length >0) {
exchange.Sell(self.orderBook.Asks[0].Price - 0.00, 0.01)
exchange.Sell(self.orderBook.Asks[0].Price - 0.01, 0.01)
exchange.Sell(self.orderBook.Asks[0].Price - 0.02, 0.01)
}
}
Sleep(BalanceTimeout)
var orders = exchange.GetOrders()
if (orders) {
for (var i = 0; i < orders.length; i++) {
if (orders[i].Id != self.tradeOrderId) {
exchange.CancelOrder(orders[i].Id)
}
}
}
}
Ketika konstruktorLeeksReaper ()
Membangun objek,balanceAccount ()
fungsi yang ditambahkan ke objek memperbarui informasi aset akun yang disimpan diself.account
, yaitu,account
Atribut objek yang dibangun. Hitung nilai pendapatan dan cetak tepat waktu. Kemudian, menurut informasi aset akun terbaru, hitung rasio saldo mata uang spot (saldo posisi spot), saat memicu ambang offset, tutup posisi dengan pesanan kecil, sehingga mata uang (posisi) kembali ke keadaan keseimbangan. Tunggu beberapa saat untuk berurusan, kemudian batalkan semua pembuat, putaran berikutnya pelaksanaan fungsi, itu akan memeriksa saldo dan melakukan pemrosesan yang sesuai lagi.
Mari kita lihat kode fungsi ini kalimat demi kalimat:
Pertama, kalimat pertamavar account = exchange.GetAccount ()
menyatakan variabel lokalaccount
dan memanggil fungsi dariexchange.GetAccount
Dapatkan data terbaru dari akun saat ini dan menetapkannya ke variabelaccount
. Lalu menilai variabelaccount
. Jika variabelnya adalahnull
(misalnya, timeout, jaringan, pertukaran antarmuka pengecualian, dll), itu akan kembali (mengandungif (!account) {...}
) secara langsung.
self.account = account
adalah untuk menetapkan variabel lokalaccount
untukaccount
Atribut dari objek yang dibangun untuk merekam informasi akun terbaru dalam objek yang dibangun.
Var now = new Date().getTime ()
menyatakan variabel lokalnow
dan memanggilgetTime()
fungsi dari bahasa JavaScriptnow
.
if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)){...}
Tentukan bahwa jika perbedaan antara timestamp saat ini dan timestamp terakhir kali tercatat melebihi parameterCalcNet Interval * 1000
, berarti telah diperbarui dari terakhir kali.CalcNetInterval * 1000
Milisekund (CalcNetInterval
Karena harga pembelian satu digunakan untuk menghitung pendapatan, kondisiself.orderBook.Bids.length > 0
juga didefinisikan dalam kondisi (data kedalaman, harus ada informasi tingkat yang valid dalam daftar urutan).self.PreCalc = now
dieksekusi untuk memperbarui variabel timestamp dari pengembalian yang paling baru dicetakself.preCalc
ke timestamp saat ininow
Di sini, metode perhitungan nilai bersih digunakan dalam statistik pengembalian.var net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks))
, yaitu mengkonversi mata uang ke dalam uang (mata uang denominasi) sesuai dengan pembelian saat ini satu harga, dan kemudian menambahkannya ke jumlah uang di rekening dan menetapkannya ke variabel lokal yang dinyatakannet
. Pertimbangkan apakah nilai bersih total saat ini konsisten dengan nilai bersih total yang dicatat terakhir kali:
if (net != self.preNet) {
self.preNet = net
LogProfit(net)
}
Jika itu tidak konsisten, yaitu,net! = self.preNet
adalah benar, update atribut dariself.preNet
digunakan untuk mencatat nilai bersih dengan variabelnet
Kemudian cetak total bersih darinet
data ke grafik kurva imbal hasil dari FMZ Quant Trading platform robot (theLogProfit
fungsi dapat ditanyakan dalam dokumen FMZ API).
Jika pencetakan pendapatan secara teratur tidak dipicu, lanjutkan proses berikut untuk mencatat pendapatan.account.Stocks
(mata uang yang tersedia di rekening arus) danaccount.Balance
(mata uang yang tersedia di rekening arus)self.BTC
danself.CNY
. Menghitung skala offset dan mencatat penugasan dalamself.p
.
self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)
Algoritma juga sangat sederhana, yaitu menghitung persentase nilai saat ini dari mata uang untuk total nilai bersih akun.
Bagaimana dengan menilai kapan untuk memicu keseimbangan uang (posisi)?
Di sini, saya mengambil 50% ditambah atau dikurangi 2 poin persentase sebagai buffer, dan menjalankan saldo di luar buffer, yaitu jikaself.p < 0.48
, saldo uang dipicu oleh penyimpangan. Jika uang kurang, harga akan meningkat sebesar 0,01 setiap kali dari posisi pembelian pada pembukaan pasar, dan tiga pesanan kecil akan diatur.self.p > 0.52
, jika mata uang lebih, menjual satu dan melepaskan pesanan kecil.Sleep(BalanceTimeout)
untuk waktu tertentu sesuai dengan pengaturan parameter.
Var orders = exchange. Get Orders () # Get all current makers, with orders variable
If (orders) { # If the variable orders used to obtain the current order data is not null
for (var i = 0; i < orders.length; I + +) { # Loop through orders and cancel orders one by one
if (orders[i].Id != self.tradeOrderId) {
Exchange. CancelOrder (orders [I]. Id) # Call exchange. CancelOrder to cancel orders based on orders [I]. Id
}
}
}
Fungsi keempat yang ditambahkan:
Di bagian inti dari strategi, inilah permainan utama.self.poll = function(){...}
fungsi adalah logika utama dari seluruh strategi.main()
fungsi mulai untuk menjalankan dan memasuki tak berujungwhile
loop, kita menggunakanvar reaper = LeeksReaper()
untuk membangun objek leeksreaper, dan kemudian menjalankan panggilan loop darireaper.poll()
dalammain()
function.
Peraturanself.poll
fungsi mulai menjalankan, melakukan beberapa pekerjaan persiapan sebelum setiap loop.self.numTick++
meningkatkan jumlah.self.updateTrades()
memperbarui catatan perdagangan pasar terbaru dan menghitung data penggunaan yang relevan.self.updateOrderBook()
memperbarui data pesanan dan menghitung data yang relevan.self.balanceAccount()
periksa saldo uang (posisi).
Var burstPrice = self. Prices [self. Prices. Length-1] * BurstThresholdPct # Calculate Burst Price
Var bull = false # Declare a bull-marked variable, initially false
Var bear = false # Declare a bear marked variable, initially false
Var tradeAmount = 0 # Declare the transaction amount variable, initially 0
Langkah selanjutnya adalah menilai apakah pasar jangka pendek saat ini adalah bull atau bear.
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
tradeAmount = self.cny / self.bidPrice * 0.99
} 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
tradeAmount = self.btc
}
Apakah Anda ingatself.updateOrderBook()
fungsi dari artikel sebelumnya di mana kita menggunakan algoritma rata-rata tertimbang untuk membangun waktu yang tersusunprices
Tiga fungsi baru:_.min
, _.max
, danslice
digunakan dalam kode dan mudah dipahami.
· _. min
: Fungsi adalah untuk menemukan nilai minimum dalam array parameter.
· _.max
: Fungsi adalah untuk menemukan nilai maksimum dalam array parameter.
· slice
: Fungsi adalah fungsi anggota dariJavaScript
array object. It
function main() {
// index .. -8 -7 -6 -5 -4 -3 -2 -1
var arr = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
Log (arr. Slice (-5, -1)) // it will intercept the elements from 4 to 1 and return a new array: [4,3,2,1]
}
Kondisi untuk menilai pasar bear atau bull adalah:
· Pengelolaanself.numTick > 2
harus benar, yaitu, ketika putaran baru harga deteksi pecah, itu harus dipicu setelah setidaknya tiga putaran deteksi, sehingga menghindari pemicu di awal.
· Perbedaan antara data terakhir diself.prices
dari urutan harga, yaitu data terbaru, dan harga maksimum atau minimum di kisaran sebelumnya diself.prices
Array harus melebihi harga ledakan dariburstPrice
.
Jika semua kondisi benar, tandabull
ataubear
sebagai benar, dan menetapkan nilai untuk variabeltradeAmount
untuk merencanakan transaksi Stud.
Kemudian, menurutself.vol
diperbarui dan dihitung pada tahun sebelumnya.self.updateTrades()
Fungsi,BurstThresholdVol
parameter menentukan apakah untuk mengurangi intensitas transaksi (mengurangi volume transaksi yang direncanakan).
if (self.vol < BurstThresholdVol) {
TradeAmount * = self. Vol/BurstThresholdVol //Reduce the planned volume by self. Vol/BurstThresholdVol times of the previous volume
}
if (self.numTick < 5) {
TradeAmount * = 0.8 // reduced to 80% of the plan
}
If (self. NumTick < 10) { // reduce to 80% of the plan
tradeAmount *= 0.8
}
Selanjutnya, menilai apakah sinyal perdagangan dan volume memenuhi persyaratan:
If ( (!Bull && !Bear) | | tradeAmount < MinStock) { # If it is not a bull market and not a bear market, or the amount tradeAmount planned to trade is less than the minimum trading volume MinStock set by the parameter, the poll function returns without trading operations directly
return
}
Setelah putusan di atas, eksekusivar tradePrice = bull ? self.bidPrice: self.askPrice
menetapkan harga transaksi sesuai dengan apakah itu adalah pasar beruang atau pasar banteng, dan menetapkan nilai dengan harga bill of lading yang sesuai.
Akhirnya, sebuahwhile
lingkaran dimasukkan, dan satu-satunya kondisi berhenti lingkaran adalah bahwa volume perdagangan yang direncanakan daritradeAmount > = MinStock
adalah kurang dari volume perdagangan minimum.
Dalam loop, order dieksekusi sesuai dengan kondisi pasar saat ini.orderId
. Sleep(200)
menunggu selama 200 milidetik setelah menempatkan perintah dalam setiap loop.orderId
adalah benar (jika perintah gagal, ID perintah tidak akan dikembalikan, dan kondisi jika tidak akan dipicu). Jika kondisi adalah benar. Dapatkan ID perintah dan atasi keself.tradeOrderId
.
Mengisyaratkan variabelorder
digunakan untuk menyimpan data pesanan, dengan nilai awalnull
Kemudian data urutan ID diperoleh dalam loop, dan menilai apakah pesanan adalah negara pembuat, jika demikian, urutan ID dibatalkan, dan jika tidak, loop deteksi diakhiri.
Var order = null // Declare a variable to hold the order data
While (true) { // a while loop
Order = exchange. GetOrder (orderId) // Call GetOrder to query the order data whose order ID is orderId
If (order) { // If the order data is queried and the query fails and the order is null, the current if condition will not be triggered
If (order. Status = = ORDER _ STATE _ PENDING) { // Judge whether the order status is maker
Exchange. CancelOrder (orderId) // If the order is maker, cancel the order
Sleep(200)
} else { // otherwise execute break to end the current while loop
break
}
}
}
Proses berikut kemudian dilakukan:
Self. TradeOrderId = 0 // Reset self. TradeOrderId.
TradeAmount-= order. DealAmount // Update tradeAmount, subtract the quantity of the order on the bill of lading that has been completed
TradeAmount * = 0.9 //Decrease the order amount
If (order. Status = = ORDER _ STATE _ CANCELED) { // if the order is already cancelled
Self. UpdateOrderBook () // Update data such as order book
While (bull & & self. BidPrice-tradePrice > 0.1) { // In a bull market, if the updated bill of lading price exceeds the current trading price by 0.1, the trading amount will be reduced and the trading price will be adjusted slightly
tradeAmount *= 0.99
tradePrice += 0.1
}
While (bear & & self. AskPrice-tradePrice < -0.1) { // In a bear market, if the updated bill of lading price exceeds the current trading price by 0.1, the trading amount will be reduced and the trading price will be adjusted slightly
tradeAmount *= 0.99
tradePrice -= 0.1
}
}
Ketika proses program berakhir dari loop dariwhile (tradeAmount > = MinStock){...}
, itu menunjukkan bahwa pelaksanaan proses transaksi harga ini telah selesai.
Mengeksekusiself.numTick = 0
, yaitu, mengatur ulangself.numTick
ke 0.
PeraturanLeeksReaper()
Konstruktor mengembalikanself
objek pada akhir eksekusi, yaitu ketikavar reaper = LeeksReaper()
, itu dikembalikan kereaper
.
Sejauh ini, kami telah menganalisis bagaimanaLeeksReaper()
constructor membangun objek LeeksReaper, setiap metode dari objek LeeksReaper, dan proses eksekusi fungsi logika utama.