Penemu mengkuantifikasi dokumen API

Penulis:Mimpi kecil, Dibuat: 2017-11-27 09:05:08, Diperbarui: 2023-07-12 16:47:31

void main() {
    Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body");
}
  • MailVersi asinkron fungsiMail_GoFungsi: Penggunaan danexchange.GoFungsi ini mirip.

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

Perhatikan: Server Ali Cloud mungkin akan menutup beberapa port sehingga email tidak dapat dikirim. Jika Anda ingin mengubah port, Anda dapat menambahkan nomor port langsung di parameter pertama, misalnya:smtp.qq.com:587, port test ini tersedia. Jika terjadi kesalahan:unencryped connectionAda yang harus diubah.MailFungsismtpServerFormat parameter adalah:ssl://xxx.com:xxxContoh QQ emailSMTPCara menggunakan SSL:ssl://smtp.qq.com:465Atausmtp://xxx.com:xxx

SetErrorFilter ((...)

SetErrorFilter(RegEx), Filter error log↑ Parameter value: String type↑ Log kesalahan yang dicocokkan dengan ekspresi reguler ini tidak akan diunggah ke sistem log, dan beberapa kali dapat dipanggil untuk mengatur beberapa kondisi filter (log yang disaring tidak ditulis ke file database yang sesuai dengan ID real disk di direktori host, mencegah kesalahan yang sering terjadi yang menyebabkan pembesaran file database).

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

Untuk memfilter pesan kesalahan antarmuka:

function main() {
    // 随便查询一个不存在的订单,id为123,故意让接口报错
    var order = exchange.GetOrder("123")
    Log(order)
    // 过滤http502错误、GetOrder接口错误,设置错误过滤之后,第二次调用GetOrder不再报错
    SetErrorFilter("502:|GetOrder")
    order = exchange.GetOrder("123")
    Log(order)
}
def main():
    order = exchange.GetOrder("123")
    Log(order)
    SetErrorFilter("502:|GetOrder")
    order = exchange.GetOrder("123")
    Log(order)
void main() {
    TId orderId;
    Order order = exchange.GetOrder(orderId);
    Log(order);
    SetErrorFilter("502:|GetOrder");
    order = exchange.GetOrder(orderId);
    Log(order);
}

GetPid ((()

GetPid(), Mengembalikan ID proses real disk.

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

GetLastError ((()

GetLastError(), untuk mendapatkan informasi kesalahan terbaru. Biasanya tidak diperlukan karena program akan mengunggah informasi kesalahan secara otomatis ke sistem log.GetLastError()Fungsi ini kemudian akan menghapus kesalahan ini dari cache dan tidak akan mengembalikan informasi yang salah pada catatan terakhir saat dihubungi lagi.

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

GetCommand ((()

GetCommand(), mengambil string perintah interaktif ((utf-8)); mengambil perintah yang dikirim dari antarmuka interaktif kebijakan dan mengosongkan cache, tidak ada perintah akan mengembalikan string kosong; format perintah yang dikembalikan adalah按钮名称:参数Jika kontrol interaktif tidak memiliki parameter (misalnya kontrol tombol tanpa kotak input), perintahnya adalah nama tombol.

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

Sistem dasar memiliki struktur antrian untuk mencatat perintah interaksi ketikaGetCommand()Ketika fungsi dipanggil, perintah interaktif yang pertama masuk ke dalam queue akan diambil (jika tidak ada perintah interaktif, kembali ke string kosong).

Contoh penggunaan kontrol interaktif, pengaturan kontrol interaktif di antarmuka editor kebijakan.

img

Strategi untuk merancang kode interaktif:

function main() {
    while (true) {
        LogStatus(_D())
        var cmd = GetCommand()
        if (cmd) {
            Log("cmd:", cmd)    
            var arr = cmd.split(":")
            if (arr[0] == "buy") {
                Log("买入,该控件不带数量")
            } else if (arr[0] == "sell") {
                Log("卖出,该控件带数量:", arr[1])
            } else {
                Log("其它控件触发:", arr)
            }
        }
        Sleep(1000)
    } 
}
def main():
    while True:
        LogStatus(_D())
        cmd = GetCommand()
        if cmd:
            Log("cmd:", cmd)
            arr = cmd.split(":")
            if arr[0] == "buy":
                Log("买入,该控件不带数量")
            elif arr[0] == "sell":
                Log("卖出,该控件带数量:", arr[1])
            else:
                Log("其它控件触发:", arr)
        Sleep(1000)
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
void split(const string& s,vector<string>& sv,const char flag = ' ') {
    sv.clear();
    istringstream iss(s);
    string temp;

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

void main() {
    while(true) {
        LogStatus(_D());
        auto cmd = GetCommand();
        if (cmd != "") {
            vector<string> arr;
            split(cmd, arr, ':');
            if(arr[0] == "buy") {
                Log("买入,该控件不带数量");
            } else if (arr[0] == "sell") {
                Log("卖出,该控件带数量:", arr[1]);
            } else {
                Log("其它控件触发:", arr);
            }
        }
        Sleep(1000);
    }
}

DapatkanMeta

GetMeta()Fungsi mengembalikan kode pendaftaran yang ditulis saat membuat kebijakanMetaFungsi ini mengembalikan nilai untuk jenis string. Skenario aplikasi, misalnya strategi yang membutuhkan pembatasan dana untuk penyewa yang berbeda. Catatan: Saat membuat kode pendaftaranMetaFungsi ini hanya berlaku untuk hard disk dan membutuhkan host terbaru. Jika tidak ada metadata yang ditetapkan saat membuat kode registrasi kebijakanGetMeta()Mengembalikan nilai kosong.

Informasi tentang penggunaan demonstrasi adegan

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

Pilih ((...)

Dial(Address, Timeout)Ini adalah yang pertama.SocketAkses, DukungantcpudptlsunixProtokol. Nilai parameter:AddressUntuk jenis string,TimeOutUntuk jenis nilai, satuan nilai adalah detik, jika terlambatDial(...)Fungsi ini mengembalikan nilai kosong.

AddressParameternya:

Pernyataan Parameter
PengaturanDialParameter fungsi Di alamat normal:wss://ws.okx.com:8443/ws/v5/publicSetelahnya|Perbedaan simbol, jika ada string parameter|Tanda-tanda ini adalah:||Digunakan sebagai simbol pemisah.&Koneksi karakter. Misalnya, agen ss5 dan parameter kompresi diatur bersama:Dial("wss://ws.okx.com:8443/ws/v5/public|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv")
Parameter yang terkait dengan kompresi data saat digunakan dalam protokol ws:compress=参数值 compress untuk mode kompresi, parameter kompresi, opsionalgzip_rawgzipJika gzip tidak standar, gzip dapat digunakan sebagai ekstensi:gzip_rawIni adalah tanda pemisah.|Tambahkan pengaturan kemudiancompress=gzip_rawMenggunakan&Simbol dan parameter mode berikutnya dipisahkan.
Parameter yang terkait dengan kompresi data saat digunakan dalam protokol ws:mode=参数值 mode untuk mode, opsionaldualsendrecvAda tiga macam.dualUntuk dua arah, mengirim data kompresi dan menerima data kompresi.sendUntuk mengirim data yang dikompres.recvUntuk menerima data kompresi, dekompresi secara lokal.
Parameter yang digunakan untuk mengatur agen socks5:proxy=参数值 Proxy adalah proxy yang diatur sebagai proxy ss5, dengan format parameter:socks5://name:pwd@192.168.0.1:1080,name adalah nama pengguna server ss5, pwd adalah password login server ss5, dan 1080 adalah port layanan ss5.
Saat digunakan pada protokol ws, atur parameter yang terkait dengan relink otomatis di bawahnya:reconnect=参数值 reconnect untuk menentukan apakah Anda telah menyiapkan koneksi ulang.reconnect=trueUntuk mengaktifkan re-linking. Jika parameter ini tidak ditetapkan, tidak re-linking secara default.
Saat digunakan pada protokol ws, atur parameter yang terkait dengan relink otomatis di bawahnya:interval=参数值 interval adalah interval waktu uji ulang, satuan milidetik,interval=10000Untuk mencoba kembali dengan interval 10 detik, tidak mengatur 1 detik secara default, yaituinterval=1000
Saat digunakan pada protokol ws, atur parameter yang terkait dengan relink otomatis di bawahnya:payload=参数值 Pesan berlangganan yang harus dikirim saat payload dihubungkan kembali ke ws, misalnya:payload=okok
function main(){
    // Dial支持tcp://,udp://,tls://,unix://协议,可加一个参数指定超时的秒数
    var client = Dial("tls://www.baidu.com:443")  
    if (client) {
        // write可再跟一个数字参数指定超时,write返回成功发送的字节数
        client.write("GET / HTTP/1.1\nConnection: Closed\n\n")
        while (true) {
            // read可再跟一个数字参数指定超时,单位:毫秒。返回null指出错或者超时或者socket已经关闭
            var buf = client.read()
            if (!buf) {
                 break
            }
            Log(buf)
        }
        client.close()
    }
}
def main():
    client = Dial("tls://www.baidu.com:443")
    if client:
        client.write("GET / HTTP/1.1\nConnection: Closed\n\n")
        while True:
            buf = client.read()
            if not buf:
                break
            Log(buf)
        client.close()
void main() {
    auto client = Dial("tls://www.baidu.com:443");
    if(client.Valid) {
        client.write("GET / HTTP/1.1\nConnection: Closed\n\n");
        while(true) {
            auto buf = client.read();
            if(buf == "") {
                break;
            }
            Log(buf);
        }
        client.close();
    }
}

readFungsi ini mendukung parameter berikut:

  • Jika tidak mengirim parameter, blokir sampai ada pesan dan kembali; misalnya:ws.read()
  • Pada saat parameter ditransmisikan, satuan adalah milidetik, dan pesan ditentukan menunggu waktu yang lebih lama. Misalnya:ws.read(2000)Waktu penundaan yang ditentukan adalah dua detik ((2000 milliseconds) ).
  • Dua parameter di bawah ini hanya benar.websocketEfektif: Parameter masuk-1Fungsi yang akan dikembalikan secara instan, apakah ada pesan atau tidak, misalnya:ws.read(-1)Saya tidak tahu. Parameter masuk-2Ini berarti bahwa fungsi akan segera kembali tanpa adanya pesan, tetapi hanya akan kembali dengan pesan terbaru, dan pesan di area buffer akan dibuang.ws.read(-2)

read()Fungsi buffer menjelaskan: Ws protokol memaksa data yang datang jika dalam kebijakanread()Interval waktu antara panggilan fungsi yang terlalu panjang dapat menyebabkan akumulasi data. Data ini disimpan di area buffer, dengan struktur data buffer sebagai larik, dengan batas maksimum 2000 data. Setelah melewati 2000, data terbaru masuk ke area buffer, dan data tertua dihapus.

PemandanganreadParameter fungsi Tidak ada parameter Parameter: -1 Parameter: -2 Parameter: 2000, satuan adalah milidetik
Ada data di area buffer. Kembali ke data tertua Kembali ke data tertua Kembali ke Data Terbaru Kembali ke data tertua
Tidak ada data di area buffer Blokir sampai ada data Mengembalikan nilai kosong segera Mengembalikan nilai kosong segera Tunggu 2000 millisecond, tidak ada data yang dikembalikan ke nol, data yang dikembalikan
ws ketika koneksi putus atau di bawahnya dihubungkan kembali Fungsi read (()) mengembalikan string kosong, yaitu: "", write (()) fungsi kembali 0 dan mendeteksi keadaan tersebut. Anda dapat menggunakan fungsi close (()) untuk menutup koneksi, jika Anda mengatur ulang otomatis tidak perlu ditutup, dan dasar sistem akan secara otomatis kembali terhubung.
  • Dukungan untuk protokol wss (WebSocket) Untuk mengakses interface pasar websocket Binance:

    function main() {
        LogStatus("正在连接...")
        // 访问币安的websocket接口
        var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
        if (!client) {
            Log("连接失败, 程序退出")
            return
        }
        
        while (true) {
            // read只返回调用read之后获取的数据
            var buf = client.read()      
            if (!buf) {
                break
            }
            var table = {
                type: 'table',
                title: '行情图表',
                cols: ['币种', '最高', '最低', '买一', '卖一', '最后成交价', '成交量', '更新时间'],
                rows: []
            }
            var obj = JSON.parse(buf)
            _.each(obj, function(ticker) {
                table.rows.push([ticker.s, ticker.h, ticker.l, ticker.b, ticker.a, ticker.c, ticker.q, _D(ticker.E)])
            })
            LogStatus('`' + JSON.stringify(table) + '`')
        }
        client.close()
    }
    
    import json
    def main():
        LogStatus("正在连接...")
        client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
        if not client:
            Log("连接失败, 程序退出")
            return 
        
        while True:
            buf = client.read()
            if not buf:
                break
            table = {
                "type" : "table", 
                "title" : "行情图表", 
                "cols" : ["币种", "最高", "最低", "买一", "卖一", "最后成交价", "成交量", "更新时间"], 
                "rows" : [] 
            }
            obj = json.loads(buf)
            for i in range(len(obj)):
                table["rows"].append([obj[i]["s"], obj[i]["h"], obj[i]["l"], obj[i]["b"], obj[i]["a"], obj[i]["c"], obj[i]["q"], _D(int(obj[i]["E"]))])
            LogStatus('`' + json.dumps(table) + '`')
        client.close()
    
    void main() {
        LogStatus("正在连接...");
        auto client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
        if(!client.Valid) {
            Log("连接失败, 程序退出");
            return;
        }
        
        while(true) {
            auto buf = client.read();
            if(buf == "") {
                break;
            }
            json table = R"({
                "type" : "table", 
                "title" : "行情图表", 
                "cols" : ["币种", "最高", "最低", "买一", "卖一", "最后成交价", "成交量", "更新时间"], 
                "rows" : []
            })"_json;
            json obj = json::parse(buf);
            for(auto& ele : obj.items()) {
                table["rows"].push_back({ele.value()["s"], ele.value()["h"], ele.value()["l"], ele.value()["b"], ele.value()["a"], ele.value()["c"], 
                    ele.value()["q"], _D(ele.value()["E"])});
            }
            LogStatus("`" + table.dump() + "`");
        }
        client.close();
    }
    

    Untuk mengakses websocket OKX:

    var ws = null 
    function main(){
        var param = {
            "op": "subscribe",
            "args": [{
                "channel": "tickers",
                "instId": "BTC-USDT"
            }]
        }
        // 在调用Dial函数时,指定reconnect=true即设置为重连模式,指定payload即为重连时发送的消息。在websocket连接断开后,会自动重连,自动发送消息
        ws = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload="+ JSON.stringify(param))
        if(ws){
            var pingCyc = 1000 * 20
            var lastPingTime = new Date().getTime()
            while(true){
                var nowTime = new Date().getTime()
                var ret = ws.read()
                Log("ret:", ret)
                if(nowTime - lastPingTime > pingCyc){
                    var retPing = ws.write("ping")
                    lastPingTime = nowTime
                    Log("发送 :ping", "#FF0000")
                }
                LogStatus("当前时间:", _D())
                Sleep(1000)
            }
        }
    }  
    
    function onexit() {
        ws.close() 
        Log("退出")
    }
    
    import json
    import time  
    
    ws = None
    def main():
        global ws 
        param = {
            "op": "subscribe",
            "args": [{
                "channel": "tickers",
                "instId": "BTC-USDT"
            }]
        }
        ws = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload=" + json.dumps(param))
        if ws:
            pingCyc = 1000 * 20
            lastPingTime = time.time() * 1000
            while True:
                nowTime = time.time() * 1000
                ret = ws.read()
                Log("ret:", ret)
                if nowTime - lastPingTime > pingCyc:
                    retPing = ws.write("ping")
                    lastPingTime = nowTime
                    Log("发送:ping", "#FF0000")
                LogStatus("当前时间:", _D())
                Sleep(1000)  
    
    def onexit():
        ws.close()
        Log("退出")
    
    auto objWS = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true");  
    
    void main() {
        json param = R"({
            "op": "subscribe",
            "args": [{
                "channel": "tickers",
                "instId": "BTC-USDT"
            }]
        })"_json;
        
        objWS.write(param.dump());
        if(objWS.Valid) {
            uint64_t pingCyc = 1000 * 20;
            uint64_t lastPingTime = Unix() * 1000;
            while(true) {
                uint64_t nowTime = Unix() * 1000;
                auto ret = objWS.read();
                Log("ret:", ret);
                if(nowTime - lastPingTime > pingCyc) {
                    auto retPing = objWS.write("ping");
                    lastPingTime = nowTime;
                    Log("发送:ping", "#FF0000");
                }
                LogStatus("当前时间:", _D());
                Sleep(1000);
            }
        }
    }  
    
    void onexit() {
        objWS.close();
        Log("退出");
    }
    

    Perangkat lunak yang digunakan untuk mengakses token adalah:

    var ws = null   
    
    function main(){
        var param = {"sub": "market.btcusdt.detail", "id": "id1"}
        ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload="+ JSON.stringify(param))
        if(ws){
            while(1){
                var ret = ws.read()
                Log("ret:", ret)
                // 响应心跳包操作
                try {
                    var jsonRet = JSON.parse(ret)
                    if(typeof(jsonRet.ping) == "number") {
                        var strPong = JSON.stringify({"pong" : jsonRet.ping})
                        ws.write(strPong)
                        Log("响应ping,发送pong:", strPong, "#FF0000")
                    }
                } catch(e) {
                    Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
                }
                
                LogStatus("当前时间:", _D())
                Sleep(1000)
            }
        }
    }  
    
    function onexit() {
        ws.close() 
        Log("执行ws.close()函数")
    }
    
    import json
    ws = None  
    
    def main():
        global ws
        param = {"sub" : "market.btcusdt.detail", "id" : "id1"}
        ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + json.dumps(param))
        if ws:
            while True:
                ret = ws.read()
                Log("ret:", ret)              
                # 响应心跳包操作
                try:
                    jsonRet = json.loads(ret)
                    if "ping" in jsonRet and type(jsonRet["ping"]) == int:
                        strPong = json.dumps({"pong" : jsonRet["ping"]})
                        ws.write(strPong)
                        Log("响应ping,发送pong:", strPong, "#FF0000")
                except Exception as e:
                    Log("e:", e)
                    
                LogStatus("当前时间:", _D())
                Sleep(1000)
        
    def onexit():
        ws.close()
        Log("执行ws.close()函数")  
    
    using namespace std;
    void main() {
        json param = R"({"sub" : "market.btcusdt.detail", "id" : "id1"})"_json;
        auto ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + param.dump());
        if(ws.Valid) {
            while(true) {
                auto ret = ws.read();
                Log("ret:", ret);              
                // 响应心跳包操作
                try 
                {
                    auto jsonRet = json::parse(ret);
                    if(jsonRet["ping"].is_number()) {
                        json pong = R"({"pong" : 0})"_json;
                        pong["pong"] = jsonRet["ping"];
                        auto strPong = pong.dump();
                        ws.write(strPong);
                        Log("响应ping,发送pong:", strPong, "#FF0000");
                    }
                } catch(exception &e) 
                {
                    Log("e:", e.what());
                }
                
                LogStatus("当前时间:", _D());
                Sleep(1000);
            }
        }
    }  
    
    void onexit() {
        // ws.close();
        Log("执行ws.close()函数");
    }
    

    Untuk mengakses OKX, websocket validasi interface:

    function getLogin(pAccessKey, pSecretKey, pPassphrase) {
        // 签名函数,用于登录
        var ts = (new Date().getTime() / 1000).toString()
        var login = {
            "op": "login",
            "args":[{
                "apiKey"    : pAccessKey,
                "passphrase" : pPassphrase,
                "timestamp" : ts,
                "sign" : exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey)
            }]
        }    
        return login
    }    
    
    var client_private = null 
    function main() {
        // 因为read函数使用了超时设置,过滤超时的报错,否则会有冗余错误输出
        SetErrorFilter("timeout")
        
        // 持仓频道订阅信息
        var posSubscribe = {
            "op": "subscribe",
            "args": [{
                "channel": "positions",
                "instType": "ANY"
            }]
        }    
    
        var accessKey = "xxx"
        var secretKey = "xxx"
        var passphrase = "xxx"
    
        client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
        client_private.write(JSON.stringify(getLogin(accessKey, secretKey, passphrase)))
        Sleep(3000)  // 登录时,不能立即订阅私有频道,需要等待服务器反应
        client_private.write(JSON.stringify(posSubscribe))
        if (client_private) {
            var lastPingTS = new Date().getTime()
            while (true) {
                var buf = client_private.read(-1)
                if (buf) {
                    Log(buf)
                }
                
                // 检测断开,重连
                if (buf == "" && client_private.write(JSON.stringify(posSubscribe)) == 0) {
                    Log("检测到断开,关闭连接,重连")
                    client_private.close()
                    client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
                    client_private.write(JSON.stringify(getLogin(accessKey, secretKey, passphrase)))
                    Sleep(3000)
                    client_private.write(JSON.stringify(posSubscribe))
                }
                
                // 发送心跳包
                var nowPingTS = new Date().getTime()
                if (nowPingTS - lastPingTS > 10 * 1000) {
                    client_private.write("ping")
                    lastPingTS = nowPingTS
                }            
            }        
        }
    }    
    
    function onexit() {    
        var ret = client_private.close()
        Log("关闭连接!", ret)
    }
    
    import json
    import time
      
    def getLogin(pAccessKey, pSecretKey, pPassphrase):
        ts = str(time.time())
        login = {
            "op": "login",
            "args":[{
                "apiKey"    : pAccessKey,
                "passphrase" : pPassphrase,
                "timestamp" : ts,
                "sign" : exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey)
            }]
        }
        return login     
    
    client_private = None 
    def main():
        global client_private
        SetErrorFilter("timeout")
        
        posSubscribe = {
            "op": "subscribe",
            "args": [{
                "channel": "positions",
                "instType": "ANY"
            }]
        }      
    
        accessKey = "xxx"
        secretKey = "xxx"
        passphrase = "xxx"
        
        client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
        client_private.write(json.dumps(getLogin(accessKey, secretKey, passphrase)))
        Sleep(3000)
        client_private.write(json.dumps(posSubscribe))
        if client_private:
            lastPingTS = time.time() * 1000
            while True:
                buf = client_private.read(-1)
                if buf:
                    Log(buf)
                
                if buf == "" and client_private.write(json.dumps(posSubscribe)) == 0:
                    Log("检测到断开,关闭连接,重连")
                    ret = client_private.close()
                    client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
                    client_private.write(json.dumps(getLogin(accessKey, secretKey, passphrase)))
                    Sleep(3000)
                    client_private.write(json.dumps(posSubscribe))
                
                nowPingTS = time.time() * 1000
                if nowPingTS - lastPingTS > 10 * 1000:
                    client_private.write("ping")
                    lastPingTS = nowPingTS    
    
    def onexit():
        ret = client_private.close()
        Log("关闭连接!", ret)
    
    auto client_private = Dial("wss://ws.okx.com:8443/ws/v5/private");      
    
    json getLogin(string pAccessKey, string pSecretKey, string pPassphrase) {
        auto ts = std::to_string(Unix());
        json login = R"({
            "op": "login",
            "args": [{
                "apiKey": "",
                "passphrase": "",
                "timestamp": "",
                "sign": ""
            }]
        })"_json;
        login["args"][0]["apiKey"] = pAccessKey;
        login["args"][0]["passphrase"] = pPassphrase;
        login["args"][0]["timestamp"] = ts;
        login["args"][0]["sign"] = exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey);
        return login;
    }      
    
    void main() {
        SetErrorFilter("timeout");
        json posSubscribe = R"({
            "op": "subscribe",
            "args": [{
                "channel": "positions",
                "instType": "ANY"
            }]
        })"_json;
        
        auto accessKey = "xxx";
        auto secretKey = "xxx";
        auto passphrase = "xxx";
        
        client_private.write(getLogin(accessKey, secretKey, passphrase).dump());
        Sleep(3000);
        client_private.write(posSubscribe.dump());    
    
        if (client_private.Valid) {
            uint64_t lastPingTS = Unix() * 1000;      
    
            while (true) {
                auto buf = client_private.read(-1);
                if (buf != "") {
                    Log(buf);
                }
                if (buf == "") {
                    if (client_private.write(posSubscribe.dump()) == 0) {
                        Log("检测到断开,关闭连接,重连");
                        client_private.close();
                        client_private = Dial("wss://ws.okx.com:8443/ws/v5/private");
                        client_private.write(getLogin(accessKey, secretKey, passphrase).dump());
                        Sleep(3000);
                        client_private.write(posSubscribe.dump());
                    }
                }
                
                uint64_t nowPingTS = Unix() * 1000;
                if (nowPingTS - lastPingTS > 10 * 1000) {
                    client_private.write("ping");
                    lastPingTS = nowPingTS;
                }
            }
        }
    }      
    
    void onexit() {
        client_private.close();
        Log("退出");
    }
    

