Pencipta Kuantiti API Dokumen

Penulis:Mimpi kecil, Dicipta: 2017-11-27 09:05:08, Dikemas kini: 2023-07-12 16:47:31

void main() {
    Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body");
}
  • MailVersi fungsi yang tidak selarasMail_GoFungsi: Penggunaan danexchange.GoFungsi serupa.

    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: Pelayan awan Ali mungkin menutup beberapa port, menyebabkan e-mel tidak dapat dihantar. Jika anda perlu menukar port, anda boleh memasukkan port langsung dalam parameter pertama, contohnya:smtp.qq.com:587, Ujian pelabuhan boleh dilakukan. Jika ada laporan yang salah:unencryped connectionYang perlu diubah.MailFungsismtpServerFormat parameter ialah:ssl://xxx.com:xxxContohnya, e-mel QQSMTPCara menggunakan SSL:ssl://smtp.qq.com:465atausmtp://xxx.com:xxx

SetErrorFilter(...)

SetErrorFilter(RegEx), penapisan log ralat. Parameter nilai: jenis baris. Log ralat yang dipadankan dengan ungkapan biasa ini tidak akan dimuat naik ke sistem log, dan anda boleh memanggil beberapa kali untuk menetapkan pelbagai syarat penapisan (log yang disaring tidak ditulis ke fail pangkalan data yang sepadan dengan ID cakera sebenar di bawah direktori hos, mencegah kesalahan yang kerap menyebabkan pembesaran fail pangkalan data).

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

Menyaring mesej ralat antara muka:

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 cakera sebenar.

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

GetLastError()

GetLastError(), untuk mendapatkan maklumat kesalahan terkini. Biasanya tidak perlu digunakan kerana program akan memuat naik maklumat kesalahan secara automatik ke sistem log.GetLastError()Fungsi ini kemudian membersihkan fail cache ini, dan tidak akan mengembalikan fail fail pada kali terakhir apabila dipanggil semula.

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

DapatkanCommand()

GetCommand(), mendapatkan tali perintah interaksi ((utf-8)); mendapatkan arahan yang dihantar oleh antara muka interaksi dasar dan mengosongkan cache, tanpa arahan akan mengembalikan tali kerja kosong; format arahan yang dikembalikan adalah按钮名称:参数Jika kawalan interaksi tidak mempunyai parameter (seperti kawalan butang tanpa kotak input), arahan adalah nama butang.

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 bawah mempunyai struktur larutan yang mencatat arahan interaksi apabilaGetCommand()Apabila fungsi dipanggil, perintah interaksi yang pertama masuk ke dalam larik akan diambil (jika tiada perintah interaksi, kembali strings kosong).

Contoh penggunaan kawalan interaktif, antara muka editor dasar untuk menetapkan kawalan interaktif.

img

Rancangan kod interaktif dalam strategi:

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 kod pendaftaran yang ditulis semasa menghasilkan dasarMetaNilai yang dikembalikan oleh fungsi adalah jenis string. Skenario aplikasi, contohnya strategi yang memerlukan batasan dana untuk penyewa yang berbeza. Nota: Kod pendaftaran dihasilkanMetaFungsi ini hanya digunakan untuk cakera fizikal dan memerlukan pengurus terkini. Jika kod pendaftaran dasar tidak ditetapkan semasa penjanaanGetMeta()Mengembalikan nilai kosong.

Maklumat mengenai 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)PermulaanSocketPengunjung, sokongantcpudptlsunixProtokol. Nilai parameter:AddressUntuk jenis strings,TimeOutUntuk jenis nilai, satuan nilai adalah saat, jika masa berlaluDial(...)Fungsi kembali nilai kosong.

AddressPerincian parameter:

