Type/to search
8
Follow
1361
Followers
Phân tích Chiến lược thu hoạch tỏi tây (2)
HFT
Created 2020-11-16 10:03:52  Updated 2024-12-05 22:03:01
 23
 8482

img

Phân tích Chiến lược thu hoạch tỏi tây (2)

sau đóNội dung trước đógiải thích.

Chức năng bổ sung thứ ba:

python
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("开始平衡", 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("开始平衡", 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) } } } }

Người xây dựngLeeksReaper()Khi xây dựng một đối tượng, hãy thêmbalanceAccount()Chức năng này là cập nhật thông tin tài sản tài khoản được lưu trữ trongself.account, nghĩa là, đối tượng được xây dựngaccounttài sản. Tính toán và in giá trị lợi nhuận thường xuyên. Sau đó, dựa trên thông tin tài sản tài khoản mới nhất, tỷ lệ cân bằng tiền tệ giao ngay (cân bằng vị thế giao ngay) được tính toán. Khi ngưỡng độ lệch được kích hoạt, một lệnh nhỏ được đóng lại để khôi phục tiền tệ (vị thế) về trạng thái cân bằng. Chờ một khoảng thời gian nhất định để hoàn tất giao dịch, sau đó hủy tất cả các lệnh đang chờ xử lý. Vòng thực hiện tiếp theo của chức năng này sẽ kiểm tra lại số dư và thực hiện xử lý tương ứng.

Chúng ta hãy xem xét từng dòng mã của hàm này:
Câu đầu tiênvar account = exchange.GetAccount()Nó khai báo một biến cục bộaccountvà gọi giao diện API của nhà phát minhexchange.GetAccount()Chức năng, lấy dữ liệu mới nhất của tài khoản hiện tại và gán nó choaccountbiến đổi. Sau đó phán xétaccountBiến này, nếu biến lànullNếu giá trị (chẳng hạn như thời gian chờ, mạng, ngoại lệ giao diện trao đổi, v.v.) không đạt được, nó sẽ được trả về trực tiếp (tương ứng vớiif (!account){...}đây).

self.account = accountCâu này là để đặt biến cục bộaccountĐược gán cho đối tượng được xây dựngaccountThuộc tính được sử 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()Câu lệnh này khai báo một biến cục bộnowvà gọi đối tượng thời gian và ngày tháng của ngôn ngữ JavaScriptgetTime()Hàm này trả về dấu thời gian hiện tại. Giao chonowbiến đổi.

if (self.orderBook.Bids.length > 0 && now - self.preCalc > (CalcNetInterval * 1000)) {...}Mã này xác định xem sự khác biệt giữa dấu thời gian hiện tại và dấu thời gian được ghi lại gần đây nhất có vượt quá tham số hay khôngCalcNetInterval * 1000Điều này có nghĩa là từ bản cập nhật cuối cùng cho đến nay, hơnCalcNetInterval * 1000mili giây(CalcNetIntervalgiây), để đạt được chức năng in thời gian thu nhập. Vì giá của lần đấu thầu đầu tiên được sử dụng khi tính thu nhập, các điều kiện cũng giới hạnself.orderBook.Bids.length > 0Điều kiện này (dữ liệu độ sâu, phải có thông tin thiết bị hợp lệ trong danh sách lệnh mua). Khi điều kiện câu lệnh if này được kích hoạt, thực thiself.preCalc = nowCập nhật biến dấu thời gian của doanh thu in ấn gần đây nhấtself.preCalcDấu thời gian hiện tạinow. Thống kê thu nhập ở đây sử dụng phương pháp tính giá trị ròng, mã làvar net = _N(account.Balance + account.FrozenBalance + self.orderBook.Bids[0].Price * (account.Stocks + account.FrozenStocks)), tức là chuyển đổi đồng xu thành tiền (mẫu số) theo giá mua hiện tại, sau đó thêm vào số tiền trong tài khoản và gán cho biến cục bộ đã khai báonet. Xác định xem tổng giá trị ròng hiện tại có nhất quán với tổng giá trị ròng được ghi lại lần trước hay không:

python
if (net != self.preNet) { self.preNet = net LogProfit(net) }

