
Apabila melaksanakan strategi kuantitatif, dalam banyak kes, pelaksanaan serentak boleh mengurangkan kependaman dan meningkatkan kecekapan. Mengambil robot lindung nilai sebagai contoh, adalah perlu untuk mendapatkan kedalaman dua syiling Kod yang dilaksanakan mengikut urutan adalah seperti berikut:
var depthA = exchanges[0].GetDepth()
var depthB = exchanges[1].GetDepth()
Terdapat kelewatan dalam meminta API rehat. Anggapkan ia adalah 100ms Maka masa untuk mendapatkan kedalaman dua kali sebenarnya berbeza Jika lebih banyak akses diperlukan, masalah kelewatan akan menjadi lebih ketara, menjejaskan pelaksanaan strategi.
Memandangkan JavaScript tidak mempunyai multi-threading, fungsi Go yang mendasari dirangkumkan untuk menyelesaikan masalah ini, tetapi disebabkan mekanisme reka bentuknya, pelaksanaannya agak rumit.
var a = exchanges[0].Go("GetDepth")
var b = exchanges[1].Go("GetDepth")
var depthA = a.wait() //调用wait方法等待返回异步获取depth结果
var depthB = b.wait()
Dalam kebanyakan kes mudah, tidak ada salahnya menulis dasar dengan cara ini. Tetapi ambil perhatian bahawa proses ini mesti diulang setiap kali gelung strategi, dan pembolehubah perantaraan a dan b sebenarnya hanya bantuan sementara. Jika kita mempunyai banyak tugas serentak, kita perlu merekodkan surat-menyurat antara a dan depthA, dan b dan depthB Apabila tugas serentak kita tidak pasti, keadaan menjadi lebih rumit. Oleh itu, kami ingin melaksanakan fungsi: apabila menulis Go concurrency, mengikat pembolehubah pada masa yang sama, dan apabila hasil larian serentak dikembalikan, hasilnya secara automatik diberikan kepada pembolehubah, dengan itu menghapuskan pembolehubah perantaraan dan menjadikan program lebih ringkas. Pelaksanaan khusus adalah seperti berikut:
function G(t, ctx, f) {
return {run:function(){
f(t.wait(1000), ctx)
}}
}
Kami mentakrifkan fungsi G, di mana parameter t ialah fungsi Go yang akan dilaksanakan, ctx ialah konteks program, dan f ialah fungsi untuk tugasan tertentu. Kita akan melihat fungsi ini beraksi sebentar lagi.
Pada ketika ini, keseluruhan rangka kerja program boleh ditulis sebagai model “pengeluar-pengguna” (dengan beberapa perbezaan Pengeluar secara berterusan mengeluarkan tugasan, dan pengguna melaksanakannya secara serentak Kod berikut hanya untuk demonstrasi dan tidak melibatkan program.
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)
}
}
Nampaknya kami hanya melaksanakan fungsi mudah selepas melalui banyak langkah, tetapi sebenarnya, kerumitan kod telah dipermudahkan. Kami hanya perlu mengambil berat tentang tugas yang perlu dihasilkan oleh program, dan pekerja (. ) program akan secara automatik melaksanakannya secara serentak dan mengembalikan hasil yang sepadan. Fleksibiliti telah banyak dipertingkatkan.