Perincian parameter
TetapanDialParameter fungsi Di alamat biasa:wss://ws.okx.com:8443/ws/v5/publicSelepas|Pemisahan simbol, jika terdapat string nombor parameter|Tanda-tanda yang digunakan ialah||Digunakan sebagai tanda pemisahan.&Sambungan watak; contohnya, agen ss5 dan parameter mampatan disiapkan bersama:Dial("wss://ws.okx.com:8443/ws/v5/public|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv")
Apabila digunakan dalam protokol ws, parameter yang berkaitan dengan mampatan data adalah:compress=参数值 compress untuk mod mampatan, parameter mampatan, pilihangzip_rawgzipJika gzip bukan gzip standard, anda boleh menggunakan kaedah lanjutan:gzip_rawIni adalah tanda pemisah.|Tambah tetapan kemudiancompress=gzip_raw, menggunakan&Simbol dan parameter mode seterusnya dipisahkan.
Apabila digunakan dalam protokol ws, parameter yang berkaitan dengan mampatan data adalah:mode=参数值 mod untuk mod, boleh dipilihdualsendrecvTerdapat tiga jenis.dualUntuk kedua-dua arah, menghantar data mampatan dan menerima data mampatan.sendUntuk menghantar data mampatan.recvUntuk menerima data mampatan, dekompres secara tempatan.
Parameter yang berkaitan untuk menetapkan ejen socks5:proxy=参数值 Proxy ditetapkan sebagai ejen ss5, format nilai parameter:socks5://name:pwd@192.168.0.1:1080, nama adalah nama pengguna terminal ss5, pwd adalah kata laluan log masuk terminal ss5, dan 1080 adalah port perkhidmatan ss5.
Apabila digunakan dalam protokol ws, atur parameter yang berkaitan dengan sambungan semula automatik di bawah:reconnect=参数值 reconnect untuk menentukan sama ada anda akan menyambung semula,reconnect=trueUntuk mengaktifkan sambung semula. Jika tidak menetapkan parameter ini, tidak sambung semula secara lalai.
Apabila digunakan dalam protokol ws, atur parameter yang berkaitan dengan sambungan semula automatik di bawah:interval=参数值 Interval ialah selang masa ujian semula, dalam satu unit mili saat.interval=10000Untuk cuba semula pada selang 10 saat, tidak menetapkan 1 saat secara lalai, iaituinterval=1000
Apabila digunakan dalam protokol ws, atur parameter yang berkaitan dengan sambungan semula automatik di bawah:payload=参数值 Mesej langganan yang perlu dihantar apabila payload disambung semula sebagai ws, contohnya: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 menyokong parameter berikut:

  • Apabila tidak menyampaikan parameter, disekat sehingga ada mesej dan dikembalikan; contohnya:ws.read()
  • Apabila parameter dihantar, unitnya adalah milidetik, yang menentukan masa menunggu mesej melebihi masa; contohnya:ws.read(2000)Masa lapang yang ditetapkan adalah dua saat ((2000 ms).
  • Kedua-dua parameter di bawah adalah benar.websocketBerkesan: Parameter masuk-1Fungsi yang dikembalikan dengan segera sama ada ada ada mesej atau tidak, seperti:ws.read(-1)Saya tidak tahu apa yang berlaku. Parameter masuk-2Fungsi ini akan kembali dengan serta-merta walaupun tiada mesej, tetapi hanya akan kembali dengan mesej terkini, dan mesej di kawasan penyangga akan dibuang; contohnya:ws.read(-2)

read()Kawasan simpanan fungsi: Data yang dihantar oleh protokol ws jika diamalkan dalam strategiread()Jarak antara panggilan fungsi yang terlalu panjang boleh menyebabkan data terkumpul. Data ini disimpan di kawasan simpanan, struktur data kawasan simpanan adalah larutan, dengan had maksimum 2000; selepas melebihi 2000, data terkini masuk ke kawasan simpanan, dan data tertua dihapuskan.

PemandanganreadParameter fungsi Tiada parameter Parameter: -1 Parameter: -2 Parameter: 2000, unitnya ialah milidetik
Kawasan penyangga sudah ada data Kembali ke data terdahulu dengan segera Kembali ke data terdahulu dengan segera Kembali ke data terkini Kembali ke data terdahulu dengan segera
Tidak ada data di kawasan penyangga Menghalang sehingga data kembali Kembalikan nilai kosong dengan segera Kembalikan nilai kosong dengan segera Tunggu 2000 ms, tiada data akan dikembalikan, data akan dikembalikan
apabila sambungan ws terputus atau disambung semula di bawah Fungsi read (()) mengembalikan strings kosong, iaitu:"",write (()) fungsi kembali 0 dan mengesan keadaan tersebut. Anda boleh menggunakan close (()) fungsi untuk menutup sambungan, jika anda menetapkan sambung semula automatik, tidak perlu ditutup, lapisan bawah sistem akan disambung semula secara automatik.
  • Sokongan untuk protokol wss (WebSocket) Untuk mengakses antara muka pasaran 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("退出");
    }
    

    Perkhidmatan websocket untuk mengakses token:

    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 pengesahan:

    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), lawatan URL rangkaian. ⇒ Nilai parameter: semua untuk jenis tali. ⇒

