개발자 양적 API 문서

저자:작은 꿈, 2017-11-27 09:05:08에서 생성, 2023-07-12 16:47:31로 업데이트

void main() {
    Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body");
}
  • Mail함수의 비동기 버전Mail_Go함수: 사용 방법 및exchange.Go함수와 비슷합니다.

    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)
    }
    
    # 不支持
    
    // 不支持
    

주의: 알리 클라우드 서버가 일부 포트를 차단하여 메일이 전송되지 않을 수 있습니다. 포트를 변경해야하는 경우 첫 번째 매개 변수에 직접 포트 번호를 추가 할 수 있습니다. 예를 들어:smtp.qq.com:587이 포트 테스트는 사용 가능합니다. 만약 오류가 발생하면:unencryped connection그리고 우리는 그것을 바꾸어야 합니다.Mail이 함수들의smtpServer파러미터의 형식은 다음과 같습니다.ssl://xxx.com:xxx예를 들어, QQ 메일SMTP이 문서는ssl://smtp.qq.com:465또는smtp://xxx.com:xxx

SetErrorFilter (실점 필터 설정)

SetErrorFilter(RegEx), 필터 오류 로그. ▲변수 값: 문자열 유형. ▲ 이 정규 표현식으로 일치하는 오류 로그는 로그 시스템에 업로드되지 않으며, 여러 필터 조건을 설정할 수 있습니다. (필터링 된 로그는 호스트 디렉토리에 해당 디스크 ID에 해당하는 데이터베이스 파일에 기록되지 않으며, 빈번한 오류가 데이터베이스 파일에 번식하는 것을 방지합니다.)

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() {
    // 随便查询一个不存在的订单,id为123,故意让接口报错
    var order = exchange.GetOrder("123")
    Log(order)
    // 过滤http502错误、GetOrder接口错误,设置错误过滤之后,第二次调用GetOrder不再报错
    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);
}

GetPid ((()

GetPid(), 리얼 디스크 프로세스 ID를 반환한다.

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

GETLastError()

GetLastError(), 최근 오류 정보를 얻는다. 일반적으로 사용이 필요하지 않습니다. 프로그램은 오류 정보를 자동으로 로그 시스템에 업로드합니다. 값: 문자열 유형을 반환합니다. 호출.GetLastError()이 함수는 나중에 이 오류 캐시를 삭제하고, 다시 호출할 때 마지막 기록의 오류 정보를 반환하지 않습니다.

function main(){
    // 因为不存在编号为123的订单,所以会出错
    exchange.GetOrder("123")
    var error = GetLastError()
    Log(error)
}
def main():
    exchange.GetOrder("123")
    error = GetLastError()
    Log(error)
void main() {
    // 订单ID类型:TId,所以不能传入字符串,我们下一个不符合交易所规范的订单来触发
    exchange.GetOrder(exchange.Buy(1, 1));
    auto error = GetLastError();
    Log(error);
}

GetCommand (() 를 받아보세요

GetCommand(), 인터랙티브 명령어 문자열 (utf-8) 을 가져옵니다.. 정책 인터랙티브 인터페이스에서 보낸 명령어를 가져와서 캐시를 비어, 명령어가 없는 경우 빈 문자열을 반환합니다.. 반환 명령어 형식은按钮名称:参数, 인터랙티브 컨트롤에 매개 변수가 없는 경우 (예를 들어 입력 상자가 없는 버튼 컨트롤) 명령어는 버튼 이름이다.

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

하위 시스템에는 쿼리 구조가 있습니다.GetCommand()함수를 호출할 때, 행에서 먼저 입력된 인터랙션 명령어를 가져옵니다 (이 인터랙션 명령어가 없으면 빈 문자열을 반환합니다).

인터랙티브 컨트롤의 사용 예제, 전략 편집 인터페이스에서 인터랙티브 컨트롤을 설정합니다.

img

이 전략은 상호 작용 코드를 설계하는 것입니다.

function main() {
    while (true) {
        LogStatus(_D())
        var cmd = GetCommand()
        if (cmd) {
            Log("cmd:", cmd)    
            var arr = cmd.split(":")
            if (arr[0] == "buy") {
                Log("买入,该控件不带数量")
            } else if (arr[0] == "sell") {
                Log("卖出,该控件带数量:", arr[1])
            } else {
                Log("其它控件触发:", arr)
            }
        }
        Sleep(1000)
    } 
}
def main():
    while True:
        LogStatus(_D())
        cmd = GetCommand()
        if cmd:
            Log("cmd:", cmd)
            arr = cmd.split(":")
            if arr[0] == "buy":
                Log("买入,该控件不带数量")
            elif arr[0] == "sell":
                Log("卖出,该控件带数量:", arr[1])
            else:
                Log("其它控件触发:", 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("买入,该控件不带数量");
            } else if (arr[0] == "sell") {
                Log("卖出,该控件带数量:", arr[1]);
            } else {
                Log("其它控件触发:", arr);
            }
        }
        Sleep(1000);
    }
}

GetMeta (메타)

GetMeta()함수는 생성 정책 레지스트리 코드에서 입력된 것을 반환합니다.Meta이 함수는 문자열 타입을 반환합니다. 예를 들어, 다른 임차인에게 자금을 제한해야 하는 전략과 같은 시나리오를 적용합니다. 참고: 등록번호를 생성할 때Meta이 함수는 디스크에만 적용되며 최신 호스트를 사용해야 합니다. 정책 등록 코드를 생성할 때 메타데이터를 설정하지 않은 경우GetMeta()0을 반환합니다.

시나리오 시범을 사용하는 정보

