Built-in Functions
Global
Version
Returns the current system version number.
Version()Examples
javascript
function main() {
Log("version:", Version())
}
python
def main():
Log("version:", Version())
c++
void main() {
Log("version:", Version());
}Returns
| Type | Description |
string | Current system version number, for example: |
Remarks
The system version number is the version number of the docker program.
Sleep
Sleep function, used to pause program execution for a specified time.
Sleep(millisecond)Examples
javascript
function main() {
Sleep(1000 * 10) // Wait for 10 seconds
Log("Waited for 10 seconds")
}
python
def main():
Sleep(1000 * 10)
Log("Waited for 10 seconds")
c++
void main() {
Sleep(1000 * 10);
Log("Waited for 10 seconds");
}Arguments
| Name | Type | Required | Description |
millisecond | number | Yes | The |
Remarks
For example, when executing Sleep(1000) function, the program will sleep for 1 second. Sleep times less than 1 millisecond are supported, such as setting Sleep(0.1). The minimum supported parameter value is 0.000001, which is nanosecond-level sleep, where 1 nanosecond equals 1e-6 milliseconds.
When writing strategies in Python, the Sleep(millisecond) function should be used for operations such as polling intervals and time waiting. It is not recommended to use the time.sleep(second) function from Python's time library. This is because using time.sleep(second) in a strategy will cause the strategy program to actually wait for the corresponding time during backtesting (rather than skipping ahead in the backtest system's time sequence), resulting in extremely slow strategy backtesting.
IsVirtual
Determine whether the strategy's runtime environment is a backtesting system.
IsVirtual()Examples
javascript
function main() {
if (IsVirtual()) {
Log("Currently in backtest environment.")
} else {
Log("Currently in live trading environment.")
}
}
python
def main():
if IsVirtual():
Log("Currently in backtest environment.")
else:
Log("Currently in live trading environment.")
c++
void main() {
if (IsVirtual()) {
Log("Currently in backtest environment.");
} else {
Log("Currently in live trading environment.");
}
}Returns
| Type | Description |
bool | Returns true when the strategy is running in a backtesting system environment, for example: |
Remarks
Determine whether the current runtime environment is a backtesting system, used to handle differences between backtesting and live trading environments.
Send email.
Mail(smtpServer, smtpUsername, smtpPassword, mailTo, title, body)Examples
javascript
function main(){
Mail("smtp.163.com", "[email protected]", "password", "[email protected]", "title", "body")
}
python
def main():
Mail("smtp.163.com", "[email protected]", "password", "[email protected]", "title", "body")
c++
void main() {
Mail("smtp.163.com", "[email protected]", "password", "[email protected]", "title", "body");
}Returns
| Type | Description |
bool | Returns |
Arguments
| Name | Type | Required | Description |
smtpServer | string | Yes | Specify the |
smtpUsername | string | Yes | Specify the email address of the email sender. |
smtpPassword | string | Yes | The |
mailTo | string | Yes | Specify the email address of the email recipient. |
title | string | Yes | Email subject. |
body | string | Yes | Email body content. |
See Also
Remarks
The smtpPassword parameter is set to the SMTP service password, not the email login password.
When setting the smtpServer parameter, if you need to change the port, you can directly specify the port number in the smtpServer parameter. For example: QQ Mail smtp.qq.com:587 (this port has been tested and is available).
If an error message appears: unencryped connection, you need to modify the smtpServer parameter of the Mail function. The parameter format is: ssl://xxx.com:xxx, for example, QQ Mail's SMTP SSL method: ssl://smtp.qq.com:465, or use the format smtp://xxx.com:xxx.
This function does not work in the backtesting system.
Mail_Go
Asynchronous version of the Mail function.
Mail_Go(smtpServer, smtpUsername, smtpPassword, mailTo, title, body)Examples
javascript
function main() {
var r1 = Mail_Go("smtp.163.com", "[email protected]", "password", "[email protected]", "title", "body")
var r2 = Mail_Go("smtp.163.com", "[email protected]", "password", "[email protected]", "title", "body")
var ret1 = r1.wait()
var ret2 = r2.wait()
Log("ret1:", ret1)
Log("ret2:", ret2)
}
python
# Not supported
c++
// Not supportedReturns
| Type | Description |
object | The |
Arguments
| Name | Type | Required | Description |
smtpServer | string | Yes | Used to specify the |
smtpUsername | string | Yes | Used to specify the email address of the email sender. |
smtpPassword | string | Yes | The |
mailTo | string | Yes | Used to specify the email address of the email recipient. |
title | string | Yes | Email subject. |
body | string | Yes | Email body content. |
See Also
Remarks
Does not work in the backtesting system.
SetErrorFilter
Filter error logs.
SetErrorFilter(filters)Examples
-
Filter common errors.
javascriptfunction main() { SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused") }pythondef main(): SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused")c++void main() { SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused"); } -
Filter specific API error messages.
javascriptfunction main() { // Query a non-existent order with id 123, intentionally causing an API error var order = exchange.GetOrder("123") Log(order) // Filter http502 errors and GetOrder API errors. After setting error filter, the second call to GetOrder will not report an error SetErrorFilter("502:|GetOrder") order = exchange.GetOrder("123") Log(order) }pythondef main(): order = exchange.GetOrder("123") Log(order) SetErrorFilter("502:|GetOrder") order = exchange.GetOrder("123") Log(order)c++void main() { TId orderId; Order order = exchange.GetOrder(orderId); Log(order); SetErrorFilter("502:|GetOrder"); order = exchange.GetOrder(orderId); Log(order); }
Arguments
| Name | Type | Required | Description |
filters | string | Yes | Regular expression string. |
Remarks
Error logs matched by this regular expression will not be uploaded to the log system. Can be called multiple times (no limit) to set multiple filter conditions, and the regular expressions set multiple times will accumulate and take effect. You can set an empty string to reset the error log filter regular expression: SetErrorFilter(""). Filtered logs will no longer be written to the database file of the corresponding live trading ID in the docker directory, preventing frequent errors from causing database file bloat.
GetPid
Get the unique identifier of the live trading process.
GetPid()Examples
javascript
function main(){
var id = GetPid()
Log(id)
}
python
def main():
id = GetPid()
Log(id)
c++
void main() {
auto id = GetPid();
Log(id);
}Returns
| Type | Description |
string | Returns the unique identifier of the current live trading process. |
GetLastError
Get the most recent error message.
GetLastError()Examples
javascript
function main(){
// 因为不存在编号为123的订单,所以会产生错误
exchange.GetOrder("123")
var error = GetLastError()
Log(error)
}
python
def main():
exchange.GetOrder("123")
error = GetLastError()
Log(error)
c++
void main() {
// 订单ID类型:TId,因此不能传入字符串,我们下一个不符合交易所规范的订单来触发错误
exchange.GetOrder(exchange.Buy(1, 1));
auto error = GetLastError();
Log(error);
}Returns
| Type | Description |
string | The most recent error message. |
Remarks
Does not work in the backtesting system.
GetCommand
Get strategy interaction commands.
GetCommand()Examples
-
Detect interactive commands and use the
Logfunction to output the command when an interactive command is detected.javascriptfunction main(){ while(true) { var cmd = GetCommand() if (cmd) { Log(cmd) } Sleep(1000) } }pythondef main(): while True: cmd = GetCommand() if cmd: Log(cmd) Sleep(1000)c++void main() { while(true) { auto cmd = GetCommand(); if(cmd != "") { Log(cmd); } Sleep(1000); } } -
For example, add a control without an input box in the strategy interaction controls, name the interaction control:
buy, control description:Buy, this is a button control. Continue to add a control with an input box, name the interaction control:sell, control description:Sell, this is an interaction control composed of a button and an input box. Design interaction code in the strategy to respond to different interaction controls:javascriptfunction main() { while (true) { LogStatus(_D()) var cmd = GetCommand() if (cmd) { Log("cmd:", cmd) var arr = cmd.split(":") if (arr[0] == "buy") { Log("Buy, this control has no quantity") } else if (arr[0] == "sell") { Log("Sell, this control has quantity:", arr[1]) } else { Log("Other control triggered:", arr) } } Sleep(1000) } }pythondef main(): while True: LogStatus(_D()) cmd = GetCommand() if cmd: Log("cmd:", cmd) arr = cmd.split(":") if arr[0] == "buy": Log("Buy, this control has no quantity") elif arr[0] == "sell": Log("Sell, this control has quantity:", arr[1]) else: Log("Other control triggered:", arr) Sleep(1000)c++#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, this control has no quantity"); } else if (arr[0] == "sell") { Log("Sell, this control has quantity:", arr[1]); } else { Log("Other control triggered:", arr); } } Sleep(1000); } }
Returns
| Type | Description |
string | The returned command format is |
Remarks
Not effective in the backtesting system.
GetMeta
Get the Meta value written when generating the strategy registration code.
GetMeta()Examples
Application scenario example: Using Meta to limit the asset quantity that a strategy can operate.
javascript
function main() {
// Maximum quote currency asset value allowed by the strategy
var maxBaseCurrency = null
// Get metadata from when the registration code was created
var level = GetMeta()
// Check conditions corresponding to Meta
if (level == "level1") {
// -1 means no limit
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()
// Check asset value
var acc = exchange.GetAccount()
if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks) {
// Stop executing strategy trading logic
LogStatus(_D(), "level:", level, "Position exceeds registration code limit, strategy trading logic will not execute!")
continue
}
// Other trading logic
// Normal status bar information output
LogStatus(_D(), "level:", level, "Strategy running normally! ticker data:\n", ticker)
}
}
python
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, "Position exceeds registration code limit, strategy trading logic will not execute!")
continue
# Other trading logic
# Normal status bar information output
LogStatus(_D(), "level:", level, "Strategy running normally! ticker data:\n", ticker)
c++
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 executing strategy trading logic
LogStatus(_D(), "level:", level, "Position exceeds registration code limit, strategy trading logic will not execute!");
continue;
}
// Other trading logic
// Normal status bar information output
LogStatus(_D(), "level:", level, "Strategy running normally! ticker data:\n", ticker);
}
}Returns
| Type | Description |
string |
|
Remarks
Application scenario: When you need to impose capital limits on different strategy renters. The Meta value set when generating the registration code cannot exceed 190 characters. The GetMeta() function only supports live trading. If no metadata (Meta) was set when generating the strategy registration code, the GetMeta() function returns null. This function does not work in the backtesting system.
Dial
Used for raw Socket access, supporting tcp, udp, tls, unix protocols. Supports 4 popular communication protocols: mqtt, nats, amqp, kafka. Supports database connections, including: sqlite3, mysql, postgres, clickhouse.
Dial(address)
Dial(address, timeout)
Dial(address, options)Examples
-
Dial function call example:
javascriptfunction main(){ // Dial supports tcp://, udp://, tls://, unix:// protocols, can add a parameter to specify timeout in seconds var client = Dial("tls://www.baidu.com:443") if (client) { // write can append a numeric parameter to specify timeout, returns the number of bytes successfully sent client.write("GET / HTTP/1.1\nConnection: Closed\n\n") while (true) { // read can append a numeric parameter to specify timeout, unit: milliseconds. Returns null indicating error, timeout, or socket closed var buf = client.read() if (!buf) { break } Log(buf) } client.close() } }pythondef 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()c++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(); } } -
Accessing Binance WebSocket market data interface:
javascriptfunction main() { LogStatus("Connecting...") // Access Binance WebSocket interface var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr") if (!client) { Log("Connection failed, exiting") return } while (true) { // read only returns data obtained after calling read var buf = client.read() if (!buf) { break } var table = { type: 'table', title: 'Market Chart', cols: ['Symbol', 'High', 'Low', 'Bid', 'Ask', 'Last 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() }pythonimport json def main(): LogStatus("Connecting...") client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr") if not client: Log("Connection failed, exiting") return while True: buf = client.read() if not buf: break table = { "type" : "table", "title" : "Market Chart", "cols" : ["Symbol", "High", "Low", "Bid", "Ask", "Last 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()c++void main() { LogStatus("Connecting..."); auto client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr"); if(!client.Valid) { Log("Connection failed, exiting"); return; } while(true) { auto buf = client.read(); if(buf == "") { break; } json table = R"({ "type" : "table", "title" : "Market Chart", "cols" : ["Symbol", "High", "Low", "Bid", "Ask", "Last 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(); } -
Access Binance's WebSocket interface and set wss request headers.
javascriptfunction main() { let options = {"headers": {"X-MBX-APIKEY": "your access key"}} let random = `fmz${UnixNano()}` let ts = new Date().getTime() let secretKey = "your secret key" let topic = "com_announcement_en" let payload = `random=${random}&topic=${topic}&recvWindow=30000×tamp=${ts}` let signature = Encode("sha256", "string", "hex", payload, "string", secretKey) let query = `?${payload}&signature=${signature}` Log("query:", query) let conn = Dial(`wss://api.binance.com/sapi/wss${query}`, options) for (var i = 0 ; i < 10 ; i++) { let ret = conn.read() Log(ret) } }pythonimport time def main(): options = {"headers": {"X-MBX-APIKEY": "your access key"}} random = "fmz" + str(UnixNano()) ts = int(time.time() * 1000) secretKey = "your secret key" topic = "com_announcement_en" payload = f"random={random}&topic={topic}&recvWindow=30000×tamp={ts}" signature = Encode("sha256", "string", "hex", payload, "string", secretKey) query = f"?{payload}&signature={signature}" Log("query:", query) conn = Dial(f"wss://api.binance.com/sapi/wss{query}", options) for i in range(10): ret = conn.read() Log(ret)c++// Not supported currently -
Accessing OKX WebSocket market data interface:
javascriptvar ws = null function main(){ var param = { "op": "subscribe", "args": [{ "channel": "tickers", "instId": "BTC-USDT" }] } // When calling the Dial function, specify reconnect=true to set reconnection mode, and specify payload as the message to send upon reconnection. After the WebSocket connection is disconnected, it will automatically reconnect and automatically send the message 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("Sending: ping", "#FF0000") } LogStatus("Current time:", _D()) Sleep(1000) } } } function onexit() { ws.close() Log("Exiting") }pythonimport 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("Sending: ping", "#FF0000") LogStatus("Current time:", _D()) Sleep(1000) def onexit(): ws.close() Log("Exiting")c++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("Sending: ping", "#FF0000"); } LogStatus("Current time:", _D()); Sleep(1000); } } } void onexit() { objWS.close(); Log("Exiting"); } -
Accessing Huobi's WebSocket market data interface:
javascriptvar 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 try { var jsonRet = JSON.parse(ret) if(typeof(jsonRet.ping) == "number") { var strPong = JSON.stringify({"pong" : jsonRet.ping}) ws.write(strPong) Log("Responding to ping, sending 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("Executing ws.close()") }pythonimport 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 try: jsonRet = json.loads(ret) if "ping" in jsonRet and type(jsonRet["ping"]) == int: strPong = json.dumps({"pong" : jsonRet["ping"]}) ws.write(strPong) Log("Responding to ping, sending pong:", strPong, "#FF0000") except Exception as e: Log("e:", e) LogStatus("Current time:", _D()) Sleep(1000) def onexit(): ws.close() Log("Executing ws.close()")c++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 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("Responding to ping, sending pong:", strPong, "#FF0000"); } } catch(exception &e) { Log("e:", e.what()); } LogStatus("Current time:", _D()); Sleep(1000); } } } void onexit() { // ws.close(); Log("Executing ws.close()"); } -
Accessing OKX's WebSocket authentication interface:
javascriptfunction 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.Encode("sha256", "string", "base64", ts + "GET" + "/users/self/verify", "string", pSecretKey) }] } return login } var client_private = null function main() { // Since the read function uses timeout settings, timeout errors need to be filtered, otherwise redundant error output will be generated 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) // Cannot subscribe to private channels immediately after login, 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 and reconnect if (buf == "" && client_private.write(JSON.stringify(posSubscribe)) == 0) { Log("Detected disconnection, closing connection, reconnecting") 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 packet var nowPingTS = new Date().getTime() if (nowPingTS - lastPingTS > 10 * 1000) { client_private.write("ping") lastPingTS = nowPingTS } } } } function onexit() { var ret = client_private.close() Log("Connection closed!", ret) }pythonimport json import time def getLogin(pAccessKey, pSecretKey, pPassphrase): ts = str(time.time()) login = { "op": "login", "args":[{ "apiKey" : pAccessKey, "passphrase" : pPassphrase, "timestamp" : ts, "sign" : exchange.Encode("sha256", "string", "base64", ts + "GET" + "/users/self/verify", "string", 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("Detected disconnection, closing connection, reconnecting") 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("Connection closed!", ret)c++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.Encode("sha256", "string", "base64", ts + "GET" + "/users/self/verify", "string", 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("Detected disconnection, closing connection, reconnecting"); 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("Exiting"); } -
Access CoinEx's WebSocket authentication interface:
javascriptvar conn = null function main() { var accessKey = "your accessKey" var ts = new Date().getTime() var signature = exchange.Encode("sha256", "string", "hex", String(ts), "string", "{{secretkey}}") Log("signature:", signature) var payload = { "id": 1, "method": "server.sign", "params": { "access_id": accessKey, "signed_str": signature, "timestamp": ts, } } Log(`JSON.stringify(payload):`, JSON.stringify(payload)) conn = Dial("wss://socket.coinex.com/v2/futures|compress=gzip&mode=recv&payload=" + JSON.stringify(payload)) if (!conn) { throw "stop" } Log("Dial ... ", conn.read()) // Subscribe to position updates conn.write(JSON.stringify({ "method": "position.subscribe", "params": {"market_list": ["BTCUSDT"]}, "id": 1 })) while (true) { var msg = conn.read() if (msg) { Log("msg:", msg) } } } function onexit() { conn.close() }python// Omittedc++// Omitted -
Example of accessing the MEXC exchange
Websocketinterface, subscribing to thepublic.aggre.deals.v3.api.pbchannel, and usingprotobuf.jsto decode binary data:javascriptlet strPushDataV3ApiWrapper = `syntax = "proto3"; option java_package = "com.mxc.push.common.protobuf"; option optimize_for = SPEED; option java_multiple_files = true; option java_outer_classname = "PushDataV3ApiWrapperProto"; message PublicAggreDealsV3Api { repeated PublicAggreDealsV3ApiItem deals = 1; string eventType = 2; } message PublicAggreDealsV3ApiItem { string price = 1; string quantity = 2; int32 tradeType = 3; int64 time = 4; } message PushDataV3ApiWrapper { string channel = 1; oneof body { PublicAggreDealsV3Api publicAggreDeals = 314; } optional string symbol = 3; optional string symbolId = 4; optional int64 createTime = 5; optional int64 sendTime = 6; }` let code = HttpQuery("https://cdnjs.cloudflare.com/ajax/libs/protobufjs/7.5.3/protobuf.js") let exports = {} let module = { exports } new Function("module", "exports", code)(module, exports) let protobuf = module.exports function main() { const PushDataV3ApiWrapper = protobuf.parse(strPushDataV3ApiWrapper).root.lookupType("PushDataV3ApiWrapper") var payload = { "method": "SUBSCRIPTION", "params": [ "[email protected]@100ms@BTCUSDT" ] } // proxy=socks5://x.x.x.x:xxxx var conn = Dial("wss://wbs-api.mexc.com/ws|payload=" + JSON.stringify(payload)) var data = null while (true) { var ret = conn.read() if (ret) { const uint8arrayData = new Uint8Array(ret) const message = PushDataV3ApiWrapper.decode(uint8arrayData) data = PushDataV3ApiWrapper.toObject(message, { longs: String, enums: String, bytes: String, defaults: true, arrays: true, objects: true }) Log("data:", data) } LogStatus(_D(), data) } }python# You can use the corresponding libraries in Python to implement encoding and decoding.c++// Omitted -
The connection object returned by the Dial function when connecting to a database has 2 unique method functions:
-
exec(sqlString): Used to execute SQL statements, similar to theDBExec()function. -
fd(): Thefd()function returns a handle (e.g., handle variable is handle), which can be used by other threads to reconnect (even if the object created by Dial has already executed theclose()function to close the connection). Pass the handle to theDial()function, e.g.,Dial(handle)to reuse the connection.
The following is an example of using the Dial function to connect to a
sqlite3database.javascriptvar client = null function main() { // client = Dial("sqlite3://:memory:") // Use in-memory database client = Dial("sqlite3://test1.db") // Open/connect to the database file in the docker's directory // Record the handle var sqlite3Handle = client.fd() Log("sqlite3Handle:", sqlite3Handle) // Query tables in the database var ret = client.exec("SELECT name FROM sqlite_master WHERE type='table'") Log(ret) } function onexit() { Log("Executing client.close()") client.close() }python// Not supportedc++// Not supported -
Returns
| Type | Description | ||||||||||||||||||||
object | If timeout occurs, the
For data pushed via WebSocket protocol, if the time interval between
|
Arguments
| Name | Type | Required | Description |
address | string | Yes | Request address. |
timeout | number | No | Timeout period, in seconds. |
options | object | No | Configuration options. |
Remarks
Detailed explanation of the address parameter: After the normal address wss://ws.okx.com:8443/ws/v5/public, use the | symbol as a separator. If the parameter string contains the | character, use || as the separator. The part after it is the function parameter settings, with each parameter connected by the & character.
For example, when setting both ss5 proxy and compression parameters simultaneously, you can write:
Dial("wss://ws.okx.com:8443/ws/v5/public|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv")
| Features supported by the address parameter of the Dial function | Parameter description |
|---|---|
| Parameters related to WebSocket protocol data compression: compress=parameter value | compress is the compression method, the compress parameter can be gzip_raw, gzip, etc. If the gzip method is non-standard gzip, you can use the extended method: gzip_raw |
| Parameters related to WebSocket protocol data compression: mode=parameter value | mode is the compression mode, the mode parameter can be one of three options: dual, send, recv. dual is bidirectional compression, both sending and receiving are compressed data; send is sending compressed data; recv is receiving compressed data and decompressing locally. |
| WebSocket protocol enable compression setting: enableCompression=true | Use enableCompression=false to disable this setting, not enabled by default. |
| Parameters related to WebSocket protocol underlying automatic reconnection: reconnect=parameter value | reconnect indicates whether to enable reconnection, reconnect=true means enabling reconnection. When this parameter is not set, reconnection is disabled by default. |
| Parameters related to WebSocket protocol underlying automatic reconnection: interval=parameter value | interval is the retry time interval in milliseconds. interval=10000 means the retry interval is 10 seconds, when not set the default is 1 second, i.e., interval=1000. |
| Parameters related to WebSocket protocol underlying automatic reconnection: payload=parameter value | payload is the subscription message that needs to be sent when WebSocket reconnects, for example: payload=okok. |
| Parameters related to socks5 proxy: proxy=parameter value | proxy is the ss5 proxy setting, parameter value format: socks5://name:[email protected]:1080, where name is the ss5 server username, pwd is the ss5 server login password, 1080 is the ss5 service port. |
The Dial() function only supports live trading.
When using the Dial function to connect to a database, please refer to the Go language driver project for each database for writing the connection string.
| Supported databases | Driver project | Connection String | Remarks |
|---|---|---|---|
| sqlite3 | github.com/mattn/go-sqlite3 | sqlite3://file:test.db?cache=shared&mode=memory | The sqlite3:// prefix indicates using the sqlite3 database, call example: Dial("sqlite3://test1.db") |
| mysql | github.com/go-sql-driver/mysql | mysql://username:yourpassword@tcp(localhost:3306)/yourdatabase?charset=utf8mb4 | -- |
| postgres | github.com/lib/pq | postgres://user=postgres dbname=yourdatabase sslmode=disable password=yourpassword host=localhost port=5432 | -- |
| clickhouse | github.com/ClickHouse/clickhouse-go | clickhouse://tcp://host:9000?username=username&password=yourpassword&database=youdatabase | -- |
Note that when the payload content set in the address parameter contains the character = or other special characters, it may affect the parsing of the address parameter in the Dial function. For example:
BackPack Exchange WebSocket private interface call example:
javascript
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 ultimately returns base64 encoding, it may contain the character "="
var signature = signEd25519(data)
// payload may contain the character "=" after JSON encoding
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, exiting")
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}}")
}
The following calling method in the code works correctly:
javascript
client = Dial("wss://ws.backpack.exchange")
client.write(JSON.stringify(payload))
If written directly in payload, it will not work properly, for example:
javascript
client = Dial("wss://ws.backpack.exchange|payload=" +
JSON.stringify(payload))
Currently, only JavaScript supports using mqtt, nats, amqp, kafka communication protocols in the Dial function. The following uses JavaScript strategy code as an example to demonstrate usage examples of the four protocols mqtt, nats, amqp, kafka:
javascript
// You need to configure and deploy the proxy servers for each protocol first
// For demonstration purposes, the subscription (read operation) and publishing (write operation) of topic test_topic are both performed in this strategy
var arrConn = []
var arrName = []
function main() {
LogReset(1)
conn_nats = Dial("nats://[email protected]:4222?topic=test_topic")
conn_mqtt = Dial("mqtt://127.0.0.1:1883?topic=test_topic")
conn_amqp = Dial("amqp://q:[email protected]: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("Closing", arrName[i], "connection")
}
}
For detailed documentation, please refer to: Exploring FMZ: Communication Protocol Practice Between Live Trading Strategies
HttpQuery
Send HTTP request.
HttpQuery(url)
HttpQuery(url, options)Examples
-
Example of accessing OKX public market API endpoints.
javascriptfunction 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) }pythonimport 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)c++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); } -
Example of using proxy settings with HttpQuery function.
javascriptfunction main() { // 本次设置代理并发送HTTP请求,无用户名、无密码,此次HTTP请求将通过代理发送 HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/") // 本次设置代理并发送HTTP请求,包含用户名和密码,仅对当前HttpQuery调用生效,后续调用HttpQuery("http://www.baidu.com")将不会使用代理 HttpQuery("socks5://username:[email protected]:8889/http://www.baidu.com/") }python# HttpQuery不支持Python,可以使用Python的urllib2库c++void main() { HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/"); HttpQuery("socks5://username:[email protected]:8889/http://www.baidu.com/"); }
Returns
| Type | Description |
string / object | Returns the response data of the request. If the return value is a |
Arguments
| Name | Type | Required | Description |
url | string | Yes | URL address for the HTTP request. |
options | object | No | HTTP request configuration parameters, can use the following structure:
All fields in this structure are optional, for example, the |
See Also
Remarks
The HttpQuery() function only supports JavaScript and C++ languages. Python language can use the urllib library to send HTTP requests directly. HttpQuery() is mainly used to access exchange interfaces that do not require signatures, such as public interfaces like market data.
In the backtesting system, HttpQuery() can be used to send requests (only GET requests are supported) to obtain data. During backtesting, access to different URLs is limited to a maximum of 20 times, and HttpQuery() access will cache data. When the same URL is accessed for the second time, the HttpQuery() function returns cached data without initiating an actual network request.
HttpQuery_Go
Send HTTP request, asynchronous version of the HttpQuery function.
HttpQuery_Go(url)
HttpQuery_Go(url, options)Examples
Asynchronously access exchange public interface to get aggregated market data.
javascript
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)
}
python
# 不支持
c++
// 不支持Returns
| Type | Description |
object | The |
Arguments
| Name | Type | Required | Description |
url | string | Yes | URL address for the HTTP request. |
options | object | No | HTTP request configuration parameters, can use the following structure:
All fields in this structure are optional, for example, you don't need to set the |
See Also
Remarks
The HttpQuery_Go() function only supports JavaScript language, Python language can use the urllib library to send HTTP requests directly. HttpQuery_Go() is mainly used to access exchange interfaces that do not require signatures, such as public interfaces like market data. The backtesting system does not support the HttpQuery_Go function.
Encode
This function encodes data based on the parameters passed in.
Encode(algo, inputFormat, outputFormat, data)
Encode(algo, inputFormat, outputFormat, data, keyFormat, key)Examples
-
Encode function call example.
javascriptfunction 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 }pythondef 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")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84bac++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 } -
The parameter
algoalso supports the following values: "text.encoder.utf8", "text.decoder.utf8", "text.encoder.gbk", "text.decoder.gbk", for encoding and decoding strings.javascriptfunction 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) }pythondef 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)c++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); }
Returns
| Type | Description |
string | The |
Arguments
| Name | Type | Required | Description |
algo | string | Yes | The parameter The parameter The parameter |
inputFormat | string | Yes | Specifies the data format of the |
outputFormat | string | Yes | Specifies the output data format. The |
data | string | Yes | The parameter |
keyFormat | string | No | Specifies the data format of the |
key | string | No | The parameter When the parameter When the parameter |
Remarks
The Encode() function only supports live trading. If the key and keyFormat parameters are not passed, key encryption is not used.
UnixNano
Get the current Unix timestamp in nanoseconds.
UnixNano()Examples
To get a millisecond timestamp, use the following code:
javascript
function main() {
var time = UnixNano() / 1000000
Log(_N(time, 0))
}
python
def main():
time = UnixNano()
Log(time)
c++
void main() {
auto time = UnixNano();
Log(time);
}Returns
| Type | Description |
number | The |
See Also
Unix
Get the current timestamp in seconds.
Unix()Examples
javascript
function main() {
var t = Unix()
Log(t)
}
python
def main():
t = Unix()
Log(t)
c++
void main() {
auto t = Unix();
Log(t);
}Returns
| Type | Description |
number | Returns timestamp in seconds. |
See Also
GetOS
Get the operating system information of the device where the docker is located.
GetOS()Examples
javascript
function main() {
Log("GetOS:", GetOS())
}
python
def main():
Log("GetOS:", GetOS())
c++
void main() {
Log("GetOS:", GetOS());
}Returns
| Type | Description |
string | Operating system information. |
Remarks
For example, when calling GetOS() function on a docker running on Mac OS operating system, it may return: darwin/amd64, because Apple computers support multiple hardware architectures. Where darwin is the kernel name of the Mac OS system.
MD5
Calculate the MD5 hash value of the parameter data.
MD5(data)Examples
javascript
function main() {
Log("MD5", MD5("hello world"))
}
python
def main():
Log("MD5", MD5("hello world"))
c++
void main() {
Log("MD5", MD5("hello world"));
}Returns
| Type | Description |
string | MD5 hash value. |
Arguments
| Name | Type | Required | Description |
data | string | Yes | The data to be MD5 calculated. |
See Also
Remarks
Calling the MD5("hello world") function returns: 5eb63bbbe01eeed093cb22bb8f5acdc3.
DBExec
Database interface function.
DBExec(sql)Examples
-
Supports in-memory database. For the
DBExecfunction parameters, if the SQL statement starts with:, it operates in the in-memory database without writing to files, which is faster. Suitable for database operations that don't require persistent storage, for example:javascriptfunction 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;")) }pythondef 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;"))c++void main() { string strSql = ":CREATE TABLE TEST_TABLE(\n TS INT PRIMARY KEY NOT NULL,\n HIGH REAL NOT NULL,\n OPEN REAL NOT NULL,\n LOW REAL NOT NULL,\n CLOSE REAL NOT NULL,\n 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;")); } -
Use the
DBExec()function to create a table.javascriptfunction 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) }pythondef 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)c++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); } -
CRUD operations on table records.
javascriptfunction 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)) }pythondef 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))c++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)); }
Returns
| Type | Description |
object | Object containing SQL statement execution results, for example:
|
Arguments
| Name | Type | Required | Description |
sql | string | Yes | SQL statement string. |
See Also
Remarks
-
The function
DBExec()can operate on the live trading database (SQLite database) through passed parameters. -
Implements operations such as insert, delete, query, and update on data in the live trading database, supporting SQLite syntax.
-
System reserved tables in the live trading database:
kvdb,cfg,log,profit,chart. Please do not operate on these tables. -
Currently does not support transactions. Such operations are not recommended as they may cause system conflicts.
-
The
DBExec()function only supports live trading environment.
UUID
Create a UUID.
UUID()Examples
javascript
function main() {
var uuid1 = UUID()
var uuid2 = UUID()
Log(uuid1, uuid2)
}
python
def main():
uuid1 = UUID()
uuid2 = UUID()
Log(uuid1, uuid2)
c++
void main() {
auto uuid1 = UUID();
auto uuid2 = UUID();
Log(uuid1, uuid2);
}Returns
| Type | Description |
string | Returns a 32-character UUID string. |
Remarks
The UUID() function is only supported in live trading environment.
EventLoop
Listens for events and returns when any WebSocket has readable data or when concurrent tasks such as exchange.Go(), HttpQuery_Go(), etc. are completed.
EventLoop()
EventLoop(timeout)Examples
javascript
function main() {
var routine_getTicker = exchange.Go("GetTicker")
var routine_getDepth = exchange.Go("GetDepth")
var routine_getTrades = exchange.Go("GetTrades")
// Sleep(2000), if you use the Sleep statement here, it will cause the subsequent EventLoop function to miss previous events, because after waiting for 2 seconds, the concurrent functions have already received data, and the EventLoop listening mechanism starts afterwards, thus missing these events
// Unless you call EventLoop(-1) at the very first line of code to initialize the EventLoop listening mechanism first, then these events will not be missed
// Log("GetDepth:", routine_getDepth.wait()) If you call the wait function here in advance to retrieve the result of the GetDepth concurrent call, the event of GetDepth function receiving the request result 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("First concurrent task completed:", _D(ts1), ret1)
Log("Second concurrent task completed:", _D(ts2), ret2)
Log("Third concurrent task completed:", _D(ts3), ret3)
Log("GetTicker:", routine_getTicker.wait())
Log("GetDepth:", routine_getDepth.wait())
Log("GetTrades:", routine_getTrades.wait())
}
python
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("First concurrent task completed:", _D(ts1), ret1)
Log("Second concurrent task completed:", _D(ts2), ret2)
Log("Third concurrent task completed:", _D(ts3), ret3)
Log("GetTicker:", routine_getTicker.wait())
Log("GetDepth:", routine_getDepth.wait())
Log("GetTrades:", routine_getTrades.wait())
c++
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("First concurrent task completed:", _D(ts1), ret1);
Log("Second concurrent task completed:", _D(ts2), ret2);
Log("Third concurrent task completed:", _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);
}Returns
| Type | Description |
object | If the returned object is not null, the
|
Arguments
| Name | Type | Required | Description |
timeout | number | No | The parameter |
See Also
Remarks
The event listening mechanism is initialized only when the EventLoop() function is called for the first time in the code. If EventLoop() is called for the first time after event callbacks have occurred, previous events will be missed. The underlying system's encapsulated queue structure caches up to 500 event callbacks. If the EventLoop() function is not called in time during program execution to retrieve events, later event callbacks exceeding the 500 cache limit will be lost.
Calling the EventLoop() function does not affect the underlying system's WebSocket cache queue, nor does it affect the cache of concurrent functions such as exchange.Go(). For these caches, you still need to use their respective methods to retrieve data. Data that has been retrieved before the EventLoop() function returns will not generate return events in the EventLoop() function.
The main purpose of the EventLoop() function is to notify the strategy layer that the underlying system has received new network data, driving the entire strategy through events. When the EventLoop() function returns an event, simply iterate through all data sources, such as WebSocket connections and objects created by exchange.Go(), to attempt to retrieve data.
The EventLoop() function only supports live trading environments.
When called in the main function main(), it listens for events in the main thread. In strategies written in JavaScript, threads created by the threading.Thread() function can call this function within their execution functions to listen for events in the current thread.
__Serve
The __Serve function is used to create HTTP services, TCP services, and WebSocket services (based on HTTP protocol).
__Serve(serveURI, handler)
__Serve(serveURI, handler, ...args)Examples
javascript
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)
}
}
python
# Not supported
c++
// Not supportedReturns
| Type | Description |
string | Returns a string recording the IP address and port of the created service. For example: |
Arguments
| Name | Type | Required | Description |
serveURI | string | Yes | The
|
handler | function | Yes | The The callback function passed in via the |
arg | string / number / bool / object / array / function / any (any type supported by the platform) | No | As the actual arguments for the parameters of the callback function passed in via the
The parameters |
See Also
Remarks
-
This function only supports JavaScript language strategies.
-
The service thread is isolated from the global scope, so it does not support closures or references to external variables, custom functions, etc.; however, all platform API functions can be called.
-
WebSocketservice is implemented based on HTTP protocol. You can set a routing branch in the path and design the implementation code forWebSocketmessage subscription/push. Please refer to the example code in this section.
-
The callback handler function passed in the handler parameter receives a ctx parameter. The ctx parameter is a context object used to get data and write data, with the following methods:
- ctx.proto()
Applies to HTTP/TCP protocol, returns the protocol name when called. For example:HTTP/1.1,tcp. - ctx.host()
Applies to HTTP protocol, returns host information when called: IP address, port. - ctx.path()
Applies to HTTP protocol, returns the request path when called. - ctx.query(key)
Applies to HTTP protocol, returns the value corresponding to the key in the query of the request when called. For example, if the request sent is:http://127.0.0.1:8088?num=123, callingctx.query("num")in the callback handler function passed in thehandlerparameter returns"123". - ctx.rawQuery()
Applies to HTTP protocol, returns the raw query in the request (query of the HTTP request) when called. - ctx.headers()
Applies to HTTP protocol, returns the request header information in the request when called. - ctx.header(key)
Applies to HTTP protocol, returns the value corresponding to a specific key in the specified request header when called. For example, to get theUser-Agentin the headers of the current request:ctx.header("User-Agent"). - ctx.method()
Applies to HTTP protocol, returns the request method when called, such asGET,POST, etc. - ctx.body()
Applies to POST requests of HTTP protocol, returns the body of the request when called. - ctx.setHeader(key, value)
Applies to HTTP protocol, sets the request header information of the response message. - ctx.setStatus(code)
Applies to HTTP protocol, sets the HTTP message status code. Usually the HTTP status code is set at the end of the routing branch, default is 200. - ctx.remoteAddr()
Applies to HTTP/TCP protocol, returns the remote client address and port in the request when called. - ctx.localAddr()
Applies to HTTP/TCP protocol, returns the local service address and port when called. - ctx.upgrade("websocket")
Applies to WebSocket protocol implementation based on HTTP protocol, switches thectxcontext object to WebSocket protocol; returns boolean value (true) on successful switch, boolean value (false) on failure. - ctx.read(timeout_ms)
Applies to WebSocket protocol implementation based on HTTP protocol/TCP protocol, reads data from WebSocket connection or TCP connection. Thereadmethod is not supported in regular HTTP protocol; you can specify the timeout parametertimeout_msin milliseconds. - ctx.write(s)
Applies to HTTP/TCP protocol, used to write string data. You can useJSON.stringify()to encode JSON objects as strings before writing. ForWebSocketprotocol, this method can be used to pass the encoded string to the client.
_G
Persistently save data. This function implements a savable global dictionary feature. The data structure is a key-value pair table, permanently saved in the docker's local database file.
_G()
_G(k)
_G(k, v)Examples
javascript
function main(){
// 设置一个全局变量num,值为1
_G("num", 1)
// 更改一个全局变量num,值为字符串ok
_G("num", "ok")
// 删除全局变量num
_G("num", null)
// 返回全局变量num的值
Log(_G("num"))
// 删除所有全局变量
_G(null)
// 返回实盘ID
var robotId = _G()
}
python
def main():
_G("num", 1)
_G("num", "ok")
_G("num", None)
Log(_G("num"))
_G(None)
robotId = _G()
c++
void main() {
_G("num", 1);
_G("num", "ok");
_G("num", NULL);
Log(_G("num"));
_G(NULL);
// 不支持 auto robotId = _G();
}Returns
| Type | Description |
string / number / bool / object / array / null | The key value data in the persistently saved |
Arguments
| Name | Type | Required | Description |
k | string / null | No | The parameter |
v | string / number / bool / object / array / null | No | The parameter |
See Also
Remarks
Each live trading uses a separate database. When the strategy restarts or the docker stops running, the data saved by the _G() function will persist. If the backtest ends, the data saved by the _G() function in the backtest system will be cleared. When using the _G() function to persistently save data, it should be used reasonably according to the memory and disk space of the hardware device to avoid abuse.
In live trading, when calling the _G() function without passing any parameters, the _G() function returns the Id of the current live trading.
When calling the _G() function, passing null for parameter v means deleting the k-v key-value pair.
When calling the _G() function and only passing parameter k (string type), the _G() function returns the saved key value corresponding to parameter k.
When calling the _G() function and only passing null for parameter k, it means deleting all recorded k-v key-value pairs.
After a k-v key-value pair has been persistently saved, calling the _G() function again with the already persistently saved key name as parameter k and a new key value as parameter v will update the k-v key-value pair.
Taking live trading Id 123456 as an example, the key-value pair data persistently saved using the _G() function is stored in the database file /logs/storage/123456/123456.db3 under the docker directory to which the live trading (i.e., strategy instance program) belongs, and the data is recorded in the kvdb table.
_D
Convert millisecond timestamp or Date object to time string.
_D()
_D(timestamp)
_D(timestamp, fmt)Examples
-
Get and print current time string:
javascriptfunction main(){ var time = _D() Log(time) }pythondef main(): strTime = _D() Log(strTime)c++void main() { auto strTime = _D(); Log(strTime); } -
Timestamp is 1574993606000, convert using code:
javascriptfunction main() { Log(_D(1574993606000)) }pythondef main(): # Running on Beijing time server: 2019-11-29 10:13:26, running this code on a docker on another regional server results in: 2019-11-29 02:13:26 Log(_D(1574993606))c++void main() { Log(_D(1574993606000)); } -
Use parameter
fmtfor formatting. Format strings differ betweenJavaScript,Python, andC++languages. See the following examples for details:javascriptfunction main() { Log(_D(1574993606000, "yyyy--MM--dd hh--mm--ss")) // 2019--11--29 10--13--26 }pythondef main(): # 1574993606 is a second-level timestamp Log(_D(1574993606, "%Y--%m--%d %H--%M--%S")) # 2019--11--29 10--13--26c++void main() { Log(_D(1574993606000, "%Y--%m--%d %H--%M--%S")); // 2019--11--29 10--13--26 }
Returns
| Type | Description |
string | Time string. |
Arguments
| Name | Type | Required | Description |
timestamp | number / object | No | Millisecond timestamp or |
fmt | string | No | Format string. |
See Also
Remarks
Returns current time string when no parameters are passed. When using _D() function in Python strategies, note that the parameter passed should be a second-level timestamp (JavaScript and C++ strategies use millisecond-level timestamps, 1 second equals 1000 milliseconds). When using _D() function in live trading environment to parse timestamps into readable time strings, pay attention to the timezone and time settings of the operating system where the docker is located. The _D() function parses timestamps into readable time strings based on the local time of the docker system.
_N
Format floating-point numbers.
_N()
_N(num)
_N(num, precision)Examples
-
For example,
_N(3.1415, 2)will remove digits beyond two decimal places from3.1415, and the function returns3.14.javascriptfunction main(){ var i = 3.1415 Log(i) var ii = _N(i, 2) Log(ii) }pythondef main(): i = 3.1415 Log(i) ii = _N(i, 2) Log(ii)c++void main() { auto i = 3.1415; Log(i); auto ii = _N(i, 2); Log(ii); } -
To set N digits to the left of the decimal point to 0, you can use negative precision:
javascriptfunction main(){ var i = 1300 Log(i) var ii = _N(i, -3) // 查看日志得知为1000 Log(ii) }pythondef main(): i = 1300 Log(i) ii = _N(i, -3) Log(ii)c++void main() { auto i = 1300; Log(i); auto ii = _N(i, -3); Log(ii); }
Returns
| Type | Description |
number | The formatted floating-point number according to the precision setting. |
Arguments
| Name | Type | Required | Description |
num | number | Yes | The floating-point number to be formatted. |
precision | number | No | The precision setting for formatting. The parameter |
See Also
Remarks
The parameter precision can be a positive or negative integer.
_C
Retry function for interface fault tolerance handling.
_C(pfn)
_C(pfn, ...args)Examples
-
For fault tolerance of functions without parameters:
javascriptfunction main(){ var ticker = _C(exchange.GetTicker) // Adjust the retry interval of _C() function to 2 seconds _CDelay(2000) var depth = _C(exchange.GetDepth) Log(ticker) Log(depth) }pythondef main(): ticker = _C(exchange.GetTicker) _CDelay(2000) depth = _C(exchange.GetDepth) Log(ticker) Log(depth)c++void main() { auto ticker = _C(exchange.GetTicker); _CDelay(2000); auto depth = _C(exchange.GetDepth); Log(ticker); Log(depth); } -
For fault tolerance of functions with parameters:
javascriptfunction main(){ var records = _C(exchange.GetRecords, PERIOD_D1) Log(records) }pythondef main(): records = _C(exchange.GetRecords, PERIOD_D1) Log(records)c++void main() { auto records = _C(exchange.GetRecords, PERIOD_D1); Log(records); } -
Can also be used for fault tolerance handling of custom functions:
javascriptvar test = function(a, b){ var time = new Date().getTime() / 1000 if(time % b == 3){ Log("Condition met!", "#FF0000") return true } Log("Retrying!", "#FF0000") return false } function main(){ var ret = _C(test, 1, 5) Log(ret) }pythonimport time def test(a, b): ts = time.time() if ts % b == 3: Log("Condition met!", "#FF0000") return True Log("Retrying!", "#FF0000") return False def main(): ret = _C(test, 1, 5) Log(ret)c++// C++ does not support this method for custom function fault tolerance
Returns
| Type | Description |
All platform-supported types except false values and null values (any). | The return value when the callback function is executed. |
Arguments
| Name | Type | Required | Description |
pfn | function | Yes | The parameter |
arg | string / number / bool / object / array / function / any (any type supported by the platform) | No | Parameters for the callback function. There may be multiple |
Remarks
The _C() function will continuously call the specified function until it returns successfully (it will retry calling pfn when the function referenced by parameter pfn returns null or false).
For example _C(exchange.GetTicker). The default retry interval is 3 seconds. You can call the _CDelay() function to set the retry interval.
For example _CDelay(1000) means changing the retry interval of the _C() function to 1 second.
The following functions can be (but are not limited to) handled for fault tolerance:
exchange.GetTicker()exchange.GetDepth()exchange.GetTrades()exchange.GetRecords()exchange.GetAccount()exchange.GetOrders()exchange.GetOrder()exchange.GetPositions()
All the above functions can be called through the _C() function to achieve fault tolerance. The _C() function is not limited to fault tolerance for the above functions. The parameter pfn is a function reference, not a function call. Note that you should use _C(exchange.GetTicker) instead of _C(exchange.GetTicker()).
_Cross
Returns the number of periods since array arr1 crossed array arr2.
_Cross(arr1, arr2)Examples
You can simulate a set of data to test the _Cross(Arr1, Arr2) function:
javascript
// 快线指标
var arr1 = [1,2,3,4,5,6,8,8,9]
// 慢线指标
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))
}
python
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))
c++
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));
}Returns
| Type | Description |
number | The number of periods since array |
Arguments
| Name | Type | Required | Description |
arr1 | array | Yes | Array with elements of type |
arr2 | array | Yes | Array with elements of type |
Remarks
When the return value of _Cross() function is positive, it indicates the number of periods since upward crossover; when negative, it indicates the number of periods since downward crossover; when 0, it indicates the current values are equal. For detailed usage instructions: Built-in Function _Cross Analysis and Usage Guide.
JSON.parse
The JSON.parse function is a method of the ECMAScript standard built-in object JSON, used for parsing JSON strings. The FMZ Quant Trading Platform has extended it by adding a safeStr parameter.
JSON.parse(s)
JSON.parse(s, safeStr)Examples
Parse JSON strings containing large numeric values.
javascript
function main() {
let s1 = '{"num": 8754613216564987646512354656874651651358}'
Log("JSON.parse:", JSON.parse(s1)) // JSON.parse: {"num":8.754613216564987e+39}
Log("JSON.parse:", JSON.parse(s1, true)) // JSON.parse: {"num":"8754613216564987646512354656874651651358"}
let s2 = '{"num": 123}'
Log("JSON.parse:", JSON.parse(s2)) // JSON.parse: {"num":123}
Log("JSON.parse:", JSON.parse(s2, true)) // JSON.parse: {"num":123}
}
python
# 可以使用Python的第三方库处理大数值数据。
c++
// 可以使用其它方案处理。Returns
| Type | Description |
object | Returns the parsed |
Arguments
| Name | Type | Required | Description |
s | string | Yes | The |
safeStr | bool | No | When this parameter is set to |
Remarks
The JSON.parse() function can correctly parse JSON strings containing large numeric values. When the safeStr parameter is set to a truthy value, large numeric values will be parsed as string types.
The safeStr parameter also supports being used as a reviver parameter, i.e., a function that transforms the result. This function will be called for each member of the object. Please refer to relevant documentation for details.
Only supported in JavaScript language.
The safeStr parameter feature of the JSON.parse() function is not supported in the backtesting system.
JSON.stringify
The JSON.stringify function is a method of the ECMAScript standard built-in object JSON, used to convert JavaScript values to JSON strings.
JSON.stringify(obj)Examples
Serialize an object to a JSON string and output it.
javascript
function main() {
let s1 = {"num": "8754613216564987646512354656874651651358"}
Log("JSON.stringify:", JSON.stringify(s1))
// JSON.stringify: {"num":"8754613216564987646512354656874651651358"}
// The variable returned by JSON.stringify(s1) is of string type
}
python
// Omitted
c++
// OmittedReturns
| Type | Description |
string | Returns the serialized |
Arguments
| Name | Type | Required | Description |
obj | string / number / bool / object / array / function / any (any type supported by the platform) | Yes | The value to be serialized into a JSON string. |
Remarks
Only supported in JavaScript language.
SetChannelData
Publishes the latest status data to a channel. This function is used for inter-live trading communication, allowing the current live trading instance to broadcast its status data to a channel for other live trading instances to subscribe and retrieve.
SetChannelData(data)Examples
-
Channel Broadcaster Example - Publishing BTC Price Market Data
javascriptfunction main() { var updateId = 0 var robotId = _G() // Get current live trading bot ID while(true) { // Get actual market price var ticker = exchange.GetTicker("BTC_USDT") if (!ticker) { Sleep(5000) continue } // Prepare current channel state data var channelState = { robotId: robotId, updateId: ++updateId, timestamp: Date.now(), symbol: "BTC_USDT", lastPrice: ticker.Last, volume: ticker.Volume, high: ticker.High, low: ticker.Low } // Publish latest state on channel (overwrites old state) SetChannelData(channelState) // Display current channel state LogStatus("Channel Broadcaster [Bot ID: " + robotId + "]\n" + "Update ID: #" + channelState.updateId + "\n" + "Time: " + _D(channelState.timestamp) + "\n" + "Symbol: " + channelState.symbol + "\n" + "Last Price: $" + channelState.lastPrice.toFixed(2) + "\n" + "Volume: " + channelState.volume.toFixed(4) + "\n" + "High: $" + channelState.high.toFixed(2) + "\n" + "Low: $" + channelState.low.toFixed(2)) Sleep(60000) // Update channel state every minute } }pythondef main(): updateId = 0 robotId = _G() # Get current live trading bot ID while True: # Get actual market price ticker = exchange.GetTicker("BTC_USDT") if not ticker: Sleep(5000) continue # Prepare current channel state data channelState = { "robotId": robotId, "updateId": updateId + 1, "timestamp": time.time() * 1000, "symbol": "BTC_USDT", "lastPrice": ticker["Last"], "volume": ticker["Volume"], "high": ticker["High"], "low": ticker["Low"] } updateId += 1 # Publish latest state on channel (overwrites old state) SetChannelData(channelState) # Display current channel state LogStatus("Channel Broadcaster [Bot ID: {}]\n".format(robotId) + "Update ID: #{}\n".format(channelState["updateId"]) + "Time: {}\n".format(_D(channelState["timestamp"])) + "Symbol: {}\n".format(channelState["symbol"]) + "Last Price: ${:.2f}\n".format(channelState["lastPrice"]) + "Volume: {:.4f}\n".format(channelState["volume"]) + "High: ${:.2f}\n".format(channelState["high"]) + "Low: ${:.2f}".format(channelState["low"])) Sleep(60000) # Update channel state every minutec++ -
Cross-platform sending example - Simulating external platform (e.g., TradingView) sending data to FMZ live trading
javascript// This example demonstrates how to use HttpQuery to send HTTP POST requests, simulating external platforms sending data to FMZ live trading // In actual scenarios, external platforms (such as TradingView's Webhook alert URL, third-party trading systems, etc.) would directly call the FMZ API endpoint function main() { let uuid = "6BC42A119B5DBFA2188A8279DA3B5C30" let robotId = 123456 // Target live trading ID (the live trading instance that needs to receive data) let baseUrl = "https://www.fmz.com" while (true) { // Prepare the data to send (can be JSON, text, or other formats) let sendData = { "action": "buy", "symbol": "BTC_USDT", "price": 50000, "timestamp": Date.now() } // Construct HTTP POST request let options = { method: "POST", body: JSON.stringify(sendData) // body can be JSON string, plain text, etc. } let url = `${baseUrl}/api/v1?method=pub&robot=${robotId}&channel=${uuid}` // Send data let ret = HttpQuery(url, options) Log("Simulated external platform sending data, result:", ret) Sleep(10000) // Send every 10 seconds } }python# This example demonstrates how to use HttpQuery to send HTTP POST requests, simulating external platforms sending data to FMZ live trading # In actual scenarios, external platforms (such as TradingView's Webhook alert URL, third-party trading systems, etc.) would directly call the FMZ API endpoint import json def main(): uuid = "6BC42A119B5DBFA2188A8279DA3B5C30" robotId = 123456 # Target live trading ID (the live trading instance that needs to receive data) baseUrl = "https://www.fmz.com" while True: # Prepare the data to send (can be JSON, text, or other formats) sendData = { "action": "buy", "symbol": "BTC_USDT", "price": 50000, "timestamp": time.time() * 1000 } # Construct HTTP POST request options = { "method": "POST", "body": json.dumps(sendData) # body can be JSON string, plain text, etc. } url = "{}/api/v1?method=pub&robot={}&channel={}".format(baseUrl, robotId, uuid) # Send data ret = HttpQuery(url, options) Log("Simulated external platform sending data, result:", ret) Sleep(10000) # Send every 10 secondsc++
Returns
| Type | Description |
null value | The function has no return value. |
Arguments
| Name | Type | Required | Description |
data | object / array / string / number / bool / null value | Yes | The data to be published to the channel, can be any data structure that can be |
See Also
Remarks
The SetChannelData() function is a non-blocking call that returns immediately after invocation without waiting for data transmission to complete.
Each live trading instance has an independent channel, and the channel ID is the live trading ID (which can be obtained through the _G() function).
Only the latest status data is saved on the channel. Each call to SetChannelData() overwrites the previously published data rather than appending historical messages.
Channel data can be broadcast across live trading instances, across dockers, and across servers. Multiple live trading instances can subscribe to the same channel.
The subscriber uses the GetChannelData() function to subscribe to channel data.
Channel communication is applicable to live trading environments; this feature may be limited in the backtesting system.
The byte length of the data parameter data after JSON serialization must not exceed 1024 bytes. Exceeding this limit may cause data publishing to fail. It is recommended to transmit only necessary status information and avoid transmitting overly large data objects.
Published data should be used reasonably according to the memory and network bandwidth of hardware devices. Avoid publishing overly large data objects.
In addition to being subscribed by other live trading instances within the FMZ platform, data published by the SetChannelData() function also supports cross-platform data sending functionality. External platforms (such as TradingView Webhook alerts, third-party trading systems, monitoring software, etc.) can send data to a specified FMZ live trading instance via HTTP POST requests.
Cross-platform data sending method: External systems send data to the FMZ platform API endpoint via HTTP POST request: https://www.fmz.com/api/v1?method=pub&robot={robotId}&channel={uuid}, where robotId is the target live trading ID, and uuid is a 32-character channel identifier. The data to be sent is passed in the request body and can be in JSON format, text, or other formats. Note: A live trading instance must first subscribe to the UUID channel before external systems can successfully send data; the broadcast data will be sent to all live trading instances under the docker where the robotId live trading instance is located, and all live trading instances under the same docker that have subscribed to the UUID channel can receive the data.
GetChannelData
Subscribe to channel data from a specified live trading instance. This function is used for inter-instance communication, allowing retrieval of the latest status data published by other live trading instances via the SetChannelData() function.
GetChannelData(channelId)Examples
-
Channel Subscriber Example - Subscribe to channel data from two live trading bots
javascriptfunction main() { // Two channel IDs to subscribe to (modify according to actual situation) var channelId1 = "632799" // Live trading bot ID for channel 1 var channelId2 = "632800" // Live trading bot ID for channel 2 while(true) { // Subscribe to current state of channel 1 var state1 = GetChannelData(channelId1) // Subscribe to current state of channel 2 var state2 = GetChannelData(channelId2) // Build status display var statusMsg = "Channel Subscriber - Current Subscription Status\n\n" // Display channel 1 status statusMsg += "═══ Channel 1 [" + channelId1 + "] ═══\n" if (state1 !== null) { statusMsg += "Update ID: #" + state1.updateId + "\n" statusMsg += "Time: " + _D(state1.timestamp) + "\n" statusMsg += "Symbol: " + state1.symbol + "\n" statusMsg += "Last Price: $" + state1.lastPrice.toFixed(2) + "\n" statusMsg += "Volume: " + state1.volume.toFixed(4) + "\n" } else { statusMsg += "Status: Waiting... (first call returns null)\n" } statusMsg += "\n" // Display channel 2 status statusMsg += "═══ Channel 2 [" + channelId2 + "] ═══\n" if (state2 !== null) { statusMsg += "Update ID: #" + state2.updateId + "\n" statusMsg += "Time: " + _D(state2.timestamp) + "\n" statusMsg += "Symbol: " + state2.symbol + "\n" statusMsg += "Last Price: $" + state2.lastPrice.toFixed(2) + "\n" statusMsg += "Volume: " + state2.volume.toFixed(4) + "\n" } else { statusMsg += "Status: Waiting... (first call returns null)\n" } LogStatus(statusMsg) Sleep(5000) // Subscribe to channels every 5 seconds } }pythondef main(): # Two channel IDs to subscribe to (modify according to actual situation) channelId1 = "632799" # Live trading bot ID for channel 1 channelId2 = "632800" # Live trading bot ID for channel 2 while True: # Subscribe to current state of channel 1 state1 = GetChannelData(channelId1) # Subscribe to current state of channel 2 state2 = GetChannelData(channelId2) # Build status display statusMsg = "Channel Subscriber - Current Subscription Status\n\n" # Display channel 1 status statusMsg += "═══ Channel 1 [{}] ═══\n".format(channelId1) if state1 is not None: statusMsg += "Update ID: #{}\n".format(state1["updateId"]) statusMsg += "Time: {}\n".format(_D(state1["timestamp"])) statusMsg += "Symbol: {}\n".format(state1["symbol"]) statusMsg += "Last Price: ${:.2f}\n".format(state1["lastPrice"]) statusMsg += "Volume: {:.4f}\n".format(state1["volume"]) else: statusMsg += "Status: Waiting... (first call returns None)\n" statusMsg += "\n" # Display channel 2 status statusMsg += "═══ Channel 2 [{}] ═══\n".format(channelId2) if state2 is not None: statusMsg += "Update ID: #{}\n".format(state2["updateId"]) statusMsg += "Time: {}\n".format(_D(state2["timestamp"])) statusMsg += "Symbol: {}\n".format(state2["symbol"]) statusMsg += "Last Price: ${:.2f}\n".format(state2["lastPrice"]) statusMsg += "Volume: {:.4f}\n".format(state2["volume"]) else: statusMsg += "Status: Waiting... (first call returns None)\n" LogStatus(statusMsg) Sleep(5000) # Subscribe to channels every 5 secondsc++ -
Cross-platform subscription example - Subscribe to data sent from external systems using UUID
javascriptfunction main() { // Use 32-bit UUID as channel identifier let uuid = "6BC42A119B5DBFA2188A8279DA3B5C30" while (true) { // Subscribe to data from UUID channel let data = GetChannelData(uuid) if (data !== null) { Log("Received cross-platform data:", data) } else { Log("Waiting for data... (first call returns null)") } Sleep(10000) // Check every 10 seconds } }pythondef main(): # Use 32-bit UUID as channel identifier uuid = "6BC42A119B5DBFA2188A8279DA3B5C30" while True: # Subscribe to data from UUID channel data = GetChannelData(uuid) if data is not None: Log("Received cross-platform data:", data) else: Log("Waiting for data... (first call returns None)") Sleep(10000) # Check every 10 secondsc++
Returns
| Type | Description |
object / array / string / number / bool / null value | Returns the latest status data from the subscribed channel. The first call returns |
Arguments
| Name | Type | Required | Description |
channelId | string / number | Yes | Channel identifier, supports two types:
|
See Also
Remarks
The GetChannelData() function is a non-blocking call that returns immediately without waiting for data reception to complete.
The first call to the GetChannelData() function will return null, requiring retries to wait for channel data synchronization to complete.
Each call retrieves the latest status data on the channel, not a historical message queue.
A live trading instance can subscribe to channels from multiple different live trading instances simultaneously by calling GetChannelData() multiple times with different live trading IDs.
The current live trading instance can also subscribe to its own channel, meaning the robotId parameter can be the current live trading ID.
Channel data can be transmitted across live trading instances, across dockers, and across servers.
The broadcasting side uses the SetChannelData() function to publish channel data.
Channel communication is designed for live trading environments; this feature may be limited in the backtesting system.
The GetChannelData() function supports cross-platform subscription functionality. When using a 32-bit UUID as the channel identifier, it can receive data sent from external systems outside the FMZ platform via HTTP API. External systems need to specify the live trading ID and UUID to send data. All live trading instances under the same docker can subscribe to data from that UUID channel, while live trading instances under different dockers cannot subscribe.
Log
Log
The Log() function is used to output logs.
Log(...msgs)Examples
-
Multiple
msgparameters can be passed:javascriptfunction main() { Log("msg1", "msg2", "msg3") }pythondef main(): Log("msg1", "msg2", "msg3")c++void main() { Log("msg1", "msg2", "msg3"); } -
Supports setting the color of output messages. If using both color settings and message push functionality, set the color first, then use the
@character at the end to set the push.javascriptfunction main() { Log("Hello FMZ Quant !@") Sleep(1000 * 5) // Add #ff0000 in the string, the printed log will be displayed in red, and the message will be pushed Log("Hello, #ff0000@") }pythondef main(): Log("Hello FMZ Quant !@") Sleep(1000 * 5) Log("Hello, #ff0000@")c++void main() { Log("Hello FMZ Quant !@"); Sleep(1000 * 5); Log("Hello, #ff0000@"); } -
The
Log()function supports printingbase64encoded images, starting with`and ending with`, for example:javascriptfunction main() { Log("`data:image/png;base64,AAAA`") }pythondef main(): Log("`data:image/png;base64,AAAA`")c++void main() { Log("`data:image/png;base64,AAAA`"); } -
The
Log()function supports directly printingPython'smatplotlib.pyplotobjects. As long as the object contains asavefigmethod, it can be printed directly using theLogfunction, for example:pythonimport matplotlib.pyplot as plt def main(): plt.plot([3,6,2,4,7,1]) Log(plt) -
The
Log()function supports language switching. The text output by theLog()function will automatically switch to the corresponding language based on the language settings on the platform page, for example:javascriptfunction main() { Log("[trans]中文|abc[/trans]") }pythondef main(): Log("[trans]中文|abc[/trans]")c++void main() { Log("[trans]中文|abc[/trans]"); }
Arguments
| Name | Type | Required | Description |
msg | string / number / bool / object / array / any (any type supported by the platform) | No | The parameter |
See Also
Remarks
The Log() function outputs a log message in the log area of the live trading or backtesting system. During live trading, logs are saved in the live trading database. When the content output by the Log() function ends with the @ character, the log will enter the message push queue and be pushed to the email address, WebHook URL, etc. configured in the Push Settings of the current FMZ Quant Trading platform account. The Debug Tool and backtesting system do not support message pushing. Message pushing has frequency limits. The specific limit rules are as follows: within a 20-second cycle of a live trading, only the last push message will be retained and pushed, while other messages will be filtered and not pushed (push logs output through the Log function will still be printed and displayed normally in the log area).
When the content output by the Log() function ends with the & character, the log will be marked as a private log. When the live trading is publicly displayed, this log will be hidden from other users, but will not be hidden from the live trading owner's account perspective. This can be used to record sensitive information such as API keys, account balances, etc. For example: Log("Private information", "&").
Regarding WebHook pushing, you can use a service program written in Golang:
golang
package main
import (
"fmt"
"net/http"
)
func Handle (w http.ResponseWriter, r *http.Request) {
defer func() {
fmt.Println("req:", *r)
}()
}
func main () {
fmt.Println("listen http://localhost:9090")
http.HandleFunc("/data", Handle)
http.ListenAndServe(":9090", nil)
}
Set the WebHook in Push Settings: http://XXX.XX.XXX.XX:9090/data?data=Hello_FMZ. After running the compiled Golang service program, start the live trading strategy. The following is a strategy written in JavaScript. When the strategy runs, it executes the Log() function and pushes a message:
javascript
function main() {
Log("msg", "@")
}
After the service program written in Golang receives the push, the service program prints the information:
log
listen http://localhost:9090
req: {GET /data?data=Hello_FMZ HTTP/1.1 1 1
map[User-Agent:[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/xx.x.xxxx.xxx
Safari/537.36] Accept-Encoding:[gzip]] {} <nil> 0 [] false
1XX.XX.X.XX:9090 map[] map[] <nil> map[] XXX.XX.XXX.XX:4xxx2
/data?data=Hello_FMZ <nil> <nil> <nil> 0xc420056300
LogProfit
Record profit/loss values, print the profit/loss figures and draw the equity curve based on the profit/loss values.
LogProfit(profit)
LogProfit(profit, ...args)Examples
If the LogProfit function ends with the character &, it will not write the log to the database, but only update the profit chart. Using the & parameter can avoid generating a large number of logs from frequent profit recording, keeping the logs concise. For example:
javascript
function main() {
// Print 30 points on the profit chart
for(var i = 0; i < 30; i++) {
LogProfit(i, '&')
Sleep(500)
}
}
python
def main():
for i in range(30):
LogProfit(i, '&')
Sleep(500)
c++
void main() {
for(int i = 0; i < 30; i++) {
LogProfit(i, '&');
Sleep(500);
}
}Arguments
| Name | Type | Required | Description |
profit | number | Yes | The parameter |
arg | string / number / bool / object / array / any (any type supported by the platform) | No | Extended parameters that can output additional information to this profit log entry. Multiple |
See Also
LogProfitReset
Clear all profit logs and profit chart data.
LogProfitReset()
LogProfitReset(remain)Examples
javascript
function main() {
// 在收益图表上打印30个点,然后重置,只保留最后10个点
for(var i = 0; i < 30; i++) {
LogProfit(i)
Sleep(500)
}
LogProfitReset(10)
}
python
def main():
for i in range(30):
LogProfit(i)
Sleep(500)
LogProfitReset(10)
c++
void main() {
for(int i = 0; i < 30; i++) {
LogProfit(i);
Sleep(500);
}
LogProfitReset(10);
}Arguments
| Name | Type | Required | Description |
remain | number | No | The |
See Also
LogStatus
Output information in the status bar of the backtesting system or live trading page.
LogStatus(...msgs)Examples
-
Supports setting the color of output content:
javascriptfunction main() { LogStatus('This is a normal status message') LogStatus('This is a red font status message#ff0000') LogStatus('This is a multi-line status message\nI am the second line') }pythondef main(): LogStatus('This is a normal status message') LogStatus('This is a red font status message#ff0000') LogStatus('This is a multi-line status message\nI am the second line')c++void main() { LogStatus("This is a normal status message"); LogStatus("This is a red font status message#ff0000"); LogStatus("This is a multi-line status message\nI am the second line"); } -
Status bar data output example:
javascriptfunction main() { var table = {type: 'table', title: 'Position Info', cols: ['Column 1', 'Column 2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]} // After JSON serialization, add ` characters on both sides to be treated as complex message format (currently supports tables) LogStatus('`' + JSON.stringify(table) + '`') // Table information can also be displayed in multiple lines LogStatus('First line message\n`' + JSON.stringify(table) + '`\nThird line message') // Supports displaying multiple tables simultaneously, will be displayed as TABs in a group LogStatus('`' + JSON.stringify([table, table]) + '`') // You can also construct buttons in the table, the strategy receives the cmd attribute content through GetCommand var table = { type: 'table', title: 'Position Operation', cols: ['Column 1', 'Column 2', 'Action'], rows: [ ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'Close All'}] ] } LogStatus('`' + JSON.stringify(table) + '`') // Or construct a standalone button LogStatus('`' + JSON.stringify({'type':'button', 'cmd': 'coverAll', 'name': 'Close All'}) + '`') // You can customize button styles (Bootstrap button attributes) LogStatus('`' + JSON.stringify({'type':'button', 'class': 'btn btn-xs btn-danger', 'cmd': 'coverAll', 'name': 'Close All'}) + '`') }pythonimport json def main(): table = {"type": "table", "title": "Position Info", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]} LogStatus('`' + json.dumps(table) + '`') LogStatus('First line message\n`' + json.dumps(table) + '`\nThird line message') LogStatus('`' + json.dumps([table, table]) + '`') table = { "type" : "table", "title" : "Position Operation", "cols" : ["Column 1", "Column 2", "Action"], "rows" : [ ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close All"}] ] } LogStatus('`' + json.dumps(table) + '`') LogStatus('`' + json.dumps({"type": "button", "cmd": "coverAll", "name": "Close All"}) + '`') LogStatus('`' + json.dumps({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "Close All"}) + '`')c++void main() { json table = R"({"type": "table", "title": "Position Info", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]})"_json; LogStatus("`" + table.dump() + "`"); LogStatus("First line message\n`" + table.dump() + "`\nThird line message"); json arr = R"([])"_json; arr.push_back(table); arr.push_back(table); LogStatus("`" + arr.dump() + "`"); table = R"({ "type" : "table", "title" : "Position Operation", "cols" : ["Column 1", "Column 2", "Action"], "rows" : [ ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close All"}] ] })"_json; LogStatus("`" + table.dump() + "`"); LogStatus("`" + R"({"type": "button", "cmd": "coverAll", "name": "Close All"})"_json.dump() + "`"); LogStatus("`" + R"({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "Close All"})"_json.dump() + "`"); } -
Support for designing button controls in the status bar (legacy button structure):
javascriptfunction main() { var table = { type: "table", title: "Status Bar Button Styles", cols: ["Default", "Primary", "Success", "Info", "Warning", "Danger"], rows: [ [ {"type":"button", "class": "btn btn-xs btn-default", "name": "Default"}, {"type":"button", "class": "btn btn-xs btn-primary", "name": "Primary"}, {"type":"button", "class": "btn btn-xs btn-success", "name": "Success"}, {"type":"button", "class": "btn btn-xs btn-info", "name": "Info"}, {"type":"button", "class": "btn btn-xs btn-warning", "name": "Warning"}, {"type":"button", "class": "btn btn-xs btn-danger", "name": "Danger"} ] ] } LogStatus("`" + JSON.stringify(table) + "`") }pythonimport json def main(): table = { "type": "table", "title": "Status Bar Button Styles", "cols": ["Default", "Primary", "Success", "Info", "Warning", "Danger"], "rows": [ [ {"type":"button", "class": "btn btn-xs btn-default", "name": "Default"}, {"type":"button", "class": "btn btn-xs btn-primary", "name": "Primary"}, {"type":"button", "class": "btn btn-xs btn-success", "name": "Success"}, {"type":"button", "class": "btn btn-xs btn-info", "name": "Info"}, {"type":"button", "class": "btn btn-xs btn-warning", "name": "Warning"}, {"type":"button", "class": "btn btn-xs btn-danger", "name": "Danger"} ] ] } LogStatus("`" + json.dumps(table) + "`")c++void main() { json table = R"({ "type": "table", "title": "Status Bar Button Styles", "cols": ["Default", "Primary", "Success", "Info", "Warning", "Danger"], "rows": [ [ {"type":"button", "class": "btn btn-xs btn-default", "name": "Default"}, {"type":"button", "class": "btn btn-xs btn-primary", "name": "Primary"}, {"type":"button", "class": "btn btn-xs btn-success", "name": "Success"}, {"type":"button", "class": "btn btn-xs btn-info", "name": "Info"}, {"type":"button", "class": "btn btn-xs btn-warning", "name": "Warning"}, {"type":"button", "class": "btn btn-xs btn-danger", "name": "Danger"} ] ] })"_json; LogStatus("`" + table.dump() + "`"); } -
Set status bar button disable and description features (legacy button structure):
javascriptfunction main() { var table = { type: "table", title: "Status Bar Button Disable and Description Test", cols: ["Column 1", "Column 2", "Column 3"], rows: [] } var button1 = {"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"} var button2 = {"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": true} var button3 = {"type": "button", "name": "Button 3", "cmd": "button3", "description": "This is the third button, set to enabled", "disabled": false} table.rows.push([button1, button2, button3]) LogStatus("`" + JSON.stringify(table) + "`") }pythonimport json def main(): table = { "type": "table", "title": "Status Bar Button Disable and Description Test", "cols": ["Column 1", "Column 2", "Column 3"], "rows": [] } button1 = {"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"} button2 = {"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": True} button3 = {"type": "button", "name": "Button 3", "cmd": "button3", "description": "This is the third button, set to enabled", "disabled": False} table["rows"].append([button1, button2, button3]) LogStatus("`" + json.dumps(table) + "`")c++void main() { json table = R"({ "type": "table", "title": "Status Bar Button Disable and Description Test", "cols": ["Column 1", "Column 2", "Column 3"], "rows": [] })"_json; json button1 = R"({"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"})"_json; json button2 = R"({"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": true})"_json; json button3 = R"({"type": "button", "name": "Button 3", "cmd": "button3", "description": "This is the third button, set to enabled", "disabled": false})"_json; json arr = R"([])"_json; arr.push_back(button1); arr.push_back(button2); arr.push_back(button3); table["rows"].push_back(arr); LogStatus("`" + table.dump() + "`"); } -
Combined with the
GetCommand()function to construct status bar button interaction functionality (legacy button structure):javascriptfunction test1() { Log("Calling custom function") } function main() { while (true) { var table = { type: 'table', title: 'Operation', cols: ['Column 1', 'Column 2', 'Action'], rows: [ ['a', '1', { 'type': 'button', 'cmd': "CoverAll", 'name': 'Close All' }], ['b', '1', { 'type': 'button', 'cmd': 10, 'name': 'Send Number' }], ['c', '1', { 'type': 'button', 'cmd': _D(), 'name': 'Call Function' }], ['d', '1', { 'type': 'button', 'cmd': 'test1', 'name': 'Call Custom Function' }] ] } LogStatus(_D(), "\n", '`' + JSON.stringify(table) + '`') var str_cmd = GetCommand() if (str_cmd) { Log("Received interaction data str_cmd:", "Type:", typeof(str_cmd), "Value:", str_cmd) if(str_cmd == "test1") { test1() } } Sleep(500) } }pythonimport json def test1(): Log("Calling custom function") def main(): while True: table = { "type": "table", "title": "Operation", "cols": ["Column 1", "Column 2", "Action"], "rows": [ ["a", "1", { "type": "button", "cmd": "CoverAll", "name": "Close All" }], ["b", "1", { "type": "button", "cmd": 10, "name": "Send Number" }], ["c", "1", { "type": "button", "cmd": _D(), "name": "Call Function" }], ["d", "1", { "type": "button", "cmd": "test1", "name": "Call Custom Function" }] ] } LogStatus(_D(), "\n", "`" + json.dumps(table) + "`") str_cmd = GetCommand() if str_cmd: Log("Received interaction data str_cmd", "Type:", type(str_cmd), "Value:", str_cmd) if str_cmd == "test1": test1() Sleep(500)c++void test1() { Log("Calling custom function"); } void main() { while(true) { json table = R"({ "type": "table", "title": "Operation", "cols": ["Column 1", "Column 2", "Action"], "rows": [ ["a", "1", { "type": "button", "cmd": "CoverAll", "name": "Close All" }], ["b", "1", { "type": "button", "cmd": 10, "name": "Send Number" }], ["c", "1", { "type": "button", "cmd": "", "name": "Call Function" }], ["d", "1", { "type": "button", "cmd": "test1", "name": "Call Custom Function" }] ] })"_json; table["rows"][2][2]["cmd"] = _D(); LogStatus(_D(), "\n", "`" + table.dump() + "`"); auto str_cmd = GetCommand(); if(str_cmd != "") { Log("Received interaction data str_cmd", "Type:", typeid(str_cmd).name(), "Value:", str_cmd); if(str_cmd == "test1") { test1(); } } Sleep(500); } } -
When constructing status bar buttons for interaction, data input is also supported. The interaction command is ultimately captured by the
GetCommand()function.Add an
inputfield to the data structure of the button control in the status bar (legacy button structure). For example, add"input": {"name": "Quantity", "type": "number", "defValue": 1}to{"type": "button", "cmd": "open", "name": "Open"}. This allows the button to pop up a dialog with an input box control when clicked (the default value in the input box is 1, as set bydefValue). You can enter data and send it along with the button command. For example, when running the following test code, clicking the "Open" button will pop up a dialog with an input box. After entering 111 in the input box and clicking "OK", theGetCommand()function will capture the message:open:111.javascriptfunction main() { var tbl = { type: "table", title: "Operation", cols: ["Column 1", "Column 2"], rows: [ ["Open Position", {"type": "button", "cmd": "open", "name": "Open", "input": {"name": "Quantity", "type": "number", "defValue": 1}}], ["Close Position", {"type": "button", "cmd": "coverAll", "name": "Close All"}] ] } LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`") while (true) { var cmd = GetCommand() if (cmd) { Log("cmd:", cmd) } Sleep(1000) } }pythonimport json def main(): tbl = { "type": "table", "title": "Operation", "cols": ["Column 1", "Column 2"], "rows": [ ["Open Position", {"type": "button", "cmd": "open", "name": "Open", "input": {"name": "Quantity", "type": "number", "defValue": 1}}], ["Close Position", {"type": "button", "cmd": "coverAll", "name": "Close All"}] ] } LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`") while True: cmd = GetCommand() if cmd: Log("cmd:", cmd) Sleep(1000)c++void main() { json tbl = R"({ "type": "table", "title": "Operation", "cols": ["Column 1", "Column 2"], "rows": [ ["Open Position", {"type": "button", "cmd": "open", "name": "Open", "input": {"name": "Quantity", "type": "number", "defValue": 1}}], ["Close Position", {"type": "button", "cmd": "coverAll", "name": "Close All"}] ] })"_json; LogStatus(_D(), "\n", "`" + tbl.dump() + "`"); while(true) { auto cmd = GetCommand(); if(cmd != "") { Log("cmd:", cmd); } Sleep(1000); } } -
Supports group button controls (legacy button structure), with functionality identical to status bar buttons with input data support (configured using the "input" field). Interactive commands are ultimately captured by the
GetCommand()function. The difference is that it uses the"group"field for configuration. When clicking the button triggers an interaction, the dialog box that pops up on the page contains a group of configured input controls, allowing you to input a set of data at once.Regarding the
"group"field in status bar button controls and group button control structures, note the following:- The
typeattribute in group only supports the following 4 types, and thedefValueattribute is the default value.
"selected": Dropdown control, use the|symbol to separate each option in the dropdown.
"number": Numeric input box control.
"string": String input box control.
"boolean": Checkbox control, checked is boolean true, unchecked is boolean false. - Interactive input controls support dependency settings:
For example, in the following example:"name": "tradePrice@orderType==1"setting, this makes the trade price (tradePrice) input control only available when the order type (orderType) dropdown control is set to limit order. - Interactive input control names support bilingual settings:
For example, in the following example: "description": "下单方式|order type" setting, use the|symbol to separate Chinese and English descriptions. - Although the
nameanddescriptionfields in group have the same field names as those in the button structure, their definitions are different.
Thenamein group also has a different definition from thenamein input. - After a group button control is triggered, the format of the sent interactive content is: the button's cmd field value, and group field related data. For example, when testing the following example, the content output by the
Log("cmd:", cmd)statement:
cmd: open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}, which is the content returned by theGetCommand()function when an interactive operation occurs:open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}. - The
typeattribute of button controls only supports:"button":
Button controls that support input data, i.e., controls with theinputattribute set, thetypeattribute in theinputfield configuration supports multiple control types.
Refer to the following example:
javascriptfunction main() { var tbl = { type: "table", title: "Group Button Control Demo", cols: ["Operation"], rows: [] } // Create group button control structure var groupBtn = { type: "button", cmd: "open", name: "Open", group: [ {"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "市价单|挂单"}, {"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100}, {"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100}, {"name": "boolean", "description": "是/否|boolean", "type": "boolean", "defValue": true} ] } // Test button 1 var testBtn1 = {"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"} var testBtn2 = {"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button", "input": {"name": "Quantity", "type": "number", "defValue": 1}} // Add groupBtn to tbl tbl.rows.push([groupBtn]) // Supports setting multiple buttons in a single cell of the status bar table, i.e., the data in a cell is an array of button structures: [testBtn1, testBtn2] tbl.rows.push([[testBtn1, testBtn2]]) while (true) { LogStatus("`" + JSON.stringify(tbl) + "`", "\n", "Group button controls can be set directly on the status bar in addition to status bar tables:", "`" + JSON.stringify(groupBtn) + "`") var cmd = GetCommand() if (cmd) { Log("cmd:", cmd) } Sleep(5000) } }pythonimport json def main(): tbl = { "type": "table", "title": "Group Button Control Demo", "cols": ["Operation"], "rows": [] } groupBtn = { "type": "button", "cmd": "open", "name": "Open", "group": [ {"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "市价单|挂单"}, {"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100}, {"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100}, {"name": "boolean", "description": "是/否|boolean", "type": "boolean", "defValue": True} ] } testBtn1 = {"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"} testBtn2 = {"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button", "input": {"name": "Quantity", "type": "number", "defValue": 1}} tbl["rows"].append([groupBtn]) tbl["rows"].append([[testBtn1, testBtn2]]) while True: LogStatus("`" + json.dumps(tbl) + "`", "\n", "Group button controls can be set directly on the status bar in addition to status bar tables:", "`" + json.dumps(groupBtn) + "`") cmd = GetCommand() if cmd: Log("cmd:", cmd) Sleep(5000)c++void main() { json tbl = R"({ "type": "table", "title": "Group Button Control Demo", "cols": ["Operation"], "rows": [] })"_json; json groupBtn = R"({ "type": "button", "name": "Open", "cmd": "open", "group": [ {"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "市价单|挂单"}, {"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100}, {"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100}, {"name": "boolean", "description": "是/否|boolean", "type": "boolean", "defValue": true} ]})"_json; json testBtn1 = R"({"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"})"_json; json testBtn2 = R"({"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button", "input": {"name": "Quantity", "type": "number", "defValue": 1}})"_json; tbl["rows"].push_back({groupBtn}); tbl["rows"].push_back({{testBtn1, testBtn2}}); while(true) { LogStatus("`" + tbl.dump() + "`", "\n", "Group button controls can be set directly on the status bar in addition to status bar tables:", "`" + groupBtn.dump() + "`"); auto cmd = GetCommand(); if(cmd != "") { Log("cmd:", cmd); } Sleep(5000); } } - The
-
When the status bar group button control (implemented by setting the
groupfield) and the status bar button control (implemented by setting theinputfield) are clicked to trigger interaction (legacy button structure), the dropdown control in the dialog box that pops up on the page also supports multi-select. The following example demonstrates how to design a dropdown control with multi-select options:javascriptfunction main() { // The dropdown control in the page triggered by the status bar button control (implemented by setting the input field) testBtn1 button uses the options field to set options and the defValue field to set the default option. This differs from other examples in this chapter that directly use defValue to set options. var testBtn1 = { type: "button", name: "testBtn1", cmd: "cmdTestBtn1", input: {name: "testBtn1ComboBox", type: "selected", options: ["A", "B"], defValue: 1} } /* The dropdown control in the page triggered by the status bar button control (implemented by setting the input field) testBtn2 button uses the options field to set options. The options in the options field not only support strings, but also support using the ```{text: "description", value: "value"}``` structure. Use the defValue field to set the default option, which can be multi-select (implemented through an array structure). Multi-select requires setting the additional field multiple to a truthy value (true). */ var testBtn2 = { type: "button", name: "testBtn2", cmd: "cmdTestBtn2", input: { name: "testBtn2MultiComboBox", type: "selected", description: "Implement multi-select dropdown", options: [{text: "Option A", value: "A"}, {text: "Option B", value: "B"}, {text: "Option C", value: "C"}], defValue: ["A", "C"], multiple: true } } // The dropdown control in the page triggered by the status bar group button control (implemented by setting the group field) testBtn3 button uses the options field to set options, and also supports directly using defValue to set options. var testBtn3 = { type: "button", name: "testBtn3", cmd: "cmdTestBtn3", group: [ {name: "comboBox1", label: "labelComboBox1", description: "Dropdown 1", type: "selected", defValue: 1, options: ["A", "B"]}, {name: "comboBox2", label: "labelComboBox2", description: "Dropdown 2", type: "selected", defValue: "A|B"}, {name: "comboBox3", label: "labelComboBox3", description: "Dropdown 3", type: "selected", defValue: [0, 2], multiple: true, options: ["A", "B", "C"]}, { name: "comboBox4", label: "labelComboBox4", description: "Dropdown 4", type: "selected", defValue: ["A", "C"], multiple: true, options: [{text: "Option A", value: "A"}, {text: "Option B", value: "B"}, {text: "Option C", value: "C"}, {text: "Option D", value: "D"}] } ] } while (true) { LogStatus("`" + JSON.stringify(testBtn1) + "`\n", "`" + JSON.stringify(testBtn2) + "`\n", "`" + JSON.stringify(testBtn3) + "`\n") var cmd = GetCommand() if (cmd) { Log(cmd) } Sleep(5000) } }pythonimport json def main(): testBtn1 = { "type": "button", "name": "testBtn1", "cmd": "cmdTestBtn1", "input": {"name": "testBtn1ComboBox", "type": "selected", "options": ["A", "B"], "defValue": 1} } testBtn2 = { "type": "button", "name": "testBtn2", "cmd": "cmdTestBtn2", "input": { "name": "testBtn2MultiComboBox", "type": "selected", "description": "Implement multi-select dropdown", "options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}], "defValue": ["A", "C"], "multiple": True } } testBtn3 = { "type": "button", "name": "testBtn3", "cmd": "cmdTestBtn3", "group": [ {"name": "comboBox1", "label": "labelComboBox1", "description": "Dropdown 1", "type": "selected", "defValue": 1, "options": ["A", "B"]}, {"name": "comboBox2", "label": "labelComboBox2", "description": "Dropdown 2", "type": "selected", "defValue": "A|B"}, {"name": "comboBox3", "label": "labelComboBox3", "description": "Dropdown 3", "type": "selected", "defValue": [0, 2], "multiple": True, "options": ["A", "B", "C"]}, { "name": "comboBox4", "label": "labelComboBox4", "description": "Dropdown 4", "type": "selected", "defValue": ["A", "C"], "multiple": True, "options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}, {"text": "Option D", "value": "D"}] } ] } while True: LogStatus("`" + json.dumps(testBtn1) + "`\n", "`" + json.dumps(testBtn2) + "`\n", "`" + json.dumps(testBtn3) + "`\n") cmd = GetCommand() if cmd: Log(cmd) Sleep(5000)c++void main() { json testBtn1 = R"({ "type": "button", "name": "testBtn1", "cmd": "cmdTestBtn1", "input": {"name": "testBtn1ComboBox", "type": "selected", "options": ["A", "B"], "defValue": 1} })"_json; json testBtn2 = R"({ "type": "button", "name": "testBtn2", "cmd": "cmdTestBtn2", "input": { "name": "testBtn2MultiComboBox", "type": "selected", "description": "Implement multi-select dropdown", "options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}], "defValue": ["A", "C"], "multiple": true } })"_json; json testBtn3 = R"({ "type": "button", "name": "testBtn3", "cmd": "cmdTestBtn3", "group": [ {"name": "comboBox1", "label": "labelComboBox1", "description": "Dropdown 1", "type": "selected", "defValue": 1, "options": ["A", "B"]}, {"name": "comboBox2", "label": "labelComboBox2", "description": "Dropdown 2", "type": "selected", "defValue": "A|B"}, {"name": "comboBox3", "label": "labelComboBox3", "description": "Dropdown 3", "type": "selected", "defValue": [0, 2], "multiple": true, "options": ["A", "B", "C"]}, { "name": "comboBox4", "label": "labelComboBox4", "description": "Dropdown 4", "type": "selected", "defValue": ["A", "C"], "multiple": true, "options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}, {"text": "Option D", "value": "D"}] } ] })"_json; while (true) { LogStatus("`" + testBtn1.dump() + "`\n", "`" + testBtn2.dump() + "`\n", "`" + testBtn3.dump() + "`\n"); auto cmd = GetCommand(); if (cmd != "") { Log(cmd); } Sleep(5000); } } -
Using the latest button structure, construct buttons in the status bar table. When clicking a button triggers an interaction, a multi-control popup will appear.
For detailed information, please refer to: User Guide - Interactive Controls in Status Bar.
javascriptvar symbols = ["BTC_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "BNB_USDT.swap", "SOL_USDT.swap"] function createBtn(tmp, group) { var btn = JSON.parse(JSON.stringify(tmp)) _.each(group, function(eleByGroup) { btn["group"].unshift(eleByGroup) }) return btn } function main() { var arrManager = [] _.each(symbols, function(symbol) { arrManager.push({ "symbol": symbol, }) }) // Btn var tmpBtnOpen = { "type": "button", "cmd": "open", "name": "Open Position", "group": [{ "type": "selected", "name": "tradeType", "label": "Order Type", "description": "Market order, Limit order", "default": 0, "group": "Trade Settings", "settings": { "options": ["Market Order", "Limit Order"], "required": true, } }, { "type": "selected", "name": "direction", "label": "Trade Direction", "description": "Buy, Sell", "default": "buy", "group": "Trade Settings", "settings": { "render": "segment", "required": true, "options": [{"name": "Buy", "value": "buy"}, {"name": "Sell", "value": "sell"}], } }, { "type": "number", "name": "price", "label": "Price", "description": "Order price", "group": "Trade Settings", "filter": "tradeType==1", "settings": { "required": true, } }, { "type": "number", "name": "amount", "label": "Order Amount", "description": "Order amount", "group": "Trade Settings", "settings": { "required": true, } }], } while (true) { var tbl = {"type": "table", "title": "dashboard", "cols": ["symbol", "actionOpen"], "rows": []} _.each(arrManager, function(m) { var btnOpen = createBtn(tmpBtnOpen, [{"type": "string", "name": "symbol", "label": "Symbol", "default": m["symbol"], "settings": {"required": true}}]) tbl["rows"].push([m["symbol"], btnOpen]) }) var cmd = GetCommand() if (cmd) { Log("Received interaction:", cmd) // Parse interaction message: open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111} // Determine which button template triggered the message based on the command before the first colon var arrCmd = cmd.split(":", 2) if (arrCmd[0] == "open") { var msg = JSON.parse(cmd.slice(5)) Log("Symbol:", msg["symbol"], ", Direction:", msg["direction"], ", Order type:", msg["tradeType"] == 0 ? "Market order" : "Limit order", msg["tradeType"] == 0 ? ", Price: Current market price" : ", Price:" + msg["price"], ", Amount:", msg["amount"]) } } LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`") Sleep(1000) } }pythonimport json symbols = ["BTC_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "BNB_USDT.swap", "SOL_USDT.swap"] def createBtn(tmp, group): btn = json.loads(json.dumps(tmp)) for eleByGroup in group: btn["group"].insert(0, eleByGroup) return btn def main(): arrManager = [] for symbol in symbols: arrManager.append({"symbol": symbol}) # Btn tmpBtnOpen = { "type": "button", "cmd": "open", "name": "Open Position", "group": [{ "type": "selected", "name": "tradeType", "label": "Order Type", "description": "Market order, Limit order", "default": 0, "group": "Trade Settings", "settings": { "options": ["Market Order", "Limit Order"], "required": True, } }, { "type": "selected", "name": "direction", "label": "Trade Direction", "description": "Buy, Sell", "default": "buy", "group": "Trade Settings", "settings": { "render": "segment", "required": True, "options": [{"name": "Buy", "value": "buy"}, {"name": "Sell", "value": "sell"}], } }, { "type": "number", "name": "price", "label": "Price", "description": "Order price", "group": "Trade Settings", "filter": "tradeType==1", "settings": { "required": True, } }, { "type": "number", "name": "amount", "label": "Order Amount", "description": "Order amount", "group": "Trade Settings", "settings": { "required": True, } }], } while True: tbl = {"type": "table", "title": "dashboard", "cols": ["symbol", "actionOpen"], "rows": []} for m in arrManager: btnOpen = createBtn(tmpBtnOpen, [{"type": "string", "name": "symbol", "label": "Symbol", "default": m["symbol"], "settings": {"required": True}}]) tbl["rows"].append([m["symbol"], btnOpen]) cmd = GetCommand() if cmd != "" and cmd != None: Log("Received interaction:", cmd) # Parse interaction message: open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111} # Determine which button template triggered the message based on the command before the first colon arrCmd = cmd.split(":") if arrCmd[0] == "open": msg = json.loads(cmd[5:]) Log("Symbol:", msg["symbol"], ", Direction:", msg["direction"], ", Order type:", "Market order" if msg["tradeType"] == 0 else "Limit order", ", Price: Current market price" if msg["tradeType"] == 0 else ", Price:" + str(msg["price"]), ", Amount:", msg["amount"]) # Output status bar information LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`") Sleep(1000)c++// Omitted... -
Horizontally merge cells in the table drawn by the
LogStatus()function:javascriptfunction main() { var table = { type: 'table', title: 'Position Operation', cols: ['Column 1', 'Column 2', 'Action'], rows: [ ['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'Close'}] ] } var ticker = exchange.GetTicker() // Add a row of data, merge the first and second cells, and output the ticker variable in the merged cell table.rows.push([{body : JSON.stringify(ticker), colspan : 2}, "abc"]) LogStatus('`' + JSON.stringify(table) + '`') }pythonimport json def main(): table = { "type" : "table", "title" : "Position Operation", "cols" : ["Column 1", "Column 2", "Action"], "rows" : [ ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close"}] ] } ticker = exchange.GetTicker() table["rows"].append({"body": json.dumps(ticker), "colspan": 2}, "abc"]) LogStatus("`" + json.dumps(table) + "`")c++void main() { json table = R"({ "type" : "table", "title" : "Position Operation", "cols" : ["Column 1", "Column 2", "Action"], "rows" : [ ["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close"}] ] })"_json; auto ticker = exchange.GetTicker(); json jsonTicker = R"({"Buy": 0, "Sell": 0, "High": 0, "Low": 0, "Volume": 0, "Last": 0, "Time": 0})"_json; jsonTicker["Buy"] = ticker.Buy; jsonTicker["Sell"] = ticker.Sell; jsonTicker["Last"] = ticker.Last; jsonTicker["Volume"] = ticker.Volume; jsonTicker["Time"] = ticker.Time; jsonTicker["High"] = ticker.High; jsonTicker["Low"] = ticker.Low; json arr = R"([{"body": {}, "colspan": 2}, "abc"])"_json; arr[0]["body"] = jsonTicker; table["rows"].push_back(arr); LogStatus("`" + table.dump() + "`"); } -
Vertically merge cells in the table drawn by the
LogStatus()function:javascriptfunction main() { var table = { type: 'table', title: 'Table Demo', cols: ['Column A', 'Column B', 'Column C'], rows: [ ['A1', 'B1', {'type':'button', 'cmd': 'coverAll', 'name': 'C1'}] ] } var ticker = exchange.GetTicker() var name = exchange.GetName() table.rows.push([{body : "A2 + B2:" + JSON.stringify(ticker), colspan : 2}, "C2"]) table.rows.push([{body : "A3 + A4 + A5:" + name, rowspan : 3}, "B3", "C3"]) // A3 is merged by the first cell of the previous row table.rows.push(["B4", "C4"]) // A4 is merged by the first cell of the previous row table.rows.push(["B5", "C5"]) table.rows.push(["A6", "B6", "C6"]) LogStatus('`' + JSON.stringify(table) + '`') }pythonimport json def main(): table = { "type" : "table", "title" : "Table Demo", "cols" : ["Column A", "Column B", "Column C"], "rows" : [ ["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}] ] } ticker = exchange.GetTicker() name = exchange.GetName() table["rows"].append([{"body": "A2 + B2:" + json.dumps(ticker), "colspan": 2}, "C2"]) table["rows"].append([{"body": "A3 + A4 + A5:" + name, "rowspan": 3}, "B3", "C3"]) table["rows"].append(["B4", "C4"]) table["rows"].append(["B5", "C5"]) table["rows"].append(["A6", "B6", "C6"]) LogStatus("`" + json.dumps(table) + "`")c++void main() { json table = R"({ "type" : "table", "title" : "Table Demo", "cols" : ["Column A", "Column B", "Column C"], "rows" : [ ["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}] ] })"_json; // For testing purposes, to make the code short and readable, constructed data is used here json jsonTicker = R"({"High": 0, "Low": 0, "Buy": 0, "Sell": 0, "Last": 0, "Time": 0, "Volume": 0})"_json; auto name = exchange.GetName(); json arr1 = R"([{"body": "", "colspan": 2}, "C2"])"_json; arr1[0]["body"] = "A2 + B2:" + jsonTicker.dump(); json arr2 = R"([{"body": "", "rowspan": 3}, "B3", "C3"])"_json; arr2[0]["body"] = "A3 + A4 + A5:" + name; table["rows"].push_back(arr1); table["rows"].push_back(arr2); table["rows"].push_back(R"(["B4", "C4"])"_json); table["rows"].push_back(R"(["B5", "C5"])"_json); table["rows"].push_back(R"(["A6", "B6", "C6"])"_json); LogStatus("`" + table.dump() + "`"); } -
Status bar table pagination display:
javascriptfunction main() { var table1 = {type: 'table', title: 'table1', cols: ['Column 1', 'Column 2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]} var table2 = {type: 'table', title: 'table2', cols: ['Column 1', 'Column 2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]} LogStatus('`' + JSON.stringify([table1, table2]) + '`') }pythonimport json def main(): table1 = {"type": "table", "title": "table1", "cols": ["Column 1", "Column 2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]} table2 = {"type": "table", "title": "table2", "cols": ["Column 1", "Column 2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]} LogStatus("`" + json.dumps([table1, table2]) + "`")c++void main() { json table1 = R"({"type": "table", "title": "table1", "cols": ["Column 1", "Column 2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json; json table2 = R"({"type": "table", "title": "table2", "cols": ["Column 1", "Column 2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json; json arr = R"([])"_json; arr.push_back(table1); arr.push_back(table2); LogStatus("`" + arr.dump() + "`"); } -
In addition to paginated table display, you can also arrange multiple tables vertically from top to bottom:
javascriptfunction main(){ var tab1 = { type : "table", title : "Table 1", cols : ["1", "2"], rows : [] } var tab2 = { type : "table", title : "Table 2", cols : ["1", "2", "3"], rows : [] } var tab3 = { type : "table", title : "Table 3", cols : ["A", "B", "C"], rows : [] } tab1.rows.push(["jack", "lucy"]) tab2.rows.push(["A", "B", "C"]) tab3.rows.push(["A", "B", "C"]) LogStatus('`' + JSON.stringify(tab1) + '`\n' + '`' + JSON.stringify(tab2) + '`\n' + '`' + JSON.stringify(tab3) + '`') Log("exit") }pythonimport json def main(): tab1 = { "type": "table", "title": "Table 1", "cols": ["1", "2"], "rows": [] } tab2 = { "type": "table", "title": "Table 2", "cols": ["1", "2", "3"], "rows": [] } tab3 = { "type": "table", "title": "Table 3", "cols": ["A", "B", "C"], "rows": [] } tab1["rows"].append(["jack", "lucy"]) tab2["rows"].append(["A", "B", "C"]) tab3["rows"].append(["A", "B", "C"]) LogStatus("`" + json.dumps(tab1) + "`\n" + "`" + json.dumps(tab2) + "`\n" + "`" + json.dumps(tab3) + "`")c++void main() { json tab1 = R"({ "type": "table", "title": "Table 1", "cols": ["1", "2"], "rows": [] })"_json; json tab2 = R"({ "type": "table", "title": "Table 2", "cols": ["1", "2", "3"], "rows": [] })"_json; json tab3 = R"({ "type": "table", "title": "Table 3", "cols": ["A", "B", "C"], "rows": [] })"_json; tab1["rows"].push_back(R"(["jack", "lucy"])"_json); tab2["rows"].push_back(R"(["A", "B", "C"])"_json); tab3["rows"].push_back(R"(["A", "B", "C"])"_json); LogStatus("`" + tab1.dump() + "`\n" + "`" + tab2.dump() + "`\n" + "`" + tab3.dump() + "`"); } -
Supports setting horizontal and vertical scroll modes for the status bar table. When the
scrollproperty is set to"auto", the content will automatically scroll when the status bar table has more than 20 rows vertically; when the horizontal columns exceed the page display range, horizontal scrolling will be enabled. Using thescrollproperty can effectively alleviate the lag issues caused by writing large amounts of data to the status bar during live trading.Refer to the following test example:
javascriptfunction main() { var tbl = { type : "table", title : "test scroll", scroll : "auto", cols : ["col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10", "col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20"], rows : [] } for (var i = 1 ; i < 100 ; i++) { tbl.rows.push([i, "1," + i, "2," + i, "3," + i, "4," + i, "5," + i, "6," + i, "7," + i, "8," + i, "9," + i, "10," + i, "11," + i, "12," + i, "13," + i, "14," + i, "15," + i, "16," + i, "17," + i, "18," + i, "19," + i, "20," + i]) } LogStatus("`" + JSON.stringify(tbl) + "`") }pythonimport json def main(): tbl = { "type" : "table", "title" : "test scroll", "scroll" : "auto", "cols" : ["col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10", "col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20"], "rows" : [] } for index in range(1, 100): i = str(index) tbl["rows"].append([i, "1," + i, "2," + i, "3," + i, "4," + i, "5," + i, "6," + i, "7," + i, "8," + i, "9," + i, "10," + i, "11," + i, "12," + i, "13," + i, "14," + i, "15," + i, "16," + i, "17," + i, "18," + i, "19," + i, "20," + i]) LogStatus("`" + json.dumps(tbl) + "`")c++void main() { json table = R"({ "type" : "table", "title" : "test scroll", "scroll" : "auto", "cols" : ["col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10", "col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20"], "rows" : [] })"_json; for (int index = 1; index < 100; ++index) { std::string i = std::to_string(index); table["rows"].push_back({i, "1," + i, "2," + i, "3," + i, "4," + i, "5," + i, "6," + i, "7," + i, "8," + i, "9," + i, "10," + i, "11," + i, "12," + i, "13," + i, "14," + i, "15," + i, "16," + i, "17," + i, "18," + i, "19," + i, "20," + i}); } LogStatus("`" + table.dump() + "`"); }
Arguments
| Name | Type | Required | Description |
msg | string / number / bool / object / array / any (any type supported by the platform) | No | The parameter |
See Also
Remarks
During live trading, the information output by the LogStatus() function is not saved to the live trading database; it only updates the status bar content of the current live trading.
The LogStatus() function supports printing base64 encoded images, starting with ` and ending with `. For example: LogStatus("`data:image/png;base64,AAAA`").
The LogStatus() function supports directly passing Python's matplotlib.pyplot object. As long as the object contains the savefig method, it can be passed as a parameter to the LogStatus() function. For example:
python
import matplotlib.pyplot as plt
def main():
plt.plot([3,6,2,4,7,1])
LogStatus(plt)
When the strategy is running live, if you browse historical records on the live trading page, the status bar will enter sleep mode and stop updating. The status bar data will only refresh when the log is on the first page. It supports outputting base64 encoded images in the status bar, and also supports outputting base64 encoded images in tables displayed in the status bar. Since the encoded image string data is usually very long, example code is not shown here.
EnableLog
Enable or disable the logging function for order information.
EnableLog(enable)Examples
javascript
function main() {
EnableLog(false)
}
python
def main():
EnableLog(False)
c++
void main() {
EnableLog(false);
}Arguments
| Name | Type | Required | Description |
enable | bool | Yes | When the |
See Also
Chart
Custom chart binding function.
Chart(options)Examples
-
Multi-chart binding configuration:
extension.layoutproperty
If this property is set with value "single", charts will not be stacked (will not display as tabbed pages), but will be displayed individually (tiled display).extension.heightproperty
This property is used to set the chart height, value can be numeric type, or set in "300px" format.extension.colproperty
This property is used to set the chart width, page width is divided into 12 units total, setting to 8 means this chart occupies 8 units of width.
javascriptfunction main() { var cfgA = { extension: { layout: 'single', // Do not participate in grouping, display individually, default is grouping 'group' height: 300, // Specify height }, title: { text: 'Order Book Chart' }, xAxis: { type: 'datetime' }, series: [{ name: 'Bid 1', data: [], }, { name: 'Ask 1', data: [], }] } var cfgB = { title: { text: 'Spread Chart' }, xAxis: { type: 'datetime' }, series: [{ name: 'Spread', type: 'column', data: [], }] } var cfgC = { __isStock: false, title: { text: 'Pie Chart' }, series: [{ type: 'pie', name: 'one', data: [ ["A", 25], ["B", 25], ["C", 25], ["D", 25], ] // After specifying initial data, no need to use add function to update, directly modify chart configuration to update series }] }; var cfgD = { extension: { layout: 'single', col: 8, // Specify width unit value occupied, total value is 12 height: '300px', }, title: { text: 'Order Book Chart' }, xAxis: { type: 'datetime' }, series: [{ name: 'Bid 1', data: [], }, { name: 'Ask 1', data: [], }] } var cfgE = { __isStock: false, extension: { layout: 'single', col: 4, height: '300px', }, title: { text: 'Pie Chart 2' }, series: [{ type: 'pie', name: 'one', data: [ ["A", 25], ["B", 25], ["C", 25], ["D", 25], ] }] }; var chart = Chart([cfgA, cfgB, cfgC, cfgD, cfgE]); chart.reset() // Add a data point to pie chart, add can only update data points added through add method, built-in data points cannot be updated later chart.add(3, { name: "ZZ", y: Math.random() * 100 }); while (true) { Sleep(1000) var ticker = exchange.GetTicker() if (!ticker) { continue; } var diff = ticker.Sell - ticker.Buy cfgA.subtitle = { text: 'Bid ' + ticker.Buy + ', Ask ' + ticker.Sell, }; cfgB.subtitle = { text: 'Spread ' + diff, }; chart.add([0, [new Date().getTime(), ticker.Buy]]); chart.add([1, [new Date().getTime(), ticker.Sell]]); // Equivalent to updating the first data series of the second chart chart.add([2, [new Date().getTime(), diff]]); chart.add(4, [new Date().getTime(), ticker.Buy]); chart.add(5, [new Date().getTime(), ticker.Buy]); cfgC.series[0].data[0][1] = Math.random() * 100; cfgE.series[0].data[0][1] = Math.random() * 100; // update actually equals resetting the chart configuration chart.update([cfgA, cfgB, cfgC, cfgD, cfgE]); } }pythonimport random import time def main(): cfgA = { "extension" : { "layout" : "single", "height" : 300, "col" : 8 }, "title" : { "text" : "Order Book Chart" }, "xAxis" : { "type" : "datetime" }, "series" : [{ "name" : "Bid 1", "data" : [] }, { "name" : "Ask 1", "data" : [] }] } cfgB = { "title" : { "text" : "Spread Chart" }, "xAxis" : { "type" : "datetime", }, "series" : [{ "name" : "Spread", "type" : "column", "data" : [] }] } cfgC = { "__isStock" : False, "title" : { "text" : "Pie Chart" }, "series" : [{ "type" : "pie", "name" : "one", "data" : [ ["A", 25], ["B", 25], ["C", 25], ["D", 25], ] }] } cfgD = { "extension" : { "layout" : "single", "col" : 8, "height" : "300px" }, "title" : { "text" : "Order Book Chart" }, "series" : [{ "name" : "Bid 1", "data" : [] }, { "name" : "Ask 1", "data" : [] }] } cfgE = { "__isStock" : False, "extension" : { "layout" : "single", "col" : 4, "height" : "300px" }, "title" : { "text" : "Pie Chart 2" }, "series" : [{ "type" : "pie", "name" : "one", "data" : [ ["A", 25], ["B", 25], ["C", 25], ["D", 25] ] }] } chart = Chart([cfgA, cfgB, cfgC, cfgD, cfgE]) chart.reset() chart.add(3, { "name" : "ZZ", "y" : random.random() * 100 }) while True: Sleep(1000) ticker = exchange.GetTicker() if not ticker : continue diff = ticker["Sell"] - ticker["Buy"] cfgA["subtitle"] = { "text" : "Bid " + str(ticker["Buy"]) + " Ask " + str(ticker["Sell"]) } cfgB["subtitle"] = { "text" : "Spread " + str(diff) } chart.add(0, [time.time() * 1000, ticker["Buy"]]) chart.add(1, [time.time() * 1000, ticker["Sell"]]) chart.add(2, [time.time() * 1000, diff]) chart.add(4, [time.time() * 1000, ticker["Buy"]]) chart.add(5, [time.time() * 1000, ticker["Buy"]]) cfgC["series"][0]["data"][0][1] = random.random() * 100 cfgE["series"][0]["data"][0][1] = random.random() * 100c++void main() { json cfgA = R"({ "extension" : { "layout" : "single", "height" : 300, "col" : 8 }, "title" : { "text" : "Order Book Chart" }, "xAxis" : { "type" : "datetime" }, "series" : [{ "name" : "Bid 1", "data" : [] }, { "name" : "Ask 1", "data" : [] }] })"_json; json cfgB = R"({ "title" : { "text" : "Spread Chart" }, "xAxis" : { "type" : "datetime" }, "series" : [{ "name" : "Spread", "type" : "column", "data" : [] }] })"_json; json cfgC = R"({ "__isStock" : false, "title" : { "text" : "Pie Chart" }, "series" : [{ "type" : "pie", "name" : "one", "data" : [ ["A", 25], ["B", 25], ["C", 25], ["D", 25] ] }] })"_json; json cfgD = R"({ "extension" : { "layout" : "single", "col" : 8, "height" : "300px" }, "title" : { "text" : "Order Book Chart" }, "series" : [{ "name" : "Bid 1", "data" : [] }, { "name" : "Ask 1", "data" : [] }] })"_json; json cfgE = R"({ "__isStock" : false, "extension" : { "layout" : "single", "col" : 4, "height" : "300px" }, "title" : { "text" : "Pie Chart 2" }, "series" : [{ "type" : "pie", "name" : "one", "data" : [ ["A", 25], ["B", 25], ["C", 25], ["D", 25] ] }] })"_json; auto chart = Chart({cfgA, cfgB, cfgC, cfgD, cfgE}); chart.reset(); json zz = R"({ "name" : "ZZ", "y" : 0 })"_json; zz["y"] = rand() % 100; chart.add(3, zz); while(true) { Sleep(1000); auto ticker = exchange.GetTicker(); if(!ticker.Valid) { continue; } auto diff = ticker.Sell - ticker.Buy; json cfgASubTitle = R"({"text" : ""})"_json; cfgASubTitle["text"] = format("Bid 1 %f, Ask 1 %f", ticker.Buy, ticker.Sell); cfgA["subtitle"] = cfgASubTitle; json cfgBSubTitle = R"({"text" : ""})"_json; cfgBSubTitle["text"] = format("Spread %f", diff); cfgB["subtitle"] = cfgBSubTitle; chart.add(0, {Unix() * 1000, ticker.Buy}); chart.add(1, {Unix() * 1000, ticker.Sell}); chart.add(2, {Unix() * 1000, diff}); chart.add(4, {Unix() * 1000, ticker.Buy}); chart.add(5, {Unix() * 1000, ticker.Buy}); cfgC["series"][0]["data"][0][1] = rand() % 100; cfgE["series"][0]["data"][0][1] = rand() % 100; chart.update({cfgA, cfgB, cfgC, cfgD, cfgE}); } } -
Simple charting example:
javascript// This chart is an object in JavaScript language. Before using the Chart function, we need to declare an object variable chart to configure the chart var chart = { // This field marks whether the chart is a general chart. Interested users can change it to false and run to see the effect __isStock: true, // Zoom tool tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'}, // Title title : { text : 'Spread Analysis Chart'}, // Range selector rangeSelector: { buttons: [{type: 'hour',count: 1, text: '1h'}, {type: 'hour',count: 3, text: '3h'}, {type: 'hour', count: 8, text: '8h'}, {type: 'all',text: 'All'}], selected: 0, inputEnabled: false }, // X-axis of coordinate system, currently set type is: time xAxis: { type: 'datetime'}, // Y-axis of coordinate system, default values adjust according to data size yAxis : { // Title title: {text: 'Spread'}, // Whether to enable right Y-axis opposite: false }, // Data series, this property stores various data series (lines, candlestick charts, labels, etc.) series : [ // Index 0, data array stores data for this index series {name : "line1", id : "Line 1,buy1Price", data : []}, // Index 1, set dashStyle:'shortdash' to create dashed line {name : "line2", id : "Line 2,lastPrice", dashStyle : 'shortdash', data : []} ] } function main(){ // Call Chart function to initialize chart var ObjChart = Chart(chart) // Clear ObjChart.reset() while(true){ // Get timestamp for current polling, i.e., a millisecond-level timestamp to determine X-axis position in chart var nowTime = new Date().getTime() // Get market data var ticker = _C(exchange.GetTicker) // Get bid price from market data return value var buy1Price = ticker.Buy // Get last traded price, add 1 to prevent line overlap var lastPrice = ticker.Last + 1 // Use timestamp as X value, bid price as Y value, pass to data series at index 0 ObjChart.add(0, [nowTime, buy1Price]) // Same as above ObjChart.add(1, [nowTime, lastPrice]) Sleep(2000) } }pythonimport time chart = { "__isStock" : True, "tooltip" : {"xDateFormat" : "%Y-%m-%d %H:%M:%S, %A"}, "title" : {"text" : "Spread Analysis Chart"}, "rangeSelector" : { "buttons" : [{"type": "count", "count": 1, "text": "1h"}, {"type": "hour", "count": 3, "text": "3h"}, {"type": "hour", "count": 8, "text": "8h"}, {"type": "all", "text": "All"}], "selected": 0, "inputEnabled": False }, "xAxis": {"type": "datetime"}, "yAxis": { "title": {"text": "Spread"}, "opposite": False }, "series": [{ "name": "line1", "id": "Line 1,buy1Price", "data": [] }, { "name": "line2", "id": "Line 2,lastPrice", "dashStyle": "shortdash", "data": [] }] } def main(): ObjChart = Chart(chart) ObjChart.reset() while True: nowTime = time.time() * 1000 ticker = exchange.GetTicker() buy1Price = ticker["Buy"] lastPrice = ticker["Last"] + 1 ObjChart.add(0, [nowTime, buy1Price]) ObjChart.add(1, [nowTime, lastPrice]) Sleep(2000)c++void main() { // When writing strategies in C++, try to avoid declaring non-basic type global variables, so chart configuration object is declared inside main function json chart = R"({ "__isStock" : true, "tooltip" : {"xDateFormat" : "%Y-%m-%d %H:%M:%S, %A"}, "title" : {"text" : "Spread Analysis Chart"}, "rangeSelector" : { "buttons" : [{"type": "count", "count": 1, "text": "1h"}, {"type": "hour", "count": 3, "text": "3h"}, {"type": "hour", "count": 8, "text": "8h"}, {"type": "all", "text": "All"}], "selected": 0, "inputEnabled": false }, "xAxis": {"type": "datetime"}, "yAxis": { "title": {"text": "Spread"}, "opposite": false }, "series": [{ "name": "line1", "id": "Line 1,buy1Price", "data": [] }, { "name": "line2", "id": "Line 2,lastPrice", "dashStyle": "shortdash", "data": [] }] })"_json; auto ObjChart = Chart(chart); ObjChart.reset(); while(true) { auto nowTime = Unix() * 1000; auto ticker = exchange.GetTicker(); auto buy1Price = ticker.Buy; auto lastPrice = ticker.Last + 1.0; ObjChart.add(0, {nowTime, buy1Price}); ObjChart.add(1, {nowTime, lastPrice}); Sleep(2000); } } -
Trigonometric curve plotting example:
javascript// Object for initializing the chart var chart = { // Chart title title: {text: "Line value triggers plotLines value"}, // Y-axis related settings yAxis: { // Horizontal lines perpendicular to Y-axis, used as trigger lines, is a structure array that can set multiple trigger lines plotLines: [{ // Trigger line value, this line will be displayed at the corresponding numerical position value: 0, // Set trigger line color color: 'red', // Width width: 2, // Display label label: { // Label text text: 'Trigger Value', // Label position centered align: 'center' } }] }, // X-axis related settings, here set type as time axis xAxis: {type: "datetime"}, series: [ {name: "sin", type: "spline", data: []}, // This is an important data series, multiple data series can be set, controlled by array index {name: "cos", type: "spline", data: []} ] } function main(){ // Pi var pi = 3.1415926535897 // Variable for recording timestamp var time = 0 // Angle var angle = 0 // Coordinate y value, used to receive sine and cosine values var y = 0 // Call API interface, use chart object to initialize chart var objChart = Chart(chart) // Clear chart on initialization objChart.reset() // Set trigger line value to 1 chart.yAxis.plotLines[0].value = 1 // Loop while(true){ // Get current timestamp time = new Date().getTime() // Every 500ms angle increases by 5 degrees, calculate sine value y = Math.sin(angle * 2 * pi / 360) // Write calculated y value to corresponding index data series in chart, first parameter of add function is specified data series index objChart.add(0, [time, y]) // Calculate cosine value y = Math.cos(angle * 2 * pi / 360) objChart.add(1, [time, y]) // Increase by 5 degrees angle += 5 // Pause for 5 seconds to avoid too frequent plotting and rapid data growth Sleep(5000) } }pythonimport math import time chart = { "title": {"text": "Line value triggers plotLines value"}, "yAxis": { "plotLines": [{ "value": 0, "color": "red", "width": 2, "label": { "text": "Trigger Value", "align": "center" } }] }, "xAxis": {"type": "datetime"}, "series": [{"name": "sin", "type": "spline", "data": []}, {"name": "cos", "type": "spline", "data": []}] } def main(): pi = 3.1415926535897 ts = 0 angle = 0 y = 0 objChart = Chart(chart) objChart.reset() chart["yAxis"]["plotLines"][0]["value"] = 1 while True: ts = time.time() * 1000 y = math.sin(angle * 2 * pi / 360) objChart.add(0, [ts, y]) y = math.cos(angle * 2 * pi / 360) objChart.add(1, [ts, y]) angle += 5 Sleep(5000)c++void main() { json chart = R"({ "title": {"text": "Line value triggers plotLines value"}, "yAxis": { "plotLines": [{ "value": 0, "color": "red", "width": 2, "label": { "text": "Trigger Value", "align": "center" } }] }, "xAxis": {"type": "datetime"}, "series": [{"name": "sin", "type": "spline", "data": []}, {"name": "cos", "type": "spline", "data": []}] })"_json; auto pi = 3.1415926535897; auto ts = 0; auto angle = 0.0; auto y = 0.0; auto objChart = Chart(chart); objChart.reset(); chart["yAxis"]["plotLines"][0]["value"] = 1; while(true) { ts = Unix() * 1000; y = sin(angle * 2 * pi / 360); objChart.add(0, {ts, y}); y = cos(angle * 2 * pi / 360); objChart.add(1, {ts, y}); angle += 5; Sleep(5000); } } -
Complex example using mixed charts:
javascript/*backtest start: 2020-03-11 00:00:00 end: 2020-04-09 23:59:00 period: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ var chartCfg = { subtitle: { text: "subtitle", }, yAxis: [{ height: "40%", lineWidth: 2, title: { text: 'PnL', }, tickPixelInterval: 20, minorGridLineWidth: 1, minorTickWidth: 0, opposite: true, labels: { align: "right", x: -3, } }, { title: { text: 'Profit', }, top: "42%", height: "18%", offset: 0, lineWidth: 2 }, { title: { text: 'Vol', }, top: '62%', height: '18%', offset: 0, lineWidth: 2 }, { title: { text: 'Asset', }, top: '82%', height: '18%', offset: 0, lineWidth: 2 }], series: [{ name: 'PnL', data: [], id: 'primary', tooltip: { xDateFormat: '%Y-%m-%d %H:%M:%S' }, yAxis: 0 }, { type: 'column', lineWidth: 2, name: 'Profit', data: [], yAxis: 1, }, { type: 'column', name: 'Trade', data: [], yAxis: 2 }, { type: 'area', step: true, lineWidth: 0, name: 'Long', data: [], yAxis: 2 }, { type: 'area', step: true, lineWidth: 0, name: 'Short', data: [], yAxis: 2 }, { type: 'line', step: true, color: '#5b4b00', name: 'Asset', data: [], yAxis: 3 }, { type: 'pie', innerSize: '70%', name: 'Random', data: [], center: ['3%', '6%'], size: '15%', dataLabels: { enabled: false }, startAngle: -90, endAngle: 90, }], }; function main() { let c = Chart(chartCfg); let preTicker = null; while (true) { let t = exchange.GetTicker(); c.add(0, [t.Time, t.Last]); // PnL c.add(1, [t.Time, preTicker ? t.Last - preTicker.Last : 0]); // profit let r = Math.random(); var pos = parseInt(t.Time/86400); c.add(2, [t.Time, pos/2]); // Vol c.add(3, [t.Time, r > 0.8 ? pos : null]); // Long c.add(4, [t.Time, r < 0.8 ? -pos : null]); // Short c.add(5, [t.Time, Math.random() * 100]); // Asset // update pie chartCfg.series[chartCfg.series.length-1].data = [ ["A", Math.random()*100], ["B", Math.random()*100], ]; c.update(chartCfg) preTicker = t; } }python'''backtest start: 2020-03-11 00:00:00 end: 2020-04-09 23:59:00 period: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] ''' import random chartCfg = { "subtitle": { "text": "subtitle" }, "yAxis": [{ "height": "40%", "lineWidth": 2, "title": { "text": 'PnL' }, "tickPixelInterval": 20, "minorGridLineWidth": 1, "minorTickWidth": 0, "opposite": True, "labels": { "align": "right", "x": -3 } }, { "title": { "text": 'Profit' }, "top": "42%", "height": "18%", "offset": 0, "lineWidth": 2 }, { "title": { "text": 'Vol' }, "top": '62%', "height": '18%', "offset": 0, "lineWidth": 2 }, { "title": { "text": 'Asset' }, "top": '82%', "height": '18%', "offset": 0, "lineWidth": 2 }], "series": [{ "name": 'PnL', "data": [], "id": 'primary', "tooltip": { "xDateFormat": '%Y-%m-%d %H:%M:%S' }, "yAxis": 0 }, { "type": 'column', "lineWidth": 2, "name": 'Profit', "data": [], "yAxis": 1 }, { "type": 'column', "name": 'Trade', "data": [], "yAxis": 2 }, { "type": 'area', "step": True, "lineWidth": 0, "name": 'Long', "data": [], "yAxis": 2 }, { "type": 'area', "step": True, "lineWidth": 0, "name": 'Short', "data": [], "yAxis": 2 }, { "type": 'line', "step": True, "color": '#5b4b00', "name": 'Asset', "data": [], "yAxis": 3 }, { "type": 'pie', "innerSize": '70%', "name": 'Random', "data": [], "center": ['3%', '6%'], "size": '15%', "dataLabels": { "enabled": False }, "startAngle": -90, "endAngle": 90 }] } def main(): c = Chart(chartCfg) preTicker = None while True: t = exchange.GetTicker() c.add(0, [t["Time"], t["Last"]]) profit = t["Last"] - preTicker["Last"] if preTicker else 0 c.add(1, [t["Time"], profit]) r = random.random() pos = t["Time"] / 86400 c.add(2, [t["Time"], pos / 2]) long = pos if r > 0.8 else None c.add(3, [t["Time"], long]) short = -pos if r < 0.8 else None c.add(4, [t["Time"], short]) c.add(5, [t["Time"], random.random() * 100]) # update pie chartCfg["series"][len(chartCfg["series"]) - 1]["data"] = [ ["A", random.random() * 100], ["B", random.random() * 100] ] c.update(chartCfg) preTicker = tc++/*backtest start: 2020-03-11 00:00:00 end: 2020-04-09 23:59:00 period: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ void main() { json chartCfg = R"({ "subtitle": { "text": "subtitle" }, "yAxis": [{ "height": "40%", "lineWidth": 2, "title": { "text": "PnL" }, "tickPixelInterval": 20, "minorGridLineWidth": 1, "minorTickWidth": 0, "opposite": true, "labels": { "align": "right", "x": -3 } }, { "title": { "text": "Profit" }, "top": "42%", "height": "18%", "offset": 0, "lineWidth": 2 }, { "title": { "text": "Vol" }, "top": "62%", "height": "18%", "offset": 0, "lineWidth": 2 }, { "title": { "text": "Asset" }, "top": "82%", "height": "18%", "offset": 0, "lineWidth": 2 }], "series": [{ "name": "PnL", "data": [], "id": "primary", "tooltip": { "xDateFormat": "%Y-%m-%d %H:%M:%S" }, "yAxis": 0 }, { "type": "column", "lineWidth": 2, "name": "Profit", "data": [], "yAxis": 1 }, { "type": "column", "name": "Trade", "data": [], "yAxis": 2 }, { "type": "area", "step": true, "lineWidth": 0, "name": "Long", "data": [], "yAxis": 2 }, { "type": "area", "step": true, "lineWidth": 0, "name": "Short", "data": [], "yAxis": 2 }, { "type": "line", "step": true, "color": "#5b4b00", "name": "Asset", "data": [], "yAxis": 3 }, { "type": "pie", "innerSize": "70%", "name": "Random", "data": [], "center": ["3%", "6%"], "size": "15%", "dataLabels": { "enabled": false }, "startAngle": -90, "endAngle": 90 }] })"_json; Chart c = Chart(chartCfg); Ticker preTicker; while(true) { auto t = exchange.GetTicker(); c.add(0, {t.Time, t.Last}); auto profit = preTicker.Valid ? t.Last - preTicker.Last : 0; c.add(1, {t.Time, profit}); auto r = rand() % 100; auto pos = t.Time / 86400.0; c.add(2, {t.Time, pos / 2.0}); auto longPos = r > 0.8 ? pos : NULL; c.add(3, {t.Time, longPos}); auto shortPos = r < 0.8 ? -pos : NULL; c.add(4, {t.Time, shortPos}); c.add(5, {t.Time, rand() % 100}); // update pie json pie = R"([["A", 0], ["B", 0]])"_json; pie[0][1] = rand() % 100; pie[1][1] = rand() % 100; chartCfg["series"][chartCfg["series"].size() - 1]["data"] = pie; c.update(chartCfg); preTicker = t; } } -
Charts of
pietype in the chart are charts without a time axis. When updating data, the chart configuration needs to be updated directly. For example, in the code of the above example, after updating the data, usec.update(chartCfg)to update the chart, as shown below:javascript// update pie chartCfg.series[chartCfg.series.length-1].data = [ ["A", Math.random()*100], ["B", Math.random()*100], ]; c.update(chartCfg)python# update pie chartCfg["series"][len(chartCfg["series"]) - 1]["data"] = [ ["A", random.random() * 100], ["B", random.random() * 100] ] c.update(chartCfg)c++// update pie json pie = R"([["A", 0], ["B", 0]])"_json; pie[0][1] = rand() % 100; pie[1][1] = rand() % 100; chartCfg["series"][chartCfg["series"].size() - 1]["data"] = pie; c.update(chartCfg);
Returns
| Type | Description |
object | Chart object. |
Arguments
| Name | Type | Required | Description |
options | object / object array | Yes | The |
See Also
Remarks
The Chart() function returns a chart object with 4 methods: add(), reset(), update(), del().
-
update()method:
Theupdate()method can update chart configuration information. The parameter of this method is a Chart configuration object (JSON).
-
del()method:
Thedel()method can delete the data series at the specified index based on the passed series parameter.
-
add()method:
Theadd()method can write data to the chart. The parameters are:
series: Used to set the data series index, integer type.data: Used to set the specific data to write, array type.index(optional): Used to set the data index, integer type. Specifies the specific index position of the data to modify, supports negative numbers. Setting it to-1represents the last data in the dataset.
For example, when drawing a line, to modify the data on the last point of the line:chart.add(0, [1574993606000, 13.5], -1), which changes the data of the last point inseries[0].dataof the chart. Not setting theindexparameter means adding data to the end of the current data series.
-
reset()method:
Thereset()method is used to clear chart data. Thereset()method can take a parameterremainto specify the number of data entries to retain. Not passing theremainparameter means clearing all data.
KLineChart
This function is used for custom charting during strategy runtime, using a drawing method similar to the Pine language.
KLineChart(options)Examples
-
To draw on the strategy's custom charting area, you must have a chart control object, created using the
KLineChart()function. The parameter of theKLineChart()function is a chart configuration structure. The chart structure used in the reference code is very simple:{overlay: true}.This chart configuration structure only sets the drawing content to be output on the main chart. If
overlayis set to a false value, such asfalse, all content on the chart will be output on the sub-chart. If you need to specify a particular drawing function to bindbindoutput on the main chart, you can also specify theoverlayparameter as a true value in the specific function call, such astrue.javascriptfunction main() { // Call KLineChart function to create chart control object c let c = KLineChart({ overlay: true }) // Use spot exchange object for testing, get K-line data. If using futures exchange object for testing, you need to set the contract first let bars = exchange.GetRecords() if (!bars) { return } // Iterate over K-line data to perform drawing operations. Drawing operations must start with ```c.begin(bar)``` function call and end with ```c.close(bar)``` function call. bars.forEach(function(bar, index) { c.begin(bar) c.barcolor(bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0.2)') if (bar.Close > bar.Open) { c.bgcolor('rgba(0, 255, 0, 0.5)') } let h = c.plot(bar.High, 'high') let l = c.plot(bar.Low, 'low') c.fill(h, l, { color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)' }) c.hline(bar.High) c.plotarrow(bar.Close - bar.Open) c.plotshape(bar.Low, { style: 'diamond' }) c.plotchar(bar.Close, { char: 'X' }) c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9) if (bar.Close > bar.Open) { // long/short/closelong/closeshort c.signal("long", bar.High, 1.5) } else if (bar.Close < bar.Open) { c.signal("closelong", bar.Low, 1.5) } c.close(bar) }) }pythondef main(): # Call KLineChart function to create chart control object c c = KLineChart({ "overlay": True }) # Use spot exchange object for testing, get K-line data. If using futures exchange object for testing, you need to set the contract first bars = exchange.GetRecords() if not bars: return for bar in bars: c.begin(bar) c.barcolor('rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(0, 0, 0, 0.2)') if bar.Close > bar.Open: c.bgcolor('rgba(0, 255, 0, 0.5)') h = c.plot(bar.High, 'high') l = c.plot(bar.Low, 'low') c.fill(h, l, 'rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(255, 0, 0, 0.2)') c.hline(bar.High) c.plotarrow(bar.Close - bar.Open) c.plotshape(bar.Low, style = 'diamond') c.plotchar(bar.Close, char = 'X') c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9) if bar.Close > bar.Open: # long/short/closelong/closeshort c.signal("long", bar.High, 1.5) elif bar.Close < bar.Open: c.signal("closelong", bar.Low, 1.5) c.close(bar)c++// Not supported currently -
Use the
pricePrecisionandvolumePrecisionparameters to control chart data precision. You can set the display precision for price and volume according to actual needs. For example, for instruments with large price fluctuations, you can set it to 0 to display integers, while for instruments requiring precise prices, you can set it to 2 or higher precision.javascriptfunction main() { // Create chart control object, set price precision to 0 (integer), volume precision to 0 (integer) let c = KLineChart({ overlay: true, pricePrecision: 0, // Price data precision, set to 2 to keep 2 decimal places volumePrecision: 0 // Volume data precision }) // Select appropriate trading pair based on exchange type let symbol = exchange.GetName().includes("Futures_") ? "ETH_USDT.swap" : "ETH_USDT" Log("Test symbol:", symbol) // Get K-line data let bars = exchange.GetRecords(symbol) if (!bars) { return } // Iterate through K-line data and draw chart bars.forEach(function(bar, index) { c.begin(bar) c.barcolor(bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0.2)') c.plot(bar.High, 'high') c.plot(bar.Low, 'low') c.close(bar) }) }pythondef main(): # Create chart control object, set price precision to 0 (integer), volume precision to 0 (integer) c = KLineChart({ "overlay": True, "pricePrecision": 0, # Price data precision, set to 2 to keep 2 decimal places "volumePrecision": 0 # Volume data precision }) # Select appropriate trading pair based on exchange type exName = exchange.GetName() symbol = "ETH_USDT.swap" if "Futures_" in exName else "ETH_USDT" Log("Test symbol:", symbol) # Get K-line data bars = exchange.GetRecords(symbol) if not bars: return # Iterate through K-line data and draw chart for bar in bars: c.begin(bar) c.barcolor('rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(0, 0, 0, 0.2)') c.plot(bar.High, 'high') c.plot(bar.Low, 'low') c.close(bar)c++// Not supported currently -
The
Pinelanguage charting interface functions supported in bindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindbindcharting operations include:barcolor, used to set K-line color.barcolor(color, offset, editable, show_last, title, display)
Optional values for display parameter: "none", "all"
javascriptc.barcolor(bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0.2)') // Using the example from the reference code in this example, no further elaboration neededpythonc.barcolor('rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(0, 0, 0, 0.2)')c++// Not supported currently -
bgcolor, used to fill the K-line background with a specified color.bgcolor(color, offset, editable, show_last, title, display, overlay)
Optional values for display parameter: "none", "all"
javascriptc.bgcolor('rgba(0, 255, 0, 0.5)')pythonc.bgcolor('rgba(0, 255, 0, 0.5)')c++// Not supported currently -
plot, plots a series of data on the chart.plot(series, title, color, linewidth, style, trackprice, histbase, offset, join, editable, show_last, display)
style parameter options: "stepline_diamond", "stepline", "cross", "areabr", "area", "circles", "columns", "histogram", "linebr", "line"
display parameter options: "none", "all"javascriptc.plot(bar.High, 'high') c.plot(bar.Open < bar.Close ? NaN : bar.Close, "Close", {style: "linebr"}) // Supports plotting discontinuous data linespythonh = c.plot(bar.High, 'high') h = c.plot(None if bar.Open < bar.Close else bar.Close, "Close", style = "linebr") # Supports plotting discontinuous data linesc++// Not supported yet -
fill, fills the background area between two plots orhlinewith the specified color.fill(hline1, hline2, color, title, editable, fillgaps, display)
display parameter options: "none", "all"Since
JavaScriptdoes not support specifying parameters by function parameter names, to solve this problem, you can use the{key: value}structure to specify parameters for specific parameter names. For example, in the reference code,{color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)'}is used to specify thecolorparameter of thefillfunction.If you need to specify multiple parameters by parameter names consecutively, you can use the
{key1: value1, key2: value2, key3: value3}format.For example, to add a
titleparameter in this example:{color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)', title: 'fill'}.Color values can be set using the
'rgba(255, 0, 0, 0.2)'format or the'#FF0000'format.javascriptlet h = c.plot(bar.High, 'high') let l = c.plot(bar.Low, 'low') c.fill(h, l, {color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)'})pythonh = c.plot(bar.High, 'high') l = c.plot(bar.Low, 'low') c.fill(h, l, color = 'rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(255, 0, 0, 0.2)')c++// Not supported yet -
hline, draws a horizontal line at the specified fixed price level.hline(price, title, color, linestyle, linewidth, editable, display)
linestyle parameter options: "dashed", "dotted", "solid"
display parameter options: "none", "all"javascriptc.hline(bar.High)pythonc.hline(bar.High)c++// Not supported yet -
plotarrow, plots up and down arrows on the chart.plotarrow(series, title, colorup, colordown, offset, minheight, maxheight, editable, show_last, display)
display parameter options: "none", "all"javascriptc.plotarrow(bar.Close - bar.Open)pythonc.plotarrow(bar.Close - bar.Open)c++// Not supported yet -
plotshape, draws visual shapes on the chart.plotshape(series, title, style, location, color, offset, text, textcolor, editable, size, show_last, display)
style parameter options: "diamond", "square", "label_down", "label_up", "arrow_down", "arrow_up", "circle", "flag", "triangle_down", "triangle_up", "cross", "xcross"
location parameter options: "abovebar", "belowbar", "top", "bottom", "absolute"
size parameter options: "10px", "14px", "20px", "40px", "80px", corresponding to size.tiny, size.small, size.normal, size.large, size.huge in Pine language
size.auto is equivalent to size.small.
display parameter options: "none", "all"javascriptc.plotshape(bar.Low, {style: 'diamond'})pythonc.plotshape(bar.Low, style = 'diamond')c++// Not supported yet -
plotchar, draws visual shapes on the chart using any Unicode character.plotchar(series, title, char, location, color, offset, text, textcolor, editable, size, show_last, display)
location parameter options: "abovebar", "belowbar", "top", "bottom", "absolute"
size parameter options: "10px", "14px", "20px", "40px", "80px", corresponding to size.tiny, size.small, size.normal, size.large, size.huge in Pine language
size.auto is equivalent to size.small.
display parameter options: "none", "all"javascriptc.plotchar(bar.Close, {char: 'X'})pythonc.plotchar(bar.Close, char = 'X')c++// Not supported yet -
plotcandle, draws candlestick chart on the chart.plotcandle(open, high, low, close, title, color, wickcolor, editable, show_last, bordercolor, display)
display parameter options: "none", "all"javascriptc.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)pythonc.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)c++// Not supported yet -
signal, this function does not exist in Pine language, used to draw buy/sell signals.signal(direction, price, qty, id)
The parameter "long" indicates the trade direction, with options: "long", "closelong", "short", "closeshort". The parameter
bar.Highspecifies the Y-axis position of the signal marker.
The parameter 1.5 represents the trade quantity of the signal. A fourth parameter can be passed to replace the default displayed text content. The default text of the signal marker is the trade direction, for example: "closelong".javascriptc.signal("long", bar.High, 1.5)pythonc.signal("long", bar.High, 1.5)c++// Not supported yet -
reset, this function does not exist in Pine language, used to clear chart data.reset(remain)
The
reset()method accepts a parameterremainto specify the number of data bars to retain. Not passing theremainparameter means clearing all data.javascriptc.reset()pythonc.reset()c++// Not supported yet
Returns
| Type | Description |
object | Chart object. The chart object returned by the |
Arguments
| Name | Type | Required | Description |
options | object / object array | Yes | The
|
See Also
Remarks
Strategy custom charting can only use one of the KLineChart() function or Chart() function methods. For color, style, and other settings used when calling the KLineChart() function, please refer to the Special Topic Article on Drawing with KLineChart Function
The pricePrecision and volumePrecision parameters are used to control the display precision of data in the chart. When these parameters are not set, the chart uses default precision to display data. After setting the precision parameters, the price and volume data in the chart will be rounded and displayed according to the specified number of decimal places, which helps simplify the chart display and improve readability.
LogReset
Clear log records.
LogReset(remain)Examples
javascript
function main() {
// 保留最近10条日志,清除其余日志
LogReset(10)
}
python
def main():
LogReset(10)
c++
void main() {
LogReset(10);
}Arguments
| Name | Type | Required | Description |
remain | number | No | The |
See Also
Remarks
The startup log generated each time a live strategy starts is counted as one record. Therefore, if no parameter is passed and there is no log output at strategy startup, no logs will be displayed at all. You need to wait for the bot's log callback (this is normal, not an exception).
LogVacuum
Used to reclaim storage space occupied by SQLite when deleting data after calling the LogReset() function to clear logs.
LogVacuum()Examples
javascript
function main() {
LogReset()
LogVacuum()
}
python
def main():
LogReset()
LogVacuum()
c++
void main() {
LogReset()
LogVacuum()
}See Also
Remarks
Since SQLite does not reclaim space when deleting data, a VACUUM operation needs to be performed to clean up tables and free up space. This function call involves file movement operations with significant latency, so it is recommended to call it at appropriate intervals.
console.log
Used to output debug information in the "Debug Info" section of the live trading page. For example, when the live trading ID is 123456, the console.log function outputs debug information on the live trading page while creating a log file with .log extension in the docker directory /logs/storage/123456/ and writing debug information to it. The file name prefix is stdout_.
console.log(...msgs)Examples
javascript
function main() {
console.log("test console.log")
}
python
# 不支持
c++
// 不支持Arguments
| Name | Type | Required | Description |
msg | string / number / bool / object / array / any (any type supported by the platform) | No | The parameter |
See Also
Remarks
Notes:
-
Only
JavaScriptlanguage supports this function. -
Only live trading environment supports this function, neither "Debug Tool" nor "Backtesting System" supports it.
-
When outputting objects, they will be converted to the string
[object Object], so it is recommended to output readable information.
console.error
Used to output error messages in the "Debug Information" section of the live trading page. For example, when the live trading ID is 123456, the console.error function outputs error messages on the live trading page while creating a log file with the prefix stderr_ and extension .log in the docker's directory /logs/storage/123456/ where the live trading belongs, and writes the error messages to this file.
console.error(...msgs)Examples
javascript
function main() {
console.error("test console.error")
}
python
# Not supported
c++
// Not supportedArguments
| Name | Type | Required | Description |
msg | string / number / bool / object / array / any (any type supported by the platform) | No | The parameter |
See Also
Remarks
Notes:
- Only
JavaScriptlanguage supports this function. - Only live trading environment supports this function, "Debug Tool" and "Backtesting System" do not support it.
- When outputting objects, they will be converted to the string
[object Object], it is recommended to output human-readable information.
Market
exchange.GetTicker
Get the Ticker structure corresponding to the currently set trading pair or contract code, i.e., market data. The GetTicker() function is a member function of the exchange object exchange. The member functions (methods) of the exchange object are only related to exchange, which will not be repeated in subsequent documentation.
exchange.GetTicker()
exchange.GetTicker(symbol)Examples
-
For futures exchange objects (i.e.,
exchangeorexchanges[0]), you need to use theexchange.SetContractType()function to set the contract code before calling market data functions. This will not be repeated in subsequent documentation.javascriptfunction main(){ // If it's a futures exchange object, first set the contract code, for example, set it to perpetual contract // exchange.SetContractType("swap") var ticker = exchange.GetTicker() /* Due to network reasons, the exchange API may not be accessible (even if the device where the bot is hosted can open the exchange website, the API interface may still be inaccessible) In this case, ticker will be null, and accessing ticker.High will cause an error, so when testing this code, ensure that the exchange API is accessible */ Log("Symbol:", ticker.Symbol, "High:", ticker.High, "Low:", ticker.Low, "Sell:", ticker.Sell, "Buy:", ticker.Buy, "Last:", ticker.Last, "Open:", ticker.Open, "Volume:", ticker.Volume) }pythondef main(): ticker = exchange.GetTicker() Log("Symbol:", ticker["Symbol"], "High:", ticker["High"], "Low:", ticker["Low"], "Sell:", ticker["Sell"], "Buy:", ticker["Buy"], "Last:", ticker["Last"], "Open:", ticker["Open"], "Volume:", ticker["Volume"])c++void main() { auto ticker = exchange.GetTicker(); Log("Symbol:", ticker.Symbol, "High:", ticker.High, "Low:", ticker.Low, "Sell:", ticker.Sell, "Buy:", ticker.Buy, "Last:", ticker.Last, "Open:", ticker.Open, "Volume:", ticker.Volume); } -
Use the
symbolparameter to request market data for a specific symbol (spot symbol).javascriptfunction main() { var ticker = exchange.GetTicker("BTC_USDT") Log(ticker) }pythondef main(): ticker = exchange.GetTicker("BTC_USDT") Log(ticker)c++void main() { auto ticker = exchange.GetTicker("BTC_USDT"); Log(ticker); }
Returns
| Type | Description |
| The |
Arguments
| Name | Type | Required | Description |
symbol | string | No | The When calling the When calling the When calling the |
See Also
exchange.GetDepth exchange.GetTrades exchange.GetRecords exchange.GetTickers exchange.IO (API rate limit control)
Remarks
In the backtesting system, the Ticker data returned by the exchange.GetTicker() function has simulated values for High and Low, taken from the best ask and best bid at that time.
In live trading, the Ticker data returned by the exchange.GetTicker() function has High and Low values determined by the data returned from the exchange's encapsulated Tick interface, which includes the highest and lowest prices within a certain period (usually a 24-hour period).
Exchanges that do not support the exchange.GetTicker() function:
| Function Name | Unsupported Spot Exchanges | Unsupported Futures Exchanges |
|---|---|---|
| GetTicker | -- | Futures_Aevo |
exchange.GetDepth
Get the Depth structure, i.e., order book data, for the spot or futures corresponding to the currently set trading pair and contract code.
exchange.GetDepth()
exchange.GetDepth(symbol)Examples
-
Test the
exchange.GetDepth()function:javascriptfunction main(){ var depth = exchange.GetDepth() /* Due to network issues, the exchange API may be inaccessible (even if the device hosting the bot can open the exchange website, the API interface may still be unreachable) In this case, depth will be null, and accessing depth.Asks[1].Price will cause an error, so when testing this code, ensure that the exchange API is accessible */ var price = depth.Asks[1].Price Log("Second ask price:", price) }pythondef main(): depth = exchange.GetDepth() price = depth["Asks"][1]["Price"] Log("Second ask price:", price)c++void main() { auto depth = exchange.GetDepth(); auto price = depth.Asks[1].Price; Log("Second ask price:", price); } -
When the configured
exchangeobject is a futures exchange object, use thesymbolparameter to request order book data for a specific instrument (futures instrument).javascriptfunction main() { // BTC USDT-margined perpetual contract var depth = exchange.GetDepth("BTC_USDT.swap") Log(depth) }pythondef main(): depth = exchange.GetDepth("BTC_USDT.swap") Log(depth)c++void main() { auto depth = exchange.GetDepth("BTC_USDT.swap"); Log(depth); }
Returns
| Type | Description |
| The |
Arguments
| Name | Type | Required | Description |
symbol | string | No | The parameter When calling the When calling the When calling the |
See Also
Remarks
In the backtesting system, when using Simulated Tick backtesting, the data returned by the exchange.GetDepth() function has simulated values for each level.
In the backtesting system, when using Real Tick backtesting, the data returned by the exchange.GetDepth() function is a second-level depth snapshot.
exchange.GetTrades
Get the Trade structure array for the currently set trading pair or contract code, i.e., the market transaction data for spot or futures.
exchange.GetTrades()
exchange.GetTrades(symbol)Examples
-
Test the
exchange.GetTrades()function:javascriptfunction main(){ var trades = exchange.GetTrades() /* Due to network issues, the exchange API may be inaccessible (even if the host device can open the exchange website, the API interface may still be unreachable) In this case, trades will be null, and accessing trades[0].Id will cause an error. Therefore, when testing this code, please ensure the exchange API is accessible */ Log("id:", trades[0].Id, "time:", trades[0].Time, "Price:", trades[0].Price, "Amount:", trades[0].Amount, "type:", trades[0].Type) }pythondef main(): trades = exchange.GetTrades() Log("id:", trades[0]["Id"], "time:", trades[0]["Time"], "Price:", trades[0]["Price"], "Amount:", trades[0]["Amount"], "type:", trades[0]["Type"])c++void main() { auto trades = exchange.GetTrades(); Log("id:", trades[0].Id, "time:", trades[0].Time, "Price:", trades[0].Price, "Amount:", trades[0].Amount, "type:", trades[0].Type); } -
When the configured
exchangeobject is a futures exchange object, use thesymbolparameter to request market trade data for a specific instrument (futures contract).javascriptfunction main() { // BTC USDT-margined perpetual contract var trades = exchange.GetTrades("BTC_USDT.swap") Log(trades) }pythondef main(): trades = exchange.GetTrades("BTC_USDT.swap") Log(trades)c++void main() { auto trades = exchange.GetTrades("BTC_USDT.swap"); Log(trades); }
Returns
| Type | Description |
| The |
Arguments
| Name | Type | Required | Description |
symbol | string | No | The parameter When calling the When calling the When calling the |
See Also
Remarks
The exchange.GetTrades() function retrieves the market trading history (not your own trades) for the current trading pair or contract. Some exchanges do not support this function, and the specific range of returned data varies by exchange and needs to be handled according to actual circumstances. The returned data is an array, where the time order of each element is consistent with the order of data returned by the exchange.GetRecords() function, meaning the last element of the array is the data closest to the current time.
In the backtesting system, when using simulated-level Tick backtesting, the exchange.GetTrades() function returns an empty array.
In the backtesting system, when using **real-level Tick** backtesting, the data returned by the exchange.GetTrades() function is order flow snapshot data, i.e., a Trade structure array.
Exchanges that do not support the exchange.GetTrades() function:
| Function Name | Unsupported Spot Exchanges | Unsupported Futures Exchanges |
|---|---|---|
| GetTrades | Hyperliquid | Futures_BitMart / Futures_Bibox / Futures_Hyperliquid / Futures_edgeX |
exchange.GetRecords
Get the Record structure array corresponding to the currently set trading pair or contract code for spot or futures, i.e., K-line data.
exchange.GetRecords()
exchange.GetRecords(symbol)
exchange.GetRecords(symbol, period)
exchange.GetRecords(symbol, period, limit)
exchange.GetRecords(period)
exchange.GetRecords(period, limit)Examples
-
Get K-line data with custom period.
javascriptfunction main() { // Print K-line data with period of 120 seconds (2 minutes) Log(exchange.GetRecords(60 * 2)) // Print K-line data with period of 5 minutes Log(exchange.GetRecords(PERIOD_M5)) }pythondef main(): Log(exchange.GetRecords(60 * 2)) Log(exchange.GetRecords(PERIOD_M5))c++void main() { Log(exchange.GetRecords(60 * 2)[0]); Log(exchange.GetRecords(PERIOD_M5)[0]); } -
Output K-line bar data:
javascriptfunction main() { var records = exchange.GetRecords(PERIOD_H1) /* Due to network issues, the exchange API may be inaccessible (even if the host device can open the exchange website, the API interface may still be unavailable) In this case, records will be null, and accessing records[0].Time will cause an error, so please ensure the exchange API is accessible when testing this code */ Log("First K-line data: Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High) Log("Second K-line data: Time:", records[1].Time ,"Close:", records[1].Close) Log("Current K-line (latest)", records[records.length-1], "Previous K-line", records[records.length-2]) }pythondef main(): records = exchange.GetRecords(PERIOD_H1) Log("First K-line data: Time:", records[0]["Time"], "Open:", records[0]["Open"], "High:", records[0]["High"]) Log("Second K-line data: Time:", records[1]["Time"], "Close:", records[1]["Close"]) Log("Current K-line (latest)", records[-1], "Previous K-line", records[-2])c++void main() { auto records = exchange.GetRecords(PERIOD_H1); Log("First K-line data: Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High); Log("Second K-line data: Time:", records[1].Time, "Close:", records[1].Close); Log("Current K-line (latest)", records[records.size() - 1], "Previous K-line", records[records.size() - 2]); } -
When the configured
exchangeobject is a futures exchange object, use thesymbol,period, andlimitparameters to request K-line data for a specific instrument (futures instrument).javascriptfunction main() { var records = exchange.GetRecords("BTC_USDT.swap", 60, 100) Log(records) }pythondef main(): records = exchange.GetRecords("BTC_USDT.swap", 60, 100) Log(records)c++void main() { auto records = exchange.GetRecords("BTC_USDT.swap", 60, 100); Log(records); }
Returns
| Type | Description |
| The |
Arguments
| Name | Type | Required | Description |
symbol | string | No | The When calling the When calling the When calling the |
period | number | No | The |
limit | number | No | The |
See Also
Remarks
The default K-line period can be set in the backtest and live trading pages. If a parameter is specified when calling the exchange.GetRecords() function, it will retrieve K-line data corresponding to that parameter's period. If no parameter is specified during the function call, it will return K-line data according to the K-line period set in the backtest or live trading parameters.
The return value is an array of Record structures. The returned K-line data accumulates over time, with the upper limit of accumulated K-line bars affected by the exchange.SetMaxBarLen() function setting. When not set, the default upper limit is 5000 K-line bars. When the K-line data reaches the accumulation limit, adding a new K-line bar will simultaneously delete the earliest K-line bar (like a queue operation). Some exchanges do not provide K-line interfaces, in which case the docker will collect real-time market trade data (Trade structure array) to generate K-lines.
If the exchange's K-line interface supports pagination queries, when calling the exchange.SetMaxBarLen() function to set a larger K-line length, multiple API requests will be made.
When initially calling the exchange.GetRecords() function, the number of K-line bars obtained differs between backtesting and live trading:
-
In the backtest system, a certain number of K-line bars before the start time of the backtest time range will be pre-fetched (default is 5000, the backtest system settings and data volume will affect the final returned quantity) as initial K-line data.
-
In live trading, the specific number of K-line bars obtained is based on the maximum data volume available from the exchange's K-line interface.
When the period parameter is set to 5, it requests 5-second period K-line data. If the period parameter is not divisible by 60 (meaning the period cannot be expressed in minutes), the underlying system will use the exchange.GetTrades() related interface to obtain trade record data and synthesize the required K-line data. If the period parameter is divisible by 60, it will use at minimum 1-minute K-line data (using larger periods as much as possible to synthesize the required K-line data) to synthesize the required K-line data.
In the backtest system, simulation-level backtesting requires setting the underlying K-line period (during simulation-level backtesting, the backtest system generates tick data based on the K-line data corresponding to the set underlying K-line period). Note that the K-line data period obtained in the strategy cannot be smaller than the underlying K-line period. This is because in simulation-level backtesting, K-line data of various periods in the backtest system are synthesized from the K-line data corresponding to the underlying K-line period.
In C++ language, if you need to construct K-line data yourself, here is a code example:
c++
#include <sstream>
void main() {
Records r;
r.Valid = true;
for (auto i = 0; i < 10; i++) {
Record ele;
ele.Time = i * 100000;
ele.High = i * 10000;
ele.Low = i * 1000;
ele.Close = i * 100;
ele.Open = i * 10;
ele.Volume = i * 1;
r.push_back(ele);
}
// Output display: Records[10]
Log(r);
auto ma = TA.MA(r,10);
// Output display: [nan,nan,nan,nan,nan,nan,nan,nan,nan,450]
Log(ma);
}
Exchanges that do not support the exchange.GetRecords() function:
| Function Name | Unsupported Spot Exchanges | Unsupported Futures Exchanges |
|---|---|---|
| GetRecords | Zaif / Coincheck / BitFlyer | Futures_Aevo |
exchange.GetPeriod
Get the K-line period set on the FMZ Quant Trading Platform website page when running backtesting or live trading strategies, which is the default K-line period used when calling the exchange.GetRecords() function without parameters.
exchange.GetPeriod()Examples
javascript
function main() {
// For example, when the K-line period set on the FMZ Quant Trading Platform website page during backtesting or live trading is 1 hour
var period = exchange.GetPeriod()
Log("K-line period:", period / (60 * 60), "hours")
}
python
def main():
period = exchange.GetPeriod()
Log("K-line period:", period / (60 * 60), "hours")
c++
void main() {
auto period = exchange.GetPeriod();
Log("K-line period:", period / (60 * 60.0), "hours");
}Returns
| Type | Description |
number | The number of seconds of the K-line period, integer value, in seconds. |
See Also
exchange.SetMaxBarLen
Set the maximum length of K-line data.
exchange.SetMaxBarLen(len)Examples
javascript
function main() {
exchange.SetMaxBarLen(50)
var records = exchange.GetRecords()
Log(records.length, records)
}
python
def main():
exchange.SetMaxBarLen(50)
r = exchange.GetRecords()
Log(len(r), r)
c++
void main() {
exchange.SetMaxBarLen(50);
auto r = exchange.GetRecords();
Log(r.size(), r[0]);
}Arguments
| Name | Type | Required | Description |
len | number | Yes | The parameter |
See Also
Remarks
The exchange.SetMaxBarLen() function has two effects on cryptocurrency strategy runtime:
-
Affects the number of K-line bars obtained on the first call.
-
Affects the upper limit of the number of K-line bars.
exchange.GetRawJSON
Get the raw content returned by the most recent rest request from the current exchange object (exchange, exchanges).
exchange.GetRawJSON()Examples
javascript
function main(){
exchange.GetAccount();
var obj = JSON.parse(exchange.GetRawJSON());
Log(obj);
}
python
import json
def main():
exchange.GetAccount()
obj = json.loads(exchange.GetRawJSON())
Log(obj)
c++
void main() {
auto obj = exchange.GetAccount();
// C++ 不支持GetRawJSON函数
Log(obj);
}Returns
| Type | Description |
string | Response data from the |
See Also
Remarks
The exchange.GetRawJSON() function only supports live trading. C++ language strategies do not support this function.
exchange.GetRate
Get the current exchange rate value set for the exchange object.
exchange.GetRate()Examples
javascript
function main(){
Log(exchange.GetTicker())
// Set exchange rate conversion
exchange.SetRate(7)
Log(exchange.GetTicker())
Log("Current rate:", exchange.GetRate())
}
python
def main():
Log(exchange.GetTicker())
exchange.SetRate(7)
Log(exchange.GetTicker())
Log("Current rate:", exchange.GetRate())
c++
void main() {
Log(exchange.GetTicker());
exchange.SetRate(7);
Log(exchange.GetTicker());
Log("Current rate:", exchange.GetRate());
}Returns
| Type | Description |
number | The current exchange rate value of the exchange object. |
See Also
Remarks
If exchange.SetRate() has not been called to set the exchange rate conversion, the default rate value returned by exchange.GetRate() function is 1, indicating that the currently displayed quote currency related data has not undergone exchange rate conversion.
If the exchange rate value has been set using exchange.SetRate(), for example exchange.SetRate(7), then all price information such as market data, depth, and order prices obtained through the exchange exchange object will be multiplied by the set exchange rate 7 for conversion.
If the exchange corresponding to exchange uses USD as the quote currency, after calling exchange.SetRate(7), all prices in live trading will be multiplied by 7 to convert to prices close to CNY. At this time, the exchange rate value obtained using exchange.GetRate() is 7.
exchange.SetData
The exchange.SetData() function is used to set data loaded during strategy runtime.
exchange.SetData(key, value)Examples
The data format of the required parameter value is shown as the data variable in the following example. You can see that the timestamp 1579622400000 corresponds to the time 2020-01-22 00:00:00. After the strategy program runs to this time, before the next data timestamp 1579708800000 (i.e., time 2020-01-23 00:00:00), when calling the exchange.GetData() function to retrieve data, it will always get the content of the data [1579622400000, 123]. As the program continues to run and time progresses, data is retrieved sequentially in this manner.
In the following example, when running (backtesting or live trading), when the current moment reaches or exceeds the timestamp 1579795200000, calling the exchange.GetData() function returns: {"Time":1579795200000,"Data":["abc",123,{"price":123}]}. Where "Time":1579795200000 corresponds to 1579795200000 in the data [1579795200000, ["abc", 123, {"price": 123}]]. "Data":["abc",123,{"price":123}] corresponds to ["abc", 123, {"price": 123}] in the data [1579795200000, ["abc", 123, {"price": 123}]].
javascript
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
function main() {
var data = [
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]
exchange.SetData("test", data)
while(true) {
Log(exchange.GetData("test"))
Sleep(1000)
}
}
python
'''backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
'''
def main():
data = [
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]
exchange.SetData("test", data)
while True:
Log(exchange.GetData("test"))
Sleep(1000)
c++
/*backtest
start: 2020-01-21 00:00:00
end: 2020-02-12 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
void main() {
json data = R"([
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
])"_json;
exchange.SetData("test", data);
while(true) {
Log(exchange.GetData("test"));
Sleep(1000);
}
}Returns
| Type | Description |
number | The string length after JSON encoding of the parameter |
Arguments
| Name | Type | Required | Description |
key | string | Yes | Data collection name. |
value | array | Yes | The data to be loaded by the |
See Also
Remarks
The loaded data can be any economic indicators, industry data, related indices, etc., used for quantitative analysis of all quantifiable information in strategies.
exchange.GetData
The exchange.GetData() function is used to retrieve data loaded by the exchange.SetData() function or data provided by external links.
exchange.GetData(key)
exchange.GetData(key, timeout)Examples
-
Get the calling method for directly writing data.
javascript/*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ function main() { exchange.SetData("test", [[1579536000000, _D(1579536000000)], [1579622400000, _D(1579622400000)], [1579708800000, _D(1579708800000)]]) while(true) { Log(exchange.GetData("test")) Sleep(1000 * 60 * 60 * 24) } }python'''backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] ''' def main(): exchange.SetData("test", [[1579536000000, _D(1579536000000/1000)], [1579622400000, _D(1579622400000/1000)], [1579708800000, _D(1579708800000/1000)]]) while True: Log(exchange.GetData("test")) Sleep(1000 * 60 * 60 * 24)c++/*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ void main() { json arr = R"([[1579536000000, ""], [1579622400000, ""], [1579708800000, ""]])"_json; arr[0][1] = _D(1579536000000); arr[1][1] = _D(1579622400000); arr[2][1] = _D(1579708800000); exchange.SetData("test", arr); while(true) { Log(exchange.GetData("test")); Sleep(1000 * 60 * 60 * 24); } } -
Supports requesting data through external links. The format of the requested data:
json{ "schema":["time","data"], "data":[ [1579536000000, "abc"], [1579622400000, 123], [1579708800000, {"price": 123}], [1579795200000, ["abc", 123, {"price": 123}]] ] }Where
schemais the data format for each record in the loaded data body. This format is fixed as["time","data"], corresponding to the format of each data item in thedataattribute. Thedataattribute stores the data body, where each data item consists of a millisecond timestamp and data content (the data content can be any JSON-encodable data).Test service program written in Go:
golangpackage 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","data"}, "data": []interface{}{ []interface{}{1579536000000, "abc"}, []interface{}{1579622400000, 123}, []interface{}{1579708800000, map[string]interface{}{"price":123}}, []interface{}{1579795200000, []interface{}{"abc", 123, map[string]interface{}{"price":123}}}, }, } b, _ := json.Marshal(ret) w.Write(b) }() } func main () { fmt.Println("listen http://localhost:9090") http.HandleFunc("/data", Handle) http.ListenAndServe(":9090", nil) }Response data after the program receives a request:
json{ "schema":["time","data"], "data":[ [1579536000000, "abc"], [1579622400000, 123], [1579708800000, {"price": 123}], [1579795200000, ["abc", 123, {"price": 123}]] ] }Test strategy code:
javascript/*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ function main() { while(true) { Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")) Sleep(1000) } }python'''backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] ''' def main(): while True: Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")) Sleep(1000)c++/*backtest start: 2020-01-21 00:00:00 end: 2020-02-12 00:00:00 period: 1d basePeriod: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ void main() { while(true) { Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")); Sleep(1000); } } -
Method for calling external link data.
javascriptfunction main() { Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")) Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json")) }pythondef main(): Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")) Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"))c++void main() { Log(exchange.GetData("http://xxx.xx.x.xx:9090/data")); Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json")); } -
Request query data created on the datadata platform, requiring the response data format to be (must include time and data field descriptions in the schema):
json{ "data": [], "schema": ["time", "data"] }The "data" field contains the required data content, and the data in the "data" field must be consistent with the format agreed upon in the "schema". When calling the
exchange.GetData()function, it returns a JSON object, for example:{"Time":1579795200000, "Data":"..."}.javascriptfunction main() { Log(exchange.GetData("https://www.datadata.com/api/v1/query/xxx/data")) // The xxx part in the link is the encoding of the queried data, xxx here is an example }pythondef main(): Log(exchange.GetData("https://www.datadata.com/api/v1/query/xxx/data"))c++void main() { Log(exchange.GetData("https://www.datadata.com/api/v1/query/xxx/data")); }
Returns
| Type | Description |
object / null | Records in the data collection or data returned by the request. |
Arguments
| Name | Type | Required | Description |
key | string | Yes | Data collection name or request link. |
timeout | number | No | Used to set cache timeout in milliseconds. The default cache timeout for live trading is one minute. |
See Also
Remarks
Data is fetched all at once during backtesting, while data is cached for one minute during live trading. In the backtesting system, when using the API request method to fetch data, the backtesting system will automatically add parameters such as from (timestamp in seconds), to (timestamp in seconds), and period (underlying K-line period, timestamp in milliseconds) to the request to determine the time range of data to be retrieved.
exchange.GetMarkets
The exchange.GetMarkets() function is used to get market information from the exchange.
exchange.GetMarkets()Examples
-
Example of calling futures exchange object:
javascriptfunction main() { var markets = exchange.GetMarkets() var currency = exchange.GetCurrency() // 获取当前合约代码也可以用exchange.GetContractType()函数 var ct = "swap" var key = currency + "." + ct Log(key, ":", markets[key]) }pythondef main(): markets = exchange.GetMarkets() currency = exchange.GetCurrency() ct = "swap" key = currency + "." + ct Log(key, ":", markets[key])c++void main() { auto markets = exchange.GetMarkets(); auto currency = exchange.GetCurrency(); auto ct = "swap"; auto key = currency + "." + ct; Log(key, ":", markets[key]); } -
Using futures exchange object to call
exchange.GetMarkets()function in the backtesting system. Before calling any market data functions, GetMarkets only returns the market data of the current default trading pair; after calling market data functions, it will return the market data of all requested instruments. Please refer to the following test example:javascript/*backtest start: 2023-05-10 00:00:00 end: 2023-05-20 00:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ function main() { var arrSymbol = ["SOL_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"] var tbl1 = { type: "table", title: "markets1", cols: ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], rows: [] } var markets1 = exchange.GetMarkets() for (var key in markets1) { var market = markets1[key] tbl1.rows.push([key, market.Symbol, market.BaseAsset, market.QuoteAsset, market.TickSize, market.AmountSize, market.PricePrecision, market.AmountPrecision, market.MinQty, market.MaxQty, market.MinNotional, market.MaxNotional, market.CtVal]) } for (var symbol of arrSymbol) { exchange.GetTicker(symbol) } var tbl2 = { type: "table", title: "markets2", cols: ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], rows: [] } var markets2 = exchange.GetMarkets() for (var key in markets2) { var market = markets2[key] tbl2.rows.push([key, market.Symbol, market.BaseAsset, market.QuoteAsset, market.TickSize, market.AmountSize, market.PricePrecision, market.AmountPrecision, market.MinQty, market.MaxQty, market.MinNotional, market.MaxNotional, market.CtVal]) } LogStatus("`" + JSON.stringify([tbl1, tbl2]) + "`") }python'''backtest start: 2023-05-10 00:00:00 end: 2023-05-20 00:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] ''' import json def main(): arrSymbol = ["SOL_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"] tbl1 = { "type": "table", "title": "markets1", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": [] } markets1 = exchange.GetMarkets() for key in markets1: market = markets1[key] tbl1["rows"].append([key, market["Symbol"], market["BaseAsset"], market["QuoteAsset"], market["TickSize"], market["AmountSize"], market["PricePrecision"], market["AmountPrecision"], market["MinQty"], market["MaxQty"], market["MinNotional"], market["MaxNotional"], market["CtVal"]]) for symbol in arrSymbol: exchange.GetTicker(symbol) tbl2 = { "type": "table", "title": "markets2", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": [] } markets2 = exchange.GetMarkets() for key in markets2: market = markets2[key] tbl2["rows"].append([key, market["Symbol"], market["BaseAsset"], market["QuoteAsset"], market["TickSize"], market["AmountSize"], market["PricePrecision"], market["AmountPrecision"], market["MinQty"], market["MaxQty"], market["MinNotional"], market["MaxNotional"], market["CtVal"]]) LogStatus("`" + json.dumps([tbl1, tbl2]) + "`")c++/*backtest start: 2023-05-10 00:00:00 end: 2023-05-20 00:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ void main() { auto arrSymbol = {"SOL_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"}; json tbl1 = R"({ "type": "table", "title": "markets1", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": [] })"_json; auto markets1 = exchange.GetMarkets(); for (auto& [key, market] : markets1.items()) { json arrJson = {key, market["Symbol"], market["BaseAsset"], market["QuoteAsset"], market["TickSize"], market["AmountSize"], market["PricePrecision"], market["AmountPrecision"], market["MinQty"], market["MaxQty"], market["MinNotional"], market["MaxNotional"], market["CtVal"]}; tbl1["rows"].push_back(arrJson); } for (const auto& symbol : arrSymbol) { exchange.GetTicker(symbol); } json tbl2 = R"({ "type": "table", "title": "markets2", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": [] })"_json; auto markets2 = exchange.GetMarkets(); for (auto& [key, market] : markets2.items()) { json arrJson = {key, market["Symbol"], market["BaseAsset"], market["QuoteAsset"], market["TickSize"], market["AmountSize"], market["PricePrecision"], market["AmountPrecision"], market["MinQty"], market["MaxQty"], market["MinNotional"], market["MaxNotional"], market["CtVal"]}; tbl2["rows"].push_back(arrJson); } json tbls = R"([])"_json; tbls.push_back(tbl1); tbls.push_back(tbl2); LogStatus("`" + tbls.dump() + "`"); }
Returns
| Type | Description |
object / null | Dictionary containing |
See Also
Remarks
The exchange.GetMarkets() function returns a dictionary with trading symbol names as keys. For spot trading, the format is fixed as trading pairs, for example:
json
{
"BTC_USDT" : {...}, // Value is Market structure
"LTC_USDT" : {...},
...
}
For futures contract exchanges, since one symbol may contain multiple contracts, for example: BTC_USDT trading pair includes perpetual contracts, quarterly contracts, etc. The exchange.GetMarkets() function returns a dictionary with keys as the combination of trading pair and contract code, for example:
json
{
"BTC_USDT.swap" : {...}, // Value is Market structure
"BTC_USDT.quarter" : {...},
"LTC_USDT.swap" : {...},
...
}
- The
exchange.GetMarkets()function supports both live trading and backtesting systems. - The
exchange.GetMarkets()function only returns market information for symbols that are actively trading on the exchange. exchange.GetMarkets()does not support options contracts.
Exchanges that do not support the exchange.GetMarkets() function:
| Function Name | Unsupported Spot Exchanges | Unsupported Futures Exchanges |
|---|---|---|
| GetMarkets | Coincheck / Bithumb / BitFlyer | -- |
exchange.GetTickers
The exchange.GetTickers() function is used to get aggregated market data from the exchange (array of Ticker structures). When exchange is a spot exchange object, it returns market data for all trading pairs; when exchange is a futures exchange object, it returns market data for all contracts.
exchange.GetTickers()Examples
-
Call the
exchange.GetTickers()function to get aggregated market data.javascriptfunction main() { var tickers = exchange.GetTickers() if (tickers && tickers.length > 0) { Log("Number of tradable symbols:", tickers.length) } }pythondef main(): tickers = exchange.GetTickers() if tickers and len(tickers) > 0: Log("Number of tradable symbols:", len(tickers))c++void main() { auto tickers = exchange.GetTickers(); if (tickers.Valid && tickers.size() > 0) { Log("Number of tradable symbols:", tickers.size()); } } -
Using spot exchange object, call the
exchange.GetTickers()function in the backtesting system. Before calling any market data functions, GetTickers only returns the ticker data of the current default trading pair; after calling market data functions, it will return ticker data for all requested symbols. Please refer to the following test example:javascript/*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ function main() { var arrSymbol = ["ADA_USDT", "LTC_USDT", "ETH_USDT", "SOL_USDT"] // Before requesting other trading pair market data, call GetTickers var tickers1 = exchange.GetTickers() var tbl1 = {type: "table", title: "tickers1", cols: ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], rows: []} for (var ticker of tickers1) { tbl1.rows.push([ticker.Symbol, ticker.High, ticker.Open, ticker.Low, ticker.Last, ticker.Buy, ticker.Sell, ticker.Time, ticker.Volume]) } // Request other trading pair market data for (var symbol of arrSymbol) { exchange.GetTicker(symbol) } // Call GetTickers again var tickers2 = exchange.GetTickers() var tbl2 = {type: "table", title: "tickers2", cols: ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], rows: []} for (var ticker of tickers2) { tbl2.rows.push([ticker.Symbol, ticker.High, ticker.Open, ticker.Low, ticker.Last, ticker.Buy, ticker.Sell, ticker.Time, ticker.Volume]) } LogStatus("`" + JSON.stringify([tbl1, tbl2]) + "`") }python'''backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] ''' import json def main(): arrSymbol = ["ADA_USDT", "LTC_USDT", "ETH_USDT", "SOL_USDT"] tickers1 = exchange.GetTickers() tbl1 = {"type": "table", "title": "tickers1", "cols": ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], "rows": []} for ticker in tickers1: tbl1["rows"].append([ticker["Symbol"], ticker["High"], ticker["Open"], ticker["Low"], ticker["Last"], ticker["Buy"], ticker["Sell"], ticker["Time"], ticker["Volume"]]) for symbol in arrSymbol: exchange.GetTicker(symbol) tickers2 = exchange.GetTickers() tbl2 = {"type": "table", "title": "tickers2", "cols": ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], "rows": []} for ticker in tickers2: tbl2["rows"].append([ticker["Symbol"], ticker["High"], ticker["Open"], ticker["Low"], ticker["Last"], ticker["Buy"], ticker["Sell"], ticker["Time"], ticker["Volume"]]) LogStatus("`" + json.dumps([tbl1, tbl2]) + "`")c++/*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ json tickerToJson(const Ticker& ticker) { json arrJson; arrJson.push_back(ticker.Symbol); arrJson.push_back(ticker.High); arrJson.push_back(ticker.Open); arrJson.push_back(ticker.Low); arrJson.push_back(ticker.Last); arrJson.push_back(ticker.Buy); arrJson.push_back(ticker.Sell); arrJson.push_back(ticker.Time); arrJson.push_back(ticker.Volume); return arrJson; } void main() { std::string arrSymbol[] = {"ADA_USDT", "LTC_USDT", "ETH_USDT", "SOL_USDT"}; auto tickers1 = exchange.GetTickers(); json tbl1 = R"({ "type": "table", "cols": ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], "rows": [] })"_json; tbl1["title"] = "tickers1"; for (const auto& ticker : tickers1) { json arrJson = tickerToJson(ticker); tbl1["rows"].push_back(arrJson); } for (const std::string& symbol : arrSymbol) { exchange.GetTicker(symbol); } auto tickers2 = exchange.GetTickers(); json tbl2 = R"({ "type": "table", "cols": ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], "rows": [] })"_json; tbl2["title"] = "tickers2"; for (const auto& ticker : tickers2) { json arrJson = tickerToJson(ticker); tbl2["rows"].push_back(arrJson); } json tbls = R"([])"_json; tbls.push_back(tbl1); tbls.push_back(tbl2); LogStatus("`" + tbls.dump() + "`"); }
Returns
| Type | Description |
| The |
See Also
Remarks
Notes:
-
This function requests the exchange's aggregated market data interface. There is no need to set trading pairs or contract codes before calling. It only returns market data for instruments currently listed on the exchange.
-
The backtesting system supports this function.
-
Exchange objects that do not provide aggregated market data interfaces do not support this function.
-
This function does not support options contracts.
Exchanges that do not support the exchange.GetTickers() function:
| Function Name | Unsupported Spot Exchanges | Unsupported Futures Exchanges |
|---|---|---|
| GetTickers | Zaif / WOO / Gemini / Coincheck / BitFlyer / Bibox | Futures_WOO / Futures_dYdX / Futures_Deribit / Futures_Bibox / Futures_Aevo / Futures_edgeX |
Trade
exchange.Buy
The exchange.Buy() function is used to place a buy order. The Buy() function is a member function of the exchange object exchange. The Buy() function operates on the exchange account bound to the exchange object exchange. The purpose of member functions (methods) of the exchange object is only related to exchange, which will not be repeated in subsequent documentation.
exchange.Buy(price, amount)
exchange.Buy(price, amount, ...args)Examples
-
The order ID returned by
exchange.Buy()can be used to query order information and cancel orders.javascriptfunction main() { var id = exchange.Buy(100, 1); Log("id:", id); }pythondef main(): id = exchange.Buy(100, 1) Log("id:", id)c++void main() { auto id = exchange.Buy(100, 1); Log("id:", id); } -
When placing orders for cryptocurrency futures contracts, you must ensure the trading direction is set correctly. If the trading direction does not match the trading function, an error will occur:
logdirection is sell, invalid order type Buy direction is buy, invalid order type Sell direction is closebuy, invalid order type Buy direction is closesell, invalid order type Selljavascript// The following are incorrect calls function main() { exchange.SetContractType("quarter") // Set short direction exchange.SetDirection("sell") // Place buy order, will error, short can only sell var id = exchange.Buy(50, 1) // Set long direction exchange.SetDirection("buy") // Place sell order, will error, long can only buy var id2 = exchange.Sell(60, 1) // Set close long direction exchange.SetDirection("closebuy") // Place buy order, will error, close long can only sell var id3 = exchange.Buy(-1, 1) // Set close short direction exchange.SetDirection("closesell") // Place sell order, will error, close short can only buy var id4 = exchange.Sell(-1, 1) }python# The following are incorrect calls def main(): exchange.SetContractType("quarter") exchange.SetDirection("sell") id = exchange.Buy(50, 1) exchange.SetDirection("buy") id2 = exchange.Sell(60, 1) exchange.SetDirection("closebuy") id3 = exchange.Buy(-1, 1) exchange.SetDirection("closesell") id4 = exchange.Sell(-1, 1)c++// The following are incorrect calls void main() { exchange.SetContractType("quarter"); exchange.SetDirection("sell"); auto id = exchange.Buy(50, 1); exchange.SetDirection("buy"); auto id2 = exchange.Sell(60, 1); exchange.SetDirection("closebuy"); auto id3 = exchange.Buy(-1, 1); exchange.SetDirection("closesell"); auto id4 = exchange.Sell(-1, 1); } -
Spot market order.
javascript// For example, trading pair: ETH_BTC, market buy order function main() { // Place market buy order, buy ETH worth 0.1 BTC (quote currency) exchange.Buy(-1, 0.1) }pythondef main(): exchange.Buy(-1, 0.1)c++void main() { exchange.Buy(-1, 0.1); }
Returns
| Type | Description |
string / null | Returns the order Id on successful order placement, returns null on failure. The |
Arguments
| Name | Type | Required | Description |
price | number | Yes | The |
amount | number | Yes | The |
arg | string / number / bool / object / array / any (any type supported by the platform) | No | Extended parameters that can output additional information to this order log. Multiple |
See Also
exchange.Sell exchange.SetContractType exchange.SetDirection exchange.IO (API rate limiting control Buy function is affected by CreateOrder rate limit settings)
Remarks
When placing orders for futures contracts, you must ensure the trading direction is set correctly. An error will be reported if the trading direction does not match the trading function. Unless otherwise specified, the order quantity for cryptocurrency futures contract exchanges is in number of contracts.
Setting the price parameter to -1 is used to place market orders, which requires the exchange's order interface to support market orders. For cryptocurrency spot market orders, when placing buy orders, the order quantity parameter amount is the amount in quote currency. For cryptocurrency futures contract market orders, the order quantity parameter amount is in number of contracts. In live trading, a few cryptocurrency exchanges do not support market order interfaces. For some spot exchanges, the order quantity for market buy orders is in base currency. Please refer to the Exchange Special Instructions in the "User Guide" for details.
If using an older version of the docker, the return value order Id of the exchange.Buy() function may differ from the return value order Id described in the current documentation.
Note that the following three exchanges have special order interfaces. For spot market buy orders, the order quantity is in coins, not in amount.
-
AscendEx -
BitMEX -
Bitfinex
exchange.Sell
The exchange.Sell() function is used to place a sell order.
exchange.Sell(price, amount)
exchange.Sell(price, amount, ...args)Examples
-
The order ID returned by
exchange.Sell()can be used to query order information and cancel orders.javascriptfunction main(){ var id = exchange.Sell(100, 1) Log("id:", id) }pythondef main(): id = exchange.Sell(100, 1) Log("id:", id)c++void main() { auto id = exchange.Sell(100, 1); Log("id:", id); } -
When placing orders for cryptocurrency futures contracts, you must ensure the trading direction is set correctly. If the trading direction does not match the trading function, an error will occur:
logdirection is sell, invalid order type Buy direction is buy, invalid order type Sell direction is closebuy, invalid order type Buy direction is closesell, invalid order type Selljavascript// The following are incorrect calls function main() { exchange.SetContractType("quarter") // Set short direction exchange.SetDirection("sell") // Place buy order, will error, short can only sell var id = exchange.Buy(50, 1) // Set long direction exchange.SetDirection("buy") // Place sell order, will error, long can only buy var id2 = exchange.Sell(60, 1) // Set close long direction exchange.SetDirection("closebuy") // Place buy order, will error, close long can only sell var id3 = exchange.Buy(-1, 1) // Set close short direction exchange.SetDirection("closesell") // Place sell order, will error, close short can only buy var id4 = exchange.Sell(-1, 1) }python# The following are incorrect calls def main(): exchange.SetContractType("quarter") exchange.SetDirection("sell") id = exchange.Buy(50, 1) exchange.SetDirection("buy") id2 = exchange.Sell(60, 1) exchange.SetDirection("closebuy") id3 = exchange.Buy(-1, 1) exchange.SetDirection("closesell") id4 = exchange.Sell(-1, 1)c++// The following are incorrect calls void main() { exchange.SetContractType("quarter"); exchange.SetDirection("sell"); auto id = exchange.Buy(50, 1); exchange.SetDirection("buy"); auto id2 = exchange.Sell(60, 1); exchange.SetDirection("closebuy"); auto id3 = exchange.Buy(-1, 1); exchange.SetDirection("closesell"); auto id4 = exchange.Sell(-1, 1); } -
Spot market order.
javascript// For example, trading pair: ETH_BTC, market sell order function main() { // Note: Place market sell order, sell 0.2 ETH exchange.Sell(-1, 0.2) }pythondef main(): exchange.Sell(-1, 0.2)c++void main() { exchange.Sell(-1, 0.2); }
Returns
| Type | Description |
string / null | Returns the order Id on successful order placement, returns null on failed order placement. The |
Arguments
| Name | Type | Required | Description |
price | number | Yes | The |
amount | number | Yes | The |
arg | string / number / bool / object / array / any (any type supported by the platform) | No | Extended parameters that can output additional information to this order log entry. Multiple |
See Also
exchange.Buy exchange.SetContractType exchange.SetDirection exchange.IO (API rate limiting control Sell function is affected by CreateOrder rate limit settings)
Remarks
When placing orders for futures contracts, ensure the trading direction is set correctly. An error will occur if the trading direction does not match the trading function. Unless otherwise specified, the order quantity for cryptocurrency futures contract exchanges is in number of contracts.
Setting the price parameter to -1 places a market order, which requires the exchange's order interface to support market orders. For cryptocurrency spot market orders, when placing a sell order, the order quantity parameter amount is denominated in the trading currency. For cryptocurrency futures contract market orders, the order quantity parameter amount is denominated in number of contracts. In live trading, a few cryptocurrency exchanges do not support market order interfaces.
If using an older version of the docker, the return value order Id from the exchange.Sell() function may differ from the return value order Id described in the current documentation.
exchange.CreateOrder
The exchange.CreateOrder() function is used to place an order.
exchange.CreateOrder(symbol, side, price, amount)
exchange.CreateOrder(symbol, side, price, amount, ...args)Examples
-
Spot exchange objects and futures exchange objects call the
exchange.CreateOrder()function to place orders.javascriptfunction main() { var id = exchange.CreateOrder("BTC_USDT", "buy", 60000, 0.01) // Spot exchange object places order for BTC_USDT spot trading pair // var id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01) // Futures exchange object places order for BTC USDT-margined perpetual contract Log("Order Id:", id) }pythondef main(): id = exchange.CreateOrder("BTC_USDT", "buy", 60000, 0.01) # Spot exchange object places order for BTC_USDT spot trading pair # id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01) # Futures exchange object places order for BTC USDT-margined perpetual contract Log("Order Id:", id)c++void main() { auto id = exchange.CreateOrder("BTC_USDT", "buy", 60000, 0.01); // Spot exchange object places order for BTC_USDT spot trading pair // auto id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01); // Futures exchange object places order for BTC USDT-margined perpetual contract Log("Order Id:", id); } -
Place orders using additional parameters (option) to pass exchange-specific parameters.
javascriptfunction main() { // Pass option parameter in JSON format var option = { "type": "TRAILING_STOP_MARKET", "activationPrice": "2300", "callbackRate": "0.1" } var sideWithOption = "buy;" + JSON.stringify(option) var id = exchange.CreateOrder("SOL_USDT.swap", sideWithOption, -1, 1) Log("Order Id:", id) Sleep(2000) Log(exchange.GetOrder(id)) }pythonimport json def main(): # Pass option parameter in JSON format option = { "type": "TRAILING_STOP_MARKET", "activationPrice": "2300", "callbackRate": "0.1" } sideWithOption = "buy;" + json.dumps(option) id = exchange.CreateOrder("SOL_USDT.swap", sideWithOption, -1, 1) Log("Order Id:", id) Sleep(2000) Log(exchange.GetOrder(id))c++void main() { // Pass option parameter in JSON format json option = R"({ "type": "TRAILING_STOP_MARKET", "activationPrice": "2300", "callbackRate": "0.1" })"_json; string sideWithOption = "buy;" + option.dump(); auto id = exchange.CreateOrder("SOL_USDT.swap", sideWithOption, -1, 1); Log("Order Id:", id); Sleep(2000); Log(exchange.GetOrder(id)); }
Returns
| Type | Description |
string / null value | Returns the order Id if the order is placed successfully, returns null value if the order fails. The When calling the |
Arguments
| Name | Type | Required | Description |
symbol | string | Yes | The parameter When calling the When calling the When calling the |
side | string | Yes | The parameter For spot exchange objects, the optional values for the For futures exchange objects, the optional values for the Supports additional parameters (option): Additional parameters can be passed through the For example: Additional parameters are used to pass exchange-specific parameters (such as order type, time-in-force rules, etc.), and the specific supported parameters depend on the exchange API. |
price | number | Yes | The parameter |
amount | number | Yes | The parameter |
arg | string / number / bool / object / array / any (any type supported by the platform) | No | Extended parameters, can output additional information to this order log, the |
See Also
Remarks
Supports passing additional parameters (option) through the side parameter to pass exchange-specific parameters. The additional parameters need to be merged with the side parameter in the format "side;{JSON object}" (recommended) or "side;key=value&key=value" (URL-encoded format). For example: "buy;{\"type\":\"TRAILING_STOP_MARKET\"}".
Different exchanges support different option parameters. Please refer to the exchange API documentation for specific supported parameters. Common parameters include: order type (type), time in force (timeInForce), activation price (activationPrice), callback rate (callbackRate), etc.
When using the option parameter, the price and amount parameters still need to be provided. If certain parameters in the exchange API have already been passed through option, these basic parameters may be overridden by the corresponding parameters in option. The specific behavior depends on the exchange API implementation.
exchange.CancelOrder
The exchange.CancelOrder() function is used to cancel an order. The Id attribute of the FMZ platform's order Order structure consists of the exchange product code and the exchange's original order ID, separated by an English comma. For example, the Id attribute format for an order of the spot trading pair ETH_USDT on the OKX exchange is: ETH-USDT,1547130415509278720.
When calling the exchange.CancelOrder() function to cancel an order, the orderId parameter passed in should be consistent with the Id attribute of the order Order structure.
exchange.CancelOrder(orderId)
exchange.CancelOrder(orderId, ...args)Examples
-
Cancel an order.
javascriptfunction main(){ var id = exchange.Sell(99999, 1) exchange.CancelOrder(id) }pythondef main(): id = exchange.Sell(99999, 1) exchange.CancelOrder(id)c++void main() { auto id = exchange.Sell(99999, 1); exchange.CancelOrder(id); } -
In FMZ's API functions that can generate log output, such as
Log(),exchange.Buy(),exchange.CancelOrder(), etc., additional output parameters can be appended after the required parameters. For example:exchange.CancelOrder(orders[i].Id, orders[i]), this way when canceling the order with Idorders[i].Id, it will also output the order information, i.e., theOrderstructureorders[i].javascriptfunction main() { if (exchange.GetName().includes("Futures_")) { Log("Set contract to: perpetual swap, set direction to: open long.") exchange.SetContractType("swap") exchange.SetDirection("buy") } var ticker = exchange.GetTicker() exchange.Buy(ticker.Last * 0.5, 0.1) var orders = exchange.GetOrders() for (var i = 0 ; i < orders.length ; i++) { exchange.CancelOrder(orders[i].Id, "Canceled order:", orders[i]) Sleep(500) } }pythondef main(): if exchange.GetName().find("Futures_") != -1: Log("Set contract to: perpetual swap, set direction to: open long.") exchange.SetContractType("swap") exchange.SetDirection("buy") ticker = exchange.GetTicker() exchange.Buy(ticker["Last"] * 0.5, 0.1) orders = exchange.GetOrders() for i in range(len(orders)): exchange.CancelOrder(orders[i]["Id"], "Canceled order:", orders[i]) Sleep(500)c++void main() { if (exchange.GetName().find("Futures_") != std::string::npos) { Log("Set contract to: perpetual swap, set direction to: open long."); exchange.SetContractType("swap"); exchange.SetDirection("buy"); } auto ticker = exchange.GetTicker(); exchange.Buy(ticker.Last * 0.5, 0.1); auto orders = exchange.GetOrders(); for (int i = 0 ; i < orders.size() ; i++) { exchange.CancelOrder(orders[i].Id, "Canceled order:", orders[i]); Sleep(500); } }
Returns
| Type | Description |
bool | The |
Arguments
| Name | Type | Required | Description |
orderId | string | Yes | The |
arg | string / number / bool / object / array / any (any type supported by the platform) | No | Extended parameters that can output additional information to this cancel order log. Multiple |
See Also
Remarks
If using an older version of the docker, the orderId parameter of the exchange.CancelOrder() function may differ from the orderId described in the current documentation.
exchange.GetOrder
The exchange.GetOrder() function is used to get order information.
exchange.GetOrder(orderId)Examples
javascript
function main(){
var id = exchange.Sell(1000, 1)
// The parameter id is the order number, you need to fill in the order number you want to query
var order = exchange.GetOrder(id)
Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:",
order.DealAmount, "Status:", order.Status, "Type:", order.Type)
}
python
def main():
id = exchange.Sell(1000, 1)
order = exchange.GetOrder(id)
Log("Id:", order["Id"], "Price:", order["Price"], "Amount:", order["Amount"], "DealAmount:",
order["DealAmount"], "Status:", order["Status"], "Type:", order["Type"])
c++
void main() {
auto id = exchange.Sell(1000, 1);
auto order = exchange.GetOrder(id);
Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount, "DealAmount:",
order.DealAmount, "Status:", order.Status, "Type:", order.Type);
}Returns
| Type | Description |
| Query order details by order ID. Returns the |
Arguments
| Name | Type | Required | Description |
orderId | string | Yes | The When calling the |
See Also
Remarks
Some exchanges do not support the exchange.GetOrder() function. The AvgPrice attribute in the returned Order structure is the average execution price. Some exchanges do not support this field, and it is set to 0 when not supported.
If using an older version of the docker, the orderId parameter of the exchange.GetOrder() function may differ from the orderId described in the current documentation.
Exchanges that do not support the exchange.GetOrder() function:
| Function Name | Unsupported Spot Exchanges | Unsupported Futures Exchanges |
|---|---|---|
| GetOrder | Zaif / Coincheck / Bitstamp | -- |
exchange.GetOrders
The exchange.GetOrders() function is used to get unfilled orders.
exchange.GetOrders()
exchange.GetOrders(symbol)Examples
-
Using spot exchange objects to operate on multiple different trading pairs, placing buy orders at half the current price, then querying pending order information.
javascript/*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ function main() { var arrSymbol = ["ETH_USDT", "BTC_USDT", "LTC_USDT", "SOL_USDT"] for (var symbol of arrSymbol) { var t = exchange.GetTicker(symbol) exchange.CreateOrder(symbol, "buy", t.Last / 2, 0.01) } var spotOrders = exchange.GetOrders() var tbls = [] for (var orders of [spotOrders]) { var tbl = {type: "table", title: "test GetOrders", cols: ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []} for (var order of orders) { tbl.rows.push([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType]) } tbls.push(tbl) } LogStatus("`" + JSON.stringify(tbls) + "`") // 打印输出一次信息后返回,防止后续回测时订单成交,影响数据观察 return }python'''backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] ''' import json def main(): arrSymbol = ["ETH_USDT", "BTC_USDT", "LTC_USDT", "SOL_USDT"] for symbol in arrSymbol: t = exchange.GetTicker(symbol) exchange.CreateOrder(symbol, "buy", t["Last"] / 2, 0.01) spotOrders = exchange.GetOrders() tbls = [] for orders in [spotOrders]: tbl = {"type": "table", "title": "test GetOrders", "cols": ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], "rows": []} for order in orders: tbl["rows"].append([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType]) tbls.append(tbl) LogStatus("`" + json.dumps(tbls) + "`") returnc++/*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Binance","currency":"BTC_USDT"}] */ void main() { auto arrSymbol = {"ETH_USDT", "BTC_USDT", "LTC_USDT", "SOL_USDT"}; for (const auto& symbol : arrSymbol) { auto t = exchange.GetTicker(symbol); exchange.CreateOrder(symbol, "buy", t.Last / 2, 0.01); } auto spotOrders = exchange.GetOrders(); json tbls = R"([])"_json; std::vector<std::vector<Order>> arr = {spotOrders}; for (const auto& orders : arr) { json tbl = R"({ "type": "table", "title": "test GetOrders", "cols": ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], "rows": [] })"_json; for (const auto& order : orders) { json arrJson = R"([])"_json; arrJson.push_back("Symbol"); arrJson.push_back("Id"); arrJson.push_back(order.Price); arrJson.push_back(order.Amount); arrJson.push_back(order.DealAmount); arrJson.push_back(order.AvgPrice); arrJson.push_back(order.Status); arrJson.push_back(order.Type); arrJson.push_back(order.Offset); arrJson.push_back(order.ContractType); tbl["rows"].push_back(arrJson); } tbls.push_back(tbl); } LogStatus(_D(), "\n", "`" + tbls.dump() + "`"); return; } -
Use futures exchange object to place orders for multiple trading pairs and contract codes. Set order prices far from the order book counterparty prices to keep orders in unfilled status, and query orders in various ways.
javascript/*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ function main() { var arrSymbol = ["BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"] for (var symbol of arrSymbol) { var t = exchange.GetTicker(symbol) exchange.CreateOrder(symbol, "buy", t.Last / 2, 1) exchange.CreateOrder(symbol, "sell", t.Last * 2, 1) } var defaultOrders = exchange.GetOrders() var swapOrders = exchange.GetOrders("USDT.swap") var futuresOrders = exchange.GetOrders("USDT.futures") var btcUsdtSwapOrders = exchange.GetOrders("BTC_USDT.swap") var tbls = [] var arr = [defaultOrders, swapOrders, futuresOrders, btcUsdtSwapOrders] var tblDesc = ["defaultOrders", "swapOrders", "futuresOrders", "btcUsdtSwapOrders"] for (var index in arr) { var orders = arr[index] var tbl = {type: "table", title: tblDesc[index], cols: ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []} for (var order of orders) { tbl.rows.push([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType]) } tbls.push(tbl) } LogStatus("`" + JSON.stringify(tbls) + "`") // 打印输出一次信息后返回,防止后续回测时订单成交,影响数据观察 return }python'''backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] ''' import json def main(): arrSymbol = ["BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"] for symbol in arrSymbol: t = exchange.GetTicker(symbol) exchange.CreateOrder(symbol, "buy", t["Last"] / 2, 1) exchange.CreateOrder(symbol, "sell", t["Last"] * 2, 1) defaultOrders = exchange.GetOrders() swapOrders = exchange.GetOrders("USDT.swap") futuresOrders = exchange.GetOrders("USDT.futures") btcUsdtSwapOrders = exchange.GetOrders("BTC_USDT.swap") tbls = [] arr = [defaultOrders, swapOrders, futuresOrders, btcUsdtSwapOrders] tblDesc = ["defaultOrders", "swapOrders", "futuresOrders", "btcUsdtSwapOrders"] for index in range(len(arr)): orders = arr[index] tbl = {"type": "table", "title": tblDesc[index], "cols": ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], "rows": []} for order in orders: tbl["rows"].append([order["Symbol"], order["Id"], order["Price"], order["Amount"], order["DealAmount"], order["AvgPrice"], order["Status"], order["Type"], order["Offset"], order["ContractType"]]) tbls.append(tbl) LogStatus("`" + json.dumps(tbls) + "`") returnc++/*backtest start: 2024-05-21 00:00:00 end: 2024-09-05 00:00:00 period: 5m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ void main() { auto arrSymbol = {"BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"}; for (const auto& symbol : arrSymbol) { auto t = exchange.GetTicker(symbol); exchange.CreateOrder(symbol, "buy", t.Last / 2, 1); exchange.CreateOrder(symbol, "sell", t.Last * 2, 1); } auto defaultOrders = exchange.GetOrders(); auto swapOrders = exchange.GetOrders("USDT.swap"); auto futuresOrders = exchange.GetOrders("USDT.futures"); auto btcUsdtSwapOrders = exchange.GetOrders("BTC_USDT.swap"); json tbls = R"([])"_json; std::vector<std::vector<Order>> arr = {defaultOrders, swapOrders, futuresOrders, btcUsdtSwapOrders}; std::string tblDesc[] = {"defaultOrders", "swapOrders", "futuresOrders", "btcUsdtSwapOrders"}; for (int index = 0; index < arr.size(); index++) { auto orders = arr[index]; json tbl = R"({ "type": "table", "cols": ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], "rows": [] })"_json; tbl["title"] = tblDesc[index]; for (const auto& order : orders) { json arrJson = R"([])"_json; arrJson.push_back(order.Symbol); arrJson.push_back(to_string(order.Id)); // Order订单结构中的Id属性类型为TId,使用FMZ平台内置的C++函数to_string进行编码 arrJson.push_back(order.Price); arrJson.push_back(order.Amount); arrJson.push_back(order.DealAmount); arrJson.push_back(order.AvgPrice); arrJson.push_back(order.Status); arrJson.push_back(order.Type); arrJson.push_back(order.Offset); arrJson.push_back(order.ContractType); tbl["rows"].push_back(arrJson); } tbls.push_back(tbl); } LogStatus(_D(), "\n", "`" + tbls.dump() + "`"); return; } -
When calling the
exchange.GetOrders()function, pass theSymbolparameter to specify the order data for the trading pair or contract code to be queried.javascriptfunction main() { var orders = exchange.GetOrders("BTC_USDT") // 现货品种举例 // var orders = exchange.GetOrders("BTC_USDT.swap") // 期货品种举例 Log("orders:", orders) }pythondef main(): orders = exchange.GetOrders("BTC_USDT") # 现货品种举例 # orders = exchange.GetOrders("BTC_USDT.swap") # 期货品种举例 Log("orders:", orders)c++void main() { auto orders = exchange.GetOrders("BTC_USDT"); // 现货品种举例 // auto orders = exchange.GetOrders("BTC_USDT.swap"); // 期货品种举例 Log("orders:", orders); }
Returns
| Type | Description |
| The |
Arguments
| Name | Type | Required | Description |
symbol | string | No | The For spot exchange objects, when the For futures exchange objects, when the |
See Also
Remarks
Summary of symbol parameter usage scenarios in the GetOrders function:
| Exchange Object Category | symbol Parameter | Query Scope | Notes |
|---|---|---|---|
| Spot | No symbol parameter | Query all spot trading pairs | In all usage scenarios, if the exchange API does not support it, an error will be reported and null value returned, not repeated hereafter |
| Spot | Specify trading variety, symbol parameter: "BTC_USDT" | Query the specified BTC_USDT trading pair | For spot exchange objects, the symbol parameter format is: "BTC_USDT" |
| Futures | No symbol parameter | Query all trading varieties within the current trading pair and contract code dimension | Assuming the current trading pair is BTC_USDT and the contract code is swap, this queries all USDT-margined perpetual contracts. Equivalent to calling GetOrders("USDT.swap") |
| Futures | Specify trading variety, symbol parameter: "BTC_USDT.swap" | Query the specified BTC USDT-margined perpetual contract | For futures exchange objects, the symbol parameter format is: a combination of trading pair and contract code defined by the FMZ platform, separated by the character "." |
| Futures | Specify trading variety range, symbol parameter: "USDT.swap" | Query all USDT-margined perpetual contracts | - |
| Futures exchanges supporting options | No symbol parameter | Query all option contracts within the current trading pair dimension | Assuming the current trading pair is BTC_USDT and the contract is set to option contracts, for example Binance option contract: BTC-240108-40000-C |
| Futures exchanges supporting options | Specify specific trading variety | Query the specified option contract | For example, for Binance futures exchange, the symbol parameter is: BTC_USDT.BTC-240108-40000-C |
| Futures exchanges supporting options | Specify trading variety range, symbol parameter: "USDT.option" | Query all USDT-margined option contracts | - |
Summary of futures exchange object query dimension ranges in the GetOrders function:
| symbol Parameter | Request Scope Definition | Notes |
|---|---|---|
| USDT.swap | USDT-margined perpetual contract range. | For dimensions not supported by the exchange API interface, calling will report an error and return null value. |
| USDT.futures | USDT-margined delivery contract range. | - |
| USD.swap | Coin-margined perpetual contract range. | - |
| USD.futures | Coin-margined delivery contract range. | - |
| USDT.option | USDT-margined option contract range. | - |
| USD.option | Coin-margined option contract range. | - |
| USDT.futures_combo | Spread combination contract range. | Futures_Deribit exchange |
| USD.futures_ff | Multi-collateral delivery contract range. | Futures_Kraken exchange |
| USD.swap_pf | Multi-collateral perpetual contract range. | Futures_Kraken exchange |
When the account represented by the exchange object exchange has no pending orders (active orders in unfilled status) within the query scope or specified trading variety, calling this function returns an empty array, i.e.: [].
The following exchanges require a symbol parameter when querying current unfilled orders. When calling the GetOrders function with these exchanges, if no symbol parameter is passed, only the unfilled orders of the current variety are requested, not all varieties' unfilled orders (because the exchange API does not support it).
Zaif, MEXC, LBank, Korbit, Coinw, BitMart, Bithumb, BitFlyer, BigONE.
Exchanges that do not support the exchange.GetOrders() function:
| Function Name | Unsupported Spot Exchanges | Unsupported Futures Exchanges |
|---|---|---|
| GetOrders | -- | Futures_Bibox |
exchange.GetHistoryOrders
The exchange.GetHistoryOrders() function is used to get historical orders for the current trading pair or contract, and supports specifying specific trading instruments.
exchange.GetHistoryOrders()
exchange.GetHistoryOrders(symbol)
exchange.GetHistoryOrders(symbol, since)
exchange.GetHistoryOrders(symbol, since, limit)
exchange.GetHistoryOrders(since)
exchange.GetHistoryOrders(since, limit)Examples
javascript
function main() {
var historyOrders = exchange.GetHistoryOrders()
Log(historyOrders)
}
python
def main():
historyOrders = exchange.GetHistoryOrders()
Log(historyOrders)
c++
void main() {
auto historyOrders = exchange.GetHistoryOrders();
Log(historyOrders);
}Returns
| Type | Description |
| The |
Arguments
| Name | Type | Required | Description |
symbol | string | No | The If querying option contract order data, set the |
since | number | No | The |
limit | number | No | The |
See Also
Remarks
-
When
symbol,since, andlimitparameters are not specified, it defaults to querying historical orders for the current trading pair or contract. It queries historical orders within a certain range closest to the current time, with the query range determined by the single query range of the exchange API. -
When the
symbolparameter is specified, it queries historical orders for the specified trading instrument. -
When the
sinceparameter is specified, it queries from thesincetimestamp towards the current time. -
When the
limitparameter is specified, it returns after querying the sufficient number of entries. -
This function only supports exchanges that provide historical order query interfaces.
Exchanges that do not support the exchange.GetHistoryOrders() function:
| Function Name | Unsupported Spot Exchanges | Unsupported Futures Exchanges |
|---|---|---|
| GetHistoryOrders | Zaif / Upbit / Coincheck / Bitstamp / Bithumb / BitFlyer / BigONE | Futures_Bibox / Futures_ApolloX |
exchange.CreateConditionOrder
exchange.CreateConditionOrder() function is used to create a conditional order. A conditional order is an order type that automatically executes when specific trigger conditions are met.
exchange.CreateConditionOrder(symbol, side, amount, condition)
exchange.CreateConditionOrder(symbol, side, amount, condition, ...args)Examples
-
Create a Take Profit order (TP): Automatically sell when the price rises to the target price.
javascriptfunction main() { // Create TP order: When BTC_USDT price rises to 65000, sell 0.01 BTC at price 65000 var condition = { ConditionType: ORDER_CONDITION_TYPE_TP, // Take Profit order TpTriggerPrice: 65000, // Trigger price TpOrderPrice: 65000 // Execution price, can also be set to -1 for market order } var id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("TP order Id:", id) }pythondef main(): # Create TP order: When BTC_USDT price rises to 65000, sell 0.01 BTC at price 65000 condition = { "ConditionType": ORDER_CONDITION_TYPE_TP, # Take Profit order "TpTriggerPrice": 65000, # Trigger price "TpOrderPrice": 65000 # Execution price, can also be set to -1 for market order } id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("TP order Id:", id)c++void main() { // Create TP order: When BTC_USDT price rises to 65000, sell 0.01 BTC at price 65000 OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 65000, .TpOrderPrice = 65000}; auto id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition); Log("TP order Id:", id); } -
Create a Stop Loss order (SL): Automatically sell when the price drops to the stop loss price.
javascriptfunction main() { // Create SL order: When BTC_USDT price drops to 58000, sell 0.01 BTC at market price var condition = { ConditionType: ORDER_CONDITION_TYPE_SL, // Stop Loss order SlTriggerPrice: 58000, // Trigger price SlOrderPrice: -1 // -1 means market order } var id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("SL order Id:", id) }pythondef main(): # Create SL order: When BTC_USDT price drops to 58000, sell 0.01 BTC at market price condition = { "ConditionType": ORDER_CONDITION_TYPE_SL, # Stop Loss order "SlTriggerPrice": 58000, # Trigger price "SlOrderPrice": -1 # -1 means market order } id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("SL order Id:", id)c++void main() { // Create SL order: When BTC_USDT price drops to 58000, sell 0.01 BTC at market price OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_SL, .SlTriggerPrice = 58000, .SlOrderPrice = -1}; auto id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition); Log("SL order Id:", id); } -
Create OCO order: Set take-profit and stop-loss simultaneously. When either one is triggered, the other is automatically canceled.
javascriptfunction main() { // Create OCO order: take-profit price 65000, stop-loss price 58000 var condition = { ConditionType: ORDER_CONDITION_TYPE_OCO, // OCO order TpTriggerPrice: 65000, // Take-profit trigger price TpOrderPrice: 65000, // Take-profit execution price SlTriggerPrice: 58000, // Stop-loss trigger price SlOrderPrice: 58000 // Stop-loss execution price } var id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("OCO order Id:", id) }pythondef main(): # Create OCO order: take-profit price 65000, stop-loss price 58000 condition = { "ConditionType": ORDER_CONDITION_TYPE_OCO, # OCO order "TpTriggerPrice": 65000, # Take-profit trigger price "TpOrderPrice": 65000, # Take-profit execution price "SlTriggerPrice": 58000, # Stop-loss trigger price "SlOrderPrice": 58000 # Stop-loss execution price } id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("OCO order Id:", id)c++void main() { // Create OCO order: take-profit price 65000, stop-loss price 58000 OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_OCO, .TpTriggerPrice = 65000, .TpOrderPrice = 65000, .SlTriggerPrice = 58000, .SlOrderPrice = 58000}; auto id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition); Log("OCO order Id:", id); } -
Create a condition order using additional parameters (option) to pass exchange-specific parameters.
javascriptfunction main() { // Pass option parameter using JSON format var option = { "type": "TRAILING_STOP_MARKET", "activatePrice": "300", "callbackRate": "0.1" } var sideWithOption = "buy;" + JSON.stringify(option) var condition = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 77, TpOrderPrice: 71 } var id = exchange.CreateConditionOrder("SOL_USDT.swap", sideWithOption, 1, condition) Log("Condition Order Id:", id) Sleep(2000) Log(exchange.GetConditionOrder(id)) }pythonimport json def main(): # Pass option parameter using JSON format option = { "type": "TRAILING_STOP_MARKET", "activatePrice": "300", "callbackRate": "0.1" } sideWithOption = "buy;" + json.dumps(option) condition = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 77, "TpOrderPrice": 71 } id = exchange.CreateConditionOrder("SOL_USDT.swap", sideWithOption, 1, condition) Log("Condition Order Id:", id) Sleep(2000) Log(exchange.GetConditionOrder(id))c++void main() { // Pass option parameter using JSON format json option = R"({ "type": "TRAILING_STOP_MARKET", "activatePrice": "300", "callbackRate": "0.1" })"_json; string sideWithOption = "buy;" + option.dump(); OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 77, .TpOrderPrice = 71}; auto id = exchange.CreateConditionOrder("SOL_USDT.swap", sideWithOption, 1, condition); Log("Condition Order Id:", id); Sleep(2000); Log(exchange.GetConditionOrder(id)); }
Returns
| Type | Description |
string / null value | Returns the conditional order ID when the conditional order is created successfully, returns null value when creation fails. The conditional order ID format is similar to regular order ID, consisting of the exchange instrument code and the exchange's original conditional order ID, separated by a comma. |
Arguments
| Name | Type | Required | Description |
symbol | string | Yes | The parameter When calling the When calling the When calling the |
side | string | Yes | The parameter For spot exchange objects, the optional values for the For futures exchange objects, the optional values for the Supports additional parameters (option): Additional parameters can be passed through the For example: Additional parameters are used to pass exchange-specific parameters (such as order type, time-in-force rules, etc.), and the specific supported parameters depend on the exchange API. |
amount | number | Yes | The parameter |
condition | object | Yes | The parameter
|
arg | string / number / bool / object / array / any (any type supported by the platform) | No | Extended parameters, can output additional information to the log of this conditional order. Multiple |
See Also
Condition exchange.CancelConditionOrder exchange.GetConditionOrder exchange.GetConditionOrders exchange.ModifyConditionOrder
Remarks
Support for conditional orders depends on the specific exchange; some exchanges may not support conditional order functionality.
Conditional orders do not occupy account funds before being triggered; funds are only occupied when the order is actually placed after triggering.
Different exchanges may have varying levels of support and specific parameters for conditional orders. Please refer to the corresponding exchange's API documentation before use.
Supports passing additional parameters (option) through the side parameter for exchange-specific parameters. Additional parameters need to be merged with the side parameter in the format "side;{JSON object}" (recommended) or "side;key=value&key=value" (URL encoded format). For example: "buy;{\"type\":\"TRAILING_STOP_MARKET\"}".
Different exchanges support different option parameters; the specific supported parameters depend on the exchange's API documentation. Common parameters include: order type (type), time in force (timeInForce), activation price (activatePrice), callback rate (callbackRate), etc.
When using option parameters, the amount and condition parameters still need to be provided. If certain parameters in the exchange API have been passed through option, these basic parameters may be overridden by the corresponding parameters in option; the specific behavior depends on the exchange API implementation.
exchange.ModifyOrder
The exchange.ModifyOrder() function is used to modify existing regular orders, allowing modification of order price and quantity. Supports modifying other order attributes through additional parameters (depending on exchange API support).
exchange.ModifyOrder(orderId, side, price, amount)Examples
-
Modify the price and quantity of a regular order.
javascriptfunction main() { // Create a limit buy order var id = exchange.CreateOrder("SOL_USDT.swap", "buy", 88, 1) Log("Original Order ID:", id) Sleep(2000) // Query original order information var order = exchange.GetOrder(id) Log("Original Order Info:", order) Sleep(1000) // Modify order price and quantity var newId = exchange.ModifyOrder(id, "buy", 77, 2) Log("Modified Order ID:", newId) Sleep(2000) // Query modified order information var newOrder = exchange.GetOrder(newId) Log("Modified Order Info:", newOrder) // Cancel order exchange.CancelOrder(newId) }pythondef main(): # Create a limit buy order id = exchange.CreateOrder("SOL_USDT.swap", "buy", 88, 1) Log("Original Order ID:", id) Sleep(2000) # Query original order information order = exchange.GetOrder(id) Log("Original Order Info:", order) Sleep(1000) # Modify order price and quantity newId = exchange.ModifyOrder(id, "buy", 77, 2) Log("Modified Order ID:", newId) Sleep(2000) # Query modified order information newOrder = exchange.GetOrder(newId) Log("Modified Order Info:", newOrder) # Cancel order exchange.CancelOrder(newId)c++void main() { // Create a limit buy order auto id = exchange.CreateOrder("SOL_USDT.swap", "buy", 88, 1); Log("Original Order ID:", id); Sleep(2000); // Query original order information auto order = exchange.GetOrder(id); Log("Original Order Info:", order); Sleep(1000); // Modify order price and quantity auto newId = exchange.ModifyOrder(id, "buy", 77, 2); Log("Modified Order ID:", newId); Sleep(2000); // Query modified order information auto newOrder = exchange.GetOrder(newId); Log("Modified Order Info:", newOrder); // Cancel order exchange.CancelOrder(newId); } -
Use additional parameters (option) to modify the order's price matching mode.
javascriptfunction main() { // Create a limit buy order var id = exchange.CreateOrder("SOL_USDT.swap", "buy", 77, 1) Log("Original Order ID:", id) Sleep(2000) // Modify order and set price matching mode to QUEUE_20 // Pass additional parameters (JSON format) through side parameter var option = {"priceMatch": "QUEUE_20"} var sideWithOption = "buy;" + JSON.stringify(option) var newId = exchange.ModifyOrder(id, sideWithOption, -1, 2) Log("Modified Order ID:", newId) Sleep(2000) // Query modified order information var newOrder = exchange.GetOrder(newId) Log("Modified Order Info:", newOrder) // Cancel order exchange.CancelOrder(newId) }pythonimport json def main(): # Create a limit buy order id = exchange.CreateOrder("SOL_USDT.swap", "buy", 77, 1) Log("Original Order ID:", id) Sleep(2000) # Modify order and set price matching mode to QUEUE_20 # Pass additional parameters (JSON format) through side parameter option = {"priceMatch": "QUEUE_20"} sideWithOption = "buy;" + json.dumps(option) newId = exchange.ModifyOrder(id, sideWithOption, -1, 2) Log("Modified Order ID:", newId) Sleep(2000) # Query modified order information newOrder = exchange.GetOrder(newId) Log("Modified Order Info:", newOrder) # Cancel order exchange.CancelOrder(newId)c++void main() { // Create a limit buy order auto id = exchange.CreateOrder("SOL_USDT.swap", "buy", 77, 1); Log("Original Order ID:", id); Sleep(2000); // Modify order and set price matching mode to QUEUE_20 // Pass additional parameters (JSON format) through side parameter json option = R"({"priceMatch": "QUEUE_20"})"_json; string sideWithOption = "buy;" + option.dump(); auto newId = exchange.ModifyOrder(id, sideWithOption, -1, 2); Log("Modified Order ID:", newId); Sleep(2000); // Query modified order information auto newOrder = exchange.GetOrder(newId); Log("Modified Order Info:", newOrder); // Cancel order exchange.CancelOrder(newId); }
Returns
| Type | Description |
string / null | Returns the order ID when order modification is successful, returns null when modification fails. The returned order ID may be the same as or different from the original order ID, depending on the exchange API implementation. Some exchanges return a new order ID after order modification, while others keep the order ID unchanged. |
Arguments
| Name | Type | Required | Description |
orderId | string | Yes | The |
side | string | Yes | The For spot exchange objects, the optional values for the For futures exchange objects, the optional values for the Supports additional parameters (option): Additional parameters can be passed through the For example: Additional parameters are used to modify other order attributes (such as price matching mode, etc.), and the specific supported parameters depend on the exchange API. |
price | number | Yes | The |
amount | number | Yes | The |
See Also
Remarks
The order ID returned by the exchange.ModifyOrder() function may behave differently depending on the exchange API implementation. Some exchange APIs will update the returned order ID, while others keep it unchanged. It is recommended to use the returned new order ID for subsequent operations.
The exchange.ModifyOrder() function does not validate parameter validity according to exchange interface rules and will submit parameters directly to the exchange API. When invalid parameters are passed (such as price or quantity being -1), the parameters may be ignored by the exchange, and the order maintains its original attributes unchanged.
Supports passing additional parameters (option) through the side parameter to modify other order attributes. Additional parameters need to be merged with the side parameter in the format "side;{JSON object}" (recommended) or "side;key=value" (URL encoding format). For example, to modify price matching mode: "buy;{\"priceMatch\":\"QUEUE_20\"}".
For market order modification of regular orders, you need to check specifically whether the exchange API supports it. Some exchanges do not support market order modification operations.
When modifying orders, other order attributes (such as order type, position mode, account mode, leverage, order validity rules, etc.) usually retain the original order settings. If you need to modify these attributes, you can pass them through additional parameters (option), provided the exchange API supports it.
Some exchange APIs may convert orders to market orders when price parameters are not received (price is -1 or null). For spot market buy orders, note that the order quantity unit may be amount rather than coin quantity.
Support for order modification functionality depends on the specific exchange. Some exchanges may not support order modification functionality or only support modification of certain parameters. Please consult the corresponding exchange's API documentation before use.
exchange.ModifyConditionOrder
The exchange.ModifyConditionOrder() function is used to modify an existing conditional order, allowing modification of the order quantity, trigger conditions, and execution price. It supports modifying other attributes of the conditional order through additional parameters (depending on exchange API support).
exchange.ModifyConditionOrder(orderId, side, amount, condition)Examples
-
Modify the quantity and trigger conditions of a conditional order.
javascriptfunction main() { // Create a take-profit conditional order var condition = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 77, TpOrderPrice: 76 } var id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, condition) Log("Original Condition Order ID:", id) Sleep(2000) // Query original conditional order info var order = exchange.GetConditionOrder(id) Log("Original Condition Order Info:", order) Sleep(1000) // Modify the quantity and trigger conditions of the conditional order var newCondition = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 75, TpOrderPrice: 71 } var newId = exchange.ModifyConditionOrder(id, "buy", 2, newCondition) Log("Modified Condition Order ID:", newId) Sleep(2000) // Query modified conditional order info var newOrder = exchange.GetConditionOrder(newId) Log("Modified Condition Order Info:", newOrder) // Cancel the conditional order exchange.CancelConditionOrder(newId) }pythondef main(): # Create a take-profit conditional order condition = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 77, "TpOrderPrice": 76 } id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, condition) Log("Original Condition Order ID:", id) Sleep(2000) # Query original conditional order info order = exchange.GetConditionOrder(id) Log("Original Condition Order Info:", order) Sleep(1000) # Modify the quantity and trigger conditions of the conditional order newCondition = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 75, "TpOrderPrice": 71 } newId = exchange.ModifyConditionOrder(id, "buy", 2, newCondition) Log("Modified Condition Order ID:", newId) Sleep(2000) # Query modified conditional order info newOrder = exchange.GetConditionOrder(newId) Log("Modified Condition Order Info:", newOrder) # Cancel the conditional order exchange.CancelConditionOrder(newId)c++void main() { // Create a take-profit conditional order OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 77, .TpOrderPrice = 76}; auto id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, condition); Log("Original Condition Order ID:", id); Sleep(2000); // Query original conditional order info auto order = exchange.GetConditionOrder(id); Log("Original Condition Order Info:", order); Sleep(1000); // Modify the quantity and trigger conditions of the conditional order OrderCondition newCondition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 75, .TpOrderPrice = 71}; auto newId = exchange.ModifyConditionOrder(id, "buy", 2, newCondition); Log("Modified Condition Order ID:", newId); Sleep(2000); // Query modified conditional order info auto newOrder = exchange.GetConditionOrder(newId); Log("Modified Condition Order Info:", newOrder); // Cancel the conditional order exchange.CancelConditionOrder(newId); } -
Use additional parameters (option) to modify the trigger price type of a conditional order.
javascriptfunction main() { // Create a take-profit conditional order var condition = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 77, TpOrderPrice: 76 } var id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, condition) Log("Original Condition Order ID:", id) Sleep(2000) // Modify the conditional order and set the trigger price type to index price // Pass additional parameters (JSON format) through the side parameter var option = {"newTpTriggerPxType": "index"} var sideWithOption = "buy;" + JSON.stringify(option) var newCondition = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 75, TpOrderPrice: 71 } var newId = exchange.ModifyConditionOrder(id, sideWithOption, 2, newCondition) Log("Modified Condition Order ID:", newId) Sleep(2000) // Query the modified conditional order information var newOrder = exchange.GetConditionOrder(newId) Log("Modified Condition Order Info:", newOrder) // Cancel the conditional order exchange.CancelConditionOrder(newId) }pythonimport json def main(): # Create a take-profit conditional order condition = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 77, "TpOrderPrice": 76 } id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, condition) Log("Original Condition Order ID:", id) Sleep(2000) # Modify the conditional order and set the trigger price type to index price # Pass additional parameters (JSON format) through the side parameter option = {"newTpTriggerPxType": "index"} sideWithOption = "buy;" + json.dumps(option) newCondition = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 75, "TpOrderPrice": 71 } newId = exchange.ModifyConditionOrder(id, sideWithOption, 2, newCondition) Log("Modified Condition Order ID:", newId) Sleep(2000) # Query the modified conditional order information newOrder = exchange.GetConditionOrder(newId) Log("Modified Condition Order Info:", newOrder) # Cancel the conditional order exchange.CancelConditionOrder(newId)c++void main() { // Create a take-profit conditional order OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 77, .TpOrderPrice = 76}; auto id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, condition); Log("Original Condition Order ID:", id); Sleep(2000); // Modify the conditional order and set the trigger price type to index price // Pass additional parameters (JSON format) through the side parameter json option = R"({"newTpTriggerPxType": "index"})"_json; string sideWithOption = "buy;" + option.dump(); OrderCondition newCondition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 75, .TpOrderPrice = 71}; auto newId = exchange.ModifyConditionOrder(id, sideWithOption, 2, newCondition); Log("Modified Condition Order ID:", newId); Sleep(2000); // Query the modified conditional order information auto newOrder = exchange.GetConditionOrder(newId); Log("Modified Condition Order Info:", newOrder); // Cancel the conditional order exchange.CancelConditionOrder(newId); }
Returns
| Type | Description |
string / null value | Returns the conditional order ID when modification is successful, returns null value when modification fails. The returned conditional order ID may be the same as or different from the original conditional order ID, depending on the exchange API implementation. Some exchanges return a new conditional order ID after modifying a conditional order, while others keep the conditional order ID unchanged. |
Arguments
| Name | Type | Required | Description |
orderId | string | Yes | The parameter |
side | string | Yes | The parameter For spot exchange objects, the optional values for the For futures exchange objects, the optional values for the Supports additional parameters (option): Additional parameters can be passed through the For example: Additional parameters are used to modify other attributes of the conditional order (such as trigger price type, etc.), and the specific supported parameters depend on the exchange API. |
amount | number | Yes | The parameter |
condition | object | Yes | The parameter
|
See Also
Condition exchange.CreateConditionOrder exchange.CancelConditionOrder exchange.GetConditionOrder exchange.GetConditionOrders
Remarks
The conditional order ID returned by the exchange.ModifyConditionOrder() function may behave differently depending on the exchange API implementation. Some exchange APIs return an updated conditional order ID, while others keep it unchanged. It is recommended to use the returned new conditional order ID for subsequent operations.
The exchange.ModifyConditionOrder() function does not validate parameter validity according to exchange interface rules, but submits parameters directly to the exchange API. When invalid parameters are passed (such as quantity of -1), the parameters may be ignored by the exchange, and the conditional order retains its original attributes.
Supports passing additional parameters (option) through the side parameter to modify other attributes of the conditional order. Additional parameters need to be merged with the side parameter in the format "side;{JSON object}" (recommended) or "side;key=value" (URL encoded format). For example, to modify the trigger price type: "buy;{\"newTpTriggerPxType\":\"index\"}".
For market order modification of conditional orders, you need to check whether the exchange API supports it. Setting TpOrderPrice or SlOrderPrice to -1 in the condition parameter indicates a market order.
When modifying a conditional order, other attributes of the conditional order (such as condition type, position mode, account mode, leverage, etc.) usually retain the original conditional order settings. If you need to modify these attributes, you can pass them through additional parameters (option), provided that the exchange API supports it.
You can modify the trigger price type through additional parameters, for example, changing the trigger price type from last price (last) to index price (index) or mark price (mark). The specific parameter names and support depend on the exchange API documentation.
Support for the modify conditional order function depends on the specific exchange. Some exchanges may not support the modify conditional order function or may only support modification of certain parameters. Please refer to the corresponding exchange's API documentation before use.
exchange.CancelConditionOrder
The exchange.CancelConditionOrder() function is used to cancel a conditional order. The conditional order ID format is similar to regular order IDs, consisting of the exchange instrument code and the exchange's original conditional order ID, separated by a comma.
When calling the exchange.CancelConditionOrder() function to cancel a conditional order, the conditionOrderId parameter passed should match the Id property of the conditional order structure.
exchange.CancelConditionOrder(conditionOrderId)
exchange.CancelConditionOrder(conditionOrderId, ...args)Examples
-
Cancel a conditional order.
javascriptfunction main(){ // Create a stop-loss conditional order var condition = { ConditionType: ORDER_CONDITION_TYPE_SL, SlTriggerPrice: 58000, SlOrderPrice: -1 // Market order } var id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Sleep(1000) exchange.CancelConditionOrder(id) }pythondef main(): # Create a stop-loss conditional order condition = { "ConditionType": ORDER_CONDITION_TYPE_SL, "SlTriggerPrice": 58000, "SlOrderPrice": -1 # Market order } id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Sleep(1000) exchange.CancelConditionOrder(id)c++void main() { // Create a stop-loss conditional order OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_SL, .SlTriggerPrice = 58000, .SlOrderPrice = -1}; auto id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition); Sleep(1000); exchange.CancelConditionOrder(id); } -
Batch cancel condition orders and output condition order information.
javascriptfunction main() { // Create several condition orders var condition1 = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 65000, TpOrderPrice: 65000 } exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition1) var condition2 = { ConditionType: ORDER_CONDITION_TYPE_SL, SlTriggerPrice: 58000, SlOrderPrice: 58000 } exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition2) Sleep(1000) var orders = exchange.GetConditionOrders() for (var i = 0 ; i < orders.length ; i++) { exchange.CancelConditionOrder(orders[i].Id, "Canceled condition order:", orders[i]) Sleep(500) } }pythondef main(): # Create several condition orders condition1 = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 65000, "TpOrderPrice": 65000 } exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition1) condition2 = { "ConditionType": ORDER_CONDITION_TYPE_SL, "SlTriggerPrice": 58000, "SlOrderPrice": 58000 } exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition2) Sleep(1000) orders = exchange.GetConditionOrders() for i in range(len(orders)): exchange.CancelConditionOrder(orders[i]["Id"], "Canceled condition order:", orders[i]) Sleep(500)c++void main() { // Create several condition orders OrderCondition condition1 = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 65000, .TpOrderPrice = 65000}; exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition1); OrderCondition condition2 = {.ConditionType = ORDER_CONDITION_TYPE_SL, .SlTriggerPrice = 58000, .SlOrderPrice = 58000}; exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition2); Sleep(1000); auto orders = exchange.GetConditionOrders(); for (int i = 0 ; i < orders.size() ; i++) { exchange.CancelConditionOrder(orders[i].Id, "Canceled condition order:", orders[i]); Sleep(500); } }
Returns
| Type | Description |
bool | The |
Arguments
| Name | Type | Required | Description |
conditionOrderId | string | Yes | The |
arg | string / number / bool / object / array / any (any type supported by the platform) | No | Extended parameters that can output additional information to the cancel conditional order log. Multiple |
See Also
exchange.CreateConditionOrder exchange.GetConditionOrder exchange.GetConditionOrders exchange.ModifyConditionOrder
Remarks
The return value of the exchange.CancelConditionOrder() function only indicates whether the request was sent successfully or failed. To determine whether the exchange has actually canceled the conditional order, you can call the exchange.GetConditionOrders() function to confirm.
Only untriggered conditional orders can be canceled. Conditional orders that have been triggered and converted to regular orders cannot be canceled through this function.
exchange.GetConditionOrder
The exchange.GetConditionOrder() function is used to get conditional order information.
exchange.GetConditionOrder(conditionOrderId)Examples
javascript
function main(){
// Create take-profit conditional order
var condition = {
ConditionType: ORDER_CONDITION_TYPE_TP,
TpTriggerPrice: 65000,
TpOrderPrice: 65000
}
var id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition)
Sleep(1000)
// The parameter id is the conditional order ID, enter the ID of the conditional order you want to query
var order = exchange.GetConditionOrder(id)
Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount,
"Status:", order.Status, "Type:", order.Type, "Condition:", order.Condition)
}
python
def main():
# Create take-profit conditional order
condition = {
"ConditionType": ORDER_CONDITION_TYPE_TP,
"TpTriggerPrice": 65000,
"TpOrderPrice": 65000
}
id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition)
Sleep(1000)
order = exchange.GetConditionOrder(id)
Log("Id:", order["Id"], "Price:", order["Price"], "Amount:", order["Amount"],
"Status:", order["Status"], "Type:", order["Type"], "Condition:", order["Condition"])
c++
void main() {
// Create take-profit conditional order
OrderCondition condition = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 65000, .TpOrderPrice = 65000};
auto id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition);
Sleep(1000);
auto order = exchange.GetConditionOrder(id);
Log("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount,
"Status:", order.Status, "Type:", order.Type);
}Returns
| Type | Description |
| Queries conditional order details by conditional order ID. Returns an The returned Order structure contains a |
Arguments
| Name | Type | Required | Description |
conditionOrderId | string | Yes | The The |
See Also
Remarks
Some exchanges do not support the exchange.GetConditionOrder() function.
The returned conditional order structure contains information such as trigger conditions, trigger price, order status, etc.
Conditional order statuses include: not triggered, triggered, canceled, etc. The specific status values depend on the exchange.
exchange.GetConditionOrders
The exchange.GetConditionOrders() function is used to get unfulfilled conditional orders (conditional orders that have not been triggered or canceled).
exchange.GetConditionOrders()
exchange.GetConditionOrders(symbol)Examples
-
Use a spot exchange object to create multiple condition orders and then query pending condition order information.
javascriptfunction main() { // Create multiple condition orders var condition1 = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 65000, TpOrderPrice: 65000 } exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition1) var condition2 = { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 3200, TpOrderPrice: 3200 } exchange.CreateConditionOrder("ETH_USDT", "sell", 0.1, condition2) Sleep(1000) // Query all pending condition orders var orders = exchange.GetConditionOrders() Log("Pending condition orders count:", orders.length) for (var i = 0; i < orders.length; i++) { Log("Condition order", i+1, ":", orders[i]) } }pythondef main(): # Create multiple condition orders condition1 = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 65000, "TpOrderPrice": 65000 } exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition1) condition2 = { "ConditionType": ORDER_CONDITION_TYPE_TP, "TpTriggerPrice": 3200, "TpOrderPrice": 3200 } exchange.CreateConditionOrder("ETH_USDT", "sell", 0.1, condition2) Sleep(1000) # Query all pending condition orders orders = exchange.GetConditionOrders() Log("Pending condition orders count:", len(orders)) for i in range(len(orders)): Log("Condition order", i+1, ":", orders[i])c++void main() { // Create multiple condition orders OrderCondition condition1 = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 65000, .TpOrderPrice = 65000}; exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition1); OrderCondition condition2 = {.ConditionType = ORDER_CONDITION_TYPE_TP, .TpTriggerPrice = 3200, .TpOrderPrice = 3200}; exchange.CreateConditionOrder("ETH_USDT", "sell", 0.1, condition2); Sleep(1000); // Query all pending condition orders auto orders = exchange.GetConditionOrders(); Log("Pending condition orders count:", orders.size()); for (int i = 0; i < orders.size(); i++) { Log("Condition order", i+1, ":", orders[i]); } } -
Query pending condition orders for a specific trading pair.
javascriptfunction main() { // Query pending condition orders for BTC_USDT trading pair var orders = exchange.GetConditionOrders("BTC_USDT") Log("BTC_USDT pending condition orders:", orders) }pythondef main(): # Query pending condition orders for BTC_USDT trading pair orders = exchange.GetConditionOrders("BTC_USDT") Log("BTC_USDT pending condition orders:", orders)c++void main() { // Query pending condition orders for BTC_USDT trading pair auto orders = exchange.GetConditionOrders("BTC_USDT"); Log("BTC_USDT pending condition orders:", orders); }
Returns
| Type | Description |
| The |
Arguments
| Name | Type | Required | Description |
symbol | string | No | The parameter |
See Also
Remarks
Summary of usage scenarios for the symbol parameter in the GetConditionOrders function:
| Exchange Object Category | symbol Parameter | Query Range | Remarks |
|---|---|---|---|
| Spot | No symbol parameter passed | Query all spot trading pairs | For all calling scenarios, if the exchange interface does not support it, an error will be reported and null will be returned, which will not be repeated |
| Spot | Specify trading instrument, symbol parameter: "BTC_USDT" | Query the specified BTC_USDT trading pair | For spot exchange objects, the symbol parameter format is: "BTC_USDT" |
| Futures | No symbol parameter passed | Query all trading instruments within the current trading pair and contract code dimension range | If the current trading pair is BTC_USDT and the contract code is swap, it queries all USDT-margined perpetual contracts. Equivalent to calling GetConditionOrders("USDT.swap") |
| Futures | Specify trading instrument, symbol parameter: "BTC_USDT.swap" | Query the specified BTC USDT-margined perpetual contract | For futures exchange objects, the symbol parameter format is: a combination of trading pair and contract code defined by the FMZ platform, separated by the character "." |
| Futures | Specify trading instrument range, symbol parameter: "USDT.swap" | Query all USDT-margined perpetual contracts | - |
| Futures exchanges supporting options | No symbol parameter passed | Query all option contracts within the current trading pair dimension range | If the current trading pair is BTC_USDT and the contract is set to an option contract, e.g., Binance option contract: BTC-240108-40000-C |
| Futures exchanges supporting options | Specify specific trading instrument | Query the specified option contract | For example, for Binance Futures exchange, symbol parameter: BTC_USDT.BTC-240108-40000-C |
| Futures exchanges supporting options | Specify trading instrument range, symbol parameter: "USDT.option" | Query all USDT-margined option contracts | - |
Summary of query dimension ranges for futures exchange objects in the GetConditionOrders function:
| symbol Parameter | Request Range Definition | Remarks |
|---|---|---|
| USDT.swap | USDT-margined perpetual contract range | For dimensions not supported by the exchange API interface, an error will be reported and null will be returned when called |
| USDT.futures | USDT-margined delivery contract range | - |
| USD.swap | Coin-margined perpetual contract range | - |
| USD.futures | Coin-margined delivery contract range | - |
| USDT.option | USDT-margined option contract range | - |
| USD.option | Coin-margined option contract range | - |
| USDT.futures_combo | Spread combination contract range | Futures_Deribit exchange |
| USD.futures_ff | Mixed margin delivery contract range | Futures_Kraken exchange |
| USD.swap_pf | Mixed margin perpetual contract range | Futures_Kraken exchange |
When the account represented by the exchange object exchange has no unfulfilled conditional orders within the query range or for the specified trading instrument, calling this function returns an empty array, i.e., [].
Support for the conditional order feature depends on the specific exchange; some exchanges may not support the conditional order feature.
exchange.GetHistoryConditionOrders
The exchange.GetHistoryConditionOrders() function is used to get historical conditional orders (including triggered, cancelled, and expired conditional orders) for the current trading pair and contract; supports specifying specific trading instruments.
exchange.GetHistoryConditionOrders()
exchange.GetHistoryConditionOrders(symbol)
exchange.GetHistoryConditionOrders(symbol, since)
exchange.GetHistoryConditionOrders(symbol, since, limit)
exchange.GetHistoryConditionOrders(since)
exchange.GetHistoryConditionOrders(since, limit)Examples
-
Query historical conditional orders, results are returned in ascending order by time.
javascriptfunction main() { var historyConditionOrders = exchange.GetHistoryConditionOrders() Log("Historical condition orders count:", historyConditionOrders.length) // Iterate and display, orders are sorted in ascending order by Time property for (var i = 0; i < historyConditionOrders.length; i++) { Log("Order", i+1, "Created at:", historyConditionOrders[i].Time, "ID:", historyConditionOrders[i].Id, "Status:", historyConditionOrders[i].Status) } }pythondef main(): historyConditionOrders = exchange.GetHistoryConditionOrders() Log("Historical condition orders count:", len(historyConditionOrders)) # Iterate and display, orders are sorted in ascending order by Time property for i in range(len(historyConditionOrders)): Log("Order", i+1, "Created at:", historyConditionOrders[i]["Time"], "ID:", historyConditionOrders[i]["Id"], "Status:", historyConditionOrders[i]["Status"])c++void main() { auto historyConditionOrders = exchange.GetHistoryConditionOrders(); Log("Historical condition orders count:", historyConditionOrders.size()); // Iterate and display, orders are sorted in ascending order by Time property for (int i = 0; i < historyConditionOrders.size(); i++) { Log("Order", i+1, "Created at:", historyConditionOrders[i].Time, "ID:", historyConditionOrders[i].Id, "Status:", historyConditionOrders[i].Status); } } -
Query historical conditional orders for a specified trading pair with a limit on the number of results.
javascriptfunction main() { // Query the last 10 historical conditional orders for BTC_USDT trading pair var historyConditionOrders = exchange.GetHistoryConditionOrders("BTC_USDT", 0, 10) Log("BTC_USDT historical condition orders:", historyConditionOrders) }pythondef main(): # Query the last 10 historical conditional orders for BTC_USDT trading pair historyConditionOrders = exchange.GetHistoryConditionOrders("BTC_USDT", 0, 10) Log("BTC_USDT historical condition orders:", historyConditionOrders)c++void main() { // Query the last 10 historical conditional orders for BTC_USDT trading pair auto historyConditionOrders = exchange.GetHistoryConditionOrders("BTC_USDT", 0, 10); Log("BTC_USDT historical condition orders:", historyConditionOrders); } -
Query historical conditional orders based on a specified time range.
javascriptfunction main() { // Query historical conditional orders starting from a specified timestamp var startTime = new Date("2024-01-01").getTime() var historyConditionOrders = exchange.GetHistoryConditionOrders(startTime, 50) Log("Historical condition orders since:", historyConditionOrders) }pythondef main(): # Query historical conditional orders starting from a specified timestamp import time startTime = int(time.mktime(time.strptime("2024-01-01", "%Y-%m-%d")) * 1000) historyConditionOrders = exchange.GetHistoryConditionOrders(startTime, 50) Log("Historical condition orders since:", historyConditionOrders)c++void main() { // Query historical conditional orders starting from a specified timestamp auto startTime = 1704067200000; // Timestamp for 2024-01-01 auto historyConditionOrders = exchange.GetHistoryConditionOrders(startTime, 50); Log("Historical condition orders since:", historyConditionOrders); }
Returns
| Type | Description |
| The The returned Order structure contains a |
Arguments
| Name | Type | Required | Description |
symbol | string | No | The If querying conditional order data for option contracts, set the |
since | number | No | The |
limit | number | No | The |
See Also
Remarks
-
When
symbol,since, andlimitparameters are not specified, it defaults to querying historical conditional orders for the current trading pair and contract. It queries historical conditional orders within a certain range from the current time, with the query range determined by the exchange API's single query range. -
When the
symbolparameter is specified, it queries historical conditional orders for the specified trading instrument. -
When the
sinceparameter is specified, it queries from thesincetimestamp towards the current time. -
When the
limitparameter is specified, it returns after querying enough entries. -
This function only supports exchanges that provide historical conditional order query interfaces.
Historical conditional orders include: triggered (converted to regular orders), cancelled, expired, and other status conditional orders.
The returned historical conditional order array is sorted in ascending order by order creation time (Time attribute), i.e., the earliest orders are at the front of the array and the latest orders are at the back.
Conditional order functionality support depends on the specific exchange; some exchanges may not support conditional order functionality or historical conditional order query functionality.
exchange.SetPrecision
The exchange.SetPrecision() function is used to set the price and order amount precision for the exchange exchange object. After setting, the system will automatically ignore the excess part of the data.
exchange.SetPrecision(pricePrecision, amountPrecision)Examples
javascript
function main(){
// 设置价格小数位精度为2位,品种下单量小数位精度为3位
exchange.SetPrecision(2, 3)
}
python
def main():
exchange.SetPrecision(2, 3)
c++
void main() {
exchange.SetPrecision(2, 3);
}Arguments
| Name | Type | Required | Description |
pricePrecision | number | Yes | The |
amountPrecision | number | Yes | The |
See Also
Remarks
The backtesting system does not support this function. The numerical precision of the backtesting system will be handled automatically.
exchange.SetRate
Set the current exchange rate conversion ratio for the exchange object.
exchange.SetRate(rate)Examples
javascript
function main(){
Log(exchange.GetTicker())
// 设置汇率转换
exchange.SetRate(7)
Log(exchange.GetTicker())
// 设置为1,不转换
exchange.SetRate(1)
}
python
def main():
Log(exchange.GetTicker())
exchange.SetRate(7)
Log(exchange.GetTicker())
exchange.SetRate(1)
c++
void main() {
Log(exchange.GetTicker());
exchange.SetRate(7);
Log(exchange.GetTicker());
exchange.SetRate(1);
}Arguments
| Name | Type | Required | Description |
rate | number | Yes | The |
See Also
Remarks
After setting the exchange rate value using the exchange.SetRate() function (for example, setting it to 7), all price information of the current exchange object (including market data, depth data, order prices, etc.) will be multiplied by the set exchange rate for conversion.
For example, if exchange is a USD-denominated exchange, after executing exchange.SetRate(7), all price data will be multiplied by 7, converting to prices approximately denominated in CNY.
exchange.IO
The exchange.IO() function is used to call other related interfaces of the exchange object.
exchange.IO(k, ...args)Examples
-
Using
"api"mode to call OKX futures batch order interface, passing JSON order data through therawparameter:javascriptfunction main() { var arrOrders = [ {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"}, {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"} ] // Call exchange.IO to directly access the exchange's batch order interface var ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", JSON.stringify(arrOrders)) Log(ret) }pythonimport json def main(): arrOrders = [ {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"}, {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"} ] ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", json.dumps(arrOrders)) Log(ret)c++void main() { json arrOrders = R"([ {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"}, {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"2","posSide":"long"} ])"_json; auto ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", arrOrders.dump()); Log(ret); } -
When the key-value in the
paramsparameter is a string, the parameter value needs to be wrapped with single quotes:javascriptvar amount = 1 var price = 10 var basecurrency = "ltc" function main () { // Note that amount.toString() and price.toString() have a ' character on both left and right sides var message = "symbol=" + basecurrency + "&amount='" + amount.toString() + "'&price='" + price.toString() + "'&side=buy" + "&type=limit" var id = exchange.IO("api", "POST", "/v1/order/new", message) }pythonamount = 1 price = 10 basecurrency = "ltc" def main(): message = "symbol=" + basecurrency + "&amount='" + str(amount) + "'&price='" + str(price) + "'&side=buy" + "&type=limit" id = exchange.IO("api", "POST", "/v1/order/new", message)c++void main() { auto amount = 1.0; auto price = 10.0; auto basecurrency = "ltc"; string message = format("symbol=%s&amount=\"%.1f\"&price=\"%.1f\"&side=buy&type=limit", basecurrency, amount, price); auto id = exchange.IO("api", "POST", "/v1/order/new", message); } -
The
resourceparameter supports full URLs:javascriptfunction main() { var ret = exchange.IO("api", "GET", "https://www.okx.com/api/v5/account/max-withdrawal", "ccy=BTC") Log(ret) }pythondef main(): ret = exchange.IO("api", "GET", "https://www.okx.com/api/v5/account/max-withdrawal", "ccy=BTC") Log(ret)c++void main() { auto ret = exchange.IO("api", "GET", "https://www.okx.com/api/v5/account/max-withdrawal", "ccy=BTC"); Log(ret); } -
GET request without using the
rawparameter:javascriptfunction main(){ var ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT") Log(ret) }pythondef main(): ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT") Log(ret)c++void main() { auto ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT"); Log(ret); } -
Switch trading pair at runtime:
javascriptfunction main() { // For example, when the live trading starts, the current trading pair of the exchange object is set to BTC_USDT, print the current trading pair ticker Log(exchange.GetTicker()) // Switch trading pair to LTC_BTC exchange.IO("currency", "LTC_BTC") Log(exchange.GetTicker()) }pythondef main(): Log(exchange.GetTicker()) exchange.IO("currency", "LTC_BTC") Log(exchange.GetTicker())c++void main() { Log(exchange.GetTicker()); exchange.IO("currency", "LTC_BTC"); Log(exchange.GetTicker()); } -
Switch exchange interface base address:
javascriptfunction main () { // exchanges[0] is the first exchange object added when creating the live trading exchanges[0].IO("base", "https://api.huobi.pro") }pythondef main(): exchanges[0].IO("base", "https://api.huobi.pro")c++void main() { exchanges[0].IO("base", "https://api.huobi.pro"); } -
Switch market interface base address via
"mbase"(using Bitfinex as an example):javascriptfunction main() { exchange.SetBase("https://api.bitfinex.com") exchange.IO("mbase", "https://api-pub.bitfinex.com") }pythondef main(): exchange.SetBase("https://api.bitfinex.com") exchange.IO("mbase", "https://api-pub.bitfinex.com")c++void main() { exchange.SetBase("https://api.bitfinex.com"); exchange.IO("mbase", "https://api-pub.bitfinex.com"); } -
Switch between demo/live trading environment (using OKX Futures as an example):
javascriptfunction main() { exchange.IO("simulate", true) // Switch to demo trading environment // ... trading logic ... exchange.IO("simulate", false) // Switch back to live trading environment }pythondef main(): exchange.IO("simulate", True) # ... trading logic ... exchange.IO("simulate", False)c++void main() { exchange.IO("simulate", true); // ... trading logic ... exchange.IO("simulate", false); } -
Switch contract margin mode and position mode (using Binance Futures as an example):
javascriptfunction main() { exchange.IO("dual", true) // Switch to hedge mode (dual position) exchange.IO("dual", false) // Switch to one-way mode exchange.SetContractType("swap") exchange.IO("cross", true) // Switch to cross margin exchange.IO("cross", false) // Switch to isolated margin }pythondef main(): exchange.IO("dual", True) exchange.IO("dual", False) exchange.SetContractType("swap") exchange.IO("cross", True) exchange.IO("cross", False)c++void main() { exchange.IO("dual", true); exchange.IO("dual", false); exchange.SetContractType("swap"); exchange.IO("cross", true); exchange.IO("cross", false); } -
Switch unified account mode (using Binance Futures as an example):
javascriptfunction main() { exchange.IO("unified", true) // Switch to unified account mode exchange.IO("unified", false) // Switch to normal mode }pythondef main(): exchange.IO("unified", True) exchange.IO("unified", False)c++void main() { exchange.IO("unified", true); exchange.IO("unified", false); } -
Set self-trade prevention mode (using Binance as an example):
javascriptfunction main() { // "NONE" means disable STP mode, other parameters: "EXPIRE_TAKER", "EXPIRE_MAKER", "EXPIRE_BOTH" exchange.IO("selfTradePreventionMode", "NONE") }pythondef main(): exchange.IO("selfTradePreventionMode", "NONE")c++void main() { exchange.IO("selfTradePreventionMode", "NONE"); } -
Futures_edgeX calculate order Hash and sign:
javascriptfunction main() { var strJson = `{ "assetIdSynthetic": "0x4554482d3900000000000000000000", "assetIdCollateral": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "assetIdFee": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "isBuyingSynthetic": true, "amountSynthetic": 10000000, "amountCollateral": 13020000, "amountFee": 6250, "nonce": 676432751, "accountID": 601416704693633632, "expirationTimestamp": 484831 }` var signature = exchange.IO("calcOrderHashAndSign", strJson) Log(signature) }pythonimport json def main(): params = { "assetIdSynthetic": "0x4554482d3900000000000000000000", "assetIdCollateral": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "assetIdFee": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "isBuyingSynthetic": True, "amountSynthetic": 10000000, "amountCollateral": 13020000, "amountFee": 6250, "nonce": 676432751, "accountID": 601416704693633632, "expirationTimestamp": 484831 } signature = exchange.IO("calcOrderHashAndSign", json.dumps(params)) Log(signature)c++void main() { json params = R"({ "assetIdSynthetic": "0x4554482d3900000000000000000000", "assetIdCollateral": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "assetIdFee": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "isBuyingSynthetic": true, "amountSynthetic": 10000000, "amountCollateral": 13020000, "amountFee": 6250, "nonce": 676432751, "accountID": 601416704693633632, "expirationTimestamp": 484831 })"_json; auto signature = exchange.IO("calcOrderHashAndSign", params.dump()); Log(signature); } -
Rate mode throttling - Limit GetTicker to a maximum of 10 calls per second, returns null when exceeded:
javascriptfunction main() { exchange.IO("rate", "GetTicker", 10, "1s") for (var i = 0; i < 20; i++) { var ticker = exchange.GetTicker("BTC_USDT") if (ticker) { Log("Ticker:", ticker.Last) } else { Log("Rate limit exceeded") } } }pythondef main(): exchange.IO("rate", "GetTicker", 10, "1s") for i in range(20): ticker = exchange.GetTicker("BTC_USDT") if ticker: Log("Ticker:", ticker["Last"]) else: Log("Rate limit exceeded")c++// C++ is not supported currently -
Rate mode throttling - Use the
"delay"parameter to automatically wait when limit is exceeded instead of returning null:javascriptfunction main() { exchange.IO("rate", "GetTicker", 10, "1s", "delay") for (var i = 0; i < 20; i++) { var ticker = exchange.GetTicker("BTC_USDT") Log("Call", i+1, "Ticker:", ticker.Last) } }pythondef main(): exchange.IO("rate", "GetTicker", 10, "1s", "delay") for i in range(20): ticker = exchange.GetTicker("BTC_USDT") Log("Call", i+1, "Ticker:", ticker["Last"])c++// C++ is not supported currently -
Multiple functions sharing rate limit quota:
javascriptfunction main() { // GetTicker and GetDepth share the limit, combined maximum of 10 calls per second exchange.IO("rate", "GetTicker,GetDepth", 10, "1s") for (var i = 0; i < 20; i++) { if (i % 2 == 0) { Log("Ticker:", exchange.GetTicker("BTC_USDT")) } else { Log("Depth:", exchange.GetDepth("BTC_USDT")) } } }pythondef main(): exchange.IO("rate", "GetTicker,GetDepth", 10, "1s") for i in range(20): if i % 2 == 0: Log("Ticker:", exchange.GetTicker("BTC_USDT")) else: Log("Depth:", exchange.GetDepth("BTC_USDT"))c++// C++ is not supported currently -
Use wildcard to limit the frequency of all API calls:
javascriptfunction main() { exchange.IO("rate", "*", 100, "1m") for (var i = 0; i < 10; i++) { exchange.GetTicker("BTC_USDT") exchange.GetDepth("BTC_USDT") exchange.GetAccount() Log("Round", i+1, "completed") Sleep(1000) } }pythondef main(): exchange.IO("rate", "*", 100, "1m") for i in range(10): exchange.GetTicker("BTC_USDT") exchange.GetDepth("BTC_USDT") exchange.GetAccount() Log("Round", i+1, "completed") Sleep(1000)c++// C++ is not supported currently -
quota mode - Strict time window aligned rate limiting:
javascriptfunction main() { exchange.IO("quota", "GetTicker", 3, "1s") for (var i = 0; i < 10; i++) { var ticker = exchange.GetTicker("BTC_USDT") if (ticker) { Log(_D(), "Ticker:", ticker.Last) } else { Log(_D(), "Quota exceeded, waiting for next window") } Sleep(100) } }pythondef main(): exchange.IO("quota", "GetTicker", 3, "1s") for i in range(10): ticker = exchange.GetTicker("BTC_USDT") if ticker: Log(_D(), "Ticker:", ticker["Last"]) else: Log(_D(), "Quota exceeded, waiting for next window") Sleep(100)c++// C++ is not supported currently -
quota mode - Daily quota, reset at specified time each day:
javascriptfunction main() { exchange.IO("quota", "GetTicker", 1000, "@0815") var count = 0 while (true) { var ticker = exchange.GetTicker("BTC_USDT") if (ticker) { count++ Log("Call count:", count, "Ticker:", ticker.Last) } else { Log("Daily quota exceeded, waiting for reset at 08:15") Sleep(60000) // Wait 1 minute } Sleep(1000) } }pythondef main(): exchange.IO("quota", "GetTicker", 1000, "@0815") count = 0 while True: ticker = exchange.GetTicker("BTC_USDT") if ticker: count += 1 Log("Call count:", count, "Ticker:", ticker["Last"]) else: Log("Daily quota exceeded, waiting for reset at 08:15") Sleep(60000) # Wait 1 minute Sleep(1000)c++// C++ is not supported currently -
Combining multiple rate limiting rules:
javascriptfunction main() { exchange.IO("rate", "GetTicker", 10, "1s") // GetTicker 10 times per second exchange.IO("rate", "GetDepth", 5, "1s") // GetDepth 5 times per second exchange.IO("rate", "CreateOrder", 2, "1s") // CreateOrder 2 times per second exchange.IO("quota", "*", 1000, "@0000") // All APIs reset daily at 00:00, limited to 1000 calls Log("Rate limits configured successfully") for (var i = 0; i < 5; i++) { exchange.GetTicker("BTC_USDT") exchange.GetDepth("BTC_USDT") Sleep(200) } }pythondef main(): exchange.IO("rate", "GetTicker", 10, "1s") # GetTicker 10 times per second exchange.IO("rate", "GetDepth", 5, "1s") # GetDepth 5 times per second exchange.IO("rate", "CreateOrder", 2, "1s") # CreateOrder 2 times per second exchange.IO("quota", "*", 1000, "@0000") # All APIs reset daily at 00:00, limited to 1000 calls Log("Rate limits configured successfully") for i in range(5): exchange.GetTicker("BTC_USDT") exchange.GetDepth("BTC_USDT") Sleep(200)c++// C++ is not supported currently
Returns
| Type | Description |
string / number / bool / object / array / any | The |
Arguments
| Name | Type | Required | Description |
k | string | Yes | Call type identifier, different values correspond to different functions, see the sections below for details. |
arg | string / number / bool / object / array / any | Yes | Extended parameters, different parameters are passed according to different |
See Also
Remarks
I. Direct Exchange API Calls ("api" mode)
javascript
exchange.IO("api", httpMethod, resource, params, raw)
Call the exchange's unwrapped raw API interface. FMZ automatically handles signature verification; you only need to fill in the request parameters.
| Parameter | Type | Required | Description |
|---|---|---|---|
| httpMethod | string | Yes | GET, POST, etc. |
| resource | string | Yes | Request path or full URL |
| params | string | No | URL-encoded request parameters |
| raw | string | No | Raw request body (JSON, etc.) |
Returns null on failure. Only supported in live trading.
II. Runtime Trading Pair Switching ("currency" mode)
javascript
exchange.IO("currency", "ETH_USDT")
Dynamically switch trading pairs, format is uppercase with underscore separator. Equivalent to exchange.SetCurrency.
Backtesting only supports spot, and can only switch between trading pairs with the same quote currency. After switching futures, you need to call
exchange.SetContractType()again.
III. Switch Base Address ("base" / "mbase" mode)
"base": Switch trading interface base address, equivalent toexchange.SetBase()."mbase": Switch market data interface base address, applicable to exchanges that use different domains for market data and trading.
IV. General Trading Mode Commands
The following commands are common across multiple exchanges. For specific support, please refer to Section V for each exchange's documentation.
| Command | Parameter | Function |
|---|---|---|
simulate | bool | Simulated trading (true) / Live trading (false) |
cross | bool | Cross margin (true) / Isolated margin (false) |
dual | bool | Hedge mode (true) / One-way mode (false) |
unified | bool | Unified account (true) / Standard account (false) |
trade_margin | None | Switch to isolated margin mode |
trade_super_margin | None | Switch to cross margin mode |
trade_normal | None | Switch back to normal spot mode |
selfTradePreventionMode | string | Self-trade prevention (STP) mode |
V. Exchange-Specific IO Commands
All exchanges support the "api" and "currency" commands. Only exchange-specific commands are listed below.
Spot Exchanges
Binance
| Command | Parameter | Description |
|---|---|---|
trade_margin | None | Switch to isolated margin mode |
trade_super_margin | None | Switch to cross margin mode |
trade_normal | None | Switch back to normal spot mode |
unified | bool | Unified account mode |
selfTradePreventionMode | string | Self-trade prevention, options: EXPIRE_TAKER/EXPIRE_MAKER/EXPIRE_BOTH/NONE |
OKX
| Command | Parameter | Description |
|---|---|---|
simulate | bool | Demo/live trading switch |
trade_margin | None | Isolated margin (tdMode=isolated) |
trade_super_margin | None | Cross margin (tdMode=cross) |
trade_normal | None | Switch back to normal spot mode |
tdMode | string | Directly set trading mode, must use cross margin under portfolio margin mode |
Huobi
| Command | Parameter | Description |
|---|---|---|
trade_margin | None | Switch to isolated margin mode |
trade_super_margin | None | Switch to cross margin mode |
trade_normal | None | Switch back to normal spot mode |
Bybit
| Command | Parameter | Description |
|---|---|---|
trade_margin | None | Switch to margin mode |
trade_normal | None | Switch back to normal spot mode |
| Command | Parameter | Description |
|---|---|---|
trade_margin | None | Switch to isolated margin mode |
trade_super_margin | None | Switch to cross margin mode |
trade_normal | None | Switch back to normal spot mode |
unified | bool | Unified account mode |
Bitget
| Command | Parameter | Description |
|---|---|---|
simulate | bool | Demo/live trading switch |
CoinEx
| Command | Parameter | Description |
|---|---|---|
trade_margin | None | Switch to margin mode |
trade_normal | None | Switch back to normal mode |
WOO
| Command | Parameter | Description |
|---|---|---|
trade_margin | None | Switch to margin mode |
trade_normal | None | Switch back to normal mode |
| Command | Parameter | Description |
|---|---|---|
trade_margin | None | Switch to margin mode |
trade_normal | None | Switch back to normal mode |
AscendEx
| Command | Parameter | Description |
|---|---|---|
trade_margin | None | Switch to margin mode |
trade_normal | None | Switch back to normal mode |
Gemini
| Command | Parameter | Description |
|---|---|---|
subAccount | string | Set sub-account name |
Poloniex
| Command | Parameter | Description |
|---|---|---|
accountId | string | Set account ID |
Bitfinex
| Command | Parameter | Description |
|---|---|---|
version | None | Get current API version number |
Backpack
| Command | Parameter | Description |
|---|---|---|
selfTradePreventionMode | string | Self-trade prevention, options: Allow/RejectTaker/RejectMaker/RejectBoth/Ban |
Hyperliquid (Spot)
| Command | Parameter | Description |
|---|---|---|
source | "a"/"b" | Switch API data source |
vaultAddress | string | Set vault address, empty string to disable |
walletAddress | string | Set wallet address |
expiresAfter | number | Order expiration time (milliseconds), set to 0 to disable |
Futures Exchanges
Futures_Binance
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
dual | bool | Hedge/one-way position mode |
unified | bool | Unified account (uses papi.binance.com after switching) |
selfTradePreventionMode | string | Self-trade prevention, options: EXPIRE_TAKER/EXPIRE_MAKER/EXPIRE_BOTH/NONE |
extend_key | string | Set API response extension fields (comma-separated) |
Futures_OKX
| Command | Parameter | Description |
|---|---|---|
simulate | bool | Demo/live trading switch |
cross | bool | Cross/isolated margin mode, default cross |
dual | bool | Hedge (long_short_mode)/one-way (net_mode) position mode |
Futures_HuobiDM
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode, default isolated. Only XXX_USDT perpetual swaps supported |
dual | bool | Hedge (dual_side)/one-way (single_side) position mode |
unified | bool | Unified account mode |
signHost | string | Set API signature host address, empty string to disable |
Futures_Bybit
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
dual | bool | Hedge/one-way position mode |
Futures_KuCoin
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
Futures_GateIO
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
dual | bool | Hedge/one-way position mode |
unified | bool | Unified account mode |
Futures_Bitget
| Command | Parameter | Description |
|---|---|---|
simulate | bool | Demo/live trading switch |
cross | bool | Cross (crossed)/isolated margin mode |
dual | bool | Hedge (hedge_mode)/one-way (one_way_mode) position mode |
Futures_MEXC
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
Futures_BitMEX
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
Futures_CoinEx
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
Futures_WOO
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
dual | bool | Hedge/one-way position mode |
Futures_Kraken
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode (only multi-collateral accounts supported) |
Futures_Aevo
| Command | Parameter | Description |
|---|---|---|
signingKey | string | Set signing key, returns public key. Must be obtained from exchange API KEY page, note expiration restrictions |
Futures_Hyperliquid
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
source | "a"/"b" | Switch API data source |
vaultAddress | string | Set vault address, empty string to disable |
walletAddress | string | Set wallet address |
expiresAfter | number | Order expiration time (milliseconds), set to 0 to disable |
Futures_Deepcoin
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
merge | bool | Merge positions (true)/split positions (false) |
Futures_DigiFinex
| Command | Parameter | Description |
|---|---|---|
simulate | bool | Demo/live trading switch |
cross | bool | Cross/isolated margin mode |
Futures_ApolloX
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
Futures_Aster
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
dual | bool | Hedge/one-way position mode |
Futures_CoinW
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
Futures_BitMart
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
Futures_Backpack
| Command | Parameter | Description |
|---|---|---|
selfTradePreventionMode | string | Self-trade prevention, options: Allow/RejectTaker/RejectMaker/RejectBoth/Ban |
Futures_Lighter
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
expiry | number | Order expiration timestamp (milliseconds), default 29 days, minimum 4 minutes |
Futures_Crypto.com
| Command | Parameter | Description |
|---|---|---|
accountId | string | Set trading account ID |
Futures_Bitfinex
| Command | Parameter | Description |
|---|---|---|
mbase | string | Set market API base address |
Futures_edgeX
| Command | Parameter | Description |
|---|---|---|
calcOrderHashAndSign | string(JSON) | Calculate order hash and sign, returns signature string |
Futures_Bibox
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode, default cross |
Futures_Pionex
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin mode |
dual | bool | Hedge/one-way position mode |
Futures_Phemex
| Command | Parameter | Description |
|---|---|---|
dual | bool | Hedge/one-way position mode. Cross/isolated margin mode must be set on exchange web interface |
Futures_WooFi
Only supports generic commands
"api"and"currency", no exchange-specific commands.
VI. Special Platform IO Commands
Polymarket (Prediction Market)
| Command | Parameters | Description |
|---|---|---|
nonce | [number] | Get or set order nonce value. Returns current nonce without parameters, sets new nonce when a number is passed |
proxyWalletAddress | None | Get proxy wallet address |
redeem | symbol, [wait] | Redeem settled positions (Gas-free via Relayer), wait defaults to true to wait for transaction confirmation. When wait is false, immediately returns {"transactionID": "..."} |
merge | symbol, [amount], [wait] | Merge YES+NO tokens back to USDC (Gas-free via Relayer). When amount is 0 or not provided, automatically takes the smaller position of the two outcomes. wait defaults to true to wait for transaction confirmation |
l2_credentials | None | Get L2 authentication info, returns {"apiKey":"","secret":"","passphrase":""}, used for WebSocket connections or other scenarios |
batchOrders | array | Batch order placement, parameter is an array of order objects, each object contains symbol, side, price, amount fields, optional option field |
Web3 (Blockchain)
| Command | Parameters | Description |
|---|---|---|
abi | Contract address, ABI string | Register contract ABI |
address | [Private key] | Get wallet address |
encode / pack | Type, Data... | ABI encode data |
encodePacked | Type, Data... | ABI packed encode data |
hash | Param1-4 | Calculate hash value |
decode / unpack | Type, Data... | ABI decode data |
key | string | Switch private key used for operations |
IB (Interactive Brokers)
| Command | Parameters | Description |
|---|---|---|
status | None | Get connection status |
time | None | Get IB server time |
reqId | None | Force get new request ID |
orderId | None | Get next available order ID |
ignore | string(array) | Ignore specified error codes |
scan | string(JSON) | Execute market scanner |
wait | [number] | Wait for market data event, can set timeout in seconds |
debug | bool | Debug mode |
marketDataType | number | Market data type (1 Real-time/2 Frozen/3 Delayed/4 Delayed Frozen) |
Futu (Futu Securities)
| Command | Parameters | Description |
|---|---|---|
refresh | bool | Cache refresh, after disabling cache the rate limit is max 10 times per 30 seconds |
accounts | None | Get all account list |
status | None | Get connection status |
lock | None | Lock trading |
unlock | None | Unlock trading |
wait | None | Wait for market data event |
VII. API Rate Limit Control ("rate" / "quota" Mode)
javascript
exchange.IO("rate", functionNames, maxCalls, period, [behavior])
exchange.IO("quota", functionNames, maxCalls, period, [behavior])
- rate: Smooth rate limiting, does not strictly align with time windows.
- quota: Quota rate limiting, strictly aligns with time windows.
| Parameter | Type | Description |
|---|---|---|
| functionNames | string | Function name, multiple functions separated by commas, * means all |
| maxCalls | number | Maximum number of calls within the time period |
| period | string | Time period ("1s"/"1m"/"1h") or reset time point ("@0815") |
| behavior | string | Optional, "delay" means wait when limit exceeded, defaults to returning null |
Rate limiting for
Buy/Sellfollows theCreateOrdersettings.Gofollows the settings of the actual concurrent function.IO/apionly applies toexchange.IO("api", ...).
exchange.Log
The exchange.Log() function is used to output order placement and cancellation logs in the log area. When called, it does not actually place orders, but only outputs and records trading logs.
exchange.Log(orderType, price, amount)
exchange.Log(orderType, price, amount, ...args)Examples
Using exchange.Log(orderType, price, amount) can be used for live trading copy testing and simulated order placement, which can help record order operations.
The most common use case is: using the exchange.IO function to access the exchange's conditional order creation interface, but using the exchange.IO() function does not output trading log information in the live trading log records.
In this case, you can use the exchange.Log() function to supplement the output logs to record order information, and the same applies to cancellation operations.
javascript
var id = 123
function main() {
// 下单类型买入,价格999,数量 0.1
exchange.Log(LOG_TYPE_BUY, 999, 0.1)
// 取消订单
exchange.Log(LOG_TYPE_CANCEL, id)
}
python
id = 123
def main():
exchange.Log(LOG_TYPE_BUY, 999, 0.1)
exchange.Log(LOG_TYPE_CANCEL, id)
c++
void main() {
auto id = 123;
exchange.Log(LOG_TYPE_BUY, 999, 0.1);
exchange.Log(LOG_TYPE_CANCEL, id);
}Arguments
| Name | Type | Required | Description |
orderType | number | Yes | The |
price | number | Yes | The |
amount | number | Yes | The |
arg | string / number / bool / object / array / any (any type supported by the platform) | No | Extended parameters that can output additional information to this log entry. Multiple |
See Also
Remarks
When the orderType parameter is LOG_TYPE_CANCEL, the price parameter is the order ID to be cancelled, used for printing cancellation logs when directly cancelling orders using the exchange.IO() function.
The exchange.Log() function is a member function of the exchange exchange object, distinct from the global function Log.
exchange.Encode
The exchange.Encode() function is used for signature encryption calculation.
exchange.Encode(algo, inputFormat, outputFormat, data)
exchange.Encode(algo, inputFormat, outputFormat, data, keyFormat, key)Examples
BitMEX Position Change Push Notification (WebSocket Protocol) Example:
javascript
function main() {
var APIKEY = "your Access Key(Bitmex API ID)"
var expires = parseInt(Date.now() / 1000) + 10
var signature = exchange.Encode("sha256", "string", "hex", "GET/realtime" + expires, "hex", "{{secretkey}}")
var client = Dial("wss://www.bitmex.com/realtime", 60)
var auth = JSON.stringify({args: [APIKEY, expires, signature], op: "authKeyExpires"})
var pos = 0
client.write(auth)
client.write('{"op": "subscribe", "args": "position"}')
while (true) {
bitmexData = client.read()
if(bitmexData.table == 'position' && pos != parseInt(bitmexData.data[0].currentQty)){
Log('position change', pos, parseInt(bitmexData.data[0].currentQty), '@')
pos = parseInt(bitmexData.data[0].currentQty)
}
}
}
python
import time
def main():
APIKEY = "your Access Key(Bitmex API ID)"
expires = int(time.time() + 10)
signature = exchange.Encode("sha256", "string", "hex", "GET/realtime" + expires, "hex", "{{secretkey}}")
client = Dial("wss://www.bitmex.com/realtime", 60)
auth = json.dumps({"args": [APIKEY, expires, signature], "op": "authKeyExpires"})
pos = 0
client.write(auth)
client.write('{"op": "subscribe", "args": "position"}')
while True:
bitmexData = json.loads(client.read())
if "table" in bitmexData and bitmexData["table"] == "position" and len(bitmexData["data"]) != 0 and pos != bitmexData["data"][0]["currentQty"]:
Log("position change", pos, bitmexData["data"][0]["currentQty"], "@")
pos = bitmexData["data"][0]["currentQty"]
c++
void main() {
auto APIKEY = "your Access Key(Bitmex API ID)";
auto expires = Unix() + 10;
auto signature = exchange.Encode("sha256", "string", "hex", format("GET/realtime%d", expires), "hex", "{{secretkey}}");
auto client = Dial("wss://www.bitmex.com/realtime", 60);
json auth = R"({"args": [], "op": "authKeyExpires"})"_json;
auth["args"].push_back(APIKEY);
auth["args"].push_back(expires);
auth["args"].push_back(signature);
auto pos = 0;
client.write(auth.dump());
client.write("{\"op\": \"subscribe\", \"args\": \"position\"}");
while(true) {
auto bitmexData = json::parse(client.read());
if(bitmexData["table"] == "position" && bitmexData["data"][0].find("currentQty") != bitmexData["data"][0].end() && pos != bitmexData["data"][0]["currentQty"]) {
Log("Test");
Log("position change", pos, bitmexData["data"][0]["currentQty"], "@");
pos = bitmexData["data"][0]["currentQty"];
}
}
}Returns
| Type | Description |
string | The |
Arguments
| Name | Type | Required | Description |
algo | string | Yes | The Supported settings: "raw" (no algorithm), "sign", "signTx", "md4", "md5", "sha256", "sha512", "sha1", "keccak256", "sha3.224", "sha3.256", "sha3.384", "sha3.512", "sha3.keccak256", "sha3.keccak512", "sha512.384", "sha512.256", "sha512.224", "ripemd160", "blake2b.256", "blake2b.512", "blake2s.128", "blake2s.256". The The |
inputFormat | string | Yes | Used to specify the data format of the |
outputFormat | string | Yes | Used to specify the output data format. The |
data | string | Yes | The |
keyFormat | string | No | Used to specify the data format of the |
key | string | No | The |
See Also
Remarks
Only live trading supports calling the exchange.Encode() function. The reference methods "{{accesskey}}" and "{{secretkey}}" are only valid when used within the exchange.Encode() function.
exchange.Go
Multi-threaded asynchronous support function that converts all supported function operations to asynchronous concurrent execution.
exchange.Go(method)
exchange.Go(method, ...args)Examples
-
Example of using
exchange.Go()function. To check forundefined, you need to usetypeof(xx) === "undefined", because in JavaScript the comparisonnull == undefinedevaluates to true.javascriptfunction main(){ // The following four operations are executed asynchronously in concurrent multi-threads, they don't consume time and return immediately var a = exchange.Go("GetTicker") var b = exchange.Go("GetDepth") var c = exchange.Go("Buy", 1000, 0.1) var d = exchange.Go("GetRecords", PERIOD_H1) // Call wait method to wait for the asynchronous ticker result to return var ticker = a.wait() // Returns depth, it's possible to return null if fetching fails var depth = b.wait() // Returns order ID, with 1 second timeout limit, returns undefined on timeout, this object can continue to call wait if the previous wait timed out var orderId = c.wait(1000) if(typeof(orderId) == "undefined") { // Timeout, fetch again orderId = c.wait() } var records = d.wait() }pythondef main(): a = exchange.Go("GetTicker") b = exchange.Go("GetDepth") c = exchange.Go("Buy", 1000, 0.1) d = exchange.Go("GetRecords", PERIOD_H1) ticker, ok = a.wait() depth, ok = b.wait() orderId, ok = c.wait(1000) if ok == False: orderId, ok = c.wait() records, ok = d.wait()c++void main() { auto a = exchange.Go("GetTicker"); auto b = exchange.Go("GetDepth"); auto c = exchange.Go("Buy", 1000, 0.1); auto d = exchange.Go("GetRecords", PERIOD_H1); Ticker ticker; Depth depth; Records records; TId orderId; a.wait(ticker); b.wait(depth); if(!c.wait(orderId, 300)) { c.wait(orderId); } d.wait(records); } -
Calling the
wait()method on a released concurrent object will trigger an error:javascriptfunction main() { var d = exchange.Go("GetRecords", PERIOD_H1) // Wait for K-line result var records = d.wait() // Here wait is called on an async operation that has already been waited and completed, will return null and log error message var ret = d.wait() }pythondef main(): d = exchange.Go("GetRecords", PERIOD_H1) records, ok = d.wait() ret, ok = d.wait()c++void main() { auto d = exchange.Go("GetRecords", PERIOD_H1); Records records; d.wait(records); Records ret; d.wait(ret); } -
Concurrently retrieve market data from multiple exchanges:
javascriptfunction main() { while(true) { var beginTS = new Date().getTime() var arrRoutine = [] var arrTicker = [] var arrName = [] for(var i = 0; i < exchanges.length; i++) { arrRoutine.push(exchanges[i].Go("GetTicker")) arrName.push(exchanges[i].GetName()) } for(var i = 0; i < arrRoutine.length; i++) { arrTicker.push(arrRoutine[i].wait()) } var endTS = new Date().getTime() var tbl = { type: "table", title: "Market Data", cols: ["Index", "Name", "Last Price"], rows: [] } for(var i = 0; i < arrTicker.length; i++) { tbl.rows.push([i, arrName[i], arrTicker[i].Last]) } LogStatus(_D(), "Total time for concurrent ticker retrieval:", endTS - beginTS, "ms", "\n", "`" + JSON.stringify(tbl) + "`") Sleep(500) } }pythonimport time import json def main(): while True: beginTS = time.time() arrRoutine = [] arrTicker = [] arrName = [] for i in range(len(exchanges)): arrRoutine.append(exchanges[i].Go("GetTicker")) arrName.append(exchanges[i].GetName()) for i in range(len(exchanges)): ticker, ok = arrRoutine[i].wait() arrTicker.append(ticker) endTS = time.time() tbl = { "type": "table", "title": "Market Data", "cols": ["Index", "Name", "Last Price"], "rows": [] } for i in range(len(arrTicker)): tbl["rows"].append([i, arrName[i], arrTicker[i]["Last"]]) LogStatus(_D(), "Total time for concurrent ticker retrieval:", endTS - beginTS, "seconds", "\n", "`" + json.dumps(tbl) + "`") Sleep(500)c++void main() { while(true) { int length = exchanges.size(); auto beginTS = UnixNano() / 1000000; Ticker arrTicker[length] = {}; string arrName[length] = {}; // Note: Based on the number of exchange objects added, you need to execute the corresponding exchanges[n].Go function. This example requires adding four exchange objects, which can be modified according to actual needs auto r0 = exchanges[0].Go("GetTicker"); auto r1 = exchanges[1].Go("GetTicker"); auto r2 = exchanges[2].Go("GetTicker"); auto r3 = exchanges[3].Go("GetTicker"); GoObj *arrRoutine[length] = {&r0, &r1, &r2, &r3}; for(int i = 0; i < length; i++) { arrName[i] = exchanges[i].GetName(); } for(int i = 0; i < length; i++) { Ticker ticker; arrRoutine[i]->wait(ticker); arrTicker[i] = ticker; } auto endTS = UnixNano() / 1000000; json tbl = R"({ "type": "table", "title": "Market Data", "cols": ["Index", "Name", "Last Price"], "rows": [] })"_json; for(int i = 0; i < length; i++) { json arr = R"(["", "", ""])"_json; arr[0] = format("%d", i); arr[1] = arrName[i]; arr[2] = format("%f", arrTicker[i].Last); tbl["rows"].push_back(arr); } LogStatus(_D(), "Total time for concurrent ticker retrieval:", format("%d", endTS - beginTS), "ms", "\n", "`" + tbl.dump() + "`"); Sleep(500); } } -
Concurrent calls to the
exchange.IO("api", ...)function:javascriptfunction main() { /* Test using OKX futures order placement interface POST /api/v5/trade/order */ var beginTS = new Date().getTime() var param = {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"} var ret1 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", JSON.stringify(param)) var ret2 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", JSON.stringify(param)) var ret3 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", JSON.stringify(param)) var id1 = ret1.wait() var id2 = ret2.wait() var id3 = ret3.wait() var endTS = new Date().getTime() Log("id1:", id1) Log("id2:", id2) Log("id3:", id3) Log("Concurrent order time:", endTS - beginTS, "ms") }pythonimport time import json def main(): beginTS = time.time() param = {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"} ret1 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", json.dumps(param)) ret2 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", json.dumps(param)) ret3 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", json.dumps(param)) id1, ok1 = ret1.wait() id2, ok2 = ret2.wait() id3, ok3 = ret3.wait() endTS = time.time() Log("id1:", id1) Log("id2:", id2) Log("id3:", id3) Log("Concurrent order time:", endTS - beginTS, "seconds")c++void main() { auto beginTS = UnixNano() / 1000000; json param = R"({"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"})"_json; auto ret1 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", param.dump()); auto ret2 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", param.dump()); auto ret3 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", param.dump()); json id1 = R"({})"_json; json id2 = R"({})"_json; json id3 = R"({})"_json; ret1.wait(id1); ret2.wait(id2); ret3.wait(id3); auto endTS = UnixNano() / 1000000; Log("id1:", id1); Log("id2:", id2); Log("id3:", id3); Log("Concurrent order time:", endTS - beginTS, "ms"); } -
Testing for automatic release mechanism
javascriptfunction main() { var counter = 0 var arr = [] // Used to test continuous reference of concurrent related variables var symbols = ["BTC_USDT", "ETH_USDT", "SOL_USDT", "LTC_USDT", "EOS_USDT"] while (true) { var arrRoutine = [] for (var symbol of symbols) { var r = exchange.Go("GetTicker", symbol) arrRoutine.push(r) // Record concurrent objects to call r.wait() function to get results, cleared each loop iteration // arr.push(r) // If this line of code is used, it will continuously reference concurrent objects at runtime and cannot be automatically released. When the number of concurrent operations exceeds 2000, an error will be reported: ```InternalError: too many routine wait, max is 2000```. counter++ } // Iterate through arrRoutine to call r.wait() LogStatus(_D(), "routine number:", counter) Sleep(50) } }
Returns
| Type | Description |
object | The |
Arguments
| Name | Type | Required | Description |
method | string | Yes | The |
arg | string / number / bool / object / array / function / any (any type supported by the platform) | No | Parameters for the concurrent execution function. There may be multiple |
See Also
Mail_Go HttpQuery_Go EventLoop exchange.IO (API Rate Limiting Control)
Remarks
This function only creates multi-threaded execution tasks during live trading. Backtesting does not support multi-threaded concurrent execution tasks (available in backtesting environment but still executes sequentially).
After the exchange.Go() function returns an object, call the wait() method of that object to get the data returned by the thread. When concurrent multi-threaded tasks are completed and related variables are no longer referenced, the system will automatically reclaim resources at the underlying level.
The wait() method supports timeout parameters:
-
Without setting a timeout parameter, i.e.,
wait(), or setting the timeout parameter to 0, i.e.,wait(0). Thewait()function will block and wait until the concurrent thread finishes running and returns the execution result of the concurrent thread. -
Setting the timeout parameter to -1, i.e.,
wait(-1). Thewait()function will return immediately. Return values differ between programming languages; please refer to the calling examples in this section for details. -
Setting a specific timeout parameter, such as
wait(300). Thewait()function will wait for a maximum of 300 milliseconds before returning.
Although the system has an automatic recycling mechanism at the underlying level, if related variables are continuously referenced, concurrent threads will not be released. When the number of concurrent threads exceeds 2000, an error will be reported: "too many routine wait, max is 2000".
Supported functions: GetTicker, GetDepth, GetTrades, GetRecords, GetAccount, GetOrders, GetOrder, CancelOrder, Buy, Sell, GetPositions, IO, etc. These functions are executed based on the current exchange exchange object when called concurrently.
Differences between Python and JavaScript languages: In Python, the wait() function of the concurrent object returns two parameters. The first is the result returned by the asynchronous API call, and the second indicates whether the asynchronous call is completed.
python
def main():
d = exchange.Go("GetRecords", PERIOD_D1)
# ok will always return True unless the strategy is stopped
ret, ok = d.wait()
# If wait times out, or if waiting on an already finished instance, ok returns False
ret, ok = d.wait(100)
Account
exchange.GetAccount
The exchange.GetAccount() function is used to request exchange account information. The GetAccount() function is a member function of the exchange object exchange. The member functions (methods) of the exchange object are only related to exchange, which will not be repeated in subsequent documentation.
exchange.GetAccount()Examples
Set trading pair and contract code, get current account information.
javascript
function main(){
// 切换交易对
exchange.IO("currency", "BTC_USDT")
// 以OKX期货为例,设置合约为当周合约,当前交易对为BTC_USDT,所以当前合约为BTC的U本位当周合约
exchange.SetContractType("this_week")
// 获取当前账户资产数据
var account = exchange.GetAccount()
// USDT作为保证金的可用余额
Log(account.Balance)
// USDT作为保证金的冻结金额
Log(account.FrozenBalance)
// 当前资产权益
Log(account.Equity)
// 当前资产作为保证金的所有持仓的未实现盈亏
Log(account.UPnL)
}
python
def main():
exchange.IO("currency", "BTC_USDT")
exchange.SetContractType("this_week")
account = exchange.GetAccount()
Log(account["Balance"])
Log(account["FrozenBalance"])
Log(account["Equity"])
Log(account["UPnL"])
c++
void main() {
exchange.IO("currency", "BTC_USDT");
exchange.SetContractType("this_week");
auto account = exchange.GetAccount();
Log(account.Balance);
Log(account.FrozenBalance);
Log(account.Equity);
Log(account.UPnL);
}Returns
| Type | Description |
| Query account asset information. Returns |
See Also
Remarks
If the exchange object is set to a cryptocurrency futures contract exchange and switched to contracts using USDT as margin (for switching methods, please refer to exchange.SetCurrency, exchange.SetContractType functions), assets are margined in USDT and recorded in the Balance and FrozenBalance properties of the Account structure.
If the exchange object is set to a cryptocurrency futures contract exchange and switched to coin-margined contracts, assets are margined in coins and recorded in the Stocks and FrozenStocks properties of the Account structure.
When using Binance Futures unified account, when calling the exchange.GetAccount() function to request account information, the encapsulated data is the amount of all assets converted to **USD**, displayed in the Balance field of the Account structure. To calculate the converted amount of other assets, divide the USD converted amount by the index price (of the asset to be converted) and then divide by the collateral rate (of the asset to be converted).
exchange.GetAssets
The exchange.GetAssets function is used to request asset information from the exchange account.
exchange.GetAssets()Examples
Get exchange account asset information, exchange.GetAssets() returns an array with Asset structure elements.
javascript
function main() {
// exchange.SetCurrency("BTC_USDT") // 可以设置交易对
// exchange.SetContractType("swap") // 可以设置合约
var assets = exchange.GetAssets()
Log(assets)
}
python
def main():
# exchange.SetCurrency("BTC_USDT") # 可以设置交易对
# exchange.SetContractType("swap") # 可以设置合约
assets = exchange.GetAssets()
Log(assets)
c++
void main() {
// exchange.SetCurrency("BTC_USDT"); // 可以设置交易对
// exchange.SetContractType("swap"); // 可以设置合约
auto assets = exchange.GetAssets();
Log(assets);
}Returns
| Type | Description |
| The |
See Also
Remarks
The GetAssets() function of futures exchange objects returns margin asset information under the current trading pair (coin-margined, USDT-margined, USDC-margined, etc.).
exchange.GetName
The exchange.GetName() function is used to get the exchange name bound to the current exchange object.
exchange.GetName()Examples
javascript
function main() {
Log("Check if exchange object is Binance spot, result:", exchange.GetName() == "Binance")
}
python
def main():
Log("Check if exchange object is Binance spot, result:", exchange.GetName() == "Binance")
c++
void main() {
Log("Check if exchange object is Binance spot, result:", exchange.GetName() == "Binance");
}Returns
| Type | Description |
string | The |
See Also
Remarks
The exchange.GetName() function is commonly used to identify exchange objects such as exchange or exchanges[1], exchanges[2] etc. in strategy code. Cryptocurrency futures contract exchange names have a fixed prefix Futures_.
exchange.GetLabel
The exchange.GetLabel() function is used to get the custom label set when configuring the exchange object.
exchange.GetLabel()Examples
javascript
function main() {
Log("exchange label:", exchange.GetLabel())
}
python
def main():
Log("exchange label:", exchange.GetLabel())
c++
void main() {
Log("exchange label:", exchange.GetLabel());
}Returns
| Type | Description |
string | The |
See Also
Remarks
Identify exchange objects such as exchange or exchanges[1], exchanges[2] etc. in the strategy code through the set labels.
exchange.GetCurrency
The exchange.GetCurrency() function is used to get the currently set trading pair.
exchange.GetCurrency()Examples
javascript
function main() {
Log("Current trading pair:", exchange.GetCurrency())
}
python
def main():
Log("Current trading pair:", exchange.GetCurrency())
c++
void main() {
Log("Current trading pair:", exchange.GetCurrency());
}Returns
| Type | Description |
string | The |
See Also
Remarks
The trading pair format is uniformly in uppercase, using underscore to separate baseCurrency and quoteCurrency, for example: BTC_USDT.
exchange.SetCurrency
The exchange.SetCurrency() function is used to switch the current trading pair of the exchange object exchange.
exchange.SetCurrency(currency)Examples
javascript
function main() {
var ticker = exchange.GetTicker()
Log(ticker)
Log(exchange.GetAccount())
// Switch trading pair, note the changes in market data and account information after switching
exchange.SetCurrency("LTC_USDT")
Log("Switched to LTC_USDT")
ticker = exchange.GetTicker()
Log(ticker)
Log(exchange.GetAccount())
}
python
def main():
ticker = exchange.GetTicker()
Log(ticker)
Log(exchange.GetAccount())
exchange.SetCurrency("LTC_USDT")
Log("Switched to LTC_USDT")
ticker = exchange.GetTicker()
Log(ticker)
Log(exchange.GetAccount())
c++
void main() {
auto ticker = exchange.GetTicker();
Log(ticker);
Log(exchange.GetAccount());
exchange.SetCurrency("LTC_USDT");
Log("Switched to LTC_USDT");
ticker = exchange.GetTicker();
Log(ticker);
Log(exchange.GetAccount());
}Arguments
| Name | Type | Required | Description |
currency | string | Yes | The |
See Also
Remarks
-
Compatible with
exchange.IO("currency", "BTC_USDT")switching method, refer toexcahnge.IO. -
Supports switching trading pairs in the backtesting system. When switching trading pairs in the backtesting system, the quote currency name cannot be changed. For example:
BTC_USDTcan be switched toLTC_USDT, but cannot be switched toLTC_BTC. -
After switching to a trading pair that is not initially set on the backtesting page, the amount of the base currency is 0. For example: during backtesting, the initially set trading pair on the backtesting page is
BTC_USDT, with 3BTCand 10000USDT. When immediately switching toLTC_USDT, after switching, the base currency amount is 0, meaning theLTCamount in the account is 0, and the switched trading pair shares theUSDTamount, which remains 10000.
exchange.GetQuoteCurrency
The exchange.GetQuoteCurrency() function is used to get the quote currency name of the current trading pair, i.e., quoteCurrency.
exchange.GetQuoteCurrency()Examples
javascript
function main() {
exchange.SetCurrency("BTC_USDT")
Log("Quote currency for BTC_USDT:", exchange.GetQuoteCurrency())
// exchange.SetCurrency("ETH_BTC")
// Log("Quote currency for ETH_BTC:", exchange.GetQuoteCurrency())
}
python
def main():
exchange.SetCurrency("BTC_USDT")
Log("Quote currency for BTC_USDT:", exchange.GetQuoteCurrency())
# exchange.SetCurrency("ETH_BTC")
# Log("Quote currency for ETH_BTC:", exchange.GetQuoteCurrency())
c++
void main() {
exchange.SetCurrency("BTC_USDT");
Log("Quote currency for BTC_USDT:", exchange.GetQuoteCurrency());
// exchange.SetCurrency("ETH_BTC")
// Log("Quote currency for ETH_BTC:", exchange.GetQuoteCurrency())
}Returns
| Type | Description |
string | The |
See Also
Remarks
For example: if the current trading pair of the exchange exchange object is BTC_USDT, the exchange.GetQuoteCurrency() function returns USDT. If the current trading pair is ETH_BTC, the exchange.GetQuoteCurrency() function returns BTC.
Futures
exchange.GetPositions
The exchange.GetPositions() function is used to get position information; GetPositions() function is a member function of the exchange object exchange.
The GetPositions() function gets the position information of the exchange account bound to the exchange object exchange. The purpose of member functions (methods) of the exchange object is only related to exchange, which will not be repeated in subsequent documentation.
exchange.GetPositions()
exchange.GetPositions(symbol)Examples
Use futures exchange object to place market orders for multiple different trading pairs and contract codes. Query positions in various ways.
javascript
/*backtest
start: 2024-05-21 00:00:00
end: 2024-09-05 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
function main() {
var arrSymbol = ["BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"]
for (var symbol of arrSymbol) {
exchange.CreateOrder(symbol, "buy", -1, 1)
exchange.CreateOrder(symbol, "sell", -1, 1)
}
var defaultPositions = exchange.GetPositions()
var swapPositions = exchange.GetPositions("USDT.swap")
var futuresPositions = exchange.GetPositions("USDT.futures")
var btcUsdtSwapPositions = exchange.GetPositions("BTC_USDT.swap")
var tbls = []
var arr = [defaultPositions, swapPositions, futuresPositions, btcUsdtSwapPositions]
var tblDesc = ["defaultPositions", "swapPositions", "futuresPositions", "btcUsdtSwapPositions"]
for (var index in arr) {
var positions = arr[index]
var tbl = {type: "table", title: tblDesc[index], cols: ["Symbol", "MarginLevel", "Amount", "FrozenAmount", "Price", "Profit", "Type", "ContractType", "Margin"], rows: [] }
for (var pos of positions) {
tbl.rows.push([pos.Symbol, pos.MarginLevel, pos.Amount, pos.FrozenAmount, pos.Price, pos.Profit, pos.Type, pos.ContractType, pos.Margin])
}
tbls.push(tbl)
}
LogStatus("`" + JSON.stringify(tbls) + "`")
// Print output information once and return to prevent subsequent order execution during backtesting, which would affect data observation
return
}
python
'''backtest
start: 2024-05-21 00:00:00
end: 2024-09-05 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
'''
import json
def main():
arrSymbol = ["BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"]
for symbol in arrSymbol:
exchange.CreateOrder(symbol, "buy", -1, 1)
exchange.CreateOrder(symbol, "sell", -1, 1)
defaultPositions = exchange.GetPositions()
swapPositions = exchange.GetPositions("USDT.swap")
futuresPositions = exchange.GetPositions("USDT.futures")
btcUsdtSwapPositions = exchange.GetPositions("BTC_USDT.swap")
tbls = []
arr = [defaultPositions, swapPositions, futuresPositions, btcUsdtSwapPositions]
tblDesc = ["defaultPositions", "swapPositions", "futuresPositions", "btcUsdtSwapPositions"]
for index in range(len(arr)):
positions = arr[index]
tbl = {"type": "table", "title": tblDesc[index], "cols": ["Symbol", "MarginLevel", "Amount", "FrozenAmount", "Price", "Profit", "Type", "ContractType", "Margin"], "rows": []}
for pos in positions:
tbl["rows"].append([pos["Symbol"], pos["MarginLevel"], pos["Amount"], pos["FrozenAmount"], pos["Price"], pos["Profit"], pos["Type"], pos["ContractType"], pos["Margin"]])
tbls.append(tbl)
LogStatus("`" + json.dumps(tbls) + "`")
return
c++
/*backtest
start: 2024-05-21 00:00:00
end: 2024-09-05 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
void main() {
auto arrSymbol = {"BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"};
for (const auto& symbol : arrSymbol) {
exchange.CreateOrder(symbol, "buy", -1, 1);
exchange.CreateOrder(symbol, "sell", -1, 1);
}
auto defaultPositions = exchange.GetPositions();
auto swapPositions = exchange.GetPositions("USDT.swap");
auto futuresPositions = exchange.GetPositions("USDT.futures");
auto btcUsdtSwapPositions = exchange.GetPositions("BTC_USDT.swap");
json tbls = R"([])"_json;
std::vector<std::vector<Position>> arr = {defaultPositions, swapPositions, futuresPositions, btcUsdtSwapPositions};
std::string tblDesc[] = {"defaultPositions", "swapPositions", "futuresPositions", "btcUsdtSwapPositions"};
for (int index = 0; index < arr.size(); index++) {
auto positions = arr[index];
json tbl = R"({
"type": "table",
"cols": ["Symbol", "MarginLevel", "Amount", "FrozenAmount", "Price", "Profit", "Type", "ContractType", "Margin"],
"rows": []
})"_json;
tbl["title"] = tblDesc[index];
for (const auto& pos : positions) {
json arrJson = R"([])"_json;
arrJson.push_back(pos.Symbol);
arrJson.push_back(pos.MarginLevel);
arrJson.push_back(pos.Amount);
arrJson.push_back(pos.FrozenAmount);
arrJson.push_back(pos.Price);
arrJson.push_back(pos.Profit);
arrJson.push_back(pos.Type);
arrJson.push_back(pos.ContractType);
arrJson.push_back(pos.Margin);
tbl["rows"].push_back(arrJson);
}
tbls.push_back(tbl);
}
LogStatus(_D(), "\n", "`" + tbls.dump() + "`");
return;
}Returns
| Type | Description |
| The |
Arguments
| Name | Type | Required | Description |
symbol | string | No | The When the |
See Also
Remarks
Cryptocurrency futures contracts differ from cryptocurrency spot trading, where spot only has a logical position concept. In the FMZ quantitative trading platform system, specific cryptocurrency futures contract varieties are identified by both **trading pair** and **contract code**. Please refer to exchange.SetCurrency and exchange.SetContractType functions.
Summary of symbol parameter usage scenarios in the GetPositions function:
| Exchange Object Category | symbol Parameter | Query Scope | Notes |
|---|---|---|---|
| Futures | No symbol parameter | Query all trading varieties within current trading pair and contract code dimension | If current trading pair is BTC_USDT and contract code is swap, it queries all USDT-margined perpetual contracts. Equivalent to calling GetPositions("USDT.swap") |
| Futures | Specify trading variety, symbol parameter: "BTC_USDT.swap" | Query specified BTC USDT-margined perpetual contract | For futures exchange objects, the symbol parameter format is: FMZ platform-defined trading pair and contract code combination, separated by . character. |
| Futures | Specify trading variety range, symbol parameter: "USDT.swap" | Query all USDT-margined perpetual contracts | - |
| Futures exchanges supporting options | No symbol parameter | Query all option contracts within current trading pair dimension | If current trading pair is BTC_USDT and contract is set to option contract, e.g., Binance option contract: BTC-240108-40000-C |
| Futures exchanges supporting options | Specify specific trading variety | Query specified option contract | For example, for Binance futures exchange, symbol parameter: BTC_USDT.BTC-240108-40000-C |
| Futures exchanges supporting options | Specify trading variety range, symbol parameter: "USDT.option" | Query all USDT-margined option contracts | - |
Summary of futures exchange object query dimension ranges in the GetPositions function:
| symbol Parameter | Request Scope Definition | Notes |
|---|---|---|
| USDT.swap | USDT-margined perpetual contract range. | For dimensions not supported by exchange API interfaces, calls will return an error with null value. |
| USDT.futures | USDT-margined delivery contract range. | - |
| USD.swap | Coin-margined perpetual contract range. | - |
| USD.futures | Coin-margined delivery contract range. | - |
| USDT.option | USDT-margined option contract range. | - |
| USD.option | Coin-margined option contract range. | - |
| USDT.futures_combo | Spread combination contract range. | Futures_Deribit exchange |
| USD.futures_ff | Multi-collateral delivery contract range. | Futures_Kraken exchange |
| USD.swap_pf | Multi-collateral perpetual contract range. | Futures_Kraken exchange |
Compatible with exchange.GetPosition() call, GetPosition and GetPositions usage is completely identical.
When the account represented by the exchange object exchange has no positions within the query scope or for the specified trading variety, the exchange.GetPositions() function returns an empty array, for example: [].
exchange.SetMarginLevel
The exchange.SetMarginLevel() function is used to set the leverage value for the trading pair or contract specified by the symbol parameter. It supports passing only the marginLevel parameter to set the leverage value for the current trading pair or contract of the exchange exchange object.
exchange.SetMarginLevel(symbol, marginLevel)
exchange.SetMarginLevel(marginLevel)Examples
javascript
function main() {
exchange.SetMarginLevel(10)
// Set the leverage of BTC's USDT-margined perpetual contract to 15
exchange.SetMarginLevel("BTC_USDT.swap", 15)
}
python
def main():
exchange.SetMarginLevel(10)
exchange.SetMarginLevel("BTC_USDT.swap", 15)
c++
void main() {
exchange.SetMarginLevel(10);
exchange.SetMarginLevel("BTC_USDT.swap", 15);
}Arguments
| Name | Type | Required | Description |
symbol | string | No | The |
marginLevel | number | Yes | The |
See Also
Remarks
The exchange.SetMarginLevel() function only supports cryptocurrency futures contract exchange objects. The backtesting system supports calling the exchange.SetMarginLevel() function to set leverage values.
For cryptocurrency futures contracts, the leverage mechanisms across exchanges are not unified.
For some exchanges, the futures contract leverage value is a parameter in the order placement interface. In this case, calling the exchange.SetMarginLevel() function will not generate a network request, but only sets the underlying leverage variable in the FMZ system (used for order interface parameter passing).
For some exchanges, the futures contract leverage value is an exchange setting that needs to be configured through the exchange website page or using API interfaces. In this case, calling the exchange.SetMarginLevel() function will generate a network request and may fail to set. Reasons for failure may include: existing positions or pending orders that prevent the trading pair or contract from being set to a new leverage value.
Exchanges that do not support the exchange.SetMarginLevel() function:
| Function Name | Unsupported Spot Exchanges | Unsupported Futures Exchanges |
|---|---|---|
| SetMarginLevel | -- | Futures_dYdX / Futures_Deribit / Futures_edgeX |
exchange.SetDirection
The exchange.SetDirection() function is used to set the order direction when placing futures contract orders with the exchange.Buy function and exchange.Sell function.
exchange.SetDirection(direction)Examples
javascript
function main(){
// 示例:设置为OKX期货当周合约
exchange.SetContractType("this_week")
// 设置杠杆为5倍
exchange.SetMarginLevel(5)
// 设置下单类型为做多
exchange.SetDirection("buy")
// 以10000的价格,合约数量为2张下单
exchange.Buy(10000, 2)
exchange.SetMarginLevel(5)
exchange.SetDirection("closebuy")
exchange.Sell(1000, 2)
}
python
def main():
exchange.SetContractType("this_week")
exchange.SetMarginLevel(5)
exchange.SetDirection("buy")
exchange.Buy(10000, 2)
exchange.SetMarginLevel(5)
exchange.SetDirection("closebuy")
exchange.Sell(1000, 2)
c++
void main() {
exchange.SetContractType("this_week");
exchange.SetMarginLevel(5);
exchange.SetDirection("buy");
exchange.Buy(10000, 2);
exchange.SetMarginLevel(5);
exchange.SetDirection("closebuy");
exchange.Sell(1000, 2);
}Arguments
| Name | Type | Required | Description |
direction | string | Yes | The |
See Also
Remarks
The correspondence between the direction set by the exchange.SetDirection() function for futures contract trading and the order placement functions:
| Order Function | Direction Set by SetDirection Parameter | Notes |
|---|---|---|
| exchange.Buy | "buy" | Buy to open long position |
| exchange.Buy | "closesell" | Buy to close short position |
| exchange.Sell | "sell" | Sell to open short position |
| exchange.Sell | "closebuy" | Sell to close long position |
exchange.SetContractType
The exchange.SetContractType() function is used to set the current contract code for the exchange exchange object.
exchange.SetContractType(symbol)Examples
-
Set the current contract to the current week contract:
javascriptfunction main() { // Set to current week contract exchange.SetContractType("this_week") }pythondef main(): exchange.SetContractType("this_week")c++void main() { exchange.SetContractType("this_week"); } -
When setting a contract with
USDTas margin, you need to switch the trading pair in the code (you can also set the trading pair directly when adding the exchange object):javascriptfunction main() { // Default trading pair is BTC_USD, set contract to current week, contract is coin-margined contract exchange.SetContractType("this_week") Log("ticker:", exchange.GetTicker()) // Switch trading pair, then set contract, switch to USDT-margined contract, different from coin-margined contract exchange.IO("currency", "BTC_USDT") exchange.SetContractType("swap") Log("ticker:", exchange.GetTicker()) }pythondef main(): exchange.SetContractType("this_week") Log("ticker:", exchange.GetTicker()) exchange.IO("currency", "BTC_USDT") exchange.SetContractType("swap") Log("ticker:", exchange.GetTicker())c++void main() { exchange.SetContractType("this_week"); Log("ticker:", exchange.GetTicker()); exchange.IO("currency", "BTC_USDT"); exchange.SetContractType("swap"); Log("ticker:", exchange.GetTicker()); } -
Print the return value of the
exchange.SetContractType()function:javascriptfunction main(){ // Set contract to current week var ret = exchange.SetContractType("this_week") // Return the information of the current week contract Log(ret) }pythondef main(): ret = exchange.SetContractType("this_week") Log(ret)c++void main() { auto ret = exchange.SetContractType("this_week"); Log(ret); }
Returns
| Type | Description |
object | The |
Arguments
| Name | Type | Required | Description |
symbol | string | Yes | The Unless otherwise specified, delivery contract codes in cryptocurrency futures contracts generally include:
Unless otherwise specified, perpetual contract codes in cryptocurrency futures contracts generally include:
|
See Also
Remarks
In cryptocurrency futures contract strategies, taking switching to the BTC_USDT trading pair as an example:
When using the exchange.SetCurrency("BTC_USDT") or exchange.IO("currency", "BTC_USDT") function to switch trading pairs, after switching you need to use the exchange.SetContractType() function to reset the contract in order to determine the current contract to operate under the new trading pair. The system determines whether it is a coin-margined contract or USDT-margined contract based on the trading pair.
For example: When the trading pair is set to BTC_USDT, using the exchange.SetContractType("swap") function to set the contract code to swap sets it to the USDT-margined perpetual contract for BTC. If the trading pair is BTC_USD, using the exchange.SetContractType("swap") function to set the contract code to swap sets it to the coin-margined perpetual contract for BTC.
Detailed introduction to supported cryptocurrency futures contract exchanges. The contract naming for each exchange is as follows:
-
Futures_OKCoin (OKX)
Set to perpetual contract:exchange.SetContractType("swap")
Set to current week contract:exchange.SetContractType("this_week")
Set to next week contract:exchange.SetContractType("next_week")
Set to monthly contract:exchange.SetContractType("month")
Set to next month contract:exchange.SetContractType("next_month")
Set to quarterly contract:exchange.SetContractType("quarter")
Set to next quarter contract:exchange.SetContractType("next_quarter")OKX supports pre-market trading contracts: The contract delivery date is fixed, and an example of the exchange-defined contract code is:
HMSTR-USDT-250207. On the FMZ platform, set the trading pair toHMSTR_USDT, then useexchange.SetContractType("HMSTR-USDT-250207")to set this contract.
For functions that support thesymbolparameter, such as:exchange.GetTicker(),exchange.CreateOrder(), etc., you can specify thesymbolparameter as:HMSTR_USDT.HMSTR-USDT-250207to get market data for this contract or execute orders. -
Futures_HuobiDM (Huobi Futures)
Set to current week contract:exchange.SetContractType("this_week").
Set to next week contract:exchange.SetContractType("next_week").
Set to quarterly contract:exchange.SetContractType("quarter").
Set to next quarter contract:exchange.SetContractType("next_quarter").
Set to perpetual contract:exchange.SetContractType("swap").
Supports contracts withUSDTas margin. TakingBTCcontract as an example: useexchange.IO("currency", "BTC_USDT")to switch to contracts withUSDTas margin,
or directly set the current trading pair toBTC_USDTwhen configuring live trading parameters and adding exchange objects. After switching trading pairs, you need to call theexchange.SetContractType()function again to set the contract. -
Futures_BitMEX (BitMEX)
Set to perpetual contract:exchange.SetContractType("swap").
Futures_BitMEX exchange's delivery contracts are monthly contracts, with contract codes as follows (January to December):code"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"Set delivery contract:
exchange.SetContractType("December"). For example, when the trading pair is set toXBT_USDT, callingexchange.SetContractType("December")function sets the BTC USDT-margined December delivery contract (the actual contract code isXBTUSDTZ23).Futures_BitMEX Contract Information Summary
Futures_BitMEX Defined Contract Code Corresponding Trading Pair on FMZ Corresponding Contract Code on FMZ Notes DOGEUSD DOGE_USD swap USD quoted, XBT settled. XBT is BTC. DOGEUSDT DOGE_USDT swap USDT quoted, USDT settled. XBTETH XBT_ETH swap ETH quoted, XBT settled. XBTEUR XBT_EUR swap EUR quoted, XBT settled. USDTUSDC USDT_USDC swap USDC quoted, XBT settled. ETHUSD_ETH ETH_USD_ETH swap USD quoted, ETH settled. XBTH24 XBT_USD March Expiry: March 2024, month code: H; USD quoted, XBT settled. ETHUSDZ23 ETH_USD December Expiry: December 2023, month code: Z; USD quoted, XBT settled. XBTUSDTZ23 XBT_USDT December Expiry: December 2023, month code: Z; USDT quoted, USDT settled. ADAZ23 ADA_XBT December Expiry: December 2023, month code: Z; XBT quoted, XBT settled. P_XBTETFX23 USDT_XXX P_XBTETFX23 Expiry: November 2023; percentage quoted, USDT settled. -
Futures_GateIO
Set to current week contract:exchange.SetContractType("this_week").
Set to next week contract:exchange.SetContractType("next_week").
Set to quarterly contract:exchange.SetContractType("quarter").
Set to next quarter contract:exchange.SetContractType("next_quarter").
Set to perpetual contract:exchange.SetContractType("swap").
Supports contracts withUSDTas margin. TakingBTCcontract as an example, useexchange.IO("currency", "BTC_USDT")to switch to contracts withUSDTas margin,
or directly set the current trading pair toBTC_USDTwhen configuring live trading parameters and adding exchange objects. After switching trading pairs, you need to call theexchange.SetContractType()function again to set the contract. -
Futures_Deribit
Set to perpetual contract:exchange.SetContractType("swap").
Supports Deribit'sUSDCcontracts.
Delivery contracts include:"this_week","next_week","month","quarter","next_quarter","third_quarter","fourth_quarter".
Spread contracts (future_combo):"this_week,swap","next_week,swap","next_quarter,this_week","third_quarter,this_week","month,next_week", and various other combinations.
For options contracts, you need to pass the specific option contract code defined by the exchange. Please refer to the Deribit official website for details. -
Futures_KuCoin
Coin-margined contracts, for example, set the trading pair toBTC_USD, then set the contract code for coin-margined contracts:
Set to perpetual contract:exchange.SetContractType("swap").
Set to current quarter contract:exchange.SetContractType("quarter").
Set to next quarter contract:exchange.SetContractType("next_quarter").Contracts with USDT as margin:
For example, set the trading pair toBTC_USDT, then set the contract code for USDT-margined contracts.
Set to perpetual contract:exchange.SetContractType("swap"). -
Futures_Binance
Binance Futures exchange defaults to the perpetual contract of the current trading pair, contract code:swap.
Set to perpetual contract:exchange.SetContractType("swap"). Binance perpetual contracts supportUSDTas margin, for example,BTC'sUSDT-margined perpetual contract, set the trading pair toBTC_USDT. Binance also supports coin-margined perpetual contracts, for example,BTC's coin-margined perpetual contract, set the trading pair toBTC_USD.
Set to quarterly contract:exchange.SetContractType("quarter"). Delivery contracts support coin-margined contracts (i.e., using coins as margin), for example,BTC's quarterly contract, set the trading pair toBTC_USD, then set the contractexchange.SetContractType("quarter")to setBTC's coin-margined quarterly contract.
Set to next quarter contract:exchange.SetContractType("next_quarter"). For example,BTC's coin-margined next quarter contract, set the trading pair toBTC_USD, then set the contractexchange.SetContractType("next_quarter").
Binance supports some delivery contracts withUSDTas margin. TakingBTCas an example, set the trading pair toBTC_USDT, then set the contract code.Supports Binance options contracts:
The option contract code format follows the exchange-defined option contract codes:BTC-241227-15000-C,XRP-240112-0.5-C,BTC-241227-15000-P. Taking Binance option contract codeBTC-241227-15000-Pas an example: BTC is the option currency code, 241227 is the exercise date, 15000 is the strike price, P indicates a put option, and C indicates a call option.
For specific information about option types (European options/American options), please refer to the exchange's option contract documentation.
The exchange may restrict option sellers, requiring separate qualification application. Binance options require seller qualification application. -
Futures_Bibox
Bibox perpetual contract code:swap.
Set to perpetual contract:exchange.SetContractType("swap"). -
Futures_Bybit
Defaults to the perpetual contract of the current trading pair, contract code:swap.
Current week contract code:this_week.
Next week contract code:next_week.
Third week contract code:third_week.
Monthly contract code:month.
Next month contract code:next_month.
Quarterly contract code:quarter.
Next quarter contract code:next_quarter.
Third quarter contract code:third_quarter.
Direct use of exchange contract naming: For exampleETHUSDT-04APR25, since some contract types on Bybit exchange do not have clear periodicity, the exchange-defined contract code naming is used directly. -
Futures_Kraken
Defaults to the perpetual contract of the current trading pair, contract code:swap.
swap: Perpetual contract.
month: Current month contract.
quarter: Quarterly contract.
next_quarter: Next quarter contract.
third_quarter: Third quarter contract.
swap_pf: Multi-collateral perpetual contract.
quarter_ff: Multi-collateral quarterly contract.
month_ff: Multi-collateral current month contract.
next_quarter_ff: Multi-collateral next quarter contract.
third_quarter_ff: Multi-collateral third quarter contract.
Direct use of exchange contract naming: For exampleFF_ETHUSD_250307, since some contract types on Kraken exchange do not have clear periodicity, the exchange-defined contract code naming is used directly. -
Futures_Bitfinex
Defaults to the perpetual contract of the current trading pair, contract code:swap. -
Futures_Bitget
Defaults to the perpetual contract of the current trading pair, contract code:swap.
Setting the trading pair toBTC_USDis for coin-margined contracts, setting the trading pair toBTC_USDTis forUSDT-settled contracts. Simulated contracts can set the trading pair to:SBTC_USD,BTC_SUSDT. -
Futures_dYdX (v4)
dYdX perpetual contract code:swap.
Set to perpetual contract:exchange.SetContractType("swap"), dYdX only has theUSD.swapinstrument dimension, using USDC as margin. -
Futures_MEXC
MEXC perpetual contract code:swap.
Set to perpetual contract:exchange.SetContractType("swap"). Setting the trading pair toBTC_USDis for coin-margined contracts, setting the trading pair toBTC_USDTis forUSDT-settled contracts. -
Futures_Crypto
Tokens in the crypto.com exchange account can be converted to USD-denominated credit for use as margin in contract trading.
Set to perpetual contract:exchange.SetContractType("swap"). For example, when the trading pair is set toBTC_USD, callingexchange.SetContractType("swap")function sets the BTC perpetual contract.
crypto.com exchange's delivery contracts are monthly contracts, with contract codes as follows (January to December):code"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"Set delivery contract:
exchange.SetContractType("October"). For example, when the trading pair is set toBTC_USD, callingexchange.SetContractType("October")function sets the BTC October delivery contract.
The contract code corresponding to the current moment is:BTCUSD-231027. -
Futures_WOO
Futures_WOO exchange supportsUSDT-margined contracts, perpetual contract code isswap. For example, when the trading pair is set toBTC_USDT, callingexchange.SetContractType("swap")function sets the current contract to BTC's USDT-margined perpetual contract. -
Futures_Hyperliquid
Futures_Hyperliquid exchange supportsUSDC-margined contracts, perpetual contract code isswap. For example, when the trading pair is set toETH_USD, callingexchange.SetContractType("swap")function sets the current contract to ETH's USDC-margined perpetual contract.
Futures_Hyperliquid only has theUSD.swapinstrument dimension, using USDC as margin.
Futures_Hyperliquid supports HIP-3 instruments. -
Futures_Lighter
Futures_Lighter exchange supportsUSDC-margined contracts, perpetual contract code isswap. For example, when the trading pair is set toBTC_USDC, callingexchange.SetContractType("swap")function sets the current contract to BTC's USDC-margined perpetual contract.
Futures_Lighter only supports perpetual contracts. -
Futures_Backpack
Futures_Backpack exchange supportsUSDC-margined contracts, perpetual contract code isswap. For example, when the trading pair is set toETH_USDC, callingexchange.SetContractType("swap")function sets the current contract to ETH's USDC-margined perpetual contract. -
Futures_edgeX
Futures_edgeX exchange supportsUSDT-margined contracts, perpetual contract code isswap. For example, when the trading pair is set toBTC_USDT, callingexchange.SetContractType("swap")function sets the current contract to BTC's USDT-margined perpetual contract. -
Futures_WOOFI
Futures_WOOFI exchange supportsUSDC-margined contracts, perpetual contract code isswap. For example, when the trading pair is set toETH_USDC, callingexchange.SetContractType("swap")function sets the current contract to ETH's USDC-margined perpetual contract. -
Futures_Coinw
Futures_Coinw exchange supportsUSDT-margined contracts, perpetual contract code isswap. For example, when the trading pair is set toETH_USDT, callingexchange.SetContractType("swap")function sets the current contract to ETH's USDT-margined perpetual contract. -
Futures_Aster
Futures_Aster exchange supportsUSDT-margined contracts, perpetual contract code isswap. For example, when the trading pair is set toETH_USDT, callingexchange.SetContractType("swap")function sets the current contract to ETH's USDT-margined perpetual contract. -
Futures_DeepCoin
Coin-margined contracts, for example, set the trading pair toBTC_USD, then set the contract code for coin-margined contracts:
Set to perpetual contract:exchange.SetContractType("swap").Contracts with USDT as margin:
For example, set the trading pair toBTC_USDT, then set the contract code for USDT-margined contracts.
Set to perpetual contract:exchange.SetContractType("swap").
exchange.GetContractType
The exchange.GetContractType() function is used to get the contract code currently set for the exchange exchange object.
exchange.GetContractType()Examples
javascript
function main () {
Log(exchange.SetContractType("this_week"))
Log(exchange.GetContractType())
}
python
def main():
Log(exchange.SetContractType("this_week"))
Log(exchange.GetContractType())
c++
void main() {
Log(exchange.SetContractType("this_week"));
Log(exchange.GetContractType());
}Returns
| Type | Description |
string | The |
See Also
exchange.GetFundings
The exchange.GetFundings() function is used to get the funding rate data for the current period.
exchange.GetFundings()
exchange.GetFundings(symbol)Examples
Using a futures exchange object, call the exchange.GetFundings() function in the backtesting system. Before calling any market data function, GetFundings only returns Funding data for the current default trading pair; after calling market data functions, it returns Funding data for all requested symbols. Refer to the following test example:
javascript
/*backtest
start: 2024-10-01 00:00:00
end: 2024-10-23 00:05:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"SOL_USDC"}]
*/
function main() {
// LPT_USDT.swap 4-hour period
var symbols = ["SOL_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "SOL_USDC.swap", "ETH_USDC.swap", "BTC_USD.swap", "BTC_USDT.quarter", "LPT_USDT.swap"]
for (var symbol of symbols) {
exchange.GetTicker(symbol)
}
var arr = []
var arrParams = ["no param", "LTC_USDT.swap", "USDT.swap", "USD.swap", "USDC.swap", "USDT.futures", "BTC_USDT.quarter"]
for (p of arrParams) {
if (p == "no param") {
arr.push(exchange.GetFundings())
} else {
arr.push(exchange.GetFundings(p))
}
}
var tbls = []
var index = 0
for (var fundings of arr) {
var tbl = {
"type": "table",
"title": arrParams[index],
"cols": ["Symbol", "Interval", "Time", "Rate"],
"rows": [],
}
for (var f of fundings) {
tbl["rows"].push([f.Symbol, f.Interval / 3600000, _D(f.Time), f.Rate * 100 + " %"])
}
tbls.push(tbl)
index++
}
LogStatus(_D(), "\n Requested symbols:", symbols, "\n`" + JSON.stringify(tbls) + "`")
}
python
'''backtest
start: 2024-10-01 00:00:00
end: 2024-10-23 00:05:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"SOL_USDC"}]
'''
import json
def main():
# LPT_USDT.swap 4-hour period
symbols = ["SOL_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "SOL_USDC.swap", "ETH_USDC.swap", "BTC_USD.swap", "BTC_USDT.quarter", "LPT_USDT.swap"]
for symbol in symbols:
exchange.GetTicker(symbol)
arr = []
arrParams = ["no param", "LTC_USDT.swap", "USDT.swap", "USD.swap", "USDC.swap", "USDT.futures", "BTC_USDT.quarter"]
for p in arrParams:
if p == "no param":
arr.append(exchange.GetFundings())
else:
arr.append(exchange.GetFundings(p))
tbls = []
index = 0
for fundings in arr:
tbl = {
"type": "table",
"title": arrParams[index],
"cols": ["Symbol", "Interval", "Time", "Rate"],
"rows": [],
}
for f in fundings:
tbl["rows"].append([f["Symbol"], f["Interval"] / 3600000, _D(f["Time"]), str(f["Rate"] * 100) + " %"])
tbls.append(tbl)
index += 1
LogStatus(_D(), "\n Requested symbols:", symbols, "\n`" + json.dumps(tbls) + "`")
c++
/*backtest
start: 2024-10-01 00:00:00
end: 2024-10-23 00:05:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"SOL_USDC"}]
*/
void main() {
// LPT_USDT.swap 4-hour period
json arrSymbol = R"([])"_json;
std::string symbols[] = {"SOL_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "SOL_USDC.swap", "ETH_USDC.swap", "BTC_USD.swap", "BTC_USDT.quarter", "LPT_USDT.swap"};
for (const std::string& symbol : symbols) {
exchange.GetTicker(symbol);
arrSymbol.push_back(symbol);
}
std::vector<std::vector<Funding>> arr = {};
std::string arrParams[] = {"no param", "LTC_USDT.swap", "USDT.swap", "USD.swap", "USDC.swap", "USDT.futures", "BTC_USDT.quarter"};
for (const std::string& p : arrParams) {
if (p == "no param") {
arr.push_back(exchange.GetFundings());
} else {
arr.push_back(exchange.GetFundings(p));
}
}
json tbls = R"([])"_json;
int index = 0;
for (int i = 0; i < arr.size(); i++) {
auto fundings = arr[i];
json tbl = R"({
"type": "table",
"cols": ["Symbol", "Interval", "Time", "Rate"],
"rows": []
})"_json;
tbl["title"] = arrParams[index];
for (int j = 0; j < fundings.size(); j++) {
auto f = fundings[j];
// json arrJson = {f.Symbol, f.Interval / 3600000, _D(f.Time), string(f.Rate * 100) + " %"};
json arrJson = {f.Symbol, f.Interval / 3600000, _D(f.Time), f.Rate};
tbl["rows"].push_back(arrJson);
}
tbls.push_back(tbl);
index++;
}
LogStatus(_D(), "\n Requested symbols:", arrSymbol.dump(), "\n`" + tbls.dump() + "`");
}Returns
| Type | Description |
| The |
Arguments
| Name | Type | Required | Description |
symbol | string | No | The parameter |
See Also
Remarks
For futures exchanges that do not support batch querying of funding rate data, if the symbol parameter is specified as a query range (e.g., USDT.swap) or the symbol parameter is not passed, the interface will report an error. When calling the GetFundings() function using such futures exchange objects, the symbol parameter must be specified as a specific perpetual contract instrument to query the current funding rate data for that instrument.
The exchange.GetFundings() function supports both live trading and backtesting systems.
Exchanges that do not support batch retrieval of funding rate data: Futures_Bitget, Futures_OKX, Futures_MEXC, Futures_Deribit, Futures_Crypto. The symbol parameter must be passed to specify a specific instrument code, e.g., ETH_USDT.swap.
Exchanges that do not support the exchange.GetFundings() function:
| Function Name | Unsupported Spot Exchanges | Unsupported Futures Exchanges |
|---|---|---|
| GetFundings | -- | Futures_DigiFinex |
NetSettings
exchange.SetBase
The exchange.SetBase() function is used to set the base address of the exchange API interface configured in the exchange exchange object.
exchange.SetBase(s)Examples
javascript
function main() {
// 使用默认基地址
Log(exchange.GetTicker())
// 切换为https://aws.okx.com
exchange.SetBase("https://aws.okx.com")
Log(exchange.GetTicker())
}
python
def main():
Log(exchange.GetTicker())
exchange.SetBase("https://aws.okx.com")
Log(exchange.GetTicker())
c++
void main() {
Log(exchange.GetTicker());
exchange.SetBase("https://aws.okx.com");
Log(exchange.GetTicker());
}Arguments
| Name | Type | Required | Description |
s | string | Yes | The |
See Also
Remarks
Switching exchange API base addresses is not supported in the backtesting system, as the backtesting system is a sandbox simulation environment and does not actually access the exchange's API interfaces.
exchange.GetBase
The exchange.GetBase() function is used to get the base address of the current exchange API interface.
exchange.GetBase()Examples
javascript
function main() {
Log(exchange.GetBase())
}
python
def main():
Log(exchange.GetBase())
c++
void main() {
Log(exchange.GetBase());
}Returns
| Type | Description |
string | The base address of the current exchange API interface. |
See Also
exchange.SetProxy
The exchange.SetProxy() function is used to set the proxy configuration for the exchange exchange object.
exchange.SetProxy(proxy)Examples
-
Configure
socks5proxy forexchangeexchange object:javascriptfunction main() { exchange.SetProxy("socks5://192.168.1.10:8080") // 如果访问不到交易所行情接口,设置一个可用的ss5代理,就可以访问到行情接口了 Log(exchange.GetTicker()) }pythondef main(): exchange.SetProxy("socks5://192.168.1.10:8080") Log(exchange.GetTicker())c++void main() { exchange.SetProxy("socks5://192.168.1.10:8080"); Log(exchange.GetTicker()); } -
In addition to **globally specifying** the IP address for requests sent by the
exchangeexchange object, it also supports specifying IP addresses based onexchange:javascriptfunction main(){ exchange.SetProxy("ip://10.0.3.15") // 发出的请求IP地址为10.0.3.15 exchange.GetTicker() }pythondef main(): exchange.SetProxy("ip://10.0.3.15") exchange.GetTicker()c++void main() { exchange.SetProxy("ip://10.0.3.15"); exchange.GetTicker(); }
Arguments
| Name | Type | Required | Description |
proxy | string | Yes | The |
See Also
Remarks
If the proxy setting fails, calling the exchange.SetProxy() function will return null.
The proxy setting functionality of the exchange.SetProxy() function only supports the rest protocol. Each exchange exchange object can set one proxy. After setting the proxy, all access to the exchange interface bound to the exchange exchange object will be accessed through the proxy.
Supports setting socks5 proxy, taking the first added exchange object exchange (i.e., exchanges[0]) as an example:
-
Set proxy (no username, no password):
exchange.SetProxy("socks5://127.0.0.1:8889"). -
Set proxy (with username and password):
exchange.SetProxy("socks5://username:[email protected]:8889"). Whereusernameis the username andpasswordis the password. -
Switch to normal mode (without proxy):
exchange.SetProxy("").
Supports setting the IP address for requests sent by the exchange exchange object, global specification.
exchange.SetTimeout
The exchange.SetTimeout() function is used to set the rest request timeout for the exchange exchange object.
exchange.SetTimeout(timeout)Examples
javascript
function main() {
exchange.SetTimeout(3000)
Log(exchange.GetTicker())
}
python
def main():
exchange.SetTimeout(3000)
Log(exchange.GetTicker())
c++
void main() {
exchange.SetTimeout(3000);
Log(exchange.GetTicker());
}Arguments
| Name | Type | Required | Description |
timeout | number | Yes | The |
See Also
Remarks
The parameter timeout is a value in milliseconds, where 1000 milliseconds equals 1 second. It only applies to the rest protocol and is used to set the timeout for rest requests. It only needs to be set once to take effect. For example: exchange.SetTimeout(3000) sets the rest request timeout for the exchange exchange object to 3 seconds. When calling functions that involve network requests such as exchange.GetTicker(), if no response is received within 3 seconds, a timeout will occur, and the function call that times out will return a null value.
SetTimeout() is not a global function, but a method of the exchange exchange object.
Threads
The FMZ Quant Trading Platform provides true multi-threading support for JavaScript language strategies at the system level, implementing the following objects:
| Object | Description | Notes |
|---|---|---|
| threading | Global multi-threading object | Member functions: Thread, getThread, mainThread, etc. |
| Thread | Thread object | Member functions: peekMessage, postMessage, join, etc. |
| ThreadLock | Thread lock object | Member functions: acquire, release. Can be passed as a parameter to thread execution functions into the thread environment. |
| ThreadEvent | Event object | Member functions: set, clear, wait, isSet. Can be passed as a parameter to thread execution functions into the thread environment. |
| ThreadCondition | Condition object | Member functions: notify, notifyAll, wait, acquire, release. Can be passed as a parameter to thread execution functions into the thread environment. |
| ThreadDict | Dictionary object | Member functions: get, set. Can be passed as a parameter to thread execution functions into the thread environment. |
threading
The threading object serves as a global multi-threading management tool, providing functions for creating concurrent threads, thread locks, condition variables, and more. This section introduces the member functions of the threading object. Only JavaScript language strategies support this object.
Thread
The Thread() function is used to create concurrent threads.
Thread(func, ...args)
Thread(...items)Examples
-
Create a concurrent thread with both a custom function and an anonymous function simultaneously.
javascriptfunction test1(a, b, c) { Log("test1:", a, b, c) } function main() { var t1 = threading.Thread(test1, 1, 2, 3) var t2 = threading.Thread(function (msg) { Log("msg:", msg) }, "Hello thread2") t1.join() t2.join() } -
Use
Thread(...items)format to create concurrent threads that execute multiple functions sequentially.javascriptfunction test1(msg) { Log("msg:", msg) test2("Hello test2") } function main() { var t1 = threading.Thread( [function(a, b, c) {Log(a, b, c)}, 1, 2, 3], [test1, "Hello test1"], [`function test2(msg) {Log("msg:", msg)}`]) t1.join() } -
Support passing functions as parameters to concurrently executing functions.
javascriptfunction testFunc1(p) { Log("testFunc1 p:", p) } function main() { threading.Thread(function(pfn) { var threadName = threading.currentThread().name() var threadId = threading.currentThread().id() pfn(`in thread threadName: ${threadName}, threadId: ${threadId}`) }, testFunc1).join() } -
Support passing function strings to dynamically import external libraries for concurrent computation.
javascriptfunction ml(input) { const net = new brain.NeuralNetwork() net.train([ { input: [0, 0], output: [0] }, { input: [0, 1], output: [1] }, { input: [1, 0], output: [1] }, { input: [1, 1], output: [0] }, ]) return net.run(input) } function main() { var ret = threading.Thread([ml, [1, 0]], [HttpQuery("https://unpkg.com/brain.js")]).join() // ret: {"id":1,"terminated":false,"elapsed":337636000,"ret":{"0":0.9339330196380615}} Log(ret) }
Returns
| Type | Description |
| The |
Arguments
| Name | Type | Required | Description |
func | function | Yes | The parameter |
arg | string / number / bool / object / array / function / any (any type supported by the platform) | No | The parameter |
item | array | Yes | The parameter |
See Also
Remarks
The thread function func passed to the Thread() function for concurrent execution runs in an isolated environment, so it cannot directly reference variables outside the thread, which will cause compilation failure when referenced. Additionally, referencing other closure functions is not supported within the thread. All APIs provided by the platform can be called inside the thread, but user-defined functions cannot be called.
When a thread completes execution and is not continuously referenced, the system will automatically reclaim thread-related resources at the underlying level, without the need to explicitly call the join() function to release resources. If there are continuous references preventing resource release, an error will be reported when the number of concurrent threads exceeds 2000: InternalError: too many routine wait, max is 2000.
Supports backtesting system and live trading environment; all concurrent thread-related functions in the backtesting system are only provided for code compatibility support and will not actually execute concurrent threads, which will not be elaborated further in this chapter.
getThread
The getThread() function is used to get a thread object based on the specified thread ID.
getThread(threadId)Examples
Get the specified thread object by threadId.
javascript
function main() {
var t1 = threading.Thread(function () {
// Thread object has method: id(), used to get the thread's Id, you can check the documentation for the corresponding Thread object section
var id = threading.currentThread().id()
var thread1 = threading.getThread(id)
Log("id:", id, ", thread1.id():", thread1.id())
Log(`id == thread1.id():`, id == thread1.id())
})
t1.join()
}Returns
| Type | Description |
| The |
Arguments
| Name | Type | Required | Description |
threadId | number | Yes | The parameter |
See Also
Remarks
Supports backtesting system and live trading environment.
If the target thread has finished executing and been released, the thread object cannot be obtained through threading.getThread(threadId).
mainThread
The mainThread() function is used to get the thread object of the main thread, which is the thread where the main() function in the strategy is located.
mainThread()Examples
-
Get the
Threadobject of the main thread and output thethreadIdof the main thread.javascriptfunction main() { Log("Main thread ID:", threading.mainThread().id()) } -
The thread object of the main thread can also be obtained in concurrent threads.
javascriptfunction test() { Log("Main thread ID output in test function:", threading.mainThread().id()) } function main() { var t1 = threading.Thread(test) t1.join() }
Returns
| Type | Description |
| The |
See Also
Remarks
Supported in backtesting system and live trading environment.
currentThread
The currentThread() function is used to get the thread object of the current thread.
currentThread()Examples
Get the Thread object of the current thread and output the threadId of the current thread.
javascript
function test() {
Log("Current thread ID:", threading.currentThread().id())
}
function main() {
var t1 = threading.Thread(test)
t1.join()
}Returns
| Type | Description |
| The |
See Also
Remarks
Supports backtesting system and live trading environment.
Lock
The Lock() function is used to create a thread lock object.
Lock()Examples
Two concurrent threads accessing shared resources.
javascript
function consumer(productionQuantity, dict, lock) {
for (var i = 0; i < productionQuantity; i++) {
lock.acquire()
var count = dict.get("count")
Log("consumer:", count)
Sleep(1000)
lock.release()
}
}
function producer(productionQuantity, dict, lock) {
for (var i = 0; i < productionQuantity; i++) {
lock.acquire()
dict.set("count", i)
Log("producer:", i)
Sleep(1000)
lock.release()
}
}
function main() {
var dict = threading.Dict()
dict.set("count", -1)
var lock = threading.Lock()
var productionQuantity = 10
var producerThread = threading.Thread(producer, productionQuantity, dict, lock)
var consumerThread = threading.Thread(consumer, productionQuantity, dict, lock)
consumerThread.join()
producerThread.join()
}Returns
| Type | Description |
| The |
See Also
Remarks
Supports backtesting system and live trading environment.
Condition
The Condition() function is used to create a condition variable object, which is used to implement synchronization and communication between threads in a multi-threaded concurrent environment. Through Condition(), a thread can enter a waiting state when specific conditions are not met, until another thread signals that the conditions have been met.
Condition()Examples
Two concurrent threads accessing shared resources.
javascript
function consumer(productionQuantity, dict, condition) {
for (var i = 0; i < productionQuantity; i++) {
condition.acquire()
while (dict.get("array").length == 0) {
condition.wait()
}
var arr = dict.get("array")
var count = arr.shift()
dict.set("array", arr)
Log("consumer:", count, ", array:", arr)
condition.release()
Sleep(1000)
}
}
function producer(productionQuantity, dict, condition) {
for (var i = 0; i < productionQuantity; i++) {
condition.acquire()
var arr = dict.get("array")
arr.push(i)
dict.set("array", arr)
Log("producer:", i, ", array:", arr)
condition.notify()
condition.release()
Sleep(1000)
}
}
function main() {
var dict = threading.Dict()
dict.set("array", [])
var condition = threading.Condition()
var productionQuantity = 10
var producerThread = threading.Thread(producer, productionQuantity, dict, condition)
var consumerThread = threading.Thread(consumer, productionQuantity, dict, condition)
consumerThread.join()
producerThread.join()
}Returns
| Type | Description |
| The |
See Also
Remarks
The backtesting system does not currently support this feature, only the interface definition is provided.
Event
The Event() function is used to create a thread event object, which is used for synchronization between threads, allowing one thread to wait for notification or signal from another thread.
Event()Examples
Two concurrent threads accessing shared resources.
javascript
function consumer(productionQuantity, dict, pEvent, cEvent) {
for (var i = 0; i < productionQuantity; i++) {
while (dict.get("array").length == 0) {
pEvent.wait()
}
if (pEvent.isSet()) {
pEvent.clear()
}
var arr = dict.get("array")
var count = arr.shift()
dict.set("array", arr)
Log("consumer:", count, ", array:", arr)
cEvent.set()
Sleep(1000)
}
}
function producer(productionQuantity, dict, pEvent, cEvent) {
for (var i = 0; i < productionQuantity; i++) {
while (dict.get("array").length != 0) {
cEvent.wait()
}
if (cEvent.isSet()) {
cEvent.clear()
}
var arr = dict.get("array")
arr.push(i)
dict.set("array", arr)
Log("producer:", i, ", array:", arr)
pEvent.set()
Sleep(1000)
}
}
function main() {
var dict = threading.Dict()
dict.set("array", [])
var pEvent = threading.Event()
var cEvent = threading.Event()
var productionQuantity = 10
var producerThread = threading.Thread(producer, productionQuantity, dict, pEvent, cEvent)
var consumerThread = threading.Thread(consumer, productionQuantity, dict, pEvent, cEvent)
consumerThread.join()
producerThread.join()
}Returns
| Type | Description |
| The |
See Also
Remarks
Supports backtesting system and live trading environment.
Dict
The Dict() function is used to create a dictionary object for passing and sharing data between concurrent threads.
Dict()Examples
-
Pass a regular object to concurrent thread execution function, test whether modifying object key values will affect object key values in other threads.
javascriptfunction threadFun1(obj) { obj["age"] = 100 while (true) { Log("threadFun1 obj:", obj) Sleep(5000) } } function threadFun2(obj) { while (true) { Log("threadFun2 obj:", obj) Sleep(5000) } } function main() { var obj = {"age": 10} var t1 = threading.Thread(threadFun1, obj) var t2 = threading.Thread(threadFun2, obj) t1.join() t2.join() } -
Pass a
ThreadDictobject created by theDict()function to concurrent thread execution function, test whether modifying object key values will affect object key values in other threads.javascriptfunction threadFun1(threadDict) { threadDict.set("age", 100) while (true) { Log(`threadFun1 threadDict.get("age"):`, threadDict.get("age")) Sleep(5000) } } function threadFun2(threadDict) { while (true) { Log(`threadFun2 threadDict.get("age"):`, threadDict.get("age")) Sleep(5000) } } function main() { var threadDict = threading.Dict() threadDict.set("age", 10) var t1 = threading.Thread(threadFun1, threadDict) var t2 = threading.Thread(threadFun2, threadDict) t1.join() t2.join() }
Returns
| Type | Description |
| The |
See Also
Remarks
When passing regular objects to concurrent thread functions, deep copy is used. Modifying key values in concurrent threads will not affect dictionaries in other threads.
Supports backtesting system and live trading environment.
pending
The pending function is used to get the number of concurrent threads currently running in the strategy program.
pending()Examples
Create two concurrently running threads and call the pending() function at different time points.
javascript
function threadFun1() {
Log("threadFun1")
Sleep(3000)
}
function threadFun2() {
for (var i = 0; i < 3; i++) {
LogStatus(_D(), "print from threadFun2")
Sleep(3000)
}
}
function main() {
Log(`begin -- threading.pending():`, threading.pending())
var t1 = threading.Thread(threadFun1)
var t2 = threading.Thread(threadFun2)
Log(`after threading.Thread -- threading.pending():`, threading.pending())
t1.join()
t2.join()
Log(`after thread.join -- threading.pending():`, threading.pending())
}Returns
| Type | Description |
number | The |
See Also
Remarks
When the strategy's main() function starts running, directly calling pending() will return 1, because the main thread where main() function is located is also counted as a running thread.
Supports both backtesting system and live trading environment.
Thread
Thread objects can be created or returned through threading.Thread(), threading.getThread(), threading.mainThread(), threading.currentThread().
peekMessage
The peekMessage() function is used to receive messages from a thread.
peekMessage()
peekMessage(timeout)Examples
Concurrent thread sends messages to the main thread.
javascript
function main() {
var t1 = threading.Thread(function() {
for (var i = 0; i < 10; i++) {
Log("thread1 postMessage():", i)
threading.mainThread().postMessage(i)
Sleep(500)
}
})
while (true) {
var msg = threading.currentThread().peekMessage()
Log("main peekMessage():", msg)
if (msg == 9) {
break
}
Sleep(1000)
}
t1.join()
}Returns
| Type | Description |
string / number / bool / object / array / any (any type supported by the platform) | The |
Arguments
| Name | Type | Required | Description |
timeout | number | No | The |
See Also
Remarks
When writing programs, be careful to avoid thread deadlock issues.
postMessage
The postMessage() function is used to send messages to a thread.
postMessage(msg)Examples
-
Send messages in concurrent threads and use
eventLoop()to receive message notifications.javascriptfunction main() { var t1 = threading.Thread(function() { for (var i = 0; i < 10; i++) { Log("thread1 postMessage():", i) threading.mainThread().postMessage(i) Sleep(500) } }) for (var i = 0; i < 10; i++) { var event = threading.mainThread().eventLoop() Log("main event:", event) Sleep(500) } t1.join() } -
Supports sending functions.
javascriptfunction main() { threading.mainThread().postMessage(function(msg) { Log("func from mainThread, msg:", msg) }) threading.Thread(function() { var func = threading.mainThread().peekMessage() func("in " + threading.currentThread().name()) }).join() }
Arguments
| Name | Type | Required | Description |
msg | string / number / bool / object / array / function / any (any type supported by the platform) | Yes | The parameter |
See Also
Remarks
When the postMessage() function is called in a thread's execution function to send signals or data, it generates a message event. You can use the eventLoop() function to receive message notifications.
join
The join() function is used to wait for a thread to exit and reclaim system resources.
join()
join(timeout)Examples
Test join() function timeout and output the return value.
javascript
function main() {
var t1 = threading.Thread(function() {
Log("Hello thread1")
Sleep(5000)
})
var ret = t1.join(1000)
Log("ret:", ret) // ret: undefined
ret = t1.join()
Log("ret:", ret) // ret: {"id":1,"terminated":false,"elapsed":5003252000}
}Returns
| Type | Description |
| The
|
Arguments
| Name | Type | Required | Description |
timeout | number | No | The |
See Also
Remarks
When the join() function times out, it returns undefined.
terminate
The terminate() function is used to forcibly terminate a thread and release the hardware resources occupied when the thread was created.
terminate()Examples
Forcibly terminate the execution of a thread. After forcibly terminating the thread, the content output by that thread will no longer be displayed in the logs.
javascript
function main() {
var t1 = threading.Thread(function() {
for (var i = 0; i < 10; i++) {
Log("thread1 i:", i)
Sleep(1000)
}
})
Sleep(3000)
t1.terminate()
Log("after t1.terminate()")
while (true) {
LogStatus(_D())
Sleep(1000)
}
}See Also
Remarks
For threads forcibly terminated using the terminate() function, the join() function can no longer be used to wait for their completion.
getData
The getData() function is used to access variables recorded in the thread environment. The data is valid when the thread has not executed the join() function (waiting for successful exit) and has not executed the terminate() function (forcibly terminating the thread).
getData()
getData(key)Examples
Record a value with the key name count in the concurrent thread environment, then read the key value of count in the main thread.
javascript
function main() {
var t1 = threading.Thread(function() {
for (var i = 0; i < 5; i++) {
threading.currentThread().setData("count", i)
Log(`setData("count"):`, i)
Sleep(1000)
}
})
for (var i = 0; i < 5; i++) {
var count = threading.getThread(t1.id()).getData("count")
Log(`getData("count"):`, count)
Sleep(1000)
}
t1.join()
}Returns
| Type | Description |
string / number / bool / object / array / any (any type supported by the platform) | The |
Arguments
| Name | Type | Required | Description |
key | string | Yes | The |
See Also
setData
The setData() function is used to store variables in the thread environment.
setData(key, value)Examples
-
Set a key-value pair in a concurrent thread and read the key-value pair in the main thread.
javascriptfunction main() { var t1 = threading.Thread(function() { threading.currentThread().setData("data", 100) }) Sleep(1000) Log(`t1.getData("data"):`, t1.getData("data")) t1.join() } -
Supports passing functions as key values.
javascriptfunction main() { threading.mainThread().setData("func2", function(p) { Log("func2 p:", p) }) var t1 = threading.Thread(function() { threading.currentThread().setData("func1", function(p) { Log("func1 p:", p) }) var func2 = threading.mainThread().getData("func2") func2("test2") }) Sleep(1000) var func1 = t1.getData("func1") func1("test1") t1.join() }
Arguments
| Name | Type | Required | Description |
key | string | Yes | The |
value | string / number / bool / object / array / function / any (any type supported by the platform) | Yes | The |
See Also
Remarks
Data remains valid as long as the thread has not executed the join() function (waiting for successful exit) and has not executed the terminate() function (forcibly terminating the thread). The value parameter must be a serializable variable.
id
The id() function is used to return the threadId of the current multi-threaded object instance.
id()Examples
Create a concurrently running thread and output the threadId of that concurrent thread in the main thread.
javascript
function main() {
var t1 = threading.Thread(function() {
threading.currentThread().setData("data", 100)
})
Log(`t1.id():`, t1.id())
t1.join()
}Returns
| Type | Description |
number | The |
See Also
name
The name() function is used to return the name of the current multi-threaded object instance.
name()Examples
Create a concurrently running thread and output the name of that concurrent thread in the main thread.
javascript
function main() {
var t1 = threading.Thread(function() {
threading.currentThread().setData("data", 100)
})
Log(`t1.name():`, t1.name()) // t1.name(): Thread-1
t1.join()
}Returns
| Type | Description |
string | The |
See Also
eventLoop
The eventLoop() function is used to listen for events received by the thread.
eventLoop()
eventLoop(timeout)Examples
Execute 3 threads concurrently and output the received event information. When timeout occurs or immediate return, the output value is null.
javascript
function main() {
var t1 = threading.Thread(function() {
while (true) {
var eventMsg = threading.currentThread().eventLoop() // 阻塞等待
// 2024-11-14 10:14:18 thread1 eventMsg: {"Seq":1,"Event":"thread","ThreadId":0,"Index":1,"Queue":0,"Nano":1731550458699947000}
Log(_D(), "thread1 eventMsg:", eventMsg)
}
})
var t2 = threading.Thread(function() {
while (true) {
var eventMsg = threading.currentThread().eventLoop(-1) // 立即返回
Log(_D(), "thread2 eventMsg:", eventMsg)
Sleep(5000)
}
})
var t3 = threading.Thread(function() {
while (true) {
var eventMsg = threading.currentThread().eventLoop(3000) // 设置3秒超时
Log(_D(), "thread3 eventMsg:", eventMsg)
}
})
t1.postMessage("Hello ", t1.name())
t2.postMessage("Hello ", t2.name())
t3.postMessage("Hello ", t3.name())
t1.join()
t2.join()
t3.join()
}Returns
| Type | Description |
object / null | The |
Arguments
| Name | Type | Required | Description |
timeout | number | No | The parameter |
See Also
Remarks
The processing mechanism of the eventLoop() function is consistent with the global function EventLoop().
ThreadLock
Thread lock object for multi-threaded synchronization processing.
acquire
The acquire() function is used to request a thread lock (acquire lock).
acquire()Examples
Please refer to the threading.Lock() section for examples.
See Also
Remarks
The acquire() function is used to request a thread lock. When a thread calls the acquire() function of a thread lock object, it attempts to acquire the lock. If the lock is not currently held by another thread, the calling thread will successfully acquire the lock and continue execution. If the lock is already held by another thread, the thread calling acquire() will be blocked until the lock is released.
release
The release() function is used to release a thread lock (unlock).
release()Examples
Test deadlock scenario
javascript
function consumer(productionQuantity, dict, pLock, cLock) {
for (var i = 0; i < productionQuantity; i++) {
pLock.acquire()
cLock.acquire()
var arr = dict.get("array")
var count = arr.shift()
dict.set("array", arr)
Log("consumer:", count, ", array:", arr)
cLock.release()
Sleep(1000)
pLock.release()
}
}
function producer(productionQuantity, dict, pLock, cLock) {
for (var i = 0; i < productionQuantity; i++) {
cLock.acquire() // cLock.acquire() 放在 pLock.acquire() 后不会产生死锁
pLock.acquire()
var arr = dict.get("array")
arr.push(i)
dict.set("array", arr)
Log("producer:", i, ", array:", arr)
pLock.release()
Sleep(1000)
cLock.release()
}
}
function main() {
var dict = threading.Dict()
dict.set("array", [])
var pLock = threading.Lock()
var cLock = threading.Lock()
var productionQuantity = 10
var producerThread = threading.Thread(producer, productionQuantity, dict, pLock, cLock)
var consumerThread = threading.Thread(consumer, productionQuantity, dict, pLock, cLock)
consumerThread.join()
producerThread.join()
}See Also
Remarks
Note that improper use of thread locks may cause deadlocks.
ThreadEvent
Event object for event notification and signal passing between multiple threads.
set
The set() function is used to set an event signal.
set()Examples
Please refer to the examples in the threading.Event() section.
See Also
Remarks
If the event has already been set via set(), it cannot be set again. You need to call the clear operation first before resetting the signal.
clear
The clear() function is used to clear the signal.
clear()Examples
Please refer to the example in the threading.Event() section.
See Also
wait
The wait() function is used to set event (signal) waiting, which will block until the event (signal) is set; supports setting timeout parameters.
wait()
wait(timeout)Examples
Test the return value of the wait() function.
javascript
function main() {
var event = threading.Event()
var t1 = threading.Thread(function(event) {
var ret = event.wait(100)
Log(`event.wait(100):`, ret)
ret = event.wait()
Log(`event.wait():`, ret)
}, event)
Sleep(1000)
event.set()
t1.join()
}Returns
| Type | Description |
bool | The |
Arguments
| Name | Type | Required | Description |
timeout | number | No | The parameter |
See Also
isSet
The isSet() function is used to determine whether an event (signal) has been set.
isSet()Examples
Please refer to the examples in the threading.Event() section.
Returns
| Type | Description |
bool | The |
See Also
ThreadCondition
Condition variable object used for implementing synchronization and communication between multiple threads.
notify
The notify() function is used to wake up one waiting thread (if any exists). Only threads that have called the wait() method can be awakened.
notify()Examples
Use the notify() function to wake up waiting threads.
javascript
function consumer(dict, condition) {
while (true) {
condition.acquire()
while (dict.get("array").length == 0) {
Log(threading.currentThread().name(), "wait()...", ", array:", dict.get("array"))
condition.wait()
}
var arr = dict.get("array")
var num = arr.shift()
Log(threading.currentThread().name(), ", num:", num, ", array:", arr, "#FF0000")
dict.set("array", arr)
Sleep(1000)
condition.release()
}
}
function main() {
var condition = threading.Condition()
var dict = threading.Dict()
dict.set("array", [])
var t1 = threading.Thread(consumer, dict, condition)
var t2 = threading.Thread(consumer, dict, condition)
var t3 = threading.Thread(consumer, dict, condition)
Sleep(1000)
var i = 0
while (true) {
condition.acquire()
var msg = ""
var arr = dict.get("array")
var randomNum = Math.floor(Math.random() * 5) + 1
if (arr.length >= 3) {
condition.notifyAll()
msg = "notifyAll"
} else {
arr.push(i)
dict.set("array", arr)
if (randomNum > 3 && arr.length > 0) {
condition.notify()
msg = "notify"
} else {
msg = "pass"
}
i++
}
Log(_D(), "randomNum:", randomNum, ", array:", arr, ", msg:", msg)
condition.release()
Sleep(1000)
}
}See Also
Remarks
The notify() function wakes up one thread in the waiting queue.
When the notify() function wakes up a thread, that thread will reacquire the thread lock.
notifyAll
The notifyAll() function is used to wake up all waiting threads.
notifyAll()Examples
For examples, please refer to the ThreadCondition.notify() section.
See Also
Remarks
The notifyAll() function wakes up all threads in the waiting state one by one, and the awakened threads will reacquire the thread lock.
wait
The wait() function is used to put a thread into a waiting state under specific conditions.
wait()Examples
For examples, please refer to the content in the ThreadCondition.notify() section.
See Also
Remarks
The wait() function releases the thread lock and will reacquire the thread lock when the thread is awakened.
acquire
The acquire() function is used to request a thread lock (acquire lock).
acquire()Examples
For examples, please refer to the content in the ThreadCondition.notify() section.
See Also
Remarks
The thread lock of the current condition object must be requested (acquired) before calling wait().
ThreadDict
Thread-safe dictionary object for data sharing in multi-threaded environments.
get
The get() function is used to retrieve the value of a key recorded in a dictionary object.
get(key)Examples
Use event objects to notify threads to read and modify data.
javascript
function main() {
var event = threading.Event()
var dict = threading.Dict()
dict.set("data", 100)
var t1 = threading.Thread(function(dict, event) {
Log(`thread1, dict.get("data"):`, dict.get("data"))
event.set()
event.clear()
event.wait()
Log(`after main change data, thread1 dict.get("data"):`, dict.get("data"))
dict.set("data", 0)
}, dict, event)
event.wait()
dict.set("data", 99)
event.set()
event.clear()
t1.join()
Log(`main thread, dict.get("data"):`, dict.get("data"))
}Returns
| Type | Description |
string / number / bool / object / array / any (any type supported by the platform) | The |
Arguments
| Name | Type | Required | Description |
key | string | Yes | The |
See Also
set
The set() function is used to set key-value pairs.
set(key, value)Examples
Supports passing functions as key values.
javascript
function main() {
var dict1 = threading.Dict()
dict1.set("func1", function(p) {
Log("func1 p:", p)
})
threading.Thread(function(dict1) {
var func1 = dict1.get("func1")
func1("test")
}, dict1).join()
}Arguments
| Name | Type | Required | Description |
key | string | Yes | The |
value | string / number / bool / object / array / function / any (any type supported by the platform) | Yes | The |
See Also
Web3
exchange.IO("abi", ...)
In the FMZ Quant Trading Platform, various blockchain-related functions are mainly implemented through the exchange.IO() function. The following documentation will describe the different functions of the exchange.IO() function separately. The exchange.IO("abi", ...) function call is used to register ABI.
-
Supports Ethereum (eth)
-
Supports TRON (tron)
exchange.IO(k, address, abiContent)Examples
javascript
function main() {
// register Uniswap SwapRouter02 abi
var routerAddress = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"
var abi = `[{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"internalType":"struct IV3SwapRouter.ExactOutputParams","name":"params","type":"tuple"}],"name":"exactOutput","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"}]`
// abi only uses partial exactOutput method content, complete abi can be searched online
exchange.IO("abi", routerAddress, abi)
}Arguments
| Name | Type | Required | Description |
k | string | Yes | The |
address | string | Yes | The |
abiContent | string | Yes | The |
Remarks
If the called smart contract method is a standard ERC20 method, registration is not required.
To obtain the contract's ABI content, you can use the following URL, just take the result field, for example:
url
https://api.etherscan.io/api?module=contract&action=getabi&address=0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45
exchange.IO("api", blockChain, ...)
The exchange.IO("api", "eth", ...) function call is used to invoke Ethereum RPC methods (requires selecting eth when configuring the Web3 exchange object).
exchange.IO("api", "tron", ...) function call is used to invoke TRON RPC methods (requires selecting tron when configuring the Web3 exchange object).
exchange.IO(k, blockChain, rpcMethod)
exchange.IO(k, blockChain, rpcMethod, ...args)Examples
-
Query ETH balance in wallet:
javascriptfunction main() { // "owner" needs to be replaced with the actual wallet address // Parameter label at "latest" string position: 'latest', 'earliest' or 'pending', refer to https://eth.wiki/json-rpc/API#the-default-block-parameter // Return value ethBalance is a hexadecimal string: 0x9b19ce56113070 var ethBalance = exchange.IO("api", "eth", "eth_getBalance", "owner", "latest") // ETH precision unit is 1e18 var ethDecimal = 18 // Due to JavaScript language precision limitations, need to use system-level encapsulated functions BigInt, BigDecimal for processing // Convert ethBalance to readable amount, 0x9b19ce56113070 converts to 0.043656995388076145 Log(Number((BigDecimal(BigInt(ethBalance))/BigDecimal(Math.pow(10, ethDecimal))).toString())) } -
ETH transfer, you can set
{gasPrice: 11, gasLimit: 111, nonce: 111}parameters according to specific requirements, this parameter is set as the last parameter of theexchange.IO()function. You can omitnonceto use system default value, or not setgasLimit/gasPrice/nonceto use all system default values.javascriptfunction mian() { // ETH precision unit is 1e18 var ethDecimal = 18 // Transfer amount, readable amount for example: 0.01 ETH var sendAmount = 0.01 // Due to JavaScript language precision limitations, need to use system-level encapsulated functions BigInt, BigDecimal for processing, and convert readable amount to on-chain processing data var toAmount = (BigDecimal(sendAmount)*BigDecimal(Math.pow(10, ethDecimal))).toFixed(0) // "toAddress" is the recipient's ETH wallet address for the transfer, needs to be specifically filled in, toAmount is the transfer amount exchange.IO("api", "eth", "send", "toAddress", toAmount) } -
Query
gasPrice:javascriptfunction toAmount(s, decimals) { return Number((BigDecimal(BigInt(s))/BigDecimal(Math.pow(10, decimals))).toString()) } function main() { var gasPrice = exchange.IO("api", "eth", "eth_gasPrice") Log("gasPrice:", toAmount(gasPrice, 0)) // 5000000000 , in wei (5 gwei) } -
Query
eth_estimateGas:javascriptfunction toAmount(s, decimals) { // toAmount函数可以将十六进制编码的数值转换为十进制数值 return Number((BigDecimal(BigInt(s))/BigDecimal(Math.pow(10, decimals))).toString()) } function main() { // 编码approve(授权)方法的调用 var data = exchange.IO("encode", "0x111111111117dC0aa78b770fA6A738034120C302", "approve", "0xe592427a0aece92de3edee1f18e0157c05861564", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") Log("data:", data) var gasPrice = exchange.IO("api", "eth", "eth_gasPrice") Log("gasPrice:", toAmount(gasPrice, 0)) var obj = { "from" : "0x0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // walletAddress "to" : "0x111111111117dC0aa78b770fA6A738034120C302", "gasPrice" : gasPrice, "value" : "0x0", "data" : "0x" + data, } var gasLimit = exchange.IO("api", "eth", "eth_estimateGas", obj) Log("gasLimit:", toAmount(gasLimit, 0)) Log("gas fee", toAmount(gasLimit, 0) * toAmount(gasPrice, 0) / 1e18) }
Returns
| Type | Description |
string / number / bool / object / array / any (any type supported by the platform) | The |
Arguments
| Name | Type | Required | Description |
k | string | Yes | The |
blockChain | string | Yes | The |
rpcMethod | string | Yes | The |
arg | string / number / bool / object / array / function / any (any type supported by the platform) | No | The There may be multiple |
See Also
Remarks
When the second parameter of the exchange.IO() function is "eth", you can directly call RPC methods available on Ethereum node servers.
exchange.IO("encode", ...)
The exchange.IO("encode", ...) function is used for data encoding operations.
exchange.IO(k, dataFormat, ...args)
exchange.IO(k, address, dataFormat)
exchange.IO(k, address, dataFormat, ...args)Examples
-
Taking the encoding of
unwrapWETH9method call as an example:javascriptfunction main() { // ContractV3SwapRouterV2 主网地址 : 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45 // 调用unwrapWETH9方法需要先注册ABI,此处省略注册 // "owner"代表钱包地址,需要具体填写,1代表解包装数量,把一个WETH解包装为ETH var data = exchange.IO("encode", "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", "unwrapWETH9(uint256,address)", 1, "owner") Log(data) } -
Encoding example equivalent to
abi.encodeinSolidity:javascriptfunction main() { var x = 10 var address = "0x02a5fBb259d20A3Ad2Fdf9CCADeF86F6C1c1Ccc9" var str = "Hello World" var array = [1, 2, 3] var ret = exchange.IO("encode", "uint256,address,string,uint256[]", x, address, str, array) // uint 即 uint256 , FMZ上需要指定类型长度 Log("ret:", ret) /* 000000000000000000000000000000000000000000000000000000000000000a // x 00000000000000000000000002a5fbb259d20a3ad2fdf9ccadef86f6c1c1ccc9 // address 0000000000000000000000000000000000000000000000000000000000000080 // str 的偏移 00000000000000000000000000000000000000000000000000000000000000c0 // array 的偏移 000000000000000000000000000000000000000000000000000000000000000b // str 的长度 48656c6c6f20576f726c64000000000000000000000000000000000000000000 // str 数据 0000000000000000000000000000000000000000000000000000000000000003 // array 的长度 0000000000000000000000000000000000000000000000000000000000000001 // array 第一个数据 0000000000000000000000000000000000000000000000000000000000000002 // array 第二个数据 0000000000000000000000000000000000000000000000000000000000000003 // array 第三个数据 */ } -
Supports encoding of tuples or type sequences containing tuples. This type sequence consists of
tupleandbytes, so when callingexchange.IO()for encoding, two corresponding parameters need to be passed:-
- Variable corresponding to tuple type:
The passed parameters must be consistent with the structure and types of thejavascript{ a: 30, b: 20, c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" }tuple, as defined in thetypesparameter:tuple(a uint256,b uint8,c address). -
- Variable corresponding to
bytestype:
javascript"0011" - Variable corresponding to
javascriptfunction main() { var types = "tuple(a uint256,b uint8,c address),bytes" var ret = exchange.IO("encode", types, { a: 30, b: 20, c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" }, "0011") Log("encode: ", ret) } -
-
Supports encoding of arrays or type sequences containing arrays:
javascriptfunction main() { var path = ["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "0xdac17f958d2ee523a2206206994597c13d831ec7"] // ETH address, USDT address var ret = exchange.IO("encode", "address[]", path) Log("encode: ", ret) }
Returns
| Type | Description |
string | The |
Arguments
| Name | Type | Required | Description |
k | string | Yes | The |
address | string | No | The |
dataFormat | string | Yes | The |
arg | string / number / tuple / array / any (any type supported by the platform) | No | The There may be multiple |
Remarks
The exchange.IO() function encapsulates the encode method, which can encode function calls and return them as hex string format. For specific usage, please refer to the platform's public "Uniswap V3 Trading Library" template.
When encoding smart contract method calls, the corresponding ABI must be registered first.
exchange.IO("encodePacked", ...)
The exchange.IO("encodePacked", ...) function is used to perform encodePacked encoding operations.
exchange.IO(k, dataFormat, ...args)Examples
When using Uniswap V3, parameters such as trading path need to be passed in, which requires the use of encodePacked encoding operations:
javascript
function main() {
var fee = exchange.IO("encodePacked", "uint24", 3000)
var tokenInAddress = "0x111111111117dC0aa78b770fA6A738034120C302"
var tokenOutAddress = "0x6b175474e89094c44da98b954eedeac495271d0f"
var path = tokenInAddress.slice(2).toLowerCase()
path += fee + tokenOutAddress.slice(2).toLowerCase()
Log("path:", path)
}Returns
| Type | Description |
string | The |
Arguments
| Name | Type | Required | Description |
k | string | Yes | The |
dataFormat | string | Yes | The |
arg | string / number / tuple / array / any (any type supported by the platform) | Yes | The There can be multiple |
exchange.IO("decode", ...)
The exchange.IO("decode", ...) function is used for data decoding operations.
exchange.IO(k, dataFormat, data)Examples
-
Example of reverse operation for
exchange.IO("encode", ...)function:javascriptfunction main() { var types = "tuple(a uint256,b uint8,c address),bytes" var ret = exchange.IO("encode", types, { a: 30, b: 20, c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" }, "0011") Log("encode: ", ret) var rawData = exchange.IO("decode", types, ret) Log("decode:", rawData) } -
The following example first performs an
encodePackedoperation on thepathparameter, as the subsequentexactOutputmethod call that needs to be encoded requirespathas a parameter. Then it encodes theexactOutputmethod of the router contract, which has only one parameter oftupletype. The encoded result of theexactOutputmethod name is:0x09b81346. Using theexchange.IO("decode", ...)method to decode yieldsdecodeRaw, whose result is consistent with the variabledataTuple.javascriptfunction main() { // register SwapRouter02 abi var walletAddress = "0x398a93ca23CBdd2642a07445bCD2b8435e0a373f" var routerAddress = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45" var abi = `[{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"internalType":"struct IV3SwapRouter.ExactOutputParams","name":"params","type":"tuple"}],"name":"exactOutput","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"}]` exchange.IO("abi", routerAddress, abi) // abi只使用了局部的exactOutput方法的内容,完整的abi可以在网上搜索 // encode path var fee = exchange.IO("encodePacked", "uint24", 3000) var tokenInAddress = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" var tokenOutAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7" var path = tokenInAddress.slice(2).toLowerCase() path += fee + tokenOutAddress.slice(2).toLowerCase() Log("path:", path) var dataTuple = { "path" : path, "recipient" : walletAddress, "amountOut" : 1000, "amountInMaximum" : 1, } // encode SwapRouter02 exactOutput var rawData = exchange.IO("encode", routerAddress, "exactOutput", dataTuple) Log("method hash:", rawData.slice(0, 8)) // 09b81346 Log("params hash:", rawData.slice(8)) // decode exactOutput params var decodeRaw = exchange.IO("decode", "tuple(path bytes,recipient address,amountOut uint256,amountInMaximum uint256)", rawData.slice(8)) Log("decodeRaw:", decodeRaw) }
Returns
| Type | Description |
array / string | The |
Arguments
| Name | Type | Required | Description |
k | string | Yes | The |
dataFormat | string | Yes | The |
data | string | Yes | The |
Remarks
The exchange.IO() function supports bidirectional data processing, capable of both encoding (encode) and decoding (decode) operations.
exchange.IO("key", ...)
The exchange.IO("key", ...) function is used to switch the private key calling method.
exchange.IO(k, key)Examples
javascript
function main() {
exchange.IO("key", "Private Key") // "Private Key" represents the private key string, which needs to be filled in specifically
}Arguments
| Name | Type | Required | Description |
k | string | Yes | The |
key | string | Yes | The |
Remarks
The exchange.IO() function supports private key switching functionality, allowing operations on multiple wallet addresses. You can also add multiple exchange objects (refer to: exchanges) to operate multiple wallet addresses.
For private key switching operations: exchange.IO("key", "xxx"), concurrent switching is not supported.
exchange.IO("api", ...)
The exchange.IO("api", ...) function is used to call smart contract methods.
exchange.IO(k, address, method)
exchange.IO(k, address, method, ...args)
exchange.IO(k, address, method, value, ...args)Examples
-
The
decimalsmethod is aconstantmethod of ERC20 that does not consume gas and can query the precision data of a token.The
decimalsmethod requires no parameters. Return value: the precision data of the token.javascriptfunction main(){ var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302" // 代币的合约地址,例子中的代币为1INCH Log(exchange.IO("api", tokenAddress, "decimals")) // 查询,打印1INCH代币的精度指数为18 } -
The
allowancemethod is aconstantmethod of ERC20 that does not consume gas and can query the authorized amount of a token for a specific contract address.The
allowancemethod requires 2 parameters: the first parameter is the wallet address, and the second parameter is the authorized address. Return value: the authorized amount of the token.owner: wallet address, represented by the string "owner" in the example, actual use requires filling in the specific address.spender: the authorized contract address, represented by the string "spender" in the example, actual use requires filling in the specific address, for example, it can be theUniswap V3 router v1address.javascriptfunction main(){ // 代币的合约地址,例子中的代币为1INCH var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302" // 例如查询得出1000000000000000000,除以该token的精度单位1e18,得出当前交易所对象绑定的钱包给spender地址授权了1个1INCH数量 Log(exchange.IO("api", tokenAddress, "allowance", "owner", "spender")) } -
The
approvemethod is a non-constantmethod of ERC20 that consumes gas and is used to authorize a contract address with an operational amount of tokens.The
approvemethod requires 2 parameters: the first parameter is the authorized address, and the second parameter is the authorized amount. Return value: txid.spender: the authorized contract address, represented by the string "spender" in the example, actual use requires filling in the specific address, for example, it can be theUniswap V3 router v1address.0xde0b6b3a7640000: the authorized amount, represented here as a hexadecimal string, corresponding to the decimal value of 1e18, divided by the token precision unit in the example (i.e., 1e18), resulting in authorization of 1 token.The third parameter of the
exchange.IO()function passes the method nameapprove, which can also be written in methodId form, for example: "0x571ac8b0". It can also be written as the complete standard method name, for example: "approve(address,uint256)".javascriptfunction main(){ // 代币的合约地址,例子中的代币为1INCH var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302" // 授权量的十六进制字符串: 0xde0b6b3a7640000 , 对应的十进制字符串: 1e18 , 1e18除以该token的精度单位,即1个代币数量 , 所以这里指授权一个代币 Log(exchange.IO("api", tokenAddress, "approve", "spender", "0xde0b6b3a7640000")) } -
The
multicallmethod is a non-constantmethod ofUniswap V3that consumes gas and is used for multi-path token swaps.The
multicallmethod may have multiple parameter passing methods. You can query the ABI containing this method for details. The ABI needs to be registered before calling this method. Return value: txid.For specific
multicallmethod call examples, you can refer to the platform's public "Uniswap V3 Trading Library" templateHere we use pseudocode to describe some details:
javascriptexchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", value, deadline, data)ContractV3SwapRouterV2: The router v2 address of Uniswap V3.value: The amount of ETH to transfer. If the tokenIn token for the swap operation is not ETH, set it to 0.deadline:deadlineis a parameter of themulticallmethod, which can be set to (new Date().getTime() / 1000) + 3600, indicating validity within one hour.data:datais a parameter of themulticallmethod, the packed operation data to be executed. Similar toexchange.IO("api", "eth", "send", "toAddress", toAmount), when calling themulticallmethod, you can also specify thegasLimit/gasPrice/noncesettings for the method call, also described using pseudocode:javascriptexchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", value, deadline, data, {gasPrice: 123456, gasLimit: 21000})You can set the
{gasPrice: 11, gasLimit: 111, nonce: 111}parameters according to specific requirements. This parameter is set as the last parameter of theexchange.IO()function.You can omit
nonceto use the system default value, or not setgasLimit/gasPrice/nonceto use all system default values.javascriptfunction main() { var ContractV3SwapRouterV2 = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45" var tokenInName = "ETH" var amountIn = 0.01 var options = {gasPrice: 5000000000, gasLimit: 21000, nonce: 100} // 此处为举例,具体要根据实际场景设置 var data = "" // 编码后的数据,此处为空字符串,具体要根据实际场景设置 var tx = exchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", (tokenInName == 'ETH' ? amountIn : 0), (new Date().getTime() / 1000) + 3600, data, options || {}) }
Returns
| Type | Description |
string / number / bool / object / array / any (any type supported by the platform) | The |
Arguments
| Name | Type | Required | Description |
k | string | Yes | The |
address | string | Yes | The |
method | string | Yes | The |
value | number / string | No | The |
arg | string / number / bool / any (any type supported by the platform) | No | The There may be multiple |
exchange.IO("address")
The exchange.IO("address") function is used to get the wallet address configured for the exchange exchange object.
exchange.IO(k)Examples
javascript
function main() {
Log(exchange.IO("address")) // 打印exchange交易所对象上配置的私钥对应的钱包地址
}Returns
| Type | Description |
string | The |
Arguments
| Name | Type | Required | Description |
k | string | Yes | The |
exchange.IO("base", ...)
The exchange.IO("base", ...) function call is used to set the RPC node address.
exchange.IO(k, address)Examples
javascript
function main() {
var chainRpc = "https://bsc-dataseed.binance.org"
e.IO("base", chainRpc) // 切换到BSC链
}Arguments
| Name | Type | Required | Description |
k | string | Yes | The |
address | string | Yes | The |
TA
TA.MACD
The TA.MACD() function is used to calculate the Moving Average Convergence Divergence indicator.
TA.MACD(inReal)
TA.MACD(inReal, optInFastPeriod, optInSlowPeriod, optInSignalPeriod)Examples
javascript
function main(){
// 可以填入不同k线周期,比如PERIOD_M1,PERIOD_M30,PERIOD_H1......
var records = exchange.GetRecords(PERIOD_M15)
var macd = TA.MACD(records, 12, 26, 9)
// 观看日志可得知返回三个数组,分别对应DIF,DEA,MACD
Log("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2])
}
python
def main():
r = exchange.GetRecords(PERIOD_M15)
macd = TA.MACD(r, 12, 26, 9)
Log("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2])
c++
void main() {
auto r = exchange.GetRecords(PERIOD_M15);
auto macd = TA.MACD(r, 12, 26, 9);
Log("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2]);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInFastPeriod | number | No | The |
optInSlowPeriod | number | No | The |
optInSignalPeriod | number | No | The |
See Also
Remarks
FMZ Quant's TA indicator library optimizes common technical indicator algorithms. It supports strategy calls in JavaScript, Python, and C++ languages, open source TA library code.
The default values for the optInFastPeriod, optInSlowPeriod, and optInSignalPeriod parameters of the TA.MACD() function are: 12, 26, and 9 respectively.
TA.KDJ
The TA.KDJ() function is used to calculate the Stochastic Oscillator.
TA.KDJ(inReal)
TA.KDJ(inReal, period, kPeriod, dPeriod)Examples
javascript
function main(){
var records = exchange.GetRecords(PERIOD_M15)
var kdj = TA.KDJ(records, 9, 3, 3)
Log("k:", kdj[0], "d:", kdj[1], "j:", kdj[2])
}
python
def main():
r = exchange.GetRecords(PERIOD_M15)
kdj = TA.KDJ(r, 9, 3, 3)
Log("k:", kdj[0], "d:", kdj[1], "j:", kdj[2])
c++
void main() {
auto r = exchange.GetRecords();
auto kdj = TA.KDJ(r, 9, 3, 3);
Log("k:", kdj[0], "d:", kdj[1], "j:", kdj[2]);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
period | number | No | The |
kPeriod | number | No | The |
dPeriod | number | No | The |
See Also
Remarks
The default values for the period, kPeriod, and dPeriod parameters of the TA.KDJ() function are: 9, 3, and 3 respectively.
TA.RSI
The TA.RSI() function is used to calculate the Relative Strength Index.
TA.RSI(inReal)
TA.RSI(inReal, optInTimePeriod)Examples
javascript
function main(){
var records = exchange.GetRecords(PERIOD_M30)
var rsi = TA.RSI(records, 14)
Log(rsi)
}
python
def main():
r = exchange.GetRecords(PERIOD_M30)
rsi = TA.RSI(r, 14)
Log(rsi)
c++
void main() {
auto r = exchange.GetRecords(PERIOD_M30);
auto rsi = TA.RSI(r, 14);
Log(rsi);
}Returns
| Type | Description |
array | The return value of the |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
See Also
Remarks
The default value of the optInTimePeriod parameter for the TA.RSI() function is: 14.
TA.ATR
The TA.ATR() function is used to calculate the Average True Range indicator.
TA.ATR(inPriceHLC)
TA.ATR(inPriceHLC, optInTimePeriod)Examples
javascript
function main(){
var records = exchange.GetRecords(PERIOD_M30)
var atr = TA.ATR(records, 14)
Log(atr)
}
python
def main():
r = exchange.GetRecords(PERIOD_M30)
atr = TA.ATR(r, 14)
Log(atr)
c++
void main() {
auto r = exchange.GetRecords(PERIOD_M30);
auto atr = TA.ATR(r, 14);
Log(atr);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInTimePeriod | number | No | The |
See Also
Remarks
The default value of the optInTimePeriod parameter for the TA.ATR() function is: 14.
TA.OBV
The TA.OBV() function is used to calculate the On-Balance Volume indicator.
TA.OBV(inReal)
TA.OBV(inReal, inPriceV)Examples
javascript
function main(){
var records = exchange.GetRecords(PERIOD_M30)
var obv = TA.OBV(records)
Log(obv)
}
python
def main():
r = exchange.GetRecords(PERIOD_M30)
obv = TA.OBV(r)
Log(obv)
c++
void main() {
auto r = exchange.GetRecords(PERIOD_M30);
auto obv = TA.OBV(r);
Log(obv);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
inPriceV |
| No | The |
See Also
TA.MA
The TA.MA() function is used to calculate the Moving Average indicator.
TA.MA(inReal)
TA.MA(inReal, optInTimePeriod)Examples
javascript
function main(){
var records = exchange.GetRecords(PERIOD_M30)
var ma = TA.MA(records, 14)
Log(ma)
}
python
def main():
r = exchange.GetRecords(PERIOD_M30)
ma = TA.MA(r, 14)
Log(ma)
c++
void main() {
auto r = exchange.GetRecords(PERIOD_M30);
auto ma = TA.MA(r, 14);
Log(ma);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
See Also
Remarks
The default value of the optInTimePeriod parameter for the TA.MA() function is: 9.
TA.EMA
The TA.EMA() function is used to calculate the Exponential Moving Average indicator.
TA.EMA(inReal)
TA.EMA(inReal, optInTimePeriod)Examples
javascript
function main(){
var records = exchange.GetRecords()
// 判断K线bar数量是否满足指标计算周期
if (records && records.length > 9) {
var ema = TA.EMA(records, 9)
Log(ema)
}
}
python
def main():
r = exchange.GetRecords()
if r and len(r) > 9:
ema = TA.EMA(r, 9)
Log(ema)
c++
void main() {
auto r = exchange.GetRecords();
if(r.Valid && r.size() > 9) {
auto ema = TA.EMA(r, 9);
Log(ema);
}
}Returns
| Type | Description |
array | The return value of the |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
See Also
Remarks
The default value of the optInTimePeriod parameter for the TA.EMA() function is: 9.
TA.BOLL
The TA.BOLL() function is used to calculate the Bollinger Bands indicator.
TA.BOLL(inReal)
TA.BOLL(inReal, period, multiplier)Examples
javascript
function main() {
var records = exchange.GetRecords()
if(records && records.length > 20) {
var boll = TA.BOLL(records, 20, 2)
var upLine = boll[0]
var midLine = boll[1]
var downLine = boll[2]
Log(upLine)
Log(midLine)
Log(downLine)
}
}
python
def main():
r = exchange.GetRecords()
if r and len(r) > 20:
boll = TA.BOLL(r, 20, 2)
upLine = boll[0]
midLine = boll[1]
downLine = boll[2]
Log(upLine)
Log(midLine)
Log(downLine)
c++
void main() {
auto r = exchange.GetRecords();
if(r.Valid && r.size() > 20) {
auto boll = TA.BOLL(r, 20, 2);
auto upLine = boll[0];
auto midLine = boll[1];
auto downLine = boll[2];
Log(upLine);
Log(midLine);
Log(downLine);
}
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
period | number | No | The |
multiplier | number | No | The |
See Also
Remarks
The default values for the period and multiplier parameters of the TA.BOLL() function are: 20 and 2 respectively.
TA.Alligator
The TA.Alligator() function is used to calculate the Alligator Indicator.
TA.Alligator(inReal)
TA.Alligator(inReal, jawLength, teethLength, lipsLength)Examples
javascript
function main(){
var records = exchange.GetRecords()
var alligator = TA.Alligator(records)
Log("jawLine:", alligator[0])
Log("teethLine:", alligator[1])
Log("lipsLine:", alligator[2])
}
python
def main():
records = exchange.GetRecords()
alligator = TA.Alligator(records)
Log("jawLine:", alligator[0])
Log("teethLine:", alligator[1])
Log("lipsLine:", alligator[2])
c++
void main() {
auto records = exchange.GetRecords();
auto alligator = TA.Alligator(records);
Log("jawLine:", alligator[0]);
Log("teethLine:", alligator[1]);
Log("lipsLine:", alligator[2]);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
jawLength | number | No | The |
teethLength | number | No | The |
lipsLength | number | No | The |
See Also
Remarks
The default values for the jawLength, teethLength, and lipsLength parameters of the TA.Alligator() function are: 13, 8, and 5 respectively.
TA.CMF
The TA.CMF() function is used to calculate the Chaikin Money Flow indicator.
TA.CMF(inReal)
TA.CMF(inReal, inPriceV)Examples
javascript
function main() {
var records = exchange.GetRecords()
var cmf = TA.CMF(records)
Log(cmf)
}
python
def main():
records = exchange.GetRecords()
cmf = TA.CMF(records)
Log(cmf)
c++
void main() {
auto records = exchange.GetRecords();
auto cmf = TA.CMF(records);
Log(cmf);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
inPriceV |
| No | The |
See Also
TA.Highest
The TA.Highest() function is used to calculate the highest price within a specified period.
TA.Highest(inReal)
TA.Highest(inReal, period, attr)Examples
javascript
function main() {
var records = exchange.GetRecords()
var highestForOpen = TA.Highest(records, 10, "Open")
Log(highestForOpen)
}
python
def main():
records = exchange.GetRecords()
highestForOpen = TA.Highest(records, 10, "Open")
Log(highestForOpen)
c++
void main() {
auto records = exchange.GetRecords();
auto highestForOpen = TA.Highest(records.Open(), 10);
Log(highestForOpen);
}Returns
| Type | Description |
number | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
period | number | No | The |
attr | string | No | The |
See Also
Remarks
For example, when calling TA.Highest(records, 30, "High") function: If the period parameter period is set to 0, it calculates the highest value of all Bars in the K-line data passed by the inReal parameter; If the attribute parameter attr is not specified, the data passed by the inReal parameter is treated as a regular numeric array.
TA.Lowest
The TA.Lowest() function is used to calculate the period lowest price.
TA.Lowest(inReal)
TA.Lowest(inReal, period, attr)Examples
javascript
function main() {
var records = exchange.GetRecords()
var lowestForOpen = TA.Lowest(records, 10, "Open")
Log(lowestForOpen)
}
python
def main():
records = exchange.GetRecords()
lowestForOpen = TA.Lowest(records, 10, "Open")
Log(lowestForOpen)
c++
void main() {
auto records = exchange.GetRecords();
auto lowestForOpen = TA.Lowest(records.Open(), 10);
Log(lowestForOpen);
}Returns
| Type | Description |
number | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
period | number | No | The |
attr | string | No | The |
See Also
Remarks
For example, when calling TA.Lowest(records, 30, "Low") function, if the period parameter period is set to 0, it calculates all Bars of the K-line data passed in the inReal parameter; if the attribute parameter attr is not specified, the K-line data passed in the inReal parameter is treated as a regular array.
When using TA.Highest() and TA.Lowest() functions in C++ strategies, note that Highest() and Lowest() functions each have only 2 parameters, and the first parameter is not the K-line data r obtained by calling auto r = exchange.GetRecords() function. You need to call the method of r and pass in specific attribute data. For example, pass in r.Close() closing price data. Close, High, Low, Open, Volume all use the calling method like r.Close().
C++ language strategy test example:
c++
void main() {
Records r;
r.Valid = true;
for (auto i = 0; i < 10; i++) {
Record ele;
ele.Time = i * 100000;
ele.High = i * 10000;
ele.Low = i * 1000;
ele.Close = i * 100;
ele.Open = i * 10;
ele.Volume = i * 1;
r.push_back(ele);
}
for(int j = 0; j < r.size(); j++){
Log(r[j]);
}
// Note: The first parameter is not r, need to call r.Close()
auto highest = TA.Highest(r.Close(), 8);
Log(highest);
}
TA.SMA
The TA.SMA() function is used to calculate the Simple Moving Average indicator.
TA.SMA(inReal)
TA.SMA(inReal, optInTimePeriod)Examples
javascript
function main(){
var records = exchange.GetRecords(PERIOD_M30)
var sma = TA.SMA(records, 14)
Log(sma)
}
python
def main():
r = exchange.GetRecords(PERIOD_M30)
sma = TA.SMA(r, 14)
Log(sma)
c++
void main() {
auto r = exchange.GetRecords(PERIOD_M30);
auto sma = TA.SMA(r, 14);
Log(sma);
}Returns
| Type | Description |
array | The return value of the |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
See Also
Remarks
The default value of the optInTimePeriod parameter for the TA.SMA() function is: 9.
Talib
talib.CDL2CROWS
The talib.CDL2CROWS() function is used to calculate Two Crows (K-line pattern - Two Crows).
talib.CDL2CROWS(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL2CROWS(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL2CROWS(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL2CROWS(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDL2CROWS() function is described in the talib library documentation as: CDL2CROWS(Records[Open,High,Low,Close]) = Array(outInteger)
For calls in Python language, the parameter passing method is different and needs to be passed according to the above description: Records[Open,High,Low,Close].
For example, split a variable records (i.e., parameter inPriceOHLC, type Record structure array) into:
Open list: represented as records.Open in Python.
High list: represented as records.High in Python.
Low list: represented as records.Low in Python.
Close list: represented as records.Close in Python.
Calling method in Python strategy code:
talib.CDL2CROWS(records.Open, records.High, records.Low, records.Close)
The calling methods for other talib indicators are similar and will not be repeated.
talib.CDL3BLACKCROWS
The talib.CDL3BLACKCROWS() function is used to calculate Three Black Crows (K-line pattern - Three Black Crows).
talib.CDL3BLACKCROWS(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL3BLACKCROWS(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL3BLACKCROWS(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL3BLACKCROWS(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDL3BLACKCROWS() function is described in the talib library documentation as: CDL3BLACKCROWS(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDL3INSIDE
The talib.CDL3INSIDE() function is used to calculate Three Inside Up/Down (Candlestick Pattern: Three Inside Up/Down).
talib.CDL3INSIDE(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL3INSIDE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL3INSIDE(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL3INSIDE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDL3INSIDE() function is described in the talib library documentation as: CDL3INSIDE(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDL3LINESTRIKE
The talib.CDL3LINESTRIKE() function is used to calculate Three-Line Strike (Candlestick Pattern: Three-Line Strike).
talib.CDL3LINESTRIKE(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL3LINESTRIKE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL3LINESTRIKE(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL3LINESTRIKE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDL3LINESTRIKE() function is described in the talib library documentation as: CDL3LINESTRIKE(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDL3OUTSIDE
The talib.CDL3OUTSIDE() function is used to calculate Three Outside Up/Down (Candlestick Pattern: Three Outside).
talib.CDL3OUTSIDE(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL3OUTSIDE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL3OUTSIDE(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL3OUTSIDE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDL3OUTSIDE() function is described in the talib library documentation as: CDL3OUTSIDE(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDL3STARSINSOUTH
The talib.CDL3STARSINSOUTH() function is used to calculate Three Stars In The South (Candlestick Pattern: Three Stars In The South).
talib.CDL3STARSINSOUTH(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL3STARSINSOUTH(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL3STARSINSOUTH(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL3STARSINSOUTH(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDL3STARSINSOUTH() function is described in the talib library documentation as: CDL3STARSINSOUTH(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDL3WHITESOLDIERS
The talib.CDL3WHITESOLDIERS() function is used to calculate Three Advancing White Soldiers (K-line pattern: Three White Soldiers).
talib.CDL3WHITESOLDIERS(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL3WHITESOLDIERS(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL3WHITESOLDIERS(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL3WHITESOLDIERS(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDL3WHITESOLDIERS() function is described in the talib library documentation as: CDL3WHITESOLDIERS(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLABANDONEDBABY
The talib.CDLABANDONEDBABY() function is used to calculate Abandoned Baby (Candlestick Pattern: Abandoned Baby).
talib.CDLABANDONEDBABY(inPriceOHLC)
talib.CDLABANDONEDBABY(inPriceOHLC, optInPenetration)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLABANDONEDBABY(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLABANDONEDBABY(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLABANDONEDBABY(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
optInPenetration | number | No | The |
Remarks
The CDLABANDONEDBABY() function is described in the talib library documentation as: CDLABANDONEDBABY(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)
talib.CDLADVANCEBLOCK
The talib.CDLADVANCEBLOCK() function is used to calculate Advance Block (Candlestick Pattern: Advance Block).
talib.CDLADVANCEBLOCK(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLADVANCEBLOCK(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLADVANCEBLOCK(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLADVANCEBLOCK(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLADVANCEBLOCK() function is described in the talib library documentation as: CDLADVANCEBLOCK(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLBELTHOLD
The talib.CDLBELTHOLD() function is used to calculate Belt-hold (Candlestick Pattern: Belt-hold).
talib.CDLBELTHOLD(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLBELTHOLD(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLBELTHOLD(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLBELTHOLD(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLBELTHOLD() function is described in the talib library documentation as: CDLBELTHOLD(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLBREAKAWAY
The talib.CDLBREAKAWAY() function is used to calculate Breakaway (Candlestick Pattern: Breakaway Pattern).
talib.CDLBREAKAWAY(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLBREAKAWAY(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLBREAKAWAY(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLBREAKAWAY(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLBREAKAWAY() function is described in the talib library documentation as: CDLBREAKAWAY(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLCLOSINGMARUBOZU
The talib.CDLCLOSINGMARUBOZU() function is used to calculate the Closing Marubozu candlestick pattern.
talib.CDLCLOSINGMARUBOZU(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLCLOSINGMARUBOZU(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLCLOSINGMARUBOZU(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLCLOSINGMARUBOZU(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLCLOSINGMARUBOZU() function is described in the talib library documentation as: CDLCLOSINGMARUBOZU(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLCONCEALBABYSWALL
The talib.CDLCONCEALBABYSWALL() function is used to calculate Concealing Baby Swallow (Candlestick Pattern: Concealing Baby Swallow).
talib.CDLCONCEALBABYSWALL(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLCONCEALBABYSWALL(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLCONCEALBABYSWALL(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLCONCEALBABYSWALL(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLCONCEALBABYSWALL() function is described in the talib library documentation as: CDLCONCEALBABYSWALL(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLCOUNTERATTACK
The talib.CDLCOUNTERATTACK() function is used to calculate Counterattack Lines (K-Line Pattern: Counterattack).
talib.CDLCOUNTERATTACK(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLCOUNTERATTACK(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLCOUNTERATTACK(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLCOUNTERATTACK(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLCOUNTERATTACK() function is described in the talib library documentation as: CDLCOUNTERATTACK(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLDARKCLOUDCOVER
The talib.CDLDARKCLOUDCOVER() function is used to calculate Dark Cloud Cover candlestick pattern.
talib.CDLDARKCLOUDCOVER(inPriceOHLC)
talib.CDLDARKCLOUDCOVER(inPriceOHLC, optInPenetration)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLDARKCLOUDCOVER(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLDARKCLOUDCOVER(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLDARKCLOUDCOVER(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
optInPenetration | number | No | The |
Remarks
The CDLDARKCLOUDCOVER() function is described in the talib library documentation as: CDLDARKCLOUDCOVER(Records[Open,High,Low,Close],Penetration = 0.5) = Array(outInteger)
talib.CDLDOJI
The talib.CDLDOJI() function is used to calculate Doji (K-line pattern: Doji Star).
talib.CDLDOJI(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLDOJI(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLDOJI(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLDOJI(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLDOJI() function is described in the talib library documentation as: CDLDOJI(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLDOJISTAR
The talib.CDLDOJISTAR() function is used to calculate Doji Star (Candlestick Pattern: Doji Star).
talib.CDLDOJISTAR(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLDOJISTAR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLDOJISTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLDOJISTAR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLDOJISTAR() function is described in the talib library documentation as: CDLDOJISTAR(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLDRAGONFLYDOJI
The talib.CDLDRAGONFLYDOJI() function is used to calculate Dragonfly Doji (Candlestick Pattern: Dragonfly Doji).
talib.CDLDRAGONFLYDOJI(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLDRAGONFLYDOJI(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLDRAGONFLYDOJI(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLDRAGONFLYDOJI(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLDRAGONFLYDOJI() function is described in the talib library documentation as: CDLDRAGONFLYDOJI(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLENGULFING
The talib.CDLENGULFING() function is used to calculate Engulfing Pattern.
talib.CDLENGULFING(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLENGULFING(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLENGULFING(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLENGULFING(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLENGULFING() function is described in the talib library documentation as: CDLENGULFING(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLEVENINGDOJISTAR
The talib.CDLEVENINGDOJISTAR() function is used to calculate Evening Doji Star (K-line pattern: Evening Doji Star).
talib.CDLEVENINGDOJISTAR(inPriceOHLC)
talib.CDLEVENINGDOJISTAR(inPriceOHLC, optInPenetration)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLEVENINGDOJISTAR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLEVENINGDOJISTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLEVENINGDOJISTAR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
optInPenetration | number | No | The |
Remarks
The CDLEVENINGDOJISTAR() function is described in the talib library documentation as: CDLEVENINGDOJISTAR(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)
talib.CDLEVENINGSTAR
The talib.CDLEVENINGSTAR() function is used to calculate the Evening Star candlestick pattern.
talib.CDLEVENINGSTAR(inPriceOHLC)
talib.CDLEVENINGSTAR(inPriceOHLC, optInPenetration)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLEVENINGSTAR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLEVENINGSTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLEVENINGSTAR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
optInPenetration | number | No | The |
Remarks
The CDLEVENINGSTAR() function is described in the talib library documentation as: CDLEVENINGSTAR(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)
talib.CDLGAPSIDESIDEWHITE
The talib.CDLGAPSIDESIDEWHITE() function is used to calculate Up/Down-gap side-by-side white lines (K-line pattern: Up/Down-gap side-by-side white lines).
talib.CDLGAPSIDESIDEWHITE(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLGAPSIDESIDEWHITE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLGAPSIDESIDEWHITE(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLGAPSIDESIDEWHITE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLGAPSIDESIDEWHITE() function is described in the talib library documentation as: CDLGAPSIDESIDEWHITE(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLGRAVESTONEDOJI
The talib.CDLGRAVESTONEDOJI() function is used to calculate the Gravestone Doji candlestick pattern.
talib.CDLGRAVESTONEDOJI(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLGRAVESTONEDOJI(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLGRAVESTONEDOJI(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLGRAVESTONEDOJI(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLGRAVESTONEDOJI() function is described in the talib library documentation as: CDLGRAVESTONEDOJI(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLHAMMER
The talib.CDLHAMMER() function is used to calculate Hammer (Candlestick Pattern: Hammer).
talib.CDLHAMMER(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHAMMER(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHAMMER(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHAMMER(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLHAMMER() function is described in the talib library documentation as: CDLHAMMER(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLHANGINGMAN
The talib.CDLHANGINGMAN() function is used to calculate Hanging Man (Candlestick Pattern: Hanging Man).
talib.CDLHANGINGMAN(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHANGINGMAN(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHANGINGMAN(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHANGINGMAN(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLHANGINGMAN() function is described in the talib library documentation as: CDLHANGINGMAN(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLHARAMI
The talib.CDLHARAMI() function is used to calculate Harami Pattern (K-line chart: bullish/bearish pattern).
talib.CDLHARAMI(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHARAMI(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHARAMI(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHARAMI(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLHARAMI() function is described in the talib library documentation as: CDLHARAMI(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLHARAMICROSS
The talib.CDLHARAMICROSS() function is used to calculate Harami Cross Pattern (Candlestick Pattern: Harami Cross).
talib.CDLHARAMICROSS(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHARAMICROSS(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHARAMICROSS(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHARAMICROSS(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLHARAMICROSS() function is described in the talib library documentation as: CDLHARAMICROSS(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLHIGHWAVE
The talib.CDLHIGHWAVE() function is used to calculate High-Wave Candle (Candlestick Pattern: High Wave Candle).
talib.CDLHIGHWAVE(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHIGHWAVE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHIGHWAVE(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHIGHWAVE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLHIGHWAVE() function is described in the talib library documentation as: CDLHIGHWAVE(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLHIKKAKE
The talib.CDLHIKKAKE() function is used to calculate Hikkake Pattern (Candlestick: Trap Pattern).
talib.CDLHIKKAKE(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHIKKAKE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHIKKAKE(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHIKKAKE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLHIKKAKE() function is described in the talib library documentation as: CDLHIKKAKE(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLHIKKAKEMOD
The talib.CDLHIKKAKEMOD() function is used to calculate Modified Hikkake Pattern (Candlestick: Modified Hikkake Pattern).
talib.CDLHIKKAKEMOD(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHIKKAKEMOD(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHIKKAKEMOD(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHIKKAKEMOD(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLHIKKAKEMOD() function is described in the talib library documentation as: CDLHIKKAKEMOD(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLHOMINGPIGEON
The talib.CDLHOMINGPIGEON() function is used to calculate Homing Pigeon (Candlestick Pattern: Homing Pigeon).
talib.CDLHOMINGPIGEON(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHOMINGPIGEON(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHOMINGPIGEON(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHOMINGPIGEON(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLHOMINGPIGEON() function is described in the talib library documentation as: CDLHOMINGPIGEON(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLIDENTICAL3CROWS
The talib.CDLIDENTICAL3CROWS() function is used to calculate Identical Three Crows (Candlestick Pattern: Identical Three Crows).
talib.CDLIDENTICAL3CROWS(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLIDENTICAL3CROWS(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLIDENTICAL3CROWS(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLIDENTICAL3CROWS(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLIDENTICAL3CROWS() function is described in the talib library documentation as: CDLIDENTICAL3CROWS(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLINNECK
The talib.CDLINNECK() function is used to calculate In-Neck Pattern (Candlestick Chart: In-Neck Pattern).
talib.CDLINNECK(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLINNECK(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLINNECK(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLINNECK(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLINNECK() function is described in the talib library documentation as: CDLINNECK(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLINVERTEDHAMMER
The talib.CDLINVERTEDHAMMER() function is used to calculate Inverted Hammer (K-Line Pattern: Inverted Hammer).
talib.CDLINVERTEDHAMMER(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLINVERTEDHAMMER(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLINVERTEDHAMMER(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLINVERTEDHAMMER(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLINVERTEDHAMMER() function is described in the talib library documentation as: CDLINVERTEDHAMMER(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLKICKING
The talib.CDLKICKING() function is used to calculate Kicking (Candlestick Pattern: Kicking Pattern).
talib.CDLKICKING(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLKICKING(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLKICKING(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLKICKING(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLKICKING() function is described in the talib library documentation as: CDLKICKING(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLKICKINGBYLENGTH
The talib.CDLKICKINGBYLENGTH() function is used to calculate Kicking - bull/bear determined by the longer marubozu (K-line pattern: Kicking Bull/Bear).
talib.CDLKICKINGBYLENGTH(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLKICKINGBYLENGTH(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLKICKINGBYLENGTH(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLKICKINGBYLENGTH(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLKICKINGBYLENGTH() function is described in the talib library documentation as: CDLKICKINGBYLENGTH(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLLADDERBOTTOM
The talib.CDLLADDERBOTTOM() function is used to calculate Ladder Bottom (Candlestick Pattern: Ladder Bottom).
talib.CDLLADDERBOTTOM(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLLADDERBOTTOM(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLLADDERBOTTOM(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLLADDERBOTTOM(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLLADDERBOTTOM() function is described in the talib library documentation as: CDLLADDERBOTTOM(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLLONGLEGGEDDOJI
The talib.CDLLONGLEGGEDDOJI() function is used to calculate Long Legged Doji (Candlestick Pattern: Long Legged Doji).
talib.CDLLONGLEGGEDDOJI(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLLONGLEGGEDDOJI(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLLONGLEGGEDDOJI(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLLONGLEGGEDDOJI(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLLONGLEGGEDDOJI() function is described in the talib library documentation as: CDLLONGLEGGEDDOJI(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLLONGLINE
The talib.CDLLONGLINE() function is used to calculate Long Line Candle Pattern (Candlestick Chart: Long Line).
talib.CDLLONGLINE(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLLONGLINE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLLONGLINE(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLLONGLINE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLLONGLINE() function is described in the talib library documentation as: CDLLONGLINE(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLMARUBOZU
The talib.CDLMARUBOZU() function is used to calculate the Marubozu (Candlestick Pattern: Shaven Head and Bottom) pattern.
talib.CDLMARUBOZU(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLMARUBOZU(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLMARUBOZU(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLMARUBOZU(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLMARUBOZU() function is described in the talib library documentation as: CDLMARUBOZU(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLMATCHINGLOW
The talib.CDLMATCHINGLOW() function is used to calculate Matching Low (Candlestick Pattern: Matching Low).
talib.CDLMATCHINGLOW(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLMATCHINGLOW(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLMATCHINGLOW(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLMATCHINGLOW(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLMATCHINGLOW() function is described in the talib library documentation as: CDLMATCHINGLOW(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLMATHOLD
The talib.CDLMATHOLD() function is used to calculate Mat Hold (Candlestick Pattern: Mat Hold).
talib.CDLMATHOLD(inPriceOHLC)
talib.CDLMATHOLD(inPriceOHLC, optInPenetration)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLMATHOLD(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLMATHOLD(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLMATHOLD(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
optInPenetration | number | No | The |
Remarks
The CDLMATHOLD() function is described in the talib library documentation as: CDLMATHOLD(Records[Open,High,Low,Close],Penetration = 0.5) = Array(outInteger)
talib.CDLMORNINGDOJISTAR
The talib.CDLMORNINGDOJISTAR() function is used to calculate Morning Doji Star (Candlestick Pattern: Morning Doji Star).
talib.CDLMORNINGDOJISTAR(inPriceOHLC)
talib.CDLMORNINGDOJISTAR(inPriceOHLC, optInPenetration)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLMORNINGDOJISTAR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLMORNINGDOJISTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLMORNINGDOJISTAR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
optInPenetration | number | No | The |
Remarks
The CDLMORNINGDOJISTAR() function is described in the talib library documentation as: CDLMORNINGDOJISTAR(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)
talib.CDLMORNINGSTAR
The talib.CDLMORNINGSTAR() function is used to calculate Morning Star (Candlestick Pattern: Morning Star).
talib.CDLMORNINGSTAR(inPriceOHLC)
talib.CDLMORNINGSTAR(inPriceOHLC, optInPenetration)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLMORNINGSTAR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLMORNINGSTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLMORNINGSTAR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
optInPenetration | number | No | The |
Remarks
The CDLMORNINGSTAR() function is described in the talib library documentation as: CDLMORNINGSTAR(Records[Open,High,Low,Close],Penetration=0.3) = Array(outInteger)
talib.CDLONNECK
The talib.CDLONNECK() function is used to calculate On-Neck Pattern (Candlestick Chart: On-Neck Pattern).
talib.CDLONNECK(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLONNECK(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLONNECK(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLONNECK(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLONNECK() function is described in the talib library documentation as: CDLONNECK(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLPIERCING
The talib.CDLPIERCING() function is used to calculate Piercing Pattern (Candlestick Pattern: Piercing Pattern).
talib.CDLPIERCING(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLPIERCING(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLPIERCING(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLPIERCING(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLPIERCING() function is described in the talib library documentation as: CDLPIERCING(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLRICKSHAWMAN
The talib.CDLRICKSHAWMAN() function is used to calculate Rickshaw Man (Candlestick Pattern: Rickshaw Man).
talib.CDLRICKSHAWMAN(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLRICKSHAWMAN(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLRICKSHAWMAN(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLRICKSHAWMAN(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLRICKSHAWMAN() function is described in the talib library documentation as: CDLRICKSHAWMAN(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLRISEFALL3METHODS
The talib.CDLRISEFALL3METHODS() function is used to calculate Rising/Falling Three Methods (Candlestick Pattern: Rising/Falling Three Methods).
talib.CDLRISEFALL3METHODS(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLRISEFALL3METHODS(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLRISEFALL3METHODS(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLRISEFALL3METHODS(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLRISEFALL3METHODS() function is described in the talib library documentation as: CDLRISEFALL3METHODS(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLSEPARATINGLINES
The talib.CDLSEPARATINGLINES() function is used to calculate Separating Lines Pattern (Candlestick Chart: Separating Lines).
talib.CDLSEPARATINGLINES(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLSEPARATINGLINES(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLSEPARATINGLINES(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLSEPARATINGLINES(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLSEPARATINGLINES() function is described in the talib library documentation as: CDLSEPARATINGLINES(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLSHOOTINGSTAR
The talib.CDLSHOOTINGSTAR() function is used to calculate Shooting Star (Candlestick Pattern: Shooting Star).
talib.CDLSHOOTINGSTAR(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLSHOOTINGSTAR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLSHOOTINGSTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLSHOOTINGSTAR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLSHOOTINGSTAR() function is described in the talib library documentation as: CDLSHOOTINGSTAR(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLSHORTLINE
The talib.CDLSHORTLINE() function is used to calculate Short Line Candle Pattern (K-Line: Short Line).
talib.CDLSHORTLINE(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLSHORTLINE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLSHORTLINE(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLSHORTLINE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLSHORTLINE() function is described in the talib library documentation as: CDLSHORTLINE(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLSPINNINGTOP
The talib.CDLSPINNINGTOP() function is used to calculate Spinning Top (Candlestick Pattern: Spinning Top).
talib.CDLSPINNINGTOP(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLSPINNINGTOP(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLSPINNINGTOP(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLSPINNINGTOP(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLSPINNINGTOP() function is described in the talib library documentation as: CDLSPINNINGTOP(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLSTALLEDPATTERN
The talib.CDLSTALLEDPATTERN() function is used to calculate Stalled Pattern (Candlestick Pattern: Stalled Pattern).
talib.CDLSTALLEDPATTERN(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLSTALLEDPATTERN(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLSTALLEDPATTERN(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLSTALLEDPATTERN(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLSTALLEDPATTERN() function is described in the talib library documentation as: CDLSTALLEDPATTERN(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLSTICKSANDWICH
The talib.CDLSTICKSANDWICH() function is used to calculate Stick Sandwich (Candlestick Pattern: Stick Sandwich).
talib.CDLSTICKSANDWICH(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLSTICKSANDWICH(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLSTICKSANDWICH(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLSTICKSANDWICH(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLSTICKSANDWICH() function is described in the talib library documentation as: CDLSTICKSANDWICH(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLTAKURI
The talib.CDLTAKURI() function is used to calculate Takuri (Dragonfly Doji with very long lower shadow) candlestick pattern.
talib.CDLTAKURI(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLTAKURI(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLTAKURI(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLTAKURI(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLTAKURI() function is described in the talib library documentation as: CDLTAKURI(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLTASUKIGAP
The talib.CDLTASUKIGAP() function is used to calculate Tasuki Gap (Candlestick Pattern: Tasuki Gap).
talib.CDLTASUKIGAP(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLTASUKIGAP(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLTASUKIGAP(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLTASUKIGAP(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLTASUKIGAP() function is described in the talib library documentation as: CDLTASUKIGAP(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLTHRUSTING
The talib.CDLTHRUSTING() function is used to calculate Thrusting Pattern (Candlestick Pattern: Thrusting Pattern).
talib.CDLTHRUSTING(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLTHRUSTING(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLTHRUSTING(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLTHRUSTING(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLTHRUSTING() function is described in the talib library documentation as: CDLTHRUSTING(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLTRISTAR
The talib.CDLTRISTAR() function is used to calculate Tristar Pattern (Candlestick Chart: Tristar Pattern).
talib.CDLTRISTAR(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLTRISTAR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLTRISTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLTRISTAR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLTRISTAR() function is described in the talib library documentation as: CDLTRISTAR(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLUNIQUE3RIVER
The talib.CDLUNIQUE3RIVER() function is used to calculate Unique 3 River (Candlestick Pattern: Unique Three River).
talib.CDLUNIQUE3RIVER(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLUNIQUE3RIVER(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLUNIQUE3RIVER(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLUNIQUE3RIVER(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLUNIQUE3RIVER() function is described in the talib library documentation as: CDLUNIQUE3RIVER(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLUPSIDEGAP2CROWS
The talib.CDLUPSIDEGAP2CROWS() function is used to calculate Upside Gap Two Crows (Candlestick Pattern: Two Crows).
talib.CDLUPSIDEGAP2CROWS(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLUPSIDEGAP2CROWS(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLUPSIDEGAP2CROWS(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLUPSIDEGAP2CROWS(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLUPSIDEGAP2CROWS() function is described in the talib library documentation as: CDLUPSIDEGAP2CROWS(Records[Open,High,Low,Close]) = Array(outInteger)
talib.CDLXSIDEGAP3METHODS
The talib.CDLXSIDEGAP3METHODS() function is used to calculate Upside/Downside Gap Three Methods (Candlestick Pattern Recognition).
talib.CDLXSIDEGAP3METHODS(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLXSIDEGAP3METHODS(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLXSIDEGAP3METHODS(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLXSIDEGAP3METHODS(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The CDLXSIDEGAP3METHODS() function is described in the talib library documentation as: CDLXSIDEGAP3METHODS(Records[Open,High,Low,Close]) = Array(outInteger)
talib.AD
The talib.AD() function is used to calculate the Chaikin A/D Line (Accumulation/Distribution Line indicator).
talib.AD(inPriceHLCV)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.AD(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.AD(records.High, records.Low, records.Close, records.Volume)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.AD(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLCV |
| Yes | The |
Remarks
The AD() function is described in the talib library documentation as: AD(Records[High,Low,Close,Volume]) = Array(outReal)
talib.ADOSC
The talib.ADOSC() function is used to calculate Chaikin A/D Oscillator.
talib.ADOSC(inPriceHLCV)
talib.ADOSC(inPriceHLCV, optInFastPeriod, optInSlowPeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.ADOSC(records, 3, 10)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.ADOSC(records.High, records.Low, records.Close, records.Volume, 3, 10)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ADOSC(records, 3, 10);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLCV |
| Yes | The |
optInFastPeriod | number | No | The |
optInSlowPeriod | number | No | The |
Remarks
The ADOSC() function is described in the talib library documentation as: ADOSC(Records[High,Low,Close,Volume],Fast Period = 3,Slow Period = 10) = Array(outReal)
talib.OBV
The talib.OBV() function is used to calculate On Balance Volume.
talib.OBV(inReal)
talib.OBV(inReal, inPriceV)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.OBV(records, records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.OBV(records.Close, records.Volume)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.OBV(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
inPriceV |
| No | The |
Remarks
The OBV() function is described in the talib library documentation as: OBV(Records[Close],Records[Volume]) = Array(outReal)
talib.ACOS
The talib.ACOS() function is used to calculate Vector Trigonometric ACos.
talib.ACOS(inReal)Examples
javascript
function main() {
var data = [-1, 0, 1]
var ret = talib.ACOS(data)
Log(ret)
}
python
import talib
import numpy as np
def main():
data = [-1.0, 0, 1.0]
ret = talib.ACOS(np.array(data))
Log(ret)
c++
void main() {
std::vector<double> data = {-1, 0, 1};
auto ret = talib.ACOS(data);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The ACOS() function is described in the talib library documentation as: ACOS(Records[Close]) = Array(outReal)
talib.ASIN
The talib.ASIN() function is used to calculate Vector Trigonometric ASin.
talib.ASIN(inReal)Examples
javascript
function main() {
var data = [-1, 0, 1]
var ret = talib.ASIN(data)
Log(ret)
}
python
import talib
import numpy as np
def main():
data = [-1.0, 0, 1.0]
ret = talib.ASIN(np.array(data))
Log(ret)
c++
void main() {
std::vector<double> data = {-1, 0, 1};
auto ret = talib.ASIN(data);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The ASIN() function is described in the talib library documentation as: ASIN(Records[Close]) = Array(outReal)
talib.ATAN
The talib.ATAN() function is used to calculate Vector Trigonometric ATan.
talib.ATAN(inReal)Examples
javascript
function main() {
var data = [-3.14/2, 0, 3.14/2]
var ret = talib.ATAN(data)
Log(ret)
}
python
import talib
import numpy as np
def main():
data = [-3.14/2, 0, 3.14/2]
ret = talib.ATAN(np.array(data))
Log(ret)
c++
void main() {
std::vector<double> data = {-3.14/2, 0, 3.14/2};
auto ret = talib.ATAN(data);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The ATAN() function is described in the talib library documentation as: ATAN(Records[Close]) = Array(outReal)
talib.CEIL
The talib.CEIL() function is used to calculate Vector Ceil.
talib.CEIL(inReal)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CEIL(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CEIL(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CEIL(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The CEIL() function is described in the talib library documentation as: CEIL(Records[Close]) = Array(outReal)
talib.COS
The talib.COS() function is used to calculate Vector Trigonometric Cos.
talib.COS(inReal)Examples
javascript
function main() {
var data = [-3.14, 0, 3.14]
var ret = talib.COS(data)
Log(ret)
}
python
import talib
import numpy as np
def main():
data = [-3.14, 0, 3.14]
ret = talib.COS(np.array(data))
Log(ret)
c++
void main() {
std::vector<double> data = {-3.14, 0, 3.14};
auto ret = talib.COS(data);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The COS() function is described in the talib library documentation as: COS(Records[Close]) = Array(outReal)
talib.COSH
The talib.COSH() function is used to calculate Vector Trigonometric Cosh.
talib.COSH(inReal)Examples
javascript
function main() {
var data = [-1, 0, 1]
var ret = talib.COSH(data)
Log(ret)
}
python
import talib
import numpy as np
def main():
data = [-1.0, 0, 1.0]
ret = talib.COSH(np.array(data))
Log(ret)
c++
void main() {
std::vector<double> data = {-1, 0, 1};
auto ret = talib.COSH(data);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The COSH() function is described in the talib library documentation as: COSH(Records[Close]) = Array(outReal)
talib.EXP
The talib.EXP() function is used to calculate Vector Arithmetic Exp.
talib.EXP(inReal)Examples
javascript
function main() {
var data = [0, 1, 2]
var ret = talib.EXP(data) // e^0, e^1, e^2
Log(ret)
}
python
import talib
import numpy as np
def main():
data = [0, 1.0, 2.0]
ret = talib.EXP(np.array(data))
Log(ret)
c++
void main() {
std::vector<double> data = {0, 1.0, 2.0};
auto ret = talib.EXP(data);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The EXP() function is described in the talib library documentation as: EXP(Records[Close]) = Array(outReal)
talib.FLOOR
The talib.FLOOR() function is used to calculate Vector Floor.
talib.FLOOR(inReal)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.FLOOR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.FLOOR(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.FLOOR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The FLOOR() function is described in the talib library documentation as: FLOOR(Records[Close]) = Array(outReal)
talib.LN
The talib.LN() function is used to calculate Vector Log Natural.
talib.LN(inReal)Examples
javascript
function main() {
var data = [1, 2, 3]
var ret = talib.LN(data)
Log(ret)
}
python
import talib
import numpy as np
def main():
data = [1.0, 2.0, 3.0]
ret = talib.LN(np.array(data))
Log(ret)
c++
void main() {
std::vector<double> data = {1, 2, 3};
auto ret = talib.LN(data);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The LN() function is described in the talib library documentation as: LN(Records[Close]) = Array(outReal)
talib.LOG10
The talib.LOG10() function is used to calculate Vector Log10 (logarithm function).
talib.LOG10(inReal)Examples
javascript
function main() {
var data = [10, 100, 1000]
var ret = talib.LOG10(data)
Log(ret)
}
python
import talib
import numpy as np
def main():
data = [10.0, 100.0, 1000.0]
ret = talib.LOG10(np.array(data))
Log(ret)
c++
void main() {
std::vector<double> data = {10, 100, 1000};
auto ret = talib.LOG10(data);
Log(ret);
}Returns
| Type | Description |
array | The return value of the |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The LOG10() function is described in the talib library documentation as: LOG10(Records[Close]) = Array(outReal)
talib.SIN
The talib.SIN() function is used to calculate Vector Trigonometric Sin.
talib.SIN(inReal)Examples
javascript
function main() {
var data = [-3.14/2, 0, 3.14/2]
var ret = talib.SIN(data)
Log(ret)
}
python
import talib
import numpy as np
def main():
data = [-3.14/2, 0, 3.14/2]
ret = talib.SIN(np.array(data))
Log(ret)
c++
void main() {
std::vector<double> data = {-3.14/2, 0, 3.14/2};
auto ret = talib.SIN(data);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The SIN() function is described in the talib library documentation as: SIN(Records[Close]) = Array(outReal)
talib.SINH
The talib.SINH() function is used to calculate Vector Trigonometric Sinh.
talib.SINH(inReal)Examples
javascript
function main() {
var data = [-1, 0, 1]
var ret = talib.SINH(data)
Log(ret)
}
python
import talib
import numpy as np
def main():
data = [-1.0, 0, 1.0]
ret = talib.SINH(np.array(data))
Log(ret)
c++
void main() {
std::vector<double> data = {-1, 0, 1};
auto ret = talib.SINH(data);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The SINH() function is described in the talib library documentation as: SINH(Records[Close]) = Array(outReal)
talib.SQRT
The talib.SQRT() function is used to calculate Vector Square Root.
talib.SQRT(inReal)Examples
javascript
function main() {
var data = [4, 64, 100]
var ret = talib.SQRT(data)
Log(ret)
}
python
import talib
import numpy as np
def main():
data = [4.0, 64.0, 100.0]
ret = talib.SQRT(np.array(data))
Log(ret)
c++
void main() {
std::vector<double> data = {4, 64, 100};
auto ret = talib.SQRT(data);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The SQRT() function is described in the talib library documentation as: SQRT(Records[Close]) = Array(outReal)
talib.TAN
The talib.TAN() function is used to calculate Vector Trigonometric Tan.
talib.TAN(inReal)Examples
javascript
function main() {
var data = [-1, 0, 1]
var ret = talib.TAN(data)
Log(ret)
}
python
import talib
import numpy as np
def main():
data = [-1.0, 0, 1.0]
ret = talib.TAN(np.array(data))
Log(ret)
c++
void main() {
std::vector<double> data = {-1, 0, 1};
auto ret = talib.TAN(data);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The TAN() function is described in the talib library documentation as: TAN(Records[Close]) = Array(outReal)
talib.TANH
The talib.TANH() function is used to calculate Vector Trigonometric Tanh.
talib.TANH(inReal)Examples
javascript
function main() {
var data = [-1, 0, 1]
var ret = talib.TANH(data)
Log(ret)
}
python
import talib
import numpy as np
def main():
data = [-1.0, 0, 1.0]
ret = talib.TANH(np.array(data))
Log(ret)
c++
void main() {
std::vector<double> data = {-1, 0, 1};
auto ret = talib.TANH(data);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The TANH() function is described in the talib library documentation as: TANH(Records[Close]) = Array(outReal)
talib.MAX
The talib.MAX() function is used to calculate the Highest value over a specified period.
talib.MAX(inReal)
talib.MAX(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MAX(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MAX(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MAX(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The MAX() function is described in the talib library documentation as: MAX(Records[Close],Time Period = 30) = Array(outReal)
talib.MAXINDEX
The talib.MAXINDEX() function is used to calculate the Index of highest value over a specified period.
talib.MAXINDEX(inReal)
talib.MAXINDEX(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MAXINDEX(records, 5)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MAXINDEX(records.Close, 5)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MAXINDEX(records, 5);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The MAXINDEX() function is described in the talib library documentation as: MAXINDEX(Records[Close],Time Period = 30) = Array(outInteger)
talib.MIN
The talib.MIN() function is used to calculate the Lowest value over a specified period.
talib.MIN(inReal)
talib.MIN(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MIN(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MIN(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MIN(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The MIN() function is described in the talib library documentation as: MIN(Records[Close],Time Period = 30) = Array(outReal)
talib.MININDEX
The talib.MININDEX() function is used to calculate the Index of lowest value over a specified period.
talib.MININDEX(inReal)
talib.MININDEX(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MININDEX(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MININDEX(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MININDEX(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The MININDEX() function is described in the talib library documentation as: MININDEX(Records[Close],Time Period = 30) = Array(outInteger)
talib.MINMAX
The talib.MINMAX() function is used to calculate the Lowest and highest values over a specified period.
talib.MINMAX(inReal)
talib.MINMAX(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MINMAX(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MINMAX(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MINMAX(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The MINMAX() function is described in the talib library documentation as: MINMAX(Records[Close],Time Period = 30) = [Array(outMin),Array(outMax)]
talib.MINMAXINDEX
The talib.MINMAXINDEX() function is used to calculate Indexes of lowest and highest values over a specified period.
talib.MINMAXINDEX(inReal)
talib.MINMAXINDEX(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MINMAXINDEX(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MINMAXINDEX(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MINMAXINDEX(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The MINMAXINDEX() function is described in the talib library documentation as: MINMAXINDEX(Records[Close],Time Period = 30) = [Array(outMinIdx),Array(outMaxIdx)]
talib.SUM
The talib.SUM() function is used to calculate Summation.
talib.SUM(inReal)
talib.SUM(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.SUM(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.SUM(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.SUM(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The SUM() function is described in the talib library documentation as: SUM(Records[Close],Time Period = 30) = Array(outReal)
talib.HT_DCPERIOD
The talib.HT_DCPERIOD() function is used to calculate Hilbert Transform - Dominant Cycle Period.
talib.HT_DCPERIOD(inReal)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.HT_DCPERIOD(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.HT_DCPERIOD(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.HT_DCPERIOD(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The HT_DCPERIOD() function is described in the talib library documentation as: HT_DCPERIOD(Records[Close]) = Array(outReal)
talib.HT_DCPHASE
The talib.HT_DCPHASE() function is used to calculate the Hilbert Transform - Dominant Cycle Phase.
talib.HT_DCPHASE(inReal)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.HT_DCPHASE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.HT_DCPHASE(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.HT_DCPHASE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The HT_DCPHASE() function is described in the talib library documentation as: HT_DCPHASE(Records[Close]) = Array(outReal)
talib.HT_PHASOR
The talib.HT_PHASOR() function is used to calculate Hilbert Transform - Phasor Components.
talib.HT_PHASOR(inReal)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.HT_PHASOR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.HT_PHASOR(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.HT_PHASOR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The HT_PHASOR() function is described in the talib library documentation as: HT_PHASOR(Records[Close]) = [Array(outInPhase),Array(outQuadrature)]
talib.HT_SINE
The talib.HT_SINE() function is used to calculate Hilbert Transform - SineWave.
talib.HT_SINE(inReal)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.HT_SINE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.HT_SINE(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.HT_SINE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The HT_SINE() function is described in the talib library documentation as: HT_SINE(Records[Close]) = [Array(outSine),Array(outLeadSine)]
talib.HT_TRENDMODE
The talib.HT_TRENDMODE() function is used to calculate Hilbert Transform - Trend vs Cycle Mode.
talib.HT_TRENDMODE(inReal)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.HT_TRENDMODE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.HT_TRENDMODE(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.HT_TRENDMODE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The HT_TRENDMODE() function is described in the talib library documentation as: HT_TRENDMODE(Records[Close]) = Array(outInteger)
talib.ATR
The talib.ATR() function is used to calculate the Average True Range indicator.
talib.ATR(inPriceHLC)
talib.ATR(inPriceHLC, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.ATR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.ATR(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ATR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The ATR() function is described in the talib library documentation as: ATR(Records[High,Low,Close],Time Period = 14) = Array(outReal)
talib.NATR
The talib.NATR() function is used to calculate Normalized Average True Range.
talib.NATR(inPriceHLC)
talib.NATR(inPriceHLC, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.NATR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.NATR(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.NATR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The NATR() function is described in the talib library documentation as: NATR(Records[High,Low,Close],Time Period = 14) = Array(outReal)
talib.TRANGE
The talib.TRANGE() function is used to calculate the True Range indicator.
talib.TRANGE(inPriceHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.TRANGE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.TRANGE(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.TRANGE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
Remarks
The TRANGE() function is described in the talib library documentation as: TRANGE(Records[High,Low,Close]) = Array(outReal)
talib.BBANDS
The talib.BBANDS() function is used to calculate Bollinger Bands.
talib.BBANDS(inReal)
talib.BBANDS(inReal, optInTimePeriod)
talib.BBANDS(inReal, optInTimePeriod, optInNbDevUp)
talib.BBANDS(inReal, optInTimePeriod, optInNbDevUp, optInNbDevDn)
talib.BBANDS(inReal, optInTimePeriod, optInNbDevUp, optInNbDevDn, optInMAType)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.BBANDS(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.BBANDS(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.BBANDS(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
optInNbDevUp | number | No | The |
optInNbDevDn | number | No | The |
optInMAType | number | No | The |
Remarks
The BBANDS() function is described in the talib library documentation as: BBANDS(Records[Close],Time Period = 5,Deviations up = 2,Deviations down = 2,MA Type = 0) = [Array(outRealUpperBand),Array(outRealMiddleBand),Array(outRealLowerBand)]
talib.DEMA
The talib.DEMA() function is used to calculate Double Exponential Moving Average.
talib.DEMA(inReal)
talib.DEMA(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.DEMA(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.DEMA(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.DEMA(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The DEMA() function is described in the talib library documentation as: DEMA(Records[Close],Time Period = 30) = Array(outReal)
talib.EMA
The talib.EMA() function is used to calculate Exponential Moving Average.
talib.EMA(inReal)
talib.EMA(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.EMA(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.EMA(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.EMA(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The EMA() function is described in the talib library documentation as: EMA(Records[Close],Time Period = 30) = Array(outReal)
talib.HT_TRENDLINE
The talib.HT_TRENDLINE() function is used to calculate Hilbert Transform - Instantaneous Trendline.
talib.HT_TRENDLINE(inReal)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.HT_TRENDLINE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.HT_TRENDLINE(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.HT_TRENDLINE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
Remarks
The HT_TRENDLINE() function is described in the talib library documentation as: HT_TRENDLINE(Records[Close]) = Array(outReal)
talib.KAMA
The talib.KAMA() function is used to calculate Kaufman Adaptive Moving Average.
talib.KAMA(inReal)
talib.KAMA(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.KAMA(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.KAMA(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.KAMA(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The KAMA() function is described in the talib library documentation as: KAMA(Records[Close],Time Period = 30) = Array(outReal)
talib.MA
The talib.MA() function is used to calculate Moving average.
talib.MA(inReal)
talib.MA(inReal, optInTimePeriod)
talib.MA(inReal, optInTimePeriod, optInMAType)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MA(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MA(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MA(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
optInMAType | number | No | The |
Remarks
The MA() function is described in the talib library documentation as: MA(Records[Close],Time Period = 30,MA Type = 0) = Array(outReal)
talib.MAMA
The talib.MAMA() function is used to calculate the MESA Adaptive Moving Average.
talib.MAMA(inReal)
talib.MAMA(inReal, optInFastLimit)
talib.MAMA(inReal, optInFastLimit, optInSlowLimit)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MAMA(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MAMA(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MAMA(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInFastLimit | number | No | The |
optInSlowLimit | number | No | The |
Remarks
The MAMA() function is described in the talib library documentation as: MAMA(Records[Close],Fast Limit = 0.5,Slow Limit = 0.05) = [Array(outMAMA),Array(outFAMA)]
talib.MIDPOINT
The talib.MIDPOINT() function is used to calculate MidPoint over period.
talib.MIDPOINT(inReal)
talib.MIDPOINT(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MIDPOINT(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MIDPOINT(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MIDPOINT(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The MIDPOINT() function is described in the talib library documentation as: MIDPOINT(Records[Close],Time Period = 14) = Array(outReal)
talib.MIDPRICE
The talib.MIDPRICE() function is used to calculate Midpoint Price over period.
talib.MIDPRICE(inPriceHL)
talib.MIDPRICE(inPriceHL, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MIDPRICE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MIDPRICE(records.High, records.Low)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MIDPRICE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHL |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The MIDPRICE() function is described in the talib library documentation as: MIDPRICE(Records[High,Low],Time Period = 14) = Array(outReal)
talib.SAR
The talib.SAR() function is used to calculate the Parabolic SAR (Stop and Reverse) indicator.
talib.SAR(inPriceHL)
talib.SAR(inPriceHL, optInAcceleration)
talib.SAR(inPriceHL, optInAcceleration, optInMaximum)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.SAR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.SAR(records.High, records.Low)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.SAR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHL |
| Yes | The |
optInAcceleration | number | No | The |
optInMaximum | number | No | The |
Remarks
The SAR() function is described in the talib library documentation as: SAR(Records[High,Low],Acceleration Factor = 0.02,AF Maximum = 0.2) = Array(outReal)
talib.SAREXT
The talib.SAREXT() function is used to calculate Parabolic SAR - Extended.
talib.SAREXT(inPriceHL)
talib.SAREXT(inPriceHL, optInStartValue)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse, optInAccelerationInitLong)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse, optInAccelerationInitLong, optInAccelerationLong)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse, optInAccelerationInitLong, optInAccelerationLong, optInAccelerationMaxLong)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse, optInAccelerationInitLong, optInAccelerationLong, optInAccelerationMaxLong, optInAccelerationInitShort)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse, optInAccelerationInitLong, optInAccelerationLong, optInAccelerationMaxLong, optInAccelerationInitShort, optInAccelerationShort)
talib.SAREXT(inPriceHL, optInStartValue, optInOffsetOnReverse, optInAccelerationInitLong, optInAccelerationLong, optInAccelerationMaxLong, optInAccelerationInitShort, optInAccelerationShort, optInAccelerationMaxShort)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.SAREXT(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.SAREXT(records.High, records.Low)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.SAREXT(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHL |
| Yes | The |
optInStartValue | number | No | The |
optInOffsetOnReverse | number | No | The |
optInAccelerationInitLong | number | No | The |
optInAccelerationLong | number | No | The |
optInAccelerationMaxLong | number | No | The |
optInAccelerationInitShort | number | No | The |
optInAccelerationShort | number | No | The |
optInAccelerationMaxShort | number | No | The |
Remarks
The SAREXT() function is described in the talib library documentation as: SAREXT(Records[High,Low],Start Value = 0,Offset on Reverse = 0,AF Init Long = 0.02,AF Long = 0.02,AF Max Long = 0.2,AF Init Short = 0.02,AF Short = 0.02,AF Max Short = 0.2) = Array(outReal)
talib.SMA
The talib.SMA() function is used to calculate Simple Moving Average.
talib.SMA(inReal)
talib.SMA(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.SMA(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.SMA(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.SMA(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The SMA() function is described in the talib library documentation as: SMA(Records[Close],Time Period = 30) = Array(outReal)
talib.T3
The talib.T3() function is used to calculate Triple Exponential Moving Average (T3).
talib.T3(inReal)
talib.T3(inReal, optInTimePeriod)
talib.T3(inReal, optInTimePeriod, optInVFactor)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.T3(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.T3(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.T3(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
optInVFactor | number | No | The |
Remarks
The T3() function is described in the talib library documentation as: T3(Records[Close],Time Period = 5,Volume Factor = 0.7) = Array(outReal)
talib.TEMA
The talib.TEMA() function is used to calculate Triple Exponential Moving Average.
talib.TEMA(inReal)
talib.TEMA(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.TEMA(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.TEMA(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.TEMA(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The TEMA() function is described in the talib library documentation as: TEMA(Records[Close],Time Period = 30) = Array(outReal)
talib.TRIMA
The talib.TRIMA() function is used to calculate Triangular Moving Average.
talib.TRIMA(inReal)
talib.TRIMA(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.TRIMA(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.TRIMA(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.TRIMA(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The TRIMA() function is described in the talib library documentation as: TRIMA(Records[Close],Time Period = 30) = Array(outReal)
talib.WMA
The talib.WMA() function is used to calculate Weighted Moving Average.
talib.WMA(inReal)
talib.WMA(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.WMA(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.WMA(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.WMA(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The WMA() function is described in the talib library documentation as: WMA(Records[Close],Time Period = 30) = Array(outReal)
talib.LINEARREG
The talib.LINEARREG() function is used to calculate the Linear Regression indicator.
talib.LINEARREG(inReal)
talib.LINEARREG(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.LINEARREG(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.LINEARREG(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.LINEARREG(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The LINEARREG() function is described in the talib library documentation as: LINEARREG(Records[Close],Time Period = 14) = Array(outReal)
talib.LINEARREG_ANGLE
The talib.LINEARREG_ANGLE() function is used to calculate Linear Regression Angle.
talib.LINEARREG_ANGLE(inReal)
talib.LINEARREG_ANGLE(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.LINEARREG_ANGLE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.LINEARREG_ANGLE(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.LINEARREG_ANGLE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The LINEARREG_ANGLE() function is described in the talib library documentation as: LINEARREG_ANGLE(Records[Close],Time Period = 14) = Array(outReal)
talib.LINEARREG_INTERCEPT
The talib.LINEARREG_INTERCEPT() function is used to calculate the Linear Regression Intercept.
talib.LINEARREG_INTERCEPT(inReal)
talib.LINEARREG_INTERCEPT(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.LINEARREG_INTERCEPT(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.LINEARREG_INTERCEPT(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.LINEARREG_INTERCEPT(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The LINEARREG_INTERCEPT() function is described in the talib library documentation as: LINEARREG_INTERCEPT(Records[Close],Time Period = 14) = Array(outReal)
talib.LINEARREG_SLOPE
The talib.LINEARREG_SLOPE() function is used to calculate Linear Regression Slope.
talib.LINEARREG_SLOPE(inReal)
talib.LINEARREG_SLOPE(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.LINEARREG_SLOPE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.LINEARREG_SLOPE(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.LINEARREG_SLOPE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The LINEARREG_SLOPE() function is described in the talib library documentation as: LINEARREG_SLOPE(Records[Close],Time Period = 14) = Array(outReal)
talib.STDDEV
The talib.STDDEV() function is used to calculate Standard Deviation.
talib.STDDEV(inReal)
talib.STDDEV(inReal, optInTimePeriod)
talib.STDDEV(inReal, optInTimePeriod, optInNbDev)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.STDDEV(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.STDDEV(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.STDDEV(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
optInNbDev | number | No | The |
Remarks
The STDDEV() function is described in the talib library documentation as: STDDEV(Records[Close],Time Period = 5,Deviations = 1) = Array(outReal)
talib.TSF
The talib.TSF() function is used to calculate Time Series Forecast.
talib.TSF(inReal)
talib.TSF(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.TSF(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.TSF(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.TSF(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The TSF() function is described in the talib library documentation as: TSF(Records[Close],Time Period = 14) = Array(outReal)
talib.VAR
The talib.VAR() function is used to calculate Variance.
talib.VAR(inReal)
talib.VAR(inReal, optInTimePeriod)
talib.VAR(inReal, optInTimePeriod, optInNbDev)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.VAR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.VAR(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.VAR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
optInNbDev | number | No | The |
Remarks
The VAR() function is described in the talib library documentation as: VAR(Records[Close],Time Period = 5,Deviations = 1) = Array(outReal)
talib.ADX
The talib.ADX() function is used to calculate the Average Directional Movement Index.
talib.ADX(inPriceHLC)
talib.ADX(inPriceHLC, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.ADX(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.ADX(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ADX(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The ADX() function is described in the talib library documentation as: ADX(Records[High,Low,Close],Time Period = 14) = Array(outReal)
talib.ADXR
The talib.ADXR() function is used to calculate the Average Directional Movement Index Rating.
talib.ADXR(inPriceHLC)
talib.ADXR(inPriceHLC, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.ADXR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.ADXR(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ADXR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The ADXR() function is described in the talib library documentation as: ADXR(Records[High,Low,Close],Time Period = 14) = Array(outReal)
talib.APO
The talib.APO() function is used to calculate Absolute Price Oscillator.
talib.APO(inReal)
talib.APO(inReal, optInFastPeriod)
talib.APO(inReal, optInFastPeriod, optInSlowPeriod)
talib.APO(inReal, optInFastPeriod, optInSlowPeriod, optInMAType)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.APO(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.APO(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.APO(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInFastPeriod | number | No | The |
optInSlowPeriod | number | No | The |
optInMAType | number | No | The |
Remarks
The APO() function is described in the talib library documentation as: APO(Records[Close],Fast Period = 12,Slow Period = 26,MA Type = 0) = Array(outReal)
talib.AROON
The talib.AROON() function is used to calculate Aroon (Aroon Indicator).
talib.AROON(inPriceHL)
talib.AROON(inPriceHL, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.AROON(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.AROON(records.High, records.Low)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.AROON(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHL |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The AROON() function is described in the talib library documentation as: AROON(Records[High,Low],Time Period = 14) = [Array(outAroonDown),Array(outAroonUp)]
talib.AROONOSC
The talib.AROONOSC() function is used to calculate the Aroon Oscillator.
talib.AROONOSC(inPriceHL)
talib.AROONOSC(inPriceHL, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.AROONOSC(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.AROONOSC(records.High, records.Low)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.AROONOSC(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHL |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The AROONOSC() function is described in the talib library documentation as: AROONOSC(Records[High,Low],Time Period = 14) = Array(outReal)
talib.BOP
The talib.BOP() function is used to calculate Balance Of Power.
talib.BOP(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.BOP(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.BOP(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.BOP(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The BOP() function is described in the talib library documentation as: BOP(Records[Open,High,Low,Close]) = Array(outReal)
talib.CCI
The talib.CCI() function is used to calculate the Commodity Channel Index.
talib.CCI(inPriceHLC)
talib.CCI(inPriceHLC, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CCI(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CCI(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CCI(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The CCI() function is described in the talib library documentation as: CCI(Records[High,Low,Close],Time Period = 14) = Array(outReal)
talib.CMO
The talib.CMO() function is used to calculate the Chande Momentum Oscillator.
talib.CMO(inReal)
talib.CMO(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.CMO(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.CMO(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CMO(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The CMO() function is described in the talib library documentation as: CMO(Records[Close],Time Period = 14) = Array(outReal)
talib.DX
The talib.DX() function is used to calculate the Directional Movement Index.
talib.DX(inPriceHLC)
talib.DX(inPriceHLC, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.DX(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.DX(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.DX(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The DX() function is described in the talib library documentation as: DX(Records[High,Low,Close],Time Period = 14) = Array(outReal)
talib.MACD
The talib.MACD() function is used to calculate Moving Average Convergence/Divergence.
talib.MACD(inReal)
talib.MACD(inReal, optInFastPeriod)
talib.MACD(inReal, optInFastPeriod, optInSlowPeriod)
talib.MACD(inReal, optInFastPeriod, optInSlowPeriod, optInSignalPeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MACD(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MACD(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MACD(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInFastPeriod | number | No | The |
optInSlowPeriod | number | No | The |
optInSignalPeriod | number | No | The |
Remarks
The MACD() function is described in the talib library documentation as: MACD(Records[Close],Fast Period = 12,Slow Period = 26,Signal Period = 9) = [Array(outMACD),Array(outMACDSignal),Array(outMACDHist)]
talib.MACDEXT
The talib.MACDEXT() function is used to calculate MACD with controllable MA type.
talib.MACDEXT(inReal)
talib.MACDEXT(inReal, optInFastPeriod)
talib.MACDEXT(inReal, optInFastPeriod, optInFastMAType)
talib.MACDEXT(inReal, optInFastPeriod, optInFastMAType, optInSlowPeriod)
talib.MACDEXT(inReal, optInFastPeriod, optInFastMAType, optInSlowPeriod, optInSlowMAType)
talib.MACDEXT(inReal, optInFastPeriod, optInFastMAType, optInSlowPeriod, optInSlowMAType, optInSignalPeriod)
talib.MACDEXT(inReal, optInFastPeriod, optInFastMAType, optInSlowPeriod, optInSlowMAType, optInSignalPeriod, optInSignalMAType)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MACDEXT(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MACDEXT(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MACDEXT(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInFastPeriod | number | No | The |
optInFastMAType | number | No | The |
optInSlowPeriod | number | No | The |
optInSlowMAType | number | No | The |
optInSignalPeriod | number | No | The |
optInSignalMAType | number | No | The |
Remarks
The MACDEXT() function is described in the talib library documentation as: MACDEXT(Records[Close],Fast Period = 12,Fast MA = 0,Slow Period = 26,Slow MA = 0,Signal Period = 9,Signal MA = 0) = [Array(outMACD),Array(outMACDSignal),Array(outMACDHist)]
talib.MACDFIX
The talib.MACDFIX() function is used to calculate Moving Average Convergence/Divergence Fix 12/26.
talib.MACDFIX(inReal)
talib.MACDFIX(inReal, optInSignalPeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MACDFIX(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MACDFIX(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MACDFIX(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInSignalPeriod | number | No | The |
Remarks
The MACDFIX() function is described in the talib library documentation as: MACDFIX(Records[Close],Signal Period = 9) = [Array(outMACD),Array(outMACDSignal),Array(outMACDHist)]
talib.MFI
The talib.MFI() function is used to calculate Money Flow Index.
talib.MFI(inPriceHLCV)
talib.MFI(inPriceHLCV, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MFI(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MFI(records.High, records.Low, records.Close, records.Volume)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MFI(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLCV |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The MFI() function is described in the talib library documentation as: MFI(Records[High,Low,Close,Volume],Time Period = 14) = Array(outReal)
talib.MINUS_DI
The talib.MINUS_DI() function is used to calculate the Minus Directional Indicator.
talib.MINUS_DI(inPriceHLC)
talib.MINUS_DI(inPriceHLC, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MINUS_DI(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MINUS_DI(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MINUS_DI(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The MINUS_DI() function is described in the talib library documentation as: MINUS_DI(Records[High,Low,Close],Time Period = 14) = Array(outReal)
talib.MINUS_DM
The talib.MINUS_DM() function is used to calculate Minus Directional Movement.
talib.MINUS_DM(inPriceHL)
talib.MINUS_DM(inPriceHL, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MINUS_DM(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MINUS_DM(records.High, records.Low)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MINUS_DM(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHL |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The MINUS_DM() function is described in the talib library documentation as: MINUS_DM(Records[High,Low],Time Period = 14) = Array(outReal)
talib.MOM
The talib.MOM() function is used to calculate Momentum (Momentum Indicator).
talib.MOM(inReal)
talib.MOM(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MOM(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MOM(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MOM(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The MOM() function is described in the talib library documentation as: MOM(Records[Close],Time Period = 10) = Array(outReal)
talib.PLUS_DI
The talib.PLUS_DI() function is used to calculate the Plus Directional Indicator.
talib.PLUS_DI(inPriceHLC)
talib.PLUS_DI(inPriceHLC, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.PLUS_DI(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.PLUS_DI(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.PLUS_DI(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The PLUS_DI() function is described in the talib library documentation as: PLUS_DI(Records[High,Low,Close],Time Period = 14) = Array(outReal)
talib.PLUS_DM
The talib.PLUS_DM() function is used to calculate Plus Directional Movement.
talib.PLUS_DM(inPriceHL)
talib.PLUS_DM(inPriceHL, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.PLUS_DM(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.PLUS_DM(records.High, records.Low)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.PLUS_DM(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHL |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The PLUS_DM() function is described in the talib library documentation as: PLUS_DM(Records[High,Low],Time Period = 14) = Array(outReal)
talib.PPO
The talib.PPO() function is used to calculate Percentage Price Oscillator.
talib.PPO(inReal)
talib.PPO(inReal, optInFastPeriod)
talib.PPO(inReal, optInFastPeriod, optInSlowPeriod)
talib.PPO(inReal, optInFastPeriod, optInSlowPeriod, optInMAType)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.PPO(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.PPO(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.PPO(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInFastPeriod | number | No | The |
optInSlowPeriod | number | No | The |
optInMAType | number | No | The |
Remarks
The PPO() function is described in the talib library documentation as: PPO(Records[Close],Fast Period = 12,Slow Period = 26,MA Type = 0) = Array(outReal)
talib.ROC
The talib.ROC() function is used to calculate the *Rate of Change indicator: ((price/prevPrice)-1)100.
talib.ROC(inReal)
talib.ROC(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.ROC(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.ROC(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ROC(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The ROC() function is described in the talib library documentation as: ROC(Records[Close],Time Period = 10) = Array(outReal)
talib.ROCP
The talib.ROCP() function is used to calculate Rate of change Percentage: (price-prevPrice)/prevPrice.
talib.ROCP(inReal)
talib.ROCP(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.ROCP(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.ROCP(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ROCP(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The ROCP() function is described in the talib library documentation as: ROCP(Records[Close],Time Period = 10) = Array(outReal)
talib.ROCR
The talib.ROCR() function is used to calculate Rate of change ratio: (price/prevPrice).
talib.ROCR(inReal)
talib.ROCR(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.ROCR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.ROCR(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ROCR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The ROCR() function is described in the talib library documentation as: ROCR(Records[Close],Time Period = 10) = Array(outReal)
talib.ROCR100
The talib.ROCR100() function is used to calculate *Rate of change ratio 100 scale: (price/prevPrice)100.
talib.ROCR100(inReal)
talib.ROCR100(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.ROCR100(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.ROCR100(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ROCR100(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The ROCR100() function is described in the talib library documentation as: ROCR100(Records[Close],Time Period = 10) = Array(outReal)
talib.RSI
The talib.RSI() function is used to calculate the Relative Strength Index.
talib.RSI(inReal)
talib.RSI(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.RSI(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.RSI(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.RSI(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The RSI() function is described in the talib library documentation as: RSI(Records[Close],Time Period = 14) = Array(outReal)
talib.STOCH
The talib.STOCH() function is used to calculate the Stochastic Oscillator (STOCH indicator).
talib.STOCH(inPriceHLC)
talib.STOCH(inPriceHLC, optInFastK_Period)
talib.STOCH(inPriceHLC, optInFastK_Period, optInSlowK_Period)
talib.STOCH(inPriceHLC, optInFastK_Period, optInSlowK_Period, optInSlowK_MAType)
talib.STOCH(inPriceHLC, optInFastK_Period, optInSlowK_Period, optInSlowK_MAType, optInSlowD_Period)
talib.STOCH(inPriceHLC, optInFastK_Period, optInSlowK_Period, optInSlowK_MAType, optInSlowD_Period, optInSlowD_MAType)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.STOCH(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.STOCH(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.STOCH(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInFastK_Period | number | No | The |
optInSlowK_Period | number | No | The |
optInSlowK_MAType | number | No | The |
optInSlowD_Period | number | No | The |
optInSlowD_MAType | number | No | The |
Remarks
The STOCH() function is described in the talib library documentation as: STOCH(Records[High,Low,Close],Fast-K Period = 5,Slow-K Period = 3,Slow-K MA = 0,Slow-D Period = 3,Slow-D MA = 0) = [Array(outSlowK),Array(outSlowD)]
talib.STOCHF
The talib.STOCHF() function is used to calculate Stochastic Fast.
talib.STOCHF(inPriceHLC)
talib.STOCHF(inPriceHLC, optInFastK_Period)
talib.STOCHF(inPriceHLC, optInFastK_Period, optInFastD_Period)
talib.STOCHF(inPriceHLC, optInFastK_Period, optInFastD_Period, optInFastD_MAType)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.STOCHF(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.STOCHF(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.STOCHF(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInFastK_Period | number | No | The |
optInFastD_Period | number | No | The |
optInFastD_MAType | number | No | The |
Remarks
The STOCHF() function is described in the talib library documentation as: STOCHF(Records[High,Low,Close],Fast-K Period = 5,Fast-D Period = 3,Fast-D MA = 0) = [Array(outFastK),Array(outFastD)]
talib.STOCHRSI
The talib.STOCHRSI() function is used to calculate the Stochastic Relative Strength Index.
talib.STOCHRSI(inReal)
talib.STOCHRSI(inReal, optInTimePeriod)
talib.STOCHRSI(inReal, optInTimePeriod, optInFastK_Period)
talib.STOCHRSI(inReal, optInTimePeriod, optInFastK_Period, optInFastD_Period)
talib.STOCHRSI(inReal, optInTimePeriod, optInFastK_Period, optInFastD_Period, optInFastD_MAType)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.STOCHRSI(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.STOCHRSI(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.STOCHRSI(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
optInFastK_Period | number | No | The |
optInFastD_Period | number | No | The |
optInFastD_MAType | number | No | The |
Remarks
The STOCHRSI() function is described in the talib library documentation as: STOCHRSI(Records[Close],Time Period = 14,Fast-K Period = 5,Fast-D Period = 3,Fast-D MA = 0) = [Array(outFastK),Array(outFastD)]
talib.TRIX
The talib.TRIX() function is used to calculate 1-day Rate-Of-Change (ROC) of a Triple Smooth EMA.
talib.TRIX(inReal)
talib.TRIX(inReal, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.TRIX(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.TRIX(records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.TRIX(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The TRIX() function is described in the talib library documentation as: TRIX(Records[Close],Time Period = 30) = Array(outReal)
talib.ULTOSC
The talib.ULTOSC() function is used to calculate the Ultimate Oscillator.
talib.ULTOSC(inPriceHLC)
talib.ULTOSC(inPriceHLC, optInTimePeriod1)
talib.ULTOSC(inPriceHLC, optInTimePeriod1, optInTimePeriod2)
talib.ULTOSC(inPriceHLC, optInTimePeriod1, optInTimePeriod2, optInTimePeriod3)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.ULTOSC(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.ULTOSC(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ULTOSC(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInTimePeriod1 | number | No | The |
optInTimePeriod2 | number | No | The |
optInTimePeriod3 | number | No | The |
Remarks
The ULTOSC() function is described in the talib library documentation as: ULTOSC(Records[High,Low,Close],First Period = 7,Second Period = 14,Third Period = 28) = Array(outReal)
talib.WILLR
The talib.WILLR() function is used to calculate Williams' %R (Williams Percent Range).
talib.WILLR(inPriceHLC)
talib.WILLR(inPriceHLC, optInTimePeriod)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.WILLR(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.WILLR(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.WILLR(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInTimePeriod | number | No | The |
Remarks
The WILLR() function is described in the talib library documentation as: WILLR(Records[High,Low,Close],Time Period = 14) = Array(outReal)
talib.AVGPRICE
The talib.AVGPRICE() function is used to calculate Average Price.
talib.AVGPRICE(inPriceOHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.AVGPRICE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.AVGPRICE(records.Open, records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.AVGPRICE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceOHLC |
| Yes | The |
Remarks
The AVGPRICE() function is described in the talib library documentation as: AVGPRICE(Records[Open,High,Low,Close]) = Array(outReal)
talib.MEDPRICE
The talib.MEDPRICE() function is used to calculate Median Price.
talib.MEDPRICE(inPriceHL)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.MEDPRICE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.MEDPRICE(records.High, records.Low)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MEDPRICE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHL |
| Yes | The |
Remarks
The MEDPRICE() function is described in the talib library documentation as: MEDPRICE(Records[High,Low]) = Array(outReal)
talib.TYPPRICE
The talib.TYPPRICE() function is used to calculate Typical Price.
talib.TYPPRICE(inPriceHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.TYPPRICE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.TYPPRICE(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.TYPPRICE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
Remarks
The TYPPRICE() function is described in the talib library documentation as: TYPPRICE(Records[High,Low,Close]) = Array(outReal)
talib.WCLPRICE
The talib.WCLPRICE() function is used to calculate Weighted Close Price.
talib.WCLPRICE(inPriceHLC)Examples
javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.WCLPRICE(records)
Log(ret)
}
python
import talib
def main():
records = exchange.GetRecords()
ret = talib.WCLPRICE(records.High, records.Low, records.Close)
Log(ret)
c++
void main() {
auto records = exchange.GetRecords();
auto ret = talib.WCLPRICE(records);
Log(ret);
}Returns
| Type | Description |
array | The |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
Remarks
The WCLPRICE() function is described in the talib library documentation as: WCLPRICE(Records[High,Low,Close]) = Array(outReal)
OS
FMZ Quant Trading Platform supports file read/write operations. The os library provides a complete file system operation interface to help users with data persistence, configuration management, and logging during strategy development.
Note that this feature only supports JavaScript language strategies.
The os library supports: File objects, File list objects, and File information objects.
| Object | Description | Notes |
|---|---|---|
| File Object: File | Provides file read/write, positioning and other operations. | Obtained through os.open(), need to call close() to release resources after use. |
| File List Object: ListFilesResult | Used to record directory listing information. | Supports wildcard matching patterns, returned by os.listFiles() function. |
| File Information Object: FileStat | File statistics information. | Returned by os.stat() function. |
Supports live trading and backtesting systems.
- Live trading environment:
The default directory for live trading is thefilesfolder at the same level as the live trading database file in the docker directory, i.e.:/logs/storage/xxx/files, wherexxxis the live trading ID, and the docker program (robot) is at the same level aslogs. - Backtesting system environment:
The backtesting system is a sandbox environment. The system simulates a file directory with the default directory:/logs/storage/1/files.
When backtesting ends, the created file contents will be cleared.
os
The os library provides a complete file system operation interface for the FMZ Quant Trading Platform.
open
Open a file in the specified mode.
open(filename)
open(filename, mode)Examples
Create a file, write data, then read it.
javascript
function main() {
let fileHandle = os.open("output.txt", "w+")
if (!fileHandle) {
Log("Failed to open file")
return
}
let bytesWritten = fileHandle.write("Hello FMZ!")
Log("Bytes written:", bytesWritten) // Bytes written: 10
fileHandle.seek(0, 0)
let fileContent = fileHandle.read()
Log("File content read:", fileContent) // File content read: Hello FMZ!
fileHandle.close()
}Returns
| Type | Description |
| The |
Arguments
| Name | Type | Required | Description |
filename | string | Yes | File name. The parameter |
mode | string | No | Specify the file opening mode. |
See Also
File ListFilesResult FileStat open fgets fputs mmap getRootDir listFiles exists remove mkdir rmdir rename stat exit
Remarks
File opening modes:
-
r: read (read-only, file must exist) -
w: write (write-only, creates file if it doesn't exist, clears content if it exists) -
a: append (append write, creates file if it doesn't exist, writes to the end if it exists) -
+: Adding + after r/w/a means both read and write are allowed (e.g., "r+", "w+", "a+") -
b: binary (binary mode, commonly used in Windows to distinguish text/binary files, e.g., "rb", "wb")
Files are opened/created in the files folder under the live trading database file directory (xxx.db3, where xxx is the live trading Id).
fgets
Read the entire file content at once.
fgets(filename)Examples
Read the content of a configuration file.
javascript
function main() {
// 先创建、写入文件
// let fileHandle = os.open("config.json", "w+")
// if (!fileHandle) {
// Log("Failed to open file")
// return
// }
// let objJson = {"name": "tom", "age": 18}
// fileHandle.write(JSON.stringify(objJson))
// fileHandle.close()
let content = os.fgets("config.json")
Log("Config content:", content) // Config content: {"name":"tom","age":18}
}Returns
| Type | Description |
string | Returns the complete content of the file. |
Arguments
| Name | Type | Required | Description |
filename | string | Yes | File path, including the filename to be read. |
See Also
File ListFilesResult FileStat open fgets fputs mmap getRootDir listFiles exists remove mkdir rmdir rename stat exit
Remarks
Suitable for quick reading of small files, loading the entire file content into memory at once.
If the file does not exist, the fgets() function will throw an error: InternalError: failed to open file: openat config.json: no such file or directory at main.
fputs
Write content to a file.
fputs(filename, content)
fputs(filename, content, append)Examples
Save strategy configuration to file.
javascript
function main() {
let config = '{"strategy": "MA", "period": 20}'
let bytesWritten = os.fputs("strategy_config.json", config)
Log("Bytes written:", bytesWritten) // Bytes written: 32
Log(`os.fgets("strategy_config.json"):`, os.fgets("strategy_config.json")) // os.fgets("strategy_config.json"): {"strategy": "MA", "period": 20}
// 追加日志信息
let logInfo = "\n[" + new Date().toISOString() + "] Config saved"
os.fputs("strategy_config.json", logInfo, true)
Log(`os.fgets("strategy_config.json"):`, os.fgets("strategy_config.json")) // os.fgets("strategy_config.json"): {"strategy": "MA", "period": 20} [2025-09-08T07:20:30.563Z] Config saved
}Returns
| Type | Description |
number | Returns the actual number of bytes written. |
Arguments
| Name | Type | Required | Description |
filename | string | Yes | File path. |
content | string | Yes | Content to write. |
append | bool | No | Whether to write in append mode, defaults to false (overwrite mode). |
See Also
File ListFilesResult FileStat open fgets fputs mmap getRootDir listFiles exists remove mkdir rmdir rename stat exit
Remarks
Convenient file writing method, overwrites file content by default. Set append to true to append to the end of the file.
mmap
Memory-mapped file, returns the binary data of the file.
mmap(filename)Examples
Map the binary data of a file.
javascript
function ab2str(buf) {
let arr = new Uint8Array(buf)
return String.fromCharCode.apply(null, arr)
}
function main() {
let buffer = os.mmap("strategyConfig/testData.txt")
Log("File size in bytes:", buffer.byteLength)
let arr = Array.from(new Uint8Array(buffer))
Log("arr:", arr) // arr: [72,101,108,108,111,32,70,77,90,33]
Log("ab2str(buffer):", ab2str(buffer)) // ab2str(buffer): Hello FMZ!
}Returns
| Type | Description |
ArrayBuffer | Returns the binary data of the file content. |
Arguments
| Name | Type | Required | Description |
filename | string | Yes | File path. |
See Also
File ListFilesResult FileStat open fgets fputs mmap getRootDir listFiles exists remove mkdir rmdir rename stat exit
Remarks
Suitable for efficient reading and processing of large files, maps the file into memory and returns it as an ArrayBuffer.
getRootDir
Get the root directory path for file operations.
getRootDir()Examples
Get and display the root directory path.
javascript
function main() {
let rootDir = os.getRootDir()
Log("Root directory:", rootDir)
}Returns
| Type | Description |
string | Returns the path of the root directory. |
See Also
listFiles
List files and subdirectories in the specified directory.
listFiles()
listFiles(pattern)Examples
List matched files and directories.
javascript
function main() {
// 列出所有json文件
let result = os.listFiles("*.json")
Log("result:", result)
// 列出所有内容
let allFiles = os.listFiles()
Log("allFiles:", allFiles)
}Returns
| Type | Description |
ListFilesResult object | Returns an object containing - files: Array of matched file names. - dirs: Array of subdirectory names in the current directory. |
Arguments
| Name | Type | Required | Description |
pattern | string | No | Optional matching pattern, supports wildcards (e.g., .txt, data_.json), can specify directory path. |
See Also
File ListFilesResult FileStat open fgets fputs mmap getRootDir listFiles exists remove mkdir rmdir rename stat exit
Remarks
When pattern parameter is not specified, lists all files and subdirectories in the current directory (../files).
exists
Check if the specified file or directory exists.
exists(filename)Examples
Check if a file or path exists.
javascript
function main() {
Log(`os.exists("./strategyConfig"):`, os.exists("./strategyConfig")) // os.exists("./strategyConfig"): true
Log(`os.exists("./strategyConfig/testData.txt"):`, os.exists("./strategyConfig/testData.txt")) // os.exists("./strategyConfig/testData.txt"): true
// Log(`os.exists("/strategyConfig"):`, os.exists("/strategyConfig")) // InternalError: invalid filename: path traversal or absolute path not allowed at main
Log(`os.exists("test_1.txt"):`, os.exists("test_1.txt")) // os.exists("test_1.txt"): true
Log(`os.exists("test_2.txt"):`, os.exists("test_2.txt")) // os.exists("test_2.txt"): false
}Returns
| Type | Description |
bool | Returns true if the file or directory exists, otherwise returns false. |
Arguments
| Name | Type | Required | Description |
filename | string | Yes | The file or directory path to check. |
See Also
remove
Delete the specified file.
remove(filename)Examples
Example of deleting a file.
javascript
function main() {
let tempFile = "test_1.txt"
if (os.exists(tempFile)) {
let success = os.remove(tempFile)
Log("Temp file deleted:", success)
}
}Returns
| Type | Description |
bool | Returns true on successful deletion, false on failure. |
Arguments
| Name | Type | Required | Description |
filename | string | Yes | The file path to delete. |
See Also
File ListFilesResult FileStat open fgets fputs mmap getRootDir listFiles exists remove mkdir rmdir rename stat exit
Remarks
This function is only for deleting files, not for deleting directories. To delete directories, please use the rmdir() function.
mkdir
Create a directory.
mkdir(dirname)Examples
Create a data storage directory, create a file and write data.
javascript
function main() {
let success = os.mkdir("data/backtest/results")
Log("Directory created:", success)
if (success) {
os.fputs("data/backtest/results/summary.txt", "Backtest completed")
}
}Returns
| Type | Description |
bool | Returns true if creation is successful, otherwise returns false. |
Arguments
| Name | Type | Required | Description |
dirname | string | Yes | The directory path to create. |
See Also
File ListFilesResult FileStat open fgets fputs mmap getRootDir listFiles exists remove mkdir rmdir rename stat exit
Remarks
Supports recursive creation of multi-level directories. If parent directories do not exist, they will be created automatically.
rmdir
Remove a directory and all its contents.
rmdir(dirname)Examples
Remove a directory and all its contents.
javascript
function main() {
let tempDir = "data"
if (os.exists(tempDir)) {
let success = os.rmdir(tempDir)
Log("directory removed:", success)
}
}Returns
| Type | Description |
bool | Returns true on successful deletion, false on failure. |
Arguments
| Name | Type | Required | Description |
dirname | string | Yes | The directory path to be removed. |
See Also
File ListFilesResult FileStat open fgets fputs mmap getRootDir listFiles exists remove mkdir rmdir rename stat exit
Remarks
This operation will permanently delete the directory and all its contents, please use with caution.
rename
Rename or move a file.
rename(oldName, newName)Examples
Rename a file and move it to another directory.
javascript
function main() {
let oldFileName = "output.txt"
let newFileName = "outputFiles/" + new Date().getTime() + "output.txt"
// let retRename = os.rename(oldFileName, newFileName)
// Log("retRename:", retRename) // InternalError: failed to rename file: renameat output.txt outputFiles/1757322073139output.txt: no such file or directory at main
os.mkdir("outputFiles")
retRename = os.rename(oldFileName, newFileName)
Log("retRename:", retRename) // retRename: true
}Returns
| Type | Description |
bool | Returns true on success, false on failure. |
Arguments
| Name | Type | Required | Description |
oldName | string | Yes | Original file name or path. |
newName | string | Yes | New file name or path. |
See Also
File ListFilesResult FileStat open fgets fputs mmap getRootDir listFiles exists remove mkdir rmdir rename stat exit
Remarks
Can be used to rename files or move files to different directories. If the directory of the new path does not exist, the operation will fail.
stat
Get detailed statistics information of a file.
stat(filename)Examples
Get file information and check file size.
javascript
function main() {
if (os.exists("strategyConfig/testData.txt")) {
let stat = os.stat("strategyConfig/testData.txt") // stat: {"size":10,"mode":420,"mtime":1757312981796,"atime":1757312981796,"ctime":1757312981796}
Log("stat:", stat)
}
}Returns
| Type | Description |
FileStat object | Returns an object containing file statistics information. |
Arguments
| Name | Type | Required | Description |
filename | string | Yes | File path. |
See Also
File ListFilesResult FileStat open fgets fputs mmap getRootDir listFiles exists remove mkdir rmdir rename stat exit
Remarks
The returned FileStat object contains the following fields:
-
size: File size.
-
mode: File permissions.
-
mtime: Last modification time.
-
atime: Last access time.
-
ctime: Creation time.
exit
Exit the program.
exit()
exit(status)Examples
Exit program after checking conditions.
javascript
function main() {
if (!os.exists("required_config.json")) {
Log("Required configuration file not found!")
os.exit(1) // Abnormal exit
}
Log("Configuration found, continuing...")
// Normal strategy logic...
}Returns
| Type | Description |
never | This function does not return a value, the program will terminate execution directly. |
Arguments
| Name | Type | Required | Description |
status | number | No | Optional exit status code, default value is 0. |
See Also
File ListFilesResult FileStat open fgets fputs mmap getRootDir listFiles exists remove mkdir rmdir rename stat exit
Remarks
Immediately terminates program execution. Status code 0 indicates normal exit, non-zero values indicate abnormal exit (will be displayed as error in live trading).
File
File object that provides file read/write, positioning and other operations.
close
Close the file and release associated resources.
close()Examples
Example of proper file operation workflow.
javascript
function main() {
let file = os.open("data.txt", "w")
file.write("Hello FMZ!")
file.close() // 必须关闭文件
}See Also
Remarks
This method must be called after using the file object to release system resources.
puts
Write one or more strings to a file.
puts(data1, data2, ...dataN)Examples
Write multiple strings to a file.
javascript
function main() {
let file = os.open("output.txt", "w+")
let bytes = file.puts("Hello", " ", "World", "!")
Log("Bytes written:", bytes) // Bytes written: 12
file.seek(0, 0)
let data = file.read()
Log("data:", data) // If using os.open("output.txt", "w") may result in data being undefined
// data: Hello World!
// file.puts() // error: puts requires at least 1 argument at main
file.puts(", Hello FMZ!")
file.seek(0, 0)
data = file.read()
Log("data:", data) // data: Hello World!, Hello FMZ!
file.close()
}Returns
| Type | Description |
number | Returns the actual number of bytes written. |
Arguments
| Name | Type | Required | Description |
data | string | Yes | String data to be written, multiple parameters can be passed. |
See Also
Remarks
Multiple string parameters can be written at once, they will be concatenated in order and then written.
printf
Write formatted data to file.
printf(format)
printf(format, arg1, arg2, ...argN)Examples
Write formatted trading data.
javascript
function main() {
let file = os.open("trade_log.txt", "w+")
let price = 100.25
let volume = 1000
let bytes = file.printf("Price: %.2f, Volume: %d\n", price, volume)
Log("Formatted bytes written:", bytes)
file.seek(0, 0)
let data = file.read()
Log("data:", data) // data: Price: 100.25, Volume: 1000
// file.printf("| Price: %.2f, Volume: %d\n") // "| Price: %!f(MISSING), Volume: %!d(MISSING)"
// file.seek(0, 0)
// data = file.read()
// Log("data:", data)
file.close()
}Returns
| Type | Description |
number | Returns the actual number of bytes written. |
Arguments
| Name | Type | Required | Description |
format | string | Yes | Format string. |
args | any (any type supported by the platform) | No | Format arguments. |
See Also
flush
Flush the file buffer to ensure data is written to disk.
flush()Examples
Write important log data in real-time.
javascript
function main() {
let logFile = os.open("critical.log", "a")
logFile.printf("[%s] Critical event occurred\n", new Date().toISOString()) // [2025-09-09T03:15:43.895Z] Critical event occurred
logFile.flush() // Immediately write data to disk
// Continue with other operations...
logFile.close()
}See Also
tell
Get the current file pointer position.
tell()Examples
Track position during file operations.
javascript
function main() {
let file = os.open("data.txt", "r+")
Log("Initial position:", file.tell()) // Initial position: 0
file.write("Hello")
Log("After write position:", file.tell()) // After write position: 5
file.close()
}Returns
| Type | Description |
number | Returns the current file pointer position (offset in bytes). |
See Also
Remarks
Returns the byte offset of the current file pointer relative to the beginning of the file.
seek
Move the file pointer to a specified position.
seek(offset, whence)Examples
Read characters in reverse order.
javascript
function main() {
let str = "Hello FMZ!"
let file = os.open("data.txt", "w+")
file.write(str)
// If i > str.length: will throw InternalError: seek .../xxx/data.txt: invalid argument at main
for (let i = 1; i <= str.length; i++) {
file.seek(-i, 2)
let data = file.read(1)
Log("i:", i, ", data:", data)
}
file.close()
}Returns
| Type | Description |
number | Returns the new file pointer position. |
Arguments
| Name | Type | Required | Description |
offset | number | Yes | Offset (in bytes). |
whence | number | Yes | Reference position: 0=beginning of file, 1=current position, 2=end of file. |
See Also
Remarks
Used to position the file pointer, the offset parameter can be negative (indicating backward movement).
eof
Check if the file pointer has reached the end of file.
eof()Examples
Read file line by line until end of file.
javascript
function main() {
let file = os.open("data.txt", "r")
let lineCount = 0
while (!file.eof()) {
let line = file.getline()
if (line) {
lineCount++
Log("Line", lineCount + ":", line)
}
}
Log("Total lines:", lineCount)
file.close()
}Returns
| Type | Description |
bool | Returns true if end of file has been reached, otherwise returns false. |
See Also
Remarks
Used to determine whether all content has been read when reading a file.
read
Read data from a file.
read()
read(size)Examples
Read file content in chunks.
javascript
function main() {
let file = os.open("data.txt", "r")
// data.txt
// This is a test line: Line 1.
// This is a test line: Line 2.
// ...
let chunkSize = 29
let totalBytes = 0
while (!file.eof()) {
let chunk = file.read(chunkSize)
if (chunk) {
totalBytes += chunk.length || chunk.byteLength
Log("Read chunk, total bytes so far:", totalBytes, ", chunk:", chunk)
}
}
file.close()
}Returns
| Type | Description |
string / ArrayBuffer / undefined | Returns the content read. Returns |
Arguments
| Name | Type | Required | Description |
size | number | No | Number of bytes to read. If not specified, reads all remaining content in the file. |
See Also
Remarks
Can read a specified number of bytes or all remaining content in the file. The return type may be string or ArrayBuffer.
write
Write string data to a file.
write(data)Examples
Writing trade records
javascript
function main() {
let file = os.open("trades.log", "a")
let timestamp = new Date().toISOString()
let tradeInfo = `${timestamp},BUY,50000,1\n`
let bytes = file.write(tradeInfo)
Log("Trade record written, bytes:", bytes)
file.close()
}Returns
| Type | Description |
number | Returns the actual number of bytes written. |
Arguments
| Name | Type | Required | Description |
data | string | Yes | The string data to be written. |
See Also
Remarks
Writes string data to the current position in the file.
getline
Read the next line from the file.
getline()Examples
Read file line by line until the end.
javascript
function main() {
let file = os.open("data.txt", "r")
let lineCount = 0
while (!file.eof()) {
let line = file.getline()
if (line) {
lineCount++
Log("Line", lineCount + ":", line)
}
}
Log("Total lines:", lineCount)
file.close()
}Returns
| Type | Description |
string / undefined | Returns the next line content, returns |
See Also
Remarks
Read file content line by line in sequential order.
toString
Get the string representation of the file object.
toString()Examples
Get the description information of the file object.
javascript
function main() {
let file = os.open("data/data.txt", "r")
Log("File info:", file.toString()) // File info: File(data/data.txt)
file.close()
}Returns
| Type | Description |
string | Returns the string description information of the file object. |
See Also
Remarks
Returns the description information of the file object.
ListFilesResult
File list object used to record directory listing information. This object contains two array properties: files (file list) and dirs (directory list).
See Also
Remarks
ListFilesResult object structure:
javascript
{
files: string[], // Array of searched file names
dirs: string[] // Array of subdirectory names in the current directory
}
This object is returned by the os.listFiles() function.
FileStat
File statistics information object.
See Also
Remarks
FileStat object structure:
javascript
{
size: number, // File size (bytes)
mode: number, // File permission mode
mtime: number, // Modification time, millisecond timestamp
atime: number, // Access time, millisecond timestamp
ctime: number // Creation time, millisecond timestamp
}
This object is returned by the os.stat() function.