Perhatikan:

  • HttpQuery(...)Fungsi hanya menyokongJavaScriptBahasa.
  • PythonBahasa boleh digunakanurllibJika anda ingin membuat permintaan, anda boleh menghantarnya ke laman web kami.

HttpQuery(...)Ia digunakan terutamanya untuk mengakses antara muka yang tidak memerlukan tandatangan, seperti antara muka awam seperti maklumat pasaran.

Contoh antara muka API yang tidak memerlukan tandatangan untuk mengakses OKX, yang mengembalikan nilai sebagaiJSONSaya tidak tahu apa yang berlaku.JavaScriptStrategi bahasa boleh digunakanJSON.parse()Penyelesaian fungsi.

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 kandungan URL yang dikembalikan jika parameter keduaPostDataUntuk stringsa=1&b=2&c=abcbentuknya.POSTCara penyampaian.PUTPermohonan yang dibuat oleh:PostDataParameter ialah{method:'PUT', data:'a=1&b=2&c=abc'}PostDataParameter juga boleh menjadiJSONString.

CookiesParameter ini mempunyai bentuk:a=10; b=20, setiap parameter mempunyai tanda perbandingan;Antara lain:HeadersParameter ini mempunyai bentuk:User-Agent: Mobile\nContent-Type: text/htmlParameter diganti dengan tanda baris\nAntara lain:

Parameter keduaPostDataCara yang boleh disesuaikan antara lain:HttpQuery("http://www.abc.com", {method:'PUT', data:'a=1&b=2&c=abc'})Perhatikan: Jika perlu, beriHttpQueryFungsi menetapkan masa lapang, boleh digunakan pada{method:'PUT', data:'a=1&b=2&c=abc'}SertaitimeoutAtribut (default 60 saat) ⇒

Seting 1 saat lewat:HttpQuery("http://www.abc.com", {method:'PUT', data:'a=1&b=2&c=abc', timeout:1000})

PenghantaranCookieString memerlukan parameter ketiga, tetapi tidakPOSTSila setkan parameter kedua sebagai nilai kosong. Apabila ujian analog, fungsi akan kembali strings tetap kerana tidak dapat meniru akses URLDummy Data│ Boleh menggunakan antara muka ini untuk menghantar mesej teks atau berinteraksi dengan antara muka API lain. │

GETContoh panggilan kaedah:HttpQuery("http://www.baidu.com")POSTContoh panggilan kaedah: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 seting ejen:

    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 fungsi yang tidak selarasHttpQuery_GoPerkataan: Penggunaan danexchange.GoFungsi yang serupa, seperti mengakses antara muka awam bursa secara tidak selaras untuk mendapatkan data pasaran 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)
    }
    
    # 不支持
    
    // 不支持
    
  • Digunakan dalam sistem pengukuran semulaHttpQuery(...)Fungsi: boleh digunakan dalam sistem pengukuran semulaHttpQuery(...)Menghantar permintaan ((hanya disokong)GETMengambil data; Mengehadkan penggunaan 20 lawatan ke URL yang berbeza semasa mengulas semula; danHttpQuery(...)Akses akan menyimpan data pada URL yang sama pada lawatan keduaHttpQuery(...)Fungsi mengembalikan data cache (tidak lagi berlaku permintaan rangkaian sebenar).

    Kita boleh menjalankan program perkhidmatan pada pelayan atau peranti untuk bertindak balas terhadap program dasar.HttpQuery(...)Permintaan yang dihantar, program perkhidmatan bahasa Go yang digunakan untuk ujian 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)
    }
    

    Penggunaan untuk mengulas semula strategiHttpQuery(...)Permintaan untuk menghantar 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

  • Sokongan untuk mengkod semula data tindak balas permintaan, menyokong pengekodan biasa. TentukanPostDataParameter:{method: "GET",charset:"GB18030"}, maka kod pemindahan data (GB18030) yang dijawab dapat dilaksanakan.

