資源の読み込みに... 荷物...

グローバル

バージョン

システムの現在のバージョン番号を返します.

現在のシステムバージョン番号,例えば3.6- わかった 文字列

バージョン

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

システムバージョン番号は,dockerのプログラムのバージョン番号です.

眠れ

睡眠機能で プログラムが一時停止します

睡眠 (ミリ秒)

についてmillisecondパラメータは睡眠時間とミリ秒数を設定するために使用されます. ミリ秒 本当 番号

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

実行する際にSleep(1000)1ミリ秒未満の睡眠時間,例えば設定をサポートします.Sleep(0.1). それは最小パラメータをサポートします0.0000011ナノ秒は1e-6ミリ秒です 戦略を書き出すときPython言語,Sleep(millisecond)投票間隔,待機時間操作のために使用する必要があります.time.sleep(second)機能Pythonほらtime図書館を活用したからです.time.sleep(second)バックテストを行うとき (バックテストシステムの時間列をスキップするのではなく),戦略が非常にゆっくりとバックテストするようになります.

IsVirtual は

戦略の実行環境がバックテストシステムであるかどうかを決定する.

ストラテジーは,真価を返します.trueバックテストシステム環境で実行される場合. 戦略は誤り値を返します.例えば:falseリアルな取引環境で実行される場合 ボール

IsVirtual (バーチャル)

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

現在の実行環境がバックテストシステムであるかどうかを決定し,バックテストとライブ取引の違いと互換性を確保するために使用します.

郵便

メールを送る

メールの送信が成功すると,実際の値が返されます.true失敗した配送が誤った値を返します.false- わかった ボール

