리소스 로딩... 로딩...

세계적

버전

시스템의 현재 버전 번호를 반환합니다.

현재 시스템 버전 번호3.6... 문자열

버전

function main() {
    Log("version:", Version())
}
def main():
    Log("version:", Version())
void main() {
    Log("version:", Version());
}

시스템 버전 번호는 도커의 프로그램의 버전 번호입니다.

잠자리

수면 기능, 일정 기간 동안 프로그램을 멈추게 만드는

잠자리 (밀리초)

millisecond이 매개 변수는 수면 기간과 밀리 초수를 설정하는 데 사용됩니다. 밀리초 사실 번호

function main() {
    Sleep(1000 * 10)   // Wait for 10 seconds
    Log("Waited for 10 seconds")
}
def main():
    Sleep(1000 * 10)
    Log("Waited for 10 seconds")
void main() {
    Sleep(1000 * 10);
    Log("Waited for 10 seconds");
}

예를 들어,Sleep(1000)기능, 프로그램은 1 초 동안 잠자리에있을 것입니다. 그것은 1 밀리 초 이하의 잠자리 시간, 예를 들어 설정Sleep(0.1)최소 매개 변수를 지원합니다.0.000001즉, 1나노초가1e-6밀리 초입니다. 전략 작성에 있어서Python언어,Sleep(millisecond)이 기능은 투표 간격, 대기 시간 작업에 사용되어야 합니다.time.sleep(second)기능Python's 'time도서관입니다.time.sleep(second)전략의 함수는 전략 프로그램이 백테스팅을 할 때 (백테스팅 시스템의 시간 계열을 건너뛰지 않고) 실제로 일정 기간 동안 기다리게 합니다. 따라서 전략이 매우 느리게 백테스트를 하게 됩니다.

IsVirtual

전략의 실행 환경이 백테스팅 시스템인지 여부를 결정합니다.

전략은 실제 값을 반환합니다. 예를 들어:true백테스팅 시스템 환경에서 실행될 때 전략은 잘못된 값을 반환합니다. 예를 들어:false실시간 거래 환경에서 실행될 때 bool

가상 (virtual)

function main() {
    if (IsVirtual()) {
        Log("The current backtest system environment.")
    } else {
        Log("The current live trading environment.")
    }
}
def main():
    if IsVirtual():
        Log("The current backtest system environment.")
    else:
        Log("The current live trading environment.")
void main() {
    if (IsVirtual()) {
        Log("The current backtest system environment.");
    } else {
        Log("The current live trading environment.");
    }
}

현재 실행 환경이 백테스팅 시스템인지 결정합니다. 백테스팅과 실시간 거래의 차이에 호환되도록 사용됩니다.

우편

메일 보내

성공적인 이메일 전달은 실제 값을 반환합니다. 예를 들어,true, 그리고 실패한 배달은 잘못된 값을 반환합니다. 예를 들어,false... bool