Enkod ((...)

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

ParameteralgoAlgoritma yang digunakan dalam pengiraan kod, disokong dengan tetapan sebagai berikut: 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 dataData yang akan diproses.inputFormat/outputFormat/keyFormatSokongan parameterrawhexbase64stringCara pengekodan. JikakeyFormatJika tidak kosong, gunakan parameter.keyMenggunakan penyulitan (HMAC), jika tidak, menggunakan penyulitan lalaikeyParameteralgoTetapkan sebagai"sign"atau"signTx"Apabila parameter diperlukankey

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 menyokong:text.encoder.utf8text.decoder.utf8text.encoder.gbktext.decoder.gbk, untuk mengkodkan, memecahkan dan menghapuskan baris.

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 tahap nanodetik, jika anda memerlukan timestamp pada tahap milidetik, anda boleh menggunakan kod 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 tahap detik jam.

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

GetOS()

GetOS(), mengembalikan maklumat mengenai sistem di mana pentadbir berada.

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

Di komputer AppleMac OSPengeluaran log pengurus yang dijalankan di sistem operasi:

GetOS:darwin/amd64

darwinMaksudnya,Mac OSNama sistem.

MD5 ((String)

MD5(String), nilai parameter: jenis baris.

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

Pengeluaran log:

MD5 5eb63bbbe01eeed093cb22bb8f5acdc3

DBExec ((...)

DBExec(), nilai parameter: boleh menjadi jenis seperti tali, nilai nombor, nilai bul, nilai kosong. Nilai pulangan: objek yang mengandungi hasil pelaksanaan pernyataan SQLite. Fungsi antara muka pangkalan dataDBExec()Menggunakan parameter penghantaran, anda boleh mengendalikan pangkalan data cakera (SQLite database). Memudahkan operasi penambahan, penghapusan, semakan, perubahan dan lain-lain pada data dalam pangkalan data cakera.SQLiteSistem Simpanan Jadual di Pangkalan Data:kvdbcfglogprofitchartJangan gunakan jadual ini. Perhatikan:DBExec()Fungsi ini hanya menyokong cakera sebenar.

  • Sokongan untuk pangkalan data memori UntukDBExecParameter fungsi jikasqlPerkataan ini adalah:Pada mulanya, operasi dalam pangkalan data dalam memori, tanpa menulis fail, lebih cepat. Sesuai untuk operasi pangkalan data yang tidak memerlukan penyimpanan kekal, 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 jadual

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);
}
  • Tambah, hapuskan, dan ubah rekod dalam jadual
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 cakera sebenar.

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)Dalam apa-apawebsocketboleh dibaca atauexchange.GoHttpQuery_GoTukar parameter pada masa yang sama.timeoutJika ditetapkan kepada 0 menunggu kejadian berlaku, jika lebih besar daripada 0 adalah masa tunggu peristiwa yang ditetapkan, jika kurang daripada 0 segera kembali kepada peristiwa terkini.nullMengembalikan apa yang terkandung dalam kandunganEventJenis pemicu untuk peristiwa. Fungsi ini hanya digunakan untuk cakera sebenar.

Panggilan pertama dalam kodEventLoopUntuk memulakannya, anda hanya perlu menghidupkan mekanisme untuk merakam kejadian itu, jika ia bermula untuk pertama kalinya selepas kejadian itu dipanggil semula.EventLoopPanggilan, akan terlepas peristiwa sebelumnya. Struktur barisan yang terbungkus oleh sistem bawah akan menyimpan sehingga 500 panggilan semula peristiwa, jika program tidak dipanggil pada masa yang tepat semasa pelaksanaanEventLoopMengambilnya, akan kehilangan 500 cache dan panggilan semula peristiwa yang lebih baru.EventLoopPanggilan fungsi tidak menjejaskan asas sistemwebsocketIa juga tidak memberi kesan kepadaexchange.GoCache fungsi selari seperti, untuk cache ini masih perlu menggunakan kaedah masing-masing untuk mendapatkan data.EventLoopData yang telah diambil tidak akan muncul sebelum fungsi kembali.EventLoopFungsi menghasilkan peristiwa pengembalian.

EventLoopFungsi utama adalah untuk memaklumkan lapisan dasar, di mana lapisan bawah sistem menerima data rangkaian baru.EventLoopFungsi hanya perlu melalui semua sumber data apabila mengembalikan peristiwa; contohnyawebsocketBerhubung.exchange.GoObjek yang dicipta cuba mendapatkan data. Ia boleh merujuk kepada reka bentuk perpustakaan sumber terbuka.Pautan perpustakaan

