発明者による量化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:xxxQQメールの例です.SMTPこのSSL方式は: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()この関数は後にこのエラーキャッシュをクリアし,次の呼び出しでは,前回の記録の誤った情報を返さない.

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(), インタラクティブコマンド文字列 ((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()返される値は,

シーンのデモンストレーションに関する情報

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(...)この関数は空の値を返します.

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_rawgzipgzip は,gzip をgzip に変換する.gzip_raw区切り符で|設定を追加するcompress=gzip_rawそして,&符号と次のモードパラメータを分離する.
Wsプロトコルでは,データ圧縮に関するパラメータは:mode=参数值 mode は,モードとして選択できます.dualsendrecv3つの種類.dual圧縮データを送信し,圧縮データを受信する.send圧縮データを送信する.recv圧縮データを受信するために,現地で解圧します.
socks5代理を設定する関連パラメータ:proxy=参数值 このプロキシは,ss5代理で設定され,パラメータ値形式は:socks5://name:pwd@192.168.0.1:1080,name は ss5 端末のユーザー名,pwd は ss5 端末のログインパスワード,1080 は ss5 端末のポートである.
WS プロトコルでは,底辺の自動再接続に関するパラメータを設定します:reconnect=参数值 reconnect は,再接続を設定するかどうか,reconnect=trueこのパラメータを設定していない場合,デフォルトで再接続しない.
WS プロトコルでは,底辺の自動再接続に関するパラメータを設定します: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ミリ秒) と指定される.
  • この2つのパラメータは,websocket効果: パラメータを転送する-1メッセージが表示されても表示されなくても,関数は即座に返します.例えば:ws.read(-1)│ │ パラメータを転送する-2函数には,メッセージが表示されても表示されないが,最新のメッセージのみが表示され,バッファリング領域のメッセージは削除される.ws.read(-2)

read()機能のバッファリング領域は, プログラムが実行されている場合,read()函数呼び出し間の時間間隔が長すぎると,データの蓄積が発生する可能性がある. これらのデータは,バッファローンのデータ構造で,キューとして保存され,最大2000個である. 2000を超えると,最新のデータがバッファローンの内に入り,最も古いデータは削除される.

シーンはread関数参数 パラメータなし パラメータ: -1 パラメータ:-2 パラメータ:2000,単位はミリ秒です
バッファーは既にデータです 古いデータに戻る 古いデータに戻る 更新されたデータに即座に戻る 古いデータに戻る
バッファーはデータがない ブロックしてデータがあるまで戻す すぐには空値に戻します すぐには空値に戻します 2000ミリ秒待って,データがない場合は空値,データがある場合は返します.
ws接続が切断されたり,底部を再接続されたりすると read ((() 関数は空の文字列,すなわち:"",write ((() 関数は0を返し,この状態を検知します. Close ((() 関数は接続を終了させることができます.
  • WSS (WebSocket) プロトコルに対応する サイト運営者 (株主) は,Binanceの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のWebソケット行情インターフェースにアクセスするには:

    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("退出");
    }
    

    このトークンへのアクセスのためのWebソケット市場インターフェース:

    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のWebソケット認証インターフェースにアクセスするには:

    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) は,

HttpQuery(Url, PostData, Cookies, Headers, IsReturnHeader)ネットワークURLへのアクセス. 参数値: すべて文字列タイプ.

警告:

  • HttpQuery(...)機能のみをサポートします.JavaScript言語は.
  • Python言語は使用できますurllibメールの送信は,メールの送信先から開始されます.

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ギャップ.

2番目のパラメータ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文字列には第3項が必要ですが,必要ありません.POST第2項を空値にしてください. 模擬テストでは,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が2度目にアクセスされたときにデータをキャッシュします.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) を実現します.

暗号化する

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,mdrip160,ke2b.256,ke2b.512,ke2b.512,ke2s.128,ke2s.256──パラメータ.data処理されるデータ.inputFormat/outputFormat/keyFormatパラメータサポートrawhexbase64string暗号化方法はー もしkeyFormat任意の項目を表示します.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 (ユニックス)

Unix()2秒レベルタイムキーを戻します.

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

GetOS (ゲットOS)

GetOS()管理者のシステムへの情報を返します.

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

AppleのコンピュータでMac OSOS で実行されている管理者ログの出力:

GetOS:ダーウィン/amd64

darwinこれはMac OSシステム名.

MD5 (文字列)

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この関数のパラメータはスクワール文は:初期的には,メモリデータベースで動作し,文書を書き込むことなく,速度が速い.持続保存を必要としないデータベース操作に適しています.

    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()この関数は実力盤のみに適用されます.

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件のイベント呼び出しをキャッシュする.EventLoop削除すると,500個以上のキャッシュが失われます.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関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C関数で,_C_関数で,_C_関数で,_C_C_関数で,_C_C_関数で,_C_C_関数で,_C_C_C_関数で,_

ハワイ ハワイ_C ((function, args...) のデフォルトは3sですか?デフォルトで_CDelay ((1000) を直接_C ((function, args...) の前に設定することができますか?一度設定できますか?

ランチャイエクラスター:もし1000個のボットを同時に ストレスを感じずに作るとしたら 複数の管理者が作られ 課題を分散できます 複数の管理者を構築して,タスクを分散させる方法.

ワングイ1log ((talib.help (('MACD'));jsでしか使えない.pythonではtalib.help属性がない...

cjz140_C (関数, args...) と Sleep (関数) の違いは?

3263243ySetErrorFilter の後に ErrorFilter を削除するにはどうすればよいですか?

QQ47898077データベースの利用は可能でしょうか?

QQ47898077交換対象に定義された新しいクラスを継承する場合は,父クラスは何を入力すべきですか?

エタヌウローカル・デュッキング・ツールはありますか?

ペンギンこのサイトは,インターネットのインターネット・サービスです.

ペンギンsell の関数が灰色になっているのは,by が使えなくなっていることを表すためでしょうか.

ペンギンsell の関数が灰色になっているのは,by が使えなくなっていることを表すためでしょうか.

ペンギン言語能力が低いので,

ペンギン言語能力が低いので,

Don.平均線を書き換えるには,

ツィートルテ市場価格で買い換える. 買い換える (1000) は,失敗した場合に返されるものは何ですか?

ニン公子この新しいフォントは素敵です.

河馬Bitmexのテストネットワーク ((testnet.bitmex.com) もAPIインターフェイスがありますが,現在,取引所はBitmexのメインステーションのみを選択できます.APIドキュメントの住所はhttps://testnet.bitmex.com/app/apiOverviewです. どうしたら支援できるでしょうか?

エクシジンvar ret1 = exchanges[0].IO (("api", "future_estimated_price", "symbol=btc_usd"); Log (('ok 期貨 預期 配送 価格', ret1); https://dn-filebox.qbox.me/d1ed268c1e75753c5d289447d279aa9d81e41b5f.png 取引所の機能インターフェースを呼び出し,エラーを表示する場合は,なぜですか?

アレン・フロストラインrealTickerとTickerの違いは何ですか? 最近,リベリー策略が書き換えられ,両 API が同時に登場していますが,前者については言及されていないようです.

ビジョンPython の開発者として,API 文書に何が書かれていると思いますか? フィールド関数インターフェースが奇妙に見えるので,githubpageやreaddocsのように文書を書くことができますか?

アレン・フロストラインGetAccount: [EAPI:Rate limit exceeded] どうしたらいいか知りたいです. QQは持っていません.微信グループなどありますか? ありがとうございました.

zhjx2314StochRSI はサポートされていませんが,すぐに追加できますか?

イーフグPython ポリシーのリアルディスクでは,スクリプトは自分の Ali Cloud サーバーか botvs 集群か?

イーフグPythonのどのバージョンを使っていますか?

じっとしてGetFeeの解釈は,がFee構造を返し,単語を省略しているはずである.

スクワップこの例では,JSでタリブを呼び出す方法があります.

イーフグPythonのドキュメントを検索する

Wmjbs123 について策略編集のコードの背景は黒か白か? 刺眼,夜にコードを書く,近視が容易

Don.ロボットの微信の推し込みの概要を設定するにはどうすればいいですか?

数字狂い注文 (Order) 構造に,取引の均等価格のフィールドを追加できますか?

小さいことGetOrders: すべての未完成の注文を取得し,Order配列構造を返します. 中国のビットコイン取引ETHでは,最近10項のみ返します.

イーフグ統計的確率論の数学関数は何処で使えますか?

ジーバンこの関数の返した値は何でしょうか?

祖母が言ったLogReset はすべてのログを空にして,保存する記号を指定する数字参数を持つことができます. ブログの最新記事を削除するにはどうすればいいですか?

エドワード・ギューtalib のCORRE 関数は移植されていないように見えるか?

貧乏山の指標参照機能がないようです!

小さいものk線時間の読み取りは,どのように現在時間に翻訳されます? ああ,わからない,あまりにも長い,解決,ありがとう.

小さいもの列の数字を削除する方法,私は records.remove ((records[0]) と使っています.

スネークイユ通常,K線は時間K線で,日K線のATRはどのように呼び出すか.

スネークイユ通常,K線は時間K線で,日K線のATRはどのように呼び出すか.

57278863伝統的なフューチャーで価格を得たり,下注したりする方法について学びましょう.

キリン伝統的先物取引の例を!

小さいもの伝統的な先物取引の例を書いてください.

小さいもの複数の空单を同時に保持しているとき,保有状態をどのように印刷するか,私の印刷方法は[object object][object object],多单と空单保有状態をどのように取得するか,またGetTickerもあります. その週,次の週,および四半期をどのように取得するか,その週の価格,括弧の当週,次の週,および四半期を私は書いています.

エクシジンフューチャー取引所はGetTickerで取引を入手できますか? そのタイプの契約取引を返します (前週,次週...)

売るストックRSIの指標は?

モモックスCancelOrder ((orderId) 注文番号に基づいて注文をキャンセルし,trueまたはfalseを返します. true=セルが成功してキャンセルされましたか?

モモックス_G(K,V) 保存可能なグローバル辞書表 この方法で保存されるグローバル変数は,異なるポリシー間のデータ共有に使用できますか?

フルフィー3D人気急上昇

ゼロログプロフィットリセットで収益ログをリセットできます.

xcy直接EAをコピーして使えますか?

スイロンマンこのプラットフォームは素晴らしい 素晴らしい グループでの交流が多くなった

小さいものこの言語は,どんな言語で,学習資料があるのでしょうか?

Jxhbtc"データエラー" "週間 ロボットに接続できず 解決方法

ほら価格の計算は,決済価格を計算するだけのものですか?

btcrobot についてこんにちは 世界

小さな夢_C関数は,成功するまで,無意識に再挑戦します.

小さな夢Pythonのタリブライブラリをインストールする必要があります.https://www.botvs.com/bbs-topic/669 この記事を参照してください.

小さな夢スリープは,プログラムが何もしず,パラメータが設定されるのを待つミリ秒数, _Cは,パラメータを1回再呼び出し,転送された関数である.

小さな夢継承せずに,JSが直接オブジェクトに包み込まれます. {name: "新しいオブジェクト", old_exchange : exchange[0],...... }

小さな夢ローカルエディタ リモートシンクロプラグイン,基本的にはローカルエディタ リモートデュッキング.

小さな夢QQグループに来て,^^ 簡単に議論できます~

小さな夢APIのドキュメントでは,この関数が灰色で表示され,青色で表示され,説明が多くないことを意味する.

小さな夢ES6はサポートされていません ^^

小さな夢QQのグループへ行って,質問を説明して,私は答えます ^^

小さな夢メールの返信は"エラー"で,注文はしません. (実際は買おう,お金が足りない!)

ツィートルテOKCoinは,持っていた人民幣よりも多く購入された場合,何が返されますか?

小さな夢OKフューチャーで注文番号を返します.

ゼロすでに実行時に取引ペアを切り替えるサポートがあり,最新のホストをダウンロードする必要があります.サポート Bter/Poloniex 詳細 API 文書 取引関数のバーの説明 (ブラウザキャッシュを空にして,表示できない場合は刷新)

小さな夢QQ,私はあなたの質問を探します.

職業養子家庭ホストのIPを設定します. このIPは,ホストのIPを設定します.

小さな夢サーバーが応答していない.API KEYのリクエスト時にIPアドレスを設定しますか?

職業養子家庭これは恥ずかしいです.... 接続されたパーティが時間内に適切に応答しなかったため,または接続されたホストが応答に失敗したため,接続の試みが失敗した wsarecv: 2017-05-23 21:08:24 ビット時代 間違い GetAccount:タイムアウト 2017-05-23 21:08:02 ビット時代 誤り GetAccount:タイムアウト 2017-05-23 21:07:40 ビット時代 エラー GetAccount:タイムアウト 2017-05-23 21:07:20 再起動 IPのホワイトリストの問題なのか?

小さな夢取引所のサーバーは応答せず,TCPプロトコルは3回握手も確立されていない.

職業養子家庭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がサポートする通貨はわずかです.

小さな夢交換.IO を呼び出すことができます.

ニン公子アカウントの認証が必要なAPIはどうでしょう?

小さな夢アカウント認証を必要としないAPIは httpQuery (BotVSドキュメントを参照してください) を使用できますが,実際の取引APIにはアクセスが必要です.

小さな夢HttpQueryのAPIのパラメータを転送するには,https://www.okcoin.com/api/v1/future_estimated_price.do?symbol=btc_usdを使用できます. 口座の検証を必要としない取引所のAPIは,プラットフォーム上のHttpQuery関数を直接使用し,アカウントに関連した APIは IOAPIを使用します (IOはこれらの認証を必要としない取引のAPIをサポートしません). 投稿: https://www.botvs.com/bbs-topic/850

ビジョン素晴らしいAPIドキュメントを期待しています.

小さな夢リアルティッカーのAPIはどこで見られるの?

小さな夢https://dn-filebox.qbox.me/fe1a6f5563ed43a5357f858ecf8a50239619228e.png APIドキュメントはJavaScript言語で記述され,python版は交流コミュニティのページのトップに記述されている.

ゼロこんにちは,ご提案ありがとうございます. APIのドキュメントが現在再構築中です.

小さな夢"こんにちは"は,アクセス頻度が制限を超えていることを示しています. https://dn-filebox.qbox.me/a09498920d04cac62624b7438a058d2098d8fb00.png 戦略ではSleep ((1000) 機能を使用していますか? この1000は,プログラムがラウンドごとに1秒間停止させ,自律的に設定できます. 目的はプログラムのアクセスAPIの頻度を制御することです.

小さな夢https://dn-filebox.qbox.me/c29ab7fc279e1b758355f137907cf52dc8257df6.png 私の個人的に書いたSTOCHRSIの指標は,OKと比較されているが,速度が少し遅い,最適化が待っています.

ゼロbotvs で提供されるサーバーでの復習または自社のホストのサーバーでの復習を選択できます.バージョンは2.7.5です.

小さな夢投稿者: 藤井 さん

小さな夢背景のスタイルを自分で設定できます.

小さな夢Pythonのドキュメントが書き込まれています.

小さな夢タリブ・ライブラリのサポートも可能です.

ハズグッド48 https://www.botvs.com/bbs-topic/276

小さな夢戦略広場には,https://www.botvs.com/strategy/15098という例があるようです.

ゼロ取引所がサポートするオーダーのAvgPrice属性にアクセスできます. サポートしない取引所は0の属性になります.

イーフグ引用された資料は?

ゼロmathjs が満足できない場合は,第三者ライブラリをコピーインポートするポリシーを検索するだけです. 編成速度のために,システムはごく少数のライブラリしか内蔵していません.

小さな夢グループで問題がある場合,Mをすることができます~私は基本的にオンラインです.

ジーバンありがとうございました

小さな夢暗号通貨取引のデータベースの コード解析の解説を見ることができます. $Cross関数の解説があります.

ゼロ最近の記事は削除できませんが,最新の記事のみを保存できます.

キリンポジション[i] を使って,すべての保持を取得するには,ポジションは数列である.

ニン公子exchange.GetRecords ((PERIOD_D1)) を取得する

キリン私の伝統的なフューチャーとは"GetAccount: not login",パスワードを間違えてない,ログインできない"というものです.

ゼロデフォルトでは SetContractType が求められます.

ゼロこの true は,取引所が返したキャンセル命令の返し値です. しかし,実際にキャンセルした場合は,取引所内部での処理によって異なります.

モモックス3q

ゼロ暫くの間は別れられる.

シュアンシュアンMT4の専用サイトです.

ゼロJavascriptの情報はネット上にあります.

売る問題を解決した?

ゼロ直接レコードまたは純粋な価格の配列になります.