function main() {
    // 策略允许的计价币最大资产数值
    var maxBaseCurrency = null
    
    // 获取创建注册码时的元数据
    var level = GetMeta()
    
    // 检测Meta对应的条件
    if (level == "level1") {
        // -1为不限制
        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()
        
        // 检测资产数值
        var acc = exchange.GetAccount()
        if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks) {
            // 停止执行策略交易逻辑
            LogStatus(_D(), "level:", level, "持仓超过注册码的使用限定,不再执行策略交易逻辑!")
            continue
        }
        
        // 其它交易逻辑
        
        // 正常输出状态栏信息
        LogStatus(_D(), "level:", level, "策略正常运行!ticker数据:\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, "持仓超过注册码的使用限定,不再执行策略交易逻辑!")
            continue        
        
        # 其它交易逻辑
        
        # 正常输出状态栏信息
        LogStatus(_D(), "level:", level, "策略正常运行!ticker数据:\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) {
            // 停止执行策略交易逻辑
            LogStatus(_D(), "level:", level, "持仓超过注册码的使用限定,不再执行策略交易逻辑!");
            continue;
        }
        
        // 其它交易逻辑
        
        // 正常输出状态栏信息
        LogStatus(_D(), "level:", level, "策略正常运行!ticker数据:\n", ticker);
    }
}

다이얼...

Dial(Address, Timeout)원시적인Socket방문, 지원tcpudptlsunix프로토콜. 파라미터 값:Address문자열 유형은TimeOut숫자의 종류, 숫자의 단위는 초이고, 시간이 지나면Dial(...)함수는 null값을 반환합니다.

Address파러미터에 대한 자세한 설명:

