void main() {
Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body");
}
Mail
Asynchronous version of the functionMail_Go
The function:
Use andexchange.Go
The function is similar.
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)
}
# 不支持
// 不支持
Please note:
The Ali Cloud server may block some ports, causing e-mail to be unable to be sent. If you need to change the port, you can add the port number directly in the first parameter, for example:smtp.qq.com:587
, the port test is available.
In case of error:unencryped connection
It needs to be modified.Mail
of the functionsmtpServer
The format of the parameters is:ssl://xxx.com:xxx
For example, the QQ e-mailSMTP
This is the most common way to use SSL:ssl://smtp.qq.com:465
Orsmtp://xxx.com:xxx
。
SetErrorFilter(RegEx)
, Filter error logs↑ Parameter value: String type↑
An error log matched by this regular expression will not be uploaded to the log system, and multiple filtering conditions can be invoked (the filtered logs are not written to the database file corresponding to the disk ID in the host directory, preventing frequent error messages from causing database file expansion).
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");
}
Filtering an interface error message:
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()
, which returns the disk process ID.
function main(){
var id = GetPid()
Log(id)
}
def main():
id = GetPid()
Log(id)
void main() {
auto id = GetPid();
Log(id);
}
GetLastError()
, to get the most recent error information. It is generally not needed because the program automatically uploads the error information to the log system.GetLastError()
The function will then clear the error cache, and the next call will not return the error message from the last recording.
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()
, retrieves the interactive command string ((utf-8)); retrieves the command from the policy interactive interface and clears the cache, returns the empty string without the command; returns the command format as按钮名称:参数
If the interactive control has no parameters (e.g. a button control without an input box), the command is the button name.
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);
}
}
The underlying system has a queue structure that records interaction commands whenGetCommand()
When a function is called, it takes the first interaction command in the queue (returns an empty string if there is no interaction command).
Examples of use of interactive controls, policy editor interface setting interactive controls.
The strategy is to design interactive code:
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()
The function returns the policy registration code that was written when it was generated.Meta
The function returns a value of the string type.
Application scenarios, such as strategies that require funding restrictions for different tenants.
Note: When generating the registration codeMeta
This function is only applicable to the physical disk and requires the use of the latest host. If the policy registry code is not set to metadata when generatedGetMeta()
Returns the empty value.
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)
The originalSocket
Access and supporttcp
,udp
,tls
,unix
Protocol. Parameter value isAddress
For the string type,TimeOut
For the type of value, the unit of value is seconds, if overtimeDial(...)
The function returns a null value.
Address
Details of the parameters:
– | Parameters |
---|---|
Set upDial Parameters of the function |
The usual address is:wss://ws.okx.com:8443/ws/v5/public Later| Symbol separation, if there is a string of digits| The characters are in|| Use as a separation symbol.& Character connections. For example, ss5 proxy and compression parameters are set together:Dial("wss://ws.okx.com:8443/ws/v5/public|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv") 。 |
When used with the ws protocol, parameters related to data compression are:compress=参数值 |
compress is a compression mode, compress parameters, optionalgzip_raw 、gzip For example, if the gzip method is not standard gzip, you can use the extension method:gzip_raw I mean, in the separator.| Add settings latercompress=gzip_raw , with& The symbol and the next mode parameter are separated. |
When used with the ws protocol, parameters related to data compression are:mode=参数值 |
mode to mode, optionaldual ,send ,recv There are three types.dual For two-way, send compression data and receive compression data.send This is the most common way to send compressed data.recv To receive the compression data, decompress locally. |
The following parameters are used to set up the socks5 agent:proxy=参数值 |
The proxy is set for the ss5 proxy, and the parameter value format is:socks5://name:pwd@192.168.0.1:1080 ,name is the username of the ss5 server, pwd is the login password of the ss5 server, and 1080 is the port of the ss5 service. |
When using the ws protocol, set the parameters for the underlying auto-reconnect:reconnect=参数值 |
reconnect is set to reconnect,reconnect=true For enabling re-connection. Default not to re-connect when not set. |
When using the ws protocol, set the parameters for the underlying auto-reconnect:interval=参数值 |
interval is the time interval for retesting, in milliseconds,interval=10000 For a 10 second retry interval, the default is not set to 1 second, i.e.interval=1000 。 |
When using the ws protocol, set the parameters for the underlying auto-reconnect:payload=参数值 |
The subscription messages that need to be sent when the payload is reconnected to the ws, for example: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
The function supports the following parameters:
ws.read()
。ws.read(2000)
Specify a delay time of two seconds (~2000 milliseconds).websocket
Effective:
Passing the parameters-1
The function returns immediately regardless of whether there is a message, for example:ws.read(-1)
I'm not sure.
Passing the parameters-2
This means that the function returns immediately, regardless of whether there is no message, but only returns the most recent message, and the message in the buffer is discarded; for example,ws.read(-2)
。read()
The function buffer area describes:
Ws protocol pushes the data if it is in the policyread()
Too long a time interval between function calls can lead to data accumulation. These data are stored in a buffer zone, with a buffer zone data structure of queues, up to a maximum of 2000; after 2000 the latest data is entered into the buffer zone, and the oldest data is deleted.
The scene.read Parameters of the function |
Parameterless | Parameters are: -1 | Parameters are: -2 | Parameters: 2000, units are milliseconds |
---|---|---|---|---|
Buffer zone data is available | Returns the oldest data immediately | Returns the oldest data immediately | Immediately return to the latest data | Returns the oldest data immediately |
No data for buffer zone | Block until data is available | Returns the empty value immediately | Returns the empty value immediately | Wait 2000 milliseconds, no data returns blank, some data returns |
When the ws connection is disconnected or the bottom is reconnected | The read ((() function returns an empty string, i.e.::"",write (()) function returns 0, detected in this case. The close ((() function can be used to close the connection, if the auto-reconnect is set, it does not need to be closed, and the system bottom will automatically reconnect. |
Support for the wss ((WebSocket) protocol Binance's websocket market interface can be accessed at:
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();
}
Access the websocket market interface of 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("退出");
}
The websocket market interface for accessing the tokens:
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()函数");
}
Access the websocket authentication interface of OKX:
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)
, network URL access. == Parameter value: all for string type ==
Please note:
HttpQuery(...)
Function only supportedJavaScript
The language.Python
Language can be usedurllib
In the meantime, I'm going to send you an http request.HttpQuery(...)
It is mainly used to access interfaces that do not require a signature, such as public interfaces such as market information.
An example of an API interface that does not require a signature to access OKX, returning a value ofJSON
The strings.JavaScript
The language strategies can be usedJSON.parse()
Functional analysis is also used.
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);
}
Returns the contents of a URL if the second parameterPostData
For the stringa=1&b=2&c=abc
It's a form.POST
How to submit. Other examplesPUT
It is not possible to change the language.PostData
The parameter is{method:'PUT', data:'a=1&b=2&c=abc'}
。
PostData
The parameters can also beJSON
String of characters.
Cookies
The form of this parameter is:a=10; b=20
, each parameter is decimated;
I'm not going to tell you.Headers
The form of this parameter is:User-Agent: Mobile\nContent-Type: text/html
The parameters are replaced with symbols.\n
I'm not going to tell you.
The second parameterPostData
You can customize methods such as:HttpQuery("http://www.abc.com", {method:'PUT', data:'a=1&b=2&c=abc'})
Please note:HttpQuery
The function sets the timeout, which can be used in{method:'PUT', data:'a=1&b=2&c=abc'}
Joinedtimeout
Attributes (default 60 seconds)
Set the delay by 1 second:HttpQuery("http://www.abc.com", {method:'PUT', data:'a=1&b=2&c=abc', timeout:1000})
DeliveredCookie
String requires a third argument, but notPOST
Please set the second parameter to null. The function returns a fixed string because the URL cannot be simulated.Dummy Data
The interface can be used to send text messages or interact with other API interfaces.
GET
Examples of method calls:HttpQuery("http://www.baidu.com")
。
POST
Examples of method calls:HttpQuery("http://www.163.com", "a=1&b=2&c=abc")
。
Going backHeader
Here are some examples:
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
The function uses the following proxy setting:
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
Asynchronous version of the functionHttpQuery_Go
I'm not sure.
Use andexchange.Go
The functions are similar, e.g. asynchronous access to the exchange's public interface to obtain aggregated market data.
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)
}
# 不支持
// 不支持
Use in retesting systemsHttpQuery(...)
The function:
Can be used in retesting systemsHttpQuery(...)
Send request ((support only)GET
request) to obtain data. Limit retrieval time to 20 different URL visits, andHttpQuery(...)
Access caches data, the same URL the second time it is accessedHttpQuery(...)
The function returns cached data (no more actual network requests).
We can run a service program on a server or a device to respond to a policy program.HttpQuery(...)
The Go language service program used to test the request was as follows:
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)
}
Used for strategy retrospectionHttpQuery(...)
Request to send the function:
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());
}
Supports transcoding of response data to requests, supporting common coding.
SpecifyPostData
Parameters are:{method: "GET",charset:"GB18030"}
The data transfer code (GB18030) can be implemented.
Encode(algo, inputFormat, outputFormat, data, keyFormat, key string)
The function encodes data based on the input parameters. Returns value: String type.
Parametersalgo
The algorithms used for coding are: *raw * (not using algorithms), *sign *, *sign Tx *, *md4 *, *md5 *, *sha256 *, *sha512 *, *sha1 *, *keccak256 *, *sha3.224 *, *sha3.256 *, *sha3.384 *, *sha3.512 *, *sha3.keccak256 *, *sha3.keccak512 *, *sha512.384 *, *sha512.256 *, *sha512.224 *, *ripmd160 *, *blake2b.256 *, *blake2b.512 *, *blake2s.128 *, *blake2s.256 *.data
The data to be processed.inputFormat
/outputFormat
/keyFormat
Parameters supportedraw
,hex
,base64
,string
The code is written in Arabic.
What ifkeyFormat
If it's not empty, use parameters.key
Encrypt (HMAC) or use the defaultkey
The parametersalgo
Set to"sign"
Or"signTx"
When parameters are neededkey
。
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
}
Parametersalgo
It also supports:text.encoder.utf8
,text.decoder.utf8
,text.encoder.gbk
,text.decoder.gbk
, to encode and decode strings.
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()
Returns a nanosecond timestamp. If a millisecond timestamp is required, the following code can be used:
function main() {
var time = UnixNano() / 1000000
Log(_N(time, 0))
}
def main():
time = UnixNano()
Log(time)
void main() {
auto time = UnixNano();
Log(time);
}
Unix()
, returns the second-level timestamp.
function main() {
var t = Unix()
Log(t)
}
def main():
t = Unix()
Log(t)
void main() {
auto t = Unix();
Log(t);
}
GetOS()
In this case, the server will return the information to the host's system.
function main() {
Log("GetOS:", GetOS())
}
def main():
Log("GetOS:", GetOS())
void main() {
Log("GetOS:", GetOS());
}
On the Apple computerMac OS
The output of the host logs running on the operating system is:
GetOS:darwin/amd64
darwin
That is,Mac OS
The name of the system.
MD5(String)
, parameter value: String type.
function main() {
Log("MD5", MD5("hello world"))
}
def main():
Log("MD5", MD5("hello world"))
void main() {
Log("MD5", MD5("hello world"));
}
The log output:
MD5 5eb63bbbe01eeed093cb22bb8f5acdc3
DBExec()
, Parameter value: can be a string, numeric value, boolean value, empty value, etc.; Return value: objects that contain SQLite statement execution results.
The database interface functionDBExec()
The SQLite database can be operated with input parameters. It supports adding, deleting, checking, modifying and so on.SQLite
Syntax. The system reserved tables in the real disk database:kvdb
、cfg
、log
、profit
、chart
Please do not manipulate these tables. Note:DBExec()
The function only supports the real disk.
Support for memory databases
For theDBExec
The parameters of the function, ifsqlThe sentence is:
Initially, it operates in the in-memory database, without writing files, faster. It is suitable for database operations that do not require persistent storage, such as:
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;"));
}
Creating tables
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()
Returns a 32-bit unique UUID, which only applies to the physical 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)
In any casewebsocket
Read orexchange.Go
、HttpQuery_Go
Let the concurrent task be returned after completion.timeout
If set to 0, wait for an event to occur before returning, if greater than 0 is set to wait for an event to occur, less than 0 immediately returns to the most recent event.null
This is the first time I've seen this.Event
Type of event trigger. This function is only applicable to the disk.
First call in codeEventLoop
The mechanism for initializing the monitoring event only works if it starts for the first time after the event is recalled.EventLoop
Calls, which will miss previous events. The underlying system encapsulates a queue structure that caches up to 500 event calls if no timely call is made during program execution.EventLoop
Removing it will lose 500 caches of event calls later.EventLoop
Calling a function does not affect the system's underlyingwebsocket
The caching queue is not affected.exchange.Go
For example, the cache of concurrent functions still requires the use of their respective methods to extract data.EventLoop
The data that's been extracted won't be in the function until the function returns.EventLoop
The function produces a return event.
EventLoop
The primary function is to notify the policy layer, the system underlying the receipt of new network data.EventLoop
When a function returns an event, all it needs to do is traverse all data sources.websocket
It's about connectivity.exchange.Go
The object created attempts to retrieve data.Links to libraries。
In the main functionmain()
In the middle of the call, listen to the events of the main thread.JavaScript
The strategy of writing the language is to make it easy for people to understand it.__Thread()
A thread created by a function can also be called into the thread's executable function to listen to the events of the current thread.
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秒,并发的函数
qq89520There's a problem with whether the C_function is going to try it all over again or only once.
haiwwhai_C ((function, args...) is this default 3s? Can I change the default to put _CDelay ((1000) directly before _C ((function, args...)?
lanchaiyeCluster: If you create 1000 robots simultaneously and without the stress, you can create multiple hosts to decentralize tasks. There are code examples for building clusters. How to build multiple hosts to decentralize tasks
wangyj1Log ((talib.help (('MACD')); can only be used in js, there is no talib.help attribute in python...
cjz140What's the difference between _C (function, args...) and sleep function, I think it all means waiting to try again.
3263243yHow to clear ErrorFilter after SetErrorFilter? without filtering error messages.
qq47898077Is there a way to use a third-party library?
qq47898077If you want to inherit a new class defined by an exchange object, what should the parent class fill in?
ethanwuDo you have any local debug tools?
penglihengWhat about exange.IO?
penglihengWhy is the sell function in gray, is the representation function no longer available?
penglihengWhy is the sell function in gray, is the representation function no longer available?
penglihengJS doesn't speak English, haha, I just want to ask if it supports ES6.
penglihengJS doesn't speak English, haha, I just want to ask if it supports ES6.
Don.How do you write the volume mean?
zjuturtleWhat will be the return if the exchange.Buy ((1000) fails to buy at market price?
The NinjaThe new font is beautiful.
hippoBitmex's testing network ((testnet.bitmex.com) also has an API interface, but currently the exchange can only select Bitmex's main station, and the API documentation address is https://testnet.bitmex.com/app/apiOverview How can you support?
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 Why is it that when you call the functional interface of other exchanges, you write an error message?
allenfrostlineI was wondering what the difference is between realTicker and Ticker? Recently, a strategy for re-writing the utility has appeared simultaneously, but the former API does not seem to mention it.
visionsHello, as a Python developer, what do you think your API documentation is writing about? Some of the field function interfaces look weird, can you write a document like githubpage and readdocs?
allenfrostlineGetAccount: [EAPI:Rate limit exceeded] Want to know how to solve this?
zhjx2314Doesn't support StochRSI, can it be added soon?
yhfggIs the script on your own Ali Cloud server or a botvs cluster?
yhfggWhat version of python do you use?
fkyslyThe interpretation of GetFee should be that it returns a Fee structure string, minus one construct.
zkwapIs there a way to call talib using js?
yhfggRequest the python documentation
wmjbs123Can the background of the code for the strategy editor be black? White prickly eyes, writing code at night, easy nearsightedness
Don.How do I set up the summary in the WeChat push of the robot?
The number is crazy.Is it possible to add a transaction-level field to the order structure?
The little one.GetOrders: Returns all unfinished orders, returns an Order array structure, in China Bitcoin trading ETH, returns only the most recent 10 items, here is a function that returns all unfinished orders in China Bitcoin ETH, meaning that other platforms can return all with GetOrders, only this ghost Chinese Bitcoin returns 10 items,
yhfggThe mathematical functions that are needed for statistical probability theory, where do they come from?
jiebangWhat is the return value of the function $.Cross ((x, y)?
My mother-in-lawThis LogReset clears all logs, and can have a numeric parameter that specifies the number of records to be reserved How does this delete the most recent logs?
edwardgywThe CORRE function in talib doesn't seem to have been ported or missed?
The poor mountain of YangyangIt doesn't seem to have any indicator referencing features!
SmallHow do you translate the k-line time to the present time?
SmallHow to delete numbers in arrays, I'm using records.remove ((records[0])
snakeayuThe most commonly obtained is the hourly K line, how to call the ATR of the daily K line?
snakeayuThe most commonly obtained is the hourly K line, how to call the ATR of the daily K line?
57278863Learn how to get traditional futures priced and ordered, sorry, the roots are thin.
kirinThis is the case with traditional futures trading!
SmallZero, can you write an example of traditional futures trading?
SmallHow to print the holding status when holding multiple blanks at the same time, how to print my [object object], how to get the holding status of multiple and blank blanks, and GetTicker (((), how to get the week, next week, and quarter of the week, the price, the week, next week, and quarter in parentheses I write.
cxjijinIs it possible for a futures exchange to get a market with GetTicker (??), returning a market for that type of contract (??, next week...)?
Selling outWhat indicator can you add to the StochRSI?
momoxCancelOrder ((orderId) Cancel an order based on the order number, return true or false, ask true= The cell was successfully canceled, right?
momox_G(K, V) Can global dictionaries be stored This method saves global variables that can be used to share data between different policies?
flufy3dRising to Popularity
ZeroYou can reset the earnings log with LogProfitReset. The history on the earnings chart before is gone.
xcyCan you directly copy the EA?
sjironmanI feel like this platform is great, great, more interaction in the group.
SmallWhat language is this, is there any material to learn?
jxhbtcData error for a week, can't connect the robot, how to fix it
dyhhuThe index library TA, is it just a calculation of the closing price?
btcrobot hi, world
The Little DreamThe _C function will try again without thinking until it gets a successful result.
The Little DreamPython's talib library needs to be installed.https://www.botvs.com/bbs-topic/669 can be found in this post.
The Little DreamSleep is the number of milliseconds the program does nothing while waiting for the parameter to be set, and _C is the number of milliseconds the function has to re-call the parameter once.
The Little DreamWithout inheritance, JS directly wrapped in the object goes {name: "new object", old_exchange : exchange[0],...... }
The Little DreamLocal editor Remote sync plug-in, basically local editor Remote debugging.
The Little DreamYou can come to the QQ group, and it's easy to discuss.
The Little DreamIn the API documentation, gray means that the function does not have too many open explanations, it shows gray, blue represents more explanations, that's all.
The Little DreamES6 is currently not supported, ^^
The Little DreamCan you come to the group QQ, describe the problem, I'll answer ^^
The Little DreamIt will immediately return an error, and will not order (actually, it is to buy, not enough money!).
zjuturtleFor example, OKCoin, what will be the return if the amount purchased is more than the amount of RMB held?
The Little DreamI'm going to return an order number in OK futures to which exchange.
ZeroIt already supports switching transaction pairs at runtime, and requires downloading the latest host. Supports Bter/Poloniex Detailed API documentation The description of the transaction function bar below ((clear browser cache after refresh if not visible)
The Little DreamQQ me, I'll help you find the problem.
Professional breadwinnersI'm going to set the host's IP?
The Little DreamThis is the underlying link not established The server is not responding. Is the IP address set when the API KEY is requested?
Professional breadwinnersIt's embarrassing... the policies I could run changed to fail in the bit era, and GetAccount can't access 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 BitTorrent error GetAccount: timeout This is a list of all the different ways GetAccount is credited in the database. 2017-05-23 21:08:02 Bit Era Error GetAccount: timeout This is a list of all the different ways GetAccount is credited in the database. 2017-05-23 21:07:40 BitTorrent error GetAccount: timeout This is a list of all the different ways GetAccount is credited in the database. This article is part of our upcoming edition of The New York Times Best Seller list. Is it the IP whitelist problem???
The Little DreamThe exchange's servers did not respond, and the TCP protocol was not established for the three handshakes.
Professional breadwinnersA connection attempt failed because the connected party did not properly respond after a period of time, and the connection attempt failed because the connected party did not properly respond after a period of time.
The Little DreamHello! This is exchange.IO ((
Professional breadwinners A connection attempt failed because the connected party did not properly respond after a period of time,
Professional breadwinnersBitcoin Age is not supported?
The Little DreamThis is a list of all the different ways Dn-filebox.qbox.me/a709b30c6cc0a3565234b9e0c99b073f7ba8b454.png is credited in the database. I'm sure it will be okay.
The NinjaFor example, I want to do a full-currency transaction on poloniex, but there are only a few currencies supported by BOTvs, and exchange.IO doesn't seem to support Pnet.
The Little DreamYou can call this exchange.IO.
The NinjaWhat about the API that needs to verify the account?
The Little DreamIf an API that does not require account verification can be used with httpQuery (see BotVS documentation for more details), the actual transaction API needs access.
The Little DreamYou can use the HttpQuery API to transmit parameters: https://www.okcoin.com/api/v1/future_estimated_price.do?symbol=btc_usd, that's it. For exchange APIs that don't require verification of accounts, use the HttpQuery function directly on the platform. This post was originally published on the website: https://www.botvs.com/bbs-topic/850
visionsThank you very much, I hope you have a good API documentation.
The Little DreamWhere did you see the realTicker API?
The Little DreamThis is a list of all the different ways Fe1a6f5563ed43a5357f858ecf8a50239619228e.png is credited in the database. The API documentation is in JavaScript language. The python version is described in the posts at the top of the plugin page.
ZeroHi, thanks for the suggestion, the API documentation is currently being rebuilt.
The Little DreamHello~ shows that the frequency of access is beyond the limit. This is a list of all the different ways Dn-filebox.qbox.me is credited in the database. Is the Sleep function used in the policy? This 1000 is to allow the program to pause one second per round, which can be set by itself, the purpose is to control the frequency of access to the API, because some exchanges set maximum access limits, a certain amount of time beyond a certain number of visits will deny access, block IP addresses.
The Little Dreamhttps://dn-filebox.qbox.me/c29ab7fc279e1b758355f137907cf52dc8257df6.png I personally wrote that the STOCHRSI indicator, which has been compared to OK, is consistent that the speed is a bit slow and needs to be optimized, but is available for now.
ZeroYou can choose to retest on the server provided by botvs or retest on the server hosted by your host, version 2.7.5
The Little DreamThis is the first time I've seen this post.
The Little DreamNow you can configure your own background style.
The Little DreamThe python documentation is being written.
The Little DreamTalib library support is available.
hzzgood48 https://www.botvs.com/bbs-topic/276
The Little DreamIt seems that there is an example in Strategy Square, https://www.botvs.com/strategy/15098
ZeroAccess the AveragePrice attribute of the Order, which the exchange supports, and the one that does not support the attribute will always be 0.
yhfggHow does a third-party source cite?
ZeroIf mathjs is not satisfied, it can only look for a third-party library copy-import policy. To speed up compilation, the system only has a small number of libraries built in.
The Little DreamI'm not polite, there are problems in the group can M me - I'm basically online.
jiebangThank you.
The Little DreamYou can look at the annotated version of the digital currency trading library code analysis, and there's an annotation for the $.Cross function.
ZeroYou can't delete the latest, you can just keep the latest few posts... delete all the old ones before.
kirinTo get each holding using position[i], position is an array.
The Ninja exchange.GetRecords(PERIOD_D1);
kirinMy traditional futures are always the "GetAccount: not login", "password not entered, login not possible"
ZeroThe default is week, which requires the specified SetContractType first.
ZeroSo, this is the return value of the cancellation order that the exchange returned, but the actual cancellation was not cancelled, depending on how it was handled inside the exchange.
momox 3q
ZeroNot for a while, but separated.
xuanxuanOf course not, that's exclusive to MT4.
ZeroJavascript resources are everywhere on the web.
Selling outIs your problem solved?
ZeroMost of the time, the input data can be directly records or an array of pure prices.