Die Ressourcen sind geladen. Beförderung...

Weltweite

Ausgabe

Gibt die aktuelle Versionnummer des Systems zurück.

Aktuelle Systemversionsnummer, z. B.3.6- Ich weiß. String

Ausgabe ((()

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

Die Systemversionsnummer ist die Versionsnummer des Dockers-Programms.

Schlaf

Die Schlaffunktion, wodurch das Programm für eine gewisse Zeit pausiert.

Schlaf (Millisekunde)

DiemillisecondDer Parameter wird verwendet, um die Schlafdauer und die Anzahl der Millisekunden festzulegen. Millisekunde - Das stimmt. Zahl

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

Zum Beispiel bei der Ausführung derSleep(1000)Es unterstützt Operationen mit einer Schlafzeit von weniger als 1 Millisekunde, z. B. Einstellung vonSleep(0.1). Es unterstützt einen Mindestparameter von0.000001, d.h. Nanosekunden-Wachstum, wobei 1 Nanosekunde gleich ist1e-6Millisekunden. Bei der Erstellung von Strategien inPythonSprache, dieSleep(millisecond)Es wird nicht empfohlen, dietime.sleep(second)Funktion derPythonDas ist...timeDas ist, weil die Verwendung dertime.sleep(second)Funktion in einer Strategie lässt das Strategieprogramm für einen Zeitraum warten, tatsächlich beim Backtesting (nicht überspringen auf die Zeitreihen des Backtesting-Systems), so dass es die Strategie verursacht, um sehr langsam zu backtest.

Istvirtual

Bestimmen Sie, ob die laufende Umgebung der Strategie ein Backtesting-System ist.

Die Strategie gibt einen wahren Wert zurück, z. B.:trueDie Strategie gibt einen falschen Wert zurück, z. B.:falsewenn sie in einer Live-Handelsumgebung ausgeführt werden. Boole

Ist virtuell?

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

Bestimmen Sie, ob die aktuelle laufende Umgebung ein Backtesting-System ist, das mit dem Unterschied zwischen Backtesting und Live-Handel kompatibel ist.

Post

Schicken Sie eine E-Mail.

Eine erfolgreiche E-Mail-Zustellung gibt einen wahren Wert zurück, z. B.true, und eine fehlgeschlagene Lieferung gibt einen falschen Wert zurück, z. B.false- Ich weiß. Boole

Mail ((smtpServer, smtpBenutzername, smtpPasswort, mailTo, Titel, Körper)

Verwendet zur Angabe derSMTPDienstadresse des E-Mail-Senders. SmtpServer wahr String Wird verwendet, um die E-Mail-Adresse des E-Mail-Senders anzugeben. Sms-Benutzername wahr String DieSMTPPasswort für das Postfach des E-Mail-Senders. Smp Passwort wahr String Verwendet zur Angabe der E-Mail-Adresse des E-Mail-Empfängers. Nachrichten wahr String E-Mail-Adresse. Titel wahr String E-Mail Körper. Körper wahr String

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

DiesmtpPasswordParameter setzt das Passwort für dieSMTPService, nicht das Postfach-Passwort. Bei Einstellung dersmtpServerParameter, wenn Sie den Port ändern müssen, können Sie die Portnummer direkt in Parameter hinzufügensmtpServer. Zum Beispiel: QQ-Mailsmtp.qq.com:587, die zur Prüfung zur Verfügung steht. Wenn ein Fehler gemeldet wird:unencryped connection, müssen Sie diesmtpServerderMailDas Parameterformat lautet:ssl://xxx.com:xxx, zum Beispiel diesslVerfahren derSMTPfür QQ-Mail:ssl://smtp.qq.com:465odersmtp://xxx.com:xxx- Ich weiß. Es funktioniert nicht im Backtesting-System.

Ich bin nicht derjenige, der dich anspricht.

E-Mail_Go

Asynchrone Version derMail function.

DieMail_GoFunktion gibt ein gleichzeitiges Objekt sofort zurück, und Sie können diewaitEine erfolgreiche Postlieferung gibt einen wahren Wert zurück, z. B.true, und eine fehlgeschlagene Lieferung gibt einen falschen Wert zurück, z. B.false- Ich weiß. Gegenstand

Mail_Go ((smtpServer, smtpBenutzername, smtpPasswort, mailTo, Titel, Körper)

Es wird verwendet, um dieSMTPDienstadresse des E-Mail-Senders. SmtpServer - Das stimmt. String Es wird verwendet, um die E-Mail-Adresse des E-Mail-Senders anzugeben. Sms-Benutzername - Das stimmt. String DieSMTPPasswort für das Postfach des E-Mail-Senders. SmtpPasswort - Das stimmt. String Es dient zur Angabe der E-Mail-Adresse des E-Mail-Empfängers. Nachrichten - Das stimmt. String E-Mail-Adresse. Titel - Das stimmt. String E-Mail Körper. Körper - Das stimmt. String

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.

Es funktioniert nicht im Backtesting-System.

Ich bin nicht hier.

SetErrorFilter

Filterfehlerprotokolle.

SetErrorFilter (Filter)

Regelmäßige Ausdrucksfolge. Filter wahr String

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

Filtern von häufigen Fehlern.

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

Filtern Sie eine Schnittstellenfehlermeldung.

Fehlerprotokolle, die mit diesem regulären Ausdruck übereinstimmen, werden nicht in das Protokollsystem hochgeladen. Sie können ihn mehrmals (ohne Begrenzung der Anzahl der Zeiten) aufrufen, um mehrere Filterbedingungen festzulegen. Regelmäßige Ausdrücke, die mehrmals gesetzt wurden, werden angesammelt und wirken gleichzeitig. Sie können eine leere Zeichenfolge festlegen, um den regulären Ausdruck, der zum Filtern von Fehlerprotokollen verwendet wird, zurückzusetzen:SetErrorFilter(""). Die gefilterten Protokolle werden nicht mehr in die Datenbankdatei geschrieben, die der Live-Trading-ID im Docker-Verzeichnis entspricht, um zu verhindern, dass häufige Fehlermeldungen die Datenbankdatei aufblähen.

GetPid

Holen Sie sich die Live-Handelsprozess-ID.

Rückgabe der Live-Handelsprozess-ID. String

GetPid (siehe unten)

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

GetLastError

Erhaltet die letzte Fehlermeldung.

Letzte Fehlermeldung. String

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

Es funktioniert nicht im Backtesting-System.

GetCommand

Erhält den Strategie-Interaktionsbefehl.

Das Format des zurückgegebenen Befehls istControlName:Data. ControlNameist der Name der Kontrolle undDataist das in die Steuerung eingegebene Datenformat. Wenn die interaktive Steuerung keine Eingabeboxen, Dropdown-Boxen und andere Komponenten (z. B. eine Tastensteuerung ohne Eingabeboxen) hat, wird das zurückgegebene BefehlformatControlName, die nur den Kontrollnamen zurückgibt. String

GetCommand (siehe unten)

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

Ermittelt den Interaktionsbefehl und verwendet dieLogFunktion zur Ausgabe des Interaktionsbefehls, wenn er erkannt wird.

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

Zum Beispiel fügt die Strategie-Interaktionssteuerung eine Steuerung ohne Eingabebox hinzu, die interaktive Steuerung heißt:buy, sind die Angaben zur Kontrollbeschreibung:buy, das eine Tastensteuerung ist. Führen Sie fort, indem Sie eine Steuerung mit einem Eingabefeld hinzufügen. Die interaktive Steuerung heißt:sellund die Beschreibungsmeldung für die Kontrolle lautet:sellDer Interaktionscode ist in der Strategie so konzipiert, dass er auf die verschiedenen Interaktionssteuerungen reagiert:

Es funktioniert nicht im Backtesting-System.

GetMeta

Erhalten Sie den Wert von Meta geschrieben, wenn die Strategie Registrierungscode generiert.

MetaDaten. String

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

Beispiel für die Anwendung: VerwendungMetadie Höhe der von der Strategie betriebenen Vermögenswerte zu begrenzen.

Anwendungsszenario: müssen Kapitallimits für verschiedene Strategie Mieter.Metader bei der Erstellung des Registrierungscodes festgelegte Wert darf 190 Zeichen nicht überschreiten, undGetMeta()Die Funktion unterstützt nur Live-Handel.Meta) wird bei der Erstellung eines Strategie-Registrierungscodes, derGetMeta()Die Funktion gibt null zurück. Sie funktioniert nicht im Backtesting System.

Wählen

Für primitiveSocketZugang, Unterstützungtcp, udp, tls, unixUnterstützung von 4 gängigen Kommunikationsprotokollen:mqtt, nats, amqp, kafkaUnterstützung für die Verbindung zu Datenbanken:sqlite3, mysql, postgres, clickhouse.

DieDial()Ein normaler Aufruf gibt ein Verbindungsobjekt zurück, das drei Methoden hat:read, writeundclose. DiereadDie Methode wird zur Ablesung der Daten verwendet.writeDaten zu senden und diecloseMethode verwendet wird, um die Verbindung zu schließen. DiereadDie Methode unterstützt folgende Parameter:

  • Wenn keine Parameter übergeben werden, blockiert es, bis eine Nachricht verfügbar ist und zurückkehrt, z. B.ws.read().
  • Wenn als Parameter übergeben, ist die Einheit Millisekunden, die die Wartezeit der Nachricht angibt.ws.read(2000)eine Zeitraffer von zwei Sekunden (2000 Millisekunden) angibt.
  • Die folgenden beiden Parameter sind nur für WebSocket gültig: Übergabe des Parameters-1bedeutet, dass die Funktion unabhängig vom Vorhandensein oder Fehlen von Nachrichten sofort zurückgibt, z. B.:ws.read(-1)- Ich weiß. Übergabe des Parameters-2bedeutet, dass die Funktion sofort mit oder ohne eine Nachricht zurückgibt, aber nur die letzte Nachricht zurückgegeben wird, und die pufferte Nachricht wird entsorgt.ws.read(-2).

read()Beschreibung des Funktionspuffers: Die eingehenden Daten, die durch das WebSocket-Protokoll geschoben werden, können eine Datenauflagerung verursachen, wenn das Zeitintervall zwischenread()Diese Daten werden in dem Puffer gespeichert, der eine Datengestaltung einer Warteschlange mit maximal 2000 hat.

Szenario Keine Parameter Parameter: -1 Parameter: -2 Parameter: 2000, in Millisekunden
Daten bereits im Puffer Sofortige Rückgabe der ältesten Daten Sofortige Rückgabe der ältesten Daten Sofort die neuesten Daten zurückgeben Sofortige Rückgabe der ältesten Daten
Keine Daten im Puffer Zurückkehren, wenn Daten blockiert sind Null sofort zurückgeben Null sofort zurückgeben Warten Sie 2000 ms, Null zurückgeben, wenn keine Daten, Null zurückgeben, wenn es Daten gibt
Die WebSocket-Verbindung wird vom zugrunde liegenden read() Funktion gibt die leere Zeichenfolge zurück, d.h.: , und write() Funktion gibt 0 zurück. Die Situation wird erkannt. Sie können die Verbindung mit der close() Funktion schließen, oder wenn Sie die automatische Wiederverbindung eingerichtet haben, müssen Sie sie nicht schließen, das zugrunde liegende System wird sie automatisch wieder verbinden.

Gegenstand

Wählen Sie (Adresse) Wählen Sie (Adresse, Zeitverzögerung)

Anfrageadresse. Anschrift wahr String Zeitraffer Sekunden, Zeitverzögerung falsche Zahl

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

Beispiel für einen Aufruf der Funktion "Dial":

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

Zugriff auf die WebSocket-Ticker-Schnittstelle von Binance:

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

Zugriff auf die OKX WebSocket-Ticker-Schnittstelle:

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

Zugriff auf Huobi's WebSocket Tickerschnittstelle:

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

Zugriff auf die WebSocket-Authentifizierungsoberfläche von OKX:

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

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

Das Verbindungsobjekt, das bei der Verbindung zu einer Datenbank durch die Funktion Dial zurückgegeben wird, hat zwei Methodenfunktionen, die einzigartig sind:

  • exec(sqlString): Wird verwendet, um SQL-Anweisungen ähnlich wie dieDBExec() function.
  • fd()Diefd()Funktion gibt einen Handler zurück (z. B. die Handlervariable ist Handler), der von anderen Threads zur Wiederverbindung verwendet wird (auch wenn das von Dial erstellte Objekt bereits durch die Ausführung desclose()Funktion, um die Verbindung zu schließen) durch dasDial()Funktion, zum Beispiel,Dial(handle)Wiederverwendungsanschluss. Das folgende ist ein Beispiel für die Dial-Funktion, die eine Verbindung zu einemsqlite3 database.

Einzelheiten deraddressParameter, getrennt durch die|Symbol nach der normalen Adresse:wss://ws.okx.com:8443/ws/v5/publicWenn es welche gibt.|Zeichen in der Parameterzeile, dann||Der Teil danach sind einige Funktionsparameter-Einstellungen, und jeder Parameter ist mit&Siehe auch:ss5Proxy- und Kompressionsparameter können wie folgt zusammengestellt werden:Dial("wss://ws.okx.com:8443/ws/v5/public|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv")

Funktionen, die durch den Adressparameter der Dial-Funktion unterstützt werden Beschreibung der Parameter
Parameter im Zusammenhang mit der Datenkomprimierung des WebSocket-Protokolls: compress=Parameterwert compress ist die Komprimierungsmethode, die Komprimierungsparameteroptionen sind: gzip_raw, gzip usw. Wenn die gzip-Methode nicht gzip ist, können Sie die erweiterte Methode verwenden: gzip_raw
Parameter im Zusammenhang mit der Datenkomprimierung des WebSocket-Protokolls: Mode=Parameterwert Modus ist der Komprimierungsmodus, Modusparameter kann dual sein, send, recv. dual ist Zwei-Wege-Komprimierung, send komprimierte Daten, empfangen komprimierte Daten. send send komprimierte Daten. recv empfangen komprimierte Daten, lokale Dekomprimierung.
Das WebSocket-Protokoll legt die zugrunde liegenden Parameter für die automatische Wiederverbindung fest: reconnect=Parameterwert reconnect ist, ob reconnect gesetzt wird, reconnect=true ist, ob reconnect aktiviert wird.
Das WebSocket-Protokoll setzt die zugrunde liegenden Parameter für die automatische Wiederverbindung: interval=Parameterwert Intervall ist das Wiederversuchsintervall, in Millisekunden, interval=10000 ist das Wiederversuchsintervall von 10 Sekunden, der Standardwert ist 1 Sekunde, wenn es nicht eingestellt ist, d. h. interval=1000.
Das WebSocket-Protokoll legt die zugrunde liegenden Parameter für die automatische Wiederverbindung fest: Nutzlast=Parameterwert Payload ist die Abonnementnachricht, die gesendet werden muss, wenn die WebSocket wieder verbunden wird, z. B.: payload=okokok.
Parameter im Zusammenhang mit socks5 proxy: proxy=Parameterwert Proxy ist die Proxy-Einstellung ss5, Parameterwertformat: socks5://name:pwd@192.168.0.1:1080, Name ist SS5-Server-Benutzername, pwd ist SS5-Server-Login-Passwort, 1080 ist SS5-Service-Port.

DieDial()Die Funktion wird nur für den Live-Handel unterstützt. Bei der Verbindung mit einer Datenbank mit der Dial-Funktion wird die Verbindungszeile mit Bezug auf das Go-Sprachtreiberprojekt für jede Datenbank geschrieben.

Unterstützte Datenbanken Antriebsprojekte Verbindungsstring Anmerkungen
Schnitt 3 github.com/mattn/go-sqlite3 sqlite3://Datei:test.db?Cache=shared&mode=Speicher Diesqlite3://Prefix zeigt an, dass eine sqlite3-Datenbank verwendet wird, Beispielruf:Dial("sqlite3://test1.db")
MySQL github.com/go-sql-driver/mysql Ich bin nicht derjenige, der das Problem hat, aber ich bin derjenige, der das Problem hat.localhost:3306) / Ihre Datenbank? Charset=utf8mb4
Nachwuchs github.com/lib/pq Postgres://user=postgres dbname=yourdatabase sslmode=disable password=yourpassword host=localhost port=5432
Klickhaus github.com/ClickHouse/clickhouse-go Sie müssen sich an die Datenbank wenden, die Sie benötigen.

Bitte beachten Sie, daß diepayloadInhalte in deraddressParameter enthält Zeichen=oder andere Sonderzeichen, kann es die Parsierung deraddressParameter derDialFunktion, wie zum Beispiel im folgenden Beispiel.

Beispiel für den Aufruf der privaten Schnittstelle von 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}}")
}