메일 ((smtp서버, smtp사용자명, smtp신호, mailTo, 제목, 본)

사용된SMTP이메일 발신자의 서비스 주소 smtp서버 사실 문자열 이메일 발신자의 이메일 주소를 지정하는 데 사용됩니다. smtp사용자명 사실 문자열 의SMTP메일 발신자의 메일박스의 비밀번호. smtpPassword 사실 문자열 이메일 수신자의 이메일 주소를 지정하는 데 사용됩니다. 메일To 사실 문자열 이메일 제목 제목 사실 문자열 이메일 본체 몸 사실 문자열

function main(){
    Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
}
def main():
    Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
void main() {
    Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body");
}

smtpPassword매개 변수SMTP메일박스 비밀번호가 아니라 설정할 때smtpServer매개 변수, 당신이 포트를 변경해야 하는 경우, 당신은 매개 변수에 직접 포트 번호를 추가 할 수 있습니다smtpServer예를 들어: QQ 메일smtp.qq.com:587, 테스트를 위해 사용할 수 있습니다. 오류가 보고되면:unencryped connection, 당신은 변경해야 합니다smtpServerMail함수입니다. 매개 변수 형식은:ssl://xxx.com:xxx예를 들어,ssl방법SMTPQQ 메일:ssl://smtp.qq.com:465또는smtp://xxx.com:xxx... 백테스팅 시스템에서는 작동하지 않습니다.

{@fun/Global/Mail_Go 메일_Go}

메일_고

비동기 버전Mail function.

Mail_Go함수는 동시 객체를 즉시 반환하고,wait메일 배달의 결과를 얻기 위해 동시 객체의 메서드를 사용한다.true, 그리고 실패한 배달은 잘못된 값을 반환합니다. 예를 들어,false... 물체

Mail_Go ((smtp서버, smtp사용자명, smtp 비밀번호, mailTo, 제목, 본체)

이 용어는SMTP이메일 발신자의 서비스 주소 smtp서버 사실 문자열 이메일 발신자의 이메일 주소를 지정하는 데 사용됩니다. smtp사용자명 사실 문자열 의SMTP메일 발신자의 메일박스의 비밀번호. smtpPassword 사실 문자열 이메일 수신자의 이메일 주소를 지정하는 데 사용됩니다. 메일To 사실 문자열 이메일 제목 제목 사실 문자열 이메일 본체 몸 사실 문자열

function main() {
    var r1 = Mail_Go("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
    var r2 = Mail_Go("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
    
    var ret1 = r1.wait()
    var ret2 = r2.wait()
    
    Log("ret1:", ret1)
    Log("ret2:", ret2)
}
# Not supported.
// Not supported.

백테스팅 시스템에서는 작동하지 않습니다.

{@fun/Global/Mail Mail}

설정 오류 필터

필터 오류 로그

SetErrorFilter (필터 설정)

정규 표현식 문자열 필터 사실 문자열

function main() {
    SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused")
}
def main():
    SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused")
void main() {
    SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused");
}

일반적인 오류를 필터링합니다.

function main() {
    // A random query for a non-existent order with an id of 123, allowing the interface to report an error deliberately
    var order = exchange.GetOrder("123")
    Log(order)
    // Filter http502 errors, GetOrder interface errors, after setting the error filter, the second call to GetOrder will no longer report errors
    SetErrorFilter("502:|GetOrder")
    order = exchange.GetOrder("123")
    Log(order)
}
def main():
    order = exchange.GetOrder("123")
    Log(order)
    SetErrorFilter("502:|GetOrder")
    order = exchange.GetOrder("123")
    Log(order)
void main() {
    TId orderId;
    Order order = exchange.GetOrder(orderId);
    Log(order);
    SetErrorFilter("502:|GetOrder");
    order = exchange.GetOrder(orderId);
    Log(order);
}

인터페이스 오류 메시지를 필터링합니다.

이 정규 표현식과 일치하는 오류 로그는 로그 시스템에 업로드되지 않습니다. 여러 필터 조건을 설정하기 위해 여러 번 호출할 수 있습니다. 여러 번 설정된 정규 표현식은 축적되어 동시에 유효합니다. 오류 로그를 필터하는 데 사용되는 정규 표현식을 다시 설정하기 위해 빈 문자열을 설정할 수 있습니다:SetErrorFilter(""). 필터 로그는 더 이상 docker 디렉토리의 라이브 거래 ID에 대응하는 데이터베이스 파일에 기록되지 않습니다. 빈번한 오류 보고가 데이터베이스 파일을 부풀어 올리는 것을 방지하기 위해.

GetPid

라이브 거래 프로세스 아이디를 얻으십시오.

라이브 거래 프로세스 ID를 반환합니다. 문자열

GetPid ((()

function main(){
    var id = GetPid()
    Log(id)
}
def main():
    id = GetPid()
    Log(id)
void main() {
    auto id = GetPid();
    Log(id);
}

GETLastError

마지막 오류 메시지가 왔어

마지막 오류 메시지 문자열

GETLastError()

function main(){
    // Because the order number 123 does not exist, so there will be an error.
    exchange.GetOrder("123")
    var error = GetLastError()
    Log(error)
}
def main():
    exchange.GetOrder("123")
    error = GetLastError()
    Log(error)
void main() {
    // Order ID type: TId, so you can't pass in a string, we place an order that doesn't meet the exchange specification to trigger
    exchange.GetOrder(exchange.Buy(1, 1));
    auto error = GetLastError();
    Log(error);
}

백테스팅 시스템에서는 작동하지 않습니다.

GetCommand

전략 상호작용 명령을 받습니다.

반환 명령어의 형식은ControlName:Data. ControlName제어물의 이름이고,Data컨트롤에 입력된 데이터입니다. 인터랙티브 컨트롤에 입력 상자, 드롭다운 상자 및 다른 구성 요소가 없다면 (예를 들어 입력 상자 없는 버튼 컨트롤) 반환 명령어 형식은ControlName, 컨트롤 이름만 반환합니다. 문자열

GetCommand (() 를 받아보세요

function main(){
    while(true) { 
        var cmd = GetCommand()
        if (cmd) { 
            Log(cmd)
        }
        Sleep(1000) 
    }
}
def main():
    while True:
        cmd = GetCommand()
        if cmd:
            Log(cmd)
        Sleep(1000)
void main() {
    while(true) {
        auto cmd = GetCommand();
        if(cmd != "") {
            Log(cmd);
        }
        Sleep(1000);
    }
}

상호 작용 명령을 감지하고Log감지될 때 상호작용 명령을 출력하는 기능

function main() {
    while (true) {
        LogStatus(_D())
        var cmd = GetCommand()
        if (cmd) {
            Log("cmd:", cmd)    
            var arr = cmd.split(":")
            if (arr[0] == "buy") {
                Log("Buy, the control without number")
            } else if (arr[0] == "sell") {
                Log("Sell, the control with the number of:", arr[1])
            } else {
                Log("Other controls trigger:", arr)
            }
        }
        Sleep(1000)
    } 
}
def main():
    while True:
        LogStatus(_D())
        cmd = GetCommand()
        if cmd:
            Log("cmd:", cmd)
            arr = cmd.split(":")
            if arr[0] == "buy":
                Log("Buy, the control without number")
            elif arr[0] == "sell":
                Log("Sell, the control with the number of:", arr[1])
            else:
                Log("Other controls trigger:", arr)
        Sleep(1000)
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
void split(const string& s,vector<string>& sv,const char flag = ' ') {
    sv.clear();
    istringstream iss(s);
    string temp;            

    while (getline(iss, temp, flag)) {
        sv.push_back(temp);
    }
    return;
}            

void main() {
    while(true) {
        LogStatus(_D());
        auto cmd = GetCommand();
        if (cmd != "") {
            vector<string> arr;
            split(cmd, arr, ':');
            if(arr[0] == "buy") {
                Log("Buy, the control without number");
            } else if (arr[0] == "sell") {
                Log("Sell, the control with the number of:", arr[1]);
            } else {
                Log("Other controls trigger:", arr);
            }
        }
        Sleep(1000);
    }
}

예를 들어, 전략 인터랙티브 컨트롤은 입력 상자가 없는 컨트롤을 추가합니다. 인터랙티브 컨트롤의 이름은:buy, 제어 설명 정보는:buy, 버튼 컨트롤입니다. 입력 상자를 가진 컨트롤을 추가하여 계속합니다. 상호 작용 컨트롤은 이름:sell그리고 제어 설명 메시지는:sell, 이것은 버튼과 입력 상자의 조합을 가진 인터랙티브 컨트롤입니다. 인터랙션 코드는 전략에서 다른 인터랙션 컨트롤에 대응하도록 설계되었습니다:

백테스팅 시스템에서는 작동하지 않습니다.

GetMeta

전략 등록 코드를 생성 할 때 메타의 값을 작성하십시오.

Meta데이터 문자열

GetMeta (메타)

function main() {
    // The maximum asset value of the denominated currency allowed by the strategy.
    var maxBaseCurrency = null
    
    // Get the metadata when creating the registration code.
    var level = GetMeta()
    
    // Detecting the conditions corresponding to Meta.
    if (level == "level1") {
        // -1 for unrestricted
        maxBaseCurrency = -1       
    } else if (level == "level2") {
        maxBaseCurrency = 10     
    } else if (level == "level3") {
        maxBaseCurrency = 1
    } else {
        maxBaseCurrency = 0.5
    }
    
    while(1) {
        Sleep(1000)
        var ticker = exchange.GetTicker()
        
        // Detect asset values
        var acc = exchange.GetAccount()
        if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks) {
            // Stop executing strategy trading logic
            LogStatus(_D(), "level:", level, "Positions exceeding the usage limit of the registration code will no longer execute the strategy trading logic!")
            continue
        }
        
        // Other trading logic
        
        // Normal output of status bar information
        LogStatus(_D(), "level:", level, "The strategy is working properly! ticker data: \n", ticker)
    }
}
def main():
    maxBaseCurrency = null
    level = GetMeta()
    
    if level == "level1":
        maxBaseCurrency = -1       
    elif level == "level2":
        maxBaseCurrency = 10     
    elif level == "level3":
        maxBaseCurrency = 1
    else:
        maxBaseCurrency = 0.5
    
    while True:
        Sleep(1000)
        ticker = exchange.GetTicker()        
        acc = exchange.GetAccount()
        if maxBaseCurrency != -1 and maxBaseCurrency < acc["Stocks"] + acc["FrozenStocks"]:
            LogStatus(_D(), "level:", level, "Positions exceeding the usage limit of the registration code will no longer execute the strategy trading logic!")
            continue        
        
        # Other trading logic
        
        # Normal output of status bar information
        LogStatus(_D(), "level:", level, "The strategy is working properly! ticker data: \n", ticker)
void main() {
    auto maxBaseCurrency = 0.0;
    auto level = GetMeta();
    
    if (level == "level1") {
        maxBaseCurrency = -1;  
    } else if (level == "level2") {
        maxBaseCurrency = 10;
    } else if (level == "level3") {
        maxBaseCurrency = 1;
    } else {
        maxBaseCurrency = 0.5;
    }
    
    while(1) {
        Sleep(1000);
        auto ticker = exchange.GetTicker();  
        auto acc = exchange.GetAccount();
        if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks) {
            // Stop execution strategy trading logic.
            LogStatus(_D(), "level:", level, "Positions exceeding the usage limit of the registration code will no longer execute the strategy trading logic!");
            continue;
        }
        
        // Other trading logic
        
        // Normal output of status bar information
        LogStatus(_D(), "level:", level, "The strategy is working properly! ticker data: \n", ticker);
    }
}

응용 시나리오 예: 사용Meta전략에 의해 운영되는 자산의 양을 제한하는 것.

적용 시나리오: 다른 전략 임대자에 대한 자본 제한을 할 필요가 있습니다.Meta등록 코드를 생성 할 때 설정된 값은 190 문자를 초과 할 수 없으며GetMeta()이 기능은 라이브 거래만 지원합니다.Meta(주) 전략 등록 코드를 생성 할 때 설정됩니다.GetMeta()함수는 null을 반환합니다. 백테스팅 시스템에서는 작동하지 않습니다.

다이얼

원시적인Socket접근, 지원tcp, udp, tls, unix프로토콜 4개의 일반적인 통신 프로토콜을 지원합니다.mqtt, nats, amqp, kafka데이터베이스 연결을 지원합니다:sqlite3, mysql, postgres, clickhouse.

Dial()함수는 시간이 끝나면 null을 반환합니다. 정상적인 호출은 세 가지 메소드를 가진 연결 객체를 반환합니다.read, write그리고close.read이 방법은 데이터를 읽기 위해 사용됩니다.write이 방법은 데이터를 전송하고close이 방법은 연결을 닫는 데 사용됩니다. 의read이 방법은 다음과 같은 매개 변수를 지원합니다.

  • 매개 변수가 전달되지 않을 때, 메시지가 사용 가능하고 반환 될 때까지 차단합니다.ws.read().
  • 매개 변수로 전달되면 단위는 밀리 초이고 메시지 대기 기간을 지정합니다. 예를 들어:ws.read(2000)2초 (2000밀리초) 의 타임아웃을 지정합니다.
  • 다음 두 개의 매개 변수는 WebSocket에만 유효합니다. 매개 변수를 전달-1함수는 메시지가 존재하거나 없더라도 즉시 반환하는 것을 의미합니다. 예를 들어:ws.read(-1)... 매개 변수를 전달-2함수는 메시지와 함께 또는 메시지가 없이 즉시 반환하지만, 최신 메시지가 반환되고 버퍼된 메시지가 폐기된다는 것을 의미합니다. 예를 들어,ws.read(-2).

read()함수 버퍼 설명: 웹소켓 프로토콜에 의해 밀어 입력 데이터는 전략 사이의 시간 간격이read()함수 호출이 너무 길다. 이 데이터는 버퍼에 저장되며, 최대 2000의 대기열의 데이터 구조를 가지고 있습니다. 2000이 초과되면 가장 새로운 데이터가 버퍼에 입력되고 가장 오래된 데이터가 삭제됩니다.

시나리오 매개 변수가 없습니다. 파라미터: -1 파라미터: -2 매개 변수: 2000 밀리 초
이미 버퍼에 있는 데이터 가장 오래된 데이터를 즉시 반환 가장 오래된 데이터를 즉시 반환 최신 데이터를 즉시 반환 가장 오래된 데이터를 즉시 반환
버퍼에 데이터가 없습니다. 데이터로 차단된 경우 반환 즉시 null을 반환합니다 즉시 null을 반환합니다 2000ms를 기다립니다. 데이터가 없다면 null을 반환합니다. 데이터가 있다면 null을 반환합니다.
웹소켓 연결이 연결이 끊어지고 또는 기본에 의해 다시 연결 read() 함수는 빈 문자열을 반환합니다. 즉: , write() 함수는 0을 반환합니다. 상황이 감지됩니다. close() 함수를 사용하여 연결을 종료할 수 있습니다. 또는 자동 재연결을 설정하면 닫을 필요가 없습니다. 기본 시스템이 자동으로 재연결합니다.

물체

전화번호 (주소) 전화 (주소, 시간)

주소 요청 주소 사실 문자열 타임아웃 초, 타임아웃 거짓 번호

function main(){
    // Dial supports tcp://,udp://,tls://,unix://protocol, you can add a parameter to specify the number of seconds for the timeout
    var client = Dial("tls://www.baidu.com:443")  
    if (client) {
        // write can be followed by a numeric parameter to specify the timeout, write returns the number of bytes successfully sent
        client.write("GET / HTTP/1.1\nConnection: Closed\n\n")
        while (true) {
            // read can be followed by a numeric parameter specifying the timeout in milliseconds. Returning null indicates an error or timeout or that the socket has been closed
            var buf = client.read()
            if (!buf) {
                 break
            }
            Log(buf)
        }
        client.close()
    }
}
def main():
    client = Dial("tls://www.baidu.com:443")
    if client:
        client.write("GET / HTTP/1.1\nConnection: Closed\n\n")
        while True:
            buf = client.read()
            if not buf:
                break
            Log(buf)
        client.close()
void main() {
    auto client = Dial("tls://www.baidu.com:443");
    if(client.Valid) {
        client.write("GET / HTTP/1.1\nConnection: Closed\n\n");
        while(true) {
            auto buf = client.read();
            if(buf == "") {
                break;
            }
            Log(buf);
        }
        client.close();
    }
}

다이얼 함수 호출 예제:

function main() {
    LogStatus("Connecting...")
    // Accessing WebSocket interface of Binance
    var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
    if (!client) {
        Log("Connection failed, program exited")
        return
    }
    
    while (true) {
        // read returns only the data retrieved after the read call
        var buf = client.read()      
        if (!buf) {
            break
        }
        var table = {
            type: 'table',
            title: 'Ticker Chart',
            cols: ['Currency', 'Highest', 'Lowest', 'Buy 1', 'Sell 1', 'Last traded price', 'Volume', 'Update time'],
            rows: []
        }
        var obj = JSON.parse(buf)
        _.each(obj, function(ticker) {
            table.rows.push([ticker.s, ticker.h, ticker.l, ticker.b, ticker.a, ticker.c, ticker.q, _D(ticker.E)])
        })
        LogStatus('`' + JSON.stringify(table) + '`')
    }
    client.close()
}
import json
def main():
    LogStatus("Connecting...")
    client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
    if not client:
        Log("Connection failed, program exited")
        return 
    
    while True:
        buf = client.read()
        if not buf:
            break
        table = {
            "type" : "table", 
            "title" : "Ticker Chart", 
            "cols" : ['Currency', 'Highest', 'Lowest', 'Buy 1', 'Sell 1', 'Last traded price', 'Volume', 'Update time'], 
            "rows" : [] 
        }
        obj = json.loads(buf)
        for i in range(len(obj)):
            table["rows"].append([obj[i]["s"], obj[i]["h"], obj[i]["l"], obj[i]["b"], obj[i]["a"], obj[i]["c"], obj[i]["q"], _D(int(obj[i]["E"]))])
        LogStatus('`' + json.dumps(table) + '`')
    client.close()
void main() {
    LogStatus("Connecting...");
    auto client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
    if(!client.Valid) {
        Log("Connection failed, program exited");
        return;
    }
    
    while(true) {
        auto buf = client.read();
        if(buf == "") {
            break;
        }
        json table = R"({
            "type" : "table", 
            "title" : "Ticker Chart", 
            "cols" : ["Currency", "Highest", "Lowest", "Buy 1", "Sell 1", "Last traded price", "Volume", "Update time"], 
            "rows" : []
        })"_json;
        json obj = json::parse(buf);
        for(auto& ele : obj.items()) {
            table["rows"].push_back({ele.value()["s"], ele.value()["h"], ele.value()["l"], ele.value()["b"], ele.value()["a"], ele.value()["c"], 
                ele.value()["q"], _D(ele.value()["E"])});
        }
        LogStatus("`" + table.dump() + "`");
    }
    client.close();
}

바이낸스의 웹소켓 틱어 인터페이스에 액세스하려면:

var ws = null 
function main(){
    var param = {
        "op": "subscribe",
        "args": [{
            "channel": "tickers",
            "instId": "BTC-USDT"
        }]
    }
    // When calling Dial function, specify reconnect=true to set reconnection mode and payload to be the message sent when reconnecting. When the WebSocket connection is disconnected, it will reconnect and send messages automatically.
    ws = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload="+ JSON.stringify(param))
    if(ws){
        var pingCyc = 1000 * 20
        var lastPingTime = new Date().getTime()
        while(true){
            var nowTime = new Date().getTime()
            var ret = ws.read()
            Log("ret:", ret)
            if(nowTime - lastPingTime > pingCyc){
                var retPing = ws.write("ping")
                lastPingTime = nowTime
                Log("Send : ping", "#FF0000")
            }
            LogStatus("Current time:", _D())
            Sleep(1000)
        }
    }
}              

function onexit() {
    ws.close() 
    Log("exit")
}
import json
import time              

ws = None
def main():
    global ws 
    param = {
        "op": "subscribe",
        "args": [{
            "channel": "tickers",
            "instId": "BTC-USDT"
        }]
    }
    ws = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload=" + json.dumps(param))
    if ws:
        pingCyc = 1000 * 20
        lastPingTime = time.time() * 1000
        while True:
            nowTime = time.time() * 1000
            ret = ws.read()
            Log("ret:", ret)
            if nowTime - lastPingTime > pingCyc:
                retPing = ws.write("ping")
                lastPingTime = nowTime
                Log("Send: ping", "#FF0000")
            LogStatus("Current time:", _D())
            Sleep(1000)              

def onexit():
    ws.close()
    Log("exit")
auto objWS = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true");              

void main() {
    json param = R"({
        "op": "subscribe",
        "args": [{
            "channel": "tickers",
            "instId": "BTC-USDT"
        }]
    })"_json;
    
    objWS.write(param.dump());
    if(objWS.Valid) {
        uint64_t pingCyc = 1000 * 20;
        uint64_t lastPingTime = Unix() * 1000;
        while(true) {
            uint64_t nowTime = Unix() * 1000;
            auto ret = objWS.read();
            Log("ret:", ret);
            if(nowTime - lastPingTime > pingCyc) {
                auto retPing = objWS.write("ping");
                lastPingTime = nowTime;
                Log("Send: ping", "#FF0000");
            }
            LogStatus("Current time:", _D());
            Sleep(1000);
        }
    }
}              

void onexit() {
    objWS.close();
    Log("exit");
}

OKX의 웹소켓 틱어 인터페이스에 액세스:

var ws = null               

function main(){
    var param = {"sub": "market.btcusdt.detail", "id": "id1"}
    ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload="+ JSON.stringify(param))
    if(ws){
        while(1){
            var ret = ws.read()
            Log("ret:", ret)
            // Respond to heartbeat packet operations
            try {
                var jsonRet = JSON.parse(ret)
                if(typeof(jsonRet.ping) == "number") {
                    var strPong = JSON.stringify({"pong" : jsonRet.ping})
                    ws.write(strPong)
                    Log("Respond to ping, send pong:", strPong, "#FF0000")
                }
            } catch(e) {
                Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
            }
            
            LogStatus("Current time:", _D())
            Sleep(1000)
        }
    }
}              

function onexit() {
    ws.close() 
    Log("Execute the ws.close() function")
}
import json
ws = None              

def main():
    global ws
    param = {"sub" : "market.btcusdt.detail", "id" : "id1"}
    ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + json.dumps(param))
    if ws:
        while True:
            ret = ws.read()
            Log("ret:", ret)              
            # Respond to heartbeat packet operations
            try:
                jsonRet = json.loads(ret)
                if "ping" in jsonRet and type(jsonRet["ping"]) == int:
                    strPong = json.dumps({"pong" : jsonRet["ping"]})
                    ws.write(strPong)
                    Log("Respond to ping, send pong:", strPong, "#FF0000")
            except Exception as e:
                Log("e:", e)
                
            LogStatus("Current time:", _D())
            Sleep(1000)
    