파라미터 설명
설정Dial기능의 매개 변수 이 글의 본문은: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")
Ws 프로토콜에서 사용되면 데이터 압축에 관련된 매개 변수는:compress=参数值 compress 압축 방식, 압축 파라미터, 선택gzip_rawgzip예를 들어, gzip 방식이 표준 gzip 방식이 아닌 경우 확장 방법을 사용할 수 있습니다.gzip_raw이 부분에서,|나중에 추가 설정compress=gzip_raw사용&기호와 다음 모드 매개 변수를 분리합니다.
Ws 프로토콜에서 사용되면 데이터 압축에 관련된 매개 변수는:mode=参数值 모드 모드, 선택dualsendrecv세 가지.dual양방향으로 압축 데이터를 전송하고 압축 데이터를 수신합니다.send압축된 데이터를 전송하기 위해.recv압축 데이터를 수신하기 위해 로컬로 압축 해제합니다.
socks5 에이전트를 설정하기 위한 관련 매개 변수:proxy=参数值 proxy는 ss5 에이전트로 설정되어 있으며, 매개 변수 값 형식은:socks5://name:pwd@192.168.0.1:1080,name는 ss5 서버 테마 사용자 이름,pwd는 ss5 서버 테마 로그인 암호,1080은 ss5 서비스의 포트이다.
WS 프로토콜에서 사용할 때, 하층 자동 재결합에 관련된 매개 변수를 설정합니다:reconnect=参数值 reconnect는 재연결을 설정하는지 여부를 표시합니다.reconnect=true재결합을 활성화하기 위해. 이 매개 변수를 설정하지 않은 상태에서 기본으로 재결합하지 않습니다.
WS 프로토콜에서 사용할 때, 하층 자동 재결합에 관련된 매개 변수를 설정합니다:interval=参数值 interval는 재검토 시간 간격, 밀리 초,interval=1000010초 간격으로 재시험을 하려면 기본값은 1초로 설정되지 않습니다.interval=1000
WS 프로토콜에서 사용할 때, 하층 자동 재결합에 관련된 매개 변수를 설정합니다:payload=参数值 payload가 ws로 재결합될 때 전송해야 하는 구독 메시지, 예를 들어:payload=okok
function main(){
    // Dial支持tcp://,udp://,tls://,unix://协议,可加一个参数指定超时的秒数
    var client = Dial("tls://www.baidu.com:443")  
    if (client) {
        // write可再跟一个数字参数指定超时,write返回成功发送的字节数
        client.write("GET / HTTP/1.1\nConnection: Closed\n\n")
        while (true) {
            // read可再跟一个数字参数指定超时,单位:毫秒。返回null指出错或者超时或者socket已经关闭
            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();
    }
}

read이 함수는 다음과 같은 매개 변수를 지원합니다.

  • 파라미터가 전달되지 않을 때, 메시지가 있을 때까지 차단하여 반환합니다. 예를 들어:ws.read()
  • 패러먼트 입력 시 단위는 밀리 초이고, 메시지가 대기 시간이 지나도록 지정한다. 예를 들어:ws.read(2000)지정한 시간 초과 시간은 2초 ((2000 밀리 초) 이다.
  • 이 두 가지 변수들은websocket효과적: 입력 매개 변수-1함수는 메시지가 없더라도 즉시 반환되는 것을 의미합니다. 예를 들어:ws.read(-1)ᅳ 입력 매개 변수-2즉, 메시지가 없더라도 함수는 즉시 반환하지만 최신 메시지가 반환되며 버퍼 영역의 메시지는 폐기됩니다. 예를 들어.ws.read(-2)

read()함수 버퍼 영역은 다음과 같습니다. ws 프로토콜에서 전송된 데이터입니다read()함수 호출 사이의 시간 간격이 너무 길어서 데이터 축적이 발생할 수 있다. 이 데이터는 버퍼 영역에 저장되며 버퍼 영역의 데이터 구조는 열로 되어 있으며, 최대 2000개이다. 2000을 넘어서면 최신 데이터가 버퍼 영역으로 들어가고 가장 오래된 데이터는 삭제된다.

장면에서read함수 변수 변수 없는 매개 변수: -1 매개 변수: -2 매개 변수: 2000, 단위는 밀리 초입니다.
버퍼 영역에 데이터가 있습니다. 가장 오래된 데이터를 바로 가져옵니다. 가장 오래된 데이터를 바로 가져옵니다. 최신 데이터를 바로 가져옵니다. 가장 오래된 데이터를 바로 가져옵니다.
버퍼 영역은 데이터가 없습니다. 데이터가 있을 때까지 차단 즉시 null값을 반환합니다. 즉시 null값을 반환합니다. 2000 밀리초를 기다립니다. 데이터가 없는 값이 빈 값으로 돌아옵니다.
ws 연결이 끊어지거나 바닥을 다시 연결하면 () 함수는 빈 문자열, 즉: "", write () 함수를 반환하고 0을 반환하여 해당 상태를 검출합니다. Close () 함수를 사용하여 연결을 닫을 수 있습니다. 자동 재결합을 설정하면 종료 할 필요가 없습니다. 시스템 하층은 자동으로 재결합됩니다.
  • ws ((WebSocket) 프로토콜을 지원합니다. 바이낸스의 웹소켓 시장 인터페이스를 방문하십시오:

    function main() {
        LogStatus("正在连接...")
        // 访问币安的websocket接口
        var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
        if (!client) {
            Log("连接失败, 程序退出")
            return
        }
        
        while (true) {
            // read只返回调用read之后获取的数据
            var buf = client.read()      
            if (!buf) {
                break
            }
            var table = {
                type: 'table',
                title: '行情图表',
                cols: ['币种', '最高', '最低', '买一', '卖一', '最后成交价', '成交量', '更新时间'],
                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("正在连接...")
        client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
        if not client:
            Log("连接失败, 程序退出")
            return 
        
        while True:
            buf = client.read()
            if not buf:
                break
            table = {
                "type" : "table", 
                "title" : "行情图表", 
                "cols" : ["币种", "最高", "最低", "买一", "卖一", "最后成交价", "成交量", "更新时间"], 
                "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("正在连接...");
        auto client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
        if(!client.Valid) {
            Log("连接失败, 程序退出");
            return;
        }
        
        while(true) {
            auto buf = client.read();
            if(buf == "") {
                break;
            }
            json table = R"({
                "type" : "table", 
                "title" : "行情图表", 
                "cols" : ["币种", "最高", "最低", "买一", "卖一", "最后成交价", "成交量", "更新时间"], 
                "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();
    }
    

    OKX의 웹소켓 시장 인터페이스를 방문:

    var ws = null 
    function main(){
        var param = {
            "op": "subscribe",
            "args": [{
                "channel": "tickers",
                "instId": "BTC-USDT"
            }]
        }
        // 在调用Dial函数时,指定reconnect=true即设置为重连模式,指定payload即为重连时发送的消息。在websocket连接断开后,会自动重连,自动发送消息
        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("发送 :ping", "#FF0000")
                }
                LogStatus("当前时间:", _D())
                Sleep(1000)
            }
        }
    }  
    
    function onexit() {
        ws.close() 
        Log("退出")
    }
    
    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("发送:ping", "#FF0000")
                LogStatus("当前时间:", _D())
                Sleep(1000)  
    
    def onexit():
        ws.close()
        Log("退出")
    
    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("发送:ping", "#FF0000");
                }
                LogStatus("当前时间:", _D());
                Sleep(1000);
            }
        }
    }  
    
    void onexit() {
        objWS.close();
        Log("退出");
    }
    

    토큰에 접근하는 웹소켓 시장 인터페이스:

    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)
                // 响应心跳包操作
                try {
                    var jsonRet = JSON.parse(ret)
                    if(typeof(jsonRet.ping) == "number") {
                        var strPong = JSON.stringify({"pong" : jsonRet.ping})
                        ws.write(strPong)
                        Log("响应ping,发送pong:", strPong, "#FF0000")
                    }
                } catch(e) {
                    Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
                }
                
                LogStatus("当前时间:", _D())
                Sleep(1000)
            }
        }
    }  
    
    function onexit() {
        ws.close() 
        Log("执行ws.close()函数")
    }
    
    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)              
                # 响应心跳包操作
                try:
                    jsonRet = json.loads(ret)
                    if "ping" in jsonRet and type(jsonRet["ping"]) == int:
                        strPong = json.dumps({"pong" : jsonRet["ping"]})
                        ws.write(strPong)
                        Log("响应ping,发送pong:", strPong, "#FF0000")
                except Exception as e:
                    Log("e:", e)
                    
                LogStatus("当前时间:", _D())
                Sleep(1000)
        
    def onexit():
        ws.close()
        Log("执行ws.close()函数")  
    
    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);              
                // 响应心跳包操作
                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("响应ping,发送pong:", strPong, "#FF0000");
                    }
                } catch(exception &e) 
                {
                    Log("e:", e.what());
                }
                
                LogStatus("当前时间:", _D());
                Sleep(1000);
            }
        }
    }  
    
    void onexit() {
        // ws.close();
        Log("执行ws.close()函数");
    }
    

    OKX의 웹소켓 검증 인터페이스를 방문:

    function getLogin(pAccessKey, pSecretKey, pPassphrase) {
        // 签名函数,用于登录
        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)
            }]
        }    
        return login
    }    
    
    var client_private = null 
    function main() {
        // 因为read函数使用了超时设置,过滤超时的报错,否则会有冗余错误输出
        SetErrorFilter("timeout")
        
        // 持仓频道订阅信息
        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)  // 登录时,不能立即订阅私有频道,需要等待服务器反应
        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)
                }
                
                // 检测断开,重连
                if (buf == "" && client_private.write(JSON.stringify(posSubscribe)) == 0) {
                    Log("检测到断开,关闭连接,重连")
                    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))
                }
                
                // 发送心跳包
                var nowPingTS = new Date().getTime()
                if (nowPingTS - lastPingTS > 10 * 1000) {
                    client_private.write("ping")
                    lastPingTS = nowPingTS
                }            
            }        
        }
    }    
    
    function onexit() {    
        var ret = client_private.close()
        Log("关闭连接!", 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("检测到断开,关闭连接,重连")
                    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("关闭连接!", 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("检测到断开,关闭连接,重连");
                        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("退出");
    }
    

HttpQuery(...)

HttpQuery(Url, PostData, Cookies, Headers, IsReturnHeader), 네트워크 URL 접속. ▲변수 값: 모든 문자열 유형. ▲

주의:

  • HttpQuery(...)함수만 지원합니다JavaScript언어는
  • Python언어는 사용할 수 있습니다.urllib큐, 직접 http 요청을 보내십시오.

HttpQuery(...)주로 시장 정보와 같은 공개 인터페이스와 같이 서명이 필요하지 않은 인터페이스를 액세스하는 거래소에 사용됩니다.

OKX에 접속하기 위해 서명할 필요가 없는 API 인터페이스의 예로, 값은JSON이 문자는JavaScript언어의 전략에서 사용할 수 있습니다JSON.parse()함수 분석.

function main(){
    // 一个GET访问不带参数的例子
    var info = JSON.parse(HttpQuery("https://www.okx.com/api/v5/public/time"))
    Log(info)
    // 一个GET访问带参数的例子
    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不支持Python,可以使用urllib/urllib2库代替
    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);
}

URL의 반환 내용을 얻을 수 있습니다.PostData문자열a=1&b=2&c=abc그 형태는POST다른 예로PUT이 모든 것은PostData변수는{method:'PUT', data:'a=1&b=2&c=abc'}PostData이 변수들은JSON문자열.

Cookies이 매개 변수는 다음과 같습니다.a=10; b=20각 매개 변수는 분수로 표시됩니다.;이 글의 내용은Headers이 매개 변수는 다음과 같습니다.User-Agent: Mobile\nContent-Type: text/html매 매개 변수마다 기호를 바꾼다\n이 글의 내용은

두 번째 매개 변수PostData이 방법은 다음과 같이 사용자 정의 할 수 있습니다.HttpQuery("http://www.abc.com", {method:'PUT', data:'a=1&b=2&c=abc'})참고: 필요한 경우HttpQuery이 함수들은 시간이 지남에 따라{method:'PUT', data:'a=1&b=2&c=abc'}가입timeout속성 (예정 60초)

1초 늦은 시간 설정:HttpQuery("http://www.abc.com", {method:'PUT', data:'a=1&b=2&c=abc', timeout:1000})

전달Cookie문자열에 세 번째 변수가 필요하지만 필요하지 않습니다.POST두 번째 변수를 null로 설정하십시오. 모방 테스트를 할 때 모방 URL에 액세스 할 수 없기 때문에 함수는 고정 문자열을 반환합니다.Dummy Data이 인터페이스를 사용하여 문자 메시지를 보내거나 다른 API 인터페이스와 상호 작용할 수 있습니다.

GET방법 호출 예제:HttpQuery("http://www.baidu.com")POST방법 호출 예제:HttpQuery("http://www.163.com", "a=1&b=2&c=abc")

돌아갑니다.Header예를 들어:

HttpQuery("http://www.baidu.com", null, "a=10; b=20", "User-Agent: Mobile\nContent-Type: text/html", true)  // will return {Header: HTTP Header, Body: HTML}
  • HttpQuery함수에서 에이전트를 사용하는 설정:

    function main() {
        // 本次设置代理并发送http请求,无用户名,无密码,此次http请求会通过代理发送
        HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/")
    
        // 本次设置代理并发送http请求,输入用户名和密码,仅HttpQuery当前调用生效,之后再次调用HttpQuery("http://www.baidu.com")这样不会使用代理
        HttpQuery("socks5://username:password@127.0.0.1:8889/http://www.baidu.com/")
    }
    
    # HttpQuery不支持Python,可以使用Python的urllib2库
    
    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_Go[중고] 사용 방법 및exchange.Go기능은 유사하다. 예를 들어, 비동기 접근 거래소의 공공 인터페이스에서 집계된 시장 데이터를 얻는다.

    function main() {
        // 创建第一个异步线程
        var r1 = HttpQuery_Go("https://www.okx.com/api/v5/market/tickers?instType=SPOT")
        // 创建第二个异步线程
        var r2 = HttpQuery_Go("https://api.huobi.pro/market/tickers")
        
        // 获取第一个异步线程调用的返回值
        var tickers1 = r1.wait()
        // 获取第二个异步线程调用的返回值
        var tickers2 = r2.wait()
        
        // 打印结果
        Log("tickers1:", tickers1)
        Log("tickers2:", tickers2)
    }
    
    # 不支持
    
    // 不支持
    
  • 재검토 시스템에서 사용HttpQuery(...)함수: 리테스트 시스템에서 사용할 수 있습니다.HttpQuery(...)요청 보내기 (만 지원)GET요청) 데이터를 얻으세요. 검색시 20번의 다른 URL을 사용하도록 제한하고,HttpQuery(...)접속은 같은 URL을 두 번째 방문할 때 데이터를 저장합니다.HttpQuery(...)함수는 캐시 데이터를 반환합니다 (실제 네트워크 요청이 더 이상 발생하지 않습니다).

    우리는 어떤 서버나 장치에서 서비스 프로그램을 실행할 수 있습니다.HttpQuery(...)요청은 다음과 같이 전송되었으며 테스트에 사용된 Go 언어 서비스 프로그램은 다음과 같습니다.

    package main
    import (
        "fmt"
        "net/http"
        "encoding/json"
    )
    
    func Handle (w http.ResponseWriter, r *http.Request) {
        defer func() {
            fmt.Println("req:", *r)
            ret := map[string]interface{}{
                "schema" : []string{"time","open","high","low","close","vol"},
                "data" : []interface{}{
                    []int64{1564315200000,9531300,9531300,9497060,9497060,787},
                    []int64{1564316100000,9495160,9495160,9474260,9489460,338},
                },
            }
            b, _ := json.Marshal(ret)
            w.Write(b)
        }()
    }
    
    func main () {
        fmt.Println("listen http://localhost:9090")
        http.HandleFunc("/data", Handle)
        http.ListenAndServe(":9090", nil)
    }
    

    전략 재검토에서 사용HttpQuery(...)함수 전송 요청:

    function main() {
        // 可以写自己运行服务程序所在设备的IP地址
        Log(HttpQuery("http://xxx.xx.x.xxx:9090/data?msg=hello"));
        Log(exchange.GetAccount());
    }
    
    # HttpQuery不支持Python,可以使用Python的urllib2库
    
    void main() {
        // 可以写自己运行服务程序所在设备的IP地址
        Log(HttpQuery("http://xxx.xx.x.xxx:9090/data?msg=hello"));
        Log(exchange.GetAccount());
    }
    

    img

  • 요청에 대한 응답 데이터의 트로코딩을 지원하고 일반적인 코딩을 지원합니다. 지정PostData파라미터:{method: "GET",charset:"GB18030"}이 경우, GB18030 (GB18030) 를 사용할 수 있습니다.