メール ((smtpサーバー, smtpユーザー名, smtpパスワード, mailTo,タイトル,ボディ)

指定するために使用されますSMTPメール送信者のサービスアドレス smtpサーバー 本当 文字列 メール送信者のメールアドレスを指定するために使用されます. smtpユーザー名 本当 文字列 についてSMTPメール送信者のメールボックスへのパスワードです smtpパスワード 本当 文字列 メール受信者のメールアドレスを指定するために使用されます. mailTo に 本当 文字列 メールアドレス タイトル 本当 文字列 メールボディ 身体 本当 文字列

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

についてsmtpPasswordパラメーターは,パスワードを設定しますSMTPメールボックスのパスワードではありません 設定するときにsmtpServerパラメータに直接ポート番号を追加することができます.smtpServer例えばQQメールsmtp.qq.com:587試験可能である. エラーが報告された場合:unencryped connection変更する必要があります.smtpServerについてMailパラメータ形式は:ssl://xxx.com:xxx例えば,ssl方法SMTPQQメールでは:ssl://smtp.qq.com:465またはsmtp://xxx.com:xxx- わかった バックテストシステムでは機能しません

{@fun/Global/Mail_Go メイル_Go}

メイル_ゴー

アシンクロンバージョンMail function.

についてMail_Goこの関数で,同じオブジェクトをすぐに返します.waitメール配信の結果を取得する同期オブジェクトの方法. メール配信が成功すると,真値が返されます.true失敗した配送が誤った値を返します.false- わかった オブジェクト

メール_Go (smtpサーバー, smtpユーザー名, smtpパスワード, mailTo,タイトル,ボディ)

指定するために使用されます.SMTPメール送信者のサービスアドレス smtpサーバー 本当 文字列 メール送信者のメールアドレスを指定するために使用されます. smtpユーザー名 本当 文字列 についてSMTPメール送信者のメールボックスのパスワードです smtpパスワード 本当 文字列 メール受信者のメールアドレスを指定するために使用されます. mailTo に 本当 文字列 メールアドレス タイトル 本当 文字列 メールボディ 身体 本当 文字列

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

バックテストシステムでは機能しません

{@fun/Global/Mail Mail} メール・メール

SetErrorFilter を設定する

フィルターエラー ログ

SetErrorFilter (フィルター設定)

規則式文字列です フィルター 本当 文字列

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

一般的なエラーをフィルタリングする

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

インターフェースエラーメッセージをフィルタリングします.

この正規表現にマッチしたエラーログはログシステムにアップロードされません.複数のフィルター条件を設定するために,複数の kere (数回数に制限はありません) を呼び出すことができます.複数の kereをセットした正規表現は,蓄積され,同時に有効になります.エラーログをフィルターするために使用される正規表現をリセットするために,空の文字列を設定できます:SetErrorFilter(""). フィルタリングされたログは,頻繁にエラー報告がデータベースファイルを膨らませるのを防ぐために,ドッカーディレクトリ内のライブ取引IDに対応するデータベースファイルに書き込まれません.

GetPid は

リアルタイムで取引の プロセスIDを取得します

リアルタイム取引プロセスIDを返します. 文字列

GetPid (ゲットピッド)

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

GetLastError を取得する

最後のエラーメッセージを受け取った.

最後のエラーメッセージ 文字列

削除する

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

バックテストシステムでは機能しません

GetCommand を取得する

戦略インタラクションのコマンドを受け取る

返したコマンドの形式はControlName:Data. ControlNameコントロールの名前で,Dataインタラクティブなコントロールに入力ボックス,ドロップダウンボックス,その他のコンポーネントがない場合 (例えば入力ボックスのないボタンのコントロール),返されるコマンドフォーマットはControlNameコントロールの名前だけ返します. 文字列

コマンドを取得する

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

インタラクションコマンドを検出し,Logインタラクションコマンドが検出されたときにそれを出力する機能です.

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

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

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

例えば,戦略インタラクティブコントロールは入力ボックスなしでコントロールを追加します.インタラクティブコントロールは以下のように命名されます.buy制御説明の情報は:buyインタラクティブなコントロールの名前は:sell制御説明メッセージは次のとおりです.sellインタラクションコードは,異なるインタラクションコントロールに対応するように戦略に設計されています.

バックテストシステムでは機能しません

GetMeta を取得する

戦略登録コードを生成するときにメタの値を書き出す.

Metaデータです 文字列

GetMeta (メタ) を取得する

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

応用例:使用Meta戦略によって運用される資産の量を制限する.

戦略の賃貸者のために資本制限を行う必要があります.Meta登録コードを生成する際に設定された値は 190文字を超えないこと,GetMeta()メタデータがない場合 (Meta戦略登録コードを生成する際に設定され,GetMeta()バックテストシステムでは動作しません.

ダイヤル

原始語Socketアクセス,サポートtcp, udp, tls, unix4つの一般的な通信プロトコルをサポートします.mqtt, nats, amqp, kafkaデータベースに接続するサポート:sqlite3, mysql, postgres, clickhouse.

についてDial()標準呼び出しでは,接続オブジェクトが3つのメソッドを持つ.read, writeそしてclose.....readデータを読み取るために使用されます.writeデータを送信するために使用されます.close接続を閉めるために使用されます. についてreadこの方法は次のパラメータをサポートします.

  • パラメータが渡されない場合は,メッセージが利用可能になるまでブロックし,返します.ws.read().
  • パラメータとして渡された場合,単位はミリ秒で,メッセージ待ちタイムアウト期間を指定します.例えば:ws.read(2000)2秒 (2000ミリ秒) のタイムアウトを指定する.
  • 次の2つのパラメータは WebSocket にのみ有効である. パラメータを転送する-1機能がメッセージの有無に関わらず即座に返信することを意味します.例えば:ws.read(-1)- わかった パラメータを転送する-2つまり,この関数はメッセージを含むか,ないか,すぐに返信しますが,最新のメッセージのみが返信され,バッファ化されたメッセージは捨てられます.例えば,ws.read(-2).

read()機能バッファの記述: WebSocket プロトコルによって押された受信データは,戦略の間の時間間隔がread()函数呼び出しが長すぎる.これらのデータはバッファーに格納され,そのデータ構造は最大2000のキューである.2000を超えると,最新のデータがバッファーに入力され,最も古いデータは削除される.

シナリオ パラメーターなし パラメータ: -1 パラメーター: -2 パラメータ: 2000 ミリ秒
すでにバッファにあるデータ 最古のデータをすぐに返します. 最古のデータをすぐに返します. 最新のデータをすぐに返します 最古のデータをすぐに返します.
バッファーにデータがない データにブロックされたときに戻す すぐに null を返します すぐに null を返します 2000 ms を待って,データがない場合は null を返します.データがある場合は null を返します.
WebSocket 接続は,底辺の接続によって切断または再接続されます. read() 機能は空の文字列を返します.つまり: ,そして write() 機能は0を返します.状況が検出されます. Close() 機能を使用して接続を終了できます.または自動再接続を設定している場合は,それを終了する必要はありません.底にあるシステムは自動的に再接続します.

オブジェクト

ダイヤル (住所) ダイヤル (住所,タイムアウト)

アドレスを要求します アドレス 本当 文字列 タイムアウト秒 タイムアウト 偽り 番号

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

ダイヤル関数呼び出しの例:

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

バイナンス WebSocket ticker インターフェースにアクセスするには:

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

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

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

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

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

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

OKXの WebSocket ticker インターフェイスへのアクセス:

var ws = null               

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

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

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

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

Huobiの WebSocket ティッカーインターフェイスへのアクセス:

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

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

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

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

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

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

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

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

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

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

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

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

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

OKXのWebSocket認証インターフェイスにアクセスするには:

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

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

データベースに接続する際に Dial 関数によって返される接続 オブジェクトには 2 つの独自のメソッド 関数があります.

  • exec(sqlString): SQL 文を SQL 文と類似した方法で実行するために使用されます.DBExec() function.
  • fd()についてfd()この関数は,他のスレッドが再接続するために使用するハンドル (例えば,ハンドル変数はハンドル) を返します (Dial によって作成されたオブジェクトが既に実行によって閉じられた場合でも).close()接続を閉じる機能) を使って,ハンドルをハンドルにDial()機能などDial(handle)再利用接続 ダイヤル関数と接続する例ですsqlite3 database.

詳細についてaddressパラメータ,|通常の住所の後ろの記号:wss://ws.okx.com:8443/ws/v5/publicもしそうなら|パラメータ文字列の文字列,その後||機能のパラメータの設定です. それぞれのパラメータは,&文字は,例えば,ss5プロキシと圧縮パラメータは次のように組み合わせることができます.Dial("wss://ws.okx.com:8443/ws/v5/public|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv")

ダイヤル機能のアドレスパラメータによってサポートされる機能 パラメータ説明
WebSocket プロトコルのデータ圧縮に関連するパラメータ: compress=パラメータ値 gzip は標準 gzip でない場合は,拡張メソッド: gzip_raw を使用できます.
WebSocket プロトコルデータ圧縮に関連するパラメータ: mode=パラメータ値 モードは圧縮モードで,モードパラメータは二重で,送信,recv. dualは二方向圧縮,圧縮データを送信,圧縮データ受信.送信は圧縮データを送信する.recvは圧縮データを受け取る,ローカルデコンプレッション.
WebSocket プロトコルは,元となる自動再接続関連パラメータを設定します: reconnect=パラメータ値 reconnect は reconnect を設定するかどうか, reconnect=true は reconnect を有効にするかどうかです.このパラメータが設定されていない場合,デフォルトでは reconnect はありません.
WebSocket プロトコルは,基礎となる自動再接続関連パラメータを設定します: interval=パラメータ値 intervalは再試行間隔,ミリ秒で,interval=10000は再試行間隔10秒,デフォルトは1秒で,設定されていない場合,つまりinterval=1000です.
WebSocket プロトコルは,基礎となる自動再接続関連パラメータを設定します: payload=パラメータ値 payload は WebSocket が再接続されたときに送信されるサブスクリプションメッセージです.例えば: payload=okokok.
靴下5のパラメータに関するプロキシ:プロキシ=パラメータ値 プロキシは ss5 プロキシ設定です パラメータ値形式: socks5://name:pwd@192.168.0.1:1080名前はSS5サーバーのユーザー名 pwdはSS5サーバーのログインパスワード 1080はSS5サービスポートです

についてDial()この機能はライブ取引のみに対応しています ダイヤル関数を使用してデータベースに接続するときは,接続文字列は各データベースのgo言語ドライバープロジェクトを参照して記述されます.

サポートされているデータベース 推進プロジェクト 接続文字列 コメント
スクライト3 github.com/mattn/go-sqlite3 sqlite3://ファイル:test.db?キャッシュ=共有&モード=メモリ についてsqlite3://前項は sqlite3 データベースが使用されていることを示します.Dial("sqlite3://test1.db")
mysql github.com/go-sql-driver/mysql mysql://username:yourpassword@tcp (あなたのパスワード@tcp)localhost:3306) /あなたのデータベース?チャルセット=utf8mb4
産後 github.com/lib/pq postgres://user=postgres dbname=yourdatabase sslmode=disable password=yourpassword ホスト=ローカルホスト ポート=5432
クリックハウス github.com/ClickHouse/clickhouse-go クリックハウス://tcp://host:9000?ユーザー名=ユーザー名&パスワード=あなたのパスワード&データベース=youdatabase

確認してください.payload設定された内容addressパラメータには文字が含まれています.=解析に影響を与える可能性があります.addressパラメータDialこの例のようなものです

backPack Exchange websocket のプライベートインターフェースの呼び出し例:

var client = null

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

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

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

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

function onexit() {
    client.close()
}

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

次の呼び出しはうまく動作します.

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

文字を書き込むとpayload機能しない場合,例えば

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

JavaScriptだけが JavaScript の使用をサポートしています.mqtt, nats, amqpそしてkafkaダイヤル関数における通信プロトコル. JavaScript 言語戦略コードは,4つのプロトコルの使用を示す例として使用されます.mqtt, nats, amqpそしてkafka:

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

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

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

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

        Sleep(1000)
    }
}

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