def onexit():
    ws.close()
    Log("Execute the ws.close() function")  
using namespace std;
void main() {
    json param = R"({"sub" : "market.btcusdt.detail", "id" : "id1"})"_json;
    auto ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + param.dump());
    if(ws.Valid) {
        while(true) {
            auto ret = ws.read();
            Log("ret:", ret);              
            // Respond to heartbeat packet operations
            try 
            {
                auto jsonRet = json::parse(ret);
                if(jsonRet["ping"].is_number()) {
                    json pong = R"({"pong" : 0})"_json;
                    pong["pong"] = jsonRet["ping"];
                    auto strPong = pong.dump();
                    ws.write(strPong);
                    Log("Respond to ping, send pong:", strPong, "#FF0000");
                }
            } catch(exception &e) 
            {
                Log("e:", e.what());
            }
            
            LogStatus("Current time:", _D());
            Sleep(1000);
        }
    }
}              

void onexit() {
    // ws.close();
    Log("Execute the ws.close() function");
}

Huobi의 웹소켓 틱어 인터페이스에 액세스:

function getLogin(pAccessKey, pSecretKey, pPassphrase) {
    // Signature function for login
    var ts = (new Date().getTime() / 1000).toString()
    var login = {
        "op": "login",
        "args":[{
            "apiKey"    : pAccessKey,
            "passphrase" : pPassphrase,
            "timestamp" : ts,
            "sign" : exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey)   // exchange.HMAC has been deprecated and is temporarily supported. Please use the latest exchange.Encode function instead.
        }]
    }    
    return login
}                

var client_private = null 
function main() {
    // Because the read function uses a timeout setting, filtering the timeout reports errors that would otherwise be output with redundant errors
    SetErrorFilter("timeout")
    
    // Position channel subscription information
    var posSubscribe = {
        "op": "subscribe",
        "args": [{
            "channel": "positions",
            "instType": "ANY"
        }]
    }                

    var accessKey = "xxx"
    var secretKey = "xxx"
    var passphrase = "xxx"            

    client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
    client_private.write(JSON.stringify(getLogin(accessKey, secretKey, passphrase)))
    Sleep(3000)  // When logging in, you cannot subscribe to private channels immediately, you need to wait for server response
    client_private.write(JSON.stringify(posSubscribe))
    if (client_private) {
        var lastPingTS = new Date().getTime()
        while (true) {
            var buf = client_private.read(-1)
            if (buf) {
                Log(buf)
            }
            
            // Detect disconnection, reconnect
            if (buf == "" && client_private.write(JSON.stringify(posSubscribe)) == 0) {
                Log("Disconnection detected, close connection, reconnect")
                client_private.close()
                client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
                client_private.write(JSON.stringify(getLogin(accessKey, secretKey, passphrase)))
                Sleep(3000)
                client_private.write(JSON.stringify(posSubscribe))
            }
            
            // Send heartbeat packets
            var nowPingTS = new Date().getTime()
            if (nowPingTS - lastPingTS > 10 * 1000) {
                client_private.write("ping")
                lastPingTS = nowPingTS
            }            
        }        
    }
}                

function onexit() {    
    var ret = client_private.close()
    Log("Close the connection!", ret)
}
import json
import time
  
def getLogin(pAccessKey, pSecretKey, pPassphrase):
    ts = str(time.time())
    login = {
        "op": "login",
        "args":[{
            "apiKey"    : pAccessKey,
            "passphrase" : pPassphrase,
            "timestamp" : ts,
            "sign" : exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey)
        }]
    }
    return login                 

client_private = None 
def main():
    global client_private
    SetErrorFilter("timeout")
    
    posSubscribe = {
        "op": "subscribe",
        "args": [{
            "channel": "positions",
            "instType": "ANY"
        }]
    }                  

    accessKey = "xxx"
    secretKey = "xxx"
    passphrase = "xxx"
    
    client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
    client_private.write(json.dumps(getLogin(accessKey, secretKey, passphrase)))
    Sleep(3000)
    client_private.write(json.dumps(posSubscribe))
    if client_private:
        lastPingTS = time.time() * 1000
        while True:
            buf = client_private.read(-1)
            if buf:
                Log(buf)
            
            if buf == "" and client_private.write(json.dumps(posSubscribe)) == 0:
                Log("Disconnection detected, close connection, reconnect")
                ret = client_private.close()
                client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
                client_private.write(json.dumps(getLogin(accessKey, secretKey, passphrase)))
                Sleep(3000)
                client_private.write(json.dumps(posSubscribe))
            
            nowPingTS = time.time() * 1000
            if nowPingTS - lastPingTS > 10 * 1000:
                client_private.write("ping")
                lastPingTS = nowPingTS                

def onexit():
    ret = client_private.close()
    Log("Close the connection!", ret)
auto client_private = Dial("wss://ws.okx.com:8443/ws/v5/private");                  

json getLogin(string pAccessKey, string pSecretKey, string pPassphrase) {
    auto ts = std::to_string(Unix());
    json login = R"({
        "op": "login",
        "args": [{
            "apiKey": "",
            "passphrase": "",
            "timestamp": "",
            "sign": ""
        }]
    })"_json;
    login["args"][0]["apiKey"] = pAccessKey;
    login["args"][0]["passphrase"] = pPassphrase;
    login["args"][0]["timestamp"] = ts;
    login["args"][0]["sign"] = exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey);
    return login;
}                  

void main() {
    SetErrorFilter("timeout");
    json posSubscribe = R"({
        "op": "subscribe",
        "args": [{
            "channel": "positions",
            "instType": "ANY"
        }]
    })"_json;
    
    auto accessKey = "xxx";
    auto secretKey = "xxx";
    auto passphrase = "xxx";
    
    client_private.write(getLogin(accessKey, secretKey, passphrase).dump());
    Sleep(3000);
    client_private.write(posSubscribe.dump());                

    if (client_private.Valid) {
        uint64_t lastPingTS = Unix() * 1000;                  

        while (true) {
            auto buf = client_private.read(-1);
            if (buf != "") {
                Log(buf);
            }
            if (buf == "") {
                if (client_private.write(posSubscribe.dump()) == 0) {
                    Log("Disconnection detected, close connection, reconnect");
                    client_private.close();
                    client_private = Dial("wss://ws.okx.com:8443/ws/v5/private");
                    client_private.write(getLogin(accessKey, secretKey, passphrase).dump());
                    Sleep(3000);
                    client_private.write(posSubscribe.dump());
                }
            }
            
            uint64_t nowPingTS = Unix() * 1000;
            if (nowPingTS - lastPingTS > 10 * 1000) {
                client_private.write("ping");
                lastPingTS = nowPingTS;
            }
        }
    }
}                  

void onexit() {
    client_private.close();
    Log("exit");
}

OKX의 웹소켓 인증 인터페이스에 액세스하려면:

var client = null 
function main() {
    // client = Dial("sqlite3://:memory:")   // Using an in-memory database
    client = Dial("sqlite3://test1.db")      // Open/connect to the database file in the docker's directory
    
    // record handle
    var sqlite3Handle = client.fd()
    Log("sqlite3Handle:", sqlite3Handle)
    
    // Querying tables in the database
    var ret = client.exec("SELECT name FROM sqlite_master WHERE type='table'")
    Log(ret)
}

function onexit() {
    Log("Execute client.close()")
    client.close()
}
// Not supported
// Not supported

데이터베이스에 연결할 때 다이얼 함수가 반환하는 연결 객체는 두 가지 고유한 메소드 함수를 가지고 있습니다.

  • exec(sqlString): SQL 명령어를 실행하는 데 사용DBExec() function.
  • fd():fd()함수는 다른 스레드가 다시 연결하기 위해 사용할 수 있는 핸들을 반환합니다. (디얼에 의해 생성된 객체가 실행에 의해 이미 닫혀있더라도)close()연결을 닫는 기능)Dial()예를 들어,Dial(handle)재사용 연결 다음은 다이얼 기능의 예를sqlite3 database.

세부 사항address매개 변수,|정상 주소 다음의 기호:wss://ws.okx.com:8443/ws/v5/public만약|매개 변수 문자열의 문자, 그리고||분기 기호로 사용됩니다. 그 다음 부분은 몇 가지 함수 매개 변수 설정입니다.&예를 들어,ss5프록시와 압축 매개 변수는 다음과 같이 함께 설정될 수 있습니다.Dial("wss://ws.okx.com:8443/ws/v5/public|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv")

