Exécution simultanée de la fonction Go enveloppée en bouteille en utilisant JavaScript pour mettre en œuvre des stratégies de quantification

Auteur:Le foin, Créé: 2019-06-29 11:24:57, Mis à jour: 2023-10-26 20:06:10

img

Dans la mise en œuvre de stratégies de quantification, dans de nombreux cas, l'exécution en parallèle peut réduire l'efficacité de l'amélioration de la latence.

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

Une fois que la requête rest API est retardée, supposons que ce soit 100 ms, alors les deux temps d'acquisition de profondeur sont en fait différents. Si plus d'accès sont nécessaires, le problème de retard sera plus important et affectera l'exécution de la stratégie.

Comme JavaScript n'a pas beaucoup de fils, la fonction Go est enveloppée en bas pour résoudre ce problème, mais elle est plus compliquée à implémenter en raison du mécanisme de conception.

var a = exchanges[0].Go("GetDepth")
var b = exchanges[1].Go("GetDepth")
var depthA = a.wait() //调用wait方法等待返回异步获取depth结果 
var depthB = b.wait()

Dans la plupart des cas simples, il n'y a pas de problème à écrire des stratégies ainsi. Mais notez que chaque cycle de stratégie doit répéter ce processus, les variables intermédiaires a et b étant en fait des auxiliaires temporaires. Si nous avons beaucoup de tâches simultanées, nous devons enregistrer une correspondance entre a et depthA, b et depthB, ce qui est plus compliqué lorsque notre tâche simultanée n'est pas certaine.

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

Nous définissons une fonction G, dont les paramètres t sont la fonction Go à exécuter, ctx est le contexte du programme d'enregistrement, et f est la fonction à l'attribution spécifique.

Dans ce cas, l'ensemble du cadre de programmation peut être écrit de manière similaire au modèle de programmation producteur-consommateur (avec quelques différences), dans lequel le producteur continue à émettre des tâches et les consommateurs les exécutent en même temps, le code étant une simple démonstration et n'impliquant pas la logique d'exécution du programme.

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

Ce qui semble être une simple fonctionnalité réalisée en un clin d'œil simplifie considérablement la complexité du code, nous ne nous soucions que de savoir quelles tâches le programme doit produire, et le programme worker () les exécute automatiquement en parallèle et renvoie les résultats correspondants.


Relationnée

Plus de

77924998Le dieu de l'herbe, peut-il faire tout Python?

RégentPour vous présenter

Le foinPython a sa propre bibliothèque de synchronisation, plus facile à utiliser que Go.