Der folgende Anruf im Code funktioniert:

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

Wenn Sie es direkt inpayload, wird es nicht richtig funktionieren, zum Beispiel:

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

Derzeit unterstützt nur JavaScript die Verwendung dermqtt, nats, amqp, undkafkaDer JavaScript-Strategiekode wird als Beispiel verwendet, um die Verwendung der vier Protokolle zu zeigen:mqtt, nats, amqp, undkafka:

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

Ausführliche Dokumentation:Erforschung von FMZ: Praxis des Kommunikationsprotokolls zwischen Live-Handelsstrategien

HttpQuery

Senden Sie eine Http-Anfrage.

Gibt die Antwortdaten der Anfrage zurück.JSONString, es kann durch dieJSON.parse()Funktion imJavaScriptDie Europäische Kommissionjson::parse()Funktion imC++Wenn Debug in der Optionsstruktur auf true gesetzt ist, ist der zurückgegebene Wert ein Objekt (JSON); wenn Debug auf false gesetzt ist, ist der zurückgegebene Wert eine Zeichenfolge. String, Objekt

HttpQuery (URL) HttpQuery (URL, Optionen)

Http-Anfrage-URL. Url - Das stimmt. String Http-Anfrage-bezogene Einstellungen können beispielsweise wie folgt strukturiert werden:

