Trong thực hiện chiến lược định lượng, trong nhiều trường hợp, việc thực hiện song song có thể làm giảm hiệu quả tăng độ trì hoãn. Ví dụ như với robot đầu cơ, cần phải có được độ sâu của hai đồng xu, mã được thực hiện theo thứ tự như sau:
var depthA = exchanges[0].GetDepth()
var depthB = exchanges[1].GetDepth()
Một lần yêu cầu rest API có sự chậm trễ, giả sử là 100ms, thì hai lần lấy độ sâu thực sự không giống nhau, nếu cần nhiều truy cập hơn, vấn đề chậm trễ sẽ nổi bật hơn, ảnh hưởng đến việc thực hiện chính sách.
JavaScript không có nhiều chuỗi, do đó, hàm Go được đóng gói dưới cùng giải quyết vấn đề này, nhưng thực hiện khá khó khăn do cơ chế thiết kế.
var a = exchanges[0].Go("GetDepth")
var b = exchanges[1].Go("GetDepth")
var depthA = a.wait() //调用wait方法等待返回异步获取depth结果
var depthB = b.wait()
Trong hầu hết các trường hợp đơn giản, viết chính sách như vậy là không có vấn đề. Nhưng lưu ý rằng mỗi vòng lặp chính sách lặp lại quá trình này, các biến trung gian a, b thực sự chỉ là trợ giúp tạm thời. Nếu chúng ta có rất 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à độ sâu A, b và độ sâu B, điều này trở nên phức tạp hơn khi nhiệm vụ đồng thời của chúng ta không chắc chắn. Do đó, chúng ta muốn thực hiện một hàm: khi viết Go đồng thời, ràng buộc một biến, khi trả về kết quả chạy đồng thời, kết quả tự động gán giá trị cho biến, do đó bỏ qua các biến trung gian, làm cho chương trình ngắn gọn hơn.
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 sẽ được thực hiện, ctx là ngữ cảnh của chương trình ghi lại, f là hàm được gán cụ thể.
Trong trường hợp này, một khuôn khổ chương trình tổng thể có thể được viết giống như một mô hình sản xuất-đầu hàng (có một số khác biệt), trong đó nhà sản xuất liên tục phát hành các nhiệm vụ, người tiêu dùng thực hiện chúng cùng một lúc, và mã chỉ là một bản trình bày, không liên quan đến logic thực thi của chương trình.
var Info = [{depth:null, account:null}, {depth:null, account:null}] //加入我们需要获取两个交易所的深度和账户,跟多的信息也可以放入,如订单Id,状态等。
var tasks = [ ] //全局的任务列表
function produce(){ //下发各种并发任务
//这里省略了任务产生的逻辑,仅为演示
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) //删掉已执行的任务
jobs.push(G(exchanges[task.exchange].Go.apply(this, task.param), task, function(v, task) {
Info[task.exchange][task.ret] = v //这里的v就是并发Go函数wait()的返回值,可以仔细体会下
}))
}
_.each(jobs, function(t){
t.run() //在这里并发执行所有任务
})
}
function main() {
while(true){
produce() // 发出交易指令
worker() // 并发执行
Sleep(1000)
}
}
Có vẻ như một vòng quay chỉ thực hiện một chức năng đơn giản, thực sự đơn giản hóa rất nhiều mức độ phức tạp của mã, 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, và các chương trình worker () tự động thực hiện chúng song song và trả về kết quả tương ứng.
77924998Grasshopper, có thể có được toàn bộ Python?
Bệ hạXin giới thiệu
Cỏ nhỏPython có thư viện trình tự riêng, dễ sử dụng hơn Go.