다이얼 함수의 주소 매개 변수로 지원되는 함수 매개 변수 설명
웹소켓 프로토콜 데이터 압축과 관련된 매개 변수: compress=parameter value 압축은 압축 메소드, 압축 매개 변수 옵션은: gzip_raw, gzip, 등입니다. gzip 메소드가 표준 gzip이 아닌 경우 확장 메소드를 사용할 수 있습니다: gzip_raw
웹소켓 프로토콜 데이터 압축과 관련된 매개 변수: mode=parameter value 모드는 압축 모드, 모드 매개 변수는 듀얼이 될 수 있습니다. 전송, recv. 듀얼은 양방향 압축, 압축 데이터를 전송, 압축 데이터를 수신합니다. 전송은 압축 데이터를 전송합니다. recv는 압축 데이터를 수신합니다. 지역 압축 해제.
웹소켓 프로토콜은 기본 자동 재연결 관련 매개 변수를 설정합니다: reconnect=parameter value reconnect는 reconnect를 설정할 것인지, reconnect=true는 reconnect를 활성화할 것인지입니다. 이 매개 변수가 설정되지 않은 경우 기본값은 reconnect가 없습니다.
웹소켓 프로토콜은 기본 자동 재연결 관련 매개 변수를 설정합니다: interval=parameter value interval는 재시험 간격입니다. 밀리초로, interval=10000는 10초의 재시험 간격입니다. 기본값은 1초입니다.
웹소켓 프로토콜은 기본 자동 재연결 관련 매개 변수를 설정합니다: payload=parameter value payload는 웹소켓이 다시 연결될 때 보내야 하는 구독 메시지입니다. 예를 들어: payload=okokok
소크스5 프록시와 관련된 매개 변수: 프록시=파라미터 값 proxy는 ss5 proxy 설정, 매개 변수 값 형식: socks5://name:pwd@192.168.0.1:1080, 이름은 ss5 서버 사용자 이름, pwd는 ss5 서버 로그인 비밀번호, 1080는 ss5 서비스 포트입니다.

Dial()이 기능은 라이브 트레이딩에서만 지원됩니다. 다이얼 함수를 사용하여 데이터베이스에 연결할 때, 연결 문자열은 각 데이터베이스의 go 언어 드라이버 프로젝트에 참조하여 작성됩니다.

지원되는 데이터베이스 추진 프로젝트 연결 문자열 언급
스클라이트3 github.com/mattn/go-sqlite3 sqlite3://file:test.db?cache=shared&mode=memory sqlite3://전자는 sqlite3 데이터베이스가 사용되고 있음을 나타냅니다. 예를 들어 호출:Dial("sqlite3://test1.db")
mysql github.com/go-sql-driver/mysql mysql://username:yourpassword@tcp(localhost:3306) / 당신의 데이터베이스?차르셋=utf8mb4
포스트그레스 github.com/lib/pq postgres://user=postgres dbname=yourdatabase sslmode=disable password=yourpassword 호스트=localhost 포트=5432
클릭하우스 github.com/ClickHouse/clickhouse-go clickhouse://tcp://host:9000?username=username&password=yourpassword&database=youdatabase

참고로,payload내용address매개 변수는 문자를 포함합니다.=또는 다른 특수 문자, 그것은 분석에 영향을 미칠 수 있습니다address매개 변수Dial다음 예시처럼

backPack Exchange 웹소켓 개인 인터페이스 호출 예제:

var client = null

function main() {
    // Base64-encoded public key of the key pair, i.e. the access key configured on FMZ
    var base64ApiKey = "xxx"

    var ts = String(new Date().getTime())
    var data = "instruction=subscribe&timestamp=" + ts + "&window=5000"

    // Since signEd25519 returns a base64 encoding, it contains the character "="
    var signature = signEd25519(data)
    
    // The payload may contain the character "=" after being encoded by JSON
    payload = {
        "method": "SUBSCRIBE",
        "params": ["account.orderUpdate"],
        "signature": [base64ApiKey, signature, ts, "5000"]
    }

    client = Dial("wss://ws.backpack.exchange")
    client.write(JSON.stringify(payload))
    if (!client) {
        Log("Connection failed, program exited")
        return
    }
    
    while (true) {
        var buf = client.read()      
        Log(buf)
    }    
}

function onexit() {
    client.close()
}

function signEd25519(data) {
    return exchange.Encode("ed25519.seed", "raw", "base64", data, "base64", "{{secretkey}}")
}

코드의 다음 호출은 잘 작동합니다.

client = Dial("wss://ws.backpack.exchange")
client.write(JSON.stringify(payload))

만약 당신이 그것을 직접payload, 그것은 제대로 작동하지 않습니다, 예를 들어:

client = Dial("wss://ws.backpack.exchange|payload=" + JSON.stringify(payload))

현재 자바스크립트만이mqtt, nats, amqp, 그리고kafka다이얼 함수에서 통신 프로토콜. 자바스크립트 언어 전략 코드는 네 개의 프로토콜의 사용을 보여주는 예로 사용됩니다.mqtt, nats, amqp, 그리고kafka:

// We need to configure and deploy proxy servers for each protocol first.
// For the sake of demonstration, the subscription (read operation) and publishing (write operation) of the topic test_topic are all performed in the current strategy.
var arrConn = []
var arrName = []

function main() {
    LogReset(1)
    conn_nats = Dial("nats://admin@127.0.0.1:4222?topic=test_topic")
    conn_mqtt = Dial("mqtt://127.0.0.1:1883?topic=test_topic")
    conn_amqp = Dial("amqp://q:admin@127.0.0.1:5672/?queue=test_Queue")
    conn_kafka = Dial("kafka://localhost:9092/test_topic")
    arrConn = [conn_nats, conn_amqp, conn_mqtt, conn_kafka]
    arrName = ["nats", "amqp", "mqtt", "kafka"]

    while (true) {
        for (var i in arrConn) {
            var conn = arrConn[i]
            var name = arrName[i]

            // Write data
            conn.write(name + ", time: " + _D() + ", test msg.")
            
            // Read data
            var readMsg = conn.read(1000)
            Log(name + " readMsg: ", readMsg, "#FF0000")
        }

        Sleep(1000)
    }
}

function onexit() {
    for (var i in arrConn) {
        arrConn[i].close()
        Log("close", arrName[i], "connect")
    }
}

자세한 문서 참조:FMZ를 탐구: 라이브 거래 전략 사이의 통신 프로토콜의 연습

HttpQuery

Http 요청을 보내십시오.

요청의 응답 데이터를 반환합니다. 반환 값이 a인 경우JSON문자열, 그것은 분석 될 수 있습니다JSON.parse()기능JavaScript언어 전략,json::parse()기능C++언어 전략. 디버그는 옵션 구조에서 true로 설정되면 반환 값은 객체 (JSON); 디버그는 false로 설정되면 반환 값은 문자열입니다. 문자열, 대상

HttpQuery (URL) HttpQuery (URL, 옵션)

Http 요청 URL url 사실 문자열 예를 들어, HTTP 요청 관련 설정은 다음과 같이 구성될 수 있습니다.

{
    method: "POST",
    body: "a=10&b=20&c=30",
    charset: "UTF-8",
    cookie: "session_id=12345; lang=en",
    profile: "chrome_103",
    debug: false,
    headers: {"TEST-HTTP-QUERY": "123"},
    timeout: 1000
}
  • 프로파일: 브라우저 시뮬레이션을 위해 사용됩니다.tls지문 지원된 설정에는 다음 옵션이 포함됩니다. chrome_:"chrome_103", "chrome_104", "chrome_105", "chrome_106", "chrome_107", "chrome_108", "chrome_109", "chrome_110", "chrome_111", "chrome_112", "chrome_117", 사파리:"safari_15_6_1", "safari_16_0", "safari_ipad_15_6", "safari_ios_15_5", "safari_ios_15_6", "safari_ios_16_0", firefox_:"firefox_102", "firefox_104", "firefox_105", "firefox_106", "firefox_108", "firefox_110", "firefox_117", 오페라:"opera_89", "opera_90", "opera_91", 젤란도"zalando_android_mobile", "zalando_ios_mobile", 나이키:"nike_ios_mobile", "nike_android_mobile", 클라우드 크래퍼:"cloudscraper", mms_:"mms_ios", mesh_:"mesh_ios", "mesh_ios_1", "mesh_ios_2", "mesh_android", "mesh_android_1", "mesh_android_2", 확인된 것"confirmed_ios", "confirmed_android", 좋아요."okhttp4_android_7", "okhttp4_android_8", "okhttp4_android_9", "okhttp4_android_10", "okhttp4_android_11", "okhttp4_android_12", "okhttp4_android_13",
  • 디버그:true, 그HttpQuery함수 호출은 전체 응답 메시지를 반환합니다.false, 단지 데이터Body응답 메시지가 반환됩니다.
  • 타임아웃: 타임아웃 설정, 설정 1000은 1초의 타임아웃을 의미합니다.
  • Charset: GB18030과 같은 요청 응답 데이터의 트랜스코딩을 지원합니다. 일반적인 코딩을 지원합니다. 이 구조의 모든 필드는 선택적입니다. 예를 들어,profile이 분야는 방치될 수 있습니다.

옵션 거짓 물체