詳細なドキュメント参照:FMZを調査する: ライブ取引戦略間の通信プロトコルの実践

HttpQuery をインストールする

Http リクエストを送信します.

リクエストの応答データを返します.JSON文字列で解析できます.JSON.parse()機能についてJavaScript言語戦略とjson::parse()機能についてC++言語戦略.デバッグがオプション構造で true に設定されている場合,返却値はオブジェクト (JSON) である.デバッグが false に設定されている場合,返却値は文字列である. 文字列,オブジェクト

HttpQuery (URL) HttpQuery (URL,オプション)

Http リクエスト URL url 本当 文字列 例えば,Http リクエストに関連する設定は,次のように構造化できます:

{
    method: "POST",
    body: "a=10&b=20&c=30",
    charset: "UTF-8",
    cookie: "session_id=12345; lang=en",
    profile: "chrome_103",
    debug: false,
    headers: {"TEST-HTTP-QUERY": "123"},
    timeout: 1000
}
  • プロフィール: ブラウザをシミュレートするために使用tls指紋を サポートされている設定には以下のオプションが含まれます. chrome_: は"chrome_103", "chrome_104", "chrome_105", "chrome_106", "chrome_107", "chrome_108", "chrome_109", "chrome_110", "chrome_111", "chrome_112", "chrome_117"ありがとうございました サファリ"safari_15_6_1", "safari_16_0", "safari_ipad_15_6", "safari_ios_15_5", "safari_ios_15_6", "safari_ios_16_0"ありがとうございました ファイアフォックス:"firefox_102", "firefox_104", "firefox_105", "firefox_106", "firefox_108", "firefox_110", "firefox_117"ありがとうございました オペラ"opera_89", "opera_90", "opera_91"ありがとうございました ザランド:"zalando_android_mobile", "zalando_ios_mobile"ありがとうございました ナイキ"nike_ios_mobile", "nike_android_mobile"ありがとうございました 雲の摩天楼"cloudscraper"ありがとうございました mms_:"mms_ios"ありがとうございました メッシュ_:"mesh_ios", "mesh_ios_1", "mesh_ios_2", "mesh_android", "mesh_android_1", "mesh_android_2"ありがとうございました 確認した"confirmed_ios", "confirmed_android"ありがとうございました わかった."okhttp4_android_7", "okhttp4_android_8", "okhttp4_android_9", "okhttp4_android_10", "okhttp4_android_11", "okhttp4_android_12", "okhttp4_android_13",
  • debug: に設定されているときtrueについてHttpQuery返信メッセージを返します.false単一のデータです.Body返信メッセージが返されます.
  • タイムアウト:タイムアウト設定で,セット1000は1秒のタイムアウトを意味します.
  • Charset: GB18030 のような要求応答データのトランスコードをサポートする. この構造のすべてのフィールドはオプションで,例えば,profileフィールドは,外に出ることができます.