코드 ((...)

Encode(algo, inputFormat, outputFormat, data, keyFormat, key string)이 함수는 입력된 매개 변수에 따라 데이터를 코딩합니다.

매개 변수algo코딩 계산에 사용되는 알고리즘, 지원 설정은:??raw?? (알고리즘을 사용하지 않는),??sign,??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,??ripmd160,??blake2b.256,??blake2b.512,??blake2s.128,??blake2s.256.data이 자료는 다른 자료와 비교해 볼 수 있습니다.inputFormat/outputFormat/keyFormat매개 변수 지원rawhexbase64string이 글은 이쪽에서 읽었습니다. 만약keyFormat0이 아닌 경우, 변수를 사용합니다.key암호화 (HMAC), 그렇지 않으면 기본 사용keyᅳ 변수algo설정:"sign"또는"signTx"이 경우,key

function main(){
    Log(Encode("md5", "raw", "hex", "hello"))
    Log(Encode("sha512", "raw", "base64", "hello"))
    Log(Encode("keccak256", "raw", "hex", "unwrapWETH9(uint256,address)"))

    Log(Encode("raw", "string", "hex", "example"))          // 6578616d706c65
    Log(Encode("raw", "hex", "string", "6578616d706c65"))   // example
}
def main():
    Log(Encode("md5", "raw", "hex", "hello", "", ""))
    Log(Encode("sha512", "raw", "base64", "hello", "", ""))
    Log(Encode("keccak256", "raw", "hex", "unwrapWETH9(uint256,address)", "", ""))

    Log(Encode("raw", "string", "hex", "example", "", ""))
    Log(Encode("raw", "hex", "string", "6578616d706c65", "", ""))
void main(){
    Log(Encode("md5", "raw", "hex", "hello"));
    Log(Encode("sha512", "raw", "base64", "hello"));
    Log(Encode("keccak256", "raw", "hex", "unwrapWETH9(uint256,address)"));
    
    Log(Encode("raw", "string", "hex", "example"));          // 6578616d706c65
    Log(Encode("raw", "hex", "string", "6578616d706c65"));   // example
}

매개 변수algo또한 지지합니다:text.encoder.utf8text.decoder.utf8text.encoder.gbktext.decoder.gbk문자열에 대한 암호화, 해독.

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

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

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

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

유닉스나노 (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);
}

