자바스크립트를 사용하여 양적 전략의 동시 실행을 구현합니다.

저자:리디아, 창작: 2023-01-31 09:57:00, 업데이트: 2023-09-18 20:10:07

img

자바스크립트를 사용하여 양적 전략의 동시 실행을 구현합니다.

양적 전략을 구현할 때, 동시 실행은 대기 시간을 줄이고 많은 경우에 효율성을 향상시킬 수 있습니다. 예를 들어 헤지 로봇을 취하면 두 동전의 깊이를 얻어야합니다. 순차적으로 실행되는 코드는 다음과 같습니다.

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

휴식 API를 요청하는 데 지연이 있습니다. 100ms라고 가정하면 깊이를 얻는 시간이 실제로 다릅니다. 더 많은 액세스가 필요한 경우 지연 문제가 더 두드러지고 전략의 구현에 영향을 미칩니다.

자바스크립트는 멀티 스레딩이 없으므로 이 문제를 해결하기 위해 아래쪽에 Go 함수가 캡슐화되어 있습니다. 그러나 설계 메커니즘으로 인해 구현은 상대적으로 번거롭습니다.

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

대부분의 간단한 경우, 이 방법으로 전략을 작성하는 데는 아무런 문제가 없습니다. 그러나 이 과정은 각 전략 루프에 대해 반복되어야 합니다. 중간 변수 a와 b는 일시적인 보조물질일 뿐입니다. 동시 작업이 많으면, a와 depthA, 그리고 b와 depthB 사이의 대응 관계를 기록해야 합니다. 우리의 동시 작업이 불확실할 때, 상황은 더 복잡해집니다. 따라서 우리는 함수를 구현하고자 합니다: Go를 동시 작성할 때, 동시에 변수를 묶고, 동시 동작의 결과가 반환될 때, 결과는 자동으로 변수에 할당되어 중간 변수를 제거하여 프로그램을 더 간결하게 만듭니다. 구체적인 구현은 다음과 같습니다:

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

원을 돌아다니면서 하나의 간단한 함수가 구현된 것 같습니다. 사실, 코드의 복잡성은 크게 단순화되었습니다. 우리는 프로그램이 생성해야 할 작업에 대해만 신경 쓸 필요가 있습니다. 작업자))) 프로그램은 자동으로 동시에 실행하고 해당 결과를 반환합니다. 유연성이 많이 향상되었습니다.


관련

더 많은