オプション 偽り オブジェクト

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

OKX パブリック ティッカー API インターフェースへのアクセス例.

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

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

HttpQuery関数はプロキシ設定を使用します.

についてHttpQuery()機能のみサポートJavaScript, C++言語Python言語はurllibHttp リクエストを直接送信します.HttpQuery()取引所のインターフェースにアクセスするために主に使用されます. チケット情報などの公開インターフェースなど,署名を必要としません.HttpQuery()バックテストシステムでリクエストを送信するために使用できます (ただGETバックテストは,異なる研究機関への20回の訪問に限定されています.URLsそしてHttpQuery()データをキャッシュします.URL2回目でアクセスされる場合,HttpQuery()この関数はキャッシュされたデータを返し,実際のネットワークリクエストは起こらない.

{@fun/Global/HttpQuery_Go HttpQuery_Go} このビデオは,

HttpQuery_Go をインストールする

Http リクエストを送信します.HttpQuery function.

についてHttpQuery_Go()Http リクエストの結果を取得するために使用できる並行オブジェクトをすぐに返します.wait方法 方法JSON.parse()解析するために使用できます.JSON.parse()機能についてJavaScript言語の戦略について
オブジェクト

HttpQuery_Go (URL) HttpQuery_Go (URL,オプション)

Http リクエスト URL url 本当 文字列 例えば,Http リクエストに関連する設定は,次のように構造化できます:

{
    method: "POST",
    body: "a=10&b=20&c=30",
    charset: "UTF-8",
    cookie: "session_id=12345; lang=en",
    // profile: "",
    debug: false,
    headers: {"TEST-HTTP-QUERY": "123"},
    timeout: 1000
}
  • プロフィール: ブラウザをシミュレートするために使用tls fingerprints.
  • debug: に設定されているときtrueこのHttpQuery_Go返信メッセージを返します.false単一のデータです.Body返信メッセージが返されます.
  • タイムアウト:タイムアウト設定で,セット1000は1秒のタイムアウトを意味します. この構造のすべてのフィールドはオプションで,例えば,profileフィールドは,外に出ることができます.

オプション 偽り オブジェクト

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

取引所の公開インターフェイスへの非同期アクセス

についてHttpQuery_Go()機能のみサポートJavaScriptについてPython言語は,urllibHttp リクエストを直接送信します.HttpQuery_Go()取引所で署名を必要としないインターフェースにアクセスするために主に使用されます.HttpQuery_Goバックテストシステムではサポートされていません.

{@fun/Global/HttpQuery HttpQuery} このビデオは,

暗号化

この関数は,入力されたパラメータに従ってデータをコードします.

についてEncode暗号化や暗号化後にデータを返します 文字列

エンコード (algo, inputFormat, output) 形式,データ エンコード (algo, inputFormat, output) 形式,データ,キー 形式,キー

パラメータalgo暗号化計算に使用されたアルゴリズムです. サポート設定は:raw(アルゴリズムが使用されていない) "サイン", サインTx, md4, md5, sha256, sha512, sha1, keccak256, sha3.224, sha3.256, sha3.384, sha3.512, sha3.keccak256, sha3.keccak512, sha512.384, sha512.256, sha512.224, ripemd160, blake2b.256, 2b.512, blake2s.128, blake2s.256 パラメーター.algoまた: text.encoder.utf8, text.decoder.utf8, text.encoder.gbk, text.decoder.gbk,エンコーディングと解読文字列をサポートしています. パラメータalgoまた: ed25519アルゴリズムもサポートしています. 異なるハッシュアルゴリズムの使用もサポートしています.algoed25519.md5,ed25519.sha512などと書ける.ed25519.seed計算する アルゴ 本当 文字列 データの形式を指定するために使用されます.dataパラメータinputFormatパラメータは次のいずれかに設定できます:raw, hex, base64, stringrawはデータが原始データであることを意味します.hexbase64 は,データがbase64文字列が文字列であることを意味します. input 形式 本当 文字列 出力のデータ形式を指定するために使用されます.outputFormatパラメータは次のいずれかに設定できます:raw, hex, base64, stringrawはデータが原始データであることを意味します.hexbase64 は,データがbase64文字列が文字列であることを意味します. output 形式 本当 文字列 パラメーターdata処理されるデータです データ 本当 文字列 データの形式を指定するために使用されます.keyパラメータkeyパラメータは次のいずれかに設定できます:raw, hex, base64, stringrawはデータが原始データであることを意味します.hexbase64 は,データがbase64文字列が文字列であることを意味します. キー形式 偽り 文字列 パラメーターkey秘密鍵はHMACパラメーターkeyパラメータがalgo設定されています.signまたはsignTx.....keyパラメータは,HMAC暗号化algoパラメータは raw に設定されます (HMAC暗号化のためにアルゴリズムを指定する必要があります). キー 偽り 文字列

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

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

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

エンコード関数呼び出しの例

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

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

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

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

パラメータalgoまた,文字列のエンコードと解読をサポートする: text.encoder.utf8, text.decoder.utf8, text.encoder.gbk, text.decoder.gbk.

についてEncode()直接取引にのみサポートされています.keyそしてkeyFormatパラメータが通過されていない場合,key暗号化が使用されていません

UnixNano について

この瞬間のナノ秒タイムスタンプを

についてUnixNano()この関数はナノ秒間のタイムスタンプを返します 番号

UnixNano (ユニックスナノ))

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

