Hãy tiếp tục giải thích nội dung của chương cuối cùng (https://www.fmz.com/bbs-topic/9725).
Chức năng bổ sung thứ ba:
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)
}
}
}
}
Khi người xây dựngLeeksReaper ()
xây dựng một đối tượng,balanceAccount ()
chức năng được thêm vào đối tượng cập nhật thông tin tài sản tài khoản được lưu trữ trongself.account
, nghĩa là,account
tính năng của đối tượng được xây dựng. Tính toán giá trị doanh thu và in nó theo thời gian. Sau đó, theo thông tin tài sản tài khoản mới nhất, tính toán tỷ lệ cân bằng tiền tệ điểm (cân bằng vị trí điểm), khi kích hoạt ngưỡng bù, đóng vị trí với một lệnh nhỏ, để tiền tệ (vị trí) trở lại trạng thái cân bằng. Chờ một thời gian nhất định để giao dịch, sau đó hủy tất cả các nhà sản xuất, vòng tiếp theo của việc thực hiện chức năng, nó sẽ kiểm tra số dư và thực hiện xử lý tương ứng một lần nữa.
Chúng ta hãy xem mã của hàm này câu theo câu:
Đầu tiên, câu đầu tiênvar account = exchange.GetAccount ()
tuyên bố một biến địa phươngaccount
và gọi chức năng củaexchange.GetAccount
trên giao diện FMZ API. Nhận dữ liệu mới nhất của tài khoản hiện tại và gán nó cho biếnaccount
. Sau đó đánh giá các biếnaccount
. Nếu biến lànull
(ví dụ, thời gian hết, mạng, giao diện trao đổi ngoại lệ, vv), nó sẽ trở lại (tương ứng vớiif (!account) {...}
) trực tiếp.
self.account = account
là để chỉ định các biến địa phươngaccount
đếnaccount
thuộc tính của đối tượng được xây dựng để ghi lại thông tin tài khoản mới nhất trong đối tượng được xây dựng.
Var now = new Date().getTime ()
tuyên bố một biến địa phươngnow
và kêu gọigetTime()
chức năng của đối tượng thời gian ngày của ngôn ngữ JavaScript để trả về dấu thời gian hiện tại. Đặt giá trị cho biếnnow
.
if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)){...}
xác định rằng nếu sự khác biệt giữa dấu giờ hiện tại và dấu giờ ghi lại lần cuối vượt quá tham sốCalcNet Interval * 1000
, có nghĩa là nó đã được cập nhật từ lần cuối cùng.CalcNetInterval * 1000
milliseconds (CalcNetInterval
Vì giá mua một chiếc máy được sử dụng để tính toán thu nhập, điều kiện củaself.orderBook.Bids.length > 0
cũng được định nghĩa trong điều kiện (dữ liệu sâu, phải có thông tin cấp độ hợp lệ trong danh sách thứ tự).self.PreCalc = now
được thực hiện để cập nhật biến timestamp của báo cáo được in gần đây nhấtself.preCalc
đến dấu thời gian hiện tạinow
Ở đây, phương pháp tính toán giá trị ròng được sử dụng trong số liệu thống kê lợi nhuận. Mã làvar net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks))
, tức là chuyển đổi tiền tệ thành tiền (tiền tệ theo mệnh giá mua hiện tại), sau đó thêm nó vào số tiền trong tài khoản và gán nó cho biến địa phương được khai báonet
Đánh giá xem tổng giá trị ròng hiện tại có phù hợp với tổng giá trị ròng được ghi nhận lần trước không:
if (net != self.preNet) {
self.preNet = net
LogProfit(net)
}
Nếu nó không phù hợp, nghĩa là,net! = self.preNet
là đúng, cập nhật thuộc tính củaself.preNet
được sử dụng để ghi lại giá trị ròng với biếnnet
. Sau đó in tổng net củanet
dữ liệu cho biểu đồ đường cong lợi nhuận của robot nền tảng giao dịch FMZ Quant (theLogProfit
chức năng có thể được truy vấn trong tài liệu FMZ API).
Nếu việc in thu nhập thường xuyên không được kích hoạt, tiếp tục quy trình sau để ghi lạiaccount.Stocks
(tiền tệ có sẵn trong tài khoản vãng lai) vàaccount.Balance
(tiền tệ có sẵn trong tài khoản vãng lai) trongself.BTC
vàself.CNY
. Tính toán thang điểm offset và ghi lại bài tập trongself.p
.
self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)
Các thuật toán cũng rất đơn giản, đó là để tính tỷ lệ phần trăm của giá trị hiện tại của tiền tệ đến tổng giá trị ròng của tài khoản.
Làm thế nào về đánh giá khi kích hoạt cán cân tiền (vị trí)?
Ở đây, tôi lấy 50% cộng hoặc trừ 2 điểm phần trăm như là bộ đệm, và thực hiện số dư ngoài bộ đệm, đó là nếuself.p < 0.48
, số dư tiền được kích hoạt bởi sai lệch. Nếu số tiền ít hơn, giá sẽ tăng 0,01 mỗi lần từ vị trí mua khi mở thị trường, và ba đơn đặt hàng nhỏ sẽ được sắp xếp. Tương tự, số dư tiềnself.p > 0.52
Cuối cùng, hủy tất cả các đơn đặt hàng sau khi chờ đợiSleep(BalanceTimeout)
trong một thời gian nhất định theo cài đặt tham số.
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
}
}
}
Chức năng thứ tư:
Trong phần cốt lõi của chiến lược, đây là trò chơi chính.self.poll = function(){...}
như chúng ta đã nói trong bài viết trước, trước khimain()
chức năng bắt đầu thực hiện và đi vào vô tậnwhile
vòng lặp, chúng tôi sử dụngvar reaper = LeeksReaper()
để xây dựng đối tượng leeksreaper, và sau đó thực hiện các cuộc gọi vòng lặp củareaper.poll()
trongmain()
function.
Cácself.poll
chức năng bắt đầu thực hiện, làm một số công việc chuẩn bị trước mỗi vòng lặp.self.numTick++
tăng số lượng.self.updateTrades()
cập nhật hồ sơ giao dịch thị trường gần đây và tính toán dữ liệu sử dụng có liên quan.self.updateOrderBook()
cập nhật dữ liệu đơn đặt hàng và tính toán dữ liệu có liên quan.self.balanceAccount()
kiểm tra số dư tiền (vị trí).
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
Bước tiếp theo là đánh giá xem thị trường ngắn hạn hiện tại là tăng hay giảm.
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
}
Anh có nhớself.updateOrderBook()
chức năng từ bài viết trước đây nơi chúng tôi đã sử dụng một thuật toán trung bình cân nhắc để xây dựng một thời gian sắp xếpprices
3 chức năng mới:_.min
, _.max
, vàslice
được sử dụng trong mã và chúng dễ hiểu.
· _. min
: Chức năng là tìm giá trị tối thiểu trong mảng tham số.
· _.max
: Chức năng là tìm giá trị tối đa trong mảng tham số.
· slice
: Chức năng là một chức năng thành viên củaJavaScript
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]
}
Các điều kiện để đánh giá thị trường giảm hoặc tăng là:
· Cácself.numTick > 2
phải là đúng, nghĩa là khi một vòng mới của giá phát hiện bùng nổ, nó phải được kích hoạt sau ít nhất ba vòng phát hiện, để tránh kích hoạt ngay từ đầu.
· Sự khác biệt giữa các dữ liệu cuối cùng trongself.prices
của chuỗi giá, tức là dữ liệu mới nhất, và giá tối đa hoặc tối thiểu trong phạm vi trước đó trongself.prices
mảng nên vượt quá giá nổ củaburstPrice
.
Nếu tất cả các điều kiện là đúng, đánh dấubull
hoặcbear
như là đúng, và gán một giá trị cho biếntradeAmount
để lên kế hoạch cho giao dịch Stud.
Sau đó, theoself.vol
được cập nhật và tính toán trong năm trướcself.updateTrades()
chức năng,BurstThresholdVol
tham số xác định liệu có nên giảm cường độ giao dịch (giảm khối lượng giao dịch dự kiến).
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
}
Tiếp theo, đánh giá liệu tín hiệu giao dịch và khối lượng có đáp ứng các yêu cầu không:
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
}
Sau phán quyết trên, thực thivar tradePrice = bull ? self.bidPrice: self.askPrice
Đặt giá giao dịch tùy theo đó là thị trường gấu hay thị trường tăng, và gán giá trị với giá vận chuyển tương ứng.
Cuối cùng,while
vòng lặp được nhập, và điều kiện dừng duy nhất của vòng lặp là khối lượng giao dịch dự kiến củatradeAmount > = MinStock
thấp hơn khối lượng giao dịch tối thiểu.
Trong vòng lặp, lệnh được thực hiện theo tình trạng thị trường hiện tại. và ghi lại ID lệnh trong biếnorderId
. Sleep(200)
chờ 200 mili giây sau khi đặt một lệnh trong mỗi vòng lặp.orderId
là true (nếu lệnh thất bại, ID lệnh sẽ không được trả về, và điều kiện if sẽ không được kích hoạt). Nếu điều kiện là true.self.tradeOrderId
.
Xác định một biếnorder
được sử dụng để lưu trữ dữ liệu đơn đặt hàng, với giá trị ban đầu lànull
. Sau đó dữ liệu thứ tự của ID được lấy trong một vòng lặp, và đánh giá xem lệnh là trạng thái người tạo, nếu có, lệnh của ID bị hủy bỏ, và nếu không, vòng lặp phát hiện được kết thúc.
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
}
}
}
Sau đó thực hiện quy trình sau:
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
}
}
Khi quá trình chương trình kết thúc vòng lặp củawhile (tradeAmount > = MinStock){...}
, nó cho thấy rằng việc thực hiện quá trình giao dịch giá bùng nổ này đã hoàn thành.
Thực hiệnself.numTick = 0
, đó là, thiết lập lạiself.numTick
đến 0.
CácLeeksReaper()
constructor trả về cácself
đối tượng ở cuối thực thi, đó là, khivar reaper = LeeksReaper()
, nó được trả lại choreaper
.
Cho đến nay, chúng tôi đã phân tích cáchLeeksReaper()
Tôi tin rằng bạn sẽ có một sự hiểu biết rõ ràng về quá trình thuật toán chiến lược tần số cao này sau khi đọc bài viết này.