function main(){
    // An example of GET access without parameters
    var info = JSON.parse(HttpQuery("https://www.okx.com/api/v5/public/time"))
    Log(info)
    // An example of GET access with parameters
    var ticker = JSON.parse(HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT"))
    Log(ticker)
}
import json
import urllib.request
def main():
    # HttpQuery does not support Python, you can use the urllib/urllib2 library instead
    info = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/public/time").read().decode('utf-8'))
    Log(info)
    ticker = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/market/books?instId=BTC-USDT").read().decode('utf-8'))
    Log(ticker)
void main() {
    auto info = json::parse(HttpQuery("https://www.okx.com/api/v5/public/time"));
    Log(info);
    auto ticker = json::parse(HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT"));
    Log(ticker);
}

OKX 공개 틱어 API 인터페이스에 액세스하는 예제.

function main() {
    // Setting proxy and sending an http request for this time, no username, no password, this http request will be sent through the proxy
    HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/")            

    // Setting proxy and sending an http request for this time, enter the user name and password, only the current call to HttpQuery takes effect, and then call HttpQuery again ("http://www.baidu.com") so that the proxy will not be used.
    HttpQuery("socks5://username:password@127.0.0.1:8889/http://www.baidu.com/")
}
# HttpQuery does not support Python, you can use the urllib/urllib2 library instead
void main() {
    HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/");
    HttpQuery("socks5://username:password@127.0.0.1:8889/http://www.baidu.com/");
}

HttpQuery 함수는 프록시 설정을 사용합니다.

HttpQuery()기능만 지원합니다JavaScript, C++언어Python언어를 사용할 수 있습니다urllibHttp 요청을 직접 전송할 수 있습니다.HttpQuery()주로 시그니처 정보와 같은 공개 인터페이스와 같이 서명이 필요하지 않은 교환의 인터페이스에 액세스하는 데 사용됩니다.HttpQuery()백테스팅 시스템에서 요청을 보내기 위해 사용할 수 있습니다.GET백테스팅은 20번의 방문으로 제한됩니다.URLs, 그리고HttpQuery()방문은 데이터를 캐시합니다.URL두 번째 접속이 되면,HttpQuery()함수는 캐시된 데이터를 반환하고 더 이상 실제 네트워크 요청이 발생하지 않습니다.

{@fun/Global/HttpQuery_Go HttpQuery_Go}

HttpQuery_Go

HTTP 요청을 보내기 위해,HttpQuery function.

HttpQuery_Go()이 함수는 Http 요청의 결과를 얻기 위해 사용할 수 있는 동시 객체를 즉시 반환합니다.wait의 방법JSON.parse()함수를 사용할 수 있습니다JSON.parse()기능JavaScript언어의 전략
물체

HttpQuery_Go (URL) HttpQuery_Go (URL, 옵션)

Http 요청 URL url 사실 문자열 예를 들어, HTTP 요청 관련 설정은 다음과 같이 구성될 수 있습니다.

{
    method: "POST",
    body: "a=10&b=20&c=30",
    charset: "UTF-8",
    cookie: "session_id=12345; lang=en",
    // profile: "",
    debug: false,
    headers: {"TEST-HTTP-QUERY": "123"},
    timeout: 1000
}
  • 프로파일: 브라우저 시뮬레이션을 위해 사용됩니다.tls fingerprints.
  • 디버그:trueHttpQuery_Go함수 호출은 전체 응답 메시지를 반환합니다.false, 단지 데이터Body응답 메시지가 반환됩니다.
  • 타임아웃: 타임아웃 설정, 설정 1000은 1초의 타임아웃을 의미합니다. 이 구조의 모든 필드는 선택적입니다. 예를 들어,profile이 분야는 방치될 수 있습니다.

옵션 거짓 물체

function main() {
    // Create the first asynchronous thread
    var r1 = HttpQuery_Go("https://www.okx.com/api/v5/market/tickers?instType=SPOT")
    // Create the second asynchronous thread
    var r2 = HttpQuery_Go("https://api.huobi.pro/market/tickers")
    
    // Get the return value of the first asynchronous thread call
    var tickers1 = r1.wait()
    // Get the return value of the second asynchronous thread call
    var tickers2 = r2.wait()
    
    // Print results
    Log("tickers1:", tickers1)
    Log("tickers2:", tickers2)
}
# Not supported
// Not supported

종합적인 틱어 데이터에 대한 거래소의 공개 인터페이스에 비동기 액세스.

HttpQuery_Go()기능만 지원합니다JavaScript, 그Python언어는urllibHttp 요청을 직접 전송할 수 있습니다.HttpQuery_Go()주로 교환에 서명이 필요하지 않은 인터페이스에 액세스하는 데 사용됩니다.HttpQuery_Go기능은 백테스팅 시스템에서 지원되지 않습니다.

{@fun/Global/HttpQuery HttpQuery}

코딩

이 함수는 입력된 매개 변수에 따라 데이터를 암호화합니다.

Encode이 함수는 암호화와 암호화 후에 데이터를 반환합니다. 문자열

엔코드 (algo, inputFormat, outputFormat, data) 엔코드 (algo, inputFormat, outputFormat, data, key)

매개 변수algo은 암호화 계산에 사용되는 알고리즘입니다. 지원 설정은:raw(알고리즘이 사용되지 않습니다), "표지", signTx, md4, md5, sha256, sha512, sha1, keccak256, sha3.224, sha3.256, sha3.384, sha3.512, sha3.keccak256, sha3.keccak512, sha512.384, sha512.256, sha512.224, ripemd160, blake2b.256, 2b.512, blake2s.128, blake2s.256 파라미터.algo또한: text.encoder.utf8, text.decoder.utf8, text.encoder.gbk, text.decoder.gbk, 인코딩 및 디코딩 문자열을 지원합니다. 매개 변수algo또한: ed25519 알고리즘을 지원합니다. 예를 들어 매개 변수algoed25519.md5, ed25519.sha512 등으로 쓸 수 있습니다.ed25519.seed계산 뭔가 사실 문자열 데이터 형식을 지정하는 데 사용됩니다.data매개 변수inputFormat매개 변수는 다음 중 하나로 설정할 수 있습니다:raw, hex, base64, string.raw은 데이터가 원료이고, hex은 데이터가hex암호화된 경우, base64는 데이터가base64암호화된 것이고, string은 데이터가 문자열이라는 것을 의미합니다. 입력형식 사실 문자열 출력 데이터 형식을 지정하는 데 사용됩니다.outputFormat매개 변수는 다음 중 하나로 설정할 수 있습니다:raw, hex, base64, string.raw은 데이터가 원료이고, hex은 데이터가hex암호화된 경우, base64는 데이터가base64암호화된 것이고, string은 데이터가 문자열이라는 것을 의미합니다. outputFormat 사실 문자열 매개 변수data처리해야 할 데이터입니다. 데이터 사실 문자열 데이터 형식을 지정하는 데 사용됩니다.key매개 변수key매개 변수는 다음 중 하나로 설정할 수 있습니다:raw, hex, base64, string.raw은 데이터가 원료이고, hex은 데이터가hex암호화된 경우, base64는 데이터가base64암호화된 것이고, string은 데이터가 문자열이라는 것을 의미합니다. 키포맷 거짓 문자열 매개 변수key비밀 키는HMAC암호화, 매개 변수key매개 변수algo설정되어 있습니다sign또는signTx.key매개 변수는 사용되지 않습니다HMAC암호화algo매개 변수는 raw로 설정됩니다 (HMAC 암호화에 대한 알고리즘이 지정되어야하기 때문입니다). 키 거짓 문자열

function main() {
    Log(Encode("raw", "raw", "hex", "example", "raw", "123"))            // 6578616d706c65
    Log(Encode("raw", "raw", "hex", "example"))                          // 6578616d706c65
    Log(Encode("sha256", "raw", "hex", "example", "raw", "123"))         // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
    Log(Encode("sha256", "raw", "hex", "example", "", "123"))            // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
    Log(Encode("sha256", "raw", "hex", "example", null, "123"))          // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
    Log(Encode("sha256", "raw", "hex", "example", "string", "123"))      // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
    
    Log(Encode("raw", "raw", "hex", "123"))           // 313233
    Log(Encode("raw", "raw", "base64", "123"))        // MTIz
    
    Log(Encode("sha256", "raw", "hex", "example", "hex", "313233"))      // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
    Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz"))     // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
}
def main():
    Log(Encode("raw", "raw", "hex", "example", "raw", "123"))            # 6578616d706c65
    Log(Encode("raw", "raw", "hex", "example", "", ""))                  # 6578616d706c65
    Log(Encode("sha256", "raw", "hex", "example", "raw", "123"))         # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
    Log(Encode("sha256", "raw", "hex", "example", "", "123"))            # 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c            

    Log(Encode("sha256", "raw", "hex", "example", "string", "123"))      # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
    
    Log(Encode("raw", "raw", "hex", "123", "", ""))           # 313233
    Log(Encode("raw", "raw", "base64", "123", "", ""))        # MTIz
    
    Log(Encode("sha256", "raw", "hex", "example", "hex", "313233"))      # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
    Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz"))     # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
void main() {
    Log(Encode("raw", "raw", "hex", "example", "raw", "123"));            // 6578616d706c65
    Log(Encode("raw", "raw", "hex", "example"));                          // 6578616d706c65
    Log(Encode("sha256", "raw", "hex", "example", "raw", "123"));         // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
    Log(Encode("sha256", "raw", "hex", "example", "", "123"));            // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c            

    Log(Encode("sha256", "raw", "hex", "example", "string", "123"));      // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
                
    Log(Encode("raw", "raw", "hex", "123"));           // 313233
    Log(Encode("raw", "raw", "base64", "123"));        // MTIz
                
    Log(Encode("sha256", "raw", "hex", "example", "hex", "313233"));      // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
    Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz"));     // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
}

엑코드 함수 호출 예제

function main(){
    var ret1 = Encode("text.encoder.utf8", "raw", "hex", "hello")     // e4bda0e5a5bd
    Log(ret1)    
    var ret2 = Encode("text.decoder.utf8", "hex", "string", ret1)   
    Log(ret2)            

    var ret3 = Encode("text.encoder.gbk", "raw", "hex", "hello")      // c4e3bac3
    Log(ret3)
    var ret4 = Encode("text.decoder.gbk", "hex", "string", ret3)
    Log(ret4)
}
def main():
    ret1 = Encode("text.encoder.utf8", "raw", "hex", "hello", "", "")     # e4bda0e5a5bd
    Log(ret1)    
    ret2 = Encode("text.decoder.utf8", "hex", "string", ret1, "", "")   
    Log(ret2)            

    ret3 = Encode("text.encoder.gbk", "raw", "hex", "hello", "", "")      # c4e3bac3
    Log(ret3)
    ret4 = Encode("text.decoder.gbk", "hex", "string", ret3, "", "")
    Log(ret4)
void main(){
    auto ret1 = Encode("text.encoder.utf8", "raw", "hex", "hello");     // e4bda0e5a5bd
    Log(ret1);    
    auto ret2 = Encode("text.decoder.utf8", "hex", "string", ret1);   
    Log(ret2);            

    auto ret3 = Encode("text.encoder.gbk", "raw", "hex", "hello");      // c4e3bac3
    Log(ret3);
    auto ret4 = Encode("text.decoder.gbk", "hex", "string", ret3);
    Log(ret4);
}

매개 변수algo또한: text.encoder.utf8, text.decoder.utf8, text.encoder.gbk, text.decoder.gbk를 지원하여 문자열을 암호화 및 디코딩합니다.

Encode()이 기능은 라이브 거래에만 지원됩니다.key그리고keyFormat매개 변수가 통과되지 않는 경우key암호화가 사용되지 않습니다.

유닉스나노

현재 순간의 나노초 시간표를 얻으십시오.

UnixNano()이 함수는 나노초 시간표를 반환합니다. 번호

유닉스나노 (UNIXNANO))

function main() {
    var time = UnixNano() / 1000000
    Log(_N(time, 0))
}
def main():
    time = UnixNano()
    Log(time)
void main() {
    auto time = UnixNano();
    Log(time);
}

밀리초 시간표를 얻으려면 다음 코드를 사용할 수 있습니다.

{@fun/Global/Unix UNIX}

유닉스

현재 순간의 시간표를 2층에서 가져와

두 번째 레벨의 시간표를 반환합니다. 번호

유닉스 ((()

function main() {
    var t = Unix()
    Log(t)
}
def main():
    t = Unix()
    Log(t)
void main() {
    auto t = Unix();
    Log(t);
}

{@fun/Global/UnixNano 유닉스나노}

GetOS

도커가 있는 장치의 시스템 정보를 얻으십시오.

시스템 정보 문자열

GetOS()

function main() {
    Log("GetOS:", GetOS())
}
def main():
    Log("GetOS:", GetOS())
void main() {
    Log("GetOS:", GetOS());
}

예를 들어,GetOS()도커에서 실행되는 함수맥 OS운영 체제가 반환 할 수 있습니다:darwin/amd64왜냐하면 애플 컴퓨터는 여러 하드웨어 아키텍처를 가지고 있기 때문입니다.darwin의 이름입니다맥 OS system.

MD5

매개 변수의 MD5 해시를 계산합니다.data.

MD5 해시 값 문자열

MD5 (데이터)

MD5 계산이 필요한 데이터입니다. 데이터 사실 문자열

function main() {
    Log("MD5", MD5("hello world"))
}
def main():
    Log("MD5", MD5("hello world"))
void main() {
    Log("MD5", MD5("hello world"));
}

전화MD5("hello world")함수, 반환 값은:5eb63bbbe01eeed093cb22bb8f5acdc3.

{@fun/Global/Encode Encode}

DBExec

데이터베이스 인터페이스 기능

a의 실행 결과를 포함하는 객체sql예를 들어,


{"columns":["TS","HIGH","OPEN","LOW","CLOSE","VOLUME"],"values":[[1518970320000,100,99.1,90,100,12345.6]]}

물체

DBExec ((sql)

sql명령어 문자열 sql 사실 문자열

function main() {
    var strSql = [
        ":CREATE TABLE TEST_TABLE(", 
        "TS INT PRIMARY KEY NOT NULL,",
        "HIGH REAL NOT NULL,", 
        "OPEN REAL NOT NULL,", 
        "LOW REAL NOT NULL,", 
        "CLOSE REAL NOT NULL,", 
        "VOLUME REAL NOT NULL)"
    ].join("")
    var ret = DBExec(strSql)
    Log(ret)
    
    // Add a piece of data
    Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
    
    // Query data
    Log(DBExec(":SELECT * FROM TEST_TABLE;"))
}
def main():
    arr = [
        ":CREATE TABLE TEST_TABLE(", 
        "TS INT PRIMARY KEY NOT NULL,",
        "HIGH REAL NOT NULL,", 
        "OPEN REAL NOT NULL,", 
        "LOW REAL NOT NULL,", 
        "CLOSE REAL NOT NULL,", 
        "VOLUME REAL NOT NULL)"
    ]
    strSql = ""
    for i in range(len(arr)):
        strSql += arr[i]
    ret = DBExec(strSql)
    Log(ret)
    
    # Add a piece of data
    Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
    
    # Query data
    Log(DBExec(":SELECT * FROM TEST_TABLE;"))
void main() {
    string strSql = ":CREATE TABLE TEST_TABLE(\
        TS INT PRIMARY KEY NOT NULL,\
        HIGH REAL NOT NULL,\
        OPEN REAL NOT NULL,\
        LOW REAL NOT NULL,\
        CLOSE REAL NOT NULL,\
        VOLUME REAL NOT NULL)";
    auto ret = DBExec(strSql);
    Log(ret);
    
    // Add a piece of data
    Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"));
    
    // Query data
    Log(DBExec(":SELECT * FROM TEST_TABLE;"));
}

메모리 데이터베이스 지원,DBExec기능 매개 변수, 만약sql문장 시작:이 경우 메모리에 있는 데이터베이스에서 동작할 수 있습니다. 파일 쓰기 없이도 더 빨라집니다.

function main() {
    var strSql = [
        "CREATE TABLE TEST_TABLE(", 
        "TS INT PRIMARY KEY NOT NULL,",
        "HIGH REAL NOT NULL,", 
        "OPEN REAL NOT NULL,", 
        "LOW REAL NOT NULL,", 
        "CLOSE REAL NOT NULL,", 
        "VOLUME REAL NOT NULL)"
    ].join("")
    var ret = DBExec(strSql)
    Log(ret)
}
def main():
    arr = [
        "CREATE TABLE TEST_TABLE(", 
        "TS INT PRIMARY KEY NOT NULL,",
        "HIGH REAL NOT NULL,", 
        "OPEN REAL NOT NULL,", 
        "LOW REAL NOT NULL,", 
        "CLOSE REAL NOT NULL,", 
        "VOLUME REAL NOT NULL)"
    ]
    strSql = ""
    for i in range(len(arr)):
        strSql += arr[i]
    ret = DBExec(strSql)
    Log(ret)
void main() {
    string strSql = "CREATE TABLE TEST_TABLE(\
        TS INT PRIMARY KEY NOT NULL,\
        HIGH REAL NOT NULL,\
        OPEN REAL NOT NULL,\
        LOW REAL NOT NULL,\
        CLOSE REAL NOT NULL,\
        VOLUME REAL NOT NULL)";
    auto ret = DBExec(strSql);
    Log(ret);
}

테이블을 만들어

function main() {
    var strSql = [
        "CREATE TABLE TEST_TABLE(", 
        "TS INT PRIMARY KEY NOT NULL,",
        "HIGH REAL NOT NULL,", 
        "OPEN REAL NOT NULL,", 
        "LOW REAL NOT NULL,", 
        "CLOSE REAL NOT NULL,", 
        "VOLUME REAL NOT NULL)"
    ].join("")
    Log(DBExec(strSql))
    
    // Add a piece of data
    Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
    
    // Query data
    Log(DBExec("SELECT * FROM TEST_TABLE;"))
    
    // Modify data
    Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))    
    
    // Delete data
    Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110))
}
def main():
    arr = [
        "CREATE TABLE TEST_TABLE(", 
        "TS INT PRIMARY KEY NOT NULL,",
        "HIGH REAL NOT NULL,", 
        "OPEN REAL NOT NULL,", 
        "LOW REAL NOT NULL,", 
        "CLOSE REAL NOT NULL,", 
        "VOLUME REAL NOT NULL)"
    ]
    strSql = ""
    for i in range(len(arr)):
        strSql += arr[i]
    Log(DBExec(strSql))
    
    # Add a piece of data
    Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
    
    # Query data
    Log(DBExec("SELECT * FROM TEST_TABLE;"))
    
    # Modify data
    Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))
    
    # Delete data
    Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110))