Nếu chúng không nhất quán,net != self.preNetNếu đúng, hãy sử dụngnetCập nhật biến được sử dụng để ghi lại các thuộc tính của giá trị ròngself.preNet. Sau đó in cái nàynetDữ liệu giá trị tài sản ròng tổng thể theo biểu đồ đường cong lợi nhuận của robot nền tảng giao dịch định lượng của nhà phát minh (có thể được truy vấn trong tài liệu API FMZLogProfitchức năng này).

Nếu doanh thu in theo lịch trình không được kích hoạt, hãy tiếp tục quy trình sau.account.Stocks(số lượng tiền có sẵn trong tài khoản hiện tại),account.Balance(Số tiền hiện có trong tài khoản) được ghi lại trongself.btcself.cny. Tính toán tỷ lệ bù trừ và gán giá trị cho bản ghiself.p

python
self.p = self.btc * self.prices[self.prices.length-1] / (self.btc * self.prices[self.prices.length-1] + self.cny)

Thuật toán cũng rất đơn giản, đó là tính giá trị hiện tại của đồng tiền theo tỷ lệ phần trăm của tổng giá trị ròng của tài khoản.

Vậy làm sao chúng ta xác định được thời điểm số dư tiền (vị thế) được kích hoạt?
Tác giả sử dụng 2 điểm phần trăm trên và dưới 50% làm vùng đệm và thực hiện cân bằng vượt quá vùng đệm, nghĩa là,self.p < 0.48Độ lệch cân bằng tiền xu được kích hoạt và người ta tin rằng có ít tiền xu hơn, vì vậy hãy bắt đầu mua ở một vị trí trên thị trường và tăng giá thêm 0,01 mỗi lần và đặt ba lệnh nhỏ. Tương tự như vậy, cân bằng tiền tệself.p > 0.52, nếu bạn nghĩ mình có quá nhiều tiền, bạn có thể đặt một lệnh nhỏ bằng cách bán ở mức giá mở cửa. Cuối cùng, hãy đợi một khoảng thời gian nhất định theo các thiết lập tham sốSleep(BalanceTimeout)Mọi đơn hàng sẽ bị hủy sau đó.

python
var orders = exchange.GetOrders() # 获取当前所有挂单,存在orders变量 if (orders) { # 如果获取当前挂单数据的变量orders不为null for (var i = 0; i < orders.length; i++) { # 循环遍历orders,逐个取消订单 if (orders[i].Id != self.tradeOrderId) { exchange.CancelOrder(orders[i].Id) # 调用exchange.CancelOrder,根据orders[i].Id取消订单 } } }

Chức năng bổ sung thứ tư:

Phần cốt lõi của chiến lược, điểm nổi bật là ở đây,self.poll = function() {...}Chức năng là logic chính của toàn bộ chiến lược. Chúng tôi cũng đã nói về nó trong bài viết trước.main()Hàm bắt đầu thực thi và nhậpwhileTrước vòng lặp vô hạn, chúng ta sử dụngvar reaper = LeeksReaper()Xây dựng một đối tượng thu hoạch tỏi tây, và sau đómain()Gọi vòng lặp trong hàmreaper.poll()Đây là chức năng được gọi.

self.pollHàm này bắt đầu thực thi và thực hiện 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 mới nhất và tính toán dữ liệu có liên quan.self.updateOrderBook()Cập nhật dữ liệu sổ lệnh và tính toán dữ liệu liên quan.self.balanceAccount()Kiểm tra số dư tiền (vị trí).

python
var burstPrice = self.prices[self.prices.length-1] * BurstThresholdPct # 计算爆发价格 var bull = false # 声明牛市标记的变量,初始为假 var bear = false # 声明熊市标记的变量,初始为假 var tradeAmount = 0 # 声明交易数量变量,初始为0

Bước tiếp theo là xác định xem thị trường ngắn hạn hiện tại là tăng giá hay giảm giá.

python
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 }