タイムスタンプを手に入れるには 次のコードを使います

{@fun/Global/Unix Unix} ユニクスは

UNIX

2階の現在の時刻のタイムスタンプを

2階のタイムスタンプを返します 番号

Unix (ユニックス)

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

{@fun/Global/UnixNano UnixNano} ユニックス・ナノ

GetOS をインストールする

ドーカーが位置するデバイスのシステム情報を取得します.

システム情報 文字列

GetOS (ゲットOS)

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

例えば,電話でGetOS()動作するドーカーのための関数マック OS操作システムが返信する可能性があります:darwin/amd64Appleのコンピュータには複数のハードウェアアーキテクチャがあるからですdarwin名称はマック OS system.

MD5

パラメータの MD5 ハッシュを計算するdata.

MD5ハッシュ値 文字列

MD5 (データ)

MD5の計算を必要とするデータです データ 本当 文字列

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

呼び出すMD5("hello world")この関数で返される値は5eb63bbbe01eeed093cb22bb8f5acdc3.

{@fun/Global/Encode エンコード}

DBExec は

データベース インターフェース機能

実行結果を含むオブジェクトスクワール例えば,以下のように


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

オブジェクト

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

メモリ内のデータベースをサポートするDBExec機能パラメータスクワールと始まる:記憶内データベースで動作する場合は,ファイルを書く必要なくより速く動作します.

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

テーブルを作れ

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

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

テーブル内のレコードを追加,削除,チェック,変更します.

機能についてDBExec()パラメータを入力してライブ取引データベース (SQLiteデータベース) を操作できます. リアル取引データベースにデータを追加,削除,チェック,変更の操作を実現します.SQLiteシステムで予約されたテーブル ライブ取引データベース:kvdb, cfg, log, profit, chartこのテーブルで操作しないでください.取引システムに衝突を引き起こす可能性があるため,そのような操作を行うことは推奨されません.DBExec()この機能はライブ取引のみに対応しています

{@fun/Global/_G _G} ほら ほら

UUID

UUID を作成します.

32ビット UUID 文字列