유닉스 ((()

Unix(), 초 차원의 시간 을 반환합니다.

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

GetOS()

GetOS(), 호스트가 있는 시스템의 정보를 반환합니다.

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

애플 컴퓨터에서Mac OS운영 체제에서 실행되는 관리자 로그 출력:

GetOS:darwin/amd64

darwin그리고 이것은Mac OS시스템 이름입니다.

MD5 (String)

MD5(String), 변수 값: 문자열 유형.

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

로그 출력:

MD5 5eb63bbbe01eeed093cb22bb8f5acdc3

DBExec(...)

DBExec(), 변수 값: 문자열, 숫자 값, 부어 값, 빈 값 등이 될 수 있다. 귀환 값: SQLite 문장의 실행 결과를 포함하는 객체. 데이터베이스 인터페이스 함수DBExec()입력 매개 변수를 통해 디스크 데이터베이스 (SQLite 데이터베이스) 를 조작할 수 있다. 디스크 데이터베이스의 데이터에 대한 추가, 삭제, 확인, 변경 등의 작업을 수행하고 지원한다.SQLite문법. 리얼 디스크 데이터베이스의 시스템 저장 테이블:kvdbcfglogprofitchart이 표를 조작하지 마십시오. 참고:DBExec()이 함수는 디스크만 지원합니다.

  • 메모리 데이터베이스 지원 이 문제에 대해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)
        
        // 增加一条数据
        Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
        
        // 查询数据
        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)
        
        # 增加一条数据
        Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
        
        # 查询数据
        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);
        
        // 增加一条数据
        Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"));
        
        // 查询数据
        Log(DBExec(":SELECT * FROM TEST_TABLE;"));
    }
    
  • 테이블을 만들자

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))
    
    // 增加一条数据
    Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
    
    // 查询数据
    Log(DBExec("SELECT * FROM TEST_TABLE;"))
    
    // 修改数据
    Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))    
    
    // 删除数据
    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))
    
    # 增加一条数据
    Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
    
    # 查询数据
    Log(DBExec("SELECT * FROM TEST_TABLE;"))
    
    # 修改数据
    Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))
    
    # 删除数据
    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));

    // 增加一条数据
    Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"));
    
    // 查询数据
    Log(DBExec("SELECT * FROM TEST_TABLE;"));
    
    // 修改数据
    Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000));
    
    // 删除数据
    Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110));
}

UUID (()

UUID()이 함수는 디스크에만 적용되는 32비트 고유 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);
}

이벤트 루프 (타임아웃)

EventLoop(timeout)어떤 경우websocket읽거나,exchange.GoHttpQuery_Go같은 작업이 완료되면 다시 돌아옵니다.timeout0로 설정되면 이벤트가 발생하기 전에 기다립니다. 0보다 큰 경우 이벤트가 대기 시간이 지나고 0보다 작은 경우 가장 최근의 이벤트를 즉시 반환합니다.null이 문서는Event이벤트 트리거 타입. 이 함수는 디스크에만 적용됩니다.

코드에서 처음 호출EventLoop만약 이 사건의 초청이 끝난 후에 처음 시작된다면, 이 감시 사건의 메커니즘을 초기화할 수 있습니다.EventLoop호출, 이전 이벤트를 놓칠 것이다. 하위 시스템 포장에 있는 쿼리 구조는 최대 500개의 이벤트 호출을 캐시하여 프로그램이 실행되는 동안 적시에 호출되지 않으면EventLoop500개 이상의 캐시를 잃게 됩니다.EventLoop함수의 호출은 시스템 기본에 영향을 미치지 않습니다.websocket하지만, 이 모든 것은exchange.Go예를 들어, 동시 함수의 캐시, 이러한 캐시에 대해서는 여전히 각각의 방법을 사용하여 데이터를 추출해야 합니다.EventLoop이 함수들이 다시 돌아가기 전까지는EventLoop함수에서 반환 이벤트를 생성합니다.