HttpQuery ((...)

HttpQuery(Url, PostData, Cookies, Headers, IsReturnHeader), Akses URL jaringan↑ Nilai parameter: semua untuk tipe string↑

Perhatikan:

  • HttpQuery(...)Fungsi hanya mendukungJavaScriptBahasa.
  • PythonBahasa dapat digunakanurllibJika Anda ingin mendapatkan informasi lebih lanjut, silakan hubungi kami.

HttpQuery(...)Ini terutama digunakan untuk mengakses antarmuka yang tidak memerlukan tanda tangan, seperti antarmuka publik seperti informasi pasar.

Contoh API yang tidak memerlukan tanda tangan untuk mengakses OKX, kembali nilaiJSONSaya tidak tahu apa yang terjadi.JavaScriptStrategi bahasa dapat digunakan untukJSON.parse()Fungsi penguraian.

function main(){
    // 一个GET访问不带参数的例子
    var info = JSON.parse(HttpQuery("https://www.okx.com/api/v5/public/time"))
    Log(info)
    // 一个GET访问带参数的例子
    var ticker = JSON.parse(HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT"))
    Log(ticker)
}
import json
import urllib.request
def main():
    # HttpQuery不支持Python,可以使用urllib/urllib2库代替
    info = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/public/time").read().decode('utf-8'))
    Log(info)
    ticker = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/market/books?instId=BTC-USDT").read().decode('utf-8'))
    Log(ticker)
void main() {
    auto info = json::parse(HttpQuery("https://www.okx.com/api/v5/public/time"));
    Log(info);
    auto ticker = json::parse(HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT"));
    Log(ticker);
}

Dapatkan konten yang dikembalikan dari sebuah URL jika parameter keduaPostDataUntuk Stringa=1&b=2&c=abcDan bentuknya adalah:POSTCara pengiriman. Contoh lainnyaPUT"Saya tidak tahu apa yang terjadi.PostDataParameternya adalah{method:'PUT', data:'a=1&b=2&c=abc'}PostDataParameter ini juga bisaJSONString adalah sebuah string.

CookiesParameter ini berupa:a=10; b=20Setiap parameter diberi angka.;Perbedaan-perbedaan tersebut.HeadersParameter ini berupa:User-Agent: Mobile\nContent-Type: text/htmlParameter diganti dengan tanda baris\nPerbedaan-perbedaan tersebut.

Parameter keduaPostDataCara yang dapat disesuaikan antara lain:HttpQuery("http://www.abc.com", {method:'PUT', data:'a=1&b=2&c=abc'})Perhatikan: Jika perlu, berikanHttpQueryFungsi ini mengatur waktu mundur.{method:'PUT', data:'a=1&b=2&c=abc'}BergabungtimeoutAtribut (default 60 detik) ⇒

Setel waktu mundur 1 detik:HttpQuery("http://www.abc.com", {method:'PUT', data:'a=1&b=2&c=abc', timeout:1000})

PengirimanCookieString membutuhkan parameter ketiga, tapi tidakPOSTSilahkan set the second parameter to null. Pada saat pengujian analog, fungsi akan mengembalikan string tetap karena tidak dapat mengakses URL analog.Dummy DataAnda dapat mengirim pesan teks melalui antarmuka ini, atau berinteraksi dengan antarmuka API lainnya.

GETContoh panggilan metode:HttpQuery("http://www.baidu.com")POSTContoh panggilan metode:HttpQuery("http://www.163.com", "a=1&b=2&c=abc")

KembaliHeaderContoh panggilan:

HttpQuery("http://www.baidu.com", null, "a=10; b=20", "User-Agent: Mobile\nContent-Type: text/html", true)  // will return {Header: HTTP Header, Body: HTML}
  • HttpQueryFungsi menggunakan pengaturan proxy:

    function main() {
        // 本次设置代理并发送http请求,无用户名,无密码,此次http请求会通过代理发送
        HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/")
    
        // 本次设置代理并发送http请求,输入用户名和密码,仅HttpQuery当前调用生效,之后再次调用HttpQuery("http://www.baidu.com")这样不会使用代理
        HttpQuery("socks5://username:password@127.0.0.1:8889/http://www.baidu.com/")
    }
    
    # HttpQuery不支持Python,可以使用Python的urllib2库
    
    void main() {
        HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/");
        HttpQuery("socks5://username:password@127.0.0.1:8889/http://www.baidu.com/");
    }
    
  • HttpQueryVersi asinkron fungsiHttpQuery_GoSaya tidak tahu. Penggunaan danexchange.GoFungsi serupa, misalnya mengakses asinkronisasi antarmuka publik bursa untuk mendapatkan data pasar agregat.

    function main() {
        // 创建第一个异步线程
        var r1 = HttpQuery_Go("https://www.okx.com/api/v5/market/tickers?instType=SPOT")
        // 创建第二个异步线程
        var r2 = HttpQuery_Go("https://api.huobi.pro/market/tickers")
        
        // 获取第一个异步线程调用的返回值
        var tickers1 = r1.wait()
        // 获取第二个异步线程调用的返回值
        var tickers2 = r2.wait()
        
        // 打印结果
        Log("tickers1:", tickers1)
        Log("tickers2:", tickers2)
    }
    
    # 不支持
    
    // 不支持
    
  • Penggunaan dalam sistem retestingHttpQuery(...)Fungsi: dapat digunakan dalam sistem retestingHttpQuery(...)Mengirim permintaan (untuk dukungan saja)GETPermintaan) untuk mendapatkan data. Batasi waktu retesting dengan menggunakan 20 kali kunjungan ke URL yang berbeda, danHttpQuery(...)Kunjungan akan menyimpan data pada URL yang sama pada kunjungan keduaHttpQuery(...)Fungsi mengembalikan data cache (tidak lagi terjadi permintaan jaringan yang sebenarnya).

    Kita bisa menjalankan program layanan pada server atau perangkat tertentu untuk menanggapi program kebijakan.HttpQuery(...)Permintaan yang dikirim, program layanan bahasa Go yang digunakan untuk pengujian adalah sebagai berikut:

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

    Strategi yang digunakan untuk evaluasi ulangHttpQuery(...)Permintaan fungsi:

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

    img

  • Dukungan untuk mengkodekan data respon terhadap permintaan, mendukung pengkodean umum. TentukanPostDataParameter:{method: "GET",charset:"GB18030"}Dengan demikian, kode transfer data (GB18030) yang digunakan untuk menjawab pertanyaan dapat diimplementasikan.

Mengenkode...

Encode(algo, inputFormat, outputFormat, data, keyFormat, key string), Fungsi ini mengkodekan data berdasarkan parameter yang ditransfer.

ParameteralgoAlgoritma yang digunakan dalam perhitungan coding, yang didukung adalah:??raw (tidak menggunakan algoritma),??sign,??signTx,??md4,??md5,??sha256,??sha512,??sha1,??keccak256,??sha3.224,??sha3.256,??sha3.384,??sha3.512,??sha3.keccak256,??sha3.keccak512,??sha512.384,??sha512.256,??sha512.224,??ripemd160,??blake2b.256,??blake2b.512,??blake2s.128,??blake2s.256.Parameter.dataUntuk data yang akan diproses.inputFormat/outputFormat/keyFormatDukungan parameterrawhexbase64stringCara mengkode. JikakeyFormatJika tidak kosong, gunakan parameter.keyUntuk mengenkripsi (HMAC) atau menggunakan defaultkeyParameteralgoSetel untuk"sign"Atau"signTx"Perhatikan parameternya.key

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

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

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

ParameteralgoMereka juga mendukung:text.encoder.utf8text.decoder.utf8text.encoder.gbktext.decoder.gbk, Mengkode, Meng-dekode, Mengganti, Mengubah, Mengubah, Mengubah, Mengubah, Mengubah.

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

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

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

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

UnixNano ((()

UnixNano(), mengembalikan timestamp pada tingkat nanodetik, jika Anda ingin mendapatkan timestamp pada tingkat milidetik, Anda dapat menggunakan kode berikut:

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

Unix ((()

Unix(), Kembali ke tingkat detik waktu tombol.

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

GetOS()

GetOS(), mengembalikan informasi dari sistem di mana administrator berada.

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

Di komputer AppleMac OSOutput log host yang berjalan di sistem operasi:

GetOS: darwin/amd64

darwinIni adalahMac OSNama sistemnya.

MD5 ((String)

MD5(String), nilai parameter: jenis string.

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

Hasil log:

MD5 5eb63bbbe01eeed093cb22bb8f5acdc3

DBExec ((...)

DBExec(), Nilai parameter: dapat berupa jenis string, nilai numerik, nilai bul, nilai kosong, dll. Nilai balik: objek yang berisi hasil eksekusi pernyataan SQLite. Fungsi antarmuka databaseDBExec()Dengan input parameter, dapat mengoperasikan basis data disk (SQLite database) ‒ memungkinkan penambahan, penghapusan, pengecekan, perubahan dan lain-lain pada data dalam basis data disk, dukunganSQLiteSyntax. ========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================kvdbcfglogprofitchartJangan mengoperasikan tabel-tabel ini.DBExec()Fungsi ini hanya mendukung real disk.

  • Dukungan database memori UntukDBExecParameter dari fungsi jikaSqlKata-kata ini adalah::Pada awalnya, operasi di dalam database memori, tanpa menulis file, lebih cepat. Cocok untuk operasi database yang tidak memerlukan penyimpanan permanen, seperti:

    function main() {
        var strSql = [
            ":CREATE TABLE TEST_TABLE(", 
            "TS INT PRIMARY KEY NOT NULL,",
            "HIGH REAL NOT NULL,", 
            "OPEN REAL NOT NULL,", 
            "LOW REAL NOT NULL,", 
            "CLOSE REAL NOT NULL,", 
            "VOLUME REAL NOT NULL)"
        ].join("")
        var ret = DBExec(strSql)
        Log(ret)
        
        // 增加一条数据
        Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
        
        // 查询数据
        Log(DBExec(":SELECT * FROM TEST_TABLE;"))
    }
    
    def main():
        arr = [
            ":CREATE TABLE TEST_TABLE(", 
            "TS INT PRIMARY KEY NOT NULL,",
            "HIGH REAL NOT NULL,", 
            "OPEN REAL NOT NULL,", 
            "LOW REAL NOT NULL,", 
            "CLOSE REAL NOT NULL,", 
            "VOLUME REAL NOT NULL)"
        ]
        strSql = ""
        for i in range(len(arr)):
            strSql += arr[i]
        ret = DBExec(strSql)
        Log(ret)
        
        # 增加一条数据
        Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
        
        # 查询数据
        Log(DBExec(":SELECT * FROM TEST_TABLE;"))
    
    void main() {
        string strSql = ":CREATE TABLE TEST_TABLE(\
            TS INT PRIMARY KEY NOT NULL,\
            HIGH REAL NOT NULL,\
            OPEN REAL NOT NULL,\
            LOW REAL NOT NULL,\
            CLOSE REAL NOT NULL,\
            VOLUME REAL NOT NULL)";
        auto ret = DBExec(strSql);
        Log(ret);
        
        // 增加一条数据
        Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"));
        
        // 查询数据
        Log(DBExec(":SELECT * FROM TEST_TABLE;"));
    }
    
  • Membuat tabel

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);
}
  • Menambahkan, menghapus, dan mengubah catatan dalam tabel
function main() {
    var strSql = [
        "CREATE TABLE TEST_TABLE(", 
        "TS INT PRIMARY KEY NOT NULL,",
        "HIGH REAL NOT NULL,", 
        "OPEN REAL NOT NULL,", 
        "LOW REAL NOT NULL,", 
        "CLOSE REAL NOT NULL,", 
        "VOLUME REAL NOT NULL)"
    ].join("")
    Log(DBExec(strSql))
    
    // 增加一条数据
    Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
    
    // 查询数据
    Log(DBExec("SELECT * FROM TEST_TABLE;"))
    
    // 修改数据
    Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))    
    
    // 删除数据
    Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110))
}
def main():
    arr = [
        "CREATE TABLE TEST_TABLE(", 
        "TS INT PRIMARY KEY NOT NULL,",
        "HIGH REAL NOT NULL,", 
        "OPEN REAL NOT NULL,", 
        "LOW REAL NOT NULL,", 
        "CLOSE REAL NOT NULL,", 
        "VOLUME REAL NOT NULL)"
    ]
    strSql = ""
    for i in range(len(arr)):
        strSql += arr[i]
    Log(DBExec(strSql))
    
    # 增加一条数据
    Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
    
    # 查询数据
    Log(DBExec("SELECT * FROM TEST_TABLE;"))
    
    # 修改数据
    Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))
    
    # 删除数据
    Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110))