Hãy nhớ, trong bài viết trướcself.updateOrderBook()chức năng, trong đó chúng ta sử dụng thuật toán trung bình có trọng số để xây dựng một chuỗi thời gian với thứ tựpricesMảng. Có ba hàm mới được sử dụng trong mã này_.min_.maxsliceBa chức năng này cũng rất dễ hiểu.

  • _.min:Chức năng của nó là tìm giá trị nhỏ nhất trong mảng tham số.

  • _.max: Chức năng của nó là tìm giá trị lớn nhất trong mảng tham số.

  • slice: Hàm này là hàm thành viên của đối tượng mảng JavaScript. Chức năng của nó là chặn một phần của mảng theo chỉ mục và trả về. Ví dụ:

    javascript
    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)) // 会截取 4 ~ 1 这几个元素,返回一个新数组:[4,3,2,1] }

    img

Các điều kiện để đánh giá gấu và bò ở đây là:

  • self.numTick > 2Để được thiết lập, điều này có nghĩa là khi một đợt giá phát hiện mới bùng phát, nó phải được kích hoạt sau ít nhất ba đợt phát hiện để tránh bị kích hoạt ngay từ đầu.
  • Dòng giáself.pricesDữ liệu cuối cùng trongself.pricesSự khác biệt giữa giá tối đa hoặc tối thiểu trong phạm vi trước đó trong mảng sẽ bị phá vỡburstPriceĐây là mức giá bùng nổ.

Nếu tất cả các điều kiện được đáp ứng, sau đó đánh dấubullhoặcbear,vìtruevà đưa ratradeAmountChỉ định các biến và lập kế hoạch giao dịch Stud.

Theo như trước đóself.updateTrades()Đã cập nhật và tính toán trong hàmself.vol, cho tham sốBurstThresholdVolQuyết định xem có nên giảm cường độ giao dịch (giảm quy mô các giao dịch đã lên kế hoạch) hay không.

