Использование JavaScript для реализации количественных стратегий и одновременное выполнение функции Go в пакете с кубиками

Автор:Трава, Создано: 2019-06-29 11:24:57, Обновлено: 2023-10-26 20:06:10

img

При реализации количественной стратегии, во многих случаях, параллельное исполнение может снизить эффективность задержки. Для примера хеджирующего робота, требующего получения глубины двух монет, код выполняется в следующем порядке:

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

При наличии задержки при одном запросе rest API, предположим, 100 мс, то время, необходимое для получения глубины дважды, фактически различается. Если требуется больше посещений, проблемы с задержкой будут более заметны, что повлияет на выполнение стратегии.

JavaScript решает эту проблему, так как у него нет много нитей, поэтому в нижнем слое встроена функция Go, но реализация более громоздкая из-за механизма проектирования.

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

В большинстве простых случаев написание такой политики без проблем. Но обратите внимание, что каждый цикл политики повторяет этот процесс, и промежуточные переменные a, b на самом деле являются временными помощниками. Если у нас очень много параллельных задач, необходимо дополнительно записать взаимоотношения между a и depthA, b и depthB, что становится более сложным, когда наша параллельная задача не определена.

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

Мы определяем функцию G, где t - это функция Go, которую мы собираемся выполнить, ctx - это контекст записи программы, f - это функция с конкретным назначением.

В этом случае общая программная структура может быть написана как аналогичная модели производителя-потребителя (с некоторыми отличиями), где производитель постоянно выпускает задачи, а потребитель выполняет их одновременно, при этом код является только демонстрацией и не затрагивает логику выполнения программы.

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

На первый взгляд, это простое выполнение одной функции, но на самом деле это значительно упрощает сложность кода. Нам нужно просто заботиться о том, какие задачи нужно создать программе, и рабочая программа автоматически выполняет их одновременно и возвращает соответствующие результаты.


Связанные

Больше

77924998Граница, может быть, весь Python

РегентСпросите о себе

ТраваPython имеет свою собственную библиотеку, которая удобнее, чем Go.