UUID ((()

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

についてUUID()機能はライブ取引のみをサポートします.

イベントループ

事件を聞いて,それは,何があるときに戻ってくるWebSocket読み取れるデータや並行作業,例えばexchange.Go(), HttpQuery_Go()完了しました.

返されたオブジェクトが null ではない場合,Event返信内容に含まれるのはイベントトリガータイプです.例えば,次の返信値構造:

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

オブジェクト

イベントループ イベントループ (タイムアウト)

パラメータtimeoutパラメーターは,このパラメータを表示します.timeoutイベントが0に設定されている場合,戻る前に発生するのを待つ. イベントが0より大きい場合は,タイムアウトを待つように設定し, 0未満の場合,最も最近のイベントをすぐに返します. タイムアウト 偽り 番号

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

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

初の電話はEventLoop()実行される場合,最初の動作が実行される場合,EventLoop()イベントコールバックが開始された後,以前のイベントを逃します. 基礎システムでは,最大500回のイベントコールバックをキャッシュするキュー構造を包み込みます.EventLoop()500キャッシュの外の後のイベントコールバックは失われます.EventLoop()基本システム WebSocket のキャッシュキューや,並行関数のキャッシュに影響しないexchange.Go(). これらのキャッシュでは,データを取得するためにそれぞれの方法を使用する必要があります.EventLoop()復元される前に取得されたデータのための機能EventLoop()主な目的は,EventLoop()戦略層に新しいネットワークデータが基盤システムに受信されたことを通知する機能です. 戦略全体がイベントによって動かされます.EventLoop()WebSocket 接続,WebSocket で作成されたオブジェクトなどexchange.Go()データを集めようとしますEventLoop()機能はライブ取引のみをサポートします. メイン機能から呼び出されるとメインスレッドのイベントを聞くmain()戦略を策定するJavaScript言語,threading.Thread()実行関数で呼び出せるスレッドを作成し,現在のスレッドのイベントを聞く.

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

__ 仕える

について__ServeHttp サービス,TCP サービス,Webソケット サービス (Http プロトコルに基づく) を作成するために使用されます.

作成されたサービスの IP アドレスとポートを記録する文字列を返します.例えば:127.0.0.1:8088, [::]:8089.

文字列

__Serve (サーバーURI,ハンドラー) __Serve (サーバーURI,ハンドラー,...args)

についてserveURIパラメータは,プロトコル,IPアドレス,ポート,および他の設定を設定するために使用されます.http://0.0.0.0:8088?gzip=trueつまりhttp://:8088?gzip=true.

  • TCP プロトコルserveURIパラメータ設定,例えばtcp://127.0.0.1:6666?tls=true証明書やプライベートキーを追加できます.tls=true&cert_pem=xxxx&cert_key_pem=xxxx.
  • Http プロトコルserveURIパラメータ設定などhttp://127.0.0.1:6666?gzip=true; 圧縮設定を設定できます:gzip=true- わかった についてserveURIHttps の場合も使用されます.https://127.0.0.1:6666?tls=true&gzip=true追加することもできますcert_pemそしてcert_key_pem証明書の読み込みのパラメータ

サービスURI 本当 文字列 についてhandlerこのパラメータは,ルーティング処理機能 (Http プロトコル),メッセージ処理機能 (TCP プロトコル),ストリーム処理機能 (Webソケット) に渡すのに使用されます. パラメータによって送信されたコールバック関数handler複数のパラメータを定義できます 最初のパラメータは ctx オブジェクト (コンテキスト オブジェクト) です

ハンドラー 本当 機能 コールバック関数の実際のパラメータがパラメータとして渡されますhandler複数のパラメータがある可能性があります.arg例えば:

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

パラメータ1, 2, 3呼び出すときに通過した__Serve()パラメータに対応する機能a, b, cコールバック機能で通過しました

アルグ 偽り 文字列,数,ボール,オブジェクト,配列,関数,ゼロ値,システムでサポートされる他のタイプ

function main() {
    let httpServer = __Serve("http://:8088?gzip=true", function (ctx) {
        Log("http connect from: ", ctx.remoteAddr(), "->", ctx.localAddr())
        let path = ctx.path()
        if (path == "/") {
            ctx.write(JSON.stringify({
                path: ctx.path(),
                method: ctx.method(),
                headers: ctx.headers(),
                cookie: ctx.header("Cookie"),
                remote: ctx.remoteAddr(),
                query: ctx.rawQuery()
            }))
        } else if (path == "/tickers") {
            let ret = exchange.GetTickers()
            if (!ret) {
                ctx.setStatus(500)
                ctx.write(GetLastError())
            } else {
                ctx.write(JSON.stringify(ret))
            }
        } else if (path == "/wss") {
            if (ctx.upgrade("websocket")) { // upgrade to websocket
                while (true) {
                    let r = ctx.read(10)
                    if (r == "") {
                        break
                    } else if (r) {
                        if (r == "ticker") {
                            ctx.write(JSON.stringify(exchange.GetTicker()))
                        } else {
                            ctx.write("not support")
                        }
                    }
                }
                Log("websocket closed", ctx.remoteAddr())
            }
        } else {
            ctx.setStatus(404)
        }
    })
    let echoServer = __Serve("tcp://:8089", function (ctx) {
        Log("tcp connect from: ", ctx.remoteAddr(), "->", ctx.localAddr())
        while (true) {
            let d = ctx.read()
            if (!d) {
                break
            }
            ctx.write(d)
        }
        Log("connect closed")
    })
    Log("http serve on", httpServer, "tcp serve on", echoServer)
    
    for (var i = 0; i < 5; i++) {
        if (i == 2) {
            // test Http
            var retHttp = HttpQuery("http://127.0.0.1:8088?num=123&limit=100", {"debug": true})
            Log("retHttp:", retHttp)
        } else if (i == 3) {
            // test TCP
            var tcpConn = Dial("tcp://127.0.0.1:8089")
            tcpConn.write("Hello TCP Server")
            var retTCP = tcpConn.read()
            Log("retTCP:", retTCP)
        } else if (i == 4) {
            // test Websocket
            var wsConn = Dial("ws://127.0.0.1:8088/wss|compress=gzip")
            wsConn.write("ticker")
            var retWS = wsConn.read(1000)
            Log("retWS:", retWS)
            // no depth
            wsConn.write("depth")
            retWS = wsConn.read(1000)
            Log("retWS:", retWS)
        }
        Sleep(1000)
    }
}
# Unsupported
// Unsupported
  • この関数は JavaScript 言語戦略のみをサポートします.
  • サービススレッドは,グローバルスコープから隔離されているため,閉鎖や外部変数,カスタム関数等への参照をサポートしません.しかし,すべてのプラットフォーム API 関数を呼び出すことができます.
  • についてWebsocket経路にルーティングブランチを設定し,実装コードを設計することができます.Websocketこのセクションのサンプルコードを参照してください.

パラメータによって送信されたコールバック関数handler受け取るctxパラメータctxパラメータは,次の方法でデータを取得し書き込むために使用されるコンテキストオブジェクトです.

  • ctx.proto ((() について Http/TCP プロトコルに適用され,呼び出すときにプロトコル名を返します.例えば:HTTP/1.1, tcp.
  • ctx.host() Http プロトコルに適用すると,IP アドレスとポートを呼んだときにホスト情報を返します.
  • ctx.path ((() について Http プロトコルに適用され,呼び出すときに要求経路を返します.
  • ctx.query (キー) Http プロトコルに適用される.呼び出し時にリクエスト内のキーに対応する値を返します.例えば,送信されたリクエストは:http://127.0.0.1:8088?num=123パラメータによって送信されたコールバック処理機能handlerリターン"123"いつctx.query("num")呼び出されています
  • ctx.rawQuery (() Http プロトコルに適用され,呼び出されると,リクエストの元のクエリ (Http リクエストのクエリ) を返します.
  • ctx.headers ((() について Http プロトコルに適用され,呼び出し時にリクエストのヘッダ情報を返します.
  • ctx.header (キー) 呼び出し時に指定された要求ヘッダのキー値を返します.例えば,User-Agent本願の表記にはctx.header("User-Agent").
  • ctx.method (ctx.方法) について Http プロトコルに適用され,呼び出すときに要求メソッドを返します.GET, POSTなど
  • ctx.body ((() について HTTP プロトコルの POST リクエストに適用され,呼び出されるとリクエストのボディを返します.
  • ctx.setHeader (キー,値) Http プロトコルに適用され,応答メッセージの要求ヘッダ情報を設定する.
  • ctx.setStatus (コード) Http プロトコルに適用され,Http メッセージの状態コードを設定します.通常,Http 状態コードはルーティング ブランチの最後に設定されます.デフォルト値は 200.
  • ctx.remoteAddr ((() について Http/TCP プロトコルに適用され,リモート クライアント アドレスとポートをリクエストで返します.
  • ctx.localAddr ((() Http/TCP プロトコルに適用され,呼び出し時にサービスのローカルアドレスとポートを返します.
  • ctx.upgrade (WEBソケット) Webソケットプロトコルの実装に適用されます.ctxWebソケットプロトコルへのコンテキストオブジェクト; スイッチが成功した場合にブール値 (true) と失敗した場合にブール値 (false) を返します.
  • ctx.read (タイムアウト) HTTP プロトコルに基づく Websocket プロトコル実装/TCP プロトコルに適用され, Websocket 接続と TCP 接続のデータを読みます.readタイムアウトパラメータを指定できます.timeout_ms数ミリ秒で
  • ctx.write ((s) について 文字列のデータを書くために使用できます.JSON.stringify()JSON オブジェクトを文字列にコードし,それを書き込みます.WebSocket暗号化された文字列をクライアントに送信します

{@fun/Global/HttpQuery HttpQuery}, {@fun/Global/HttpQuery_Go HttpQuery_Go} ウェブ上で検索するサイト

_G

データを継続的に保存する,この関数は保存できるグローバル辞書関数を実装する.データ構造は,dockerのローカルデータベースファイルに永久に保存されるKVテーブルである.

キー値のデータを保存するk-vキー値のペア 文字列,数,ボール,オブジェクト,配列,ゼロ値

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

パラメータk保存されたキー値ペアの鍵の名前で,小字・小文字が表示されない. k 偽り 文字列,ゼロ値 パラメーターv保存されたキー値ペアのキー値です.JSONシリーズ化しました v 偽り 文字列,数,ボール,オブジェクト,配列,ゼロ値

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

リアルタイム取引の各個別データベース,_G()バックテストが完了すると,バックテストシステムに保存されたデータは,_G()機能が削除されます._G()ハードウェアデバイスのメモリとハードディスクスペースに応じて合理的に使用し,悪用してはならない. 呼び出すとき_G()パラメータが通過されなければ,_G()この関数は,Id現行のライブ取引._G()パラメータv削除を表示する為, null に渡されます.k-v呼び出すとき_G()パラメータのみk文字列で渡され,_G()保存されたパラメータに対応するキー値を返します.k. 呼び出すとき_G()パラメータのみkすべての記録が0で表示されます.k-vキー値ペアが削除されます.k-vキー値ペアが持続的に保存されている場合,_G()パラメータとして保存されたキー名を入力します.kパラメータとして新しいキー値を入力v更新しますk-vキー値ペア

{@fun/Global/DBExec DBExec} このビデオは

_D

ミリ秒タイムスタンプまたはDate時間の文字列にオブジェクト.

タイムストリング 文字列

_D() _D (時間) タイムスタンプ,fmt

ミリ秒タイムスタンプかDateオブジェクト タイムスタンプ 偽り 番号、対象 文字列をフォーマットJavaScript言語のデフォルト形式:yyyy-MM-dd hh:mm:ss; Python言語のデフォルト形式:%Y-%m-%d %H:%M:%S; C++言語のデフォルト形式:%Y-%m-%d %H:%M:%S- わかった fmt 偽り 文字列

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

現在の時間文字列を取得してプリントします:

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

タイムスタンプは1574993606000,コード変換で:

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

パラメータでフォーマットするfmt異なる場合JavaScript, PythonそしてC++言語は以下の例で示されている.

パラメータを通過することなく現在の時間文字列を返します._D()機能についてPythonパラメータは2階のタイムスタンプ (JavaScriptとC++の戦略では1秒は1000ミリ秒) である._D()タイムスタンプで読み取れる時間文字列を解析するには,ドッカープログラムが位置するオペレーティングシステムのタイムゾーンと時間設定に注意する必要があります._D()この関数は,dockerのシステムの時間に応じて,タイムスタンプを読み取れる時間文字列に解析します.

{@fun/Global/UnixNano UnixNano}, {@fun/Global/Unix Unix} ユーニックス

_ N

浮動小数点番号をフォーマットする

精度設定に従ってフォーマットされた浮動点数 番号

_ N() _ N (数) _N (num,精度)

フォーマットする必要がある浮動小数点番号. ナンバー 本当 番号 フォーマットの精度設定,パラメータprecisionこのパラメータは,precision4に設定します. 精度 偽り 番号

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

例えば_N(3.1415, 2)削除する3.1415この関数から返します.3.14.

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

0に書き換えることができます. これは,

パラメータprecision負の整数です. 負の整数です.

{@fun/Trade/exchange.SetPrecision exchange.SetPrecision} チェンジする

_C

インターフェースの障害耐性を再試します

コールバック関数の実行時に返される値 システムでは,すべてのタイプがサポートされています.論理的誤り値そしてゼロ値.

_C(pfn) _C ((pfn,... args) について

パラメータpfn函数参照であり,コールバック機能- わかった pfn 本当 機能 パラメーターコールバック機能複数のパラメータがある可能性があります.argパラメータの種類と数arg測定するコールバック機能- わかった アルグ 偽り 文字列,数, bool,オブジェクト,配列,関数,すべてのタイプは,ゼロ値などのシステムでサポートされています

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

パラメータのない誤差容量関数については:

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

パラメータが誤差耐性のある関数については:

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

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

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

また,カスタム機能の障害耐性にも使用できます.

について_C()指定された関数を成功して返すまで呼び続けます (パラメータが参照する関数)pfnリターンゼロまたは偽り呼び出されると呼び出します.pfn) など_C(exchange.GetTicker)3秒で再試行します._CDelay()試行距離を設定する関数です._CDelay(1000)試行錯誤の間隔を変更する_C()1秒まで 障害許容は,以下のような機能に限らずに行うことができる.

  • exchange.GetTicker()
  • exchange.GetDepth()
  • exchange.GetTrades()
  • exchange.GetRecords()
  • exchange.GetAccount()
  • exchange.GetOrders()
  • exchange.GetOrder()
  • exchange.GetPositions()呼び出すことができます._C()誤差耐性について_C()機能は上記に記載されている機能の障害許容量に限定されていない場合,パラメータpfn函数呼び出しではなく関数参照です 注目してください._C(exchange.GetTicker)しない_C(exchange.GetTicker()).

_クロス

配列の交差点数を返しますarr1そして配列arr2.

配列の交差期数arr1そして配列arr2- わかった 番号

_ 交差 (arr1,arr2)

エレメントは型の配列である.number- わかった arr1 本当 配列 エレメントは型の配列である.number- わかった arr2 本当 配列

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

数値のセットをシミュレーションして _Cross ((Arr1,Arr2) 関数をテストできます:

返回値が_Cross()値が正数である場合,上向きの浸透期間を示し,負数である場合,下向きの浸透期間を示し,0は現在の価格と同じです. 具体的な使用説明:内蔵機能に関する分析と使用説明 _Cross.

JSONパース

機能についてJSONParse()解析するために使用されます.JSON strings.

JSONオブジェクト オブジェクト

JSONParse (JSONパース)

JSONストリング s 本当 文字列

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

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

JSON の文字列は,文字列の種類として解析されます.JSONParse()バックテストシステムでは機能がサポートされていません.

ログ