void main() {
    string strSql = "CREATE TABLE TEST_TABLE(\
        TS INT PRIMARY KEY NOT NULL,\
        HIGH REAL NOT NULL,\
        OPEN REAL NOT NULL,\
        LOW REAL NOT NULL,\
        CLOSE REAL NOT NULL,\
        VOLUME REAL NOT NULL)";
    Log(DBExec(strSql));            

    // Add a piece of data
    Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"));
    
    // Query data
    Log(DBExec("SELECT * FROM TEST_TABLE;"));
    
    // Modify data
    Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000));
    
    // Delete data
    Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110));
}

테이블에 레코드를 추가, 삭제, 확인 및 변경.

기능DBExec()라이브 거래 데이터베이스 (SQLite 데이터베이스) 를 패러미터를 전달하여 작동 할 수 있습니다. 라이브 거래 데이터베이스에서 데이터 추가, 삭제, 확인 및 변경 작업을 실현, 지원SQLite문법. 시스템 라이브 거래 데이터베이스에 테이블을 예약:kvdb, cfg, log, profit, chart이 테이블에서 작업하지 마십시오.거래지원되지 않으며 시스템에서 충돌을 일으킬 수 있는 그러한 작업을 수행하는 것은 권장되지 않습니다.DBExec()이 기능은 라이브 트레이딩에서만 지원됩니다.

#############

UUID

UUID를 생성합니다.

32비트 UUID 문자열

