Apabila melaksanakan strategi kuantitatif, pelaksanaan serentak boleh mengurangkan latensi dan meningkatkan kecekapan dalam banyak kes.
var depthA = exchanges[0].GetDepth()
var depthB = exchanges[1].GetDepth()
Terdapat kelewatan dalam meminta API rehat. Dengan mengandaikan bahawa ia adalah 100ms, masa untuk mendapatkan kedalaman sebenarnya berbeza. Jika lebih banyak akses diperlukan, masalah kelewatan akan menjadi lebih menonjol dan mempengaruhi pelaksanaan strategi.
JavaScript tidak mempunyai multithreading, jadi fungsi Go dikapsulkan di bahagian bawah untuk menyelesaikan masalah ini.
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()
Dalam kebanyakan kes yang paling mudah, tidak ada yang salah dengan menulis strategi dengan cara ini. Walau bagaimanapun, perlu diperhatikan bahawa proses ini harus diulangi untuk setiap gelung strategi. Peubah-peubah perantara a dan b hanya bantuan sementara. Jika kita mempunyai banyak tugas serentak, kita perlu merakam hubungan yang sesuai antara a dan kedalamanA, dan b dan kedalamanB. Apabila tugas serentak kita tidak pasti, situasi menjadi lebih kompleks. Oleh itu, kita ingin melaksanakan fungsi: apabila menulis Go serentak, mengikat pemboleh ubah pada masa yang sama, dan apabila hasil operasi serentak kembali, hasilnya akan diberikan secara automatik kepada pemboleh ubah, menghapuskan pemboleh ubah perantara dan dengan itu membuat program lebih ringkas. Pelaksanaan tertentu adalah seperti berikut:
function G(t, ctx, f) {
return {run:function(){
f(t.wait(1000), ctx)
}}
}
Kita tentukan fungsi G, di mana parameter t adalah fungsi Go yang akan dijalankan, ctx adalah konteks program rakaman, dan f adalah fungsi tugasan tertentu.
Pada masa ini, kerangka kerja program keseluruhan boleh ditulis seperti yang serupa dengan model
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)
}
}
Ia seolah-olah hanya satu fungsi mudah telah dilaksanakan selepas berjalan di sekeliling bulatan. Sebenarnya, kerumitan kod telah dipermudahkan. Kita hanya perlu mengambil berat tentang apa tugas yang perlu dihasilkan oleh program. Program pekerja akan secara automatik melaksanakan mereka serentak dan mengembalikan hasil yang sepadan. Fleksibiliti telah bertambah baik banyak.