시스템의 현재 버전 번호를 반환합니다.
현재 시스템 버전 번호3.6
...
문자열
버전
function main() {
Log("version:", Version())
}
def main():
Log("version:", Version())
void main() {
Log("version:", Version());
}
시스템 버전 번호는 도커의 프로그램의 버전 번호입니다.
수면 기능, 일정 기간 동안 프로그램을 멈추게 만드는
잠자리 (밀리초)
이millisecond
이 매개 변수는 수면 기간과 밀리 초수를 설정하는 데 사용됩니다.
밀리초
사실
번호
function main() {
Sleep(1000 * 10) // Wait for 10 seconds
Log("Waited for 10 seconds")
}
def main():
Sleep(1000 * 10)
Log("Waited for 10 seconds")
void main() {
Sleep(1000 * 10);
Log("Waited for 10 seconds");
}
예를 들어,Sleep(1000)
기능, 프로그램은 1 초 동안 잠자리에있을 것입니다. 그것은 1 밀리 초 이하의 잠자리 시간, 예를 들어 설정Sleep(0.1)
최소 매개 변수를 지원합니다.0.000001
즉, 1나노초가1e-6
밀리 초입니다.
전략 작성에 있어서Python
언어,Sleep(millisecond)
이 기능은 투표 간격, 대기 시간 작업에 사용되어야 합니다.time.sleep(second)
기능Python
's 'time
도서관입니다.time.sleep(second)
전략의 함수는 전략 프로그램이 백테스팅을 할 때 (백테스팅 시스템의 시간 계열을 건너뛰지 않고) 실제로 일정 기간 동안 기다리게 합니다. 따라서 전략이 매우 느리게 백테스트를 하게 됩니다.
전략의 실행 환경이 백테스팅 시스템인지 여부를 결정합니다.
전략은 실제 값을 반환합니다. 예를 들어:true
백테스팅 시스템 환경에서 실행될 때 전략은 잘못된 값을 반환합니다. 예를 들어:false
실시간 거래 환경에서 실행될 때
bool
가상 (virtual)
function main() {
if (IsVirtual()) {
Log("The current backtest system environment.")
} else {
Log("The current live trading environment.")
}
}
def main():
if IsVirtual():
Log("The current backtest system environment.")
else:
Log("The current live trading environment.")
void main() {
if (IsVirtual()) {
Log("The current backtest system environment.");
} else {
Log("The current live trading environment.");
}
}
현재 실행 환경이 백테스팅 시스템인지 결정합니다. 백테스팅과 실시간 거래의 차이에 호환되도록 사용됩니다.
메일 보내
성공적인 이메일 전달은 실제 값을 반환합니다. 예를 들어,true
, 그리고 실패한 배달은 잘못된 값을 반환합니다. 예를 들어,false
...
bool
메일 ((smtp서버, smtp사용자명, smtp신호, mailTo, 제목, 본)
사용된SMTP
이메일 발신자의 서비스 주소
smtp서버
사실
문자열
이메일 발신자의 이메일 주소를 지정하는 데 사용됩니다.
smtp사용자명
사실
문자열
의SMTP
메일 발신자의 메일박스의 비밀번호.
smtpPassword
사실
문자열
이메일 수신자의 이메일 주소를 지정하는 데 사용됩니다.
메일To
사실
문자열
이메일 제목
제목
사실
문자열
이메일 본체
몸
사실
문자열
function main(){
Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
}
def main():
Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
void main() {
Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body");
}
이smtpPassword
매개 변수SMTP
메일박스 비밀번호가 아니라
설정할 때smtpServer
매개 변수, 당신이 포트를 변경해야 하는 경우, 당신은 매개 변수에 직접 포트 번호를 추가 할 수 있습니다smtpServer
예를 들어: QQ 메일smtp.qq.com:587
, 테스트를 위해 사용할 수 있습니다.
오류가 보고되면:unencryped connection
, 당신은 변경해야 합니다smtpServer
의Mail
함수입니다. 매개 변수 형식은:ssl://xxx.com:xxx
예를 들어,ssl
방법SMTP
QQ 메일:ssl://smtp.qq.com:465
또는smtp://xxx.com:xxx
...
백테스팅 시스템에서는 작동하지 않습니다.
{@fun/Global/Mail_Go 메일_Go}
비동기 버전Mail
function.
이Mail_Go
함수는 동시 객체를 즉시 반환하고,wait
메일 배달의 결과를 얻기 위해 동시 객체의 메서드를 사용한다.true
, 그리고 실패한 배달은 잘못된 값을 반환합니다. 예를 들어,false
...
물체
Mail_Go ((smtp서버, smtp사용자명, smtp 비밀번호, mailTo, 제목, 본체)
이 용어는SMTP
이메일 발신자의 서비스 주소
smtp서버
사실
문자열
이메일 발신자의 이메일 주소를 지정하는 데 사용됩니다.
smtp사용자명
사실
문자열
의SMTP
메일 발신자의 메일박스의 비밀번호.
smtpPassword
사실
문자열
이메일 수신자의 이메일 주소를 지정하는 데 사용됩니다.
메일To
사실
문자열
이메일 제목
제목
사실
문자열
이메일 본체
몸
사실
문자열
function main() {
var r1 = Mail_Go("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
var r2 = Mail_Go("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
var ret1 = r1.wait()
var ret2 = r2.wait()
Log("ret1:", ret1)
Log("ret2:", ret2)
}
# Not supported.
// Not supported.
백테스팅 시스템에서는 작동하지 않습니다.
{@fun/Global/Mail Mail}
필터 오류 로그
SetErrorFilter (필터 설정)
정규 표현식 문자열 필터 사실 문자열
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");
}
일반적인 오류를 필터링합니다.
function main() {
// A random query for a non-existent order with an id of 123, allowing the interface to report an error deliberately
var order = exchange.GetOrder("123")
Log(order)
// Filter http502 errors, GetOrder interface errors, after setting the error filter, the second call to GetOrder will no longer report errors
SetErrorFilter("502:|GetOrder")
order = exchange.GetOrder("123")
Log(order)
}
def main():
order = exchange.GetOrder("123")
Log(order)
SetErrorFilter("502:|GetOrder")
order = exchange.GetOrder("123")
Log(order)
void main() {
TId orderId;
Order order = exchange.GetOrder(orderId);
Log(order);
SetErrorFilter("502:|GetOrder");
order = exchange.GetOrder(orderId);
Log(order);
}
인터페이스 오류 메시지를 필터링합니다.
이 정규 표현식과 일치하는 오류 로그는 로그 시스템에 업로드되지 않습니다. 여러 필터 조건을 설정하기 위해 여러 번 호출할 수 있습니다. 여러 번 설정된 정규 표현식은 축적되어 동시에 유효합니다. 오류 로그를 필터하는 데 사용되는 정규 표현식을 다시 설정하기 위해 빈 문자열을 설정할 수 있습니다:SetErrorFilter("")
. 필터 로그는 더 이상 docker 디렉토리의 라이브 거래 ID에 대응하는 데이터베이스 파일에 기록되지 않습니다. 빈번한 오류 보고가 데이터베이스 파일을 부풀어 올리는 것을 방지하기 위해.
라이브 거래 프로세스 아이디를 얻으십시오.
라이브 거래 프로세스 ID를 반환합니다. 문자열
GetPid ((()
function main(){
var id = GetPid()
Log(id)
}
def main():
id = GetPid()
Log(id)
void main() {
auto id = GetPid();
Log(id);
}
마지막 오류 메시지가 왔어
마지막 오류 메시지 문자열
GETLastError()
function main(){
// Because the order number 123 does not exist, so there will be an error.
exchange.GetOrder("123")
var error = GetLastError()
Log(error)
}
def main():
exchange.GetOrder("123")
error = GetLastError()
Log(error)
void main() {
// Order ID type: TId, so you can't pass in a string, we place an order that doesn't meet the exchange specification to trigger
exchange.GetOrder(exchange.Buy(1, 1));
auto error = GetLastError();
Log(error);
}
백테스팅 시스템에서는 작동하지 않습니다.
전략 상호작용 명령을 받습니다.
반환 명령어의 형식은ControlName:Data
. ControlName
제어물의 이름이고,Data
컨트롤에 입력된 데이터입니다. 인터랙티브 컨트롤에 입력 상자, 드롭다운 상자 및 다른 구성 요소가 없다면 (예를 들어 입력 상자 없는 버튼 컨트롤) 반환 명령어 형식은ControlName
, 컨트롤 이름만 반환합니다.
문자열
GetCommand (() 를 받아보세요
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);
}
}
상호 작용 명령을 감지하고Log
감지될 때 상호작용 명령을 출력하는 기능
function main() {
while (true) {
LogStatus(_D())
var cmd = GetCommand()
if (cmd) {
Log("cmd:", cmd)
var arr = cmd.split(":")
if (arr[0] == "buy") {
Log("Buy, the control without number")
} else if (arr[0] == "sell") {
Log("Sell, the control with the number of:", arr[1])
} else {
Log("Other controls trigger:", arr)
}
}
Sleep(1000)
}
}
def main():
while True:
LogStatus(_D())
cmd = GetCommand()
if cmd:
Log("cmd:", cmd)
arr = cmd.split(":")
if arr[0] == "buy":
Log("Buy, the control without number")
elif arr[0] == "sell":
Log("Sell, the control with the number of:", arr[1])
else:
Log("Other controls trigger:", arr)
Sleep(1000)
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
void split(const string& s,vector<string>& sv,const char flag = ' ') {
sv.clear();
istringstream iss(s);
string temp;
while (getline(iss, temp, flag)) {
sv.push_back(temp);
}
return;
}
void main() {
while(true) {
LogStatus(_D());
auto cmd = GetCommand();
if (cmd != "") {
vector<string> arr;
split(cmd, arr, ':');
if(arr[0] == "buy") {
Log("Buy, the control without number");
} else if (arr[0] == "sell") {
Log("Sell, the control with the number of:", arr[1]);
} else {
Log("Other controls trigger:", arr);
}
}
Sleep(1000);
}
}
예를 들어, 전략 인터랙티브 컨트롤은 입력 상자가 없는 컨트롤을 추가합니다. 인터랙티브 컨트롤의 이름은:buy
, 제어 설명 정보는:buy
, 버튼 컨트롤입니다. 입력 상자를 가진 컨트롤을 추가하여 계속합니다. 상호 작용 컨트롤은 이름:sell
그리고 제어 설명 메시지는:sell
, 이것은 버튼과 입력 상자의 조합을 가진 인터랙티브 컨트롤입니다. 인터랙션 코드는 전략에서 다른 인터랙션 컨트롤에 대응하도록 설계되었습니다:
백테스팅 시스템에서는 작동하지 않습니다.
전략 등록 코드를 생성 할 때 메타의 값을 작성하십시오.
Meta
데이터
문자열
GetMeta (메타)
function main() {
// The maximum asset value of the denominated currency allowed by the strategy.
var maxBaseCurrency = null
// Get the metadata when creating the registration code.
var level = GetMeta()
// Detecting the conditions corresponding to Meta.
if (level == "level1") {
// -1 for unrestricted
maxBaseCurrency = -1
} else if (level == "level2") {
maxBaseCurrency = 10
} else if (level == "level3") {
maxBaseCurrency = 1
} else {
maxBaseCurrency = 0.5
}
while(1) {
Sleep(1000)
var ticker = exchange.GetTicker()
// Detect asset values
var acc = exchange.GetAccount()
if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks) {
// Stop executing strategy trading logic
LogStatus(_D(), "level:", level, "Positions exceeding the usage limit of the registration code will no longer execute the strategy trading logic!")
continue
}
// Other trading logic
// Normal output of status bar information
LogStatus(_D(), "level:", level, "The strategy is working properly! ticker data: \n", ticker)
}
}
def main():
maxBaseCurrency = null
level = GetMeta()
if level == "level1":
maxBaseCurrency = -1
elif level == "level2":
maxBaseCurrency = 10
elif level == "level3":
maxBaseCurrency = 1
else:
maxBaseCurrency = 0.5
while True:
Sleep(1000)
ticker = exchange.GetTicker()
acc = exchange.GetAccount()
if maxBaseCurrency != -1 and maxBaseCurrency < acc["Stocks"] + acc["FrozenStocks"]:
LogStatus(_D(), "level:", level, "Positions exceeding the usage limit of the registration code will no longer execute the strategy trading logic!")
continue
# Other trading logic
# Normal output of status bar information
LogStatus(_D(), "level:", level, "The strategy is working properly! ticker data: \n", ticker)
void main() {
auto maxBaseCurrency = 0.0;
auto level = GetMeta();
if (level == "level1") {
maxBaseCurrency = -1;
} else if (level == "level2") {
maxBaseCurrency = 10;
} else if (level == "level3") {
maxBaseCurrency = 1;
} else {
maxBaseCurrency = 0.5;
}
while(1) {
Sleep(1000);
auto ticker = exchange.GetTicker();
auto acc = exchange.GetAccount();
if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks) {
// Stop execution strategy trading logic.
LogStatus(_D(), "level:", level, "Positions exceeding the usage limit of the registration code will no longer execute the strategy trading logic!");
continue;
}
// Other trading logic
// Normal output of status bar information
LogStatus(_D(), "level:", level, "The strategy is working properly! ticker data: \n", ticker);
}
}
응용 시나리오 예: 사용Meta
전략에 의해 운영되는 자산의 양을 제한하는 것.
적용 시나리오: 다른 전략 임대자에 대한 자본 제한을 할 필요가 있습니다.Meta
등록 코드를 생성 할 때 설정된 값은 190 문자를 초과 할 수 없으며GetMeta()
이 기능은 라이브 거래만 지원합니다.Meta
(주) 전략 등록 코드를 생성 할 때 설정됩니다.GetMeta()
함수는 null을 반환합니다. 백테스팅 시스템에서는 작동하지 않습니다.
원시적인Socket
접근, 지원tcp
, udp
, tls
, unix
프로토콜 4개의 일반적인 통신 프로토콜을 지원합니다.mqtt
, nats
, amqp
, kafka
데이터베이스 연결을 지원합니다:sqlite3
, mysql
, postgres
, clickhouse
.
이Dial()
함수는 시간이 끝나면 null을 반환합니다. 정상적인 호출은 세 가지 메소드를 가진 연결 객체를 반환합니다.read
, write
그리고close
.read
이 방법은 데이터를 읽기 위해 사용됩니다.write
이 방법은 데이터를 전송하고close
이 방법은 연결을 닫는 데 사용됩니다.
의read
이 방법은 다음과 같은 매개 변수를 지원합니다.
ws.read()
.ws.read(2000)
2초 (2000밀리초) 의 타임아웃을 지정합니다.-1
함수는 메시지가 존재하거나 없더라도 즉시 반환하는 것을 의미합니다. 예를 들어:ws.read(-1)
...
매개 변수를 전달-2
함수는 메시지와 함께 또는 메시지가 없이 즉시 반환하지만, 최신 메시지가 반환되고 버퍼된 메시지가 폐기된다는 것을 의미합니다. 예를 들어,ws.read(-2)
.read()
함수 버퍼 설명:
웹소켓 프로토콜에 의해 밀어 입력 데이터는 전략 사이의 시간 간격이read()
함수 호출이 너무 길다. 이 데이터는 버퍼에 저장되며, 최대 2000의 대기열의 데이터 구조를 가지고 있습니다. 2000이 초과되면 가장 새로운 데이터가 버퍼에 입력되고 가장 오래된 데이터가 삭제됩니다.
시나리오 | 매개 변수가 없습니다. | 파라미터: -1 | 파라미터: -2 | 매개 변수: 2000 밀리 초 |
---|---|---|---|---|
이미 버퍼에 있는 데이터 | 가장 오래된 데이터를 즉시 반환 | 가장 오래된 데이터를 즉시 반환 | 최신 데이터를 즉시 반환 | 가장 오래된 데이터를 즉시 반환 |
버퍼에 데이터가 없습니다. | 데이터로 차단된 경우 반환 | 즉시 null을 반환합니다 | 즉시 null을 반환합니다 | 2000ms를 기다립니다. 데이터가 없다면 null을 반환합니다. 데이터가 있다면 null을 반환합니다. |
웹소켓 연결이 연결이 끊어지고 또는 기본에 의해 다시 연결 | read() 함수는 빈 문자열을 반환합니다. 즉: |
물체
전화번호 (주소) 전화 (주소, 시간)
주소 요청 주소 사실 문자열 타임아웃 초, 타임아웃 거짓 번호
function main(){
// Dial supports tcp://,udp://,tls://,unix://protocol, you can add a parameter to specify the number of seconds for the timeout
var client = Dial("tls://www.baidu.com:443")
if (client) {
// write can be followed by a numeric parameter to specify the timeout, write returns the number of bytes successfully sent
client.write("GET / HTTP/1.1\nConnection: Closed\n\n")
while (true) {
// read can be followed by a numeric parameter specifying the timeout in milliseconds. Returning null indicates an error or timeout or that the socket has been closed
var buf = client.read()
if (!buf) {
break
}
Log(buf)
}
client.close()
}
}
def main():
client = Dial("tls://www.baidu.com:443")
if client:
client.write("GET / HTTP/1.1\nConnection: Closed\n\n")
while True:
buf = client.read()
if not buf:
break
Log(buf)
client.close()
void main() {
auto client = Dial("tls://www.baidu.com:443");
if(client.Valid) {
client.write("GET / HTTP/1.1\nConnection: Closed\n\n");
while(true) {
auto buf = client.read();
if(buf == "") {
break;
}
Log(buf);
}
client.close();
}
}
다이얼 함수 호출 예제:
function main() {
LogStatus("Connecting...")
// Accessing WebSocket interface of Binance
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
if (!client) {
Log("Connection failed, program exited")
return
}
while (true) {
// read returns only the data retrieved after the read call
var buf = client.read()
if (!buf) {
break
}
var table = {
type: 'table',
title: 'Ticker Chart',
cols: ['Currency', 'Highest', 'Lowest', 'Buy 1', 'Sell 1', 'Last traded price', 'Volume', 'Update time'],
rows: []
}
var obj = JSON.parse(buf)
_.each(obj, function(ticker) {
table.rows.push([ticker.s, ticker.h, ticker.l, ticker.b, ticker.a, ticker.c, ticker.q, _D(ticker.E)])
})
LogStatus('`' + JSON.stringify(table) + '`')
}
client.close()
}
import json
def main():
LogStatus("Connecting...")
client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
if not client:
Log("Connection failed, program exited")
return
while True:
buf = client.read()
if not buf:
break
table = {
"type" : "table",
"title" : "Ticker Chart",
"cols" : ['Currency', 'Highest', 'Lowest', 'Buy 1', 'Sell 1', 'Last traded price', 'Volume', 'Update time'],
"rows" : []
}
obj = json.loads(buf)
for i in range(len(obj)):
table["rows"].append([obj[i]["s"], obj[i]["h"], obj[i]["l"], obj[i]["b"], obj[i]["a"], obj[i]["c"], obj[i]["q"], _D(int(obj[i]["E"]))])
LogStatus('`' + json.dumps(table) + '`')
client.close()
void main() {
LogStatus("Connecting...");
auto client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
if(!client.Valid) {
Log("Connection failed, program exited");
return;
}
while(true) {
auto buf = client.read();
if(buf == "") {
break;
}
json table = R"({
"type" : "table",
"title" : "Ticker Chart",
"cols" : ["Currency", "Highest", "Lowest", "Buy 1", "Sell 1", "Last traded price", "Volume", "Update time"],
"rows" : []
})"_json;
json obj = json::parse(buf);
for(auto& ele : obj.items()) {
table["rows"].push_back({ele.value()["s"], ele.value()["h"], ele.value()["l"], ele.value()["b"], ele.value()["a"], ele.value()["c"],
ele.value()["q"], _D(ele.value()["E"])});
}
LogStatus("`" + table.dump() + "`");
}
client.close();
}
바이낸스의 웹소켓 틱어 인터페이스에 액세스하려면:
var ws = null
function main(){
var param = {
"op": "subscribe",
"args": [{
"channel": "tickers",
"instId": "BTC-USDT"
}]
}
// When calling Dial function, specify reconnect=true to set reconnection mode and payload to be the message sent when reconnecting. When the WebSocket connection is disconnected, it will reconnect and send messages automatically.
ws = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload="+ JSON.stringify(param))
if(ws){
var pingCyc = 1000 * 20
var lastPingTime = new Date().getTime()
while(true){
var nowTime = new Date().getTime()
var ret = ws.read()
Log("ret:", ret)
if(nowTime - lastPingTime > pingCyc){
var retPing = ws.write("ping")
lastPingTime = nowTime
Log("Send : ping", "#FF0000")
}
LogStatus("Current time:", _D())
Sleep(1000)
}
}
}
function onexit() {
ws.close()
Log("exit")
}
import json
import time
ws = None
def main():
global ws
param = {
"op": "subscribe",
"args": [{
"channel": "tickers",
"instId": "BTC-USDT"
}]
}
ws = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload=" + json.dumps(param))
if ws:
pingCyc = 1000 * 20
lastPingTime = time.time() * 1000
while True:
nowTime = time.time() * 1000
ret = ws.read()
Log("ret:", ret)
if nowTime - lastPingTime > pingCyc:
retPing = ws.write("ping")
lastPingTime = nowTime
Log("Send: ping", "#FF0000")
LogStatus("Current time:", _D())
Sleep(1000)
def onexit():
ws.close()
Log("exit")
auto objWS = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true");
void main() {
json param = R"({
"op": "subscribe",
"args": [{
"channel": "tickers",
"instId": "BTC-USDT"
}]
})"_json;
objWS.write(param.dump());
if(objWS.Valid) {
uint64_t pingCyc = 1000 * 20;
uint64_t lastPingTime = Unix() * 1000;
while(true) {
uint64_t nowTime = Unix() * 1000;
auto ret = objWS.read();
Log("ret:", ret);
if(nowTime - lastPingTime > pingCyc) {
auto retPing = objWS.write("ping");
lastPingTime = nowTime;
Log("Send: ping", "#FF0000");
}
LogStatus("Current time:", _D());
Sleep(1000);
}
}
}
void onexit() {
objWS.close();
Log("exit");
}
OKX
var ws = null
function main(){
var param = {"sub": "market.btcusdt.detail", "id": "id1"}
ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload="+ JSON.stringify(param))
if(ws){
while(1){
var ret = ws.read()
Log("ret:", ret)
// Respond to heartbeat packet operations
try {
var jsonRet = JSON.parse(ret)
if(typeof(jsonRet.ping) == "number") {
var strPong = JSON.stringify({"pong" : jsonRet.ping})
ws.write(strPong)
Log("Respond to ping, send pong:", strPong, "#FF0000")
}
} catch(e) {
Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
}
LogStatus("Current time:", _D())
Sleep(1000)
}
}
}
function onexit() {
ws.close()
Log("Execute the ws.close() function")
}
import json
ws = None
def main():
global ws
param = {"sub" : "market.btcusdt.detail", "id" : "id1"}
ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + json.dumps(param))
if ws:
while True:
ret = ws.read()
Log("ret:", ret)
# Respond to heartbeat packet operations
try:
jsonRet = json.loads(ret)
if "ping" in jsonRet and type(jsonRet["ping"]) == int:
strPong = json.dumps({"pong" : jsonRet["ping"]})
ws.write(strPong)
Log("Respond to ping, send pong:", strPong, "#FF0000")
except Exception as e:
Log("e:", e)
LogStatus("Current time:", _D())
Sleep(1000)
def onexit():
ws.close()
Log("Execute the ws.close() function")
using namespace std;
void main() {
json param = R"({"sub" : "market.btcusdt.detail", "id" : "id1"})"_json;
auto ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + param.dump());
if(ws.Valid) {
while(true) {
auto ret = ws.read();
Log("ret:", ret);
// Respond to heartbeat packet operations
try
{
auto jsonRet = json::parse(ret);
if(jsonRet["ping"].is_number()) {
json pong = R"({"pong" : 0})"_json;
pong["pong"] = jsonRet["ping"];
auto strPong = pong.dump();
ws.write(strPong);
Log("Respond to ping, send pong:", strPong, "#FF0000");
}
} catch(exception &e)
{
Log("e:", e.what());
}
LogStatus("Current time:", _D());
Sleep(1000);
}
}
}
void onexit() {
// ws.close();
Log("Execute the ws.close() function");
}
Huobi의 웹소켓 틱어 인터페이스에 액세스:
function getLogin(pAccessKey, pSecretKey, pPassphrase) {
// Signature function for login
var ts = (new Date().getTime() / 1000).toString()
var login = {
"op": "login",
"args":[{
"apiKey" : pAccessKey,
"passphrase" : pPassphrase,
"timestamp" : ts,
"sign" : exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey) // exchange.HMAC has been deprecated and is temporarily supported. Please use the latest exchange.Encode function instead.
}]
}
return login
}
var client_private = null
function main() {
// Because the read function uses a timeout setting, filtering the timeout reports errors that would otherwise be output with redundant errors
SetErrorFilter("timeout")
// Position channel subscription information
var posSubscribe = {
"op": "subscribe",
"args": [{
"channel": "positions",
"instType": "ANY"
}]
}
var accessKey = "xxx"
var secretKey = "xxx"
var passphrase = "xxx"
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
client_private.write(JSON.stringify(getLogin(accessKey, secretKey, passphrase)))
Sleep(3000) // When logging in, you cannot subscribe to private channels immediately, you need to wait for server response
client_private.write(JSON.stringify(posSubscribe))
if (client_private) {
var lastPingTS = new Date().getTime()
while (true) {
var buf = client_private.read(-1)
if (buf) {
Log(buf)
}
// Detect disconnection, reconnect
if (buf == "" && client_private.write(JSON.stringify(posSubscribe)) == 0) {
Log("Disconnection detected, close connection, reconnect")
client_private.close()
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
client_private.write(JSON.stringify(getLogin(accessKey, secretKey, passphrase)))
Sleep(3000)
client_private.write(JSON.stringify(posSubscribe))
}
// Send heartbeat packets
var nowPingTS = new Date().getTime()
if (nowPingTS - lastPingTS > 10 * 1000) {
client_private.write("ping")
lastPingTS = nowPingTS
}
}
}
}
function onexit() {
var ret = client_private.close()
Log("Close the connection!", ret)
}
import json
import time
def getLogin(pAccessKey, pSecretKey, pPassphrase):
ts = str(time.time())
login = {
"op": "login",
"args":[{
"apiKey" : pAccessKey,
"passphrase" : pPassphrase,
"timestamp" : ts,
"sign" : exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey)
}]
}
return login
client_private = None
def main():
global client_private
SetErrorFilter("timeout")
posSubscribe = {
"op": "subscribe",
"args": [{
"channel": "positions",
"instType": "ANY"
}]
}
accessKey = "xxx"
secretKey = "xxx"
passphrase = "xxx"
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
client_private.write(json.dumps(getLogin(accessKey, secretKey, passphrase)))
Sleep(3000)
client_private.write(json.dumps(posSubscribe))
if client_private:
lastPingTS = time.time() * 1000
while True:
buf = client_private.read(-1)
if buf:
Log(buf)
if buf == "" and client_private.write(json.dumps(posSubscribe)) == 0:
Log("Disconnection detected, close connection, reconnect")
ret = client_private.close()
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
client_private.write(json.dumps(getLogin(accessKey, secretKey, passphrase)))
Sleep(3000)
client_private.write(json.dumps(posSubscribe))
nowPingTS = time.time() * 1000
if nowPingTS - lastPingTS > 10 * 1000:
client_private.write("ping")
lastPingTS = nowPingTS
def onexit():
ret = client_private.close()
Log("Close the connection!", ret)
auto client_private = Dial("wss://ws.okx.com:8443/ws/v5/private");
json getLogin(string pAccessKey, string pSecretKey, string pPassphrase) {
auto ts = std::to_string(Unix());
json login = R"({
"op": "login",
"args": [{
"apiKey": "",
"passphrase": "",
"timestamp": "",
"sign": ""
}]
})"_json;
login["args"][0]["apiKey"] = pAccessKey;
login["args"][0]["passphrase"] = pPassphrase;
login["args"][0]["timestamp"] = ts;
login["args"][0]["sign"] = exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey);
return login;
}
void main() {
SetErrorFilter("timeout");
json posSubscribe = R"({
"op": "subscribe",
"args": [{
"channel": "positions",
"instType": "ANY"
}]
})"_json;
auto accessKey = "xxx";
auto secretKey = "xxx";
auto passphrase = "xxx";
client_private.write(getLogin(accessKey, secretKey, passphrase).dump());
Sleep(3000);
client_private.write(posSubscribe.dump());
if (client_private.Valid) {
uint64_t lastPingTS = Unix() * 1000;
while (true) {
auto buf = client_private.read(-1);
if (buf != "") {
Log(buf);
}
if (buf == "") {
if (client_private.write(posSubscribe.dump()) == 0) {
Log("Disconnection detected, close connection, reconnect");
client_private.close();
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private");
client_private.write(getLogin(accessKey, secretKey, passphrase).dump());
Sleep(3000);
client_private.write(posSubscribe.dump());
}
}
uint64_t nowPingTS = Unix() * 1000;
if (nowPingTS - lastPingTS > 10 * 1000) {
client_private.write("ping");
lastPingTS = nowPingTS;
}
}
}
}
void onexit() {
client_private.close();
Log("exit");
}
OKX
var client = null
function main() {
// client = Dial("sqlite3://:memory:") // Using an in-memory database
client = Dial("sqlite3://test1.db") // Open/connect to the database file in the docker's directory
// record handle
var sqlite3Handle = client.fd()
Log("sqlite3Handle:", sqlite3Handle)
// Querying tables in the database
var ret = client.exec("SELECT name FROM sqlite_master WHERE type='table'")
Log(ret)
}
function onexit() {
Log("Execute client.close()")
client.close()
}
// Not supported
// Not supported
데이터베이스에 연결할 때 다이얼 함수가 반환하는 연결 객체는 두 가지 고유한 메소드 함수를 가지고 있습니다.
exec(sqlString)
: SQL 명령어를 실행하는 데 사용DBExec()
function.fd()
:fd()
함수는 다른 스레드가 다시 연결하기 위해 사용할 수 있는 핸들을 반환합니다. (디얼에 의해 생성된 객체가 실행에 의해 이미 닫혀있더라도)close()
연결을 닫는 기능)Dial()
예를 들어,Dial(handle)
재사용 연결
다음은 다이얼 기능의 예를sqlite3
database.세부 사항address
매개 변수,|
정상 주소 다음의 기호:wss://ws.okx.com:8443/ws/v5/public
만약|
매개 변수 문자열의 문자, 그리고||
분기 기호로 사용됩니다. 그 다음 부분은 몇 가지 함수 매개 변수 설정입니다.&
예를 들어,ss5
프록시와 압축 매개 변수는 다음과 같이 함께 설정될 수 있습니다.Dial("wss://ws.okx.com:8443/ws/v5/public|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv")
다이얼 함수의 주소 매개 변수로 지원되는 함수 | 매개 변수 설명 |
---|---|
웹소켓 프로토콜 데이터 압축과 관련된 매개 변수: compress=parameter value | 압축은 압축 메소드, 압축 매개 변수 옵션은: gzip_raw, gzip, 등입니다. gzip 메소드가 표준 gzip이 아닌 경우 확장 메소드를 사용할 수 있습니다: gzip_raw |
웹소켓 프로토콜 데이터 압축과 관련된 매개 변수: mode=parameter value | 모드는 압축 모드, 모드 매개 변수는 듀얼이 될 수 있습니다. 전송, recv. 듀얼은 양방향 압축, 압축 데이터를 전송, 압축 데이터를 수신합니다. 전송은 압축 데이터를 전송합니다. recv는 압축 데이터를 수신합니다. 지역 압축 해제. |
웹소켓 프로토콜은 기본 자동 재연결 관련 매개 변수를 설정합니다: reconnect=parameter value | reconnect는 reconnect를 설정할 것인지, reconnect=true는 reconnect를 활성화할 것인지입니다. 이 매개 변수가 설정되지 않은 경우 기본값은 reconnect가 없습니다. |
웹소켓 프로토콜은 기본 자동 재연결 관련 매개 변수를 설정합니다: interval=parameter value | interval는 재시험 간격입니다. 밀리초로, interval=10000는 10초의 재시험 간격입니다. 기본값은 1초입니다. |
웹소켓 프로토콜은 기본 자동 재연결 관련 매개 변수를 설정합니다: payload=parameter value | payload는 웹소켓이 다시 연결될 때 보내야 하는 구독 메시지입니다. 예를 들어: payload=okokok |
소크스5 프록시와 관련된 매개 변수: 프록시=파라미터 값 | proxy는 ss5 proxy 설정, 매개 변수 값 형식: socks5://name:pwd@192.168.0.1:1080, 이름은 ss5 서버 사용자 이름, pwd는 ss5 서버 로그인 비밀번호, 1080는 ss5 서비스 포트입니다. |
이Dial()
이 기능은 라이브 트레이딩에서만 지원됩니다.
다이얼 함수를 사용하여 데이터베이스에 연결할 때, 연결 문자열은 각 데이터베이스의 go 언어 드라이버 프로젝트에 참조하여 작성됩니다.
지원되는 데이터베이스 | 추진 프로젝트 | 연결 문자열 | 언급 |
---|---|---|---|
스클라이트3 | github.com/mattn/go-sqlite3 | sqlite3://file:test.db?cache=shared&mode=memory | 이sqlite3:// 전자는 sqlite3 데이터베이스가 사용되고 있음을 나타냅니다. 예를 들어 호출:Dial("sqlite3://test1.db") |
mysql | github.com/go-sql-driver/mysql | mysql://username:yourpassword@tcp(localhost:3306) / 당신의 데이터베이스?차르셋=utf8mb4 | – |
포스트그레스 | github.com/lib/pq | postgres://user=postgres dbname=yourdatabase sslmode=disable password=yourpassword 호스트=localhost 포트=5432 | – |
클릭하우스 | github.com/ClickHouse/clickhouse-go | clickhouse://tcp://host:9000?username=username&password=yourpassword&database=youdatabase | – |
참고로,payload
내용address
매개 변수는 문자를 포함합니다.=
또는 다른 특수 문자, 그것은 분석에 영향을 미칠 수 있습니다address
매개 변수Dial
다음 예시처럼
backPack Exchange 웹소켓 개인 인터페이스 호출 예제:
var client = null
function main() {
// Base64-encoded public key of the key pair, i.e. the access key configured on FMZ
var base64ApiKey = "xxx"
var ts = String(new Date().getTime())
var data = "instruction=subscribe×tamp=" + ts + "&window=5000"
// Since signEd25519 returns a base64 encoding, it contains the character "="
var signature = signEd25519(data)
// The payload may contain the character "=" after being encoded by JSON
payload = {
"method": "SUBSCRIBE",
"params": ["account.orderUpdate"],
"signature": [base64ApiKey, signature, ts, "5000"]
}
client = Dial("wss://ws.backpack.exchange")
client.write(JSON.stringify(payload))
if (!client) {
Log("Connection failed, program exited")
return
}
while (true) {
var buf = client.read()
Log(buf)
}
}
function onexit() {
client.close()
}
function signEd25519(data) {
return exchange.Encode("ed25519.seed", "raw", "base64", data, "base64", "{{secretkey}}")
}
코드의 다음 호출은 잘 작동합니다.
client = Dial("wss://ws.backpack.exchange")
client.write(JSON.stringify(payload))
만약 당신이 그것을 직접payload
, 그것은 제대로 작동하지 않습니다, 예를 들어:
client = Dial("wss://ws.backpack.exchange|payload=" + JSON.stringify(payload))
현재 자바스크립트만이mqtt
, nats
, amqp
, 그리고kafka
다이얼 함수에서 통신 프로토콜. 자바스크립트 언어 전략 코드는 네 개의 프로토콜의 사용을 보여주는 예로 사용됩니다.mqtt
, nats
, amqp
, 그리고kafka
:
// We need to configure and deploy proxy servers for each protocol first.
// For the sake of demonstration, the subscription (read operation) and publishing (write operation) of the topic test_topic are all performed in the current strategy.
var arrConn = []
var arrName = []
function main() {
LogReset(1)
conn_nats = Dial("nats://admin@127.0.0.1:4222?topic=test_topic")
conn_mqtt = Dial("mqtt://127.0.0.1:1883?topic=test_topic")
conn_amqp = Dial("amqp://q:admin@127.0.0.1:5672/?queue=test_Queue")
conn_kafka = Dial("kafka://localhost:9092/test_topic")
arrConn = [conn_nats, conn_amqp, conn_mqtt, conn_kafka]
arrName = ["nats", "amqp", "mqtt", "kafka"]
while (true) {
for (var i in arrConn) {
var conn = arrConn[i]
var name = arrName[i]
// Write data
conn.write(name + ", time: " + _D() + ", test msg.")
// Read data
var readMsg = conn.read(1000)
Log(name + " readMsg: ", readMsg, "#FF0000")
}
Sleep(1000)
}
}
function onexit() {
for (var i in arrConn) {
arrConn[i].close()
Log("close", arrName[i], "connect")
}
}
자세한 문서 참조:FMZ를 탐구: 라이브 거래 전략 사이의 통신 프로토콜의 연습
Http 요청을 보내십시오.
요청의 응답 데이터를 반환합니다. 반환 값이 a인 경우JSON
문자열, 그것은 분석 될 수 있습니다JSON.parse()
기능JavaScript
언어 전략,json::parse()
기능C++
언어 전략. 디버그는 옵션 구조에서 true로 설정되면 반환 값은 객체 (JSON); 디버그는 false로 설정되면 반환 값은 문자열입니다.
문자열, 대상
HttpQuery (URL) HttpQuery (URL, 옵션)
Http 요청 URL url 사실 문자열 예를 들어, HTTP 요청 관련 설정은 다음과 같이 구성될 수 있습니다.
{
method: "POST",
body: "a=10&b=20&c=30",
charset: "UTF-8",
cookie: "session_id=12345; lang=en",
profile: "chrome_103",
debug: false,
headers: {"TEST-HTTP-QUERY": "123"},
timeout: 1000
}
tls
지문
지원된 설정에는 다음 옵션이 포함됩니다.
chrome_:"chrome_103"
, "chrome_104"
, "chrome_105"
, "chrome_106"
, "chrome_107"
, "chrome_108"
, "chrome_109"
, "chrome_110"
, "chrome_111"
, "chrome_112"
, "chrome_117"
,
사파리:"safari_15_6_1"
, "safari_16_0"
, "safari_ipad_15_6"
, "safari_ios_15_5"
, "safari_ios_15_6"
, "safari_ios_16_0"
,
firefox_:"firefox_102"
, "firefox_104"
, "firefox_105"
, "firefox_106"
, "firefox_108"
, "firefox_110"
, "firefox_117"
,
오페라:"opera_89"
, "opera_90"
, "opera_91"
,
젤란도"zalando_android_mobile"
, "zalando_ios_mobile"
,
나이키:"nike_ios_mobile"
, "nike_android_mobile"
,
클라우드 크래퍼:"cloudscraper"
,
mms_:"mms_ios"
,
mesh_:"mesh_ios"
, "mesh_ios_1"
, "mesh_ios_2"
, "mesh_android"
, "mesh_android_1"
, "mesh_android_2"
,
확인된 것"confirmed_ios"
, "confirmed_android"
,
좋아요."okhttp4_android_7"
, "okhttp4_android_8"
, "okhttp4_android_9"
, "okhttp4_android_10"
, "okhttp4_android_11"
, "okhttp4_android_12"
, "okhttp4_android_13"
,true
, 그HttpQuery
함수 호출은 전체 응답 메시지를 반환합니다.false
, 단지 데이터Body
응답 메시지가 반환됩니다.profile
이 분야는 방치될 수 있습니다.옵션 거짓 물체
function main(){
// An example of GET access without parameters
var info = JSON.parse(HttpQuery("https://www.okx.com/api/v5/public/time"))
Log(info)
// An example of GET access with parameters
var ticker = JSON.parse(HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT"))
Log(ticker)
}
import json
import urllib.request
def main():
# HttpQuery does not support Python, you can use the urllib/urllib2 library instead
info = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/public/time").read().decode('utf-8'))
Log(info)
ticker = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/market/books?instId=BTC-USDT").read().decode('utf-8'))
Log(ticker)
void main() {
auto info = json::parse(HttpQuery("https://www.okx.com/api/v5/public/time"));
Log(info);
auto ticker = json::parse(HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT"));
Log(ticker);
}
OKX 공개 틱어 API 인터페이스에 액세스하는 예제.
function main() {
// Setting proxy and sending an http request for this time, no username, no password, this http request will be sent through the proxy
HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/")
// Setting proxy and sending an http request for this time, enter the user name and password, only the current call to HttpQuery takes effect, and then call HttpQuery again ("http://www.baidu.com") so that the proxy will not be used.
HttpQuery("socks5://username:password@127.0.0.1:8889/http://www.baidu.com/")
}
# HttpQuery does not support Python, you can use the urllib/urllib2 library instead
void main() {
HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/");
HttpQuery("socks5://username:password@127.0.0.1:8889/http://www.baidu.com/");
}
HttpQuery 함수는 프록시 설정을 사용합니다.
이HttpQuery()
기능만 지원합니다JavaScript
, C++
언어Python
언어를 사용할 수 있습니다urllib
Http 요청을 직접 전송할 수 있습니다.HttpQuery()
주로 시그니처 정보와 같은 공개 인터페이스와 같이 서명이 필요하지 않은 교환의 인터페이스에 액세스하는 데 사용됩니다.HttpQuery()
백테스팅 시스템에서 요청을 보내기 위해 사용할 수 있습니다.GET
백테스팅은 20번의 방문으로 제한됩니다.URLs
, 그리고HttpQuery()
방문은 데이터를 캐시합니다.URL
두 번째 접속이 되면,HttpQuery()
함수는 캐시된 데이터를 반환하고 더 이상 실제 네트워크 요청이 발생하지 않습니다.
{@fun/Global/HttpQuery_Go HttpQuery_Go}
HTTP 요청을 보내기 위해,HttpQuery
function.
이HttpQuery_Go()
이 함수는 Http 요청의 결과를 얻기 위해 사용할 수 있는 동시 객체를 즉시 반환합니다.wait
의 방법JSON.parse()
함수를 사용할 수 있습니다JSON.parse()
기능JavaScript
언어의 전략
물체
HttpQuery_Go (URL) HttpQuery_Go (URL, 옵션)
Http 요청 URL url 사실 문자열 예를 들어, HTTP 요청 관련 설정은 다음과 같이 구성될 수 있습니다.
{
method: "POST",
body: "a=10&b=20&c=30",
charset: "UTF-8",
cookie: "session_id=12345; lang=en",
// profile: "",
debug: false,
headers: {"TEST-HTTP-QUERY": "123"},
timeout: 1000
}
tls
fingerprints.true
이HttpQuery_Go
함수 호출은 전체 응답 메시지를 반환합니다.false
, 단지 데이터Body
응답 메시지가 반환됩니다.profile
이 분야는 방치될 수 있습니다.옵션 거짓 물체
function main() {
// Create the first asynchronous thread
var r1 = HttpQuery_Go("https://www.okx.com/api/v5/market/tickers?instType=SPOT")
// Create the second asynchronous thread
var r2 = HttpQuery_Go("https://api.huobi.pro/market/tickers")
// Get the return value of the first asynchronous thread call
var tickers1 = r1.wait()
// Get the return value of the second asynchronous thread call
var tickers2 = r2.wait()
// Print results
Log("tickers1:", tickers1)
Log("tickers2:", tickers2)
}
# Not supported
// Not supported
종합적인 틱어 데이터에 대한 거래소의 공개 인터페이스에 비동기 액세스.
이HttpQuery_Go()
기능만 지원합니다JavaScript
, 그Python
언어는urllib
Http 요청을 직접 전송할 수 있습니다.HttpQuery_Go()
주로 교환에 서명이 필요하지 않은 인터페이스에 액세스하는 데 사용됩니다.HttpQuery_Go
기능은 백테스팅 시스템에서 지원되지 않습니다.
{@fun/Global/HttpQuery HttpQuery}
이 함수는 입력된 매개 변수에 따라 데이터를 암호화합니다.
이Encode
이 함수는 암호화와 암호화 후에 데이터를 반환합니다.
문자열
엔코드 (algo, inputFormat, outputFormat, data) 엔코드 (algo, inputFormat, outputFormat, data, key)
매개 변수algo
은 암호화 계산에 사용되는 알고리즘입니다. 지원 설정은:raw
(알고리즘이 사용되지 않습니다), "표지", algo
또한: algo
또한: algo
ed25519.seed
계산
뭔가
사실
문자열
데이터 형식을 지정하는 데 사용됩니다.data
매개 변수inputFormat
매개 변수는 다음 중 하나로 설정할 수 있습니다:raw
, hex
, base64
, string
.hex
암호화된 경우, base64
암호화된 것이고, outputFormat
매개 변수는 다음 중 하나로 설정할 수 있습니다:raw
, hex
, base64
, string
.hex
암호화된 경우, base64
암호화된 것이고, data
처리해야 할 데이터입니다.
데이터
사실
문자열
데이터 형식을 지정하는 데 사용됩니다.key
매개 변수key
매개 변수는 다음 중 하나로 설정할 수 있습니다:raw
, hex
, base64
, string
.hex
암호화된 경우, base64
암호화된 것이고, key
비밀 키는HMAC
암호화, 매개 변수key
매개 변수algo
설정되어 있습니다sign
또는signTx
.key
매개 변수는 사용되지 않습니다HMAC
암호화algo
매개 변수는
function main() {
Log(Encode("raw", "raw", "hex", "example", "raw", "123")) // 6578616d706c65
Log(Encode("raw", "raw", "hex", "example")) // 6578616d706c65
Log(Encode("sha256", "raw", "hex", "example", "raw", "123")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "", "123")) // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
Log(Encode("sha256", "raw", "hex", "example", null, "123")) // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
Log(Encode("sha256", "raw", "hex", "example", "string", "123")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("raw", "raw", "hex", "123")) // 313233
Log(Encode("raw", "raw", "base64", "123")) // MTIz
Log(Encode("sha256", "raw", "hex", "example", "hex", "313233")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
}
def main():
Log(Encode("raw", "raw", "hex", "example", "raw", "123")) # 6578616d706c65
Log(Encode("raw", "raw", "hex", "example", "", "")) # 6578616d706c65
Log(Encode("sha256", "raw", "hex", "example", "raw", "123")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "", "123")) # 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
Log(Encode("sha256", "raw", "hex", "example", "string", "123")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("raw", "raw", "hex", "123", "", "")) # 313233
Log(Encode("raw", "raw", "base64", "123", "", "")) # MTIz
Log(Encode("sha256", "raw", "hex", "example", "hex", "313233")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
void main() {
Log(Encode("raw", "raw", "hex", "example", "raw", "123")); // 6578616d706c65
Log(Encode("raw", "raw", "hex", "example")); // 6578616d706c65
Log(Encode("sha256", "raw", "hex", "example", "raw", "123")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "", "123")); // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
Log(Encode("sha256", "raw", "hex", "example", "string", "123")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("raw", "raw", "hex", "123")); // 313233
Log(Encode("raw", "raw", "base64", "123")); // MTIz
Log(Encode("sha256", "raw", "hex", "example", "hex", "313233")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
}
엑코드 함수 호출 예제
function main(){
var ret1 = Encode("text.encoder.utf8", "raw", "hex", "hello") // e4bda0e5a5bd
Log(ret1)
var ret2 = Encode("text.decoder.utf8", "hex", "string", ret1)
Log(ret2)
var ret3 = Encode("text.encoder.gbk", "raw", "hex", "hello") // c4e3bac3
Log(ret3)
var ret4 = Encode("text.decoder.gbk", "hex", "string", ret3)
Log(ret4)
}
def main():
ret1 = Encode("text.encoder.utf8", "raw", "hex", "hello", "", "") # e4bda0e5a5bd
Log(ret1)
ret2 = Encode("text.decoder.utf8", "hex", "string", ret1, "", "")
Log(ret2)
ret3 = Encode("text.encoder.gbk", "raw", "hex", "hello", "", "") # c4e3bac3
Log(ret3)
ret4 = Encode("text.decoder.gbk", "hex", "string", ret3, "", "")
Log(ret4)
void main(){
auto ret1 = Encode("text.encoder.utf8", "raw", "hex", "hello"); // e4bda0e5a5bd
Log(ret1);
auto ret2 = Encode("text.decoder.utf8", "hex", "string", ret1);
Log(ret2);
auto ret3 = Encode("text.encoder.gbk", "raw", "hex", "hello"); // c4e3bac3
Log(ret3);
auto ret4 = Encode("text.decoder.gbk", "hex", "string", ret3);
Log(ret4);
}
매개 변수algo
또한:
이Encode()
이 기능은 라이브 거래에만 지원됩니다.key
그리고keyFormat
매개 변수가 통과되지 않는 경우key
암호화가 사용되지 않습니다.
현재 순간의 나노초 시간표를 얻으십시오.
이UnixNano()
이 함수는 나노초 시간표를 반환합니다.
번호
유닉스나노 (UNIXNANO))
function main() {
var time = UnixNano() / 1000000
Log(_N(time, 0))
}
def main():
time = UnixNano()
Log(time)
void main() {
auto time = UnixNano();
Log(time);
}
밀리초 시간표를 얻으려면 다음 코드를 사용할 수 있습니다.
{@fun/Global/Unix UNIX}
현재 순간의 시간표를 2층에서 가져와
두 번째 레벨의 시간표를 반환합니다. 번호
유닉스 ((()
function main() {
var t = Unix()
Log(t)
}
def main():
t = Unix()
Log(t)
void main() {
auto t = Unix();
Log(t);
}
{@fun/Global/UnixNano 유닉스나노}
도커가 있는 장치의 시스템 정보를 얻으십시오.
시스템 정보 문자열
GetOS()
function main() {
Log("GetOS:", GetOS())
}
def main():
Log("GetOS:", GetOS())
void main() {
Log("GetOS:", GetOS());
}
예를 들어,GetOS()
도커에서 실행되는 함수맥 OS운영 체제가 반환 할 수 있습니다:darwin/amd64
왜냐하면 애플 컴퓨터는 여러 하드웨어 아키텍처를 가지고 있기 때문입니다.darwin
의 이름입니다맥 OS system.
매개 변수의 MD5 해시를 계산합니다.data
.
MD5 해시 값 문자열
MD5 (데이터)
MD5 계산이 필요한 데이터입니다. 데이터 사실 문자열
function main() {
Log("MD5", MD5("hello world"))
}
def main():
Log("MD5", MD5("hello world"))
void main() {
Log("MD5", MD5("hello world"));
}
전화MD5("hello world")
함수, 반환 값은:5eb63bbbe01eeed093cb22bb8f5acdc3
.
{@fun/Global/Encode Encode}
데이터베이스 인터페이스 기능
a의 실행 결과를 포함하는 객체sql예를 들어,
{"columns":["TS","HIGH","OPEN","LOW","CLOSE","VOLUME"],"values":[[1518970320000,100,99.1,90,100,12345.6]]}
물체
DBExec ((sql)
sql명령어 문자열 sql 사실 문자열
function main() {
var strSql = [
":CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
].join("")
var ret = DBExec(strSql)
Log(ret)
// Add a piece of data
Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
// Query data
Log(DBExec(":SELECT * FROM TEST_TABLE;"))
}
def main():
arr = [
":CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
]
strSql = ""
for i in range(len(arr)):
strSql += arr[i]
ret = DBExec(strSql)
Log(ret)
# Add a piece of data
Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
# Query data
Log(DBExec(":SELECT * FROM TEST_TABLE;"))
void main() {
string strSql = ":CREATE TABLE TEST_TABLE(\
TS INT PRIMARY KEY NOT NULL,\
HIGH REAL NOT NULL,\
OPEN REAL NOT NULL,\
LOW REAL NOT NULL,\
CLOSE REAL NOT NULL,\
VOLUME REAL NOT NULL)";
auto ret = DBExec(strSql);
Log(ret);
// Add a piece of data
Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"));
// Query data
Log(DBExec(":SELECT * FROM TEST_TABLE;"));
}
메모리 데이터베이스 지원,DBExec
기능 매개 변수, 만약sql문장 시작:
이 경우 메모리에 있는 데이터베이스에서 동작할 수 있습니다. 파일 쓰기 없이도 더 빨라집니다.
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))
// Add a piece of data
Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
// Query data
Log(DBExec("SELECT * FROM TEST_TABLE;"))
// Modify data
Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))
// Delete data
Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110))
}
def main():
arr = [
"CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
]
strSql = ""
for i in range(len(arr)):
strSql += arr[i]
Log(DBExec(strSql))
# Add a piece of data
Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
# Query data
Log(DBExec("SELECT * FROM TEST_TABLE;"))
# Modify data
Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))
# Delete data
Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110))
void main() {
string strSql = "CREATE TABLE TEST_TABLE(\
TS INT PRIMARY KEY NOT NULL,\
HIGH REAL NOT NULL,\
OPEN REAL NOT NULL,\
LOW REAL NOT NULL,\
CLOSE REAL NOT NULL,\
VOLUME REAL NOT NULL)";
Log(DBExec(strSql));
// Add a piece of data
Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"));
// Query data
Log(DBExec("SELECT * FROM TEST_TABLE;"));
// Modify data
Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000));
// Delete data
Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110));
}
테이블에 레코드를 추가, 삭제, 확인 및 변경.
기능DBExec()
라이브 거래 데이터베이스 (SQLite 데이터베이스) 를 패러미터를 전달하여 작동 할 수 있습니다. 라이브 거래 데이터베이스에서 데이터 추가, 삭제, 확인 및 변경 작업을 실현, 지원SQLite문법. 시스템 라이브 거래 데이터베이스에 테이블을 예약:kvdb
, cfg
, log
, profit
, chart
이 테이블에서 작업하지 마십시오.거래지원되지 않으며 시스템에서 충돌을 일으킬 수 있는 그러한 작업을 수행하는 것은 권장되지 않습니다.DBExec()
이 기능은 라이브 트레이딩에서만 지원됩니다.
#############
UUID를 생성합니다.
32비트 UUID 문자열
UUID (()
function main() {
var uuid1 = UUID()
var uuid2 = UUID()
Log(uuid1, uuid2)
}
def main():
uuid1 = UUID()
uuid2 = UUID()
Log(uuid1, uuid2)
void main() {
auto uuid1 = UUID();
auto uuid2 = UUID();
Log(uuid1, uuid2);
}
이UUID()
이 기능은 라이브 거래만 지원합니다.
사건에 대한 귀를 기울이고, 그것은 어떤 경우에 돌아옵니다WebSocket
가독 가능한 데이터 또는 동시에 수행되는 작업,exchange.Go()
, HttpQuery_Go()
, 등이 완료됩니다.
반환 객체가 null 값이 아니라면,Event
반환 컨텐츠에 포함된 것은 이벤트 트리거 타입입니다. 예를 들어 다음 반환 값 구조:
{"Seq":1,"Event":"Exchange_GetTrades","ThreadId":0,"Index":3,"Nano":1682068771309583400}
물체
이벤트 루프 ((() 이벤트 루프 (타임아웃)
매개 변수timeout
타임아웃 설정, 밀리초입니다.timeout
0로 설정된 경우 이벤트가 발생하기 전에 발생을 기다립니다. 0보다 크면 타임아웃을 기다리도록 설정하고 0보다 작으면 가장 최근의 이벤트를 즉시 반환합니다.
타임아웃
거짓
번호
function main() {
var routine_getTicker = exchange.Go("GetTicker")
var routine_getDepth = exchange.Go("GetDepth")
var routine_getTrades = exchange.Go("GetTrades")
// Sleep(2000), if the Sleep statement is used here, it will cause the subsequent EventLoop function to miss the previous events, because after waiting for 2 seconds, the concurrent function has received the data, and the subsequent EventLoop listening mechanism started, it misses these events.
// These events will not be missed unless EventLoop(-1) is called at the beginning of the first line of code to first initialize the EventLoop's listening mechanism.
// Log("GetDepth:", routine_getDepth.wait()) If the wait function is called in advance to retrieve the result of a concurrent call to the GetDepth function, the event that the GetDepth function receives the result of the request will not be returned in the EventLoop function.
var ts1 = new Date().getTime()
var ret1 = EventLoop(0)
var ts2 = new Date().getTime()
var ret2 = EventLoop(0)
var ts3 = new Date().getTime()
var ret3 = EventLoop(0)
Log("The first concurrent task completed was:", _D(ts1), ret1)
Log("The second concurrent task completed was:", _D(ts2), ret2)
Log("The third concurrent task completed was:", _D(ts3), ret3)
Log("GetTicker:", routine_getTicker.wait())
Log("GetDepth:", routine_getDepth.wait())
Log("GetTrades:", routine_getTrades.wait())
}
import time
def main():
routine_getTicker = exchange.Go("GetTicker")
routine_getDepth = exchange.Go("GetDepth")
routine_getTrades = exchange.Go("GetTrades")
ts1 = time.time()
ret1 = EventLoop(0)
ts2 = time.time()
ret2 = EventLoop(0)
ts3 = time.time()
ret3 = EventLoop(0)
Log("The first concurrent task completed was:", _D(ts1), ret1)
Log("The second concurrent task completed was:", _D(ts2), ret2)
Log("The third concurrent task completed was:", _D(ts3), ret3)
Log("GetTicker:", routine_getTicker.wait())
Log("GetDepth:", routine_getDepth.wait())
Log("GetTrades:", routine_getTrades.wait())
void main() {
auto routine_getTicker = exchange.Go("GetTicker");
auto routine_getDepth = exchange.Go("GetDepth");
auto routine_getTrades = exchange.Go("GetTrades");
auto ts1 = Unix() * 1000;
auto ret1 = EventLoop(0);
auto ts2 = Unix() * 1000;
auto ret2 = EventLoop(0);
auto ts3 = Unix() * 1000;
auto ret3 = EventLoop(0);
Log("The first concurrent task completed was:", _D(ts1), ret1);
Log("The second concurrent task completed was:", _D(ts2), ret2);
Log("The third concurrent task completed was:", _D(ts3), ret3);
Ticker ticker;
Depth depth;
Trades trades;
routine_getTicker.wait(ticker);
routine_getDepth.wait(depth);
routine_getTrades.wait(trades);
Log("GetTicker:", ticker);
Log("GetDepth:", depth);
Log("GetTrades:", trades);
}
첫 번째 전화EventLoop()
코드의 함수는 그 청취된 이벤트의 메커니즘을 초기화합니다.EventLoop()
호출은 이벤트 콜백이 시작되면 이전 이벤트를 놓칠 것입니다. 기본 시스템은 최대 500 개의 이벤트 콜백을 캐시하는 대기열 구조를 포장합니다.EventLoop()
이 함수는 프로그램 실행 중에 꺼내기 위해 시간 내에 호출되지 않으면, 500 캐시 외부의 후속 이벤트 콜백은 손실됩니다.EventLoop()
함수는 기본 시스템 WebSocket의 캐시 대기열 또는 같은 동시 함수의 캐시에 영향을 미치지 않습니다exchange.Go()
이 캐시의 경우, 여전히 해당 방법을 사용하여 데이터를 검색하는 것이 필요합니다.EventLoop()
함수EventLoop()
함수 반환.EventLoop()
기능은 새로운 네트워크 데이터가 기본 시스템에 수신되었다는 전략 계층을 알리는 것입니다. 전체 전략은 이벤트에 의해 주도됩니다.EventLoop()
함수는 이벤트를 반환, 그냥 모든 데이터 소스를 통과합니다. 예를 들어, 웹소켓 연결, 객체에 의해 생성exchange.Go()
데이터를 얻기 위해 노력합니다.EventLoop()
이 기능은 라이브 거래만 지원합니다.
메인 함수에서 호출될 때 메인 스레드에서 이벤트를 듣기main()
.JavaScript
언어,threading.Thread()
이 함수는 스레드를 생성합니다. 스레드
{@fun/Global/Dial Dial}, {@fun/Trade/exchange.Go exchange.Go}, {@fun/Global/HttpQuery_Go HttpQuery_Go}
이__Serve
이 함수는 Http 서비스, TCP 서비스, 웹소켓 서비스 (Http 프로토콜을 기반으로) 를 생성하는 데 사용됩니다.
생성된 서비스의 IP 주소와 포트를 기록하는 문자열을 반환합니다. 예를 들어:127.0.0.1:8088
, [::]:8089
.
문자열
__서비스 (서비스URI, 관리자) __서비스 (서비스 (SERVURI, 핸들러,...args)
이serveURI
이 매개 변수는 프로토콜, IP 주소, 포트 및 서비스 결합의 다른 설정을 구성하는 데 사용됩니다.http://0.0.0.0:8088?gzip=true
, 즉,http://:8088?gzip=true
.
serveURI
파라미터 설정,tcp://127.0.0.1:6666?tls=true
; 당신은 인증서와 개인 키를 추가할 수 있습니다.tls=true&cert_pem=xxxx&cert_key_pem=xxxx
.serveURI
파라미터 설정,http://127.0.0.1:6666?gzip=true
; 압축 설정을 설정할 수 있습니다:gzip=true
...
의serveURI
Https를 위한 매개 변수입니다.https://127.0.0.1:6666?tls=true&gzip=true
; 당신은 추가 할 수 있습니다cert_pem
그리고cert_key_pem
인증서를 로드하는 매개 변수serveURI
사실
문자열
의handler
이 매개 변수는 라우팅 처리 함수 (Http 프로토콜), 메시지 처리 함수 (TCP 프로토콜), 스트림 처리 함수 (Websocket) 에서 전달하는 데 사용됩니다.
매개 변수에서 전달된 콜백 함수handler
여러 매개 변수를 정의할 수 있는데 첫 번째 매개 변수는 ctx 객체 (context object) 입니다.
관리자
사실
기능
콜백 함수의 실제 매개 변수는 매개 변수로 전달handler
여러 매개 변수가 있을 수 있습니다.arg
예를 들어:
__Serve("http://:8088", function(ctx, a, b, c) {
Log(`ctx.host():`, ctx.host(), ", a=", a, ", b=", b, ", c=", c)
}, 1, 2, 3)
매개 변수1
, 2
, 3
전화 할 때 통과__Serve()
함수는 매개 변수와 일치합니다a
, b
, c
콜백 함수에서 통과했습니다.
아그 거짓 문자열, 숫자, bool, 객체, 배열, 함수, null 값 및 시스템에서 지원되는 다른 유형
function main() {
let httpServer = __Serve("http://:8088?gzip=true", function (ctx) {
Log("http connect from: ", ctx.remoteAddr(), "->", ctx.localAddr())
let path = ctx.path()
if (path == "/") {
ctx.write(JSON.stringify({
path: ctx.path(),
method: ctx.method(),
headers: ctx.headers(),
cookie: ctx.header("Cookie"),
remote: ctx.remoteAddr(),
query: ctx.rawQuery()
}))
} else if (path == "/tickers") {
let ret = exchange.GetTickers()
if (!ret) {
ctx.setStatus(500)
ctx.write(GetLastError())
} else {
ctx.write(JSON.stringify(ret))
}
} else if (path == "/wss") {
if (ctx.upgrade("websocket")) { // upgrade to websocket
while (true) {
let r = ctx.read(10)
if (r == "") {
break
} else if (r) {
if (r == "ticker") {
ctx.write(JSON.stringify(exchange.GetTicker()))
} else {
ctx.write("not support")
}
}
}
Log("websocket closed", ctx.remoteAddr())
}
} else {
ctx.setStatus(404)
}
})
let echoServer = __Serve("tcp://:8089", function (ctx) {
Log("tcp connect from: ", ctx.remoteAddr(), "->", ctx.localAddr())
while (true) {
let d = ctx.read()
if (!d) {
break
}
ctx.write(d)
}
Log("connect closed")
})
Log("http serve on", httpServer, "tcp serve on", echoServer)
for (var i = 0; i < 5; i++) {
if (i == 2) {
// test Http
var retHttp = HttpQuery("http://127.0.0.1:8088?num=123&limit=100", {"debug": true})
Log("retHttp:", retHttp)
} else if (i == 3) {
// test TCP
var tcpConn = Dial("tcp://127.0.0.1:8089")
tcpConn.write("Hello TCP Server")
var retTCP = tcpConn.read()
Log("retTCP:", retTCP)
} else if (i == 4) {
// test Websocket
var wsConn = Dial("ws://127.0.0.1:8088/wss|compress=gzip")
wsConn.write("ticker")
var retWS = wsConn.read(1000)
Log("retWS:", retWS)
// no depth
wsConn.write("depth")
retWS = wsConn.read(1000)
Log("retWS:", retWS)
}
Sleep(1000)
}
}
# Unsupported
// Unsupported
Websocket
Http 프로토콜에 기반하여 구현됩니다. 경로에서 라우팅 브랜치를 설정하고 실행 코드를 설계할 수 있습니다Websocket
이 섹션에서 샘플 코드를 참조 할 수 있습니다.매개 변수에서 전달된 콜백 함수handler
수락ctx
매개 변수ctx
매개 변수 는 다음 방법 으로 데이터를 얻고 기록 하기 위해 사용되는 컨텍스트 객체 입니다.
HTTP/1.1
, tcp
.http://127.0.0.1:8088?num=123
, 그리고 매개 변수에 의해 전달된 호출 역 처리 함수handler
수익"123"
언제ctx.query("num")
라고 불립니다.User-Agent
현재 요청의 제목에:ctx.header("User-Agent")
.GET
, POST
, 등등ctx
컨텍스트 객체에 웹소켓 프로토콜; 귀환 boolean 값 (진짜) 전환이 성공하면, 그리고 boolean 값 (거짓) 실패하면.read
이 방법은 일반적인 HTTP 프로토콜에서 지원되지 않습니다. 당신은 타임 아웃 매개 변수를 지정할 수 있습니다timeout_ms
밀리 초에JSON.stringify()
JSON 객체를 문자열로 인코딩하고WebSocket
프로토콜, 이 방법을 사용하여 암호화된 문자열을 클라이언트에 전달할 수 있습니다.{@fun/Global/HttpQuery HttpQuery}, {@fun/Global/HttpQuery_Go HttpQuery_Go}
지속적으로 데이터를 저장, 함수는 저장 할 수있는 글로벌 사전 함수를 구현합니다. 데이터 구조는 도커의 로컬 데이터베이스 파일에 영구적으로 저장되는 KV 테이블입니다.
계속 저장된 키 값 데이터k-v
키-값 쌍
문자열, 숫자, bool, 객체, 배열, null 값
_G() _G(k) _G(k, v)
매개 변수k
저장된 키-값 쌍의 키의 이름이고 대소문 감수성이 없습니다.
k
거짓
문자열, null 값
매개 변수v
저장된 키-값 쌍의 키 값입니다.JSON
시리즈화 된 것입니다.
v
거짓
문자열, 숫자, bool, 객체, 배열, null 값
function main(){
// Set a global variable num with a value of 1
_G("num", 1)
// Change a global variable num to the value of the string ok
_G("num", "ok")
// Delete the global variable num
_G("num", null)
// Returns the value of the global variable num
Log(_G("num"))
// Delete all global variables
_G(null)
// Return to live trading ID
var robotId = _G()
}
def main():
_G("num", 1)
_G("num", "ok")
_G("num", None)
Log(_G("num"))
_G(None)
robotId = _G()
void main() {
_G("num", 1);
_G("num", "ok");
_G("num", NULL);
Log(_G("num"));
_G(NULL);
// Not support auto robotId = _G();
}
각 라이브 거래에 대한 별도의 데이터베이스,_G()
함수는 항상 전략이 다시 시작되거나 도커가 실행을 중단하면있을 것입니다. 백테스팅이 완료되면 백테스팅 시스템에 저장된 데이터는_G()
이 기능을 사용 하 여_G()
저장된 데이터를 유지하기 위한 기능, 하드웨어 장치의 메모리 및 하드 디스크 공간에 따라 합리적으로 사용되어야 하며, 남용되어서는 안 됩니다.
전화할 때_G()
라이브 거래에서 기능 및 어떤 매개 변수가 전달되지 않습니다,_G()
함수는Id
현재 라이브 거래._G()
함수, 매개 변수v
0으로 전달되면k-v
키-값 쌍을 호출할 때_G()
함수, 단지 매개 변수k
문자열에 전달됩니다, 그리고_G()
함수는 저장된 매개 변수에 대응하는 키 값을 반환k
전화할 때_G()
함수, 단지 매개 변수k
0값으로 전달됩니다.k-v
키-값 쌍이 삭제됩니다.k-v
키값 쌍이 지속적으로 저장된 경우,_G()
함수는 다시 호출되고 매개 변수로 지속적으로 저장된 키의 이름을 전달합니다.k
. 새로운 키 값을 매개 변수로 전달v
업데이트 할 것입니다.k-v
키-값 쌍
{@fun/Global/DBExec DBExec}
밀리초 시간표 또는Date
시간 문자열에 대한 객체입니다.
시간 줄. 문자열
_D() 시간표 _D (시간표, fmt)
밀리초 시간표 또는Date
물체.
시간표
거짓
번호, 대상
형식 문자열,JavaScript
언어 기본 형식:yyyy-MM-dd hh:mm:ss
; Python
언어 기본 형식:%Y-%m-%d %H:%M:%S
; C++
언어 기본 형식:%Y-%m-%d %H:%M:%S
...
fmt
거짓
문자열
function main(){
var time = _D()
Log(time)
}
def main():
strTime = _D()
Log(strTime)
void main() {
auto strTime = _D();
Log(strTime);
}
현재 시간 문자열을 가져와 인쇄합니다:
function main() {
Log(_D(1574993606000))
}
def main():
# Running this code on a server in Beijing time: 2019-11-29 10:13:26 , a docker on another server in another region results in: 2019-11-29 02:13:26
Log(_D(1574993606))
void main() {
Log(_D(1574993606000));
}
시간표는 1574993606000, 코드 변환:
function main() {
Log(_D(1574993606000, "yyyy--MM--dd hh--mm--ss")) // 2019--11--29 10--13--26
}
def main():
# 1574993606 is timestamped in seconds.
Log(_D(1574993606, "%Y--%m--%d %H--%M--%S")) # 2019--11--29 10--13--26
void main() {
Log(_D(1574993606000, "%Y--%m--%d %H--%M--%S")); // 2019--11--29 10--13--26
}
매개 변수와 함께 포맷fmt
다른 경우JavaScript
, Python
, 그리고C++
다음 예제에서 보여준 바와 같이 언어
매개 변수를 전달하지 않고 현재 시간 문자열을 반환합니다._D()
기능Python
전략, 당신은 통과 매개 변수 두 번째 수준의 타임 스탬프 (자바스크립트와 C ++ 전략에서 밀리 초 수준 타임 스탬프, 1 초 1000 밀리 초에 해당하는) 이다._D()
실시간 거래에서 읽을 수 있는 시간표가 있는 시간 문자열을 분석하기 위해, 당신은 도커 프로그램이 위치하는 운영 체제의 시간대와 시간 설정에 주의를 기울여야 합니다._D()
함수는 도커
UNIX UNIX UNIX UNIX UNIX UNIX
부동 소수점 번호를 포맷하세요.
정밀 설정에 따라 포맷된 부동 소수점 번호 번호
_N() _N(num) _N (num, 정밀)
형식이 필요한 부동 소수점 번호
수
사실
번호
포맷의 정밀 설정, 매개 변수precision
정수이고 매개 변수는precision
기본값은 4입니다
정확성
거짓
번호
function main(){
var i = 3.1415
Log(i)
var ii = _N(i, 2)
Log(ii)
}
def main():
i = 3.1415
Log(i)
ii = _N(i, 2)
Log(ii)
void main() {
auto i = 3.1415;
Log(i);
auto ii = _N(i, 2);
Log(ii);
}
예를 들어,_N(3.1415, 2)
다음 값을 삭제합니다3.1415
두 소수점, 그리고 함수는 반환3.14
.
function main(){
var i = 1300
Log(i)
var ii = _N(i, -3)
// Check the logs and see that it is 1000
Log(ii)
}
def main():
i = 1300
Log(i)
ii = _N(i, -3)
Log(ii)
void main() {
auto i = 1300;
Log(i);
auto ii = _N(i, -3);
Log(ii);
}
소수점 왼쪽에 있는 모든 n자리들을 0으로 바꾸면 이렇게 쓸 수 있습니다
매개 변수precision
양 పూర్수는 될 수 있고, 음 పూర్수는 될 수 있습니다
{@fun/Trade/exchange.SetPrecision exchange.SetPrecision}
인터페이스 오류 용도 기능을 다시 시도합니다.
콜백 함수가 실행될 때 반환되는 값 모든 타입은 시스템에서 지원됩니다.논리적인 잘못된 값그리고null 값.
_C(pfn) _C ((pfn,...args)
매개 변수pfn
함수 참조입니다.콜백 함수...
pfn
사실
기능
매개 변수콜백 함수, 한 개 이상의 매개 변수가 있을 수 있습니다.arg
- 파라미터의 종류와 수arg
그 매개 변수에 따라콜백 함수- 네
아그
거짓
문자열, 숫자, bool, 객체, 배열, 함수, 모든 유형은 null 값과 같이 시스템에서 지원됩니다.
function main(){
var ticker = _C(exchange.GetTicker)
// Adjust _C() function retry interval to 2 seconds
_CDelay(2000)
var depth = _C(exchange.GetDepth)
Log(ticker)
Log(depth)
}
def main():
ticker = _C(exchange.GetTicker)
_CDelay(2000)
depth = _C(exchange.GetDepth)
Log(ticker)
Log(depth)
void main() {
auto ticker = _C(exchange.GetTicker);
_CDelay(2000);
auto depth = _C(exchange.GetDepth);
Log(ticker);
Log(depth);
}
매개 변수 없는 오류 허용 함수:
function main(){
var records = _C(exchange.GetRecords, PERIOD_D1)
Log(records)
}
def main():
records = _C(exchange.GetRecords, PERIOD_D1)
Log(records)
void main() {
auto records = _C(exchange.GetRecords, PERIOD_D1);
Log(records);
}
오류 용이성 있는 매개 변수를 가진 함수:
var test = function(a, b){
var time = new Date().getTime() / 1000
if(time % b == 3){
Log("Eligible!", "#FF0000")
return true
}
Log("Retry!", "#FF0000")
return false
}
function main(){
var ret = _C(test, 1, 5)
Log(ret)
}
import time
def test(a, b):
ts = time.time()
if ts % b == 3:
Log("Eligible!", "#FF0000")
return True
Log("Retry!", "#FF0000")
return False
def main():
ret = _C(test, 1, 5)
Log(ret)
// C++ does not support fault tolerance for custom functions in this way
또한 사용자 정의 함수의 오류 허용에 사용할 수 있습니다:
이_C()
function는 지정된 함수를 호출할 수 있습니다.pfn
수익null또는거짓호출되면 다시 호출을 시도합니다.pfn
예를 들어_C(exchange.GetTicker)
. 기본 재시험 간격은 3 초입니다, 당신은 호출 할 수 있습니다_CDelay()
재시험 간격을 설정하는 기능입니다. 예를 들어,_CDelay(1000)
재시험 간격을 변경하기 위한 수단_C()
1초로 작동합니다.
결함 허용은 다음 기능에 적용될 수 있지만 제한되지 않습니다.
exchange.GetTicker()
exchange.GetDepth()
exchange.GetTrades()
exchange.GetRecords()
exchange.GetAccount()
exchange.GetOrders()
exchange.GetOrder()
exchange.GetPositions()
모든 것은_C()
결함 허용 함수_C()
함수는 위와 같은 함수 결함 허용에 국한되지 않습니다, 매개 변수pfn
함수 호출보다는 함수 참조입니다.
이 점에 유의해야 합니다._C(exchange.GetTicker)
아니_C(exchange.GetTicker())
.배열의 교차점 수를 반환합니다.arr1
그리고 배열arr2
.
배열의 교차기점 수arr1
그리고 배열arr2
...
번호
_십자 (arr1,arr2)
요소는 타입의 배열입니다.number
...
arr1
사실
배열
요소는 타입의 배열입니다.number
...
arr2
사실
배열
// Fast line indicator
var arr1 = [1,2,3,4,5,6,8,8,9]
// Slow line indicator
var arr2 = [2,3,4,5,6,7,7,7,7]
function main(){
Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
}
arr1 = [1,2,3,4,5,6,8,8,9]
arr2 = [2,3,4,5,6,7,7,7,7]
def main():
Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
void main() {
vector<double> arr1 = {1,2,3,4,5,6,8,8,9};
vector<double> arr2 = {2,3,4,5,6,7,7,7,7};
Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2));
Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1));
}
데이터 세트를 시뮬레이션하여 _Cross ((Arr1, Arr2) 함수를 테스트 할 수 있습니다.
만약_Cross()
이 함수 는 양수 이면 상향 진입 기간 을 나타내고, 이 함수 이 음수 이면 하향 진입 기간 을 나타내고, 0 은 현재 가격 과 동일 합니다. 사용 지침:내장 기능에 대한 분석 및 사용 지침 _ 크로스.
기능JSONParse()
분석하는 데 사용됩니다.JSON
strings.
JSON
물체.
물체
JSONParse ((s)
JSON
끈.
s
사실
문자열
function main() {
let s1 = '{"num": 8754613216564987646512354656874651651358}'
Log("JSON.parse:", JSON.parse(s1)) // JSON.parse: {"num":8.754613216564988e+39}
Log("JSONParse:", JSONParse(s1)) // JSONParse: {"num":"8754613216564987646512354656874651651358"}
let s2 = '{"num": 123}'
Log("JSON.parse:", JSON.parse(s2)) // JSON.parse: {"num":123}
Log("JSONParse:", JSONParse(s2)) // JSONParse: {"num":123}
}
import json
def main():
s1 = '{"num": 8754613216564987646512354656874651651358}'
Log("json.loads:", json.loads(s1)) # json.loads: map[num:8.754613216564987e+39]
Log("JSONParse:", JSONParse(s1)) # JSONParse: map[num:8754613216564987646512354656874651651358]
s2 = '{"num": 123}'
Log("json.loads:", json.loads(s2)) # json.loads: map[num:123]
Log("JSONParse:", JSONParse(s2)) # JSONParse: map[num:123]
void main() {
auto s1 = "{\"num\":8754613216564987646512354656874651651358}";
Log("json::parse:", json::parse(s1));
// Log("JSONParse:", JSONParse(s1)); // The function is not supported.
auto s2 = "{\"num\":123}";
Log("json::parse:", json::parse(s2));
// Log("JSONParse:", JSONParse(s2)); // The function is not supported.
}
큰 값의 JSON 문자열을 올바르게 분석할 수 있고, 큰 값을 문자열 유형으로 분석할 것입니다.JSONParse()
backtest 시스템에서 기능이 지원되지 않습니다.