{
    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
}
  • Profil: Verwendet zur Simulation des BrowserstlsFingerabdrücke. Die unterstützten Einstellungen umfassen folgende Optionen: - Ich weiß nicht."chrome_103", "chrome_104", "chrome_105", "chrome_106", "chrome_107", "chrome_108", "chrome_109", "chrome_110", "chrome_111", "chrome_112", "chrome_117"- Ich weiß. Safari_:"safari_15_6_1", "safari_16_0", "safari_ipad_15_6", "safari_ios_15_5", "safari_ios_15_6", "safari_ios_16_0"- Ich weiß. Firefox_:"firefox_102", "firefox_104", "firefox_105", "firefox_106", "firefox_108", "firefox_110", "firefox_117"- Ich weiß. - Ich weiß nicht."opera_89", "opera_90", "opera_91"- Ich weiß. Ich habe ihn nicht gesehen."zalando_android_mobile", "zalando_ios_mobile"- Ich weiß. - Ich weiß nicht."nike_ios_mobile", "nike_android_mobile"- Ich weiß. Wolkenkratzer:"cloudscraper"- Ich weiß. - Ich weiß nicht."mms_ios"- Ich weiß. Sieh mal an:"mesh_ios", "mesh_ios_1", "mesh_ios_2", "mesh_android", "mesh_android_1", "mesh_android_2"- Ich weiß. Bestätigt:"confirmed_ios", "confirmed_android"- Ich weiß. Ok. Das ist alles."okhttp4_android_7", "okhttp4_android_8", "okhttp4_android_9", "okhttp4_android_10", "okhttp4_android_11", "okhttp4_android_12", "okhttp4_android_13",
  • Debug: Wenn es auftrue, dieHttpQueryFunktionsanruf gibt die vollständige Antwort zurück.false, nur die Daten inBodyder Antwortnachricht zurückgegeben wird.
  • Timeout: Einstellung von Timeout, eingestellt auf 1000 bedeutet 1 Sekunde Timeout.
  • Charset: Es unterstützt die Transkodierung der angeforderten Antwortdaten, wie z. B. GB18030. Alle Felder in dieser Struktur sind optional, zum Beispiel:profileDas Feld kann ausgeschlossen werden.