UUID (()

function main() {
    var uuid1 = UUID()
    var uuid2 = UUID()
    Log(uuid1, uuid2)
}
def main():
    uuid1 = UUID()
    uuid2 = UUID()
    Log(uuid1, uuid2)
void main() {
    auto uuid1 = UUID();
    auto uuid2 = UUID();
    Log(uuid1, uuid2);
}

UUID()이 기능은 라이브 거래만 지원합니다.

이벤트 루프

사건에 대한 귀를 기울이고, 그것은 어떤 경우에 돌아옵니다WebSocket가독 가능한 데이터 또는 동시에 수행되는 작업,exchange.Go(), HttpQuery_Go(), 등이 완료됩니다.

반환 객체가 null 값이 아니라면,Event반환 컨텐츠에 포함된 것은 이벤트 트리거 타입입니다. 예를 들어 다음 반환 값 구조:

{"Seq":1,"Event":"Exchange_GetTrades","ThreadId":0,"Index":3,"Nano":1682068771309583400}

물체

이벤트 루프 ((() 이벤트 루프 (타임아웃)

매개 변수timeout타임아웃 설정, 밀리초입니다.timeout0로 설정된 경우 이벤트가 발생하기 전에 발생을 기다립니다. 0보다 크면 타임아웃을 기다리도록 설정하고 0보다 작으면 가장 최근의 이벤트를 즉시 반환합니다. 타임아웃 거짓 번호

function main() {
    var routine_getTicker = exchange.Go("GetTicker")
    var routine_getDepth = exchange.Go("GetDepth")
    var routine_getTrades = exchange.Go("GetTrades")
    
    // Sleep(2000), if the Sleep statement is used here, it will cause the subsequent EventLoop function to miss the previous events, because after waiting for 2 seconds, the concurrent function has received the data, and the subsequent EventLoop listening mechanism started, it misses these events.
    // These events will not be missed unless EventLoop(-1) is called at the beginning of the first line of code to first initialize the EventLoop's listening mechanism.            

    // Log("GetDepth:", routine_getDepth.wait()) If the wait function is called in advance to retrieve the result of a concurrent call to the GetDepth function, the event that the GetDepth function receives the result of the request will not be returned in the EventLoop function.
    var ts1 = new Date().getTime()
    var ret1 = EventLoop(0)
    
    var ts2 = new Date().getTime()
    var ret2 = EventLoop(0)
    
    var ts3 = new Date().getTime()
    var ret3 = EventLoop(0)
    
    Log("The first concurrent task completed was:", _D(ts1), ret1)
    Log("The second concurrent task completed was:", _D(ts2), ret2)
    Log("The third concurrent task completed was:", _D(ts3), ret3)
    
    Log("GetTicker:", routine_getTicker.wait())
    Log("GetDepth:", routine_getDepth.wait())
    Log("GetTrades:", routine_getTrades.wait())
}
import time
def main():
    routine_getTicker = exchange.Go("GetTicker")
    routine_getDepth = exchange.Go("GetDepth")
    routine_getTrades = exchange.Go("GetTrades")
    
    ts1 = time.time()
    ret1 = EventLoop(0)
    
    ts2 = time.time()
    ret2 = EventLoop(0)
    
    ts3 = time.time()
    ret3 = EventLoop(0)
    
    Log("The first concurrent task completed was:", _D(ts1), ret1)
    Log("The second concurrent task completed was:", _D(ts2), ret2)
    Log("The third concurrent task completed was:", _D(ts3), ret3)
    
    Log("GetTicker:", routine_getTicker.wait())
    Log("GetDepth:", routine_getDepth.wait())
    Log("GetTrades:", routine_getTrades.wait())
void main() {
    auto routine_getTicker = exchange.Go("GetTicker");
    auto routine_getDepth = exchange.Go("GetDepth");
    auto routine_getTrades = exchange.Go("GetTrades");
    
    auto ts1 = Unix() * 1000;
    auto ret1 = EventLoop(0);
    
    auto ts2 = Unix() * 1000;
    auto ret2 = EventLoop(0);
    
    auto ts3 = Unix() * 1000;
    auto ret3 = EventLoop(0);
    
    Log("The first concurrent task completed was:", _D(ts1), ret1);
    Log("The second concurrent task completed was:", _D(ts2), ret2);
    Log("The third concurrent task completed was:", _D(ts3), ret3);
    
    Ticker ticker;
    Depth depth;
    Trades trades;
    routine_getTicker.wait(ticker);
    routine_getDepth.wait(depth);
    routine_getTrades.wait(trades);
    
    Log("GetTicker:", ticker);
    Log("GetDepth:", depth);
    Log("GetTrades:", trades);
}

첫 번째 전화EventLoop()코드의 함수는 그 청취된 이벤트의 메커니즘을 초기화합니다.EventLoop()호출은 이벤트 콜백이 시작되면 이전 이벤트를 놓칠 것입니다. 기본 시스템은 최대 500 개의 이벤트 콜백을 캐시하는 대기열 구조를 포장합니다.EventLoop()이 함수는 프로그램 실행 중에 꺼내기 위해 시간 내에 호출되지 않으면, 500 캐시 외부의 후속 이벤트 콜백은 손실됩니다.EventLoop()함수는 기본 시스템 WebSocket의 캐시 대기열 또는 같은 동시 함수의 캐시에 영향을 미치지 않습니다exchange.Go()이 캐시의 경우, 여전히 해당 방법을 사용하여 데이터를 검색하는 것이 필요합니다.EventLoop()함수EventLoop()함수 반환.EventLoop()기능은 새로운 네트워크 데이터가 기본 시스템에 수신되었다는 전략 계층을 알리는 것입니다. 전체 전략은 이벤트에 의해 주도됩니다.EventLoop()함수는 이벤트를 반환, 그냥 모든 데이터 소스를 통과합니다. 예를 들어, 웹소켓 연결, 객체에 의해 생성exchange.Go()데이터를 얻기 위해 노력합니다.EventLoop()이 기능은 라이브 거래만 지원합니다. 메인 함수에서 호출될 때 메인 스레드에서 이벤트를 듣기main().JavaScript언어,threading.Thread()이 함수는 스레드를 생성합니다. 스레드의 실행 함수에서도 호출될 수 있습니다.

{@fun/Global/Dial Dial}, {@fun/Trade/exchange.Go exchange.Go}, {@fun/Global/HttpQuery_Go HttpQuery_Go}

__서비스

__Serve이 함수는 Http 서비스, TCP 서비스, 웹소켓 서비스 (Http 프로토콜을 기반으로) 를 생성하는 데 사용됩니다.

생성된 서비스의 IP 주소와 포트를 기록하는 문자열을 반환합니다. 예를 들어:127.0.0.1:8088, [::]:8089.

문자열

__서비스 (서비스URI, 관리자) __서비스 (서비스 (SERVURI, 핸들러,...args)

serveURI이 매개 변수는 프로토콜, IP 주소, 포트 및 서비스 결합의 다른 설정을 구성하는 데 사용됩니다.http://0.0.0.0:8088?gzip=true, 즉,http://:8088?gzip=true.

  • TCP 프로토콜serveURI파라미터 설정,tcp://127.0.0.1:6666?tls=true; 당신은 인증서와 개인 키를 추가할 수 있습니다.tls=true&cert_pem=xxxx&cert_key_pem=xxxx.
  • HTTP 프로토콜serveURI파라미터 설정,http://127.0.0.1:6666?gzip=true; 압축 설정을 설정할 수 있습니다:gzip=true... 의serveURIHttps를 위한 매개 변수입니다.https://127.0.0.1:6666?tls=true&gzip=true; 당신은 추가 할 수 있습니다cert_pem그리고cert_key_pem인증서를 로드하는 매개 변수

serveURI 사실 문자열 의handler이 매개 변수는 라우팅 처리 함수 (Http 프로토콜), 메시지 처리 함수 (TCP 프로토콜), 스트림 처리 함수 (Websocket) 에서 전달하는 데 사용됩니다. 매개 변수에서 전달된 콜백 함수handler여러 매개 변수를 정의할 수 있는데 첫 번째 매개 변수는 ctx 객체 (context object) 입니다.

관리자 사실 기능 콜백 함수의 실제 매개 변수는 매개 변수로 전달handler여러 매개 변수가 있을 수 있습니다.arg예를 들어:

__Serve("http://:8088", function(ctx, a, b, c) {
    Log(`ctx.host():`, ctx.host(), ", a=", a, ", b=", b, ", c=", c)
}, 1, 2, 3)

매개 변수1, 2, 3전화 할 때 통과__Serve()함수는 매개 변수와 일치합니다a, b, c콜백 함수에서 통과했습니다.

아그 거짓 문자열, 숫자, bool, 객체, 배열, 함수, null 값 및 시스템에서 지원되는 다른 유형

function main() {
    let httpServer = __Serve("http://:8088?gzip=true", function (ctx) {
        Log("http connect from: ", ctx.remoteAddr(), "->", ctx.localAddr())
        let path = ctx.path()
        if (path == "/") {
            ctx.write(JSON.stringify({
                path: ctx.path(),
                method: ctx.method(),
                headers: ctx.headers(),
                cookie: ctx.header("Cookie"),
                remote: ctx.remoteAddr(),
                query: ctx.rawQuery()
            }))
        } else if (path == "/tickers") {
            let ret = exchange.GetTickers()
            if (!ret) {
                ctx.setStatus(500)
                ctx.write(GetLastError())
            } else {
                ctx.write(JSON.stringify(ret))
            }
        } else if (path == "/wss") {
            if (ctx.upgrade("websocket")) { // upgrade to websocket
                while (true) {
                    let r = ctx.read(10)
                    if (r == "") {
                        break
                    } else if (r) {
                        if (r == "ticker") {
                            ctx.write(JSON.stringify(exchange.GetTicker()))
                        } else {
                            ctx.write("not support")
                        }
                    }
                }
                Log("websocket closed", ctx.remoteAddr())
            }
        } else {
            ctx.setStatus(404)
        }
    })
    let echoServer = __Serve("tcp://:8089", function (ctx) {
        Log("tcp connect from: ", ctx.remoteAddr(), "->", ctx.localAddr())
        while (true) {
            let d = ctx.read()
            if (!d) {
                break
            }
            ctx.write(d)
        }
        Log("connect closed")
    })
    Log("http serve on", httpServer, "tcp serve on", echoServer)
    
    for (var i = 0; i < 5; i++) {
        if (i == 2) {
            // test Http
            var retHttp = HttpQuery("http://127.0.0.1:8088?num=123&limit=100", {"debug": true})
            Log("retHttp:", retHttp)
        } else if (i == 3) {
            // test TCP
            var tcpConn = Dial("tcp://127.0.0.1:8089")
            tcpConn.write("Hello TCP Server")
            var retTCP = tcpConn.read()
            Log("retTCP:", retTCP)
        } else if (i == 4) {
            // test Websocket
            var wsConn = Dial("ws://127.0.0.1:8088/wss|compress=gzip")
            wsConn.write("ticker")
            var retWS = wsConn.read(1000)
            Log("retWS:", retWS)
            // no depth
            wsConn.write("depth")
            retWS = wsConn.read(1000)
            Log("retWS:", retWS)
        }
        Sleep(1000)
    }
}
# Unsupported
// Unsupported
  • 이 함수는 자바스크립트 언어 전략만 지원합니다.
  • 서비스 스레드는 글로벌 범위에서 격리되어 있으므로 종료 또는 외부 변수, 사용자 정의 함수 등에 대한 참조를 지원하지 않습니다. 그러나 모든 플랫폼 API 함수를 호출 할 수 있습니다.
  • WebsocketHttp 프로토콜에 기반하여 구현됩니다. 경로에서 라우팅 브랜치를 설정하고 실행 코드를 설계할 수 있습니다Websocket이 섹션에서 샘플 코드를 참조 할 수 있습니다.

매개 변수에서 전달된 콜백 함수handler수락ctx매개 변수ctx매개 변수 는 다음 방법 으로 데이터를 얻고 기록 하기 위해 사용되는 컨텍스트 객체 입니다.

  • ctx.proto (() Http/TCP 프로토콜에 적용, 호출할 때 프로토콜 이름을 반환합니다. 예를 들어:HTTP/1.1, tcp.
  • ctx.host() HTTP 프로토콜에 적용하면 IP 주소와 포트를 호출할 때 호스트 정보를 반환합니다.
  • ctx.path (() Http 프로토콜에 적용되어 호출할 때 요청 경로를 반환합니다.
  • ctx.query (키) Http 프로토콜에 적용, 호출 때 요청에 있는 쿼리의 키에 대응하는 값을 반환합니다. 예를 들어 전송된 요청은:http://127.0.0.1:8088?num=123, 그리고 매개 변수에 의해 전달된 호출 역 처리 함수handler수익"123"언제ctx.query("num")라고 불립니다.
  • ctx.rawQuery() Http 프로토콜에 적용, 호출되면, 요청의 원래 질의 (Http 요청의 질의) 를 반환합니다.
  • ctx.headers (주) Http 프로토콜에 적용되며 호출할 때 요청 헤더 정보를 반환합니다.
  • ctx.header (키) Http 프로토콜에 적용, 그것은 호출 때 지정된 요청 헤더에 키의 값을 반환합니다. 예를 들어,User-Agent현재 요청의 제목에:ctx.header("User-Agent").
  • ctx.method (() Http 프로토콜에 적용, 호출 때 요청 방법을 반환, 예를 들어GET, POST, 등등
  • ctx.body ((() Http 프로토콜의 POST 요청에 적용되며 호출할 때 요청의 본체를 반환합니다.
  • ctx.setHeader (키, 값) HTTP 프로토콜에 적용하여 응답 메시지의 요청 헤더 정보를 설정합니다.
  • ctx.setStatus (코드) Http 프로토콜에 적용, Http 메시지 상태 코드를 설정합니다. 일반적으로, Http 상태 코드는 라우팅 지부의 끝에 설정됩니다. 기본 값은 200.
  • ctx.remoteAddr() Http/TCP 프로토콜에 적용, 호출할 때 요청에 있는 원격 클라이언트 주소와 포트를 반환합니다.
  • ctx.localAddr() Http/TCP 프로토콜에 적용, 호출할 때 서비스의 로컬 주소와 포트를 반환합니다.
  • ctx.upgrade ((websocket)) HTTP 프로토콜을 기반으로 웹소켓 프로토콜 구현에 적용, 전환ctx컨텍스트 객체에 웹소켓 프로토콜; 귀환 boolean 값 (진짜) 전환이 성공하면, 그리고 boolean 값 (거짓) 실패하면.
  • ctx.read ((timeout_ms) HTTP 프로토콜을 기반으로 웹소켓 프로토콜 구현 / TCP 프로토콜에 적용, 웹소켓 연결과 TCP 연결의 데이터를 읽습니다.read이 방법은 일반적인 HTTP 프로토콜에서 지원되지 않습니다. 당신은 타임 아웃 매개 변수를 지정할 수 있습니다timeout_ms밀리 초에
  • ctx.write ((s) Http/TCP 프로토콜에 적용, 문자열 데이터를 작성하는 데 사용됩니다.JSON.stringify()JSON 객체를 문자열로 인코딩하고WebSocket프로토콜, 이 방법을 사용하여 암호화된 문자열을 클라이언트에 전달할 수 있습니다.

{@fun/Global/HttpQuery HttpQuery}, {@fun/Global/HttpQuery_Go HttpQuery_Go}

_G

지속적으로 데이터를 저장, 함수는 저장 할 수있는 글로벌 사전 함수를 구현합니다. 데이터 구조는 도커의 로컬 데이터베이스 파일에 영구적으로 저장되는 KV 테이블입니다.

계속 저장된 키 값 데이터k-v키-값 쌍 문자열, 숫자, bool, 객체, 배열, null 값

_G() _G(k) _G(k, v)

매개 변수k저장된 키-값 쌍의 키의 이름이고 대소문 감수성이 없습니다. k 거짓 문자열, null 값 매개 변수v저장된 키-값 쌍의 키 값입니다.JSON시리즈화 된 것입니다. v 거짓 문자열, 숫자, bool, 객체, 배열, null 값

function main(){
    // Set a global variable num with a value of 1
    _G("num", 1)     
    // Change a global variable num to the value of the string ok
    _G("num", "ok")    
    // Delete the global variable num
    _G("num", null)
    // Returns the value of the global variable num
    Log(_G("num"))
    // Delete all global variables
    _G(null)
    // Return to live trading ID
    var robotId = _G()
}
def main():
    _G("num", 1)     
    _G("num", "ok")    
    _G("num", None)
    Log(_G("num"))
    _G(None)
    robotId = _G()
void main() {
    _G("num", 1);
    _G("num", "ok");
    _G("num", NULL);
    Log(_G("num"));
    _G(NULL);
    // Not support auto robotId = _G();
}

각 라이브 거래에 대한 별도의 데이터베이스,_G()함수는 항상 전략이 다시 시작되거나 도커가 실행을 중단하면있을 것입니다. 백테스팅이 완료되면 백테스팅 시스템에 저장된 데이터는_G()이 기능을 사용 하 여_G()저장된 데이터를 유지하기 위한 기능, 하드웨어 장치의 메모리 및 하드 디스크 공간에 따라 합리적으로 사용되어야 하며, 남용되어서는 안 됩니다. 전화할 때_G()라이브 거래에서 기능 및 어떤 매개 변수가 전달되지 않습니다,_G()함수는Id현재 라이브 거래._G()함수, 매개 변수v0으로 전달되면k-v키-값 쌍을 호출할 때_G()함수, 단지 매개 변수k문자열에 전달됩니다, 그리고_G()함수는 저장된 매개 변수에 대응하는 키 값을 반환k전화할 때_G()함수, 단지 매개 변수k0값으로 전달됩니다.k-v키-값 쌍이 삭제됩니다.k-v키값 쌍이 지속적으로 저장된 경우,_G()함수는 다시 호출되고 매개 변수로 지속적으로 저장된 키의 이름을 전달합니다.k. 새로운 키 값을 매개 변수로 전달v업데이트 할 것입니다.k-v키-값 쌍

{@fun/Global/DBExec DBExec}

_D

밀리초 시간표 또는Date시간 문자열에 대한 객체입니다.

시간 줄. 문자열

_D() 시간표 _D (시간표, fmt)

밀리초 시간표 또는Date물체. 시간표 거짓 번호, 대상 형식 문자열,JavaScript언어 기본 형식:yyyy-MM-dd hh:mm:ss; Python언어 기본 형식:%Y-%m-%d %H:%M:%S; C++언어 기본 형식:%Y-%m-%d %H:%M:%S... fmt 거짓 문자열

function main(){
    var time = _D()
    Log(time)
}
def main():
    strTime = _D()
    Log(strTime)
void main() {
    auto strTime = _D();
    Log(strTime);
}

현재 시간 문자열을 가져와 인쇄합니다:

function main() {
    Log(_D(1574993606000))
}
def main():
    # Running this code on a server in Beijing time: 2019-11-29 10:13:26 , a docker on another server in another region results in: 2019-11-29 02:13:26
    Log(_D(1574993606))
void main() {
    Log(_D(1574993606000));
}

시간표는 1574993606000, 코드 변환:

function main() {
    Log(_D(1574993606000, "yyyy--MM--dd hh--mm--ss"))   // 2019--11--29 10--13--26
}
def main():
    # 1574993606 is timestamped in seconds.
    Log(_D(1574993606, "%Y--%m--%d %H--%M--%S"))        #  2019--11--29 10--13--26
void main() {
    Log(_D(1574993606000, "%Y--%m--%d %H--%M--%S"));    // 2019--11--29 10--13--26
}

매개 변수와 함께 포맷fmt다른 경우JavaScript, Python, 그리고C++다음 예제에서 보여준 바와 같이 언어

매개 변수를 전달하지 않고 현재 시간 문자열을 반환합니다._D()기능Python전략, 당신은 통과 매개 변수 두 번째 수준의 타임 스탬프 (자바스크립트와 C ++ 전략에서 밀리 초 수준 타임 스탬프, 1 초 1000 밀리 초에 해당하는) 이다._D()실시간 거래에서 읽을 수 있는 시간표가 있는 시간 문자열을 분석하기 위해, 당신은 도커 프로그램이 위치하는 운영 체제의 시간대와 시간 설정에 주의를 기울여야 합니다._D()함수는 도커의 시간에 따라 시간표를 읽을 수 있는 시간 문자열로 분석합니다.

UNIX UNIX UNIX UNIX UNIX UNIX

_N

부동 소수점 번호를 포맷하세요.

정밀 설정에 따라 포맷된 부동 소수점 번호 번호

_N() _N(num) _N (num, 정밀)

형식이 필요한 부동 소수점 번호 수 사실 번호 포맷의 정밀 설정, 매개 변수precision정수이고 매개 변수는precision기본값은 4입니다 정확성 거짓 번호

function main(){
    var i = 3.1415
    Log(i)
    var ii = _N(i, 2)
    Log(ii)
}
def main():
    i = 3.1415
    Log(i)
    ii = _N(i, 2)
    Log(ii)
void main() {
    auto i = 3.1415;
    Log(i);
    auto ii = _N(i, 2);
    Log(ii);
}

예를 들어,_N(3.1415, 2)다음 값을 삭제합니다3.1415두 소수점, 그리고 함수는 반환3.14.

function main(){
    var i = 1300
    Log(i)
    var ii = _N(i, -3)
    // Check the logs and see that it is 1000
    Log(ii)
}
def main():
    i = 1300
    Log(i)
    ii = _N(i, -3)
    Log(ii)
void main() {
    auto i = 1300;
    Log(i);
    auto ii = _N(i, -3);
    Log(ii);
}

소수점 왼쪽에 있는 모든 n자리들을 0으로 바꾸면 이렇게 쓸 수 있습니다

매개 변수precision양 పూర్수는 될 수 있고, 음 పూర్수는 될 수 있습니다

{@fun/Trade/exchange.SetPrecision exchange.SetPrecision}

_C

인터페이스 오류 용도 기능을 다시 시도합니다.

콜백 함수가 실행될 때 반환되는 값 모든 타입은 시스템에서 지원됩니다.논리적인 잘못된 값그리고null 값.

_C(pfn) _C ((pfn,...args)

매개 변수pfn함수 참조입니다.콜백 함수... pfn 사실 기능 매개 변수콜백 함수, 한 개 이상의 매개 변수가 있을 수 있습니다.arg- 파라미터의 종류와 수arg그 매개 변수에 따라콜백 함수- 네 아그 거짓 문자열, 숫자, bool, 객체, 배열, 함수, 모든 유형은 null 값과 같이 시스템에서 지원됩니다.

function main(){
    var ticker = _C(exchange.GetTicker)
    // Adjust _C() function retry interval to 2 seconds
    _CDelay(2000)
    var depth = _C(exchange.GetDepth)
    Log(ticker)
    Log(depth)
}
def main():
    ticker = _C(exchange.GetTicker)
    _CDelay(2000)
    depth = _C(exchange.GetDepth)
    Log(ticker)
    Log(depth)
void main() {
    auto ticker = _C(exchange.GetTicker);
    _CDelay(2000);
    auto depth = _C(exchange.GetDepth);
    Log(ticker);
    Log(depth);
}

매개 변수 없는 오류 허용 함수:

function main(){
    var records = _C(exchange.GetRecords, PERIOD_D1)
    Log(records)
}
def main():
    records = _C(exchange.GetRecords, PERIOD_D1)
    Log(records)
void main() {
    auto records = _C(exchange.GetRecords, PERIOD_D1);
    Log(records);
}

오류 용이성 있는 매개 변수를 가진 함수:

var test = function(a, b){
    var time = new Date().getTime() / 1000
    if(time % b == 3){
        Log("Eligible!", "#FF0000")
        return true
    }
    Log("Retry!", "#FF0000")
    return false
}            

function main(){
    var ret = _C(test, 1, 5)
    Log(ret)
}
import time
def test(a, b):
    ts = time.time()
    if ts % b == 3:
        Log("Eligible!", "#FF0000")
        return True
    Log("Retry!", "#FF0000")
    return False            

def main():
    ret = _C(test, 1, 5)
    Log(ret)
// C++ does not support fault tolerance for custom functions in this way

또한 사용자 정의 함수의 오류 허용에 사용할 수 있습니다:

_C()function는 지정된 함수를 호출할 수 있습니다.pfn수익null또는거짓호출되면 다시 호출을 시도합니다.pfn예를 들어_C(exchange.GetTicker). 기본 재시험 간격은 3 초입니다, 당신은 호출 할 수 있습니다_CDelay()재시험 간격을 설정하는 기능입니다. 예를 들어,_CDelay(1000)재시험 간격을 변경하기 위한 수단_C()1초로 작동합니다. 결함 허용은 다음 기능에 적용될 수 있지만 제한되지 않습니다.

  • exchange.GetTicker()
  • exchange.GetDepth()
  • exchange.GetTrades()
  • exchange.GetRecords()
  • exchange.GetAccount()
  • exchange.GetOrders()
  • exchange.GetOrder()
  • exchange.GetPositions()모든 것은_C()결함 허용 함수_C()함수는 위와 같은 함수 결함 허용에 국한되지 않습니다, 매개 변수pfn함수 호출보다는 함수 참조입니다. 이 점에 유의해야 합니다._C(exchange.GetTicker)아니_C(exchange.GetTicker()).

_십자

배열의 교차점 수를 반환합니다.arr1그리고 배열arr2.

배열의 교차기점 수arr1그리고 배열arr2... 번호

_십자 (arr1,arr2)

요소는 타입의 배열입니다.number... arr1 사실 배열 요소는 타입의 배열입니다.number... arr2 사실 배열

// Fast line indicator
var arr1 = [1,2,3,4,5,6,8,8,9]
// Slow line indicator
var arr2 = [2,3,4,5,6,7,7,7,7]
function main(){
    Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
    Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
}
arr1 = [1,2,3,4,5,6,8,8,9]     
arr2 = [2,3,4,5,6,7,7,7,7]
def main():
    Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
    Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
void main() {
    vector<double> arr1 = {1,2,3,4,5,6,8,8,9};
    vector<double> arr2 = {2,3,4,5,6,7,7,7,7};
    Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2));
    Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1));
}

데이터 세트를 시뮬레이션하여 _Cross ((Arr1, Arr2) 함수를 테스트 할 수 있습니다.

만약_Cross()이 함수 는 양수 이면 상향 진입 기간 을 나타내고, 이 함수 이 음수 이면 하향 진입 기간 을 나타내고, 0 은 현재 가격 과 동일 합니다. 사용 지침:내장 기능에 대한 분석 및 사용 지침 _ 크로스.

JSONParse

기능JSONParse()분석하는 데 사용됩니다.JSON strings.

JSON물체. 물체

JSONParse ((s)

JSON끈. s 사실 문자열

function main() {
    let s1 = '{"num": 8754613216564987646512354656874651651358}'
    Log("JSON.parse:", JSON.parse(s1))    // JSON.parse: {"num":8.754613216564988e+39}
    Log("JSONParse:", JSONParse(s1))      // JSONParse:  {"num":"8754613216564987646512354656874651651358"}
    
    let s2 = '{"num": 123}'
    Log("JSON.parse:", JSON.parse(s2))    // JSON.parse: {"num":123}
    Log("JSONParse:", JSONParse(s2))      // JSONParse:  {"num":123}
}
import json

def main():
    s1 = '{"num": 8754613216564987646512354656874651651358}'
    Log("json.loads:", json.loads(s1))    # json.loads: map[num:8.754613216564987e+39]
    Log("JSONParse:", JSONParse(s1))      # JSONParse:  map[num:8754613216564987646512354656874651651358]
    
    s2 = '{"num": 123}'
    Log("json.loads:", json.loads(s2))    # json.loads: map[num:123]
    Log("JSONParse:", JSONParse(s2))      # JSONParse:  map[num:123]
void main() {
    auto s1 = "{\"num\":8754613216564987646512354656874651651358}";
    Log("json::parse:", json::parse(s1));
    // Log("JSONParse:", JSONParse(s1));   // The function is not supported.
    
    auto s2 = "{\"num\":123}";
    Log("json::parse:", json::parse(s2));
    // Log("JSONParse:", JSONParse(s2));   // The function is not supported.
}

큰 값의 JSON 문자열을 올바르게 분석할 수 있고, 큰 값을 문자열 유형으로 분석할 것입니다.JSONParse()backtest 시스템에서 기능이 지원되지 않습니다.

로그