Sử dụng JavaScript để thực hiện thực thi đồng thời của chiến lược định lượng - đóng gói hàm Go

Tác giả:Lydia., Tạo: 2023-01-31 09:57:00, Cập nhật: 2023-09-18 20:10:07

img

Sử dụng JavaScript để thực hiện thực thi đồng thời của chiến lược định lượng - đóng gói hàm Go

Khi thực hiện chiến lược định lượng, thực thi đồng thời có thể làm giảm độ trễ và cải thiện hiệu quả trong nhiều trường hợp.

var depthA = exchanges[0].GetDepth()
var depthB = exchanges[1].GetDepth()

Có một sự chậm trễ trong việc yêu cầu một API nghỉ ngơi. Giả sử đó là 100ms, thời gian để có được độ sâu thực sự khác nhau. Nếu cần nhiều truy cập hơn, vấn đề chậm trễ sẽ trở nên nổi bật hơn và ảnh hưởng đến việc thực hiện chiến lược.

JavaScript không có nhiều luồng, vì vậy hàm Go được đóng gói ở phía dưới để giải quyết vấn đề này. Tuy nhiên, do cơ chế thiết kế, việc thực hiện tương đối khó khăn.

var a = exchanges[0].Go("GetDepth")
var b = exchanges[1].Go("GetDepth")
var depthA = a.wait() // Call the wait method to wait for the return of the depth result asynchronously 
var depthB = b.wait()

Trong hầu hết các trường hợp đơn giản, không có gì sai khi viết chiến lược theo cách này. Tuy nhiên, cần lưu ý rằng quá trình này nên được lặp lại cho mỗi vòng lặp chiến lược. Các biến trung gian a và b chỉ là trợ giúp tạm thời. Nếu chúng ta có nhiều nhiệm vụ đồng thời, chúng ta cần ghi lại mối quan hệ tương ứng giữa a và depthA, và b và depthB. Khi các nhiệm vụ đồng thời của chúng ta không chắc chắn, tình hình trở nên phức tạp hơn. Do đó, chúng ta muốn thực hiện một hàm: khi viết Go đồng thời, liên kết một biến cùng một lúc, và khi kết quả của hoạt động đồng thời trở lại, kết quả sẽ tự động được gán cho biến, loại bỏ biến trung gian và do đó làm cho chương trình cụ thể ngắn gọn hơn. Việc thực hiện như sau:

function G(t, ctx, f) {
    return {run:function(){
        f(t.wait(1000), ctx)
    }}
}

Chúng ta định nghĩa một hàm G, trong đó tham số t là hàm Go được thực thi, ctx là ngữ cảnh chương trình ghi, và f là hàm gán cụ thể.

Tại thời điểm này, khuôn khổ chương trình tổng thể có thể được viết tương tự như mô hình nhân viên-nhà tiêu dùng (với một số khác biệt). Nhà sản xuất tiếp tục gửi các nhiệm vụ, và người tiêu dùng thực hiện chúng đồng thời. Mã sau chỉ dành cho trình diễn, không liên quan đến logic thực thi chương trình.

var Info = [{depth:null, account:null}, {depth:null, account:null}] // If we need to obtain the depth and account of the two exchanges, more information can also be put in, such as order ID, status, etc.
var tasks = [ ] // Global list of tasks

function produce(){ // Issue various concurrent tasks
  // The logic of task generation is omitted here, for demonstration purposes only.
  tasks.push({exchange:0, ret:'depth', param:['GetDepth']})
  tasks.push({exchange:1, ret:'depth', param:['GetDepth']})
  tasks.push({exchange:0, ret:'sellID', param:['Buy', Info[0].depth.Asks[0].Price, 10]})
  tasks.push({exchange:1, ret:'buyID', param:['Sell', Info[1].depth.Bids[0].Price, 10]})
}
function worker(){
    var jobs = []
    for(var i=0;i<tasks.length;i++){
        var task = tasks[i]
        tasks.splice(i,1) // Delete executed tasks
        jobs.push(G(exchanges[task.exchange].Go.apply(this, task.param), task, function(v, task) {
                    Info[task.exchange][task.ret] = v // The v here is the return value of the concurrent Go function wait(), which can be experienced carefully.
                }))
    }
    _.each(jobs, function(t){
            t.run() // Execute all tasks concurrently here
        })
}
function main() {
    while(true){
        produce()         // Send trade orders
        worker()        // Concurrent execution
        Sleep(1000)
    }
}

Có vẻ như chỉ có một chức năng đơn giản đã được thực hiện sau khi đi vòng tròn. Trên thực tế, sự phức tạp của mã đã được đơn giản hóa rất nhiều. Chúng ta chỉ cần quan tâm đến những nhiệm vụ mà chương trình cần tạo ra. Chương trình worker))) sẽ tự động thực hiện chúng đồng thời và trả về kết quả tương ứng. Tính linh hoạt đã được cải thiện rất nhiều.


Có liên quan

Thêm nữa