EventLoop함수의 주요 용도는 새로운 네트워크 데이터를 수신하는 시스템 하층의 정책 계층을 알리는 것입니다.EventLoop함수가 이벤트를 반환할 때 모든 데이터 소스를 탐색하는 것만으로도 됩니다. 예를 들어,websocket이 글은 다른 글과 연결됩니다.exchange.Go생성된 객체는 데이터를 얻기 위해 시도합니다.클래스 라이브러리 링크

주 함수에서main()중간에 호출을 할 때, 주요 스레드의 이벤트를 경청합니다.JavaScript이 언어의 전략은__Thread()함수가 생성하는 스레드는 스레드의 실행 함수에서 호출하여 현재 스레드의 이벤트를 감청할 수 있습니다.

function main() {
    var routine_getTicker = exchange.Go("GetTicker")
    var routine_getDepth = exchange.Go("GetDepth")
    var routine_getTrades = exchange.Go("GetTrades")
    
    // Sleep(2000),如果这里使用Sleep语句,会导致之后的EventLoop函数错过之前的事件,因为等待了2秒,并发的函数

더 많은

qq89520C 함수에서 한 번만 반복하는 것이 문제입니다

와 와_C ((function, args...) 이 기본값은 3s입니까? 기본값을 변경하여 바로 _CDelay ((1000) 를 C ((function, args...) 이전에 설정할 수 있습니까? 한 번 설정해도 될까요?

하이클러스터: 만약 여러분이 1000개의 로봇을 동시에 만들 수 있다면, 또한 스트레스를 받지 않고도, 여러 개의 관리자를 만들 수 있습니다. 클러스터를 만드는 데 코드 예가 있습니까? 여러 호스트를 구축하여 작업을 분산하는 방법

뱅지1log ((talib.help (('MACD')); js에서만 사용할 수 있으며, 파이썬에서는 talib.help 속성이 없습니다.

cjz140_C (function, args...) 와 Sleep (Sleep) 의 차이점은 무엇일까요?

3263243ySetErrorFilter를 사용하다가 ErrorFilter를 어떻게 비어낼까요?

qq47898077만약 제3자 라이브러리를 이용하고 싶다면 어떻게 해야 할까요?

qq47898077만약 거래소 객체가 새로운 클래스를 정의하는 것을 계승하고자 한다면, 부모 클래스는 무엇을 채워야 하는가?

에탄우이 사이트는 다른 사이트와 비교해 볼 수 있습니다.

그 exange.IO (exange.IO "status") 는?

왜 sell의 함수가 회색으로 표시되는가? by가 사용할 수 있다면 어떻게 팔 수 있습니까?

왜 sell의 함수가 회색으로 표시되는가? by가 사용할 수 있다면 어떻게 팔 수 있습니까?

js는 언어학이 없는데, 哈哈哈.

js는 언어학이 없는데, 哈哈哈.

Don.분량의 중간선을 어떻게 써야 할까요?

쥬트르트시장 가격에 교환을 구매합니다.Buy ((1000) 성공하지 않으면 무엇을 반환합니까?

닌자쿠새로운 글꼴이 멋지네요.

해마Bitmex의 테스트 네트워크 ((testnet.bitmex.com) 에서도 API 인터페이스가 존재하지만 현재 거래소는 Bitmex 본부를 선택할 수 있으며 API 문서 주소는 https://testnet.bitmex.com/app/apiOverview입니다. 어떻게 지원할 수 있을까요?

cxjijinvar ret1 = exchanges[0].IO (("api", "future_estimated_price", "symbol=btc_usd"); 로그 (('ok 선물 예상 거래 가격', ret1); https://dn-filebox.qbox.me/d1ed268c1e75753c5d289447d279aa9d81e41b5f.png 다른 거래소의 기능 인터페이스를 호출하여 오류를 작성하는 이유는 무엇입니까?

알렌프로스트라인realTicker와 Ticker의 차이점은 무엇입니까? 최근에는 리얼티커와 리얼티커 API에서 언급되지 않은 두 가지 전략이 동시에 등장했습니다.

비전안녕하세요. 파이썬 개발자로서, 여러분의 API 문서가 무엇을 쓰고 있다고 생각하십니까? 필드 함수 인터페이스가 약간 이상해 보이지만, githubpage와 readdocs처럼 문서를 쓸 수 있나요?

알렌프로스트라인GetAccount: [EAPI: Rate limit exceeded] 어떻게 해결되는지 궁금합니다?

zhjx2314StochRSI가 지원되지 않습니다.

yhfggPython 정책 리얼 디스크에서 스크립트는 자신의 Ali 클라우드 서버 또는 botvs 클러스터에 있습니까?

yhfgg어떤 버전의 파이썬을 사용하시나요?

아예GetFee의 설명은 가 하나의 Fee 구조 을 반환하고, 하나의 구성자를 빼는 것이라고 생각됩니다.

zkwapjs에서 Talib를 호출하는 방법

yhfggpython 문서를 검색합니다

wmjbs123전략 편집자의 코드 배경은 검은색이 될 수 있습니까? 흰색 톱니, 밤에 코드를 작성하고 근시하기 쉽습니다.

Don.로봇의 WeChat 게시물에서 요약은 어떻게 설정합니까?

미쳤어요주문 (Order) 구조에 거래의 정비값 필드를 추가할 수 있습니까?

작은 것GetOrders: 모든 미완성 주문을 가져오기, Order 배열 구조를 반환하기, 중국 비트코인 거래에서 ETH, 가장 최근의 10 항목만 반환합니다. 여기에 중국 비트코인 ETH의 모든 미완성 주문을 반환하는 함수가 있습니까?

yhfgg통계 확률 이론에 필요한 수학 함수들은 어디서 사용되나요?

이 함수의 값은 $Cross (x, y) 입니다.

제 할머니는이 로그리셋은 모든 로그를 비워버립니다. 어떻게 하면 최근 몇 개의 로그를 삭제할 수 있을까요?

에드워드talib에서 CORRE 함수는 이식되지 않은 것처럼 보이거나 놓쳤습니까?

가난한 산에 있는 이 지표에 대한 참조 기능이 없는 것 같습니다.

작은 것이 k 라인 시간을 읽고 지금 시간으로 번역하는 방법 아, 이해가 안 돼, 너무 길어, 해결, 감사합니다

작은 것소수에서 숫자를 삭제하는 방법을 어떻게 쓸지, 저는 records.remove ((records[0]) 를 사용해서

스네키야우일반적으로는 시간 K선으로, 어떻게 일 K선의 ATR를 호출합니까?

스네키야우일반적으로는 시간 K선으로, 어떻게 일 K선의 ATR를 호출합니까?

57278863전통적인 선물의 가격과 주문을 얻는 방법을 배우십시오. 죄송합니다. 뿌리가 얇습니다.

키린이 자리에서 우리는 이 자리에서 다른 사람들을 만나게 될 것입니다.

작은 것제로, 전통적인 선물 거래의 예를 써줄 수 있나요?

작은 것복수 빈单을 동시에 보유할 때, 보유 상태를 어떻게 인쇄하느냐, 나의 인쇄 방식은 [object object][object object], 복수单과 빈单 보유 상태를 어떻게 얻을 것인가, 그리고 GetTicker ((), 그 주, 다음 주, 그리고 분기 모두 어떻게 얻을 것인가.

cxjijin선물 거래소는 GetTicker (,) 를 사용하여 시장을 얻을 수 있습니까?

팔아치워StochRSI는 어떤 지표를 추가할 수 있을까요?

모박스CancelOrder (orderId) 는 주문 번호에 따라 주문을 취소하고 true 또는 false를 반환합니다. true= 셀이 성공적으로 취소되었습니다.

모박스_G(K, V) 저장할 수 있는 글로벌 사전 목록 이 방법은 저장할 수 있는 글로벌 변수를 사용해서 다른 정책들 사이에서 데이터를 공유할 수 있는가?

플루피3D인기를 끌고

제로로그프로프리트리셋을 사용하여 수익 로그를 다시 설정할 수 있습니다. 이전 수익 차트의 역사는 사라집니다.

xy이 EA를 직접 복사할 수 있을까요?

스라이론맨이 플랫폼이 정말 멋지고, 정말 멋지고, 더 많은 사람들이 함께 소통하는 것 같아요.

작은 것이 언어는 어떤 언어이고, 학습 자료가 있나요?

jxhbtc데이터 오류 일주일 동안 로봇을 연결할 수 없습니다

이 지표는 단지 종결 가격을 계산하기 위한 지표가 아닌가요?

btcrobot안녕, 세상

작은 꿈_C 함수는 성공적으로 결과를 얻을 때까지 다시 시도합니다.

작은 꿈python의 talib 라이브러리는 설치가 필요합니다.https://www.botvs.com/bbs-topic/669 이 게시물을 참조하십시오.

작은 꿈Sleep는 프로그램이 아무 것도 하지 않고, 매개 변수가 설정되는 것을 기다리는 밀리초 수, _C는 매개 변수를 한 번 다시 호출하는 함수이다.

작은 꿈상속을 하지 않고 JS를 직접 객체에 엮어버린다.

작은 꿈로컬 편집기 원격 동기화 플러그인, 기본적으로 로컬 편집기 원격 오디션.

작은 꿈QQ 그룹에 오셔서,^^ 쉽게 토론하실 수 있습니다~

작은 꿈API 문헌에서 회색은 함수가 너무 많은 설명이 없이 회색, 파란색의 대표자가 더 많은 설명이 있고, 그것뿐이라는 것을 의미합니다.

작은 꿈ES6는 현재 지원되지 않습니다 ^^

작은 꿈QQ 그룹에 가서 문제를 설명해줘, 내가 대답해줄게 ^^

작은 꿈이 문서는 바로 오류를 반환하고 주문을 하지 않습니다. (사실 구매하기 위해 돈이 충분하지 않습니다!)

쥬트르트예를 들어, OKCoin, 만약 구매한 금액이 보유한 인민 화폐보다 많다면 어떤 수익을 올릴까요?

작은 꿈그리고 어떤 거래소에서 제가 OK 선물에서 주문 번호를 돌려보낼까요?

제로이미 실행 중인 트랜잭션 전환을 지원하고 있으며 최신 호스트를 다운로드해야 합니다. 지원 Bter/Poloniex 자세한 API 문서 트랜잭션 함수 탭 아래의 설명 (검색자 캐시를 비어 후 갱신하지 않으면 보이지 않습니다)

작은 꿈QQ, 제가 도와드릴게요.

직업적인 가정화이트리스트를 설정해야 합니다. 저는 호스트의 IP를 설정합니다.

작은 꿈이것은 하위 링크입니다. 설치되지 않았습니다. 서버가 응답하지 않았습니다. API KEY를 요청할 때 IP 주소를 설정해야합니까?

직업적인 가정이것은 당황스럽습니다... 제가 실행할 수 있는 전략은 비트 시대부터 고장 났고, GetAccount도 GetAccount에 액세스 할 수 없습니다: 포스트 http://api.btc38.com/v1/getMyBalance.php: read tcp 192.168.0.227:58596->211.149.148.144:80: wsarecv: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. 2017-05-23 21:08:24 비트 시대 오류 GetAccount: timeout 2017-05-23 21:08:02 비트 시대 오류 GetAccount: timeout 2017-05-23 21:07:40 비트 시대 오류 GetAccount: timeout 2017-05-23 21:07:20 다시 시작 IP 화이트리스트 문제인가요?

작은 꿈거래소의 서버는 응답하지 않았고, TCP 프로토콜은 세 번이나 악수되지 않았습니다.

직업적인 가정A connection attempt failed because the connected party did not properly respond after a period of time. A connection attempt failed because the connected party did not properly respond after a period of time. A connection attempt failed because the connected party did not properly respond after a period of time. A connection attempt failed because the connected party did not properly respond after a period of time. A connection attempt failed because the connected party did not properly respond after a period of time. A connection attempt failed because the connected party did not properly respond after a period of time.

작은 꿈안녕하세요! exchange.IO (api, ApiName, Args) 의 함수가 지원되지 않습니다. https://www.botvs.com/bbs-topic/812

직업적인 가정연결 시도가 실패한 이유는 연결된 당사자가 일정 기간 후에 제대로 응답하지 않았기 때문입니다.

직업적인 가정비트 시대가 지지하지 않나요?

작은 꿈https://dn-filebox.qbox.me/a709b30c6cc0a3565234b9e0c99b073f7ba8b454.png 이 글은 이쪽에서 읽었습니다.

닌자쿠예를 들어, 나는 폴로니엑스 (poloniex) 의 모든 통화 거래를 하고 싶지만, BOTvs (BOTvs) 가 지원하는 화폐는 몇 개 밖에 없으며, exchange.IO는 P 네트워크를 지원하지 않는 것 같습니다.

작은 꿈이 경우, 이 화면은 Exchange.IO를 호출할 수 있습니다.

닌자쿠어떤 API가 계정 검증을 필요로 할까요?

작은 꿈계정 검증이 필요하지 않은 API는 httpQuery (BotVS 문서를 참조하십시오) 를 사용할 수 있으며 실제 거래 API는 액세스해야합니다.

작은 꿈HttpQuery API를 사용하여 매개 변수를 전송할 수 있습니다: https://www.okcoin.com/api/v1/future_estimated_price.do?symbol=btc_usd, 이렇게 하면 됩니다. 계정 검증이 필요하지 않은 계정 API의 경우 플랫폼의 HttpQuery 함수를 직접 사용하여 계정과 관련된 경우 IO API를 사용합니다. 포스팅: https://www.botvs.com/bbs-topic/850

비전좋은 감사합니다. 좋은 API 문서를 기대합니다.

작은 꿈이 API를 어디서 보았는지 알려주세요.

작은 꿈https://dn-filebox.qbox.me/fe1a6f5563ed43a5357f858ecf8a50239619228e.png API 문서는 자바스크립트 언어로 설명되어 있으며, 파이썬 버전은 커뮤니케이션 커뮤니티 페이지의 꼭대기에 설명되어 있습니다.

제로안녕하세요, 제안에 감사드립니다. 현재 API 문서는 재구성 중입니다.

작은 꿈안녕하세요~ 접속 빈도가 제한을 넘었다는 표시입니다. https://dn-filebox.qbox.me/a09498920d04cac62624b7438a058d2098d8fb00.png 정책에서 Sleep (1000) 함수를 사용했습니까? 이 1000은 프로그램을 회당 1초 중단시키는 것입니다. 자체적으로 설정할 수 있습니다. 목적은 프로그램을 제어하는 것입니다. API에 액세스하는 빈도, 일부 거래소가 최대 액세스 제한을 설정하기 때문에 특정 방문 횟수를 초과하는 특정 시간이 액세스 거부, IP 주소를 차단합니다.

작은 꿈https://dn-filebox.qbox.me/c29ab7fc279e1b758355f137907cf52dc8257df6.png 제가 개인적으로 쓴 글은 STOCHRSI 지표와 비교해봤는데, 평론에 따르면, 속도가 약간 느리고 최적화되어 있고, 일시적으로 사용할 수 있습니다.

제로botvs가 제공하는 서버에서 다시 테스트를 하거나 자신의 호스트가 있는 서버에서 다시 테스트를 선택할 수 있습니다. 버전은 2.7.5입니다.

작은 꿈이 글은 현재 추가된 글입니다.

작은 꿈이제 배경 스타일을 직접 설정할 수 있습니다.

작은 꿈파이썬 문서가 작성되고 있습니다.

작은 꿈알리바의 문헌을 참고하세요.

hzzgood48 https://www.botvs.com/bbs-topic/276

작은 꿈이 경우, 이 경우, 이 경우, 이 경우, 이 경우, 이 경우.

제로오더의 AVGPrice 속성에 접근하면 거래소가 지원할 수 있고 지원하지 않는 거래소는 0으로 유지됩니다.

yhfgg제3자 자료는 어떻게 인용합니까?

제로mathjs가 만족할 수 없다면, 3자 라이브러리 복제입 정책만 찾아볼 수 있다. 컴파일 속도를 위해, 시스템은 일부 라이브러리만을 내장했다.

작은 꿈"이봐요, 이봐요, 이봐요, 이봐요, 이봐요, 이봐요.

감사합니다.

작은 꿈그룹에서? 당신은 설명서 버전의 디지털 통화 거래 클래스 코드 분석을 볼 수 있습니다. 그 안에 $.Cross 함수의 설명이 있습니다.

제로가장 최근의 항목을 삭제할 수 없고, 최신 몇 개만 유지할 수 있습니다.

키린포지션[i]를 사용하여 모든 포지션을 얻으려면 포지션은 대수입니다.

닌자쿠exchange.GetRecords ((PERIOD_D1));

키린내 전통적인 선물은 항상 "GetAccount: not login", "패드 잘못 입력되지 않았다면 로그인 할 수 없습니다".

제로기본값은 주입니다. 지정된 SetContractType를 얻기 위해서는 먼저 SetContractType가 필요합니다.

제로보시다시피, true는 거래소가 반환하는 취소 명령의 반환 값입니다. 하지만 실제로는 취소되지 않습니다.

모박스3q

제로잠시 동안은 그렇지 않노라

수안물론, MT4의 전용입니다.

제로자바스크립트 자료는 인터넷 상에 있습니다.

팔아치워네 문제가 해결됐나요?

제로대부분의 경우, 입력된 데이터는 직접 기록 또는 순수 가격의 배열이 될 수 있습니다.