Optionen falsche Gegenstand

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

Ein Beispiel für den Zugriff auf die öffentliche OKX-Ticker-API-Schnittstelle.

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

Die HttpQuery-Funktion verwendet Proxy-Einstellungen.

DieHttpQuery()Funktion nur unterstütztJavaScript, C++Sprache,PythonSprache kann dieurllibDie Web-Library ist für den direkten Versand von HTTP-Anfragen geeignet.HttpQuery()Die Anwendungsmöglichkeiten sind in der Regel für den Zugriff auf die Schnittstellen der Börse, die keine Signatur erfordern, wie z. B. öffentliche Schnittstellen wie Tickerinformationen.HttpQuery()kann im Backtesting-System verwendet werden, um Anfragen (nurGETDas Backtesting beschränkt sich auf die Verwendung von 20 Besuchen in verschiedenenURLs, undHttpQuery()Die Daten werden von den Besuchern im Cache gespeichert.URLDer zweite Zugriff erfolgtHttpQuery()Funktion gibt die zwischengespeicherten Daten zurück und es werden keine tatsächlichen Netzwerkanfragen mehr erfolgen.

Ich bin nicht derjenige, der das Problem hat.

HttpQuery_Go

Sendet eine HTTP-Anfrage, eine asynchrone Version desHttpQuery function.

DieHttpQuery_Go()Funktion gibt sofort ein gleichzeitiges Objekt zurück, das verwendet werden kann, um das Ergebnis einer HTTP-Anfrage mit demwaitVerfahren derJSON.parse()Funktion kann verwendet werden, um dieJSON.parse()Funktion imJavaScriptSprachenstrategie.
Gegenstand

HttpQuery_Go (URL) HttpQuery_Go (URL, Optionen)

Http-Anfrage-URL. Url - Das stimmt. String Http-Anfrage-bezogene Einstellungen können beispielsweise wie folgt strukturiert werden:

{
    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
}
  • Profil: Verwendet zur Simulation des Browserstls fingerprints.
  • Debug: Wenn es auftrueDas ist...HttpQuery_GoFunktionsanruf gibt die vollständige Antwort zurück.false, nur die Daten inBodyder Antwortnachricht zurückgegeben wird.
  • Timeout: Einstellung von Timeout, eingestellt auf 1000 bedeutet 1 Sekunde Timeout. Alle Felder in dieser Struktur sind optional, zum Beispiel:profileDas Feld kann ausgeschlossen werden.

Optionen falsche Gegenstand

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

Asynchroner Zugriff auf die öffentliche Schnittstelle der Börse für aggregierte Tickerdaten.

DieHttpQuery_Go()Funktion nur unterstütztJavaScript, diePythonDie Sprache kann mit derurllibDie Web-Library ist für den direkten Versand von HTTP-Anfragen geeignet.HttpQuery_Go()Die Anwendungsmöglichkeiten sind in der Regel in der Form von Anwendungen, die für den Zugang zu Schnittstellen verwendet werden, die keine Unterschrift auf der Börse erfordern, z. B. öffentliche Schnittstellen wie Tickerinformationen.HttpQuery_GoFunktion nicht im Backtesting-System unterstützt.

Ich bin nicht derjenige, der das Problem hat.

Codieren

Diese Funktion kodiert die Daten nach den eingegebenen Parametern.

DieEncodeFunktion gibt die Daten nach der Verschlüsselung und Verschlüsselung zurück. String

Code (algo, inputFormat, outputFormat, Daten) Code ((algo, inputFormat, outputFormat, Daten, SchlüsselFormat, Schlüssel)

Der Parameteralgoist der Algorithmus, der bei der Codierung berechnet wird.raw(Kein Algorithmus wird verwendet), das"Zeichen", signTx, md4, md5, sha256, sha512, sha1, keccak256, sha3.224, sha3.256, sha3.384, sha3.512, sha3.keccak256, sha3.keccak512, sha512.384, sha512.256, sha512.224, ripemd160, blake2b.256, 2b.512, blake2s.128, blake2s.256 Der Parameter.algoUnterstützt auch: text.encoder.utf8, text.decoder.utf8, text.encoder.gbk, text.decoder.gbk, kodieren und entschlüsseln Zeichenfolgen. Der Parameteralgounterstützt auch: ed25519 Algorithmus. Unterstützt die Verwendung verschiedener Hash-Algorithmen, zum Beispiel den Parameteralgokann als ed25519.md5, ed25519.sha512 usw. geschrieben werden.ed25519.seedBerechnung. etwas wahr String Verwendet zur Festlegung des Datenformats derdataDieinputFormatDer Parameter kann als einer der folgenden Einstellungen festgelegt werden:raw, hex, base64, string. raw bedeutet, dass die Daten roh sind, hex bedeutet, dass die Datenhexkodiert, base64 bedeutet, dass die Datenbase64und string bedeutet, dass die Daten eine Zeichenfolge sind. InputFormat - Das stimmt. String Verwendet, um das Datenformat der Ausgabe anzugeben.outputFormatDer Parameter kann als einer der folgenden Einstellungen festgelegt werden:raw, hex, base64, string. raw bedeutet, dass die Daten roh sind, hex bedeutet, dass die Datenhexkodiert, base64 bedeutet, dass die Datenbase64und string bedeutet, dass die Daten eine Zeichenfolge sind. AusgabeFormat - Das stimmt. String Der Parameterdataist die zu verarbeitende Daten. Daten wahr String Verwendet zur Festlegung des Datenformats derkeyDiekeyDer Parameter kann als einer der folgenden Einstellungen festgelegt werden:raw, hex, base64, string. raw bedeutet, dass die Daten roh sind, hex bedeutet, dass die Datenhexkodiert, base64 bedeutet, dass die Datenbase64und string bedeutet, dass die Daten eine Zeichenfolge sind. SchlüsselFormat falsche String Der Parameterkeyist der geheime Schlüssel, der fürHMACDer Parameterkeyist erforderlich, wenn der Parameteralgoist aufsignodersignTx. DiekeyParameter wird nicht fürHMACVerschlüsselung, wennalgoDer Parameter ist auf raw eingestellt (weil der Algorithmus für die HMAC-Verschlüsselung angegeben werden muss). Schlüssel falsche String

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
}

Beispiel für den Aufruf der Funktion "Encode".

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

Der ParameteralgoUnterstützt auch: text.encoder.utf8, text.decoder.utf8, text.encoder.gbk, text.decoder.gbk zum Codieren und Entschlüsseln von Zeichenfolgen.

DieEncode()Die Funktion wird nur für den Live-Handel unterstützt.keyundkeyFormatParameter werden nicht übergeben, dannkeyVerschlüsselung wird nicht verwendet.

UnixNano

Holen Sie sich den Nanosekunden-Zeitstempel des aktuellen Moments.

DieUnixNano()Die Funktion gibt den Nanosekundenzeitstempel zurück. Zahl

UnixNano (siehe unten)

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

Wenn Sie Millisekundenzeitstempel benötigen, können Sie den folgenden Code verwenden:

Ich bin nicht derjenige.

Unix

Holen Sie sich den Zeitstempel des aktuellen Moments auf der zweiten Ebene.

Gibt den Zeitstempel der zweiten Ebene zurück. Zahl

Unix()

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

Ich bin nicht derjenige, der das Problem hat.

GetOS

Holen Sie sich die Systeminformationen des Geräts, wo sich der Docker befindet.

Systeminformationen. String

GetOS()

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

Zum Beispiel ein Anruf an dieGetOS()Funktion für einen Docker, der auf derMac-BetriebssystemDas Betriebssystem könnte zurückkehren:darwin/amd64Weil Apple-Computer mehrere Hardware-Architekturen haben.darwinist der Name derMac-Betriebssystem system.

MD5

Berechnet den MD5-Hash des Parametersdata.

MD5-Hashwert. String

MD5 (Daten)

Die Daten, die eine MD5-Berechnung erfordern. Daten wahr String

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

Ich rufe dieMD5("hello world")Funktion, der Rückgabewert beträgt:5eb63bbbe01eeed093cb22bb8f5acdc3.

Ich bin nicht derjenige.

DBExec

Datenbank-Schnittstellenfunktionen

Ein Objekt, das das Ergebnis der Ausführung einesQuadratkilometerAngabe, zum Beispiel:


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

Gegenstand

DBExec (sql)

QuadratkilometerAnweisungsstring. Quadratkilometer wahr String

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

Unterstützung der Datenbank im Speicher fürDBExecFunktionsparameter, wennQuadratkilometerBeginnt mit:Es ist für Datenbankoperationen geeignet, die kein ständiges Speichern erfordern, zum Beispiel:

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

Machen Sie einen Tisch.

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

Hinzufügen, Löschen, Überprüfen und Ändern der Datensätze in der Tabelle.

Die FunktionDBExec()kann die Live-Trading-Datenbank (SQLite-Datenbank) bedienen, indem Parameter eingegeben werden.SQLiteDas System reservierte Tabellen in der Live-Handelsdatenbank:kvdb, cfg, log, profit, chartSie dürfen auf diesen Tischen nicht arbeiten.TransaktionenDiese Funktionen werden nicht unterstützt und es wird nicht empfohlen, solche Operationen durchzuführen, da sie Konflikte im System verursachen können.DBExec()Die Funktion wird nur für den Live-Handel unterstützt.

Ich bin nicht derjenige, der das Problem hat.

UUID

Erstellen Sie eine UUID.

32-Bit-UID. String

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

DieUUID()Die Funktion unterstützt nur Live-Handel.

EventLoop

Hören Sie auf die Ereignisse, es kommt zurück, wenn es irgendwelcheWebSocketLesbare Daten oder gleichzeitige Aufgaben wieexchange.Go(), HttpQuery_Go(), etc. sind abgeschlossen.

Wenn das zurückgegebene Objekt kein Nullwert ist, wird dieEventDer in der Rückgabe enthaltenen Inhalt ist der Ereignis-Trigger-Typ. Zum Beispiel die folgende Rückgabewertstruktur:

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

Gegenstand

EventLoop (siehe unten) EventLoop (Zeitrahmen)

Der Parametertimeoutist die Einstellung der Ausfallzeit in Millisekunden.timeoutwartet, bis ein Ereignis auftritt, bevor es zurückgegeben wird, wenn es auf 0 gesetzt ist. Wenn es größer als 0 ist, setzt es das Ereignis auf einen Timeout und gibt das jüngste Ereignis sofort zurück, wenn es kleiner als 0 ist. Zeitverzögerung falsche Zahl

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

Der erste Anruf an dieEventLoop()Funktion im Code initialisiert den Mechanismus für das zugehörte Ereignis, und wenn die ersteEventLoop()Wenn ein Call nach dem Ereignis-Callback beginnt, wird es die vorherigen Ereignisse verpassen. Das zugrunde liegende System wickelt eine Warteschlange, die maximal 500 Ereignis-Callbacks speichert.EventLoop()Wenn die Funktion nicht rechtzeitig aufgerufen wird, um sie während der Programmdurchführung zu entfernen, werden spätere Ereignisrückrufe außerhalb des 500-Cache verloren gehen.EventLoop()Funktion beeinflussen nicht die Cache-Warteschlange des zugrunde liegenden Systems WebSocket oder die Caches von gleichzeitigen Funktionen wieexchange.Go(). Für diese Caches ist es immer noch notwendig, die jeweiligen Methoden zu verwenden, um die Daten abzurufen.EventLoop()Funktion für Daten, die vor demEventLoop()Der Hauptzweck derEventLoop()Die Funktion der Strategie-Schicht besteht darin, die Strategie-Schicht darüber zu informieren, dass neue Netzdaten vom zugrunde liegenden System empfangen wurden.EventLoop()Funktion gibt ein Ereignis zurück, durchläuft einfach alle Datenquellen.exchange.Go()Versuchen Sie, Daten zu erhalten.EventLoop()Die Funktion unterstützt nur Live-Handel. Hören Sie auf Ereignisse im Hauptthread, wenn Sie von der Hauptfunktion aufgerufen werdenmain(). in den in derJavaScriptSprache, diethreading.Thread()Funktion erstellt einen Thread, der auch in der Ausführungsfunktion des Threads aufgerufen werden kann, um auf Ereignisse im aktuellen Thread zu hören.

Das bedeutet, dass wir uns nicht mehr auf die Frage konzentrieren müssen.

__Dienen

Die__ServeFunktion wird verwendet, um Http-Dienst, TCP-Dienst und Websocket-Dienst (basierend auf Http-Protokoll) zu erstellen.

Gibt eine Zeichenfolge zurück, die die IP-Adresse und den Port des erstellten Dienstes aufzeichnet.127.0.0.1:8088, [::]:8089.

String

__Serve (ServeURI, Handler) __Serve ((serveURI, Handler,...args)

DieserveURIParameter wird verwendet, um das Protokoll, die IP-Adresse, den Port und andere Einstellungen der Dienstbindung zu konfigurieren, wiehttp://0.0.0.0:8088?gzip=true, d. h.http://:8088?gzip=true.

  • TCP-ProtokollserveURIEinstellung von Parametern wietcp://127.0.0.1:6666?tls=trueSie können z. B. Zertifikate und private Schlüssel hinzufügentls=true&cert_pem=xxxx&cert_key_pem=xxxx.
  • HTTP-ProtokollserveURIEinstellungen von Parametern wiehttp://127.0.0.1:6666?gzip=true; Sie können Komprimierungseinstellungen einstellen:gzip=true- Ich weiß. DieserveURIParameter wird für Https verwendet, wiehttps://127.0.0.1:6666?tls=true&gzip=true; Sie können hinzufügencert_pemundcert_key_pemParameter zum Laden des Zertifikats.

ServiceURI wahr String DiehandlerDer Parameter wird verwendet, um in der Routing-Verarbeitungsfunktion (Http-Protokoll), der Nachrichtenverarbeitungsfunktion (TCP-Protokoll) und der Stream-Verarbeitungsfunktion (Websocket) zu übergeben. Die von dem Parameter übermittelte Rückruffunktionhandlerkann mehrere Parameter definieren, der erste Parameter ist das ctx-Objekt (Kontextobjekt).

Handler wahr Funktion Der tatsächliche Parameter der Rückruffunktion wird als Parameter übergebenhandlerEs kann mehrere Parameter geben.arg, zum Beispiel:

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

Die Parameter1, 2, 3Sie ist bei der Anrufung der__Serve()Funktion entsprechen den Parameterna, b, cin der Rückruffunktion übergeben.

Arg falsche String, Zahl, bool, Objekt, Array, Funktion, Nullwert und andere vom System unterstützte Typen

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
  • Diese Funktion unterstützt nur JavaScript-Sprachstrategien.
  • Der Service-Thread ist vom globalen Umfang isoliert, so dass er keine Schließungen oder Verweise auf externe Variablen, benutzerdefinierte Funktionen usw. unterstützt; er kann jedoch alle Plattform-API-Funktionen aufrufen.
  • DieWebsocketSie können einen Routing-Zweig in den Pfad setzen und den Implementierungscode fürWebsocketSie können sich auf den Mustercode in diesem Abschnitt beziehen.

Die von dem Parameter übermittelte Rückruffunktionhandlererhält einectxDiectxParameter ist ein Kontextobjekt, das zur Erfassung und Schreibung von Daten mit folgenden Methoden verwendet wird:

  • ctx.proto ((() Wird auf das Http/TCP-Protokoll angewendet, gibt den Protokollnamen zurück, wenn er aufgerufen wird.HTTP/1.1, tcp.
  • ctx.host(') Anwendet auf das HTTP-Protokoll, gibt es Hostinformationen zurück, wenn IP-Adresse und Port aufgerufen werden.
  • ctx.path ((() Wird auf das HTTP-Protokoll angewendet, gibt er den Anforderungspfad zurück, wenn er aufgerufen wird.
  • ctx.query (Schlüssel) Wird auf das HTTP-Protokoll angewendet, gibt den Wert zurück, der dem Schlüssel in der Abfrage in der Anfrage entspricht, wenn sie aufgerufen wird.http://127.0.0.1:8088?num=123, und die von dem Parameter übermittelte Funktion für die RückrufverarbeitunghandlerErträge"123"Wann?ctx.query("num")ist genannt.
  • ctx.rawQuery() Wird auf das Http-Protokoll angewendet, wird bei Aufruf die ursprüngliche Abfrage in der Anfrage zurückgegeben (die Abfrage der Http-Anfrage).
  • ctx.header (n) Wird auf das Http-Protokoll angewendet und gibt bei Aufruf die Anforderungsheader-Informationen in der Anfrage zurück.
  • ctx.header (Schlüssel) Wird auf das HTTP-Protokoll angewendet, gibt es den Wert eines Schlüssels in der angegebenen Anforderungskopfzeile zurück, wenn er aufgerufen wird.User-Agentin den Überschriften des vorliegenden Antrags:ctx.header("User-Agent").
  • ctx.Methode (() Wird auf das Http-Protokoll angewendet, gibt die Anforderungsmethode zurück, wenn sie aufgerufen wird, wie z. B.GET, POST, usw.
  • ctx.body (siehe unten) Wird auf die POST-Anfrage des HTTP-Protokolls angewendet und gibt den Körper der Anfrage zurück, wenn er aufgerufen wird.
  • ctx.setHeader (Schlüssel, Wert) Wird auf das HTTP-Protokoll angewendet, um die Anfrageheader-Informationen der Antwortnachricht festzulegen.
  • ctx.setStatus (code) Für das Http-Protokoll wird der Statuscode der Http-Nachricht gesetzt. Normalerweise wird der Statuscode am Ende des Routing-Branches gesetzt. Der Standardwert ist 200.
  • ctx.remoteAddr() Wird auf das HTTP/TCP-Protokoll angewendet, gibt die Adresse des Remote-Clients und den Port in der Anfrage zurück, wenn er aufgerufen wird.
  • ctx.localAddr() Wird auf das HTTP/TCP-Protokoll angewendet, gibt die lokale Adresse und den Port des Dienstes zurück, wenn er aufgerufen wird.
  • ctx.upgrade ((Websocket) Wird auf die Implementierung des Websocket-Protokolls basierend auf dem Http-Protokoll angewendet, wird diectxKontextobjekt zum Websocket-Protokoll; Gibt einen Boolean-Wert (true) zurück, wenn der Switch erfolgreich ist, und einen Boolean-Wert (false), wenn er fehlschlägt.
  • ctx.read ((timeout_ms) Wird auf Websocket-Protokollimplementierung/TCP-Protokoll basierend auf HTTP-Protokoll angewendet, liest Daten von Websocket-Verbindung und TCP-Verbindung.readSie können den Timeout-Parameter angeben.timeout_msin Millisekunden.
  • ctx.write (s) Wird auf das HTTP/TCP-Protokoll angewendet, verwendet, um String-Daten zu schreiben.JSON.stringify()Das JSON-Objekt in eine Zeichenkette zu kodieren und dann zu schreiben.WebSocketProtokoll, Sie können diese Methode verwenden, um die verschlüsselte Zeichenfolge an den Client weiterzugeben.

Das ist eine sehr schwierige Aufgabe.

_G

Die Datenstruktur ist eine KV-Tabelle, die dauerhaft in der lokalen Datenbankdatei des Dockers gespeichert wird.

Dauerhaft gespeicherte Schlüsselwertdaten ink-vSchlüssel-Wert-Paare. String, Zahl, bool, Objekt, Array, Nullwert

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

Der Parameterkist der Name des Schlüssels im gespeicherten Schlüssel-Wert-Paar und ist nicht groß- oder kleinbuchstabenbezogen. k falsche String, Nullwert Der Parametervist der Schlüsselwert im gespeicherten Schlüssel-Wert-Paar, das alle Daten sein kann, die gespeichert werden könnenJSONSie ist in Serie. v falsche String, Zahl, bool, Objekt, Array, Nullwert

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

Eine getrennte Datenbank für jeden Live-Handel, die von der_G()Wenn das Backtesting abgeschlossen ist, werden die Daten, die im Backtesting-System gespeichert werden, von der_G()Wenn Sie die Funktion_G()Funktion, um die gespeicherten Daten aufrechtzuerhalten, sollte sie entsprechend dem Speicher- und Festplattenraum der Hardwareinrichtung vernünftig verwendet werden und nicht missbraucht werden. Bei Anrufen der_G()Funktion in einem Live-Handel und keine Parameter übergeben werden, die_G()Funktion gibt dieIdDer aktuelle Live-Handel._G()Funktion, der Parametervwird als null übergeben, um die Löschung derk-vBei Aufrufen der_G()Funktion, nur der Parameterkwird in der Zeichenfolge übergeben, und die_G()Funktion gibt den Schlüsselwert zurück, der dem gespeicherten Parameter entsprichtk. Wenn Sie die_G()Funktion, nur der Parameterkwird in einem Nullwert übergeben, der anzeigt, dass alle Datensätze derk-vDas Key-Value-Paar wird gelöscht.k-vdie Schlüssel-Wert-Paare wurden dauerhaft gespeichert,_G()Funktion wird erneut aufgerufen, indem der Name des Schlüssels, der als Parameter aufrechterhalten wurde, weitergegeben wirdk. Das neue Schlüsselwert als Parameter gebenvWir werden das aktualisieren.k-vSchlüssel-Wert-Paar.

Ich bin nicht derjenige.

_D

Konvertiert Millisekundenzeitstempel oderDateGegenstände zu Zeitfolgen.

Zeitstring. String

_D() Zeitstempel _BAR_ Zeitstempel, fmt)

Zeitstempel in Millisekunden oderDateGegenstand. Zeitstempel falsche Nummer, Gegenstand Formatierung der Zeichenkette,JavaScriptSprache Standardformat:yyyy-MM-dd hh:mm:ss; PythonSprache Standardformat:%Y-%m-%d %H:%M:%S; C++Sprache Standardformat:%Y-%m-%d %H:%M:%S- Ich weiß. fmt falsche String

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

Erhalten und drucken Sie die aktuelle Zeitfolge:

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

Der Zeitstempel lautet 1574993606000, wobei der Code umgerechnet wird:

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
}

Formatierung mit dem Parameterfmtist fürJavaScript, Python, undC++Sprachen, wie in den folgenden Beispielen gezeigt:

Gibt die aktuelle Zeitfolge zurück, ohne Parameter zu übergeben._D()Funktion imPythonSie müssen sich bewusst sein, dass die übergebenen Parameter Zeitstempel der zweiten Ebene sind (Zeitstempel auf Millisekundenebene in den JavaScript- und C++-Strategien, bei denen 1 Sekunde 1000 Millisekunden entspricht)._D()Die Funktion, um eine Zeitkette mit einem lesbaren Zeitstempel im Live-Handel zu analysieren, müssen Sie auf die Zeitzone und die Zeiteinstellung des Betriebssystems, in dem sich das Docker-Programm befindet, achten._D()Die Funktion analysiert einen Zeitstempel in eine lesbare Zeitfolge, abhängig von der Zeit des Dockers-Systems.

Das ist nicht nur ein Spiel, sondern auch ein Spiel.

_N

Formatieren Sie eine Fließkomma.

Die nach der Präzisionseinstellung formatierte Zahl mit schwebender Komma. Zahl

_N() _N (Nummer) _N (Nummer, Präzision)

Die zu formatierende Zahl mit schwebender Komma. Zahl wahr Zahl Die Präzisionseinstellung für die Formatierung, der Parameterprecisionist eine ganze Zahl, und der ParameterprecisionStandardeinstellungen 4. Präzision falsche Zahl

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

Zum Beispiel:_N(3.1415, 2)wird den Wert nach3.1415Zwei Dezimalstellen und die Funktion gibt zurück3.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);
}

Wenn Sie alle N-Zahlen links vom Dezimalpunkt auf 0 ändern müssen, können Sie es so schreiben:

Der Parameterprecisionkann eine positive oder negative ganze Zahl sein.

Ich bin nicht derjenige, der das Problem hat.

_C

Wiederholen Sie die Funktion für die Schnittstellenfehlertoleranz.

Der Rückgabewert der Rückruffunktion bei Ausführung. Alle Typen werden vom System unterstützt, außerlogischer falscher WertundNull-Wert.

_C (((pfn) - Ich bin nicht derjenige.

Der Parameterpfnist eine Funktionsreferenz, die eineRückruffunktion- Ich weiß. Pfn wahr Funktion Parameter bisRückruffunktionen, kann es mehr als einen Parameter gebenarg. Art und Anzahl der ParameterargDie Ergebnisse der StudieRückruffunktion- Ich weiß. Arg falsche String, Zahl, bool, Objekt, Array, Funktion, alle Typen werden vom System unterstützt, z. B. Nullwerte

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

Für fehlertolerante Funktionen ohne Parameter:

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

Für Funktionen mit fehlertoleranten Parametern:

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

Es kann auch für die Fehlerverträglichkeit von benutzerdefinierten Funktionen verwendet werden:

Die_C()function wird die angegebene Funktion aufrufen, bis sie erfolgreich zurückgegeben wird (die Funktion, auf die der Parameter verweistpfnErträgeNulloderfalscheWenn Sie angerufen werden, versuchen Sie es erneut.pfn) Zum Beispiel_C(exchange.GetTicker). Das Standard-Wiederversuchsintervall beträgt 3 Sekunden, Sie können die_CDelay()Funktion, um das Wiederholungsintervall festzulegen._CDelay(1000)Mittel zur Änderung des Wiederversuchsintervalls der_C()Funktion auf 1 Sekunde. Die Fehlertoleranz kann für folgende Funktionen durchgeführt werden, jedoch nicht auf diese beschränkt:

  • exchange.GetTicker()
  • exchange.GetDepth()
  • exchange.GetTrades()
  • exchange.GetRecords()
  • exchange.GetAccount()
  • exchange.GetOrders()
  • exchange.GetOrder()
  • exchange.GetPositions()Alle können von der_C()Die Funktion der Fehlerverträglichkeit_C()Die Funktion ist nicht auf die oben aufgeführte Funktion Fehlertoleranz beschränkt, der Parameterpfnist eine Funktionsreferenz und nicht ein Funktionsanruf. Beachten Sie, dass es_C(exchange.GetTicker), nicht_C(exchange.GetTicker()).

_ Kreuzung

Gibt die Anzahl der Schnittpunkte des Arrays zurückarr1und das Arrayarr2.

Anzahl der Querschnittsperioden des Arraysarr1und das Arrayarr2- Ich weiß. Zahl

_Kreuzung ((arr1, arr2)

Elemente sind Arrays von Typnumber- Ich weiß. Arr1 wahr Reihenfolge Elemente sind Arrays von Typnumber- Ich weiß. Arr2 wahr Reihenfolge

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

Eine Datenmenge kann simuliert werden, um die _Cross ((Arr1, Arr2) -Funktion zu testen:

Wenn der Rückgabewert der_Cross()Wenn die Funktion eine positive Zahl ist, gibt sie die Periode des Aufwärtstrends an, wenn sie eine negative Zahl ist, gibt sie die Periode des Abwärtstrends an, 0 entspricht dem aktuellen Preis.Analyse und Gebrauchsanweisung über die eingebaute Funktion.

JSONParse

Die FunktionJSONParse()wird zur Parsierung verwendetJSON strings.

JSONGegenstand. Gegenstand

JSONParse (s)

JSONSieht aus wie eine Schnur. s wahr String

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-Strings mit großen Werten können korrekt analysiert werden, und es wird große Werte als Stringtypen analysieren.JSONParse()Funktion wird im Backtestsystem nicht unterstützt.

Tagebücher