Dalam fungsi utamamain()Apabila panggilan tengah, dengarkan kejadian pada benang utama.JavaScriptDalam strategi penulisan bahasa, anda boleh menggunakan bahasa yang berbeza.__Thread()Thread yang dicipta oleh fungsi juga boleh dipanggil dalam fungsi pelaksanaan untuk mendengar kejadian pada thread semasa.

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 lanjut

qq89520Terdapat satu masalah, adakah fungsi C akan cuba semula atau hanya sekali sahaja.

Haiwwhai_C ((function, args...) ini adalah 3s secara lalai? Adakah anda boleh menukar secara lalai untuk meletakkan _CDelay ((1000) sebelum _C ((function, args...)?

makan malamKluster: Jika anda mencipta 1000 bot secara serentak, tanpa tekanan, anda boleh mencipta beberapa pengurus untuk menyebarkan tugas. Terdapat contoh kod untuk membina kluster? Bagaimana untuk membina pelbagai hos untuk mengagihkan tugas

wangyj1Log ((talib.help (('MACD')); hanya boleh digunakan di bawah js, Python tidak mempunyai sifat talib.help...

cjz140Apakah perbezaan antara fungsi _C (function, args...) dan fungsi Sleep, yang saya rasa bermaksud menunggu untuk mencuba semula?

3263243yBagaimana untuk mengosongkan ErrorFilter selepas SetErrorFilter? tanpa menapis mesej ralat.

qq47898077Adakah ada cara lain untuk menggunakan perpustakaan pihak ketiga?

qq47898077Apakah yang harus diisi oleh kelas induk jika anda ingin mewarisi kelas baru yang ditakrifkan oleh objek bursa?

ethanwuAdakah terdapat alat debugging tempatan?

penglihengApakah exange.IO (("status") itu?

penglihengAdakah fungsi sell tidak boleh digunakan lagi? by boleh digunakan, bagaimana untuk menjual?

penglihengAdakah fungsi sell tidak boleh digunakan lagi? by boleh digunakan, bagaimana untuk menjual?

penglihengJS tak pandai bahasa Inggeris, haha, nak tanya support ES6 tak?

penglihengJS tak pandai bahasa Inggeris, haha, nak tanya support ES6 tak?

Don.Bagaimana kita menulis garis tengah bagi volume?

ZjuturtleApakah yang akan dikembalikan jika tidak berjaya membeli pada harga pasaran?

Lelaki NingFonts baru ini nampak cantik.

ikan hippopotamusRangkaian ujian Bitmex ((testnet.bitmex.com) juga mempunyai antara muka API, tetapi pada masa ini pertukaran hanya boleh memilih stesen utama Bitmex, alamat dokumen API adalah https://testnet.bitmex.com/app/apiOverview Bagaimana anda boleh menyokongnya?

cxjijinvar ret1 = exchanges[0].IO (("api", "future_estimated_price", "symbol=btc_usd"); Log (('ok niaga hadapan anggaran harga penghantaran', ret1); https://dn-filebox.qbox.me/d1ed268c1e75753c5d289447d279aa9d81e41b5f.png Jika anda menggunakan antara muka lain untuk membuat laporan kesalahan, mengapa?

AllenfrostlineSaya ingin bertanya apa perbezaan antara realTicker dan Ticker? Strategi untuk menulis semula suite baru-baru ini muncul pada masa yang sama tetapi tidak kelihatan ada sebutan dalam API yang pertama.

penglihatanHalo, sebagai pemaju Python, apa yang anda rasa dokumen API anda menulis? beberapa antara muka fungsi bidang kelihatan pelik, bolehkah anda menulis dokumen seperti githubpage dan readdocs?

AllenfrostlineGetAccount: [EAPI: Rate limit exceeded] Nak tanya bagaimana ini boleh diselesaikan?

zhjx2314Tidak menyokong StochRSI, boleh ditambah secepat mungkin

yhfggAdakah skrip di pelayan awan Ali sendiri atau botvs cluster?

yhfggApakah versi python yang anda gunakan?

FkyslyPenerangan GetFee sepatutnya ialah yang mengembalikan struktur Fee, minus satu kata.

zkwapAdakah cara memanggil talib menggunakan js?

yhfggMemeriksa dokumentasi Python

Wmjbs123Adakah latar belakang kod editor strategi boleh menjadi hitam? mata putih yang menusuk, menulis kod pada waktu malam, mudah rabun.

Don.Bagaimana untuk menetapkan ringkasan dalam akhbar WeChat robot?

Bilangan: GilaBolehkah anda menambah satu bidang dengan harga sama dalam struktur pesanan?

Anak kecil.GetOrders: Dapatkan semua pesanan yang belum selesai, kembalikan struktur array Order, dalam perdagangan Bitcoin ETH di China, hanya mengembalikan 10 item yang paling baru, apakah terdapat fungsi yang mengembalikan semua pesanan yang belum selesai di China Bitcoin ETH, yang bermaksud platform lain boleh menggunakan GetOrders untuk mengembalikan semua, hanya hantu ini Cina Bitcoin kembali 10 item,

yhfggFungsi matematik yang diperlukan untuk teori kebarangkalian statistik, di mana ia digunakan?

jiebangApakah maksud nilai pulangan fungsi $.Cross ((x, y)?

Nama ibu sayaLogReset akan mengosongkan semua log, dengan parameter nombor untuk menentukan rekod yang akan disimpan Bagaimana untuk memadamkan beberapa log terkini?

EdwardgywAdakah fungsi CORRE dalam talib seolah-olah tidak dipindahkan atau terlepas?

Gunung miskin Yang YangTidak kelihatan ada ciri rujukan penunjuk!

KecilSaya tidak faham, terlalu lama, selesai, terima kasih

KecilBagaimana untuk menulis nombor dalam array, saya menggunakan records.remove ((records[0]) seolah-olah tidak berfungsi

ularayuJika anda menggunakan ATR, anda boleh menggunakan ATR pada hari-hari.

ularayuJika anda menggunakan ATR, anda boleh menggunakan ATR pada hari-hari.

57278863Belajar bagaimana untuk mendapatkan harga dan pesanan pada niaga hadapan tradisional, maaf, asasnya tipis.

kirinContoh perdagangan niaga hadapan tradisional!

KecilBolehkah anda menulis contoh perdagangan niaga hadapan tradisional?

KecilBagaimana saya boleh mencetak status simpanan, bagaimana saya boleh mencetak status simpanan obyek, bagaimana saya boleh mendapatkan status simpanan simpanan simpanan dan simpanan kosong, dan juga GetTicker (), bagaimana saya boleh mendapatkan harga minggu, minggu berikutnya, dan suku pada minggu itu. Saya menulis minggu, minggu berikutnya, dan suku pada minggu itu.

cxjijinAdakah bursa niaga hadapan boleh menggunakan GetTicker untuk mendapatkan pasaran? Apakah jenis pasaran kontrak yang dikembalikan (minggu, minggu seterusnya...)?

MenjualAdakah anda boleh menambah StochRSI?

momoxCancelOrder ((orderId) untuk membatalkan pesanan berdasarkan nombor pesanan, kembalikan true atau false, tanya true= sel telah berjaya dibatalkan, betul?

momox_G(K, V) boleh disimpan global dictionary Adakah kaedah ini menyimpan global variabel yang boleh digunakan untuk berkongsi data antara dasar yang berbeza?

flufy3dKemasukan

SifarAnda boleh menetapkan semula log pendapatan dengan menggunakan LogProfitReset.

xyBolehkah anda menyalin EA secara langsung?

sjironmanSaya rasa platform ini sangat hebat, lebih banyak interaksi dalam kumpulan.

KecilBahasa apa ini, ada bahan untuk belajar?

jxhbtcData error seminggu tidak boleh disambungkan ke bot.

DyahhuAdakah indeks TA hanya untuk mengira harga penutupan?

btcrobotHai, dunia.

Mimpi kecilFungsi _C akan mencuba semula tanpa berfikir sehingga hasil yang berjaya diperoleh.

Mimpi kecilPerpustakaan talib untuk python memerlukan pemasangan.https://www.botvs.com/bbs-topic/669 boleh lihat catatan ini.

Mimpi kecilSleep ialah program yang tidak melakukan apa-apa, menunggu parameter ditetapkan dalam beberapa mili saat, _C ialah fungsi yang dipanggil semula sekali parameter yang dihantar.

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

Mimpi kecilTerdapat penyunting tempatan, pemalam sinkronisasi jauh, yang pada dasarnya adalah penyunting tempatan, debugging jauh.

Mimpi kecilBoleh datang ke kumpulan QQ,^^ mudah dibincangkan~

Mimpi kecilDalam dokumentasi API, warna kelabu bermaksud fungsi ini tidak mempunyai banyak penjelasan yang terbuka, menunjukkan wakil kelabu, biru mempunyai lebih banyak penjelasan, dan itu sahaja.

Mimpi kecilES6 tidak disokong buat masa ini ^^

Mimpi kecilBoleh ke kumpulan QQ saya, jelaskan soalan saya, saya akan menjawab ^^

Mimpi kecilJika anda membeli barang yang tidak sesuai dengan harga yang anda inginkan, anda akan mendapat satu kesilapan dan anda tidak akan membuat pesanan (yang sebenarnya adalah membeli, tidak cukup wang!)

ZjuturtleSebagai contoh, OKCoin, jika jumlah yang dibeli melebihi jumlah yang dipegang, apa yang akan dikembalikan?

Mimpi kecilSaya akan kembalikan satu nombor pesanan di OK Futures.

SifarSudah menyokong pertukaran transaksi pada masa berjalan, memerlukan muat turun hos terkini. Sokongan Bter/Poloniex Perincian API dokumentasi Fungsi urus niaga gambar di bawah ((bersihkan cache penyemak imbas dan kemas semula jika tidak dapat dilihat)

Mimpi kecilQQ saya, saya akan membantu anda mencari soalan anda.

Ibu bapa profesionalJika anda ingin membuat senarai putih, saya akan menetapkan IP hos?

Mimpi kecilIni adalah pautan bawah tanah yang tidak dibuat pelayan tidak bertindak balas. Adakah anda menetapkan alamat IP semasa meminta API KEY?

Ibu bapa profesionalIni memalukan... Saya ok boleh menjalankan strategi yang telah gagal pada zaman 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 Zaman Bitcoin Kesilapan GetAccount: timeout 2017-05-23 21:08:02 Zaman Bitcoin Kesilapan GetAccount: timeout 2017-05-23 21:07:40 Zaman Bitcoin Kesilapan GetAccount: timeout 2017-05-23 21:07:20 Mulakan semula Adakah masalah senarai putih IP???

Mimpi kecilPelayan pertukaran tidak bertindak balas, protokol TCP tidak ditubuhkan dan tiga kali berjabat tangan tidak dilakukan.

Ibu bapa profesionalA connection attempt failed because the connected party did not properly respond after a period of time. A connection attempt failed because the connected party did not properly respond after a period of time. A connection attempt failed because the connected party did not properly respond after a period of time.

Mimpi kecilHello! Saya bercakap mengenai fungsi exchange.IO (api, ApiName, Args) yang tidak disokong, lihat https://www.botvs.com/bbs-topic/812

Ibu bapa profesionalPercubaan sambungan gagal kerana pihak yang disambungkan tidak bertindak balas dengan betul selepas tempoh masa,

Ibu bapa profesionalAdakah Zaman Bit tidak menyokong?

Mimpi kecilhttps://dn-filebox.qbox.me/a709b30c6cc0a3565234b9e0c99b073f7ba8b454.png Mungkin boleh.

Lelaki NingSebagai contoh, saya ingin melakukan perdagangan semua mata wang untuk poloniex, tetapi hanya beberapa mata wang yang disokong oleh BOTvs, dan exchange.IO nampaknya tidak menyokong Pnet.

Mimpi kecilIa boleh dipanggil sebagai exchange.IO.

Lelaki NingBagaimana pula dengan API yang memerlukan pengesahan akaun?

Mimpi kecilJika API yang tidak memerlukan pengesahan akaun boleh digunakan dengan httpQuery (lihat dokumentasi BotVS), API urus niaga sebenar memerlukan akses.

Mimpi kecilParameter boleh dihantar menggunakan API HttpQuery: https://www.okcoin.com/api/v1/future_estimated_price.do?symbol=btc_usd. Untuk API pertukaran yang tidak memerlukan pelaksanaan pengesahan akaun, gunakan fungsi HttpQuery di platform secara langsung, yang berkaitan dengan akaun hanya menggunakan IO API (IO tidak menyokong API pelaksanaan yang tidak memerlukan pengesahan ini). Posting: https://www.botvs.com/bbs-topic/850

penglihatanTerima kasih, saya berharap anda mempunyai dokumentasi API yang baik.

Mimpi kecilDi mana anda boleh melihat API realTicker?

Mimpi kecilhttps://dn-filebox.qbox.me/fe1a6f5563ed43a5357f858ecf8a50239619228e.png Dokumen API adalah bahasa JavaScript. Disebutkan, versi python dijelaskan di bahagian atas halaman Komuniti Komuniti Perbuatan.

SifarHi, terima kasih atas cadangan, dokumen API sedang dibina semula.

Mimpi kecilSelamat datang ~ menunjukkan bahawa frekuensi akses melebihi had. https://dn-filebox.qbox.me/a09498920d04cac62624b7438a058d2098d8fb00.png Adakah anda menggunakan fungsi Sleep (1000) dalam dasar anda?, 1000 ini adalah untuk menghentikan program selama satu saat setiap pusingan, yang boleh ditetapkan sendiri, tujuan adalah untuk mengawal frekuensi program mengakses API, kerana beberapa bursa menetapkan had akses maksimum, masa tertentu melebihi jumlah lawatan tertentu akan menolak akses, menyekat alamat IP.

Mimpi kecilhttps://dn-filebox.qbox.me/c29ab7fc279e1b758355f137907cf52dc8257df6.png Saya sendiri menulis bahawa STOCHRSI yang telah dibandingkan dengan OK adalah agak perlahan dan perlu dioptimumkan sementara.

SifarAnda boleh memilih untuk mengulang semula pada pelayan yang disediakan oleh botvs atau pelayan hos anda sendiri, versi adalah 2.7.5

Mimpi kecilSaya tidak tahu apa yang akan berlaku.

Mimpi kecilSekarang anda boleh menyesuaikan gaya latar belakang anda sendiri.

Mimpi kecilDokumen python sedang ditulis.

Mimpi kecilTalib Library boleh disokong.

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

Mimpi kecilRupanya terdapat contoh di Strategy Square, https://www.botvs.com/strategy/15098

SifarAkses kepada sifat AvergPrice Order, yang boleh disokong oleh bursa, dan yang tidak disokong oleh bursa akan sentiasa mempunyai sifat 0.

yhfggBagaimana sumber pihak ketiga mengutip?

SifarJika mathjs tidak dapat memuaskan permintaan, maka ia hanya boleh mencari dasar penyalinan salinan dari perpustakaan pihak ketiga. Untuk mempercepatkan penyusunan, sistem hanya membina beberapa perpustakaan.

Mimpi kecilTidak sopan, ada masalah dalam kumpulan boleh M saya - saya pada dasarnya online.

jiebangTerima kasih.

Mimpi kecilAnda boleh lihat nota-nota mengenai perpustakaan kod pertukaran mata wang digital, di mana terdapat nota mengenai fungsi $.Cross.

SifarTidak dapat memadamkan yang terbaru, hanya menyimpan beberapa yang terkini... memadamkan semua yang lama sebelum ini.

kirinUntuk mendapatkan setiap pegangan dengan posisi [i], kedudukan adalah satu aritmatika

Lelaki Ningpertukaran.GetRecords ((PERIOD_D1));

kirinFitur niaga hadapan tradisional saya selalu memberi isyarat: "GetAccount: not login", "Password tidak salah, tidak boleh log masuk", "GetAccount: not login", "Password tidak salah, tidak boleh log masuk".

SifarSetContractType diperlukan untuk mendapatkan SetContractType yang ditentukan.

SifarSeperti yang anda lihat, ini adalah nilai pulangan untuk tindakan membatalkan pesanan yang dikembalikan oleh bursa, tetapi pembatalan sebenarnya tidak dibatalkan, bergantung kepada bagaimana ia diuruskan di dalam bursa.

momox3q

Sifar"Tidaklah demikian, kerana ia adalah tempat yang terpencil.

xuanxuanSudah tentu tidak, itu eksklusif untuk MT4.

SifarJavascript ada di mana-mana di internet.

MenjualAdakah masalah anda diselesaikan?

SifarKebanyakan data yang anda masukkan boleh berupa rekod secara langsung atau merupakan satu set harga murni.