void main() {
    string strSql = "CREATE TABLE TEST_TABLE(\
        TS INT PRIMARY KEY NOT NULL,\
        HIGH REAL NOT NULL,\
        OPEN REAL NOT NULL,\
        LOW REAL NOT NULL,\
        CLOSE REAL NOT NULL,\
        VOLUME REAL NOT NULL)";
    Log(DBExec(strSql));

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

UUID ((()

UUID(), mengembalikan UUID unik 32-bit, yang hanya berlaku untuk hard disk.

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

EventLoop (timeout)

EventLoop(timeout)dan di mana punwebsocketBisa dibaca atauexchange.GoHttpQuery_GoPerangkat lunak ini dapat digunakan untuk melakukan beberapa hal yang sama.timeoutJika settingnya 0 maka akan kembali menunggu kejadian terjadi, jika setannya lebih besar dari 0 maka akan kembali menunggu kejadian lewat waktu, dan jika setannya lebih kecil dari 0 maka akan segera kembali kejadian terbaru.nullDengan cara ini, Anda akan mendapatkan hasil yang lebih baik.EventUntuk tipe pemicu peristiwa. Fungsi ini hanya berlaku untuk disk.

Panggilan pertama dalam kodeEventLoopUntuk menginisiasi mekanisme pemasangan, Anda harus melakukan pemasangan pertama kali setelah pemasangan kembali.EventLoopPanggilan, yang akan melewatkan peristiwa sebelumnya. Struktur antrian yang terbungkus pada sistem dasar akan menyimpan hingga 500 panggilan kejadian jika tidak ada panggilan yang tepat waktu selama program dijalankan.EventLoopJika Anda mengambilnya, maka Anda akan kehilangan 500 cache yang lebih baru.EventLoopPanggilan fungsi tidak mempengaruhi dasar sistemwebsocketSaya tidak tahu apa yang akan terjadi.exchange.GoCache fungsi paralel, misalnya, masih perlu menggunakan metode masing-masing untuk mengambil data.EventLoopDan jika Anda tidak dapat memindahkan data yang telah diambil, Anda tidak akan dapat memindahkan data yang telah diambil.EventLoopFungsi menghasilkan peristiwa pengembalian.

EventLoopFungsi utama adalah untuk menginformasikan layer kebijakan, yang merupakan lapisan bawah sistem yang menerima data jaringan baru.EventLoopFungsi hanya perlu melewati semua sumber data saat mengembalikan peristiwa.websocket"Semoga kita bisa melakukan hal yang sama", katanya.exchange.GoObjek yang dibuat mencoba untuk mendapatkan data. Anda dapat menggunakan desain pustaka sumber terbuka, dan Anda dapat mengkliknya untuk mendapatkan data.Tautan Kelas

Pada fungsi utamamain()Pada saat panggilan tengah, dengarkan kejadian pada thread utama.JavaScriptDalam strategi penulisan bahasa, Anda dapat menggunakan beberapa strategi yang berbeda.__Thread()Thread yang dibuat oleh fungsi dapat juga dipanggil dalam fungsi eksekusi dari thread untuk mendengarkan kejadian pada thread saat ini.

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

Lebih banyak

QQ89520Ada satu masalah, apakah fungsi_C akan mencoba lagi atau hanya sekali saja.

Haiwwhai_C ((function, args...) Apakah ini default 3s? Apakah Anda bisa mengubah default untuk langsung menempatkan _CDelay ((1000) sebelum _C ((function, args...)?

makan siangCluster: Jika Anda membuat 1000 robot secara bersamaan, dan tidak ada stres, Anda dapat membuat beberapa administrator untuk mendistribusikan tugas. Apakah ada contoh kode untuk membangun cluster? Bagaimana membangun beberapa host untuk mendistribusikan tugas

Wangij1Log ((talib.help (('MACD')); hanya dapat digunakan di bawah js, Python tidak memiliki atribut talib.help...

cjz140Apa perbedaan antara fungsi _C ((function, args...) dan fungsi Sleep, yang menurut saya berarti menunggu untuk mencoba lagi?

3263243yBagaimana cara menghapus ErrorFilter setelah SetErrorFilter? tanpa menyaring pesan kesalahan.

QQ47898077Apakah ada cara lain untuk menggunakan perpustakaan pihak ketiga?

QQ47898077Apa yang harus diisi oleh kelas induk jika Anda ingin mewarisi obyek bursa yang mendefinisikan kelas baru?

ethanwuApakah ada alat debugging lokal?

penglihengApa itu exange.IO (status)?

penglihengMengapa fungsi sell berwarna abu-abu, apakah fungsi representasi tidak tersedia lagi?

penglihengMengapa fungsi sell berwarna abu-abu, apakah fungsi representasi tidak tersedia lagi?

penglihengJS tidak bisa bahasa Inggris, haha, jadi saya ingin bertanya apakah Anda mendukung ES6.

penglihengJS tidak bisa bahasa Inggris, haha, jadi saya ingin bertanya apakah Anda mendukung ES6.

Don.Bagaimana cara menulis garis tengah volume?

TurtleJika tidak berhasil, apa yang akan dikembalikan jika Anda membeli di exchange.Buy.1000 dengan harga pasar?

Anak laki-laki NingFonts baru ini bagus.

kuda nilJaringan pengujian Bitmex ((testnet.bitmex.com) juga memiliki antarmuka API, tetapi saat ini pertukaran hanya dapat memilih Bitmex home station, alamat dokumen API adalah https://testnet.bitmex.com/app/apiOverview Bagaimana cara mendukungnya?

Cxjijinvar ret1 = exchanges[0].IO (("api", "future_estimated_price", "symbol=btc_usd"); Log (('ok futures estimated delivery price', ret1); https://dn-filebox.qbox.me/d1ed268c1e75753c5d289447d279aa9d81e41b5f.png Jika Anda menggunakan antarmuka yang berbeda, mengapa Anda menulis laporan kesalahan?

allenfrostlineApakah ada perbedaan antara realTicker dan Ticker? Baru-baru ini ada strategi untuk menulis ulang paket yang muncul pada saat yang sama, tetapi tampaknya tidak ada yang disebutkan dalam API yang pertama.

penglihatanHalo, sebagai seorang pengembang Python, apa yang menurut Anda ditulis dalam dokumen API Anda? Beberapa antarmuka fungsi bidang terlihat aneh, bisakah Anda menulis dokumen seperti githubpage dan readdocs?

allenfrostlineGetAccount: [EAPI:Rate limit exceeded] Mau tanya bagaimana cara mengatasinya? selain itu saya tidak punyaqq atau ada kelompok WeChat seperti itu? terima kasih

zhjx2314Tidak mendukung StochRSI, apakah bisa ditambahkan secepatnya?

yhfggPada saat itu, apakah skrip berada di server Ali Cloud sendiri atau di botvs cluster?

yhfggApa versi python yang Anda gunakan?

FkyslyGetFee harus diartikan sebagai sebuah struktur yang dikembalikan oleh Fee, dengan satu kata yang hilang.

ZkwapBagaimana cara memanggil talib menggunakan js?

yhfggMinta dokumentasi python

Wmjbs123Apakah background kode editor strategi bisa berwarna hitam? mata putih berbintik-bintik, menulis kode di malam hari, mudah dekat.

Don.Bagaimana cara menyetel ringkasan dalam pesan WeChat robot?

Angka-AngkaApakah saya bisa menambahkan bidang harga rata dalam struktur order?

Anak kecil.GetOrders: mendapatkan semua pesanan yang belum selesai, mengembalikan struktur Array Order, dalam perdagangan Bitcoin ETH di Cina, hanya mengembalikan 10 item terbaru.

yhfggFungsi matematika yang dibutuhkan untuk menggunakan probabilitas statistik, di mana?

jiebangApakah nilai yang dikembalikan dari fungsi $.Cross ((x, y) ini berarti apa?

Nama Ibu SayaLogReset ini akan mengosongkan semua log, dan dapat menggunakan parameter angka untuk menentukan jumlah catatan yang akan disimpan. Bagaimana cara menghapus beberapa log terbaru?

edwardgywFungsi CORRE di talib tampaknya tidak dipindahkan atau hilang?

Gunung miskin YangyangTampaknya tidak ada fitur referensi indikator!

KecilBagaimana waktu k-line yang dibaca diterjemahkan menjadi waktu sekarang oh, saya tidak mengerti, terlalu lama satu, diselesaikan, terima kasih

KecilBagaimana cara menulis angka di array, saya menggunakan records.remove (rekords[0]) sepertinya tidak bisa.

ularayuJika Anda ingin menggunakan ATR, Anda harus menggunakan ATR yang ada di jam-jam.

ularayuJika Anda ingin menggunakan ATR, Anda harus menggunakan ATR yang ada di jam-jam.

57278863Belajar bagaimana futures tradisional mendapatkan harga dan pesanan, maaf, akarnya tipis.

KirinIni adalah contoh dari perdagangan futures tradisional!

KecilApakah Anda bisa menulis contoh tentang perdagangan futures tradisional?

KecilBagaimana cara mencetak status kepemilikan, bagaimana cara saya mencetak adalah [object object], bagaimana cara mendapatkan status kepemilikan multi-objek dan kosong, dan juga GetTicker (), bagaimana cara mendapatkan minggu, minggu berikutnya, dan kuartal pada minggu itu.

CxjijinApakah bursa berjangka dapat mendapatkan pasar dengan GetTicker (??), dan apakah pasar yang dikembalikan adalah jenis kontrak (??) minggu ini, minggu berikutnya, dll.?

MenjualApakah ada indikator lain yang bisa ditambahkan untuk StochRSI?

MomoxCancelOrder ((orderId) Menghapus sebuah order berdasarkan nomor order, mengembalikan true atau false, tanya true= sel berhasil dibatalkan, kan?

Momox_G(K, V) Tabel global yang dapat disimpan Apakah metode ini menyimpan variabel global yang dapat digunakan untuk berbagi data antara kebijakan yang berbeda?

fluffy3dKeberhasilan yang luar biasa

Tidak adaAnda dapat mengatur ulang log pendapatan dengan LogProfitReset. Sejarah pada grafik pendapatan sebelumnya tidak ada.

xcyApakah Anda bisa menyalin EA secara langsung?

sjironmanSaya merasa platform ini luar biasa, luar biasa, lebih banyak interaksi dalam kelompok.

KecilBahasa apa itu, apakah ada bahan untuk belajar?

JxhbtcData error selama seminggu, tidak bisa terhubung ke robot, bagaimana cara menyelesaikannya?

DyahhuApakah indeks TA hanya untuk menghitung harga penutupan?

btcrobotHai, dunia.

Mimpi kecilFungsi _C akan mencoba lagi tanpa berpikir sampai hasilnya berhasil.

Mimpi kecilPerpustakaan talib untuk python perlu diinstal. https://www.botvs.com/bbs-topic/669 dapat dilihat di posting ini.

Mimpi kecilSleep adalah program yang tidak melakukan apa-apa, menunggu parameter yang ditetapkan dalam hitungan millisecond, _C adalah fungsi yang kembali memanggil parameter yang dikirimkan.

Mimpi kecilTanpa perlu mewarisi, JS langsung terbungkus pada objek {name: "objek baru", old_exchange : exchange[0],...... }

Mimpi kecilAda editor lokal, plugin sinkronisasi jarak jauh, yang pada dasarnya adalah editor lokal, debugging jarak jauh.

Mimpi kecilAnda bisa datang ke grup QQ, dan bisa mendiskusikannya.

Mimpi kecilDalam dokumentasi API, warna abu-abu berarti bahwa fungsi ini tidak memiliki penjelasan yang terlalu luas, menunjukkan representasi abu-abu dan biru. Ada lebih banyak penjelasan, itu saja.

Mimpi kecilES6 saat ini tidak didukung, ^^

Mimpi kecilAnda bisa masuk ke grup QQ Saya, jelaskan masalahnya, saya akan menjawabnya ^^

Mimpi kecilJika Anda tidak mau membeli, maka Anda harus membayarnya.

TurtleOKCoin, misalnya, jika jumlah yang dibeli melebihi jumlah yang dimiliki, apa yang akan dikembalikan?

Mimpi kecilSaya akan kembalikan nomor pesanan di OK Futures, dan saya akan kembalikan nomor pesanan di OK Futures.

Tidak adaSudah mendukung pertukaran transaksi pada saat berjalan, perlu mengunduh host terbaru. Dukungan Bter/Poloniex Rincian API dokumentasi Fungsi transaksi Tab deskripsi di bawah ((mengosongkan cache browser setelah refresh jika tidak terlihat)

Mimpi kecilQQ saya, saya akan membantu Anda mencari jawabannya.

Rumah Tangga yang BerkarirJika Anda ingin membuat daftar putih, saya akan mengatur IP host.

Mimpi kecilIni adalah tautan bawah tanah yang tidak dibuat. Server tidak merespons. Apakah alamat IP ditetapkan saat permintaan API KEY?

Rumah Tangga yang BerkarirIni sangat memalukan... saya tidak bisa menjalankan strategi yang telah gagal pada era bitcoin, GetAccount tidak dapat mengakses GetAccount: Post http://api.btc38.com/v1/getMyBalance.php: read tcp 192.168.0.227:58596->211.149.148.144:80: wsarecv: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. 2017-05-23 21:08:24 Era Bitcoin Kesalahan GetAccount: timeout 2017-05-23 21:08:02 Era Bitcoin Kesalahan GetAccount: timeout 2017-05-23 21:07:40 Era Bites Kesalahan GetAccount: timeout 2017-05-23 21:07:20 Membuat halaman berisi "Membuat halaman berisi 'Membuat halaman berisi 'Membuat halaman berisi 'Membuat halaman berisi 'Membuat halaman berisi 'Membuat halaman berisi 'Membuat halaman berisi 'Membuat halaman berisi 'Membuat halaman berisi 'Membuat halaman berisi 'Membuat halaman berisi 'Membuat halaman berisi 'Membuat halaman berisi 'Membuat halaman berisi ' Apakah itu masalah daftar putih IP???

Mimpi kecilServer bursa tidak merespon, protokol TCP tidak dibangun, tiga kali berjabat tangan tidak dilakukan.

Rumah Tangga yang BerkarirA connection attempt failed because the connected party did not properly respond after a period of time, atau "Percobaan koneksi gagal karena pihak yang terhubung tidak merespons dengan benar setelah periode waktu".

Mimpi kecilHalo! Ini adalah fungsi exchange.IO (api, ApiName, Args) yang tidak didukung, lihat https://www.botvs.com/bbs-topic/812

Rumah Tangga yang BerkarirPercobaan koneksi gagal karena pihak yang terhubung tidak merespon dengan benar setelah periode waktu,

Rumah Tangga yang BerkarirApakah Era Bitcoin Tidak Mendukung?

Mimpi kecilhttps://dn-filebox.qbox.me/a709b30c6cc0a3565234b9e0c99b073f7ba8b454.png Saya tidak tahu apa yang harus dilakukan.

Anak laki-laki NingSebagai contoh, saya ingin melakukan perdagangan mata uang penuh dengan poloniex, tetapi hanya beberapa mata uang yang didukung oleh BOTvs, dan exchange.IO tampaknya tidak mendukung Pnet.

Mimpi kecilAnda dapat memanggilnya sebagai exchange.IO.

Anak laki-laki NingBagaimana dengan API yang membutuhkan verifikasi akun?

Mimpi kecilJika API yang tidak memerlukan validasi akun dapat digunakan dengan httpQuery (lihat dokumentasi BotVS untuk lebih lanjut), API transaksi sebenarnya membutuhkan akses.

Mimpi kecilAnda dapat menggunakan HttpQuery untuk mengirim parameter API: https://www.okcoin.com/api/v1/future_estimated_price.do?symbol=btc_usd. Untuk API pertukaran yang tidak memerlukan verifikasi akun, langsung gunakan fungsi HttpQuery di platform, yang terkait dengan akun menggunakan IO API (IO tidak mendukung API pasar yang tidak memerlukan verifikasi ini). Posting: https://www.botvs.com/bbs-topic/850

penglihatanTerima kasih banyak, semoga ada dokumentasi API yang bagus.

Mimpi kecilSaya ingin tahu di mana saya melihat API realTicker?

Mimpi kecilhttps://dn-filebox.qbox.me/fe1a6f5563ed43a5357f858ecf8a50239619228e.png Dokumen API adalah bahasa JavaScript. Deskripsi, versi python. Deskripsi di bagian atas halaman Komunitas Komunitas.

Tidak adaHalo, terima kasih atas saran, dokumen API sedang dibangun ulang.

Mimpi kecilHello~ yang menunjukkan bahwa frekuensi akses telah melampaui batas. https://dn-filebox.qbox.me/a09498920d04cac62624b7438a058d2098d8fb00.png Apakah Anda menggunakan fungsi Sleep ((1000) dalam kebijakan?, 1000 ini adalah untuk membuat program berhenti sejenak per putaran, dapat diatur sendiri, tujuannya adalah untuk mengontrol program Akses frekuensi API, karena beberapa bursa menetapkan batas akses maksimum, waktu tertentu melebihi jumlah kunjungan tertentu akan menolak akses, memblokir alamat IP.

Mimpi kecilhttps://dn-filebox.qbox.me/c29ab7fc279e1b758355f137907cf52dc8257df6.png Saya sendiri menulis bahwa indikator STOCHRSI yang telah di bandingkan dengan OK, sepakat bahwa kecepatan agak lambat dan harus dioptimalkan, sementara tersedia.

Tidak adaAnda dapat memilih untuk meng-retest di server yang disediakan oleh botvs atau di server host Anda sendiri, versi adalah 2.7.5

Mimpi kecil"Mengharukan" adalah ungkapan yang sering diucapkan.

Mimpi kecilSekarang Anda dapat mengkonfigurasi gaya latar belakang Anda sendiri.

Mimpi kecilDokumen python sedang ditulis.

Mimpi kecilTalib Library mendukung ini.

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

Mimpi kecilTampaknya ada contoh di Strategy Square, https://www.botvs.com/strategy/15098

Tidak adaAkses properti AvergPrice untuk Order, yang didukung oleh pertukaran, dan yang tidak didukung oleh pertukaran akan selalu memiliki properti 0.

yhfggBagaimana sumber-sumber informasi pihak ketiga mengutip?

Tidak adaJika mathjs tidak dapat memuaskan kebutuhannya, maka hanya perlu mencari kebijakan copy-import dari library pihak ketiga. Untuk kecepatan kompilasi, sistem hanya memiliki sejumlah kecil library internal.

Mimpi kecilTidak sopan, ada masalah di grup Anda bisa M saya - saya pada dasarnya online.

jiebangTerima kasih.

Mimpi kecilAnda bisa melihat di kolom komentar, analisis kode dari perpustakaan perdagangan mata uang digital, dan di dalamnya ada komentar tentang fungsi $.Cross.

Tidak adaTidak dapat menghapus yang terbaru, hanya menyimpan beberapa yang terbaru... menghapus semua yang lama sebelum itu.

KirinUntuk mendapatkan setiap posisi dengan posisi [i], posisi adalah suatu array.

Anak laki-laki Ningexchange.GetRecords ((PERIOD_D1));

KirinFutur tradisional saya selalu berteriak "GetAccount: not login", "Password tidak salah, tidak bisa login", "GetAccount: not login", "GetAccount: not login", "Password tidak salah, tidak bisa login", "GetAccount: not login", "GetAccount: not login", "Password tidak salah, tidak bisa login", "GetAccount: tidak login", "GetAccount: not login", "Password tidak salah, tidak bisa login", "GetAccount: tidak login", "GetAccount: tidak login", "Password tidak salah, tidak bisa masuk", "GetAccount: tidak masuk", "GetAccount: tidak masuk", "GetAccount: tidak masuk", "GetAccount: tidak masuk", "GetAccount: tidak masuk", "Gain: tidak masuk"

Tidak adaJika Anda memilih untuk mengklik SetContractType, maka Anda akan mendapatkan SetContractType.

Tidak adaSeperti yang kita lihat, true adalah nilai yang dikembalikan dari tindakan membatalkan order yang dikembalikan oleh bursa, tetapi pembatalan sebenarnya tidak dibatalkan, tergantung pada bagaimana hal itu ditangani di dalam bursa.

Momox3q

Tidak ada(Tidak demikian) sampai suatu waktu (yang telah dipisahkan).

xuanxuanTentu saja tidak, itu eksklusif untuk MT4.

Tidak adaJavascript tersedia di mana-mana di internet.

MenjualApakah masalah Anda sudah diselesaikan?

Tidak adaSebagian besar dari data yang masuk bisa langsung menjadi rekaman atau sebuah array harga murni.