python
if (self.vol < BurstThresholdVol) { tradeAmount *= self.vol / BurstThresholdVol // 缩减计划交易量,缩减为之前量的self.vol / BurstThresholdVol 倍 } if (self.numTick < 5) { tradeAmount *= 0.8 // 缩减为计划的80% } if (self.numTick < 10) { // 缩减为计划的80% tradeAmount *= 0.8 }

Tiếp theo, xác định xem tín hiệu giao dịch và khối lượng giao dịch có đáp ứng các yêu cầu hay không:

python
if ((!bull && !bear) || tradeAmount < MinStock) { # 如果非牛市并且也非熊市,或者计划交易的量tradeAmount小于参数设置的最小交易量MinStock,poll函数直接返回,不做交易操作 return }

Sau khi có phán quyết trên, thực hiệnvar tradePrice = bull ? self.bidPrice : self.askPriceThiết lập giá giao dịch theo thị trường giá xuống hay thị trường giá lên và gán giá trị theo giá vận đơn tương ứng.

Cuối cùng nhập mộtwhileĐiều kiện duy nhất để dừng vòng lặp làtradeAmount >= MinStockKhối lượng giao dịch theo kế hoạch thấp hơn khối lượng giao dịch tối thiểu.
Trong vòng lặp, các lệnh được đặt dựa trên việc thị trường hiện tại đang tăng giá hay giảm giá. Và ghi lại ID đơn hàng trong biếnorderId. Sau mỗi vòng đặt hàngSleep(200)Chờ 200 mili giây. Sau đó phán đoán trong vòng lặporderIdCó đúng không (nếu đơn hàng không thành công, ID đơn hàng 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à đúng. Lấy ID đơn hàng và chỉ định nó choself.tradeOrderId

Khai báo một biến để lưu trữ dữ liệu đơn hàngorderGiá trị ban đầu lànull. Sau đó lặp lại để lấy dữ liệu đơn hàng của ID này và xác định xem đơn hàng có đang ở trạng thái đơn hàng đang chờ xử lý hay không. Nếu đang ở trạng thái đơn hàng đang chờ xử lý, hãy hủy đơn hàng của ID này. Nếu không ở trạng thái đơn hàng đang chờ xử lý, hãy thoát khỏi trạng thái này vòng phát hiện.

pine
var order = null // 声明一个变量用于保存订单数据 while (true) { // 一个while循环 order = exchange.GetOrder(orderId) // 调用GetOrder查询订单ID为 orderId的订单数据 if (order) { // 如果查询到订单数据,查询失败order为null,不会触发当前if条件 if (order.Status == ORDER_STATE_PENDING) { // 判断订单状态是不是正在挂单中 exchange.CancelOrder(orderId) // 如果当前正在挂单,取消该订单 Sleep(200) } else { // 否则执行break跳出当前while循环 break } } }

Sau đó làm theo quy trình dưới đây:

pine
self.tradeOrderId = 0 // 重置self.tradeOrderId tradeAmount -= order.DealAmount // 更新tradeAmount,减去提单的订单已经成交的数量 tradeAmount *= 0.9 // 减小下单力度 if (order.Status == ORDER_STATE_CANCELED) { // 如果订单已经是取消了 self.updateOrderBook() // 更新订单薄等数据 while (bull && self.bidPrice - tradePrice > 0.1) { // 牛市时,更新后的提单价格超过当前交易价格0.1就减小交易力度,略微调整交易价格 tradeAmount *= 0.99 tradePrice += 0.1 } while (bear && self.askPrice - tradePrice < -0.1) { // 熊市时,更新后的提单价格超过当前交易价格0.1就减小交易力度,略微调整交易价格 tradeAmount *= 0.99 tradePrice -= 0.1 } }

Khi luồng chương trình nhảy rawhile (tradeAmount >= MinStock) {...}Chu kỳ này cho biết quá trình giao dịch bùng nổ giá đã hoàn tất.
thực hiệnself.numTick = 0, nghĩa là, thiết lập lạiself.numTicklà 0.

LeeksReaper()Cuối cùng, hàm xây dựng thực thiselfĐối tượng được trả về làvar reaper = LeeksReaper()Khi nó được trả lạireaper

Cho đến nayLeeksReaper()Chúng tôi đã phân tích cách trình xây dựng đối tượng máy gặt tỏi tây, các phương thức khác nhau của đối tượng máy gặt tỏi tây và quy trình thực hiện các hàm logic chính. Tôi tin rằng sau khi đọc bài viết này, bạn sẽ hiểu rõ hơn về tần số cao quá trình thuật toán chiến lược. hiểu.

Related Recommendations
Comment
All comments (19)

    感谢梦总。梦总,请问韭菜收割机跟草神的高频机器人两者结合的思路有没有搞头啊?

    4 years ago

    草神有篇文章讲过,高频需要有市场环境。策略而言韭菜收割机跟草神的高频机器人有思路上的共同点。

    4 years ago

    说了一堆废话。核心的一句都没讲。

    4 years ago

    实在抱歉,这个文章主要是给入门初学者讲执行流程的,讲了一堆废话确实扎眼了,您忽略就行了。

    4 years ago

    有一点不明白,为什么一定要保持币和钱的平衡,如果没有达到平衡,就得操作买和卖。之后过BalanceTimeout又取消订单,不再平衡,而是进入下一个爆发环节。

    5 years ago

    下单命令在哪里。。。

    5 years ago

    之前看的云里雾里,用了一阵FMZ,重新看了一遍。总结思路来说。这个策略的思路是:
    监控盘口价格异动,发现价格爆发,顺着趋势的方向,以交易量大小作为参照计算出梭哈百分比,进行梭哈交易。梭哈交易完以后不持仓,长期保持一个币钱平衡的状态。
    我说的对吗,梦总?嘿嘿。

    5 years ago

    great !~

    5 years ago

    请教梦总,程序不停的在平衡币和钱,这个功能出于什么考虑?去掉balanceAccount()程序会怎样发展?

    5 years ago

    原版韭菜收割机是有一个平衡模块,可以考虑去掉。具体影响不太清楚了。

    5 years ago

    感谢梦总,fmz真的是大宝库

    5 years ago

    不客气 ~

    5 years ago

    还是看不明白

    5 years ago

    ~囧~

    5 years ago

    BurstThresholdVol 这个参数是干嘛的?该怎么设置啊

    6 years ago

    爆发量,这个是策略参数,人为设置的,详细看下策略、文章,就知道这个变量控制什么了。

    6 years ago

    细节满满,看了1小时才勉强理解细节,赞

    6 years ago

    梦总666,研究明白后我能写出跟print money 一样的韭菜收割机么

    6 years ago

    原理应该是差不多吧

    6 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)