void main() {
Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body");
}
Mail
Versi asinkron fungsiMail_Go
Fungsi:
Penggunaan danexchange.Go
Fungsi 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 connection
Ada yang harus diubah.Mail
FungsismtpServer
Format parameter adalah:ssl://xxx.com:xxx
Contoh QQ emailSMTP
Cara menggunakan SSL:ssl://smtp.qq.com:465
Atausmtp://xxx.com:xxx
。
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()
, 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()
, 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()
, 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.
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);
}
}
GetMeta()
Fungsi mengembalikan kode pendaftaran yang ditulis saat membuat kebijakanMeta
Fungsi ini mengembalikan nilai untuk jenis string.
Skenario aplikasi, misalnya strategi yang membutuhkan pembatasan dana untuk penyewa yang berbeda.
Catatan: Saat membuat kode pendaftaranMeta
Fungsi 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);
}
}
Dial(Address, Timeout)
Ini adalah yang pertama.Socket
Akses, Dukungantcp
,udp
,tls
,unix
Protokol. Nilai parameter:Address
Untuk jenis string,TimeOut
Untuk jenis nilai, satuan nilai adalah detik, jika terlambatDial(...)
Fungsi ini mengembalikan nilai kosong.
Address
Parameternya:
– | Pernyataan Parameter |
---|---|
PengaturanDial Parameter fungsi |
Di alamat normal:wss://ws.okx.com:8443/ws/v5/public Setelahnya| 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_raw 、gzip Jika gzip tidak standar, gzip dapat digunakan sebagai ekstensi:gzip_raw Ini adalah tanda pemisah.| Tambahkan pengaturan kemudiancompress=gzip_raw Menggunakan& Simbol dan parameter mode berikutnya dipisahkan. |
Parameter yang terkait dengan kompresi data saat digunakan dalam protokol ws:mode=参数值 |
mode untuk mode, opsionaldual ,send ,recv Ada tiga macam.dual Untuk dua arah, mengirim data kompresi dan menerima data kompresi.send Untuk mengirim data yang dikompres.recv Untuk 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=true Untuk 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=10000 Untuk 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();
}
}
read
Fungsi ini mendukung parameter berikut:
ws.read()
。ws.read(2000)
Waktu penundaan yang ditentukan adalah dua detik ((2000 milliseconds) ).websocket
Efektif:
Parameter masuk-1
Fungsi yang akan dikembalikan secara instan, apakah ada pesan atau tidak, misalnya:ws.read(-1)
Saya tidak tahu.
Parameter masuk-2
Ini 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.
Pemandanganread Parameter 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(Url, PostData, Cookies, Headers, IsReturnHeader)
, Akses URL jaringan↑ Nilai parameter: semua untuk tipe string↑
Perhatikan:
HttpQuery(...)
Fungsi hanya mendukungJavaScript
Bahasa.Python
Bahasa dapat digunakanurllib
Jika 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 nilaiJSON
Saya tidak tahu apa yang terjadi.JavaScript
Strategi 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 keduaPostData
Untuk Stringa=1&b=2&c=abc
Dan bentuknya adalah:POST
Cara pengiriman. Contoh lainnyaPUT
"Saya tidak tahu apa yang terjadi.PostData
Parameternya adalah{method:'PUT', data:'a=1&b=2&c=abc'}
。
PostData
Parameter ini juga bisaJSON
String adalah sebuah string.
Cookies
Parameter ini berupa:a=10; b=20
Setiap parameter diberi angka.;
Perbedaan-perbedaan tersebut.Headers
Parameter ini berupa:User-Agent: Mobile\nContent-Type: text/html
Parameter diganti dengan tanda baris\n
Perbedaan-perbedaan tersebut.
Parameter keduaPostData
Cara yang dapat disesuaikan antara lain:HttpQuery("http://www.abc.com", {method:'PUT', data:'a=1&b=2&c=abc'})
Perhatikan: Jika perlu, berikanHttpQuery
Fungsi ini mengatur waktu mundur.{method:'PUT', data:'a=1&b=2&c=abc'}
Bergabungtimeout
Atribut (default 60 detik) ⇒
Setel waktu mundur 1 detik:HttpQuery("http://www.abc.com", {method:'PUT', data:'a=1&b=2&c=abc', timeout:1000})
PengirimanCookie
String membutuhkan parameter ketiga, tapi tidakPOST
Silahkan set the second parameter to null. Pada saat pengujian analog, fungsi akan mengembalikan string tetap karena tidak dapat mengakses URL analog.Dummy Data
Anda dapat mengirim pesan teks melalui antarmuka ini, atau berinteraksi dengan antarmuka API lainnya.
GET
Contoh panggilan metode:HttpQuery("http://www.baidu.com")
。
POST
Contoh panggilan metode:HttpQuery("http://www.163.com", "a=1&b=2&c=abc")
。
KembaliHeader
Contoh 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}
HttpQuery
Fungsi 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/");
}
HttpQuery
Versi asinkron fungsiHttpQuery_Go
Saya tidak tahu.
Penggunaan danexchange.Go
Fungsi 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)GET
Permintaan) 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());
}
Dukungan untuk mengkodekan data respon terhadap permintaan, mendukung pengkodean umum.
TentukanPostData
Parameter:{method: "GET",charset:"GB18030"}
Dengan demikian, kode transfer data (GB18030) yang digunakan untuk menjawab pertanyaan dapat diimplementasikan.
Encode(algo, inputFormat, outputFormat, data, keyFormat, key string)
, Fungsi ini mengkodekan data berdasarkan parameter yang ditransfer.
Parameteralgo
Algoritma yang digunakan dalam perhitungan coding, yang didukung adalah:??rawdata
Untuk data yang akan diproses.inputFormat
/outputFormat
/keyFormat
Dukungan parameterraw
,hex
,base64
,string
Cara mengkode.
JikakeyFormat
Jika tidak kosong, gunakan parameter.key
Untuk mengenkripsi (HMAC) atau menggunakan defaultkey
Parameteralgo
Setel 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
}
Parameteralgo
Mereka juga mendukung:text.encoder.utf8
,text.decoder.utf8
,text.encoder.gbk
,text.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()
, 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()
, 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()
, 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 OS
Output log host yang berjalan di sistem operasi:
GetOS: darwin/amd64
darwin
Ini adalahMac OS
Nama sistemnya.
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()
, 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, dukunganSQLite
Syntax. ========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================kvdb
、cfg
、log
、profit
、chart
Jangan mengoperasikan tabel-tabel ini.DBExec()
Fungsi ini hanya mendukung real disk.
Dukungan database memori
UntukDBExec
Parameter 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);
}
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()
, 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)
dan di mana punwebsocket
Bisa dibaca atauexchange.Go
、HttpQuery_Go
Perangkat lunak ini dapat digunakan untuk melakukan beberapa hal yang sama.timeout
Jika 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.null
Dengan cara ini, Anda akan mendapatkan hasil yang lebih baik.Event
Untuk tipe pemicu peristiwa. Fungsi ini hanya berlaku untuk disk.
Panggilan pertama dalam kodeEventLoop
Untuk menginisiasi mekanisme pemasangan, Anda harus melakukan pemasangan pertama kali setelah pemasangan kembali.EventLoop
Panggilan, 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.EventLoop
Jika Anda mengambilnya, maka Anda akan kehilangan 500 cache yang lebih baru.EventLoop
Panggilan fungsi tidak mempengaruhi dasar sistemwebsocket
Saya tidak tahu apa yang akan terjadi.exchange.Go
Cache fungsi paralel, misalnya, masih perlu menggunakan metode masing-masing untuk mengambil data.EventLoop
Dan jika Anda tidak dapat memindahkan data yang telah diambil, Anda tidak akan dapat memindahkan data yang telah diambil.EventLoop
Fungsi menghasilkan peristiwa pengembalian.
EventLoop
Fungsi utama adalah untuk menginformasikan layer kebijakan, yang merupakan lapisan bawah sistem yang menerima data jaringan baru.EventLoop
Fungsi hanya perlu melewati semua sumber data saat mengembalikan peristiwa.websocket
"Semoga kita bisa melakukan hal yang sama", katanya.exchange.Go
Objek 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.JavaScript
Dalam 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秒,并发的函数
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 (
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.