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())
rust
fn main() {
Log!("version:", Version());
}
c++
void main() {
Log("version:", Version());
}Returns
| Type | Description |
string | The current system version number, for example: |
Remarks
The system version number is the version number of the hosting program (docker/agent).
Sleep
The sleep function pauses program execution for a specified period of 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")
rust
fn main() {
Sleep(1000 * 10); // Wait for 10 seconds
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 the Sleep(1000) function, the program will sleep for 1 second. This function supports sleep operations of less than 1 millisecond, such as Sleep(0.1). The minimum supported parameter is 0.000001, i.e. nanosecond-level sleep, where 1 nanosecond equals 1e-6 milliseconds.
When writing strategies in Python, for operations such as polling intervals and time waiting, you should use the Sleep(millisecond) function rather than the time.sleep(second) function from Python's time library. This is because if a strategy uses the time.sleep(second) function during backtesting, it will cause the strategy program to actually wait for a period of time (instead of skipping ahead on the backtesting system's time series), resulting in very slow backtesting speed.
IsVirtual
Used to determine whether the strategy's runtime environment is the 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.")
rust
fn 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 | When the strategy runs in the backtesting system environment, it returns a truthy value, for example: |
Remarks
Used to determine whether the current runtime environment is the backtesting system, in order to accommodate the differences between the backtesting and live trading environments.
Send an 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")
rust
fn 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 a truthy value, such as |
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 | Used to specify the |
mailTo | string | Yes | Used to specify the email address of the email recipient. |
title | string | Yes | The email subject. |
body | string | Yes | The email body. |
See Also
Remarks
The smtpPassword parameter sets the password for the SMTP service, not the mailbox login password.
When setting the smtpServer parameter, if you need to change the port, you can append the port number directly in the smtpServer parameter. For example: the smtp.qq.com:587 port of QQ Mail has been tested and works.
If the error unencryped connection occurs, you need to modify the smtpServer parameter of the Mail function to the format ssl://xxx.com:xxx. For example, the ssl method for QQ Mail SMTP is ssl://smtp.qq.com:465, or use 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
Filters 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")rustfn 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 error messages from a specific interface.
javascriptfunction main() { // Query a non-existent order (id 123) to deliberately trigger an interface error var order = exchange.GetOrder("123") Log(order) // Filter http 502 errors and GetOrder interface errors; after setting the error filter, the second call to GetOrder will no longer 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)rustfn main() { // Query a non-existent order (id 123) to deliberately trigger an interface error let orderId = OrderId { S: "123".to_string(), ..Default::default() }; let order = exchange.GetOrder(&orderId); Log!(order); // Filter http 502 errors and GetOrder interface errors; after setting the error filter, the second call to GetOrder will no longer report an error SetErrorFilter("502:|GetOrder"); let order = exchange.GetOrder(&orderId); 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 | A regular expression string. |
Remarks
Error logs that match this regular expression will no longer be uploaded to the logging system. This function can be called multiple times (with no limit on the number of calls) to set multiple filter conditions; regular expressions set across multiple calls accumulate and take effect simultaneously. You can pass an empty string to reset the regular expression used to filter error logs: SetErrorFilter(""). Filtered logs will no longer be written to the database file corresponding to the live trading Id under the docker directory, thereby preventing the database file from bloating due to frequent errors.
GetPid
Get the ID of the live trading process.
GetPid()Examples
javascript
function main(){
var id = GetPid()
Log(id)
}
python
def main():
id = GetPid()
Log(id)
rust
fn main() {
let id = GetPid();
Log!(id);
}
c++
void main() {
auto id = GetPid();
Log(id);
}Returns
| Type | Description |
string | Returns the ID of the live trading process. |
GetLastError
Retrieves the most recent error message.
GetLastError()Examples
javascript
function main(){
// Since order number 123 does not exist, this will trigger an error
exchange.GetOrder("123")
var error = GetLastError()
Log(error)
}
python
def main():
exchange.GetOrder("123")
error = GetLastError()
Log(error)
rust
fn main() {
// Since order number 123 does not exist, this will trigger an error
// Rust's GetOrder accepts a &OrderId parameter; the string id must be placed in the S field
let id = OrderId { S: "123".to_string(), ..Default::default() };
let _ = exchange.GetOrder(&id);
let error = GetLastError();
Log!(error);
}
c++
void main() {
// The order ID is of type TId, so a string cannot be passed in; here we place an order that does not conform to the exchange's specifications to trigger an error
exchange.GetOrder(exchange.Buy(1, 1));
auto error = GetLastError();
Log(error);
}Returns
| Type | Description |
string | The most recent error message. |
Remarks
This function does not work in the backtesting system.
GetCommand
Get the strategy's interactive command.
GetCommand()Examples
-
Detect interactive commands, and when an interactive command is detected, use the
Logfunction to output it.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)rustfn main() { loop { // Rust's GetCommand() requires a timeout parameter (milliseconds) and returns Option<String>, which is None when there is no command if let Some(cmd) = GetCommand(0) { Log!(cmd); } Sleep(1000); } }c++void main() { while(true) { auto cmd = GetCommand(); if(cmd != "") { Log(cmd); } Sleep(1000); } } -
For example, in the strategy's interactive controls, add a control without an input box, name it
buy, with the control descriptionBuy; this is a button control. Then add a control with an input box, name itsell, with the control descriptionSell; this is an interactive control composed of a button and an input box. Write interactive code in the strategy to respond to the different interactive 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)rustfn main() { loop { LogStatus!(_D(None)); if let Some(cmd) = GetCommand(0) { Log!("cmd:", cmd); let arr: Vec<&str> = cmd.split(':').collect(); 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); } }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
This function is invalid in the backtesting system.
GetMeta
Get the Meta value written when generating the strategy registration code.
GetMeta()Examples
Application scenario example: Use Meta to limit the number of assets the strategy can operate.
javascript
function main() {
// The maximum asset value of the quote currency allowed by the strategy
var maxBaseCurrency = null
// Get the metadata when creating the registration code
var level = GetMeta()
// Check the condition 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 the asset value
var acc = exchange.GetAccount()
if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks) {
// Stop executing the strategy trading logic
LogStatus(_D(), "level:", level, "Position exceeds registration code limit, strategy trading logic will not execute!")
continue
}
// Other trading logic
// Normally output the status bar information
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
# Normally output the status bar information
LogStatus(_D(), "level:", level, "Strategy running normally! ticker data:\n", ticker)
rust
fn main() {
// The maximum asset value of the quote currency allowed by the strategy
let maxBaseCurrency;
// Get the metadata when creating the registration code, Rust's GetMeta() returns a JsonValue type
let meta = GetMeta();
let level = meta.as_str().unwrap_or("");
// Check the condition corresponding to Meta
if level == "level1" {
// -1 means no limit
maxBaseCurrency = -1.0;
} else if level == "level2" {
maxBaseCurrency = 10.0;
} else if level == "level3" {
maxBaseCurrency = 1.0;
} else {
maxBaseCurrency = 0.5;
}
loop {
Sleep(1000);
let ticker = exchange.GetTicker(None).unwrap();
// Check the asset value
let acc = exchange.GetAccount().unwrap();
if maxBaseCurrency != -1.0 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks {
// Stop executing the strategy trading logic
LogStatus!(_D(None), "level:", level, "Position exceeds registration code limit, strategy trading logic will not execute!");
continue;
}
// Other trading logic
// Normally output the status bar information
LogStatus!(_D(None), "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 the strategy trading logic
LogStatus(_D(), "level:", level, "Position exceeds registration code limit, strategy trading logic will not execute!");
continue;
}
// Other trading logic
// Normally output the status bar information
LogStatus(_D(), "level:", level, "Strategy running normally! ticker data:\n", ticker);
}
}Returns
| Type | Description |
string |
|
Remarks
Application scenario: You need to impose fund restrictions on different strategy lessees. The length of the Meta value set when generating the registration code cannot exceed 190 characters. The GetMeta() function is only supported in live trading and does not work in the backtesting system. If the metadata (Meta) is not set when generating the strategy registration code, the GetMeta() function will return an empty value.
Dial
Used for raw Socket access, supporting the tcp, udp, tls, and unix protocols. Supports 4 mainstream messaging protocols: mqtt, nats, amqp, and kafka. Also supports connecting to databases, with available databases including: sqlite3, mysql, postgres, and clickhouse.
Dial(address)
Dial(address, timeout)
Dial(address, options)Examples
-
Dial function call example:
javascriptfunction main(){ // Dial supports the tcp://, udp://, tls://, and unix:// protocols, and accepts a parameter specifying the timeout in seconds var client = Dial("tls://www.baidu.com:443") if (client) { // write can take an additional numeric parameter to specify a timeout, and returns the number of bytes successfully sent client.write("GET / HTTP/1.1\nConnection: Closed\n\n") while (true) { // read can take an additional numeric parameter to specify a timeout, in milliseconds; returning null indicates an error, timeout, or that the socket has been 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()rustfn main() { // Dial supports the tcp://, udp://, tls://, and unix:// protocols, and you can use Dial::new(addr, timeout) to specify the timeout in seconds let mut client = Dial("tls://www.baidu.com:443"); if client.Valid() { // The second numeric parameter of write is used to specify a timeout, and it returns the number of bytes successfully sent client.write("GET / HTTP/1.1\nConnection: Closed\n\n", 0); loop { // The numeric parameter of read is used to specify a timeout, in milliseconds; returning an empty string indicates an error, timeout, or that the socket has been closed let buf = client.read(0); if 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(); } } -
Access Binance's WebSocket market data interface:
javascriptfunction main() { LogStatus("Connecting...") // Access Binance's 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 received after read is called 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()rustfn main() { LogStatus!("Connecting..."); // Access Binance's WebSocket interface let mut client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr"); if !client.Valid() { Log!("Connection failed, exiting"); return; } loop { // read only returns data received after read is called let buf = client.read(0); if buf == "" { break; } let obj = JSONParse(&buf).unwrap(); // The Rust SDK has no JSON serialization; here we use string concatenation to build the JSON text for the status bar table let mut rows = String::new(); if let Some(arr) = obj.as_array() { for ticker in arr { if !rows.is_empty() { rows += ","; } rows += &format!(r#"["{}","{}","{}","{}","{}","{}","{}","{}"]"#, ticker["s"].as_str().unwrap_or(""), ticker["h"].as_str().unwrap_or(""), ticker["l"].as_str().unwrap_or(""), ticker["b"].as_str().unwrap_or(""), ticker["a"].as_str().unwrap_or(""), ticker["c"].as_str().unwrap_or(""), ticker["q"].as_str().unwrap_or(""), _D(ticker["E"].as_i64().unwrap_or(0))); } } let table = format!(r#"{{"type":"table","title":"Market Chart","cols":["Symbol","High","Low","Bid","Ask","Last Price","Volume","Update Time"],"rows":[{}]}}"#, rows); LogStatus!(format!("`{}`", 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 the 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)rustfn main() { // In Rust, use Dial::with_options() and pass options as a JSON string to set the request headers let options = r#"{"headers": {"X-MBX-APIKEY": "your access key"}}"#; let random = format!("fmz{}", UnixNano()); let ts = Unix() * 1000; let secretKey = "your secret key"; let topic = "com_announcement_en"; let payload = format!("random={}&topic={}&recvWindow=30000×tamp={}", random, topic, ts); let signature = Encode("sha256", "string", "hex", &payload, "string", secretKey); let query = format!("?{}&signature={}", payload, signature); Log!("query:", query); let mut conn = Dial::with_options(&format!("wss://api.binance.com/sapi/wss{}", query), options); for _i in 0..10 { let ret = conn.read(0); Log!(ret); } }c++// Not supported yet -
Access OKX's 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 enable reconnection mode, and specify payload as the message to be sent upon reconnection. When the WebSocket connection is disconnected, it will automatically reconnect and automatically send this 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")rustfn main() { let param = r#"{"op":"subscribe","args":[{"channel":"tickers","instId":"BTC-USDT"}]}"#; // When calling the Dial function, specify reconnect=true to enable reconnection mode, and specify payload as the message to be sent upon reconnection. When the WebSocket connection is disconnected, it will automatically reconnect and automatically send this message let mut ws = Dial(&format!("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload={}", param)); if ws.Valid() { let pingCyc = 1000 * 20; let mut lastPingTime = Unix() * 1000; loop { let nowTime = Unix() * 1000; let ret = ws.read(0); Log!("ret:", ret); if nowTime - lastPingTime > pingCyc { let retPing = ws.write("ping", 0); lastPingTime = nowTime; Log!("Sending: ping", "#FF0000"); } LogStatus!("Current time:", _D(None)); Sleep(1000); } } // In Rust, the connection object is automatically closed when it goes out of scope; you can also explicitly call ws.close() }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"); } -
Access the Huobi exchange'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 the 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 the 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()")rustfn main() { let param = r#"{"sub":"market.btcusdt.detail","id":"id1"}"#; let mut ws = Dial(&format!("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload={}", param)); if ws.Valid() { loop { let ret = ws.read(0); Log!("ret:", ret); // Respond to the heartbeat packet; in Rust use JSONParse() to parse, which returns None on parse failure if let Some(jsonRet) = JSONParse(&ret) { if jsonRet["ping"].is_number() { let strPong = format!(r#"{{"pong":{}}}"#, jsonRet["ping"].as_i64().unwrap_or(0)); ws.write(&strPong, 0); Log!("Responding to ping, sending pong:", strPong, "#FF0000"); } } LogStatus!("Current time:", _D(None)); Sleep(1000); } } // In Rust the connection object is automatically closed when it leaves scope; you can also explicitly call 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 the 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()") } -
Access OKX's WebSocket authentication interface:
javascriptfunction getLogin(pAccessKey, pSecretKey, pPassphrase) { // Signature function, used to generate the login request 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 has a timeout set, timeout errors need to be filtered, otherwise redundant error output will be produced SetErrorFilter("timeout") // Subscription information for the positions channel 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) // You cannot subscribe to private channels immediately after login; you need to wait for the 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) } // Reconnect after detecting a disconnection 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)rustfn getLogin(pAccessKey: &str, pSecretKey: &str, pPassphrase: &str) -> String { // Signature function, used to generate the login request. There is no exchange.Encode member function in Rust, so the global Encode function is used to compute the signature let ts = format!("{}", Unix()); let sign = Encode("sha256", "string", "base64", &format!("{}GET/users/self/verify", ts), "string", pSecretKey); format!(r#"{{"op":"login","args":[{{"apiKey":"{}","passphrase":"{}","timestamp":"{}","sign":"{}"}}]}}"#, pAccessKey, pPassphrase, ts, sign) } fn main() { // Since the read function has a timeout set, timeout errors need to be filtered, otherwise redundant error output will be produced SetErrorFilter("timeout"); // Subscription information for the positions channel let posSubscribe = r#"{"op":"subscribe","args":[{"channel":"positions","instType":"ANY"}]}"#; let accessKey = "xxx"; let secretKey = "xxx"; let passphrase = "xxx"; let mut client_private = Dial("wss://ws.okx.com:8443/ws/v5/private"); client_private.write(&getLogin(accessKey, secretKey, passphrase), 0); Sleep(3000); // You cannot subscribe to private channels immediately after login; you need to wait for the server response client_private.write(posSubscribe, 0); if client_private.Valid() { let mut lastPingTS = Unix() * 1000; loop { let buf = client_private.read(-1); if buf != "" { Log!(buf); } // Reconnect after detecting a disconnection if buf == "" && client_private.write(posSubscribe, 0) == 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), 0); Sleep(3000); client_private.write(posSubscribe, 0); } // Send heartbeat packet let nowPingTS = Unix() * 1000; if nowPingTS - lastPingTS > 10 * 1000 { client_private.write("ping", 0); lastPingTS = nowPingTS; } } } }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 push 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// Omittedrustfn main() { let accessKey = "your accessKey"; let ts = Unix() * 1000; // Rust does not have the exchange.Encode member function and cannot use the {{secretkey}} template substitution, so use the global Encode function to pass the secret key directly to compute the signature let signature = Encode("sha256", "string", "hex", &format!("{}", ts), "string", "your secretKey"); Log!("signature:", signature); // The Rust SDK does not have JSON serialization, so use string concatenation to construct the payload's JSON text let payload = format!(r#"{{"id":1,"method":"server.sign","params":{{"access_id":"{}","signed_str":"{}","timestamp":{}}}}}"#, accessKey, signature, ts); Log!("payload:", payload); let mut conn = Dial(&format!("wss://socket.coinex.com/v2/futures|compress=gzip&mode=recv&payload={}", payload)); if !conn.Valid() { Panic!("stop"); } Log!("Dial ... ", conn.read(0)); // Subscribe to position push conn.write(r#"{"method":"position.subscribe","params":{"market_list":["BTCUSDT"]},"id":1}"#, 0); loop { let msg = conn.read(0); if msg != "" { Log!("msg:", msg); } } }c++// Omitted -
The following example demonstrates how to access the
Websocketinterface of the MEXC exchange, subscribe to thepublic.aggre.deals.v3.api.pbchannel, and useprotobuf.jsto decode the 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 when the Dial function connects to a database has 2 unique methods:
-
exec(sqlString): Used to execute SQL statements, with usage similar to theDBExec()function.-
fd(): This function returns a handle (for example, a handle variable named handle), used for reconnecting in other threads. Even if the connection object created by Dial has already been closed via theclose()function, you can still pass this handle into theDial()function (for example,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 an 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 the 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 supportedrustfn main() { // let mut client = Dial("sqlite3://:memory:"); // Use an in-memory database let mut client = Dial("sqlite3://test1.db"); // Open/connect to the database file in the docker's directory // Rust's connection object does not support the fd() method // Query the tables in the database let ret = client.exec("SELECT name FROM sqlite_master WHERE type='table'"); Log!(format!("{:?}", ret)); Log!("Executing client.close()"); client.close(); }c++// Not supported
Returns
| Type | Description | ||||||||||||||||||||
object | If the call times out, the
For data pushed via the WebSocket protocol, if the time interval between two calls of the
|
Arguments
| Name | Type | Required | Description |
address | string | Yes | The request address. |
timeout | number | No | The timeout period (unit: seconds). |
options | object | No | Configuration options. |
Remarks
address parameter details: after the standard 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 instead. The portion after the separator specifies the functional parameter settings, with individual parameters joined by the & character.
For example, to set both an ss5 proxy and compression parameters at the same time, 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=value | compress specifies the compression method. Available values include gzip_raw, gzip, etc. If the gzip used is not standard gzip, you can use the extended form: gzip_raw |
| Parameters related to WebSocket protocol data compression: mode=value | mode specifies the compression mode, with three options: dual, send, and recv. dual indicates bidirectional compression, i.e., sending and receiving compressed data simultaneously; send indicates only sending compressed data; recv indicates only receiving compressed data and decompressing it locally. |
| Enable the WebSocket protocol compression setting: enableCompression=true | Use enableCompression=false to disable this setting. It is disabled by default. |
| Parameters for configuring underlying auto-reconnection of the WebSocket protocol: reconnect=value | reconnect sets whether to auto-reconnect. reconnect=true enables reconnection. If this parameter is not set, reconnection is disabled by default. |
| Parameters for configuring underlying auto-reconnection of the WebSocket protocol: interval=value | interval is the retry interval, in milliseconds. For example, interval=10000 means a retry interval of 10 seconds; when not set, it defaults to 1 second, i.e., interval=1000. |
| Parameters for configuring underlying auto-reconnection of the WebSocket protocol: payload=value | payload is the subscription message to be sent when the WebSocket reconnects, for example: payload=okok. |
| Parameters related to the socks5 proxy: proxy=value | proxy configures the ss5 proxy. The value format is: socks5://name:[email protected]:1080. Here name is the username of the ss5 server, pwd is the login password of the ss5 server, and 1080 is the port of the ss5 service. |
The Dial() function is only supported in live trading.
When using the Dial function to connect to a database, you can refer to the Go language driver project corresponding to each database for how to write the connection string.
| Supported databases | Driver project | Connection String | Notes |
|---|---|---|---|
| sqlite3 | github.com/mattn/go-sqlite3 | sqlite3://file:test.db?cache=shared&mode=memory | The sqlite3:// prefix indicates that the sqlite3 database is used. Example call: 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 how the Dial function parses the address parameter. See the example below.
Example of calling the backPack exchange websocket private interface:
javascript
var client = null
function main() {
// The 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 a base64 encoding, it may contain the character "="
var signature = signEd25519(data)
// After being JSON-encoded, payload may contain the character "="
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}}")
}
Using the following calling approach in the code works properly:
javascript
client = Dial("wss://ws.backpack.exchange")
client.write(JSON.stringify(payload))
If it is written directly into the payload (in the address), it will not work properly, for example:
javascript
client = Dial("wss://ws.backpack.exchange|payload=" +
JSON.stringify(payload))
Currently, only the JavaScript language supports using the mqtt, nats, amqp, and kafka communication protocols in the Dial function. The following uses JavaScript strategy code as an example to demonstrate how to use the four protocols mqtt, nats, amqp, and kafka:
javascript
// You need to first configure and deploy the proxy servers for each protocol
// For ease of demonstration, both subscribing to (read operation) and publishing to (write operation) the topic test_topic are performed within this current 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 a detailed introduction, please refer to the documentation: Exploring FMZ: Practices of Communication Protocols Between Live Trading Strategies
HttpQuery
Sends an HTTP request.
HttpQuery(url)
HttpQuery(url, options)Examples
-
An example of accessing the OKX public market data API interface.
javascriptfunction main(){ // An example of a GET request without parameters var info = JSON.parse(HttpQuery("https://www.okx.com/api/v5/public/time")) Log(info) // An example of a GET request with parameters 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 does not support Python; you can use the urllib/urllib2 library instead info = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/public/time").read().decode('utf-8')) Log(info) ticker = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/market/books?instId=BTC-USDT").read().decode('utf-8')) Log(ticker)rustfn main() { // An example of a GET request without parameters; in Rust, the return value type annotation determines whether the Body string (String) or the complete response (HttpRet) is returned let body: String = HttpQuery("https://www.okx.com/api/v5/public/time", None); let info = JSONParse(&body).unwrap(); Log!(info); // An example of a GET request with parameters let body2: String = HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT", None); let ticker = JSONParse(&body2).unwrap(); 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); } -
An example of using proxy settings with the HttpQuery function.
javascriptfunction main() { // This sets a proxy and sends an HTTP request, with no username and no password; this HTTP request will be sent through the proxy HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/") // This sets a proxy and sends an HTTP request, providing a username and password, effective only for the current call to HttpQuery; subsequent calls to HttpQuery("http://www.baidu.com") will not use the proxy HttpQuery("socks5://username:[email protected]:8889/http://www.baidu.com/") }python# HttpQuery does not support Python; you can use Python's urllib2 libraryrustfn main() { // This sets a proxy and sends an HTTP request, with no username and no password; this HTTP request will be sent through the proxy let ret1: String = HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/", None); // This sets a proxy and sends an HTTP request, providing a username and password, effective only for the current call to HttpQuery; subsequent calls to HttpQuery("http://www.baidu.com") will not use the proxy let ret2: String = HttpQuery("socks5://username:[email protected]:8889/http://www.baidu.com/", None); }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 | The URL of the HTTP request. |
options | object | No | Settings related to the HTTP request, for example the following structure:
All fields in this structure are optional; for example, the |
See Also
Remarks
The HttpQuery() function only supports the JavaScript and C++ languages; in Python, you can use the urllib library to send HTTP requests directly. HttpQuery() is mainly used to access exchange interfaces that do not require signing, 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, the number of times different URLs can be accessed is limited to 20, and HttpQuery() caches the accessed data; on the second access to the same URL, the HttpQuery() function returns the cached data instead of making 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 according to the parameters passed in.
Encode(algo, inputFormat, outputFormat, data)
Encode(algo, inputFormat, outputFormat, data, keyFormat, key)Examples
-
Example of calling the Encode function.
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")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84barustfn main() { // In Rust, all 6 parameters of the Encode() function are required; when not encrypting, simply pass empty strings for keyFormat and key 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 }c++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", which are used to encode and decode 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)rustfn main() { // In Rust, all 6 parameters of the Encode() function are required; when not encrypting, pass empty strings for keyFormat and key let ret1 = Encode("text.encoder.utf8", "raw", "hex", "你好", "", ""); // e4bda0e5a5bd Log!(ret1); let ret2 = Encode("text.decoder.utf8", "hex", "string", &ret1, "", ""); Log!(ret2); let ret3 = Encode("text.encoder.gbk", "raw", "hex", "你好", "", ""); // c4e3bac3 Log!(ret3); let 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 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 When the When the |
Remarks
The Encode() function is only supported in live trading. If the key and keyFormat parameters are not passed in, no key encryption is performed.
UnixNano
Get the nanosecond-level timestamp of the current moment.
UnixNano()Examples
If you need to get a millisecond-level timestamp, you can use the following code:
javascript
function main() {
var time = UnixNano() / 1000000
Log(_N(time, 0))
}
python
def main():
time = UnixNano()
Log(time)
rust
fn main() {
let time = UnixNano() / 1000000;
Log!(_N(time, 0));
}
c++
void main() {
auto time = UnixNano();
Log(time);
}Returns
| Type | Description |
number | The |
See Also
Unix
Get the second-level timestamp of the current moment.
Unix()Examples
javascript
function main() {
var t = Unix()
Log(t)
}
python
def main():
t = Unix()
Log(t)
rust
fn main() {
let t = Unix();
Log!(t);
}
c++
void main() {
auto t = Unix();
Log(t);
}Returns
| Type | Description |
number | Returns the second-level timestamp. |
See Also
GetOS
Retrieves the operating system information of the device hosting the bot.
GetOS()Examples
javascript
function main() {
Log("GetOS:", GetOS())
}
python
def main():
Log("GetOS:", GetOS())
rust
fn main() {
Log!("GetOS:", GetOS());
}
c++
void main() {
Log("GetOS:", GetOS());
}Returns
| Type | Description |
string | Operating system information. |
Remarks
For example, a bot running on the Mac OS operating system may return darwin/amd64 when calling the GetOS() function. Since Apple computers use various hardware architectures, the return value includes the specific architecture information. Here, darwin is the kernel name of the Mac OS system.
MD5
Calculate the MD5 hash of the parameter data.
MD5(data)Examples
javascript
function main() {
Log("MD5", MD5("hello world"))
}
python
def main():
Log("MD5", MD5("hello world"))
rust
fn main() {
Log!("MD5", MD5("hello world"));
}
c++
void main() {
Log("MD5", MD5("hello world"));
}Returns
| Type | Description |
string | The MD5 hash value. |
Arguments
| Name | Type | Required | Description |
data | string | Yes | The data on which to perform the MD5 calculation. |
See Also
Remarks
After calling the MD5("hello world") function, the return value is: 5eb63bbbe01eeed093cb22bb8f5acdc3.
DBExec
Database interface function.
DBExec(sql)Examples
-
Supports in-memory databases. For the parameter of the
DBExecfunction, if the sql statement begins with:, the operation is executed in the in-memory database; since there is no need to write to a file, it is faster. This approach is suitable for database operations that do not 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) // Add a record Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);")) // Query data Log(DBExec(":SELECT * FROM TEST_TABLE;")) }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) # Add a record Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);")) # Query data Log(DBExec(":SELECT * FROM TEST_TABLE;"))rustfn main() { let 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)", ]; let strSql = arr.join(""); let ret = DBExec(&strSql); Log!(format!("{:?}", ret)); // Add a record Log!(format!("{:?}", DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))); // Query data Log!(format!("{:?}", DBExec(":SELECT * FROM TEST_TABLE;"))); }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); // Add a record Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);")); // Query data Log(DBExec(":SELECT * FROM TEST_TABLE;")); } -
Use the
DBExec()function to create a data 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)rustfn main() { let 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)", ]; let strSql = arr.join(""); let ret = DBExec(&strSql); Log!(format!("{:?}", 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); } -
Perform insert, delete, query, and update operations on records in a data 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("") Log(DBExec(strSql)) // Insert a record Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);")) // Query data Log(DBExec("SELECT * FROM TEST_TABLE;")) // Update data Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000)) // Delete data 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)) # Insert a record Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);")) # Query data Log(DBExec("SELECT * FROM TEST_TABLE;")) # Update data Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000)) # Delete data Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110))rustfn main() { let 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)", ]; let strSql = arr.join(""); Log!(format!("{:?}", DBExec(&strSql))); // Insert a record Log!(format!("{:?}", DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))); // Query data Log!(format!("{:?}", DBExec("SELECT * FROM TEST_TABLE;"))); // Update data. Rust's DBExec() function only accepts a single SQL statement string argument and does not support the ? placeholder for passing parameters; parameter values are written directly in the statement Log!(format!("{:?}", DBExec("UPDATE TEST_TABLE SET HIGH=110 WHERE TS=1518970320000;"))); // Delete data Log!(format!("{:?}", 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)); // Insert a record Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);")); // Query data Log(DBExec("SELECT * FROM TEST_TABLE;")); // Update data Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000)); // Delete data Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110)); }
Returns
| Type | Description |
object | An object containing the execution result of the sql statement, for example: ```json {"columns":["TS","HIGH","OPEN","LOW","CLOSE","VOLUME"],"values":[[1518970320000,100,99.1,90,100,12345.6]]} ``` |
Arguments
| Name | Type | Required | Description |
sql | string | Yes | The sql statement string. |
See Also
Remarks
-
By passing an argument to the
DBExec()function, you can operate on the live trading database (SQLite database).-
It supports insert, delete, query, and update operations on data in the live trading database, and supports SQLite syntax.
-
The system-reserved tables in the live trading database include:
kvdb,cfg,log,profit,chart. Please do not operate on these tables. -
Transactions are currently not supported, and such operations are not recommended, as they may cause system conflicts.
-
The
DBExec()function only supports live trading.
-
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)
rust
fn main() {
let uuid1 = UUID();
let uuid2 = UUID();
Log!(uuid1, uuid2);
}
c++
void main() {
auto uuid1 = UUID();
auto uuid2 = UUID();
Log(uuid1, uuid2);
}Returns
| Type | Description |
string | A 32-bit UUID. |
Remarks
The UUID() function is only supported in live trading.
EventLoop
Listens for events and returns when any WebSocket has readable data, or when concurrent tasks such as exchange.Go() or HttpQuery_Go() complete.
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 a Sleep statement is used here, it will cause the subsequent EventLoop function to miss the previous events. Because after waiting 2 seconds, the concurrent functions have already received data, and only then does the EventLoop listening mechanism start, so these events will be missed
// Unless EventLoop(-1) is called on the very first line to initialize the EventLoop listening mechanism first, these events will not be missed
// Log("GetDepth:", routine_getDepth.wait()) If the wait function is called here in advance to retrieve the result of the concurrent GetDepth function call, the event of this 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())
rust
fn main() {
// In Rust, exchange.Go uses typed tokens (such as Go::GetTicker) instead of method-name strings; pass () when there are no arguments
let routine_getTicker = exchange.Go(Go::GetTicker, ());
let routine_getDepth = exchange.Go(Go::GetDepth, ());
let routine_getTrades = exchange.Go(Go::GetTrades, ());
// Sleep(2000), if a Sleep statement is used here, it will cause the subsequent EventLoop function to miss the previous events. Because after waiting 2 seconds, the concurrent functions have already received data, and only then does the EventLoop listening mechanism start, so these events will be missed
// Unless EventLoop(-1) is called on the very first line to initialize the EventLoop listening mechanism first, these events will not be missed
// Log!("GetDepth:", routine_getDepth.wait(0)) If the wait function is called here in advance to retrieve the result of the concurrent GetDepth function call, the event of this GetDepth function receiving the request result will not be returned in the EventLoop function
let ts1 = Unix() * 1000;
let ret1 = EventLoop(0);
let ts2 = Unix() * 1000;
let ret2 = EventLoop(0);
let ts3 = Unix() * 1000;
let 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(0).unwrap());
Log!("GetDepth:", routine_getDepth.wait(0).unwrap());
Log!("GetTrades:", routine_getTrades.wait(0).unwrap());
}
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 empty, the
|
Arguments
| Name | Type | Required | Description |
timeout | number | No | The When |
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 first called after an event callback has already occurred, that earlier event will be missed. The queue structure encapsulated at the system's underlying level can cache at most 500 event callbacks; if the program does not call the EventLoop() function in time to retrieve them, later event callbacks exceeding the 500-cache limit will be lost.
Calling the EventLoop() function does not affect the underlying WebSocket cache queue of the system, nor does it affect the cache of concurrent functions such as exchange.Go(). The data in these caches must still be retrieved using their respective methods. For data that has already been retrieved before the EventLoop() function returns, no return event will be generated again in the EventLoop() function.
The main purpose of the EventLoop() function is to notify the strategy layer that the system's underlying level has received new network data, thereby driving the entire strategy in an event-driven manner. When the EventLoop() function returns an event, you only need to iterate through all data sources (such as WebSocket connections and objects created by exchange.Go()) and attempt to retrieve the data.
The EventLoop() function is only supported in live trading.
When called in the main function main(), it listens for events on the main thread. In strategies written in JavaScript, it can also be called in the execution function of a thread created by the threading.Thread() function to listen for events on 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 store data. This function implements a persistently stored global dictionary, saving data as key-value (KV) pairs permanently in the local database file of the hosting device (docker).
_G()
_G(k)
_G(k, v)Examples
javascript
function main(){
// Set a global variable num with a value of 1
_G("num", 1)
// Change the global variable num to the string value ok
_G("num", "ok")
// Delete the global variable num
_G("num", null)
// Return the value of the global variable num
Log(_G("num"))
// Delete all global variables
_G(null)
// Return the live trading bot ID
var robotId = _G()
}
python
def main():
_G("num", 1)
_G("num", "ok")
_G("num", None)
Log(_G("num"))
_G(None)
robotId = _G()
rust
fn main() {
// Set a global variable num with a value of 1
_G!("num", 1);
// Change the global variable num to the string value ok
_G!("num", "ok");
// Delete the global variable num
_G!("num", null);
// Return the value of the global variable num
Log!(_G!("num"));
// Rust does not support the _G!(null) form for deleting all global variables
// Return the live trading bot ID
let robotId = _G!();
}
c++
void main() {
_G("num", 1);
_G("num", "ok");
_G("num", NULL);
Log(_G("num"));
_G(NULL);
// auto robotId = _G(); is not supported
}Returns
| Type | Description |
string / number / bool / object / array / null | The value data in the persistently stored |
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 bot corresponds to a separate database. After the strategy restarts or the hosting device (docker) stops running, the data saved by the _G() function will still persist. However, after a backtest ends, the data saved by the _G() function in the backtesting system will be cleared. When using the _G() function to persistently store data, use it reasonably according to the memory and disk space of the hardware device, and never abuse it.
In live trading, when the _G() function is called without passing any parameters, the _G() function returns the Id of the current live trading bot.
When calling the _G() function, passing a null value for the parameter v indicates deleting the corresponding k-v key-value pair.
When calling the _G() function, if only the parameter k is passed as a string, then the _G() function returns the stored value corresponding to the parameter k.
When calling the _G() function, if only the parameter k is passed as a null value, it indicates deleting all recorded k-v key-value pairs.
After a k-v key-value pair has been persistently stored, calling the _G() function again and passing the persistently stored key name as the parameter k and a new value as the parameter v will update that k-v key-value pair.
Taking a live trading bot with Id 123456 as an example, the K-V key-value data persistently stored using the _G() function is stored in the /logs/storage/123456/123456.db3 database file located in the directory of the hosting device (docker) to which the live trading bot (i.e., the strategy instance program) belongs, and the data is recorded in the kvdb table.
_D
Convert a millisecond-level timestamp or a Date object into a time string.
_D()
_D(timestamp)
_D(timestamp, fmt)Examples
-
Get and print the current time string:
javascriptfunction main(){ var time = _D() Log(time) }pythondef main(): strTime = _D() Log(strTime)rustfn main() { let time = _D(None); Log!(time); }c++void main() { auto strTime = _D(); Log(strTime); } -
The timestamp is 1574993606000; convert it with code:
javascriptfunction main() { Log(_D(1574993606000)) }pythondef main(): # Running on a server set to Beijing time, the result is: 2019-11-29 10:13:26; while running this code on a docker on a server in another region gives the result: 2019-11-29 02:13:26 Log(_D(1574993606))rustfn main() { Log!(_D(1574993606000)); }c++void main() { Log(_D(1574993606000)); } -
Format using the
fmtargument. The format strings forJavaScript,Python, andC++differ; please refer to 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--26rustfn main() { // Rust's _D() function does not support the fmt argument; it only supports the default format: yyyy-MM-dd hh:mm:ss Log!(_D(1574993606000)); // 2019-11-29 10:13:26 }c++void main() { Log(_D(1574993606000, "%Y--%m--%d %H--%M--%S")); // 2019--11--29 10--13--26 }
Returns
| Type | Description |
string | The time string. |
Arguments
| Name | Type | Required | Description |
timestamp | number / object | No | A millisecond-level timestamp or a |
fmt | string | No | The format string. Default format for |
See Also
Remarks
If no argument is passed, the current time string is returned. When using the _D() function in a Python strategy, note that the argument passed in is a second-level timestamp (in JavaScript and C++ strategies it is a millisecond-level timestamp; 1 second equals 1000 milliseconds). When using the _D() function in live trading to parse a timestamp into a readable time string, note the time zone and time settings of the operating system on which the docker (hosting program) runs, because the parsing result of the _D() function depends on the docker system's time.
_N
Format a floating-point number.
_N()
_N(num)
_N(num, precision)Examples
-
For example,
_N(3.1415, 2)keeps3.1415to two decimal places, removes the remaining digits, 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)rustfn main() { let i = 3.1415; Log!(i); let ii = _N(i, 2); Log!(ii); }c++void main() { auto i = 3.1415; Log(i); auto ii = _N(i, 2); Log(ii); } -
If you need to set the N digits to the left of the decimal point all to 0, you can write it like this:
javascriptfunction main(){ var i = 1300 Log(i) var ii = _N(i, -3) // Check the log and you will see it is 1000 Log(ii) }pythondef main(): i = 1300 Log(i) ii = _N(i, -3) Log(ii)rustfn main() { let i = 1300; Log!(i); let ii = _N(i, -3); // Check the log and you will see it is 1000 Log!(ii); }c++void main() { auto i = 1300; Log(i); auto ii = _N(i, -3); Log(ii); }
Returns
| Type | Description |
number | The floating-point number formatted according to the precision setting. |
Arguments
| Name | Type | Required | Description |
num | number | Yes | The floating-point number to be formatted. |
precision | number | No | Used to set the formatting precision. The parameter |
See Also
Remarks
The parameter precision can be a positive integer or a negative integer.
_C
A retry function used for fault-tolerant handling of interface calls.
_C(pfn)
_C(pfn, ...args)Examples
-
Apply fault-tolerant handling to a function without parameters:
javascriptfunction main(){ var ticker = _C(exchange.GetTicker) // Change the retry interval of the _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)rustfn main() { let ticker = _C!(exchange.GetTicker(None)); // Change the retry interval of the _C!() macro to 2 seconds _CDelay(2000); let depth = _C!(exchange.GetDepth(None)); Log!(ticker); Log!(depth); }c++void main() { auto ticker = _C(exchange.GetTicker); _CDelay(2000); auto depth = _C(exchange.GetDepth); Log(ticker); Log(depth); } -
Apply fault-tolerant handling to a function with parameters:
javascriptfunction main(){ var records = _C(exchange.GetRecords, PERIOD_D1) Log(records) }pythondef main(): records = _C(exchange.GetRecords, PERIOD_D1) Log(records)rustfn main() { let records = _C!(exchange.GetRecords(None, PERIOD_D1, None)); Log!(records); }c++void main() { auto records = _C(exchange.GetRecords, PERIOD_D1); Log(records); } -
It can also be used to apply fault-tolerant handling to 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)rustfn test(a: i64, b: i64) -> Result<bool> { let time = Unix(); if time % b == 3 { Log!("Condition met!", "#FF0000"); return Ok(true); } Log!("Retrying!", "#FF0000"); Err(Error::Api("retry".to_string())) } fn main() { // In Rust, a custom function can use the _C! macro for fault tolerance as long as it returns a Result type; it will retry when Err is returned let ret = _C!(test(1, 5)); Log!(ret); }c++// C++ does not support this way of applying fault tolerance to custom functions
Returns
| Type | Description |
All types supported by the platform except false values and null values (any). | The return value after 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 | The parameters of the callback function. There can be multiple |
Remarks
The _C() function repeatedly calls the specified function until it returns successfully (when the function referenced by the parameter pfn returns a null value or a false value upon being called, the call to pfn will be retried).
For example, _C(exchange.GetTicker). The default retry interval is 3 seconds, and 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.
Fault-tolerant handling can be applied to the following functions (but is not limited to them):
exchange.GetTicker()exchange.GetDepth()exchange.GetTrades()exchange.GetRecords()exchange.GetAccount()exchange.GetOrders()exchange.GetOrder()exchange.GetPositions()
All of the above functions can be called through the _C() function to achieve fault tolerance. The fault tolerance of the _C() function is not limited to the functions listed above. Please note that the parameter pfn is a function reference rather than a function call, i.e. it should be written as _C(exchange.GetTicker), not _C(exchange.GetTicker()).
_Cross
Returns the number of crossover periods between array arr1 and array arr2.
_Cross(arr1, arr2)Examples
You can simulate a set of data to test the _Cross(Arr1, Arr2) function:
javascript
// Fast line indicator
var arr1 = [1,2,3,4,5,6,8,8,9]
// Slow line indicator
var arr2 = [2,3,4,5,6,7,7,7,7]
function main(){
Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
}
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))
rust
fn main() {
// Fast line indicator
let arr1 = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 8.0, 9.0];
// Slow line indicator
let arr2 = [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 7.0, 7.0, 7.0];
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 crossover periods between array |
Arguments
| Name | Type | Required | Description |
arr1 | array | Yes | An array whose elements are of type |
arr2 | array | Yes | An array whose elements are of type |
Remarks
When the return value of the _Cross() function is positive, it indicates the number of periods since the upward cross (golden cross); when negative, it indicates the number of periods since the downward cross (death cross); when 0, it indicates that the current prices are equal. For detailed usage instructions, please refer to: Analysis and Usage Instructions for the Built-in Function _Cross.
JSON.parse
The JSON.parse function is a method of the ECMAScript standard built-in object JSON, used to decode (parse) a JSON string. The FMZ Quant Trading Platform has extended it with an additional parameter safeStr on this basis.
JSON.parse(s)
JSON.parse(s, safeStr)Examples
Decode (parse) a JSON string containing a large numeric value.
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
# You can use Python's third-party libraries to handle large numeric data.
rust
fn main() {
// Rust uses the JSONParse() function to parse JSON strings, without the safeStr parameter
// Large numeric values that exceed the precision range will be parsed as f64, which may lose precision
let s1 = r#"{"num": 8754613216564987646512354656874651651358}"#;
Log!("JSONParse:", JSONParse(s1).unwrap()["num"].as_f64().unwrap_or(0.0)); // JSONParse: 8.754613216564987e39
let s2 = r#"{"num": 123}"#;
Log!("JSONParse:", JSONParse(s2).unwrap()["num"].as_f64().unwrap_or(0.0)); // JSONParse: 123
}
c++
// Other solutions can be used to handle this.Returns
| Type | Description |
object | The return value is a |
Arguments
| Name | Type | Required | Description |
s | string | Yes | This parameter is 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 the string type.
The safeStr parameter position also supports passing in a reviver parameter, i.e. a function used to transform the result, which is called once for each member of the object; for specific usage, please refer to the relevant materials, which will not be elaborated here.
Only the JavaScript language is supported.
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 communication between live trading bots, allowing the current bot's status data to be broadcast to a channel for other live trading bots to subscribe to and retrieve.
SetChannelData(data)Examples
-
Channel Broadcaster Example - Publishing BTC Market Price Data
javascriptfunction main() { var updateId = 0 var robotId = _G() // Get current live bot ID while(true) { // Get real-time market price var ticker = exchange.GetTicker("BTC_USDT") if (!ticker) { Sleep(5000) continue } // Construct 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 the latest state on the channel (overwrites the 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 once per minute } }pythondef main(): updateId = 0 robotId = _G() # Get current live bot ID while True: # Get real-time market price ticker = exchange.GetTicker("BTC_USDT") if not ticker: Sleep(5000) continue # Construct 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 the latest state on the channel (overwrites the 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 once per minuterustfn main() { let mut updateId = 0; let robotId = _G!(); // Get current live bot ID loop { // Get real-time market price let ticker = match exchange.GetTicker("BTC_USDT") { Ok(t) => t, Err(_) => { Sleep(5000); continue; } }; // Construct current channel state data // Rust's SetChannelData only accepts a string argument, so use format! to build the JSON text updateId += 1; let timestamp = Unix() * 1000; let channelState = format!( r#"{{"robotId": {}, "updateId": {}, "timestamp": {}, "symbol": "BTC_USDT", "lastPrice": {}, "volume": {}, "high": {}, "low": {}}}"#, robotId, updateId, timestamp, ticker.Last, ticker.Volume, ticker.High, ticker.Low ); // Publish the latest state on the channel (overwrites the old state) SetChannelData(&channelState); // Display current channel state LogStatus!(format!( "Channel Broadcaster [Bot ID: {}]\nUpdate ID: #{}\nTime: {}\nSymbol: BTC_USDT\nLast Price: ${:.2}\nVolume: {:.4}\nHigh: ${:.2}\nLow: ${:.2}", robotId, updateId, _D(timestamp), ticker.Last, ticker.Volume, ticker.High, ticker.Low )); Sleep(60000); // Update channel state once per minute } }c++ -
Cross-platform sending example - Simulate an external platform (such as TradingView) sending data to an FMZ live bot
javascript// This example demonstrates how to use HttpQuery to send an HTTP POST request, simulating an external platform sending data to an FMZ live bot // In a real scenario, external platforms (such as TradingView's Webhook alert URL, third-party trading systems, etc.) directly call the FMZ API endpoint function main() { let uuid = "6BC42A119B5DBFA2188A8279DA3B5C30" let robotId = 123456 // Target live bot ID (the live bot used 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 the HTTP POST request let options = { method: "POST", body: JSON.stringify(sendData) // body can be a JSON string, plain text, etc. } let url = `${baseUrl}/api/v1?method=pub&robot=${robotId}&channel=${uuid}` // Send the data let ret = HttpQuery(url, options) Log("Simulated external platform sending data, result:", ret) Sleep(10000) // Send once every 10 seconds } }python# This example demonstrates how to use HttpQuery to send an HTTP POST request, simulating an external platform sending data to an FMZ live bot # In a real scenario, external platforms (such as TradingView's Webhook alert URL, third-party trading systems, etc.) directly call the FMZ API endpoint import json def main(): uuid = "6BC42A119B5DBFA2188A8279DA3B5C30" robotId = 123456 # Target live bot ID (the live bot used 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 the HTTP POST request options = { "method": "POST", "body": json.dumps(sendData) # body can be a JSON string, plain text, etc. } url = "{}/api/v1?method=pub&robot={}&channel={}".format(baseUrl, robotId, uuid) # Send the data ret = HttpQuery(url, options) Log("Simulated external platform sending data, result:", ret) Sleep(10000) # Send once every 10 secondsrust// This example demonstrates how to use HttpQuery to send an HTTP POST request, simulating an external platform sending data to an FMZ live bot // In a real scenario, external platforms (such as TradingView's Webhook alert URL, third-party trading systems, etc.) directly call the FMZ API endpoint fn main() { let uuid = "6BC42A119B5DBFA2188A8279DA3B5C30"; let robotId = 123456; // Target live bot ID (the live bot used to receive data) let baseUrl = "https://www.fmz.com"; loop { // Prepare the data to send (can be JSON, text, or other formats) let sendData = format!( r#"{{"action": "buy", "symbol": "BTC_USDT", "price": 50000, "timestamp": {}}}"#, Unix() * 1000 ); // Construct the HTTP POST request; {:?} escapes body into a valid JSON string value let options = format!(r#"{{"method": "POST", "body": {:?}}}"#, sendData); let url = format!("{}/api/v1?method=pub&robot={}&channel={}", baseUrl, robotId, uuid); // Send the data let ret: String = HttpQuery(&url, options.as_str()); Log!("Simulated external platform sending data, result:", ret); Sleep(10000); // Send once every 10 seconds } }c++
Returns
| Type | Description |
null | This function has no return value. |
Arguments
| Name | Type | Required | Description |
data | object / array / string / number / bool / null | Yes | The data to be published to the channel. It can be any data structure that supports |
See Also
Remarks
The SetChannelData() function is a non-blocking call; it returns immediately after being called and does not wait for the data transmission to complete.
Each live trading bot has its own dedicated channel, and the channel ID is the bot ID (which can be obtained via the _G() function).
The channel only stores the latest status data. Each call to SetChannelData() overwrites the previously published data rather than appending to a message history.
Channel data supports broadcasting across live trading bots, across dockers, and across servers, and multiple bots can subscribe to the same channel.
The subscriber side uses the GetChannelData() function to subscribe to channel data.
Channel communication is intended for live trading environments; this feature may be restricted in the backtesting system.
The byte length of the passed-in data parameter after JSON serialization must not exceed 1024 bytes. Exceeding this limit may cause the data publishing to fail. It is recommended to transmit only the necessary status information and to avoid transmitting overly large data objects.
The published data should be used reasonably according to the memory and network bandwidth of the hardware device; avoid publishing overly large data objects.
The data published by the SetChannelData() function can not only be subscribed to by other live trading bots within the FMZ platform, but also supports cross-platform data sending. External platforms (such as TradingView Webhook alerts, third-party trading systems, monitoring software, etc.) can send data to a specified FMZ live trading bot via HTTP POST requests.
How to send data across platforms: External systems send data to the FMZ platform API endpoint via an HTTP POST request: https://www.fmz.com/api/v1?method=pub&robot={robotId}&channel={uuid}, where robotId is the target live trading bot 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, plain text, or other formats. Note: a live trading bot must already be subscribed to the specified UUID channel before an external system can successfully send data; the broadcast data will be sent to all live trading bots under the same docker as the robotId bot, and any bot under that docker subscribed to the UUID channel can receive the data.
GetChannelData
Subscribes to the channel data of a specified live trading bot. This function is used for inter-bot communication, allowing you to retrieve the latest status data published by other live trading bots via the SetChannelData() function.
GetChannelData(channelId)Examples
-
Channel Subscriber Example - Subscribe to Channel Data from Two Live Trading Bots
javascriptfunction main() { // The two channel IDs to subscribe to (modify according to your actual situation) var channelId1 = "632799" // Live trading bot ID of channel 1 var channelId2 = "632800" // Live trading bot ID of channel 2 while(true) { // Subscribe to the current state of channel 1 var state1 = GetChannelData(channelId1) // Subscribe to the current state of channel 2 var state2 = GetChannelData(channelId2) // Build the status display var statusMsg = "Channel Subscriber - Current Subscription State\n\n" // Display channel 1 state statusMsg += "═══ Channel 1 [" + channelId1 + "] ═══\n" if (state1 !== null) { statusMsg += "Update ID: #" + state1.updateId + "\n" statusMsg += "Time: " + _D(state1.timestamp) + "\n" statusMsg += "Trading Pair: " + state1.symbol + "\n" statusMsg += "Last Price: $" + state1.lastPrice.toFixed(2) + "\n" statusMsg += "Volume: " + state1.volume.toFixed(4) + "\n" } else { statusMsg += "State: Waiting... (first call returns null)\n" } statusMsg += "\n" // Display channel 2 state statusMsg += "═══ Channel 2 [" + channelId2 + "] ═══\n" if (state2 !== null) { statusMsg += "Update ID: #" + state2.updateId + "\n" statusMsg += "Time: " + _D(state2.timestamp) + "\n" statusMsg += "Trading Pair: " + state2.symbol + "\n" statusMsg += "Last Price: $" + state2.lastPrice.toFixed(2) + "\n" statusMsg += "Volume: " + state2.volume.toFixed(4) + "\n" } else { statusMsg += "State: Waiting... (first call returns null)\n" } LogStatus(statusMsg) Sleep(5000) // Subscribe to the channel every 5 seconds } }pythondef main(): # The two channel IDs to subscribe to (modify according to your actual situation) channelId1 = "632799" # Live trading bot ID of channel 1 channelId2 = "632800" # Live trading bot ID of channel 2 while True: # Subscribe to the current state of channel 1 state1 = GetChannelData(channelId1) # Subscribe to the current state of channel 2 state2 = GetChannelData(channelId2) # Build the status display statusMsg = "Channel Subscriber - Current Subscription State\n\n" # Display channel 1 state 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 += "Trading Pair: {}\n".format(state1["symbol"]) statusMsg += "Last Price: ${:.2f}\n".format(state1["lastPrice"]) statusMsg += "Volume: {:.4f}\n".format(state1["volume"]) else: statusMsg += "State: Waiting... (first call returns None)\n" statusMsg += "\n" # Display channel 2 state 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 += "Trading Pair: {}\n".format(state2["symbol"]) statusMsg += "Last Price: ${:.2f}\n".format(state2["lastPrice"]) statusMsg += "Volume: {:.4f}\n".format(state2["volume"]) else: statusMsg += "State: Waiting... (first call returns None)\n" LogStatus(statusMsg) Sleep(5000) # Subscribe to the channel every 5 secondsrustfn main() { // Rust's GetChannelData() function does not accept a channel ID parameter; it can only read the current live trading bot's own channel // (i.e. the latest data published by this bot via SetChannelData()); it cannot subscribe to the channels of other live trading bots loop { // Subscribe to the current state of the channel let state = GetChannelData(); // Build the status display let mut statusMsg = String::from("Channel Subscriber - Current Subscription State\n\n"); if !state.is_null() { statusMsg += &format!("Update ID: #{}\n", state["updateId"].as_i64().unwrap_or(0)); statusMsg += &format!("Time: {}\n", _D(state["timestamp"].as_i64().unwrap_or(0))); statusMsg += &format!("Trading Pair: {}\n", state["symbol"].as_str().unwrap_or("")); statusMsg += &format!("Last Price: ${:.2}\n", state["lastPrice"].as_f64().unwrap_or(0.0)); statusMsg += &format!("Volume: {:.4}\n", state["volume"].as_f64().unwrap_or(0.0)); } else { statusMsg += "State: Waiting... (first call returns null)\n"; } LogStatus!(statusMsg); Sleep(5000); // Subscribe to the channel every 5 seconds } }c++ -
Cross-platform subscription example - Using UUID to subscribe to data sent from external systems
javascriptfunction main() { // Use a 32-bit UUID as the channel identifier let uuid = "6BC42A119B5DBFA2188A8279DA3B5C30" while (true) { // Subscribe to data on the 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 a 32-bit UUID as the channel identifier uuid = "6BC42A119B5DBFA2188A8279DA3B5C30" while True: # Subscribe to data on the 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 secondsrustfn main() { // Rust's GetChannelData() function does not accept a channel ID parameter, so it cannot use a 32-bit UUID to subscribe to cross-platform data; // it can only read the latest data from the current live trading bot's own channel (i.e., data published by this bot via SetChannelData()) loop { // Subscribe to the channel's data let data = GetChannelData(); if !data.is_null() { Log!("Received cross-platform data:", data); } else { Log!("Waiting for data... (first call returns null)"); } Sleep(10000); // Check every 10 seconds } }c++
Returns
| Type | Description |
object / array / string / number / bool / null value | Returns the latest status data of the subscribed channel. It returns |
Arguments
| Name | Type | Required | Description |
channelId | string / number | Yes | The channel identifier, which supports the following two types:
|
See Also
Remarks
The GetChannelData() function is a non-blocking call. It returns immediately after being called and does not wait for data reception to complete.
The first time the GetChannelData() function is called, it returns null. You need to retry and wait for the channel data synchronization to complete.
Each call retrieves the latest status data on the channel, rather than a historical message queue.
A single live trading bot can subscribe to the channels of multiple different bots simultaneously; simply call GetChannelData() multiple times, passing in a different bot ID each time.
The current live trading bot can also subscribe to its own channel, meaning the robotId parameter can be the ID of the current bot.
Channel data can be transmitted across bots, across administrators, and across servers.
The broadcasting end uses the SetChannelData() function to publish channel data.
Channel communication is suitable for the live trading environment; this feature may be limited in the backtesting system.
The GetChannelData() function supports cross-platform subscription. When a 32-bit UUID is used as the channel identifier, it can receive data sent by external systems outside the FMZ platform via the HTTP API. The external system must specify both the bot ID and the UUID in order to send data; all live trading bots under the same administrator can subscribe to the data of that UUID channel, while bots under different administrators cannot subscribe.
Log
Log
The Log() function is used to output logs.
Log(...msgs)Examples
-
Multiple
msgparameters can be passed in:javascriptfunction main() { Log("msg1", "msg2", "msg3") }pythondef main(): Log("msg1", "msg2", "msg3")rustfn main() { Log!("msg1", "msg2", "msg3"); }c++void main() { Log("msg1", "msg2", "msg3"); } -
Setting the color of the output message is supported. If you need to set both the color and push simultaneously, set the color first and then use the
@character to set push at the end.javascriptfunction main() { Log("Hello FMZ Quant !@") Sleep(1000 * 5) // Adding #ff0000 within the string makes the printed log display in red and pushes the message Log("Hello, #ff0000@") }pythondef main(): Log("Hello FMZ Quant !@") Sleep(1000 * 5) Log("Hello, #ff0000@")rustfn main() { Log!("Hello FMZ Quant !@"); Sleep(1000 * 5); // Adding #ff0000 within the string makes the printed log display in red and pushes the message Log!("Hello, #ff0000@"); }c++void main() { Log("Hello FMZ Quant !@"); Sleep(1000 * 5); Log("Hello, #ff0000@"); } -
The
Log()function supports printingbase64-encoded images. The content starts with`and ends with`, for example:javascriptfunction main() { Log("`data:image/png;base64,AAAA`") }pythondef main(): Log("`data:image/png;base64,AAAA`")rustfn main() { Log!("`data:image/png;base64,AAAA`"); }c++void main() { Log("`data:image/png;base64,AAAA`"); } -
The
Log()function supports directly printingPython'smatplotlib.pyplotobject. 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. Its output text will automatically switch to the corresponding language according to the language setting of the platform page, for example:javascriptfunction main() { Log("[trans]中文|abc[/trans]") }pythondef main(): Log("[trans]中文|abc[/trans]")rustfn 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 to the log area of the live trading or backtesting system. During live trading, the logs will be saved in the live trading database. If the content output by the Log() function ends with the @ character, that log will enter the message push queue and be pushed to the email address, WebHook address, etc. configured in the Push Settings of the current FMZ Quant Trading Platform account. The Debugging Tool and the backtesting system do not support message push. Message push is subject to frequency limits, with the specific rules as follows: within each 20-second cycle of live trading, only the last push message is retained and pushed, while the rest are filtered out and not pushed (the push logs output via the Log function are still printed and displayed normally in the log area).
If the content output by the Log() function ends with the & character, that log will be marked as a private log. When the live trading is publicly displayed, that log is hidden from other users, but remains visible from the perspective of the live trading owner's account. This feature can be used to record sensitive information such as API keys, account balances, etc. For example: Log("Private information", "&").
Regarding WebHook push, 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 the Push Settings: http://XXX.XX.XXX.XX:9090/data?data=Hello_FMZ. After running the written Golang service program, you can start running the live trading strategy. The following is a strategy written in JavaScript; when the strategy runs, it executes the Log() function and pushes the message:
javascript
function main() {
Log("msg", "@")
}
After the service program written in Golang receives the push, it prints the following 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
Records and prints the profit/loss value, and plots the equity curve based on the profit/loss value.
LogProfit(profit)
LogProfit(profit, ...args)Examples
When calling the LogProfit function, if the last parameter is the character &, the log will not be written to the database and only the profit chart will be updated. Using the & parameter can avoid generating a large number of logs from frequent profit records, thereby keeping the logs clean. For example:
javascript
function main() {
// Plot 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)
rust
fn main() {
// Plot 30 points on the profit chart
// In Rust, LogProfit only accepts the profit value parameter and does not support extended parameters such as '&'
for i in 0..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 parameter, used to output additional information to this profit log. Multiple |
See Also
LogProfitReset
Clear all profit logs and the profit chart.
LogProfitReset()
LogProfitReset(remain)Examples
javascript
function main() {
// Print 30 data points on the profit chart, then reset, keeping only the last 10 data points
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)
rust
fn main() {
// Print 30 data points on the profit chart, then reset, keeping only the last 10 data points
for i in 0..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
Outputs information to the status bar on the backtesting system or the live trading page.
LogStatus(...msgs)Examples
-
Supports setting the color of the 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')rustfn 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"); } -
Example of data output in the status bar:
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 at both ends of the string to have it recognized as a complex message format (tables are currently supported) LogStatus('`' + JSON.stringify(table) + '`') // Table information can also be displayed within multi-line text LogStatus('First line message\n`' + JSON.stringify(table) + '`\nThird line message') // Multiple tables can be displayed simultaneously, and will be grouped and shown as tabs (TAB) LogStatus('`' + JSON.stringify([table, table]) + '`') // Buttons can also be constructed within the table; the strategy receives the content of the cmd property via 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'}) + '`') // Button styles can be customized (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"}) + '`')rustfn main() { let table = r#"{"type": "table", "title": "Position Info", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}"#; // Add ` characters at both ends of the JSON string to have it recognized as a complex message format (tables are currently supported) LogStatus!(format!("`{}`", table)); // Table information can also be displayed within multi-line text LogStatus!(format!("First line message\n`{}`\nThird line message", table)); // Multiple tables can be displayed simultaneously, and will be grouped and shown as tabs (TAB) LogStatus!(format!("`[{},{}]`", table, table)); // Buttons can also be constructed within the table; the strategy receives the content of the cmd property via GetCommand let table = String::from(r#"{"type": "table", "title": "Position Operation", "cols": ["Column 1", "Column 2", "Action"], "rows": ["#) + r#"["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close All"}]"# + r#"]}"#; LogStatus!(format!("`{}`", table)); // Or construct a standalone button LogStatus!(format!("`{}`", r#"{"type": "button", "cmd": "coverAll", "name": "Close All"}"#)); // Button styles can be customized (bootstrap button attributes) LogStatus!(format!("`{}`", r#"{"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() + "`"); } -
Supports 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) + "`")rustfn main() { let table = String::from(r#"{"type": "table", "title": "Status Bar Button Styles", "cols": ["Default", "Primary", "Success", "Info", "Warning", "Danger"], "rows": [["#) + r#"{"type": "button", "class": "btn btn-xs btn-default", "name": "Default"},"# + r#"{"type": "button", "class": "btn btn-xs btn-primary", "name": "Primary"},"# + r#"{"type": "button", "class": "btn btn-xs btn-success", "name": "Success"},"# + r#"{"type": "button", "class": "btn btn-xs btn-info", "name": "Info"},"# + r#"{"type": "button", "class": "btn btn-xs btn-warning", "name": "Warning"},"# + r#"{"type": "button", "class": "btn btn-xs btn-danger", "name": "Danger"}"# + r#"]]}"#; LogStatus!(format!("`{}`", 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() + "`"); } -
Configure the disable and description features of status bar buttons (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) + "`")rustfn main() { let button1 = r#"{"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"}"#; let button2 = r#"{"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": true}"#; let button3 = r#"{"type": "button", "name": "Button 3", "cmd": "button3", "description": "This is the third button, set to enabled", "disabled": false}"#; let table = format!( r#"{{"type": "table", "title": "Status Bar Button Disable and Description Test", "cols": ["Column 1", "Column 2", "Column 3"], "rows": [[{}, {}, {}]]}}"#, button1, button2, button3 ); LogStatus!(format!("`{}`", 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() + "`"); } -
In combination with the
GetCommand()function, build the interactive functionality of status bar buttons (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)rustfn test1() { Log!("Calling custom function"); } fn main() { loop { let table = String::from(r#"{"type": "table", "title": "Operation", "cols": ["Column 1", "Column 2", "Action"], "rows": ["#) + r#"["a", "1", {"type": "button", "cmd": "CoverAll", "name": "Close All"}],"# + r#"["b", "1", {"type": "button", "cmd": 10, "name": "Send Number"}],"# + &format!(r#"["c", "1", {{"type": "button", "cmd": "{}", "name": "Call Function"}}],"#, _D(None)) + r#"["d", "1", {"type": "button", "cmd": "test1", "name": "Call Custom Function"}]"# + r#"]}"#; LogStatus!(_D(None), "\n", format!("`{}`", table)); if let Some(str_cmd) = GetCommand(0) { Log!("Received interaction data str_cmd:", "Type:", "String", "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, and the interaction command is ultimately captured by the
GetCommand()function.By adding an
inputfield to the data structure of a status bar button control (legacy button structure) — for example, adding"input": {"name": "Quantity", "type": "number", "defValue": 1}to{"type": "button", "cmd": "open", "name": "Open"}— the button, when clicked, will pop up a dialog containing an input field control (the default value in the input field is 1, i.e. the value set bydefValue), so that a value can be entered and sent together with the button command. For example, when running the following test code, clicking the "Open Position" button will pop up a dialog with an input field; entering 111 in the input field and clicking "OK" will cause theGetCommand()function to 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)rustfn main() { let tbl = String::from(r#"{"type": "table", "title": "Operation", "cols": ["Column 1", "Column 2"], "rows": ["#) + r#"["Open Position", {"type": "button", "cmd": "open", "name": "Open", "input": {"name": "Quantity", "type": "number", "defValue": 1}}],"# + r#"["Close Position", {"type": "button", "cmd": "coverAll", "name": "Close All"}]"# + r#"]}"#; LogStatus!(_D(None), "\n", format!("`{}`", tbl)); loop { if let Some(cmd) = GetCommand(0) { 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); } } -
Group button controls are supported (the legacy button structure). Their functionality is identical to the status bar button that supports data input (configured via the "input" field), and the interaction commands are ultimately captured by the
GetCommand()function. The difference is that group buttons are configured via the"group"field: when a button is clicked to trigger an interaction, the dialog box that pops up on the page displays a pre-configured set of input controls, allowing a group of data to be entered all at once.
Regarding the"group"field in the structure of status bar button controls and group button controls, note the following points:- The
typeproperty in group only supports the following 4 types, and thedefValueproperty is used to set the default value.
"selected": drop-down box control; use the|symbol to separate the options in the drop-down box.
"number": numeric input box control.
"string": string input box control.
"boolean": checkbox control; checked means (boolean) true, unchecked means (boolean) false. - Controls for interactive input support dependency settings:
For example, the"name": "tradePrice@orderType==1"setting in the example below makes the trade price (tradePrice) input control available only when the order type (orderType) drop-down box control is set to limit order. - The names of controls for interactive input support bilingual settings.
For example, the "description": "下单方式|order type" setting in the example below uses the|symbol to separate the Chinese and English description content. - Although the
nameanddescriptionin group share the same field names as thenameanddescriptionin the button structure, their definitions are not the same.
Thenamein group is also defined differently from thenamein input. - After a group button control is triggered, the format of the interaction content sent is: the button's cmd field value plus the group field-related data. For example, when testing the example below, the content output by the
Log("cmd:", cmd)statement is:
cmd: open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}, that is, the content returned by theGetCommand()function when the interaction operation occurs:open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}. - The
typeproperty of button controls only supports"button":
For button controls that support data input, i.e. controls with theinputproperty set, thetypeproperty 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 the 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]) // A single cell of a status bar table supports setting multiple buttons, i.e. the data in a single 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)rustfn main() { // Create the group button control structure let group_btn = String::from(r#"{"type": "button", "cmd": "open", "name": "Open", "group": ["#) + r#"{"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "市价单|挂单"},"# + r#"{"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100},"# + r#"{"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100},"# + r#"{"name": "boolean", "description": "是/否|boolean", "type": "boolean", "defValue": true}"# + r#"]}"#; // Test button 1, test button 2 let test_btn1 = r#"{"type": "button", "name": "Button 1", "cmd": "button1", "description": "This is the first button"}"#; let test_btn2 = r#"{"type": "button", "name": "Button 2", "cmd": "button2", "description": "This is the second button", "input": {"name": "Quantity", "type": "number", "defValue": 1}}"#; // Add groupBtn to tbl; a single cell of a status bar table supports setting multiple buttons, i.e. the data in a single cell is an array of button structures: [testBtn1, testBtn2] let tbl = format!( r#"{{"type": "table", "title": "Group Button Control Demo", "cols": ["Operation"], "rows": [[{}], [[{}, {}]]]}}"#, group_btn, test_btn1, test_btn2 ); loop { LogStatus!(format!("`{}`", tbl), "\n", "Group button controls can be set directly on the status bar in addition to status bar tables:", format!("`{}`", group_btn)); if let Some(cmd) = GetCommand(0) { 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() { // In the page triggered by the status bar button control (implemented by setting the input field) testBtn1 button, the dropdown control uses the options field to set options, and uses the defValue field to set the default option. This differs from the approach in other examples of this chapter that set options directly using defValue. var testBtn1 = { type: "button", name: "testBtn1", cmd: "cmdTestBtn1", input: {name: "testBtn1ComboBox", type: "selected", options: ["A", "B"], defValue: 1} } /* In the page triggered by the status bar button control (implemented by setting the input field) testBtn2 button, the dropdown control uses the options field to set options. The options in the options field support not only strings, but also the ```{text: "description", value: "value"}``` structure. Use the defValue field to set the default option; the default option supports multi-select (implemented via an array structure). For multi-select, you need to additionally set the multiple field 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 } } // In the page triggered by the status bar group button control (implemented by setting the group field) testBtn3 button, the dropdown control uses the options field to set options, and also supports setting options directly using defValue. 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)rustfn main() { // In the page triggered by the status bar button control (implemented by setting the input field) testBtn1 button, the dropdown control uses the options field to set options, and uses the defValue field to set the default option. This differs from the approach in other examples of this chapter that set options directly using defValue. let test_btn1 = r#"{"type": "button", "name": "testBtn1", "cmd": "cmdTestBtn1", "input": {"name": "testBtn1ComboBox", "type": "selected", "options": ["A", "B"], "defValue": 1}}"#; /* In the page triggered by the status bar button control (implemented by setting the input field) testBtn2 button, the dropdown control uses the options field to set options. The options in the options field support not only strings, but also the {"text": "description", "value": "value"} structure. Use the defValue field to set the default option; the default option supports multi-select (implemented via an array structure). For multi-select, you need to additionally set the multiple field to a truthy value (true). */ let test_btn2 = String::from(r#"{"type": "button", "name": "testBtn2", "cmd": "cmdTestBtn2", "input": {"#) + r#""name": "testBtn2MultiComboBox", "type": "selected", "description": "Implement multi-select dropdown","# + r#""options": [{"text": "Option A", "value": "A"}, {"text": "Option B", "value": "B"}, {"text": "Option C", "value": "C"}],"# + r#""defValue": ["A", "C"], "multiple": true}}"#; // In the page triggered by the status bar group button control (implemented by setting the group field) testBtn3 button, the dropdown control uses the options field to set options, and also supports setting options directly using defValue. let test_btn3 = String::from(r#"{"type": "button", "name": "testBtn3", "cmd": "cmdTestBtn3", "group": ["#) + r#"{"name": "comboBox1", "label": "labelComboBox1", "description": "Dropdown 1", "type": "selected", "defValue": 1, "options": ["A", "B"]},"# + r#"{"name": "comboBox2", "label": "labelComboBox2", "description": "Dropdown 2", "type": "selected", "defValue": "A|B"},"# + r#"{"name": "comboBox3", "label": "labelComboBox3", "description": "Dropdown 3", "type": "selected", "defValue": [0, 2], "multiple": true, "options": ["A", "B", "C"]},"# + r#"{"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"}]}"# + r#"]}"#; loop { LogStatus!(format!("`{}`\n", test_btn1), format!("`{}`\n", test_btn2), format!("`{}`\n", test_btn3)); if let Some(cmd) = GetCommand(0) { 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); } } -
Based on the current latest button structure, construct the buttons in the status bar table; when clicking a button triggers an interaction, pop up a dialog box containing multiple controls.
For more details, refer to: User Guide - Interactive Controls in the 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 the 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 the 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)rustfn main() { let symbols = ["BTC_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "BNB_USDT.swap", "SOL_USDT.swap"]; // Btn: button template; the first element of "group" is the trading symbol control, __SYMBOL__ is a placeholder that is replaced when constructing the button let tmp_btn_open = String::from(r#"{"type": "button", "cmd": "open", "name": "Open Position", "group": ["#) + r#"{"type": "string", "name": "symbol", "label": "Symbol", "default": "__SYMBOL__", "settings": {"required": true}},"# + r#"{"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}},"# + r#"{"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"}]}},"# + r#"{"type": "number", "name": "price", "label": "Price", "description": "Order price", "group": "Trade Settings", "filter": "tradeType==1", "settings": {"required": true}},"# + r#"{"type": "number", "name": "amount", "label": "Order Amount", "description": "Order amount", "group": "Trade Settings", "settings": {"required": true}}"# + r#"]}"#; loop { let mut rows: Vec<String> = Vec::new(); for symbol in &symbols { let btn_open = tmp_btn_open.replace("__SYMBOL__", symbol); rows.push(format!(r#"["{}", {}]"#, symbol, btn_open)); } let tbl = format!(r#"{{"type": "table", "title": "dashboard", "cols": ["symbol", "actionOpen"], "rows": [{}]}}"#, rows.join(",")); if let Some(cmd) = GetCommand(0) { Log!("Received interaction:", &cmd); // Parse the 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 : if cmd.starts_with("open:") { let msg = JSONParse(&cmd[5..]).unwrap(); let trade_type = msg["tradeType"].as_i64().unwrap_or(0); Log!("Symbol:", msg["symbol"].as_str().unwrap_or(""), ", Direction:", msg["direction"].as_str().unwrap_or(""), ", Order type:", if trade_type == 0 { "Market order" } else { "Limit order" }, if trade_type == 0 { ", Price: Current market price".to_string() } else { format!(", Price:{}", msg["price"].as_f64().unwrap_or(0.0)) }, ", Amount:", msg["amount"].as_f64().unwrap_or(0.0)); } } LogStatus!(_D(None), "\n", format!("`{}`", 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) + "`")rustfn main() { let table_tpl = String::from(r#"{"type": "table", "title": "Position Operation", "cols": ["Column 1", "Column 2", "Action"], "rows": ["#) + r#"["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close"}],"# + r#"__ROW2__"# + r#"]}"#; let ticker = exchange.GetTicker(None).unwrap(); let json_ticker = format!( r#"{{"Buy": {}, "Sell": {}, "High": {}, "Low": {}, "Volume": {}, "Last": {}, "Time": {}}}"#, ticker.Buy, ticker.Sell, ticker.High, ticker.Low, ticker.Volume, ticker.Last, ticker.Time ); // Add a row of data, merge the first and second cells, and output the ticker data in the merged cell // body is a string (corresponding to JS's JSON.stringify(ticker)); its internal quotes must be escaped before being embedded into the JSON let row2 = format!(r#"[{{"body": "{}", "colspan": 2}}, "abc"]"#, json_ticker.replace('"', "\\\"")); let table = table_tpl.replace("__ROW2__", &row2); LogStatus!(format!("`{}`", 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 a 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 into the first cell of the previous row table.rows.push(["B4", "C4"]) // A2 is merged into 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) + "`")rustfn main() { // For ease of testing, constructed data is used here to keep the code short and readable let json_ticker = r#"{"High": 0, "Low": 0, "Buy": 0, "Sell": 0, "Last": 0, "Time": 0, "Volume": 0}"#; let name = exchange.GetName(); let mut rows: Vec<String> = Vec::new(); rows.push(String::from(r#"["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}]"#)); // body is a string, and the quotes inside it must be escaped before they can be embedded in JSON let body = format!("A2 + B2:{}", json_ticker).replace('"', "\\\""); rows.push(format!(r#"[{{"body": "{}", "colspan": 2}}, "C2"]"#, body)); rows.push(format!(r#"[{{"body": "A3 + A4 + A5:{}", "rowspan": 3}}, "B3", "C3"]"#, name)); // A3 is merged into the first cell of the previous row rows.push(String::from(r#"["B4", "C4"]"#)); // A2 is merged into the first cell of the previous row rows.push(String::from(r#"["B5", "C5"]"#)); rows.push(String::from(r#"["A6", "B6", "C6"]"#)); let table = format!(r#"{{"type": "table", "title": "Table Demo", "cols": ["Column A", "Column B", "Column C"], "rows": [{}]}}"#, rows.join(",")); LogStatus!(format!("`{}`", 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 ease of testing, constructed data is used here to keep the code short and readable 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() + "`"); } -
Display tables with pagination in the status bar:
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]) + "`")rustfn main() { let table1 = r#"{"type": "table", "title": "table1", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}"#; let table2 = r#"{"type": "table", "title": "table2", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}"#; LogStatus!(format!("`[{},{}]`", 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 displaying tables with pagination, you can also arrange multiple tables 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) + "`")rustfn main() { // In Rust, write the row data directly into the JSON string let tab1 = r#"{"type": "table", "title": "Table 1", "cols": ["1", "2"], "rows": [["jack", "lucy"]]}"#; let tab2 = r#"{"type": "table", "title": "Table 2", "cols": ["1", "2", "3"], "rows": [["A", "B", "C"]]}"#; let tab3 = r#"{"type": "table", "title": "Table 3", "cols": ["A", "B", "C"], "rows": [["A", "B", "C"]]}"#; LogStatus!(format!("`{}`\n`{}`\n`{}`", tab1, tab2, tab3)); Log!("exit"); }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. After setting the
scrollattribute to"auto", when the number of vertical rows in the status bar table exceeds 20, the content will scroll automatically; when the number of horizontal columns exceeds the visible range of the page, horizontal scrolling will be applied. Using thescrollattribute can help mitigate the lag 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) + "`")rustfn main() { let tbl_tpl = String::from(r#"{"type": "table", "title": "test scroll", "scroll": "auto", "cols": ["#) + r#""col 0", "col 1", "col 2", "col 3", "col 4", "col 5", "col 6", "col 7", "col 8", "col 9", "col 10","# + r#""col 11", "col 12", "col 13", "col 14", "col 15", "col 16", "col 17", "col 18", "col 19", "col 20""# + r#"], "rows": [__ROWS__]}"#; let mut rows: Vec<String> = Vec::new(); for index in 1..100 { let i = index.to_string(); rows.push(format!( r#"[{}, "1,{}", "2,{}", "3,{}", "4,{}", "5,{}", "6,{}", "7,{}", "8,{}", "9,{}", "10,{}", "11,{}", "12,{}", "13,{}", "14,{}", "15,{}", "16,{}", "17,{}", "18,{}", "19,{}", "20,{}"]"#, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i )); } let tbl = tbl_tpl.replace("__ROWS__", &rows.join(",")); LogStatus!(format!("`{}`", 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 content of the current live trading status bar.
The LogStatus() function supports printing base64-encoded images. The image string starts with ` and ends with `. For example: LogStatus("`data:image/png;base64,AAAA`").
The LogStatus() function supports directly passing in a Python 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 a strategy is running live, if you scroll through the historical records on the live trading page, the status bar enters a dormant state and stops updating; the status bar data is only refreshed when the log is on the first page. The status bar supports outputting base64-encoded images, and also supports outputting base64-encoded images within tables displayed in the status bar. Since encoded image string data is usually very long, no example code is shown here.
EnableLog
Enable or disable logging of order information.
EnableLog(enable)Examples
javascript
function main() {
EnableLog(false)
}
python
def main():
EnableLog(False)
rust
fn main() {
EnableLog(false);
}
c++
void main() {
EnableLog(false);
}Arguments
| Name | Type | Required | Description |
enable | bool | Yes | When the |
See Also
Chart
Custom chart plotting function.
Chart(options)Examples
-
Multi-chart drawing configuration notes:
extension.layoutproperty
When this property is set to "single", the chart will not be displayed stacked with other charts (i.e., it is not presented as tabbed pages), but is instead tiled separately.extension.heightproperty
This property is used to set the height of the chart. The value can be a numeric type, or it can be set in the form of "300px".extension.colproperty
This property is used to set the width of the chart. The page width is divided into 12 units in total; setting it to 8 means the chart occupies 8 units of width.
javascriptfunction main() { var cfgA = { extension: { layout: 'single', // Not included in grouping, displayed separately; the 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 the initial data, there is no need to use the add function to update; you can update the data series simply by modifying the chart configuration directly. }] }; var cfgD = { extension: { layout: 'single', col: 8, // Specify the number of units the width occupies; the total number of units 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() // Append a data point to the pie chart; add can only update data points that were added via the 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 is actually equivalent to 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() * 100rustfn main() { // In Rust, the chart configuration is a JSON string; variable parts are represented with placeholders, which are replaced when updating to rebuild the configuration let cfg_a_tpl = r#"{ "extension": { "layout": "single", "height": 300 }, "title": {"text": "Order Book Chart"}, "subtitle": {"text": "__SUBTITLE__"}, "xAxis": {"type": "datetime"}, "series": [{"name": "Bid 1", "data": []}, {"name": "Ask 1", "data": []}] }"#; let cfg_b_tpl = r#"{ "title": {"text": "Spread Chart"}, "subtitle": {"text": "__SUBTITLE__"}, "xAxis": {"type": "datetime"}, "series": [{"name": "Spread", "type": "column", "data": []}] }"#; let cfg_c_tpl = r#"{ "__isStock": false, "title": {"text": "Pie Chart"}, "series": [{ "type": "pie", "name": "one", "data": [["A", __Y__], ["B", 25], ["C", 25], ["D", 25]] }] }"#; let cfg_d = r#"{ "extension": { "layout": "single", "col": 8, "height": "300px" }, "title": {"text": "Order Book Chart"}, "xAxis": {"type": "datetime"}, "series": [{"name": "Bid 1", "data": []}, {"name": "Ask 1", "data": []}] }"#; let cfg_e_tpl = r#"{ "__isStock": false, "extension": { "layout": "single", "col": 4, "height": "300px" }, "title": {"text": "Pie Chart 2"}, "series": [{ "type": "pie", "name": "one", "data": [["A", __Y__], ["B", 25], ["C", 25], ["D", 25]] }] }"#; let cfg_a = cfg_a_tpl.replace("__SUBTITLE__", ""); let cfg_b = cfg_b_tpl.replace("__SUBTITLE__", ""); let cfg_c = cfg_c_tpl.replace("__Y__", "25"); let cfg_e = cfg_e_tpl.replace("__Y__", "25"); let chart = Chart::new(&format!("[{},{},{},{},{}]", cfg_a, cfg_b, cfg_c, cfg_d, cfg_e)); chart.reset(0); // Append a data point to the pie chart; add can only update data points that were added via the add method, built-in data points cannot be updated later let y = (UnixNano() % 100) as f64; // Use the timestamp to simulate a random number chart.add(3, &format!(r#"{{"name": "ZZ", "y": {}}}"#, y), -1); loop { Sleep(1000); let ticker = match exchange.GetTicker(None) { Ok(t) => t, Err(_) => continue, }; let diff = ticker.Sell - ticker.Buy; let cfg_a = cfg_a_tpl.replace("__SUBTITLE__", &format!("Bid {}, Ask {}", ticker.Buy, ticker.Sell)); let cfg_b = cfg_b_tpl.replace("__SUBTITLE__", &format!("Spread {}", diff)); let now = Unix() * 1000; chart.add(0, &format!("[{}, {}]", now, ticker.Buy), -1); chart.add(1, &format!("[{}, {}]", now, ticker.Sell), -1); // Equivalent to updating the first data series of the second chart chart.add(2, &format!("[{}, {}]", now, diff), -1); chart.add(4, &format!("[{}, {}]", now, ticker.Buy), -1); chart.add(5, &format!("[{}, {}]", now, ticker.Buy), -1); let cfg_c = cfg_c_tpl.replace("__Y__", &format!("{}", (UnixNano() % 100) as f64)); let cfg_e = cfg_e_tpl.replace("__Y__", &format!("{}", (UnixNano() % 100) as f64)); // update is actually equivalent to resetting the chart configuration chart.update(&format!("[{},{},{},{},{}]", cfg_a, cfg_b, cfg_c, cfg_d, cfg_e)); } }c++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"] = str_format("Bid %f , Ask %f", ticker.Buy, ticker.Sell); cfgA["subtitle"] = cfgASubTitle; json cfgBSubTitle = R"({"text" : ""})"_json; cfgBSubTitle["text"] = str_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}); } } -
A simple charting example:
javascript// In JavaScript, chart is an object; before calling the Chart function, we need to declare an object variable chart used to configure the chart var chart = { // This field marks whether the chart is an ordinary chart; interested readers can change it to false and run it to see the effect __isStock: true, // Tooltip 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 }, // Horizontal axis (i.e., the x-axis); the currently set type is: datetime xAxis: { type: 'datetime'}, // Vertical axis (i.e., the y-axis); by default the values are automatically adjusted according to the data size yAxis : { // Title title: {text: 'Spread'}, // Whether to enable the right-side vertical axis opposite: false }, // Data series; this property holds each data series (line charts, candlestick charts, labels, etc.) series : [ // Index 0; the data array stores the data for the series at this index {name : "line1", id : "Line 1,buy1Price", data : []}, // Index 1; dashStyle: 'shortdash' is set, i.e., it is set as a dashed line {name : "line2", id : "Line 2,lastPrice", dashStyle : 'shortdash', data : []} ] } function main(){ // Call the Chart function to initialize the chart var ObjChart = Chart(chart) // Clear ObjChart.reset() while(true){ // Get the timestamp of this poll (i.e., a millisecond-level timestamp), used to determine the X-axis position written to the chart var nowTime = new Date().getTime() // Get the ticker data var ticker = _C(exchange.GetTicker) // Get the best bid price from the return value of the ticker data var buy1Price = ticker.Buy // Get the last traded price; to prevent the two lines from overlapping, add 1 to it here var lastPrice = ticker.Last + 1 // Pass the timestamp as the X value and the best bid price as the Y value into the 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)rustfn main() { // In Rust, the chart configuration is a JSON string; before calling the Chart::new function, define the chart configuration first let chart = r#"{ "__isStock": true, "tooltip": {"xDateFormat": "%Y-%m-%d %H:%M:%S, %A"}, "title": {"text": "Spread Analysis Chart"}, "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 }, "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": []} ] }"#; // Call the Chart::new function to initialize the chart let obj_chart = Chart::new(chart); // Clear obj_chart.reset(0); loop { // Get the timestamp of this poll (i.e., a millisecond-level timestamp), used to determine the X-axis position written to the chart let now_time = Unix() * 1000; // Get the ticker data let ticker = _C!(exchange.GetTicker(None)); // Get the best bid price from the return value of the ticker data let buy1_price = ticker.Buy; // Get the last traded price; to prevent the two lines from overlapping, add 1 to it here let last_price = ticker.Last + 1.0; // Pass the timestamp as the X value and the best bid price as the Y value into the data series at index 0 obj_chart.add(0, &format!("[{}, {}]", now_time, buy1_price), -1); // Same as above obj_chart.add(1, &format!("[{}, {}]", now_time, last_price), -1); Sleep(2000); } }c++void main() { // When writing a strategy in C++, try not to declare global variables of non-primitive types, so the chart configuration object is declared inside the 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); } } -
Example of drawing trigonometric function curves:
javascript// Configuration object used to initialize the chart var chart = { // Chart title title: {text: "Line value triggers plotLines value"}, // Y-axis related settings yAxis: { // A horizontal line perpendicular to the Y-axis, used as a trigger line; this is an array of structs, and multiple trigger lines can be set plotLines: [{ // The value of the trigger line; the line will be displayed at the corresponding numerical position value: 0, // Set the color of the trigger line color: 'red', // Line width width: 2, // The displayed label label: { // Label text text: 'Trigger Value', // Center-align the label align: 'center' } }] }, // X-axis related settings; here the type is set to a datetime axis xAxis: {type: "datetime"}, series: [ {name: "sin", type: "spline", data: []}, // Data series; multiple can be set and controlled via array indices {name: "cos", type: "spline", data: []} ] } function main(){ // Pi var pi = 3.1415926535897 // Variable used to record the timestamp var time = 0 // Angle var angle = 0 // The y-coordinate value, used to receive the sine or cosine value var y = 0 // Call the API interface to initialize the chart using the chart object var objChart = Chart(chart) // Clear the chart during initialization objChart.reset() // Set the value of the trigger line to 1 chart.yAxis.plotLines[0].value = 1 // Loop while(true){ // Get the timestamp of the current moment time = new Date().getTime() // Every 500ms, increase the angle by 5 degrees and calculate the sine value y = Math.sin(angle * 2 * pi / 360) // Write the calculated y value into the data series at the corresponding index in the chart; the first parameter of the add function is the specified data series index objChart.add(0, [time, y]) // Calculate the 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 plotting too frequently and data growing too fast 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)rustfn main() { // JSON configuration string used to initialize the chart; the trigger line value is set directly to 1 in the configuration let chart = r#"{ "title": {"text": "Line value triggers plotLines value"}, "yAxis": { "plotLines": [{ "value": 1, "color": "red", "width": 2, "label": { "text": "Trigger Value", "align": "center" } }] }, "xAxis": {"type": "datetime"}, "series": [{"name": "sin", "type": "spline", "data": []}, {"name": "cos", "type": "spline", "data": []}] }"#; // Pi let pi = 3.1415926535897_f64; // Angle let mut angle = 0.0_f64; // Call the API interface to initialize the chart using the chart configuration let obj_chart = Chart::new(chart); // Clear the chart during initialization obj_chart.reset(0); // Loop loop { // Get the millisecond timestamp of the current moment let ts = Unix() * 1000; // Increase the angle by 5 degrees and calculate the sine value let mut y = (angle * 2.0 * pi / 360.0).sin(); // Write the calculated y value into the data series at the corresponding index in the chart; the first parameter of the add function is the specified data series index obj_chart.add(0, &format!("[{}, {}]", ts, y), -1); // Calculate the cosine value y = (angle * 2.0 * pi / 360.0).cos(); obj_chart.add(1, &format!("[{}, {}]", ts, y), -1); // Increase by 5 degrees angle += 5.0; // Pause for 5 seconds to avoid plotting too frequently and data growing too fast 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); } } -
A complex example using a mixed chart:
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 = trust/*backtest start: 2020-03-11 00:00:00 end: 2020-04-09 23:59:00 period: 1d exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ fn main() { // In Rust, the chart configuration is represented as a JSON string; the pie chart data is marked with the placeholder __PIE_DATA__, which is replaced to rebuild the configuration on update let chart_cfg_tpl = 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": __PIE_DATA__, "center": ["3%", "6%"], "size": "15%", "dataLabels": {"enabled": false}, "startAngle": -90, "endAngle": 90 }] }"##; let c = Chart::new(&chart_cfg_tpl.replace("__PIE_DATA__", "[]")); let mut pre_ticker: Option<Ticker> = None; loop { let t = exchange.GetTicker(None).unwrap(); c.add(0, &format!("[{}, {}]", t.Time, t.Last), -1); // PnL let profit = if let Some(p) = &pre_ticker { t.Last - p.Last } else { 0.0 }; c.add(1, &format!("[{}, {}]", t.Time, profit), -1); // profit let r = (UnixNano() % 100) as f64 / 100.0; // use the timestamp to simulate a random number let pos = (t.Time / 86400) as f64; c.add(2, &format!("[{}, {}]", t.Time, pos / 2.0), -1); // Vol c.add(3, &format!("[{}, {}]", t.Time, if r > 0.8 { pos.to_string() } else { "null".to_string() }), -1); // Long c.add(4, &format!("[{}, {}]", t.Time, if r < 0.8 { (-pos).to_string() } else { "null".to_string() }), -1); // Short c.add(5, &format!("[{}, {}]", t.Time, (UnixNano() % 10000) as f64 / 100.0), -1); // Asset // update pie let pie = format!(r#"[["A", {}], ["B", {}]]"#, (UnixNano() % 100) as f64, (UnixNano() % 100) as f64); c.update(&chart_cfg_tpl.replace("__PIE_DATA__", &pie)); pre_ticker = Some(t); } }c++/*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; } } -
The
pietype chart does not have a time axis, so you need to update the chart configuration directly when updating the data. For example, in the code of the example above, after updating the data, simply callc.update(chartCfg)to refresh 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)rust// update pie // In Rust the chart configuration is a JSON string; rebuild the configuration containing the new data and then call update to refresh the chart let pie = format!(r#"[["A", {}], ["B", {}]]"#, (UnixNano() % 100) as f64, (UnixNano() % 100) as f64); c.update(&chart_cfg_tpl.replace("__PIE_DATA__", &pie));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, which contains 4 methods: add(), reset(), update(), del().
-
update()method:
Theupdate()method is used to update the chart's configuration information. Its parameter is a Chart chart configuration object (JSON).
-
del()method:
Thedel()method deletes the data series at the specified index according to the passed series parameter.
-
add()method:
Theadd()method is used to write data into the chart. Its parameters are, in order:
series: used to set the index of the data series, an integer.data: used to set the specific data to be written, an array.index(optional): used to set the data index, an integer, specifying the exact index position of the data to be modified. Negative numbers are supported; setting it to-1indicates the last data point of the data set.
For example, when drawing a line, to modify the data of the last point on the line:chart.add(0, [1574993606000, 13.5], -1), i.e. change the data of the last point in the chart'sseries[0].data. When theindexparameter is not set, it means appending data to the end of the current data series (series).
-
reset()method:
Thereset()method is used to clear the chart data. It can take one parameterremain, used to specify the number of data entries to retain. When theremainparameter is not passed, it means clearing all data.
KLineChart
This function is used to perform custom drawing while a strategy is running, using a drawing approach similar to the Pine language.
KLineChart(options)Examples
-
If you need to draw on the strategy's custom chart area, you must first create a chart control object, which can be created using the
KLineChart()function. The argument of theKLineChart()function is a chart configuration structure. The chart configuration 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 falsy value (for examplefalse), then all the chart content will be output on the sub-chart; if you need to specify that a certain drawing function draws on the main chart, you can also specify the argumentoverlayas a truthy value (for exampletrue) in the specific function call.javascriptfunction main() { // Call the KLineChart function to create the chart control object c let c = KLineChart({ overlay: true }) // Test with a spot exchange object to obtain K-line data. If testing with a futures exchange object, you need to set the contract first let bars = exchange.GetRecords() if (!bars) { return } // Iterate over the K-line data to perform drawing operations. Each drawing operation must start with a ```c.begin(bar)``` function call and end with a ```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 the KLineChart function to create the chart control object c c = KLineChart({ "overlay": True }) # Test with a spot exchange object to obtain K-line data. If testing with a futures exchange object, 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)rustfn main() { // Call KLineChart::new to create the chart control object c let mut c = KLineChart::new(r#"{"overlay": true}"#); // Test with a spot exchange object to obtain K-line data. If testing with a futures exchange object, you need to set the contract first let bars = exchange.GetRecords(None, None, None).unwrap(); // Iterate over the K-line data to perform drawing operations. Each drawing operation must start with a c.begin(bar) function call and end with a c.close() function call. for bar in &bars { c.begin(bar); c.barcolor(if bar.Close > bar.Open { "rgba(255, 0, 0, 0.2)" } else { "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, r#"{"title": "high"}"#); let l = c.plot(bar.Low, r#"{"title": "low"}"#); c.fill(h, l, if bar.Close > bar.Open { r#"{"color": "rgba(255, 0, 0, 0.2)"}"# } else { r#"{"color": "rgba(255, 0, 0, 0.2)"}"# }); c.hline(bar.High, "{}"); c.plotarrow(bar.Close - bar.Open, "{}"); c.plotshape(bar.Low > 0.0, r#"{"style": "diamond"}"#); c.plotchar(bar.Close > 0.0, r#"{"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, "long"); } else if bar.Close < bar.Open { c.signal("closelong", bar.Low, 1.5, "closelong"); } c.close(); } }c++// Not supported yet -
Use the
pricePrecisionandvolumePrecisionparameters to control the display precision of the chart data. You can set the display precision for price and volume according to your actual needs. For example, for instruments with large price fluctuations, you can set the precision to 0 to display integers; for instruments with finer price granularity, you can set it to 2 or a higher precision.javascriptfunction main() { // Create the chart control object, setting both price precision and volume precision to 0 (i.e., display integers) let c = KLineChart({ overlay: true, pricePrecision: 0, // Price data precision; set to 2 to keep 2 decimal places volumePrecision: 0 // Volume data precision }) // Select the appropriate trading pair based on the 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 over the K-line data and draw the 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 the chart control object, setting both price precision and volume precision to 0 (i.e., display integers) c = KLineChart({ "overlay": True, "pricePrecision": 0, # Price data precision; set to 2 to keep 2 decimal places "volumePrecision": 0 # Volume data precision }) # Select the appropriate trading pair based on the 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 over the K-line data and draw the 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)rustfn main() { // Create the chart control object, setting both price precision and volume precision to 0 (i.e., display integers) // pricePrecision is the price data precision; set to 2 to keep 2 decimal places; volumePrecision is the volume data precision let mut c = KLineChart::new(r#"{"overlay": true, "pricePrecision": 0, "volumePrecision": 0}"#); // Select the appropriate trading pair based on the exchange type let symbol = if exchange.GetName().contains("Futures_") { "ETH_USDT.swap" } else { "ETH_USDT" }; Log!("Test symbol:", symbol); // Get K-line data let bars = exchange.GetRecords(symbol, None, None).unwrap(); // Iterate over the K-line data and draw the chart for bar in &bars { c.begin(bar); c.barcolor(if bar.Close > bar.Open { "rgba(255, 0, 0, 0.2)" } else { "rgba(0, 0, 0, 0.2)" }, "{}"); c.plot(bar.High, r#"{"title": "high"}"#); c.plot(bar.Low, r#"{"title": "low"}"#); c.close(); } }c++// Not supported yet -
The
Pinelanguage drawing interface functions supported in drawing operations are as follows:barcolor: Sets the color of the candlesticks.barcolor(color, offset, editable, show_last, title, display)
The available values for the display parameter are: "none", "all"
javascriptc.barcolor(bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0.2)') // The usage is the same as the reference code in the example above, so it will not be repeated herepythonc.barcolor('rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(0, 0, 0, 0.2)')rustc.barcolor(if bar.Close > bar.Open { "rgba(255, 0, 0, 0.2)" } else { "rgba(0, 0, 0, 0.2)" }, "{}"); // The usage is the same as the reference code in the example above, so it will not be repeated herec++// Not supported yet -
bgcolor: Fills the candlestick background with the specified color.bgcolor(color, offset, editable, show_last, title, display, overlay)
The available values for the display parameter are: "none", "all"
javascriptc.bgcolor('rgba(0, 255, 0, 0.5)')pythonc.bgcolor('rgba(0, 255, 0, 0.5)')rustc.bgcolor("rgba(0, 255, 0, 0.5)", "{}");c++// Not supported yet -
plot: Plots a series of data on the chart.plot(series, title, color, linewidth, style, trackprice, histbase, offset, join, editable, show_last, display)
The available values for the style parameter are: "stepline_diamond", "stepline", "cross", "areabr", "area", "circles", "columns", "histogram", "linebr", "line"
The available values for the display parameter are: "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 linesrustlet h = c.plot(bar.High, r#"{"title": "high"}"#); c.plot(if bar.Open < bar.Close { f64::NAN } else { bar.Close }, r#"{"title": "Close", "style": "linebr"}"#); // Supports plotting discontinuous data linesc++// Not supported yet -
fill, fills the background area between two plots orhlines with a specified color. > fill(hline1, hline2, color, title, editable, fillgaps, display) > display parameter options: "none", "all"Since the
JavaScriptlanguage cannot pass arguments by parameter name, to solve this problem you can use the{key: value}structure to pass arguments to specified parameter names. For example, the reference code uses{color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)'}to assign a value to thecolorparameter of thefillfunction.To pass arguments to multiple parameter names consecutively, you can use
{key1: value1, key2: value2, key3: value3}.For example, this sample additionally specifies a
titleparameter:{color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0.2)', title: 'fill'}.Color values can be set either 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)')rustlet h = c.plot(bar.High, r#"{"title": "high"}"#); let l = c.plot(bar.Low, r#"{"title": "low"}"#); c.fill(h, l, if bar.Close > bar.Open { r#"{"color": "rgba(255, 0, 0, 0.2)"}"# } else { r#"{"color": "rgba(255, 0, 0, 0.2)"}"# });c++// Not supported yet -
hline, draws a horizontal line at a given 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)rustc.hline(bar.High, "{}");c++// Not supported yet -
plotarrow, draws 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)rustc.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)
The style parameter can be: "diamond", "square", "label_down", "label_up", "arrow_down", "arrow_up", "circle", "flag", "triangle_down", "triangle_up", "cross", "xcross"
The location parameter can be: "abovebar", "belowbar", "top", "bottom", "absolute"
The size parameter can be: "10px", "14px", "20px", "40px", "80px", corresponding respectively to size.tiny, size.small, size.normal, size.large, and size.huge in the Pine language.
size.auto is equivalent to size.small.
The display parameter can be: "none", "all"
javascriptc.plotshape(bar.Low, {style: 'diamond'})pythonc.plotshape(bar.Low, style = 'diamond')rustc.plotshape(bar.Low > 0.0, r#"{"style": "diamond"}"#);c++// Not supported yet -
plotchar, draws visual shapes on the chart using any given Unicode character.plotchar(series, title, char, location, color, offset, text, textcolor, editable, size, show_last, display)
The location parameter can be: "abovebar", "belowbar", "top", "bottom", "absolute"
The size parameter can be: "10px", "14px", "20px", "40px", "80px", corresponding respectively to size.tiny, size.small, size.normal, size.large, and size.huge in the Pine language.
size.auto is equivalent to size.small.
The display parameter can be: "none", "all"
javascriptc.plotchar(bar.Close, {char: 'X'})pythonc.plotchar(bar.Close, char = 'X')rustc.plotchar(bar.Close > 0.0, r#"{"char": "X"}"#);c++// Not supported yet -
plotcandle, draws a candlestick chart on the chart.plotcandle(open, high, low, close, title, color, wickcolor, editable, show_last, bordercolor, display)
The display parameter can be: "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)rustc.plotcandle(bar.Open * 0.9, bar.High * 0.9, bar.Low * 0.9, bar.Close * 0.9, "{}");c++// Not supported yet -
signal, this is a function that does not exist in the Pine language; here it is used to draw buy/sell signals.signal(direction, price, qty, id)
The parameter "long" indicates the trade direction, which can be "long", "closelong", "short", or "closeshort". The parameter
bar.Highindicates the position of the signal marker on the Y-axis.The parameter 1.5 indicates the trade quantity of the signal. A fourth parameter can be passed to replace the default text drawn; 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)rustc.signal("long", bar.High, 1.5, "long");c++// Not supported yet -
reset, this is a function that does not exist in the Pine language; it is used to clear chart data.reset(remain)
The
reset()method accepts a parameterremain, used to specify the number of data entries to retain. If theremainparameter is not passed, it means all data will be cleared.javascriptc.reset()pythonc.reset()rustc.reset(0);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
For custom drawing in a strategy, you can only choose one of the two methods: the KLineChart() function or the Chart() function. For settings such as colors and styles involved when calling the KLineChart() function, please refer to the topic article on drawing with the 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 displays data using the default precision. After the precision parameters are set, 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 the logs.
LogReset(remain)Examples
javascript
function main() {
// Retain the 10 most recent log entries and clear the rest
LogReset(10)
}
python
def main():
LogReset(10)
rust
fn main() {
// Retain the 10 most recent log entries and clear the rest
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 trading strategy starts is counted as one entry. Therefore, if no parameter is passed and the strategy produces no log output when it starts, the logs will not be displayed at all, and you will need to wait for the docker to send back the logs (this is normal behavior, not an error).
LogVacuum
Used to reclaim the storage space occupied by deleted data in SQLite after clearing logs with the LogReset() function.
LogVacuum()Examples
javascript
function main() {
LogReset()
LogVacuum()
}
python
def main():
LogReset()
LogVacuum()
rust
fn main() {
LogReset(0);
LogVacuum();
}
c++
void main() {
LogReset();
LogVacuum();
}See Also
Remarks
The reason is that SQLite does not immediately reclaim the occupied storage space when deleting data; the VACUUM command must be executed to clean up the data tables and free up space. This function triggers a file move operation when called, resulting in significant latency, so it is recommended to call it at appropriate time 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
Retrieves the Ticker structure (i.e., the market data) corresponding to the spot or contract of the currently configured trading pair and contract code. The GetTicker() function is a member function of the exchange object exchange. The purpose of the member functions (methods) of the exchange object is related only to exchange, which will not be repeated in the subsequent documentation.
exchange.GetTicker()
exchange.GetTicker(symbol)Examples
-
For a futures exchange object (i.e.,
exchangeorexchanges[0]), you need to first use theexchange.SetContractType()function to set the contract code before calling the market data functions, which will not be repeated in the subsequent documentation.javascriptfunction main(){ // If it is a futures exchange object, first set the contract code, for example, set it to a perpetual contract // exchange.SetContractType("swap") var ticker = exchange.GetTicker() /* Due to network reasons, the exchange interface may be inaccessible (even if the device where the docker program is located can open the exchange website, the API interface may still be unreachable) In this case, ticker is null, and accessing ticker.High will cause an error, so when testing this code, make sure the exchange interface 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"])rustfn main() { // If it is a futures exchange object, first set the contract code, for example, set it to a perpetual contract // exchange.SetContractType("swap").unwrap(); let ticker = exchange.GetTicker(None).unwrap(); 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 of a specific instrument (spot instrument).javascriptfunction main() { var ticker = exchange.GetTicker("BTC_USDT") Log(ticker) }pythondef main(): ticker = exchange.GetTicker("BTC_USDT") Log(ticker)rustfn main() { let ticker = exchange.GetTicker("BTC_USDT").unwrap(); 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 parameter When calling the When calling the When calling the |
See Also
exchange.GetDepth exchange.GetTrades exchange.GetRecords exchange.GetTickers exchange.IO (API rate limiting control)
Remarks
In the backtesting system, in the Ticker data returned by the exchange.GetTicker() function, High and Low are simulated values, taken from the best ask price and best bid price of the order book at that time.
In live trading, in the Ticker data returned by the exchange.GetTicker() function, the values of High and Low are determined based on the data returned by the wrapped exchange's Tick interface. This data contains the highest price and lowest price 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
Gets the Depth structure, i.e. the order book data, of the spot or contract 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 reasons, the exchange interface may be inaccessible (even if the device where the docker program runs can open the exchange website, the API interface may still be unreachable) In this case depth is null, and accessing depth.Asks[1].Price will cause an error, so when testing this code make sure the exchange interface 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)rustfn main() { let depth = exchange.GetDepth(None).unwrap(); let 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 the order book data of a specified 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)rustfn main() { // BTC USDT-margined perpetual contract let depth = exchange.GetDepth("BTC_USDT.swap").unwrap(); 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 When calling the When calling the When calling the |
See Also
Remarks
In the backtesting system, when backtesting with Simulated-level Tick, all levels of the data returned by the exchange.GetDepth() function are simulated values.
In the backtesting system, when backtesting with Live-level Tick, the data returned by the exchange.GetDepth() function is a second-level depth snapshot.
exchange.GetTrades
Gets the Trade structure array of the spot or futures corresponding to the currently set trading pair and contract code, i.e. the market's trade (tick) data.
exchange.GetTrades()
exchange.GetTrades(symbol)Examples
-
Test the
exchange.GetTrades()function:javascriptfunction main(){ var trades = exchange.GetTrades() /* Due to network reasons, the exchange interface may be inaccessible (even if the device where the docker program is located can open the exchange website, the API interface may still be unreachable) In this case trades is null, and accessing trades[0].Id will cause an error, so when testing this code, make sure the exchange interface 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"])rustfn main() { let trades = exchange.GetTrades(None).unwrap(); 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 the market trade record data of a specific instrument (futures instrument).javascriptfunction main() { // BTC's USDT-margined perpetual contract var trades = exchange.GetTrades("BTC_USDT.swap") Log(trades) }pythondef main(): trades = exchange.GetTrades("BTC_USDT.swap") Log(trades)rustfn main() { // BTC's USDT-margined perpetual contract let trades = exchange.GetTrades("BTC_USDT.swap").unwrap(); 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 is used to get the trade history (not your own trades) of the market corresponding to the current trading pair and contract. Some exchanges do not support this function, and the specific range of trade records returned varies from exchange to exchange, which needs to be handled according to the actual situation. The returned data is an array, in which the time order of each element is consistent with the order of the data returned by the exchange.GetRecords() function, i.e. the last element of the array is the data closest to the current time.
In the backtesting system, when backtesting with simulation-level Tick, the exchange.GetTrades() function returns an empty array.
In the backtesting system, when backtesting with **live-trading-level Tick**, the data returned by the exchange.GetTrades() function is order flow snapshot data, i.e. the 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 (i.e. K-line data) of the spot or contract corresponding to the currently set trading pair or contract code.
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 for a custom period.
javascriptfunction main() { // Print K-line data with a K-line period of 120 seconds (2 minutes) Log(exchange.GetRecords(60 * 2)) // Print K-line data with a K-line period of 5 minutes Log(exchange.GetRecords(PERIOD_M5)) }pythondef main(): Log(exchange.GetRecords(60 * 2)) Log(exchange.GetRecords(PERIOD_M5))rustfn main() { // Print K-line data with a K-line period of 120 seconds (2 minutes) Log!(exchange.GetRecords(None, 60 * 2, None)); // Print K-line data with a K-line period of 5 minutes Log!(exchange.GetRecords(None, PERIOD_M5, None)); }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 reasons, it may not be possible to access the exchange interface (even if the device running the docker program can open the exchange website, the API interface may still be inaccessible) In this case, records is null, and accessing records[0].Time will cause an error. Therefore, when testing this code, please make sure you can access the exchange interface normally */ 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])rustfn main() { let records = exchange.GetRecords(None, PERIOD_H1, None).unwrap(); 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.len() - 1], "Previous K-line", records[records.len() - 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, you can use thesymbol,period, andlimitparameters to request K-line data for a specified 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)rustfn main() { let records = exchange.GetRecords("BTC_USDT.swap", 60, 100).unwrap(); 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 on the backtesting and live trading pages. When calling the exchange.GetRecords() function, if a parameter is specified, it retrieves the K-line data for the period specified by that parameter; if no parameter is specified, it returns the K-line data for the period set in the backtesting or live trading parameters.
The return value is a Record structure array. The returned K-line data accumulates continuously over time, and the upper limit of the accumulated number of K-line bars is affected by the setting of the exchange.SetMaxBarLen() function. When not set, the default upper limit is 5000 K-line bars. Once the K-line data reaches the accumulation limit, each time a new K-line bar is added, the earliest K-line bar is deleted (similar to the first-in-first-out behavior of a queue). Some exchanges do not provide a K-line interface, in which case the docker collects market trade record data (a Trade structure array) in real time to synthesize K-lines.
If the exchange's K-line interface supports paginated queries, when calling the exchange.SetMaxBarLen() function to set a large K-line length, the system will initiate multiple API requests.
When the exchange.GetRecords() function is called for the first time, the number of K-line bars obtained differs between the backtesting and live trading environments:
-
The backtesting system pre-fetches a certain number of K-line bars prior to the start time of the backtesting time range (5000 by default; the relevant settings and data volume of the backtesting system will affect the final returned number) as the initial K-line data.
-
In live trading, the actual number of K-line bars obtained depends on the maximum amount of data that the exchange's K-line interface can provide.
Setting the period parameter to 5 means requesting K-line data with a period of 5 seconds. If the period parameter is not divisible by 60 (i.e., the represented period cannot be expressed in units of minutes), the underlying system will use the relevant interface of exchange.GetTrades() to obtain trade record data in order to synthesize the required K-line data; if the period parameter is divisible by 60, then 1-minute K-line data is used at minimum (using as large a period as possible) to synthesize the required K-line data.
In the simulation-level backtesting of the backtesting system, because the underlying K-line period must be set (during simulation-level backtesting, the system uses the corresponding K-line data to generate Tick data based on the configured underlying K-line period), the following must be noted: 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, the K-line data of each period is synthesized from the K-line data corresponding to the underlying K-line period.
In the C++ language, if you need to construct K-line data yourself, you can refer to the following 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 displays: Records[10]
Log(r);
auto ma = TA.MA(r,10);
// Output displays: [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
Retrieves the K-line period configured on the FMZ Quant Trading platform website page when running a strategy in backtesting or live trading, i.e., the default K-line period used when calling the exchange.GetRecords() function without passing any parameters.
exchange.GetPeriod()Examples
javascript
function main() {
// For example, 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")
rust
fn main() {
// For example, the K-line period set on the FMZ Quant Trading platform website page during backtesting or live trading is 1 hour
let period = exchange.GetPeriod();
Log!("K-line period:", period as f64 / (60.0 * 60.0), "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, an integer value, in seconds. |
See Also
exchange.SetMaxBarLen
Set the maximum length of the K-line (candlestick chart).
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)
rust
fn main() {
exchange.SetMaxBarLen(50);
let records = exchange.GetRecords(None, None, None).unwrap();
Log!(records.len(), records);
}
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 affects the following two aspects when a cryptocurrency strategy is running:
-
It affects the number of K-line bars (Bar) obtained on the first call.
-
It affects the upper limit on the number of K-line bars (Bar).
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 exchange rate currently 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())
rust
fn main() {
Log!(exchange.GetTicker(None));
// Set exchange rate conversion
exchange.SetRate(7);
Log!(exchange.GetTicker(None));
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 the conversion rate has not been set by calling exchange.SetRate(), the exchange.GetRate() function will return the default rate value 1, meaning that the data related to the currently displayed quote currency (quoteCurrency) has not been converted by any exchange rate.
If an exchange rate value has been set using exchange.SetRate(), for example exchange.SetRate(7), then all price information obtained through the exchange exchange object—such as tickers, market depth, and order prices—will be multiplied by the set rate 7 for conversion.
If exchange corresponds to an exchange that uses the US dollar as its quote currency, after calling exchange.SetRate(7), all prices in live trading will be multiplied by 7, converting them to prices close to the Chinese yuan (CNY). At this point, the rate value obtained through exchange.GetRate() is 7.
exchange.SetData
The exchange.SetData() function is used to set the data loaded when the strategy is running.
exchange.SetData(key, value)Examples
The data format required by the value parameter is like the data variable in the following example. As you can see, the timestamp 1579622400000 corresponds to the time 2020-01-22 00:00:00. When the running time of the strategy program exceeds this time and is before the timestamp 1579708800000 of the next data entry (i.e. the time 2020-01-23 00:00:00), calling the exchange.GetData() function will always retrieve the content of this data entry [1579622400000, 123]. As the program continues to run and time passes, and so on, the data can be retrieved entry by entry.
In the following example, when the current moment of the runtime (backtesting or live trading) reaches or exceeds the timestamp 1579795200000, calling the exchange.GetData() function returns: {"Time":1579795200000,"Data":["abc",123,{"price":123}]}. Here "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)
rust
/*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"}]
*/
fn main() {
// In the Rust SDK, the data argument of SetData is a JSON string
let data = r#"[
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]"#;
exchange.SetData("test", data);
loop {
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 of the |
Arguments
| Name | Type | Required | Description |
key | string | Yes | The name of the data collection. |
value | array | Yes | The data to be loaded by the |
See Also
Remarks
The loaded data can be any economic indicator, industry data, related index, etc., used to quantitatively evaluate various types of quantifiable information within the strategy.
exchange.GetData
The exchange.GetData() function is used to retrieve data loaded by the exchange.SetData() function, or data provided by an external link.
exchange.GetData(key)
exchange.GetData(key, timeout)Examples
-
How to call the method for writing data directly.
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)rust/*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"}] */ fn main() { // In the Rust SDK, the data parameter of SetData is a JSON string; use format! to concatenate the data let data = format!(r#"[[1579536000000, "{}"], [1579622400000, "{}"], [1579708800000, "{}"]]"#, _D(1579536000000), _D(1579622400000), _D(1579708800000)); exchange.SetData("test", &data); loop { 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); } } -
Data can be requested through external links. The data format returned by the request is as follows:
json{ "schema":["time","data"], "data":[ [1579536000000, "abc"], [1579622400000, 123], [1579708800000, {"price": 123}], [1579795200000, ["abc", 123, {"price": 123}]] ] }Here
schemadefines the data format of each record in the data body. This format is fixed as["time","data"], corresponding one-to-one with the format of each piece of data in thedataattribute. Thedataattribute is used to store the data body, where each piece of data consists of a millisecond-level timestamp and the data content (the data content can be any JSON-encodable data).The following is a 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) }The response data returned by the program after receiving the request:
json{ "schema":["time","data"], "data":[ [1579536000000, "abc"], [1579622400000, 123], [1579708800000, {"price": 123}], [1579795200000, ["abc", 123, {"price": 123}]] ] }The test strategy code is as follows:
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)rust/*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"}] */ fn main() { loop { 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); } } -
How to call the method for fetching data from external links.
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"))rustfn 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 the query data created on the datadata platform. The response data format must meet the following requirements (the schema must describe the time and data fields):
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 fields defined in the "schema". When calling the
exchange.GetData()function, a JSON object is returned, 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 code of the query data; xxx here is just an example }pythondef main(): Log(exchange.GetData("https://www.datadata.com/api/v1/query/xxx/data"))rustfn main() { Log!(exchange.GetData("https://www.datadata.com/api/v1/query/xxx/data")); // The xxx part in the link is the code of the query data; xxx here is just an example }c++void main() { Log(exchange.GetData("https://www.datadata.com/api/v1/query/xxx/data")); }
Returns
| Type | Description |
object / null value | The records in the dataset, or the data returned by the request. |
Arguments
| Name | Type | Required | Description |
key | string | Yes | The name of the dataset, or the data request URL. |
timeout | number | No | Used to set the cache timeout period, in milliseconds. In live trading, the default cache timeout is one minute. |
See Also
Remarks
In backtesting, the data is retrieved all at once; in live trading, the data is cached for one minute. In the backtesting system, when requesting data via an access interface, the backtesting system automatically adds parameters such as from (timestamp, in seconds), to (timestamp, in seconds), and period (the underlying K-line period, timestamp, in milliseconds) to the request, in order to determine the time range of the data to be retrieved.
exchange.GetMarkets
The exchange.GetMarkets() function is used to retrieve market information from the exchange.
exchange.GetMarkets()Examples
-
Call example for a futures exchange object:
javascriptfunction main() { var markets = exchange.GetMarkets() var currency = exchange.GetCurrency() // To get the current contract code you can also use the exchange.GetContractType() function 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])rustfn main() { let markets = exchange.GetMarkets(); let currency = exchange.GetCurrency(); // To get the current contract code you can also use the exchange.GetContractType() function let ct = "swap"; let key = format!("{}.{}", currency, ct); Log!(key, ":", format!("{:?}", markets.get(&key))); }c++void main() { auto markets = exchange.GetMarkets(); auto currency = exchange.GetCurrency(); auto ct = "swap"; auto key = currency + "." + ct; Log(key, ":", markets[key]); } -
In the backtesting system, use the futures exchange object to call the
exchange.GetMarkets()function. Before calling any market data function, GetMarkets only returns the market data of the current default trading pair; after calling a market data function, it returns the market data of all symbols that have already been requested. 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]) + "`")rust/*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"}] */ fn marketToJson(key: &str, market: &Market) -> String { format!(r#"["{}", "{}", "{}", "{}", {}, {}, {}, {}, {}, {}, {}, {}, {}]"#, 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) } fn main() { let arrSymbol = ["SOL_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"]; // The Rust SDK has no JSON serialization feature; here format! is used to concatenate the table's JSON text let markets1 = exchange.GetMarkets(); let mut rows1: Vec<String> = Vec::new(); for (key, market) in &markets1 { rows1.push(marketToJson(key, market)); } let tbl1 = format!(r#"{{"type": "table", "title": "markets1", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": [{}]}}"#, rows1.join(",")); for symbol in arrSymbol { exchange.GetTicker(symbol); } let markets2 = exchange.GetMarkets(); let mut rows2: Vec<String> = Vec::new(); for (key, market) in &markets2 { rows2.push(marketToJson(key, market)); } let tbl2 = format!(r#"{{"type": "table", "title": "markets2", "cols": ["key", "Symbol", "BaseAsset", "QuoteAsset", "TickSize", "AmountSize", "PricePrecision", "AmountPrecision", "MinQty", "MaxQty", "MinNotional", "MaxNotional", "CtVal"], "rows": [{}]}}"#, rows2.join(",")); LogStatus!(format!("`[{},{}]`", 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 | A dictionary containing |
See Also
Remarks
The return value of the exchange.GetMarkets() function is a dictionary. For spot exchanges, the key is the trading instrument name, in a fixed trading pair format, for example:
json
{
"BTC_USDT" : {...}, // The value is a Market structure
"LTC_USDT" : {...},
...
}
For futures contract exchanges, since the same instrument may have multiple contracts—for example, the BTC_USDT trading pair includes perpetual contracts, quarterly contracts, etc.—the keys in the dictionary returned by the exchange.GetMarkets() function are a combination of the trading pair and the contract code, for example:
json
{
"BTC_USDT.swap" : {...}, // The value is a Market structure
"BTC_USDT.quarter" : {...},
"LTC_USDT.swap" : {...},
...
}
-
The
exchange.GetMarkets()function is supported by both live trading and the backtesting system. -
The
exchange.GetMarkets()function only returns market information for trading instruments that are already listed on the exchange. -
The
exchange.GetMarkets()function 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 retrieve aggregated market data from the exchange (an array of Ticker structures). When exchange is a spot exchange object, it returns the ticker market data for all trading pairs; when exchange is a futures exchange object, it returns the ticker market data for all contracts.
exchange.GetTickers()Examples
-
Call the
exchange.GetTickers()function to retrieve aggregated market ticker 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))rustfn main() { if let Ok(tickers) = exchange.GetTickers() { if tickers.len() > 0 { Log!("Number of tradable symbols:", tickers.len()); } } }c++void main() { auto tickers = exchange.GetTickers(); if (tickers.Valid && tickers.size() > 0) { Log("Number of tradable symbols:", tickers.size()); } } -
Use a spot exchange object and call the
exchange.GetTickers()function in the backtesting system. Before calling any market data function, GetTickers only returns the ticker data of the current default trading pair; after calling a market data function, it returns the ticker data of all trading pairs that have been requested. You can 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 the market data of other trading pairs, 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 the market data of other trading pairs 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]) + "`")rust/*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"}] */ fn tickerToJson(ticker: &Ticker) -> String { format!(r#"["{}", {}, {}, {}, {}, {}, {}, {}, {}]"#, ticker.Symbol, ticker.High, ticker.Open, ticker.Low, ticker.Last, ticker.Buy, ticker.Sell, ticker.Time, ticker.Volume) } fn main() { let arrSymbol = ["ADA_USDT", "LTC_USDT", "ETH_USDT", "SOL_USDT"]; // Before requesting the market data of other trading pairs, call GetTickers // The Rust SDK has no JSON serialization, so use format! to concatenate the JSON text of the table let tickers1 = exchange.GetTickers().unwrap(); let rows1 = tickers1.iter().map(tickerToJson).collect::<Vec<String>>().join(","); let tbl1 = format!(r#"{{"type": "table", "title": "tickers1", "cols": ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], "rows": [{}]}}"#, rows1); // Request the market data of other trading pairs for symbol in arrSymbol { exchange.GetTicker(symbol); } // Call GetTickers again let tickers2 = exchange.GetTickers().unwrap(); let rows2 = tickers2.iter().map(tickerToJson).collect::<Vec<String>>().join(","); let tbl2 = format!(r#"{{"type": "table", "title": "tickers2", "cols": ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], "rows": [{}]}}"#, rows2); LogStatus!(format!("`[{},{}]`", 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 a trading pair or contract code before calling it, and it only returns market data for trading instruments that are already listed on the exchange.
-
The backtesting system supports this function.
-
Exchange objects that do not provide an aggregated market data interface 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 the member functions (methods) of the exchange object is only related to exchange, which will not be repeated in the rest of this document.
exchange.Buy(price, amount)
exchange.Buy(price, amount, ...args)Examples
-
The order number 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)rustfn main() { let id = exchange.Buy(100, 1).unwrap(); Log!("id:", id); }c++void main() { auto id = exchange.Buy(100, 1); Log("id:", id); } -
When placing an order for a cryptocurrency futures contract, you must pay attention to whether the trading direction is set correctly. If the trading direction does not match the trading function, an error will be reported:
```log
direction 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 Sell
```
javascript// The following are incorrect calls function main() { exchange.SetContractType("quarter") // Set the short direction exchange.SetDirection("sell") // Placing a buy order will report an error; shorting can only sell var id = exchange.Buy(50, 1) // Set the long direction exchange.SetDirection("buy") // Placing a sell order will report an error; going long can only buy var id2 = exchange.Sell(60, 1) // Set the close-long direction exchange.SetDirection("closebuy") // Placing a buy order will report an error; closing long can only sell var id3 = exchange.Buy(-1, 1) // Set the close-short direction exchange.SetDirection("closesell") // Placing a sell order will report an error; closing 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)rust// The following are incorrect calls fn main() { let _ = exchange.SetContractType("quarter"); // Set the short direction let _ = exchange.SetDirection("sell"); // Placing a buy order will report an error; shorting can only sell let id = exchange.Buy(50, 1); // Set the long direction let _ = exchange.SetDirection("buy"); // Placing a sell order will report an error; going long can only buy let id2 = exchange.Sell(60, 1); // Set the close-long direction let _ = exchange.SetDirection("closebuy"); // Placing a buy order will report an error; closing long can only sell let id3 = exchange.Buy(-1, 1); // Set the close-short direction let _ = exchange.SetDirection("closesell"); // Placing a sell order will report an error; closing short can only buy let 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 order buy function main() { // Place a market order to buy, buying ETH worth 0.1 BTC (quote currency) exchange.Buy(-1, 0.1) }pythondef main(): exchange.Buy(-1, 0.1)rust// For example, trading pair: ETH_BTC, market order buy fn main() { // Place a market order to buy, buying ETH worth 0.1 BTC (quote currency) let _ = exchange.Buy(-1, 0.1); }c++void main() { exchange.Buy(-1, 0.1); }
Returns
| Type | Description |
string / null value | Returns the order Id if the order is placed successfully, and returns a null value if the order fails. 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 | Extension parameter used to output accompanying information to this order log. Multiple |
See Also
exchange.Sell exchange.SetContractType exchange.SetDirection exchange.IO (API rate limit control; the Buy function is affected by the CreateOrder rate limit setting)
Remarks
When placing an order for a futures contract, you must pay attention to whether the trading direction is set correctly. If the trading direction does not match the trading function, an error will be reported. Unless otherwise specified, the order amount on cryptocurrency futures contract exchanges is denominated in number of contracts.
When the price parameter is set to -1, it is used to place a market order. This feature requires the exchange's order placement interface to support market orders. When placing a buy order for cryptocurrency spot in the form of a market order, the order amount parameter amount is the amount denominated in the quote currency. When placing an order for a cryptocurrency futures contract in the form of a market order, the unit of the order amount parameter amount is number of contracts. In live trading, a few cryptocurrency exchanges do not support the market order interface. For a few spot exchanges, the order amount of a market buy order is the number of trading coins. For details, please refer to the Exchange Special Notes in the "User Guide".
If you are using an older version of the docker, the order Id returned by the exchange.Buy() function may differ from the return value order Id described in the current document.
It should be noted that the order placement interfaces of the following three exchanges are relatively special. For spot market buy orders, the order amount is the number of coins rather than the 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 number 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)rustfn main() { let id = exchange.Sell(100, 1).unwrap(); Log!("id:", id); }c++void main() { auto id = exchange.Sell(100, 1); Log("id:", id); } -
When placing orders for cryptocurrency futures contracts, you must pay attention to whether the trading direction is set correctly. If the trading direction does not match the trading function, an error will be reported:
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 the short direction exchange.SetDirection("sell") // Placing a buy order will report an error; shorting can only sell var id = exchange.Buy(50, 1) // Set the long direction exchange.SetDirection("buy") // Placing a sell order will report an error; going long can only buy var id2 = exchange.Sell(60, 1) // Set the close-long direction exchange.SetDirection("closebuy") // Placing a buy order will report an error; closing a long can only sell var id3 = exchange.Buy(-1, 1) // Set the close-short direction exchange.SetDirection("closesell") // Placing a sell order will report an error; closing a 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)rust// The following are incorrect calls fn main() { let _ = exchange.SetContractType("quarter"); // Set the short direction let _ = exchange.SetDirection("sell"); // Placing a buy order will report an error; shorting can only sell let id = exchange.Buy(50, 1); // Set the long direction let _ = exchange.SetDirection("buy"); // Placing a sell order will report an error; going long can only buy let id2 = exchange.Sell(60, 1); // Set the close-long direction let _ = exchange.SetDirection("closebuy"); // Placing a buy order will report an error; closing a long can only sell let id3 = exchange.Buy(-1, 1); // Set the close-short direction let _ = exchange.SetDirection("closesell"); // Placing a sell order will report an error; closing a short can only buy let 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, sell with a market order function main() { // Note: place a market order to sell, selling 0.2 ETH exchange.Sell(-1, 0.2) }pythondef main(): exchange.Sell(-1, 0.2)rust// For example, trading pair: ETH_BTC, sell with a market order fn main() { // Note: place a market order to sell, selling 0.2 ETH let _ = exchange.Sell(-1, 0.2); }c++void main() { exchange.Sell(-1, 0.2); }
Returns
| Type | Description |
string / null value | Returns the order Id when the order is placed successfully, and returns a null value when the order fails. 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 | An extension parameter used to output additional information attached to this order log. Multiple |
See Also
exchange.Buy exchange.SetContractType exchange.SetDirection exchange.IO (API rate limit control; the Sell function is affected by the CreateOrder rate limit setting)
Remarks
When placing orders for futures contracts, you must pay attention to whether the trading direction is set correctly. If the trading direction does not match the trading function, an error will be reported. For cryptocurrency futures contract exchanges, the order size is denominated in number of contracts unless otherwise specified.
When the price parameter is set to -1, it is used to place a market order, which requires the exchange's order interface to support market orders. When trading cryptocurrency spot with market orders, when placing a sell order, the order size parameter amount is denominated in the trading currency. When trading cryptocurrency futures contracts with market orders, the order size parameter amount is denominated in number of contracts. In live trading, a few cryptocurrency exchanges do not support the market order interface.
If you are using an older version of the docker, the order Id returned by the exchange.Sell() function may differ from the returned order Id described in the current documentation.
exchange.CreateOrder
exchange.CreateOrder() function is used to place orders.
exchange.CreateOrder(symbol, side, price, amount)
exchange.CreateOrder(symbol, side, price, amount, ...args)Examples
-
Both spot exchange objects and futures exchange objects place orders by calling the
exchange.CreateOrder()function.javascriptfunction main() { var id = exchange.CreateOrder("BTC_USDT", "buy", 60000, 0.01) // Spot exchange object places an order, trading the BTC_USDT spot trading pair // var id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01) // Futures exchange object places an order, trading BTC's USDT-margined perpetual contract Log("Order Id:", id) }pythondef main(): id = exchange.CreateOrder("BTC_USDT", "buy", 60000, 0.01) # Spot exchange object places an order, trading the BTC_USDT spot trading pair # id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01) # Futures exchange object places an order, trading BTC's USDT-margined perpetual contract Log("Order Id:", id)rustfn main() { let id = exchange.CreateOrder("BTC_USDT", "buy", 60000, 0.01); // Spot exchange object places an order, trading the BTC_USDT spot trading pair // let id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01); // Futures exchange object places an order, trading BTC's 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 an order, trading the BTC_USDT spot trading pair // auto id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01); // Futures exchange object places an order, trading BTC's USDT-margined perpetual contract Log("Order Id:", id); } -
Place an order with additional parameters (option), used to pass exchange-specific parameters.
javascriptfunction main() { // Pass the 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 the 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))rustfn main() { // Pass the option parameter in JSON format (Rust does not support JSON.stringify, so construct the JSON text directly using a raw string) let option = r#"{"type": "TRAILING_STOP_MARKET", "activationPrice": "2300", "callbackRate": "0.1"}"#; let sideWithOption = format!("buy;{}", option); let id = exchange.CreateOrder("SOL_USDT.swap", &sideWithOption, -1, 1).unwrap(); Log!("Order Id:", id); Sleep(2000); Log!(exchange.GetOrder(&id)); }c++void main() { // Pass the 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 when the order is placed successfully, and returns a null value when the order fails. The When calling the |
Arguments
| Name | Type | Required | Description |
symbol | string | Yes | The When calling the When calling the When calling the |
side | string | Yes | The For spot exchange objects, the available values for the For futures exchange objects, the available values for the Supports additional parameters (option): You can pass additional parameters via the For example: Additional parameters are used to pass exchange-specific parameters (such as order type, time-in-force rules, etc.); the specific parameters supported depend on the exchange API. |
price | number | Yes | The |
amount | number | Yes | The |
arg | string / number / bool / object / array / any (any type supported by the platform) | No | An extension parameter used to output accompanying information to the log of this order; the |
See Also
Remarks
Additional parameters (option) can be passed via the side parameter to specify exchange-specific parameters. The additional parameters must be merged into 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\"}".
The option parameters supported by different exchanges vary. The specific supported parameters are subject to the exchange's API documentation. Common parameters include: order type (type), time in force (timeInForce), activation price (activationPrice), callback rate (callbackRate), etc.
When using the option parameters, you still need to provide the price and amount parameters. If certain parameters have already been passed via option, these base parameters may be overridden by the corresponding parameters in option; the specific behavior depends on the exchange's API implementation.
exchange.CancelOrder
The exchange.CancelOrder() function is used to cancel an order. In the order Order structure of the FMZ platform, the property Id is composed of the exchange's symbol code and the exchange's original order Id, separated by an English comma. For example, for an order of the OKX exchange spot trading pair ETH_USDT, the format of its Id property is: ETH-USDT,1547130415509278720.
When calling the exchange.CancelOrder() function to cancel an order, the passed-in parameter orderId is consistent with the Id property 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)rustfn main() { let id = exchange.Sell(99999, 1).unwrap(); let _ = exchange.CancelOrder(&id); }c++void main() { auto id = exchange.Sell(99999, 1); exchange.CancelOrder(id); } -
Among FMZ's API functions, functions that can produce log output (such as
Log(),exchange.Buy(),exchange.CancelOrder(), etc.) can all be accompanied by some output parameters after the required parameters.For example:
exchange.CancelOrder(orders[i].Id, orders[i]), that is, when canceling the order with Idorders[i].Id, additionally output the information of that order, 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)rustfn main() { if exchange.GetName().contains("Futures_") { Log!("Set contract to: perpetual swap, set direction to: open long."); let _ = exchange.SetContractType("swap"); let _ = exchange.SetDirection("buy"); } let ticker = exchange.GetTicker(None).unwrap(); let _ = exchange.Buy(ticker.Last * 0.5, 0.1); let orders = exchange.GetOrders(None).unwrap(); for i in 0..orders.len() { // Rust does not support appending output parameters after the required parameters of CancelOrder; after canceling the order, call the Log! macro separately to output the accompanying information let _ = exchange.CancelOrder(&orders[i].Id); Log!("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 parameter |
arg | string / number / bool / object / array / any (any type supported by the platform) | No | An extension parameter used to output accompanying information into this order-cancellation log; multiple |
See Also
Remarks
If you are using an older version of the docker (hosting agent), the parameter orderId of the exchange.CancelOrder() function may differ from the orderId described in the current documentation.
exchange.GetOrder
The exchange.GetOrder() function is used to obtain order information.
exchange.GetOrder(orderId)Examples
javascript
function main(){
var id = exchange.Sell(1000, 1)
// The parameter id is the order number; fill in the number of the order 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"])
rust
fn main() {
let id = exchange.Sell(1000, 1).unwrap();
// The parameter id is the order number; fill in the number of the order you want to query
let order = exchange.GetOrder(&id).unwrap();
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 |
| Queries order details based on the 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 return value Order structure is the average filled price; some exchanges do not support this field, and if it is not supported it will be set to 0.
If you are 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 obtain the current unfilled orders.
exchange.GetOrders()
exchange.GetOrders(symbol)Examples
-
Using a spot exchange object, place buy orders for multiple different trading pairs at half of the current price as the order price, then query the information of unfilled orders.
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) + "`") // Print the information once and then return, to prevent orders from being filled during subsequent 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":"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) + "`") returnrust/*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"}] */ fn main() { let arrSymbol = ["ETH_USDT", "BTC_USDT", "LTC_USDT", "SOL_USDT"]; for symbol in arrSymbol { let t = exchange.GetTicker(symbol).unwrap(); let _ = exchange.CreateOrder(symbol, "buy", t.Last / 2.0, 0.01); } let spotOrders = exchange.GetOrders(None).unwrap(); // Rust does not support JSON.stringify, use format! to build the table's JSON text let mut tbls = Vec::new(); for orders in [&spotOrders] { let mut rows = Vec::new(); for order in orders { rows.push(format!(r#"["{}", "{}", {}, {}, {}, {}, {}, {}, {}, "{}"]"#, order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType)); } let tbl = format!(r#"{{"type": "table", "title": "test GetOrders", "cols": ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], "rows": [{}]}}"#, rows.join(",")); tbls.push(tbl); } LogStatus!(format!("`[{}]`", tbls.join(","))); // Print the information once and then return, to prevent orders from being filled during subsequent backtesting, which would affect data observation return; }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"}] */ 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 the futures exchange object to place orders on multiple symbols with different trading pairs and contract codes. The order prices are set far away from the counterparty price at the top of the order book, keeping the orders in an unfilled state, and then query the 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) + "`") // Print the output once and then return immediately, to prevent orders from being filled later in the backtest and affecting the 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: 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) + "`") returnrust/*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"}] */ fn main() { let arrSymbol = ["BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"]; for symbol in arrSymbol { let t = exchange.GetTicker(symbol).unwrap(); let _ = exchange.CreateOrder(symbol, "buy", t.Last / 2.0, 1); let _ = exchange.CreateOrder(symbol, "sell", t.Last * 2.0, 1); } let defaultOrders = exchange.GetOrders(None).unwrap(); let swapOrders = exchange.GetOrders("USDT.swap").unwrap(); let futuresOrders = exchange.GetOrders("USDT.futures").unwrap(); let btcUsdtSwapOrders = exchange.GetOrders("BTC_USDT.swap").unwrap(); // Rust does not support JSON.stringify, so format! is used here to assemble the JSON text of the table let mut tbls = Vec::new(); let arr = [&defaultOrders, &swapOrders, &futuresOrders, &btcUsdtSwapOrders]; let tblDesc = ["defaultOrders", "swapOrders", "futuresOrders", "btcUsdtSwapOrders"]; for index in 0..arr.len() { let orders = arr[index]; let mut rows = Vec::new(); for order in orders { rows.push(format!(r#"["{}", "{}", {}, {}, {}, {}, {}, {}, {}, "{}"]"#, order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType)); } let tbl = format!(r#"{{"type": "table", "title": "{}", "cols": ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], "rows": [{}]}}"#, tblDesc[index], rows.join(",")); tbls.push(tbl); } LogStatus!(format!("`[{}]`", tbls.join(","))); // Print the output once and then return immediately, to prevent orders from being filled later in the backtest and affecting the data observation 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) { 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)); // The Id attribute in the Order struct is of type TId, so the FMZ platform's built-in C++ function to_string is used here for encoding 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, you can pass in theSymbolparameter to request order data for a specific trading pair or contract code.javascriptfunction main() { var orders = exchange.GetOrders("BTC_USDT") // Spot symbol example // var orders = exchange.GetOrders("BTC_USDT.swap") // Futures symbol example Log("orders:", orders) }pythondef main(): orders = exchange.GetOrders("BTC_USDT") # Spot symbol example # orders = exchange.GetOrders("BTC_USDT.swap") # Futures symbol example Log("orders:", orders)rustfn main() { let orders = exchange.GetOrders("BTC_USDT"); // Spot symbol example // let orders = exchange.GetOrders("BTC_USDT.swap"); // Futures symbol example Log!("orders:", orders); }c++void main() { auto orders = exchange.GetOrders("BTC_USDT"); // Spot symbol example // auto orders = exchange.GetOrders("BTC_USDT.swap"); // Futures symbol example Log("orders:", orders); }
Returns
| Type | Description |
| The |
Arguments
| Name | Type | Required | Description |
symbol | string | No | The For a spot exchange object, if the For a futures exchange object, if the |
See Also
Remarks
In the GetOrders function, the use cases of the symbol parameter are summarized as follows:
| Exchange Object Category | symbol Parameter | Query Range | Remarks |
|---|---|---|---|
| Spot | Do not pass the symbol parameter | Query all spot trading pairs | Applicable to all calling scenarios; if the exchange interface does not support it, an error is reported and a null value is returned, which will not be repeated below |
| Spot | Specify a trading instrument, with the symbol parameter as: "BTC_USDT" | Query the specified BTC_USDT trading pair | For a spot exchange object, the format of the symbol parameter is: "BTC_USDT" |
| Futures | Do not pass the symbol parameter | Query all trading instruments within the dimension range of the current trading pair and contract code | If 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 a trading instrument, with the symbol parameter as: "BTC_USDT.swap" | Query the specified BTC USDT-margined perpetual contract | For a futures exchange object, the format of the symbol parameter is: a combination of the trading pair and contract code defined by the FMZ platform, separated by the character ".". |
| Futures | Specify a range of trading instruments, with the symbol parameter as: "USDT.swap" | Query all USDT-margined perpetual contracts | - |
| Futures exchange supporting options | Do not pass the symbol parameter | Query all option contracts within the dimension range of the current trading pair | If the current trading pair is BTC_USDT and the contract is set to an option contract, for example the Binance option contract: BTC-240108-40000-C |
| Futures exchange supporting options | Specify a specific trading instrument | Query the specified option contract | For example, for the Binance futures exchange, the symbol parameter is: BTC_USDT.BTC-240108-40000-C |
| Futures exchange supporting options | Specify a range of trading instruments, with the symbol parameter as: "USDT.option" | Query all USDT-margined option contracts | - |
In the GetOrders function, the query dimension ranges for a futures exchange object are summarized as follows:
| symbol Parameter | Request Range Definition | Remarks |
|---|---|---|
| USDT.swap | Range of USDT-margined perpetual contracts. | For dimensions not supported by the exchange API interface, an error is reported and a null value is returned when called. |
| USDT.futures | Range of USDT-margined delivery contracts. | - |
| USD.swap | Range of coin-margined perpetual contracts. | - |
| USD.futures | Range of coin-margined delivery contracts. | - |
| USDT.option | Range of USDT-margined option contracts. | - |
| USD.option | Range of coin-margined option contracts. | - |
| USDT.futures_combo | Range of spread combo contracts. | Futures_Deribit exchange |
| USD.futures_ff | Range of multi-collateral delivery contracts. | Futures_Kraken exchange |
| USD.swap_pf | Range of multi-collateral perpetual contracts. | Futures_Kraken exchange |
When the account represented by the exchange object exchange has no open orders (i.e., active orders in an unfilled state) within the query range or on the specified trading instrument, calling this function will return an empty array, that is: [].
The following exchanges require a symbol parameter to be passed in for the interface that queries current unfilled orders. When calling the GetOrders function on these exchanges, if the symbol parameter is not passed in, only the unfilled orders of the current instrument are requested, rather than the unfilled orders of all instruments (because the exchange interface 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
exchange.GetHistoryOrders() function is used to retrieve the historical orders of the current trading pair or contract, and supports specifying a particular trading instrument.
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)
rust
fn main() {
let historyOrders = exchange.GetHistoryOrders(None, None, None);
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 order data for an options contract, the |
since | number | No | The |
limit | number | No | The |
See Also
Remarks
-
When the
symbol,since, andlimitparameters are not specified, the historical orders of the current trading pair or contract are queried by default, i.e., the historical orders within a certain range closest to the current time are queried. The specific query range depends on the single-query range of the exchange's interface. -
When the
symbolparameter is specified, the historical orders of the set trading instrument are queried. -
When the
sinceparameter is specified, the query starts from thesincetimestamp and proceeds toward the current time. -
When the
limitparameter is specified, the query returns once a sufficient number of records is reached. -
This function is only supported by exchanges that provide a historical order query interface.
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
The exchange.CreateConditionOrder() function is used to create a conditional order. A conditional order is a type of order that is automatically executed 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 a take-profit order: when the BTC_USDT price rises to 65000, sell 0.01 BTC at the price of 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 a market order } var id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("TP order Id:", id) }pythondef main(): # Create a take-profit order: when the BTC_USDT price rises to 65000, sell 0.01 BTC at the price of 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 a market order } id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("TP order Id:", id)rustfn main() { // Create a take-profit order: when the BTC_USDT price rises to 65000, sell 0.01 BTC at the price of 65000 let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, // Take-profit order TpTriggerPrice: 65000.0, // Trigger price TpOrderPrice: 65000.0, // Execution price, can also be set to -1 for a market order ..Default::default() }; let id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition); Log!("TP order Id:", id); }c++void main() { // Create a take-profit order: when the BTC_USDT price rises to 65000, sell 0.01 BTC at the price of 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): when the price drops to the stop-loss trigger price, automatically sell in the configured manner.
javascriptfunction main() { // Create a stop-loss order: when the 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 indicates a market order } var id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("SL order Id:", id) }pythondef main(): # Create a stop-loss order: when the 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 indicates a market order } id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, condition) Log("SL order Id:", id)rustfn main() { // Create a stop-loss order: when the BTC_USDT price drops to 58000, sell 0.01 BTC at market price let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_SL, // Stop-loss order SlTriggerPrice: 58000.0, // Trigger price SlOrderPrice: -1.0, // -1 indicates a market order ..Default::default() }; let id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition); Log!("SL order Id:", id); }c++void main() { // Create a stop-loss order: when the 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 an OCO order: set take-profit and stop-loss simultaneously. Once either one is triggered, the other is automatically canceled.
javascriptfunction main() { // Create an 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 an 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)rustfn main() { // Create an OCO order: take-profit price 65000, stop-loss price 58000 let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_OCO, // OCO order TpTriggerPrice: 65000.0, // Take-profit trigger price TpOrderPrice: 65000.0, // Take-profit execution price SlTriggerPrice: 58000.0, // Stop-loss trigger price SlOrderPrice: 58000.0 // Stop-loss execution price }; let id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition); Log!("OCO order Id:", id); }c++void main() { // Create an 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 conditional order with an additional parameter (option), used to pass exchange-specific parameters.
javascriptfunction main() { // Pass the option parameter in 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 the option parameter in 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))rustfn main() { // Pass the option parameter in JSON format (Rust has no JSON serialization capability, so a raw string is used directly here to construct it) let option = r#"{"type": "TRAILING_STOP_MARKET", "activatePrice": "300", "callbackRate": "0.1"}"#; let sideWithOption = format!("buy;{}", option); let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 77.0, TpOrderPrice: 71.0, ..Default::default() }; let id = exchange.CreateConditionOrder("SOL_USDT.swap", &sideWithOption, 1, &condition).unwrap(); Log!("Condition Order Id:", id); Sleep(2000); Log!(exchange.GetConditionOrder(&id)); }c++void main() { // Pass the option parameter in 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 | When the conditional order is created successfully, the conditional order Id is returned; when creation fails, a null value is returned. The format of the conditional order Id is similar to that of an ordinary order Id, consisting of the exchange symbol code and the exchange's original conditional order Id, separated by an English comma. |
Arguments
| Name | Type | Required | Description |
symbol | string | Yes | The When calling the When calling the When calling the |
side | string | Yes | The For a spot exchange object, the available values of the For a futures exchange object, the available values of the Additional parameters (option) are supported: additional parameters can be passed through the For example: Additional parameters are used to pass exchange-specific parameters (such as order type, effective rules, etc.). The specific supported parameters depend on the exchange API. |
amount | number | Yes | The |
condition | object | Yes | The
|
arg | string / number / bool / object / array / any (any type supported by the platform) | No | An extension parameter used to output additional information to the log of this conditional order. Multiple |
See Also
Condition exchange.CancelConditionOrder exchange.GetConditionOrder exchange.GetConditionOrders exchange.ModifyConditionOrder
Remarks
Whether conditional orders are supported depends on the specific exchange; some exchanges may not support conditional orders.
A conditional order does not lock up account funds before it is triggered; the order is only actually placed and funds are only committed after it is triggered.
Different exchanges may vary in their level of support for conditional orders and in the specific parameters involved. Please consult the API documentation of the corresponding exchange before use.
Additional parameters (option) can be passed via the side parameter to supply exchange-specific parameters. The additional parameters must be merged into 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\"}".
The option parameters supported vary from exchange to exchange; 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), and so on.
When using option parameters, you still need to provide the amount and condition parameters. If certain parameters in the exchange API have already been passed via option, these base parameters may be overridden by the corresponding parameters in option; the exact behavior depends on the exchange API's implementation.
exchange.ModifyOrder
The exchange.ModifyOrder() function is used to modify an existing regular order, allowing you to modify the order's price and quantity. This function supports modifying other order attributes via additional parameters (depending on the support of the exchange API).
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 the original order info var order = exchange.GetOrder(id) Log("Original Order Info:", order) Sleep(1000) // Modify the order's price and quantity var newId = exchange.ModifyOrder(id, "buy", 77, 2) Log("Modified Order ID:", newId) Sleep(2000) // Query the modified order info var newOrder = exchange.GetOrder(newId) Log("Modified Order Info:", newOrder) // Cancel the 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 the original order info order = exchange.GetOrder(id) Log("Original Order Info:", order) Sleep(1000) # Modify the order's price and quantity newId = exchange.ModifyOrder(id, "buy", 77, 2) Log("Modified Order ID:", newId) Sleep(2000) # Query the modified order info newOrder = exchange.GetOrder(newId) Log("Modified Order Info:", newOrder) # Cancel the order exchange.CancelOrder(newId)rustfn main() { // Create a limit buy order let id = exchange.CreateOrder("SOL_USDT.swap", "buy", 88, 1).unwrap(); Log!("Original Order ID:", id); Sleep(2000); // Query the original order info let order = exchange.GetOrder(&id).unwrap(); Log!("Original Order Info:", order); Sleep(1000); // Modify the order's price and quantity let newId = exchange.ModifyOrder(&id, "buy", 77, 2).unwrap(); Log!("Modified Order ID:", newId); Sleep(2000); // Query the modified order info let newOrder = exchange.GetOrder(&newId).unwrap(); Log!("Modified Order Info:", newOrder); // Cancel the order let _ = 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 the original order info auto order = exchange.GetOrder(id); Log("Original Order Info:", order); Sleep(1000); // Modify the order's price and quantity auto newId = exchange.ModifyOrder(id, "buy", 77, 2); Log("Modified Order ID:", newId); Sleep(2000); // Query the modified order info auto newOrder = exchange.GetOrder(newId); Log("Modified Order Info:", newOrder); // Cancel the order exchange.CancelOrder(newId); } -
Use the additional parameter (option) to modify the order's price match 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 the order and set the price match mode to QUEUE_20 // Pass the additional parameter (JSON format) via the 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 the modified order information var newOrder = exchange.GetOrder(newId) Log("Modified Order Info:", newOrder) // Cancel the 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 the order and set the price match mode to QUEUE_20 # Pass the additional parameter (JSON format) via the 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 the modified order information newOrder = exchange.GetOrder(newId) Log("Modified Order Info:", newOrder) # Cancel the order exchange.CancelOrder(newId)rustfn main() { // Create a limit buy order let id = exchange.CreateOrder("SOL_USDT.swap", "buy", 77, 1).unwrap(); Log!("Original Order ID:", id); Sleep(2000); // Modify the order and set the price match mode to QUEUE_20 // Pass the additional parameter (JSON format) via the side parameter; Rust does not support JSON.stringify, so construct the JSON text directly using a raw string let option = r#"{"priceMatch": "QUEUE_20"}"#; let sideWithOption = format!("buy;{}", option); let newId = exchange.ModifyOrder(&id, &sideWithOption, -1, 2).unwrap(); Log!("Modified Order ID:", newId); Sleep(2000); // Query the modified order information let newOrder = exchange.GetOrder(&newId).unwrap(); Log!("Modified Order Info:", newOrder); // Cancel the order let _ = 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 the order and set the price match mode to QUEUE_20 // Pass the additional parameter (JSON format) via the 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 the modified order information auto newOrder = exchange.GetOrder(newId); Log("Modified Order Info:", newOrder); // Cancel the order exchange.CancelOrder(newId); }
Returns
| Type | Description |
string / null value | Returns the order ID when the order modification succeeds, and returns a null value when the modification fails. The returned order ID may be the same as the original order ID or different, depending on the exchange API implementation. Some exchanges return a new order ID after modifying the order, 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 available values for the For futures exchange objects, the available values for the Supports additional parameters (option): Additional parameters can be passed via the For example: Additional parameters are used to modify other order attributes (such as the price match mode, etc.); the specific parameters supported 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 return an updated 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 the validity of parameters according to the exchange interface rules, but instead submits the parameters directly to the exchange API. When invalid parameters are passed in (such as a price or quantity of -1), the parameters may be ignored by the exchange, and the order will retain its original attributes unchanged.
Supports passing additional parameters (option) via the side parameter to modify other order attributes. Additional parameters must be merged with the side parameter before being passed in, in the format "side;{JSON object}" (recommended) or "side;key=value" (URL-encoded format). For example, to modify the price match mode: "buy;{\"priceMatch\":\"QUEUE_20\"}".
For modifying market orders among regular orders, you need to check specifically whether the exchange API supports it. Some exchanges do not support modifying market orders.
When modifying an order, the order's other attributes (such as order type, position mode, account mode, leverage, order time-in-force rules, etc.) usually retain the settings of the original order. If you need to modify these attributes, they can be passed in via additional parameters (option), provided the exchange API supports it.
Certain exchange APIs may convert an order into a market order when the price parameter is not received (price is -1 or null). For spot market buy orders, note that the unit of the order quantity may be the amount rather than the number of coins.
Support for the order modification feature depends on the specific exchange; some exchanges may not support the order modification feature, or may only support modifying certain parameters. Please consult the API documentation of the corresponding exchange before use.
exchange.ModifyConditionOrder
The exchange.ModifyConditionOrder() function is used to modify an existing conditional order, allowing modification of the order amount, trigger condition, and execution price of the conditional order. It supports modifying other properties of the conditional order through additional parameters (depending on the specific support of the exchange API).
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 the original conditional order information 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 the modified conditional order information 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 the original conditional order information 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 the modified conditional order information newOrder = exchange.GetConditionOrder(newId) Log("Modified Condition Order Info:", newOrder) # Cancel the conditional order exchange.CancelConditionOrder(newId)rustfn main() { // Create a take-profit conditional order let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 77.0, TpOrderPrice: 76.0, ..Default::default() }; let id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, &condition).unwrap(); Log!("Original Condition Order ID:", id); Sleep(2000); // Query the original conditional order information let order = exchange.GetConditionOrder(&id); Log!("Original Condition Order Info:", order); Sleep(1000); // Modify the quantity and trigger conditions of the conditional order let newCondition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 75.0, TpOrderPrice: 71.0, ..Default::default() }; let newId = exchange.ModifyConditionOrder(&id, "buy", 2, &newCondition).unwrap(); Log!("Modified Condition Order ID:", newId); Sleep(2000); // Query the modified conditional order information let newOrder = exchange.GetConditionOrder(&newId); Log!("Modified Condition Order Info:", newOrder); // Cancel the conditional order let _ = 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 the original conditional order information 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 the modified conditional order information auto newOrder = exchange.GetConditionOrder(newId); Log("Modified Condition Order Info:", newOrder); // Cancel the conditional order exchange.CancelConditionOrder(newId); } -
Use the additional parameter (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 (index) // Pass the additional parameter via the side parameter (in JSON format) 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 (index) # Pass the additional parameter via the side parameter (in JSON format) 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)rustfn main() { // Create a take-profit conditional order let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 77.0, TpOrderPrice: 76.0, ..Default::default() }; let id = exchange.CreateConditionOrder("SOL_USDT.swap", "buy", 1, &condition).unwrap(); Log!("Original Condition Order ID:", id); Sleep(2000); // Modify the conditional order and set the trigger price type to index price (index) // Pass the additional parameter via the side parameter (in JSON format; Rust has no JSON serialization here, so a raw string literal is used directly) let sideWithOption = r#"buy;{"newTpTriggerPxType": "index"}"#; let newCondition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 75.0, TpOrderPrice: 71.0, ..Default::default() }; let newId = exchange.ModifyConditionOrder(&id, sideWithOption, 2, &newCondition).unwrap(); Log!("Modified Condition Order ID:", newId); Sleep(2000); // Query the modified conditional order information let newOrder = exchange.GetConditionOrder(&newId); Log!("Modified Condition Order Info:", newOrder); // Cancel the conditional order let _ = 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 (index) // Pass the additional parameter via the side parameter (in JSON format) 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 | When the conditional order is successfully modified, the conditional order ID is returned; when the modification fails, a null value is returned. The returned conditional order ID may be the same as the original conditional order ID, or it may be different, depending on the specific implementation of the exchange API. Some exchanges return a new conditional order ID after modifying the conditional order, while some exchanges keep the conditional order ID unchanged. |
Arguments
| Name | Type | Required | Description |
orderId | string | Yes | The |
side | string | Yes | The For spot exchange objects, the available values for the For futures exchange objects, the available values for the Additional parameters (option) supported: Additional parameters can be passed through the For example: Additional parameters are used to modify other properties of the conditional order (such as the trigger price type, etc.), and the specific parameters supported depend on the exchange API. |
amount | number | Yes | The |
condition | object | Yes | The
|
See Also
Condition exchange.CreateConditionOrder exchange.CancelConditionOrder exchange.GetConditionOrder exchange.GetConditionOrders
Remarks
The conditional order ID returned by the exchange.ModifyConditionOrder() function may exhibit different behaviors 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 the validity of the parameters according to the exchange interface rules, but submits the parameters directly to the exchange API. When invalid parameters are passed in (such as an amount of -1), the parameter may be ignored by the exchange, and the conditional order retains its original properties unchanged.
Passing additional parameters (option) through the side parameter is supported, used to modify other properties of the conditional order. The 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 specifically check whether the exchange API supports it. Setting TpOrderPrice or SlOrderPrice in the condition parameter to -1 indicates a market order.
When modifying a conditional order, other properties of the conditional order (such as condition type, position mode, account mode, leverage, etc.) are usually retained from the original conditional order's settings. If you need to modify these properties, you can pass them in through additional parameters (option), provided that the exchange API supports it.
The trigger price type can be modified through additional parameters, for example, changing the trigger price type from the last price (last) to the index price (index) or the mark price (mark). The specific parameter names and support status depend on the exchange API documentation.
The support for the conditional order modification feature depends on the specific exchange. Some exchanges may not support the conditional order modification feature, or may only support modifying some parameters. Please consult the API documentation of the corresponding exchange before use.
exchange.CancelConditionOrder
exchange.CancelConditionOrder() function is used to cancel a conditional order. The format of the conditional order Id is similar to that of a regular order Id, consisting of the exchange symbol code and the exchange's original conditional order Id, separated by an English comma.
When calling the exchange.CancelConditionOrder() function to cancel a conditional order, the conditionOrderId parameter passed in is consistent with the Id attribute 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)rustfn main() { // Create a stop-loss conditional order let condition = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_SL, SlTriggerPrice: 58000.0, SlOrderPrice: -1.0, // Market order ..Default::default() }; let id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition).unwrap(); Sleep(1000); let _ = 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, with condition order information output.
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)rustfn main() { // Create several condition orders let condition1 = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 65000.0, TpOrderPrice: 65000.0, ..Default::default() }; let _ = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition1); let condition2 = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_SL, SlTriggerPrice: 58000.0, SlOrderPrice: 58000.0, ..Default::default() }; let _ = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition2); Sleep(1000); let orders = exchange.GetConditionOrders(None).unwrap(); for i in 0..orders.len() { // In Rust, CancelConditionOrder does not support extended parameters; output the accompanying information with Log let _ = exchange.CancelConditionOrder(&orders[i].Id); Log!("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 | An extended parameter used to output additional information to the log of this canceled conditional order. Multiple |
See Also
exchange.CreateConditionOrder exchange.GetConditionOrder exchange.GetConditionOrders exchange.ModifyConditionOrder
Remarks
The return value of the exchange.CancelConditionOrder() function only indicates whether the cancellation request was sent successfully or failed. To determine whether the exchange has actually canceled the conditional order, you can call the exchange.GetConditionOrders() function for confirmation.
Only untriggered conditional orders can be canceled; conditional orders that have already been triggered and converted into regular orders cannot be canceled through this function.
exchange.GetConditionOrder
The exchange.GetConditionOrder() function is used to retrieve information about a specified conditional order.
exchange.GetConditionOrder(conditionOrderId)Examples
javascript
function main(){
// Create a 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 number; fill in the number 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 a 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"])
rust
fn main() {
// Create a take-profit conditional order
let condition = OrderCondition {
ConditionType: ORDER_CONDITION_TYPE_TP,
TpTriggerPrice: 65000.0,
TpOrderPrice: 65000.0,
..Default::default()
};
let id = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition).unwrap();
Sleep(1000);
// The parameter id is the conditional order number; fill in the number of the conditional order you want to query
let order = exchange.GetConditionOrder(&id).unwrap();
Log!("Id:", order.Id, "Price:", order.Price, "Amount:", order.Amount,
"Status:", order.Status, "Type:", order.Type, "Condition:", order.Condition);
}
c++
void main() {
// Create a 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 |
| Query the details of a conditional order by its conditional order Id. When the query succeeds, the 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 the trigger condition, trigger price, and order status.
Conditional order statuses include: not triggered, triggered, canceled, etc. The specific status values are determined by the exchange.
exchange.GetConditionOrders
exchange.GetConditionOrders() function is used to obtain unfinished conditional orders (conditional orders that have not yet been triggered or canceled).
exchange.GetConditionOrders()
exchange.GetConditionOrders(symbol)Examples
-
Use the spot exchange object to create multiple condition orders, then query the 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])rustfn main() { // Create multiple condition orders let condition1 = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 65000.0, TpOrderPrice: 65000.0, ..Default::default() }; let _ = exchange.CreateConditionOrder("BTC_USDT", "sell", 0.01, &condition1); let condition2 = OrderCondition { ConditionType: ORDER_CONDITION_TYPE_TP, TpTriggerPrice: 3200.0, TpOrderPrice: 3200.0, ..Default::default() }; let _ = exchange.CreateConditionOrder("ETH_USDT", "sell", 0.1, &condition2); Sleep(1000); // Query all pending condition orders let orders = exchange.GetConditionOrders(None).unwrap(); Log!("Pending condition orders count:", orders.len()); for i in 0..orders.len() { 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 the pending condition orders for a specified trading pair.
javascriptfunction main() { // Query the pending condition orders for the BTC_USDT trading pair var orders = exchange.GetConditionOrders("BTC_USDT") Log("BTC_USDT pending condition orders:", orders) }pythondef main(): # Query the pending condition orders for the BTC_USDT trading pair orders = exchange.GetConditionOrders("BTC_USDT") Log("BTC_USDT pending condition orders:", orders)rustfn main() { // Query the pending condition orders for the BTC_USDT trading pair let orders = exchange.GetConditionOrders("BTC_USDT"); Log!("BTC_USDT pending condition orders:", orders); }c++void main() { // Query the pending condition orders for the BTC_USDT trading pair auto orders = exchange.GetConditionOrders("BTC_USDT"); Log("BTC_USDT pending condition orders:", orders); }
Returns
| Type | Description |
| The The returned Order structure contains a |
Arguments
| Name | Type | Required | Description |
symbol | string | No | The For spot exchange objects, when the For futures exchange objects, when the |
See Also
Remarks
In the GetConditionOrders function, the use cases of the symbol parameter are summarized as follows:
| Exchange Object Category | symbol Parameter | Query Scope | Remarks |
|---|---|---|---|
| Spot | symbol parameter not passed | Query all spot trading pairs | Applicable to all call scenarios; if the exchange interface does not support it, an error is reported and a null value is returned, which will not be repeated below |
| Spot | Specify a trading instrument, with symbol parameter as: "BTC_USDT" | Query the specified BTC_USDT trading pair | For spot exchange objects, the format of the symbol parameter is: "BTC_USDT" |
| Futures | symbol parameter not passed | Query all trading instruments within the dimension range of the current trading pair and contract code | Assuming the current trading pair is BTC_USDT and the contract code is swap, this queries all USDT-margined perpetual contracts. Equivalent to calling GetConditionOrders("USDT.swap") |
| Futures | Specify a trading instrument, with symbol parameter as: "BTC_USDT.swap" | Query the specified BTC USDT-margined perpetual contract | For futures exchange objects, the format of the symbol parameter is: a combination of the trading pair and contract code defined by the FMZ platform, with the two separated by the character ".". |
| Futures | Specify a range of trading instruments, with symbol parameter as: "USDT.swap" | Query all USDT-margined perpetual contracts | - |
| Futures exchange supporting options | symbol parameter not passed | Query all option contracts within the dimension range of the current trading pair | Assuming the current trading pair is BTC_USDT and the contract is set to an option contract, such as a Binance option contract: BTC-240108-40000-C |
| Futures exchange supporting options | Specify a specific trading instrument | Query the specified option contract | For example, for the Binance futures exchange, the symbol parameter is: BTC_USDT.BTC-240108-40000-C |
| Futures exchange supporting options | Specify a range of trading instruments, with symbol parameter as: "USDT.option" | Query all USDT-margined option contracts | - |
In the GetConditionOrders function, the query dimension ranges of the futures exchange object are summarized as follows:
| symbol Parameter | Request Scope Definition | Remarks |
|---|---|---|
| USDT.swap | USDT-margined perpetual contract range. | For dimensions not supported by the exchange API interface, an error is reported and a null value is 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 unfinished conditional orders within the query scope or on the specified trading instrument, calling this function will return 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 retrieve the historical conditional orders (including triggered, canceled, and expired conditional orders) for the current trading pair or contract, and supports specifying a particular trading instrument.
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. The returned results are sorted 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 the 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 the 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"])rustfn main() { let historyConditionOrders = exchange.GetHistoryConditionOrders(None, None, None).unwrap(); Log!("Historical condition orders count:", historyConditionOrders.len()); // Iterate and display; orders are sorted in ascending order by the Time property for i in 0..historyConditionOrders.len() { 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 the 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 the historical conditional orders of a specified trading pair, and limit the number of results returned.
javascriptfunction main() { // Query the 10 most recent historical conditional orders for the BTC_USDT trading pair var historyConditionOrders = exchange.GetHistoryConditionOrders("BTC_USDT", 0, 10) Log("BTC_USDT historical condition orders:", historyConditionOrders) }pythondef main(): # Query the 10 most recent historical conditional orders for the BTC_USDT trading pair historyConditionOrders = exchange.GetHistoryConditionOrders("BTC_USDT", 0, 10) Log("BTC_USDT historical condition orders:", historyConditionOrders)rustfn main() { // Query the 10 most recent historical conditional orders for the BTC_USDT trading pair let historyConditionOrders = exchange.GetHistoryConditionOrders("BTC_USDT", 0, 10); Log!("BTC_USDT historical condition orders:", historyConditionOrders); }c++void main() { // Query the 10 most recent historical conditional orders for the BTC_USDT trading pair auto historyConditionOrders = exchange.GetHistoryConditionOrders("BTC_USDT", 0, 10); Log("BTC_USDT historical condition orders:", historyConditionOrders); } -
Query historical conditional orders by time range.
javascriptfunction main() { // Query historical conditional orders starting from the 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 the 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)rustfn main() { // Query historical conditional orders starting from the specified timestamp let startTime: i64 = 1704067200000; // Timestamp for 2024-01-01 // In Rust, passing None for the symbol parameter means the current trading pair let historyConditionOrders = exchange.GetHistoryConditionOrders(None, startTime, 50); Log!("Historical condition orders since:", historyConditionOrders); }c++void main() { // Query historical conditional orders starting from the specified timestamp auto startTime = 1704067200000; // Timestamp for 2024-01-01 // In C++, the symbol parameter cannot be omitted; pass "" to indicate the current trading pair 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 you are querying conditional order data for an options contract, set the |
since | number | No | The |
limit | number | No | The |
See Also
Remarks
-
When the
symbol,since, andlimitparameters are not specified, the historical conditional orders of the current trading pair or contract are queried by default, i.e., the historical conditional orders within a certain range closest to the current time are queried. The query range depends on the single-query range of the exchange interface. -
When the
symbolparameter is specified, the historical conditional orders of the set trading instrument are queried. -
When the
sinceparameter is specified, the query starts from thesincetimestamp and proceeds toward the current time. -
When the
limitparameter is specified, the query returns after a sufficient number of records has been found. -
This function is only supported by exchanges that provide a historical conditional order query interface.
Historical conditional orders include conditional orders in states such as triggered (converted to regular orders), canceled, and expired.
The returned array of historical conditional orders is sorted in ascending order by order creation time (the Time attribute), i.e., orders with the earliest time are at the front of the array, and orders with the latest time are at the back.
Support for the conditional order feature depends on the specific exchange. Some exchanges may not support the conditional order feature or the historical conditional order query feature.
exchange.SetPrecision
The exchange.SetPrecision() function is used to set the precision of the price and order amount for the exchange exchange object. Once set, the system will automatically ignore any excess portion of the data that exceeds the specified precision.
exchange.SetPrecision(pricePrecision, amountPrecision)Examples
javascript
function main(){
// Set the price decimal precision to 2 digits and the order amount decimal precision to 3 digits
exchange.SetPrecision(2, 3)
}
python
def main():
exchange.SetPrecision(2, 3)
rust
fn main() {
// Set the price decimal precision to 2 digits and the order amount decimal precision to 3 digits
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 in the backtesting system is handled automatically by the system.
exchange.SetRate
Sets the current exchange rate for the exchange object.
exchange.SetRate(rate)Examples
javascript
function main(){
Log(exchange.GetTicker())
// Set the exchange rate conversion
exchange.SetRate(7)
Log(exchange.GetTicker())
// Set to 1, no conversion
exchange.SetRate(1)
}
python
def main():
Log(exchange.GetTicker())
exchange.SetRate(7)
Log(exchange.GetTicker())
exchange.SetRate(1)
rust
fn main() {
Log!(exchange.GetTicker(None));
// Set the exchange rate conversion
exchange.SetRate(7);
Log!(exchange.GetTicker(None));
// Set to 1, no conversion
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
If you set an exchange rate value using the exchange.SetRate() function (for example, set it to 7), then all price information represented by the current exchange object — such as tickers, depth, order prices, and so on — will be multiplied by the set rate of 7 for conversion.
For example, exchange is an exchange with USD as its quote currency. After executing exchange.SetRate(7), all prices in live trading will be multiplied by 7, converting them to prices close to those quoted in CNY.
exchange.IO
exchange.IO() function is used to call other interfaces related to the exchange object.
exchange.IO(k, ...args)Examples
-
Use the
"api"mode to call the OKX futures batch order placement interface, and pass the JSON-formatted order data via 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 placement 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)rustfn main() { // Rust has no JSON serialization; construct the order array directly using a raw string let 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"} ]"#; // Call exchange.IO to directly access the exchange's batch order placement interface; multiple parameters are passed in as a tuple let ret = exchange.IO(("api", "POST", "/api/v5/trade/batch-orders", "", 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 value of a key in the
paramsparameter is of string type, you need to wrap the parameter value with single quotes:javascriptvar amount = 1 var price = 10 var basecurrency = "ltc" function main () { // Note that there is a ' character on both the left and right sides of amount.toString() and price.toString() 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)rustfn main() { let amount = 1; let price = 10; let basecurrency = "ltc"; // Note that there is a ' character on both the left and right sides of the amount and price parameter values let message = format!("symbol={}&amount='{}'&price='{}'&side=buy&type=limit", basecurrency, amount, price); let 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 = str_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 passing in a complete URL: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)rustfn main() { let 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); } -
A GET request that does not use 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)rustfn main() { let 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 bot starts, the exchange object's current trading pair is BTC_USDT; print the ticker of the current trading pair Log(exchange.GetTicker()) // Switch the 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())rustfn main() { // For example, when the live bot starts, the exchange object's current trading pair is BTC_USDT; print the ticker of the current trading pair Log!(exchange.GetTicker(None)); // Switch the trading pair to LTC_BTC let _ = exchange.IO(("currency", "LTC_BTC")); Log!(exchange.GetTicker(None)); }c++void main() { Log(exchange.GetTicker()); exchange.IO("currency", "LTC_BTC"); Log(exchange.GetTicker()); } -
Switch the exchange API base address:
javascriptfunction main () { // exchanges[0] is the first exchange object added when the live bot was created exchanges[0].IO("base", "https://api.huobi.pro") }pythondef main(): exchanges[0].IO("base", "https://api.huobi.pro")rustfn main() { // exchanges[0] is the first exchange object added when the live bot was created let _ = exchanges[0].IO(("base", "https://api.huobi.pro")); }c++void main() { exchanges[0].IO("base", "https://api.huobi.pro"); } -
Switch the market data API 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")rustfn main() { exchange.SetBase("https://api.bitfinex.com"); let _ = 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 the 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)rustfn main() { let _ = exchange.IO(("simulate", true)); // Switch to demo trading environment // ... trading logic ... let _ = exchange.IO(("simulate", false)); // Switch back to live trading environment }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)rustfn main() { let _ = exchange.IO(("dual", true)); // Switch to hedge mode (dual position) let _ = exchange.IO(("dual", false)); // Switch to one-way mode let _ = exchange.SetContractType("swap"); let _ = exchange.IO(("cross", true)); // Switch to cross margin let _ = exchange.IO(("cross", false)); // Switch to isolated margin }c++void main() { exchange.IO("dual", true); exchange.IO("dual", false); exchange.SetContractType("swap"); exchange.IO("cross", true); exchange.IO("cross", false); } -
Switch to 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)rustfn main() { let _ = exchange.IO(("unified", true)); // Switch to unified account mode let _ = exchange.IO(("unified", false)); // Switch to normal mode }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")rustfn main() { // "NONE" means disable STP mode, other parameters: "EXPIRE_TAKER", "EXPIRE_MAKER", "EXPIRE_BOTH" let _ = exchange.IO(("selfTradePreventionMode", "NONE")); }c++void main() { exchange.IO("selfTradePreventionMode", "NONE"); } -
Futures_edgeX calculates the order Hash and signs it:
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)rustfn main() { let strJson = r#"{ "assetIdSynthetic": "0x4554482d3900000000000000000000", "assetIdCollateral": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "assetIdFee": "0x2ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c5", "isBuyingSynthetic": true, "amountSynthetic": 10000000, "amountCollateral": 13020000, "amountFee": 6250, "nonce": 676432751, "accountID": 601416704693633632, "expirationTimestamp": 484831 }"#; let signature = exchange.IO(("calcOrderHashAndSign", strJson)); 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 rate limiting - Limit GetTicker to a maximum of 10 calls per second; returns null when the limit is 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")rustfn main() { let _ = exchange.IO(("rate", "GetTicker", 10, "1s")); for _i in 0..20 { // GetTicker returns Err when the limit is exceeded match exchange.GetTicker("BTC_USDT") { Ok(ticker) => Log!("Ticker:", ticker.Last), Err(_) => Log!("Rate limit exceeded"), } } }c++// C++ is not supported yet -
rate mode rate limiting - Use the
"delay"parameter to automatically wait instead of returning null when the limit is exceeded: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"])rustfn main() { let _ = exchange.IO(("rate", "GetTicker", 10, "1s", "delay")); for i in 0..20 { let ticker = exchange.GetTicker("BTC_USDT").unwrap(); Log!("Call", i + 1, "Ticker:", ticker.Last); } }c++// C++ is not supported yet -
Multiple functions sharing a rate limit quota:
javascriptfunction main() { // GetTicker and GetDepth share the rate limit quota, with a 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"))rustfn main() { // GetTicker and GetDepth share the rate limit quota, with a combined maximum of 10 calls per second let _ = exchange.IO(("rate", "GetTicker,GetDepth", 10, "1s")); for i in 0..20 { if i % 2 == 0 { Log!("Ticker:", exchange.GetTicker("BTC_USDT")); } else { Log!("Depth:", exchange.GetDepth("BTC_USDT")); } } }c++// C++ is not supported yet -
Use a wildcard to uniformly limit the call frequency of all APIs:
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)rustfn main() { let _ = exchange.IO(("rate", "*", 100, "1m")); for i in 0..10 { let _ = exchange.GetTicker("BTC_USDT"); let _ = exchange.GetDepth("BTC_USDT"); let _ = exchange.GetAccount(); Log!("Round", i + 1, "completed"); Sleep(1000); } }c++// C++ is not supported yet -
quota mode - strict rate limiting aligned to time windows:
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)rustfn main() { let _ = exchange.IO(("quota", "GetTicker", 3, "1s")); for _i in 0..10 { match exchange.GetTicker("BTC_USDT") { Ok(ticker) => Log!(_D(None), "Ticker:", ticker.Last), Err(_) => Log!(_D(None), "Quota exceeded, waiting for next window"), } Sleep(100); } }c++// C++ not supported yet -
quota mode - intraday quota, resets daily at the specified time:
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)rustfn main() { let _ = exchange.IO(("quota", "GetTicker", 1000, "@0815")); let mut count = 0; loop { match exchange.GetTicker("BTC_USDT") { Ok(ticker) => { count += 1; Log!("Call count:", count, "Ticker:", ticker.Last); } Err(_) => { Log!("Daily quota exceeded, waiting for reset at 08:15"); Sleep(60000); // Wait 1 minute } } Sleep(1000); } }c++// C++ not supported yet -
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, cap of 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, cap of 1000 calls Log("Rate limits configured successfully") for i in range(5): exchange.GetTicker("BTC_USDT") exchange.GetDepth("BTC_USDT") Sleep(200)rustfn main() { let _ = exchange.IO(("rate", "GetTicker", 10, "1s")); // GetTicker 10 times per second let _ = exchange.IO(("rate", "GetDepth", 5, "1s")); // GetDepth 5 times per second let _ = exchange.IO(("rate", "CreateOrder", 2, "1s")); // CreateOrder 2 times per second let _ = exchange.IO(("quota", "*", 1000, "@0000")); // All APIs reset daily at 00:00, cap of 1000 calls Log!("Rate limits configured successfully"); for _i in 0..5 { let _ = exchange.GetTicker("BTC_USDT"); let _ = exchange.GetDepth("BTC_USDT"); Sleep(200); } }c++// C++ is not supported yet
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; please refer to the descriptions in each section below for details. |
arg | string / number / bool / object / array / any | Yes | Extended parameters. Different parameters need to be passed in according to the different |
See Also
Remarks
I. Directly Calling Exchange APIs ("api" mode)
javascript
exchange.IO("api", httpMethod, resource, params, raw)
Used to call the exchange's native API endpoints that are not wrapped by FMZ. 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 | Request parameters in URL-encoded format |
| raw | string | No | Raw request body (JSON, etc.) |
Returns a null value on failure, and this mode is only supported in live trading.
II. Switching Trading Pairs at Runtime ("currency" mode)
javascript
exchange.IO("currency", "ETH_USDT")
Used to dynamically switch trading pairs at runtime. The trading pair format is uppercase letters separated by an underscore. This instruction is equivalent to exchange.SetCurrency.
In backtesting mode, only spot is supported, and you can only switch to a trading pair with the same quote currency. After switching trading pairs for futures, you need to call
exchange.SetContractType()again.
III. Switching the Base Address ("base" / "mbase" mode)
-
"base": Switches the base address of the trading interface, equivalent toexchange.SetBase(). -
"mbase": Switches the base address of the market data interface, suitable for exchanges that use different domain names for market data and trading.
IV. Common Trading Mode Instructions
The following instructions are common across multiple exchanges. For the specific support of each exchange, please refer to the description in Section V.
| Instruction | 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 the 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 | Switch between demo and live trading |
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 the trading mode; cross must be used in 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 | Switch between demo and live trading |
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 the sub-account name |
Poloniex
| Command | Parameter | Description |
|---|---|---|
accountId | string | Set the account ID |
Bitfinex
| Command | Parameter | Description |
|---|---|---|
version | None | Get the 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 the API data source |
vaultAddress | string | Set the vault address; pass an empty string to disable |
walletAddress | string | Set the wallet address |
expiresAfter | number | Order expiration time (milliseconds); set to 0 to disable |
Futures Exchanges
Futures_Binance (Binance Futures)
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
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 extended fields in the API response (comma-separated) |
Futures_OKX (OKX Futures)
| Command | Parameter | Description |
|---|---|---|
simulate | bool | Switch between demo and live trading |
cross | bool | Cross/isolated margin; defaults to cross |
dual | bool | Hedge (long_short_mode)/one-way (net_mode) position mode |
Futures_HuobiDM (Huobi Futures)
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin; defaults to isolated. Only supported for XXX_USDT perpetual swaps (swap) |
dual | bool | Hedge (dual_side)/one-way (single_side) position mode |
unified | bool | Unified account mode |
signHost | string | Set the API signature Host address; pass an empty string to disable |
Futures_Bybit
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
dual | bool | Hedge/one-way position mode |
Futures_KuCoin
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
Futures_GateIO
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
dual | bool | Hedge/one-way position mode |
unified | bool | Unified account mode |
Futures_Bitget
| Command | Parameter | Description |
|---|---|---|
simulate | bool | Switch between demo and live trading |
cross | bool | Cross (crossed)/isolated (isolated) margin |
dual | bool | Hedge (hedge_mode)/one-way (one_way_mode) position mode |
Futures_MEXC
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
Futures_BitMEX
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
Futures_CoinEx
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
Futures_WOO
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
dual | bool | Hedge/one-way position mode |
Futures_Kraken
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin (only supported for multi-collateral accounts) |
Futures_Aevo
| Command | Parameter | Description |
|---|---|---|
signingKey | string | Set the signing key and return the public key. Must be obtained from the exchange's API Key page; note that it is time-sensitive |
Futures_Hyperliquid
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
source | "a"/"b" | Switch the API data source |
vaultAddress | string | Set the vault address; pass an empty string to disable |
walletAddress | string | Set the wallet address |
expiresAfter | number | Order expiration time (milliseconds); set to 0 to disable |
Futures_Deepcoin
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
merge | bool | Merge positions (true)/split positions (false) |
Futures_DigiFinex
| Command | Parameter | Description |
|---|---|---|
simulate | bool | Switch between demo and live trading |
cross | bool | Cross/isolated margin |
Futures_ApolloX
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
Futures_Aster
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
dual | bool | Hedge/one-way position mode |
Futures_CoinW
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
Futures_BitMart
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
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 |
expiry | number | Order expiration timestamp (milliseconds); defaults to 29 days, minimum 4 minutes |
Futures_Crypto.com
| Command | Parameter | Description |
|---|---|---|
accountId | string | Set the trading account ID |
Futures_Bitfinex
| Command | Parameter | Description |
|---|---|---|
mbase | string | Set the market data API base address |
Futures_edgeX
| Command | Parameter | Description |
|---|---|---|
calcOrderHashAndSign | string(JSON) | Compute the order hash and sign it; returns the signature string |
Futures_Bibox
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin; defaults to cross |
Futures_Pionex
| Command | Parameter | Description |
|---|---|---|
cross | bool | Cross/isolated margin |
dual | bool | Hedge/one-way position mode |
Futures_Phemex
| Command | Parameter | Description |
|---|---|---|
dual | bool | Hedge/one-way position mode. Cross/isolated margin must be set on the exchange's web interface |
Futures_WooFi
Only the generic commands
"api"and"currency"are supported; no exchange-specific commands.
VI. Special Platform IO Commands
Polymarket (Prediction Market)
| Command | Parameters | Description |
|---|---|---|
nonce | [number] | Gets or sets the order's nonce value. Returns the current nonce when no parameter is passed; sets a new nonce when a value is passed |
proxyWalletAddress | None | Gets the proxy wallet address |
redeem | symbol, [wait] | Redeems settled positions (gas-free via Relayer). wait defaults to true, waiting for transaction confirmation; when wait is false, returns {"transactionID": "..."} immediately |
merge | symbol, [amount], [wait] | Merges and redeems YES+NO tokens into USDC (gas-free via Relayer). When amount is 0 or not passed, automatically takes the smaller position size of the two outcomes. wait defaults to true, waiting for transaction confirmation |
l2_credentials | None | Gets L2 authentication information, returns {"apiKey":"","secret":"","passphrase":""}, used for scenarios such as WebSocket connections |
batchOrders | array | Batch order placement; the parameter is an array of order objects, each object containing symbol, side, price, amount fields, as well as an optional option field |
Web3 (Blockchain)
| Command | Parameters | Description |
|---|---|---|
abi | contract address, ABI string | Registers a contract ABI |
address | [private key] | Gets the wallet address |
encode / pack | type, data... | ABI-encodes data |
encodePacked | type, data... | ABI tightly-packed encodes data |
hash | param 1-4 | Computes the hash value |
decode / unpack | type, data... | ABI-decodes data |
key | string | Switches the private key used for operations |
IB (Interactive Brokers)
| Command | Parameters | Description |
|---|---|---|
status | None | Gets the connection status |
time | None | Gets the IB server time |
reqId | None | Forces retrieval of a new request ID |
orderId | None | Gets the next available order ID |
ignore | string (array) | Ignores the specified error codes |
scan | string (JSON) | Executes the market scanner |
wait | [number] | Waits for a market data event, with an optional 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; when caching is disabled, the rate limit is a maximum of 10 times per 30 seconds |
accounts | None | Gets the list of all accounts |
status | None | Gets the connection status |
lock | None | Locks trading |
unlock | None | Unlocks trading |
wait | None | Waits for a market data event |
VII. API Rate Limiting Control ("rate" / "quota" modes)
javascript
exchange.IO("rate", functionNames, maxCalls, period, [behavior])
exchange.IO("quota", functionNames, maxCalls, period, [behavior])
- rate: Smooth rate limiting, not strictly aligned to time windows.
- quota: Quota-based rate limiting, strictly aligned to time windows.
| Parameter | Type | Description |
|---|---|---|
| functionNames | string | Function names, separated by commas for multiple; * means all |
| maxCalls | number | Maximum number of calls within a single time period |
| period | string | Time period ("1s"/"1m"/"1h") or reset time point ("@0815") |
| behavior | string | Optional; "delay" means wait when the limit is exceeded, defaults to returning null |
The rate limiting of
Buy/Sellfollows the settings ofCreateOrder;Gofollows the settings of the actual concurrent function;IO/apionly takes effect forexchange.IO("api", ...).
exchange.Log
The exchange.Log() function is used to output order placement and cancellation logs in the log column area. When this function is called, it does not actually place an order; it is only used to output and record trading logs.
exchange.Log(orderType, price, amount)
exchange.Log(orderType, price, amount, ...args)Examples
Using exchange.Log(orderType, price, amount) allows you to perform live order-following tests and simulated order placement, and it can also assist in recording order information.
The most common use case is: accessing the exchange's conditional order creation interface through the exchange.IO function, but calling the exchange.IO() function does not output trading log information in the live log.
In this case, you can use the exchange.Log() function to supplement the log output in order to record the order information. The same applies to cancellation operations.
javascript
var id = 123
function main() {
// Order type buy, price 999, quantity 0.1
exchange.Log(LOG_TYPE_BUY, 999, 0.1)
// Cancel order
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)
rust
fn main() {
let id = 123;
// Order type buy, price 999, quantity 0.1
exchange.Log(LOG_TYPE_BUY, 999, 0.1);
// Cancel order; when orderType is LOG_TYPE_CANCEL, the price parameter is the order Id to be canceled (in Rust the amount parameter is required and can be passed as 0)
exchange.Log(LOG_TYPE_CANCEL, id, 0);
}
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 | An extension parameter used to output additional information to this log entry. Multiple |
See Also
Remarks
When the orderType parameter is LOG_TYPE_CANCEL, the price parameter represents the order Id to be canceled, which is used to print the cancellation log when canceling an order by directly calling the exchange.IO() function.
The exchange.Log() function is a member function of the exchange exchange object, which is distinct from the global function Log.
exchange.Encode
The exchange.Encode() function is used to perform signature and encryption computations.
exchange.Encode(algo, inputFormat, outputFormat, data)
exchange.Encode(algo, inputFormat, outputFormat, data, keyFormat, key)Examples
Example of BitMEX position change push (wss protocol):
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) {
var bitmexData = JSON.parse(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", str_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 It supports the following 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 calling the exchange.Encode() function.
exchange.Go
Multi-threaded asynchronous support function that can convert the operations of all supported functions into asynchronous concurrent execution.
exchange.Go(method)
exchange.Go(method, ...args)Examples
-
exchange.Go()function usage example. When checking forundefined, you must usetypeof(xx) === "undefined", becausenull == undefinedholds true in JavaScript.javascriptfunction main(){ // The following four operations execute concurrently in asynchronous multi-threaded mode; they take no 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 the wait method to wait for the result of the asynchronous ticker retrieval var ticker = a.wait() // Returns the depth data; it may also return null if the retrieval fails var depth = b.wait() // Returns the order ID with a 1-second timeout; returns undefined on timeout. If the previous wait timed out, this object can continue calling wait var orderId = c.wait(1000) if(typeof(orderId) == "undefined") { // Timed out, retrieve 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()rustfn main() { // In Rust, exchange.Go uses a typed form: use the Go:: method token to specify the concurrent function; pass () for no arguments and a tuple for arguments // The following four operations execute concurrently in asynchronous multi-threaded mode; they take no time and return immediately let a = exchange.Go(Go::GetTicker, ()); let b = exchange.Go(Go::GetDepth, ()); // There is no Buy token in Rust; it is equivalent to CreateOrder, where the first argument "" indicates the current trading pair let c = exchange.Go(Go::CreateOrder, ("", "buy", 1000, 0.1)); let d = exchange.Go(Go::GetRecords, (PERIOD_H1,)); // Call the wait method to wait for the result of the asynchronous ticker retrieval; wait(0) blocks until the concurrent thread finishes running (corresponding to the parameterless wait() in JS) let ticker = a.wait(0); // Returns the depth data; it may also return Err if the retrieval fails let depth = b.wait(0); // Returns the order ID with a 1-second timeout; returns Err on timeout. If the previous wait timed out, this object can continue calling wait // Note: Err may also indicate that the order placement itself failed (indistinguishable from a timeout); in this case, calling wait again will return Err and log the error message let mut orderId = c.wait(1000); if orderId.is_err() { // Timed out, retrieve again orderId = c.wait(0); } let records = d.wait(0); }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 raise an error:javascriptfunction main() { var d = exchange.Go("GetRecords", PERIOD_H1) // Wait for the K-line data results to return var records = d.wait() // Calling wait again here on an asynchronous operation that has already been waited on and finished will return null and log an error message var ret = d.wait() }pythondef main(): d = exchange.Go("GetRecords", PERIOD_H1) records, ok = d.wait() ret, ok = d.wait()rustfn main() { // In Rust, exchange.Go uses a typed syntax: specify the concurrent function via the Go:: method token let d = exchange.Go(Go::GetRecords, (PERIOD_H1,)); // Wait for the K-line data results to return; wait(0) blocks until execution completes (equivalent to JS's parameterless wait()) let records = d.wait(0); // Calling wait again here on an asynchronous operation that has already been waited on and finished will return Err and log an error message let ret = d.wait(0); }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)rustfn main() { loop { let beginTS = UnixNano() / 1000000; let mut arrRoutine = Vec::new(); let mut arrTicker = Vec::new(); let mut arrName = Vec::new(); for e in exchanges.iter() { // In Rust, exchange.Go is a typed form; the token is Go::GetTicker arrRoutine.push(e.Go(Go::GetTicker, ())); arrName.push(e.GetName()); } // On failure, record None as a placeholder to stay index-aligned with arrName for r in arrRoutine.iter() { arrTicker.push(r.wait(0).ok()); } let endTS = UnixNano() / 1000000; // Rust has no built-in JSON serialization; use format! to assemble the table's JSON text let mut rows = String::new(); for i in 0..arrTicker.len() { if let Some(ticker) = &arrTicker[i] { if !rows.is_empty() { rows.push(','); } rows += &format!(r#"[{}, "{}", {}]"#, i, arrName[i], ticker.Last); } } let tbl = format!(r#"{{"type": "table", "title": "Market Data", "cols": ["Index", "Name", "Last Price"], "rows": [{}]}}"#, rows); LogStatus!(_D(None), "Total time for concurrent ticker retrieval:", endTS - beginTS, "ms", "\n", format!("`{}`", tbl)); Sleep(500); } }c++void main() { while(true) { int length = exchanges.size(); auto beginTS = UnixNano() / 1000000; vector<Ticker> arrTicker(length); vector<string> arrName(length); // Note: run the exchanges[n].Go function once for each exchange object you add. This example requires adding four exchange objects; adjust as needed auto r0 = exchanges[0].Go("GetTicker"); auto r1 = exchanges[1].Go("GetTicker"); auto r2 = exchanges[2].Go("GetTicker"); auto r3 = exchanges[3].Go("GetTicker"); vector<GoObj*> arrRoutine = {&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] = str_format("%d", i); arr[1] = arrName[i]; arr[2] = str_format("%f", arrTicker[i].Last); tbl["rows"].push_back(arr); } LogStatus(_D(), "Total time for concurrent ticker retrieval:", str_format("%d", endTS - beginTS), "ms", "\n", "`" + tbl.dump() + "`"); Sleep(500); } } -
Concurrently call the
exchange.IO("api", ...)function:javascriptfunction main() { /* Test the OKX futures order placement endpoint 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")rustfn main() { /* Test the OKX futures order placement endpoint POST /api/v5/trade/order */ let beginTS = UnixNano() / 1000000; // Rust does not support JSON serialization, so construct the parameters directly using a raw string let param = r#"{"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"}"#; // In Rust, exchange.Go uses a typed form: the token is Go::IO, and the parameters are passed as a tuple let ret1 = exchange.Go(Go::IO, ("api", "POST", "/api/v5/trade/order", "", param)); let ret2 = exchange.Go(Go::IO, ("api", "POST", "/api/v5/trade/order", "", param)); let ret3 = exchange.Go(Go::IO, ("api", "POST", "/api/v5/trade/order", "", param)); let id1 = ret1.wait(0); let id2 = ret2.wait(0); let id3 = ret3.wait(0); let endTS = UnixNano() / 1000000; Log!("id1:", id1); Log!("id2:", id2); Log!("id3:", id3); Log!("Concurrent order time:", endTS - beginTS, "ms"); }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 the automatic release mechanism
javascriptfunction main() { var counter = 0 var arr = [] // Variables used to test persistently referencing concurrent objects 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 the concurrent object, used to call the r.wait() function to get the result; cleared every loop iteration // arr.push(r) // If this line is used, the runtime will persistently reference the concurrent objects, preventing them from being automatically released; when the number of concurrent tasks exceeds 2000, it will report an error: ```InternalError: too many routine wait, max is 2000```. counter++ } // Iterate over arrRoutine and call r.wait() to get the results LogStatus(_D(), "routine number:", counter) Sleep(50) } }rustfn main() { let mut counter = 0; let mut arr: Vec<TypedRoutine<Go::GetTicker>> = Vec::new(); // Variables used to test persistently referencing concurrent objects let symbols = ["BTC_USDT", "ETH_USDT", "SOL_USDT", "LTC_USDT", "EOS_USDT"]; loop { let mut arrRoutine = Vec::new(); for symbol in symbols { // In Rust, exchange.Go uses a typed form, with the token being Go::GetTicker let r = exchange.Go(Go::GetTicker, (symbol,)); arrRoutine.push(r); // Record the concurrent object, used to call the r.wait(0) function to get the result; cleared every loop iteration // arr.push(r); // If this line is used, the runtime will persistently reference the concurrent objects, preventing them from being automatically released; when the number of concurrent tasks exceeds 2000, it will report an error: InternalError: too many routine wait, max is 2000. counter += 1; } // Iterate over arrRoutine and call r.wait(0) to get the results LogStatus!(_D(None), "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 | The parameters of the concurrent execution function. The |
See Also
Mail_Go HttpQuery_Go EventLoop exchange.IO (API rate limiting control)
Remarks
This function only creates multi-threaded execution tasks when running in live trading. Backtesting does not support multi-threaded concurrent execution of tasks (it can be used in backtesting, but is still executed sequentially).
After the exchange.Go() function returns an object, you can call its wait() function through that object to obtain the data returned by the thread. When the concurrent multi-threaded tasks have finished executing and the related variables are no longer referenced, the underlying system will automatically handle resource reclamation.
The wait() method supports a timeout parameter:
-
Do not set the timeout parameter, i.e.
wait(), or set the timeout parameter to 0, i.e.wait(0). In this case, thewait()function will block and wait until the concurrent thread finishes running, and return the execution result of the concurrent thread. -
Set the timeout parameter to -1, i.e.
wait(-1). In this case, thewait()function will return immediately. The return value differs across programming languages; for details, please refer to the call examples in this section. -
Set a specific timeout parameter, i.e.
wait(300). In this case, thewait()function will wait at most 300 milliseconds before returning.
Although the underlying system has an automatic reclamation mechanism, if the related variables are continuously referenced, the 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. When these functions are called concurrently, they are all executed based on the current exchange exchange object.
The difference between the Python language and the JavaScript language is that in Python, the wait() function of a concurrent object returns two values: 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 is guaranteed to return True, unless the strategy is stopped
ret, ok = d.wait()
# If the wait times out, or you wait on an instance that has already finished, ok returns False
ret, ok = d.wait(100)
Account
exchange.GetAccount
The exchange.GetAccount() function is used to request the 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 the subsequent documentation.
exchange.GetAccount()Examples
Set the trading pair and contract code, and get the current account information.
javascript
function main(){
// Switch the trading pair
exchange.IO("currency", "BTC_USDT")
// Taking OKX Futures as an example, set the contract to the current-week contract. The current trading pair is BTC_USDT, so the current contract is the USDT-margined current-week contract of BTC
exchange.SetContractType("this_week")
// Get the current account asset data
var account = exchange.GetAccount()
// Available balance with USDT as margin
Log(account.Balance)
// Frozen amount with USDT as margin
Log(account.FrozenBalance)
// Current asset equity
Log(account.Equity)
// Unrealized profit and loss of all positions with the current assets as margin
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"])
rust
fn main() {
// Switch the trading pair
exchange.IO(("currency", "BTC_USDT")).unwrap();
// Taking OKX Futures as an example, set the contract to the current-week contract. The current trading pair is BTC_USDT, so the current contract is the USDT-margined current-week contract of BTC
exchange.SetContractType("this_week").unwrap();
// Get the current account asset data
let account = exchange.GetAccount().unwrap();
// Available balance with USDT as margin
Log!(account.Balance);
// Frozen amount with USDT as margin
Log!(account.FrozenBalance);
// Current asset equity
Log!(account.Equity);
// Unrealized profit and loss of all positions with the current assets as margin
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 |
| Queries the account asset information. Returns the |
See Also
Remarks
If the exchange object is set to a cryptocurrency futures contract exchange and switched to a contract that uses USDT as margin (for the switching method, please refer to the exchange.SetCurrency and exchange.SetContractType functions), the assets are then denominated in USDT as margin 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 a coin-margined contract, the assets are then denominated in the coin as margin and recorded in the Stocks and FrozenStocks properties of the Account structure.
When using a Binance Futures unified account, calling the exchange.GetAccount() function to request account information returns encapsulated data where all assets are converted into their value in **USD**, displayed in the Balance field of the Account structure. If you need to calculate the converted value of other assets, you can divide the USD-converted amount by the index price (of the asset to be converted), and then divide by the collateral ratio (of the asset to be converted).
exchange.GetAssets
The exchange.GetAssets function is used to request the asset information of the exchange account.
exchange.GetAssets()Examples
Get the asset information of the exchange account. The exchange.GetAssets() function returns an array with Asset structures as elements.
javascript
function main() {
// exchange.SetCurrency("BTC_USDT") // You can set the trading pair
// exchange.SetContractType("swap") // You can set the contract
var assets = exchange.GetAssets()
Log(assets)
}
python
def main():
# exchange.SetCurrency("BTC_USDT") # You can set the trading pair
# exchange.SetContractType("swap") # You can set the contract
assets = exchange.GetAssets()
Log(assets)
rust
fn main() {
// exchange.SetCurrency("BTC_USDT"); // You can set the trading pair
// exchange.SetContractType("swap").unwrap(); // You can set the contract
let assets = exchange.GetAssets().unwrap();
Log!(assets);
}
c++
void main() {
// exchange.SetCurrency("BTC_USDT"); // You can set the trading pair
// exchange.SetContractType("swap"); // You can set the contract
auto assets = exchange.GetAssets();
Log(assets);
}Returns
| Type | Description |
| The |
See Also
Remarks
The GetAssets() function of a futures exchange object returns the margin assets under the current trading pair (coin-margined, USDT-margined, USDC-margined, etc.).
exchange.GetName
The exchange.GetName() function is used to get the name of the exchange 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")
rust
fn 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 typically used to identify the exchange or exchanges[1], exchanges[2], and other exchange objects in the strategy code. The name of a cryptocurrency futures contract exchange carries the fixed prefix Futures_.
exchange.GetLabel
The exchange.GetLabel() function is used to obtain 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())
rust
fn main() {
Log!("exchange label:", exchange.GetLabel());
}
c++
void main() {
Log("exchange label:", exchange.GetLabel());
}Returns
| Type | Description |
string | The |
See Also
Remarks
By means of the label that was set, you can identify the exchange or exchanges[1], exchanges[2] and other exchange objects in the strategy code.
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())
rust
fn 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 uniformly uses uppercase, with an underscore separating 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 the 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())
rust
fn main() {
let ticker = exchange.GetTicker(None).unwrap();
Log!(ticker);
Log!(exchange.GetAccount());
// Switch the trading pair, note the changes in market data and account information after switching
exchange.SetCurrency("LTC_USDT");
Log!("Switched to LTC_USDT");
let ticker = exchange.GetTicker(None).unwrap();
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 the
exchange.IO("currency", "BTC_USDT")switching method, seeexcahnge.IOfor details. -
Switching trading pairs is supported in the backtesting system, but when switching trading pairs in the backtesting system, the name of the quote currency cannot be changed. For example:
BTC_USDTcan be switched toLTC_USDT, but cannot be switched toLTC_BTC. -
After switching to a trading pair other than the one initially set on the backtesting page, the amount of the base currency is 0. For example: during backtesting, the trading pair initially set on the backtesting page is
BTC_USDT, with 3BTCand 10000USDT. If you immediately switch toLTC_USDTat this point, the amount of the base currency after switching is 0, i.e., the amount ofLTCin the account is 0; the amount ofUSDTis shared after switching, i.e., the amount remains 10000.
exchange.GetQuoteCurrency
The exchange.GetQuoteCurrency() function is used to get the name of the quote currency 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())
rust
fn 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: when 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, then the exchange.GetQuoteCurrency() function returns BTC.
Futures
exchange.GetPositions
exchange.GetPositions() function is used to get position information; the GetPositions() function is a member function of the exchange object exchange.
GetPositions() function is used to get the position information of the exchange account bound to the exchange object exchange. The purpose of the member functions (methods) of the exchange object is only related to exchange, which will not be repeated in the rest of this document.
exchange.GetPositions()
exchange.GetPositions(symbol)Examples
Using the futures exchange object, place market orders on multiple symbols with different trading pairs and contract codes, and query position information through various methods.
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) + "`")
// After printing the information once, return to prevent subsequent order fills during backtesting from affecting 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
rust
/*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"}]
*/
fn main() {
let 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);
}
let defaultPositions = exchange.GetPositions(None).unwrap();
let swapPositions = exchange.GetPositions("USDT.swap").unwrap();
let futuresPositions = exchange.GetPositions("USDT.futures").unwrap();
let btcUsdtSwapPositions = exchange.GetPositions("BTC_USDT.swap").unwrap();
// The Rust SDK has no JSON serialization; use format! to concatenate the table's JSON text
let mut tbls: Vec<String> = Vec::new();
let arr = [defaultPositions, swapPositions, futuresPositions, btcUsdtSwapPositions];
let tblDesc = ["defaultPositions", "swapPositions", "futuresPositions", "btcUsdtSwapPositions"];
for (index, positions) in arr.iter().enumerate() {
let mut rows: Vec<String> = Vec::new();
for pos in positions {
rows.push(format!(r#"["{}", {}, {}, {}, {}, {}, {}, "{}", {}]"#, pos.Symbol, pos.MarginLevel, pos.Amount, pos.FrozenAmount, pos.Price, pos.Profit, pos.Type, pos.ContractType, pos.Margin));
}
let tbl = format!(r#"{{"type": "table", "title": "{}", "cols": ["Symbol", "MarginLevel", "Amount", "FrozenAmount", "Price", "Profit", "Type", "ContractType", "Margin"], "rows": [{}]}}"#, tblDesc[index], rows.join(","));
tbls.push(tbl);
}
LogStatus!(format!("`[{}]`", tbls.join(",")));
// After printing the information once, return to prevent subsequent order fills during backtesting from affecting data observation
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 are different from cryptocurrency spot; spot only has a logical concept of position. In the FMZ Quant Trading Platform system, the specific instrument of a cryptocurrency futures contract is jointly identified by the **trading pair** and the **contract code**. Refer to the exchange.SetCurrency and exchange.SetContractType functions.
In the GetPositions function, the usage scenarios of the symbol parameter are summarized as follows:
| Exchange Object Category | symbol Parameter | Query Scope | Remarks |
|---|---|---|---|
| Futures | symbol parameter not passed | Query all trading instruments within the dimension range of the current trading pair and contract code | If the current trading pair is BTC_USDT and the contract code is swap, it queries all USDT-margined perpetual contracts. Equivalent to calling GetPositions("USDT.swap") |
| Futures | Specify a trading instrument, symbol parameter is: "BTC_USDT.swap" | Query the specified BTC USDT-margined perpetual contract | For a futures exchange object, the format of the symbol parameter is: the combination of the trading pair and contract code defined by the FMZ platform, separated by the character ".". |
| Futures | Specify a range of trading instruments, symbol parameter is: "USDT.swap" | Query all USDT-margined perpetual contracts | - |
| Futures exchange supporting options | symbol parameter not passed | Query all option contracts within the dimension range of the current trading pair | If the current trading pair is BTC_USDT and the contract is set to an option contract, for example, a Binance option contract: BTC-240108-40000-C |
| Futures exchange supporting options | Specify a specific trading instrument | Query the specified option contract | For example, for the Binance futures exchange, the symbol parameter is: BTC_USDT.BTC-240108-40000-C |
| Futures exchange supporting options | Specify a range of trading instruments, symbol parameter is: "USDT.option" | Query all USDT-margined option contracts | - |
In the GetPositions function, the query dimension ranges of the futures exchange object are summarized as follows:
| symbol Parameter | Request Scope Definition | Remarks |
|---|---|---|
| USDT.swap | Scope of USDT-margined perpetual contracts. | For dimensions not supported by the exchange API interface, calling it will report an error and return a null value. |
| USDT.futures | Scope of USDT-margined delivery contracts. | - |
| USD.swap | Scope of coin-margined perpetual contracts. | - |
| USD.futures | Scope of coin-margined delivery contracts. | - |
| USDT.option | Scope of USDT-margined option contracts. | - |
| USD.option | Scope of coin-margined option contracts. | - |
| USDT.futures_combo | Scope of spread combo contracts. | Futures_Deribit exchange |
| USD.futures_ff | Scope of mixed-margin delivery contracts. | Futures_Kraken exchange |
| USD.swap_pf | Scope of mixed-margin perpetual contracts. | Futures_Kraken exchange |
Compatible with the exchange.GetPosition() call; GetPosition and GetPositions are used in exactly the same way.
When the account represented by the exchange object exchange has no positions within the query scope or on the specified trading instrument, 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 is also compatible with a calling method that passes only the marginLevel parameter, which is used to set the leverage value of 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)
rust
fn main() {
exchange.SetMarginLevel(10);
// In the Rust SDK, the SetMarginLevel function does not support the symbol parameter; it only sets the leverage value of the current trading pair or contract
// To set the leverage of the BTC_USDT.swap instrument to 15, you need to switch to that trading pair or contract first and then call exchange.SetMarginLevel(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 the leverage value.
For cryptocurrency futures contracts, the leverage mechanisms of different cryptocurrency futures contract exchanges are not unified.
On some exchanges, the leverage value of a futures contract is a parameter in the order-placing interface. In this case, calling the exchange.SetMarginLevel() function does not generate a network request; it merely sets the underlying leverage variable in the FMZ system (used for passing parameters to the order-placing interface).
On other exchanges, the leverage value of a futures contract is an independent setting of the exchange, which needs to be set through the exchange's website page or API interface. In this case, calling the exchange.SetMarginLevel() function will generate a network request and may fail to set the value. There can be various reasons for failure, for example: there are currently open positions or pending orders, which prevents a new leverage value from being set for that trading pair or contract.
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 calling the exchange.Buy function or exchange.Sell function to place futures contract orders.
exchange.SetDirection(direction)Examples
javascript
function main(){
// For example, set to OKX futures this-week contract
exchange.SetContractType("this_week")
// Set leverage to 5x
exchange.SetMarginLevel(5)
// Set the order direction to long
exchange.SetDirection("buy")
// Place an order at a price of 10000 with a quantity of 2 contracts
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)
rust
fn main() {
// Note: In the Rust SDK, using the SetDirection, Buy, and Sell functions is not recommended. It is advisable to prefer the CreateOrder function,
// CreateOrder can directly specify the side parameter ("buy", "sell", "closebuy", "closesell"), without needing to call SetDirection first
// For example, set to OKX futures this-week contract
exchange.SetContractType("this_week").unwrap();
// Set leverage to 5x
exchange.SetMarginLevel(5);
// Set the order direction to long
exchange.SetDirection("buy").unwrap();
// Place an order at a price of 10000 with a quantity of 2 contracts
exchange.Buy(10000, 2).unwrap();
exchange.SetMarginLevel(5);
exchange.SetDirection("closebuy").unwrap();
exchange.Sell(1000, 2).unwrap();
}
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 exchange.SetDirection() function is used to set the correspondence between the futures contract trading direction and the order-placing functions:
| Order Function | Direction Set by SetDirection | Remarks |
|---|---|---|
| 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 of the exchange exchange object.
exchange.SetContractType(symbol)Examples
-
Set the current contract to the current-week contract:
javascriptfunction main() { // Set to the current-week contract exchange.SetContractType("this_week") }pythondef main(): exchange.SetContractType("this_week")rustfn main() { // Set to the current-week contract exchange.SetContractType("this_week").unwrap(); }c++void main() { exchange.SetContractType("this_week"); } -
When setting a contract that uses
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() { // The default trading pair is BTC_USD; set the contract to current-week, which is a coin-margined contract exchange.SetContractType("this_week") Log("ticker:", exchange.GetTicker()) // Switch the trading pair, then set the contract, switching to a USDT-margined contract, as distinct from a 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())rustfn main() { // The default trading pair is BTC_USD; set the contract to current-week, which is a coin-margined contract exchange.SetContractType("this_week").unwrap(); Log!("ticker:", exchange.GetTicker(None)); // Switch the trading pair, then set the contract, switching to a USDT-margined contract, as distinct from a coin-margined contract exchange.IO(("currency", "BTC_USDT")).unwrap(); exchange.SetContractType("swap").unwrap(); Log!("ticker:", exchange.GetTicker(None)); }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 the contract to current-week var ret = exchange.SetContractType("this_week") // Returns the information of the current-week contract Log(ret) }pythondef main(): ret = exchange.SetContractType("this_week") Log(ret)rustfn main() { // Set the contract to current-week let ret = exchange.SetContractType("this_week").unwrap(); // Returns the information of the current-week contract 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, the codes for delivery contracts in cryptocurrency futures contracts generally include:
Unless otherwise specified, the codes for perpetual contracts in cryptocurrency futures contracts generally include:
|
See Also
Remarks
In cryptocurrency futures contract strategies, take switching to the BTC_USDT trading pair as an example:
After switching the trading pair using the exchange.SetCurrency("BTC_USDT") or exchange.IO("currency", "BTC_USDT") function, you need to call the exchange.SetContractType() function again to reset the contract, so as to determine the specific contract to operate on under the new trading pair. The system determines whether the contract is a coin-margined contract or a 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 BTC USDT-margined perpetual contract. If the trading pair is BTC_USD, using the exchange.SetContractType("swap") function to set the contract code to swap sets it to the BTC coin-margined perpetual contract.
Detailed introduction to the cryptocurrency futures contract exchanges supported by the platform. The contract naming conventions for each exchange are 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 offers pre-market trading contracts, whose delivery dates are fixed. Taking the exchange-defined contract code
HMSTR-USDT-250207as an example, first set the trading pair toHMSTR_USDTon the FMZ platform, then useexchange.SetContractType("HMSTR-USDT-250207")to set this contract.
For functions that support thesymbolparameter (such asexchange.GetTicker(),exchange.CreateOrder(), etc.), you can specify thesymbolparameter asHMSTR_USDT.HMSTR-USDT-250207to obtain market data for this contract or to place orders and perform other operations. -
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 usingUSDTas margin. Taking theBTCcontract as an example: callexchange.IO("currency", "BTC_USDT")to switch to a contract usingUSDTas margin,
or directly set the current trading pair toBTC_USDTwhen configuring live trading parameters and adding the exchange object. After switching the trading pair, you must call theexchange.SetContractType()function again to set the contract. -
Futures_BitMEX (BitMEX)
Set to perpetual contract:exchange.SetContractType("swap").
The delivery contracts on the Futures_BitMEX exchange are monthly contracts, with the following contract codes (January through December):code"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"Set a delivery contract:
exchange.SetContractType("December"). For example, when the trading pair is set toXBT_USDT, calling theexchange.SetContractType("December")function sets the USDT-margined December delivery contract for BTC (the corresponding actual contract code isXBTUSDTZ23).Summary of Futures_BitMEX contract information
Contract code defined by Futures_BitMEX Corresponding trading pair on FMZ Corresponding contract code on FMZ Remarks DOGEUSD DOGE_USD swap USD-denominated, XBT-settled. XBT is BTC. DOGEUSDT DOGE_USDT swap USDT-denominated, USDT-settled. XBTETH XBT_ETH swap ETH-denominated, XBT-settled. XBTEUR XBT_EUR swap EUR-denominated (EUR), XBT-settled. USDTUSDC USDT_USDC swap USDC-denominated, XBT-settled. ETHUSD_ETH ETH_USD_ETH swap USD-denominated, ETH-settled. XBTH24 XBT_USD March Expiry: March 2024, month code H; USD-denominated, XBT-settled. ETHUSDZ23 ETH_USD December Expiry: December 2023, month code Z; USD-denominated, XBT-settled. XBTUSDTZ23 XBT_USDT December Expiry: December 2023, month code Z; USDT-denominated, USDT-settled. ADAZ23 ADA_XBT December Expiry: December 2023, month code Z; XBT-denominated, XBT-settled. P_XBTETFX23 USDT_XXX P_XBTETFX23 Expiry: November 2023; denominated in percentage, 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 usingUSDTas margin. Taking theBTCcontract as an example, callexchange.IO("currency", "BTC_USDT")to switch to a contract usingUSDTas margin,
or directly set the current trading pair toBTC_USDTwhen configuring live trading parameters and adding the exchange object. After switching the trading pair, you must 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 in the specific options contract code defined by the exchange; for details, please refer to the Deribit official website. -
Futures_KuCoin
Coin-margined contracts: for example, set the trading pair toBTC_USD, then set the contract code, which yields a coin-margined contract.
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 using USDT as margin:
For example, set the trading pair toBTC_USDT, then set the contract code, which yields a contract using USDT as margin.
Set to perpetual contract:exchange.SetContractType("swap"). -
Futures_Binance
The Binance Futures exchange defaults to the perpetual contract of the current trading pair, with contract code:swap.
Set to perpetual contract:exchange.SetContractType("swap"). Binance's perpetual contracts support usingUSDTas margin; for example, for theUSDT-margined perpetual contract ofBTC, set the trading pair toBTC_USDT; Binance also supports coin-margined perpetual contracts, for example the coin-margined perpetual contract ofBTC, for which you set the trading pair toBTC_USD.
Set to quarterly contract:exchange.SetContractType("quarter"). Delivery contracts include coin-margined contracts (i.e., using the coin as margin); for example, to set the quarterly contract ofBTC, set the trading pair toBTC_USD, then callexchange.SetContractType("quarter")to set the coin-margined quarterly contract ofBTC.
Set to next-quarter contract:exchange.SetContractType("next_quarter"). For example, to set the coin-margined next-quarter contract ofBTC, set the trading pair toBTC_USD, then callexchange.SetContractType("next_quarter").
Binance supports someUSDT-margined delivery contracts. TakingBTCas an example, set the trading pair toBTC_USDT, then set the contract code.Supports Binance options contracts:
The options contract code format follows the exchange definition, for exampleBTC-241227-15000-C,XRP-240112-0.5-C,BTC-241227-15000-P. Taking the Binance options contract codeBTC-241227-15000-Pas an example: BTC is the option's underlying coin code, 241227 is the exercise date, 15000 is the strike price, P indicates a put option, and C indicates a call option.
For the specific type of option (European or American), please refer to the relevant documentation on the exchange's options contracts.
The exchange may impose restrictions on option sellers, requiring a separate application for eligibility. Binance options, for instance, require applying for seller eligibility. -
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, with 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.
Directly use the exchange's contract naming: for exampleETHUSDT-04APR25. Since some contract instruments on the Bybit exchange have no clear periodicity, the exchange-defined contract code is used directly for naming. -
Futures_Kraken
Defaults to the perpetual contract of the current trading pair, with 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.
Directly use the exchange's contract naming: for exampleFF_ETHUSD_250307. Since some contract instruments on the Kraken exchange have no clear periodicity, the exchange-defined contract code is used directly for naming. -
Futures_Bitfinex
Defaults to the perpetual contract of the current trading pair, with contract code:swap. -
Futures_Bitget
Defaults to the perpetual contract of the current trading pair, with contract code:swap.
Setting the trading pair toBTC_USDyields a coin-margined contract, and setting the trading pair toBTC_USDTyields aUSDT-settled contract. For simulation contracts, you can set the trading pair toSBTC_USDorBTC_SUSDT. -
Futures_dYdX (v4)
dYdX perpetual contract code:swap.
Set to perpetual contract:exchange.SetContractType("swap"). dYdX has only theUSD.swapinstrument dimension, and the margin used is USDC. -
Futures_MEXC
MEXC perpetual contract code:swap.
Set to perpetual contract:exchange.SetContractType("swap"). Setting the trading pair toBTC_USDyields a coin-margined contract, and setting the trading pair toBTC_USDTyields aUSDT-settled contract. -
Futures_Crypto
Tokens in the crypto.com exchange account can be converted into a USD-denominated allowance to be used as margin for contract trading.
Set to perpetual contract:exchange.SetContractType("swap"). For example, when the trading pair is set toBTC_USD, calling theexchange.SetContractType("swap")function sets the perpetual contract of BTC.
The delivery contracts on the crypto.com exchange are monthly contracts, with the following contract codes (January through December):code"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"Set a delivery contract:
exchange.SetContractType("October"). For example, when the trading pair is set toBTC_USD, calling theexchange.SetContractType("October")function sets the October delivery contract of BTC.
The contract code corresponding to the current moment isBTCUSD-231027. -
Futures_WOO
The Futures_WOO exchange supportsUSDT-margined contracts, with perpetual contract codeswap. For example, when the trading pair is set toBTC_USDT, calling theexchange.SetContractType("swap")function sets the current contract to the USDT-margined perpetual contract of BTC. -
Futures_Hyperliquid
The Futures_Hyperliquid exchange supportsUSDC-margined contracts, with perpetual contract codeswap. For example, when the trading pair is set toETH_USD, calling theexchange.SetContractType("swap")function sets the current contract to the USDC-margined perpetual contract of ETH.
Futures_Hyperliquid has only theUSD.swapinstrument dimension, and the margin used is USDC.
Futures_Hyperliquid supports HIP-3 instruments. -
Futures_Lighter
The Futures_Lighter exchange supportsUSDC-margined contracts, with perpetual contract codeswap. For example, when the trading pair is set toBTC_USDC, calling theexchange.SetContractType("swap")function sets the current contract to the USDC-margined perpetual contract of BTC.
Futures_Lighter supports perpetual contracts only. -
Futures_Backpack
The Futures_Backpack exchange supportsUSDC-margined contracts, with perpetual contract codeswap. For example, when the trading pair is set toETH_USDC, calling theexchange.SetContractType("swap")function sets the current contract to the USDC-margined perpetual contract of ETH. -
Futures_edgeX
The Futures_edgeX exchange supportsUSDT-margined contracts, with perpetual contract codeswap. For example, when the trading pair is set toBTC_USDT, calling theexchange.SetContractType("swap")function sets the current contract to the USDT-margined perpetual contract of BTC. -
Futures_WOOFI
The Futures_WOOFI exchange supportsUSDC-margined contracts, with perpetual contract codeswap. For example, when the trading pair is set toETH_USDC, calling theexchange.SetContractType("swap")function sets the current contract to the USDC-margined perpetual contract of ETH. -
Futures_Coinw
The Futures_Coinw exchange supportsUSDT-margined contracts, with perpetual contract codeswap. For example, when the trading pair is set toETH_USDT, calling theexchange.SetContractType("swap")function sets the current contract to the USDT-margined perpetual contract of ETH. -
Futures_Aster
The Futures_Aster exchange supportsUSDT-margined contracts, with perpetual contract codeswap. For example, when the trading pair is set toETH_USDT, calling theexchange.SetContractType("swap")function sets the current contract to the USDT-margined perpetual contract of ETH. -
Futures_DeepCoin
Coin-margined contracts: for example, set the trading pair toBTC_USD, then set the contract code, which yields a coin-margined contract.
Set to perpetual contract:exchange.SetContractType("swap").Contracts using USDT as margin:
For example, set the trading pair toBTC_USDT, then set the contract code, which yields a contract using USDT as margin.
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())
rust
fn 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 obtain the funding rate data for the current period.
exchange.GetFundings()
exchange.GetFundings(symbol)Examples
Using the futures exchange object, call the exchange.GetFundings() function in the backtesting system. Before any market data function is called, GetFundings returns only the Funding data of the current default trading pair; after a market data function is called, it returns the Funding data of all symbols that have been requested. 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 interval
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 (var 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 interval
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) + "`")
rust
/*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"}]
*/
fn main() {
// LPT_USDT.swap 4-hour interval
let 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);
}
let mut arr: Vec<Vec<Funding>> = Vec::new();
let 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.push(exchange.GetFundings(None).unwrap());
} else {
arr.push(exchange.GetFundings(p).unwrap());
}
}
// The Rust SDK has no JSON serialization; use format! to concatenate the table's JSON text
let mut tbls: Vec<String> = Vec::new();
for (index, fundings) in arr.iter().enumerate() {
let mut rows: Vec<String> = Vec::new();
for f in fundings {
rows.push(format!(r#"["{}", {}, "{}", "{} %"]"#, f.Symbol, f.Interval as f64 / 3600000.0, _D(f.Time), f.Rate * 100.0));
}
let tbl = format!(r#"{{"type": "table", "title": "{}", "cols": ["Symbol", "Interval", "Time", "Rate"], "rows": [{}]}}"#, arrParams[index], rows.join(","));
tbls.push(tbl);
}
LogStatus!(_D(None), "\n Requested symbols:", format!("{:?}", symbols), format!("\n`[{}]`", tbls.join(",")));
}
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 interval
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 |
| When the |
Arguments
| Name | Type | Required | Description |
symbol | string | No | The |
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 (for example USDT.swap) or is not passed in, the interface will report an error. When calling the GetFundings() function on such futures exchange objects, the symbol parameter must be specified as a specific perpetual contract in order to query the current-period funding rate data for that trading pair.
The exchange.GetFundings() function supports both live trading and the backtesting system.
Exchanges that do not support batch retrieval of funding rate data: Futures_Bitget, Futures_OKX, Futures_MEXC, Futures_Deribit, Futures_Crypto. When calling, you need to pass in the symbol parameter to specify the concrete trading pair code, for example: 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 URL of the exchange API interface used by the exchange exchange object.
exchange.SetBase(s)Examples
javascript
function main() {
// Use the default base URL
Log(exchange.GetTicker())
// Switch to 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())
rust
fn main() {
// Use the default base URL
Log!(exchange.GetTicker(None));
// Switch to https://aws.okx.com
exchange.SetBase("https://aws.okx.com");
Log!(exchange.GetTicker(None));
}
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
The backtesting system does not support switching the base URL of the exchange API interface, because the backtesting system is a sandbox simulation environment and does not actually access the exchange's API interface.
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())
rust
fn 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 configure the proxy settings of the exchange exchange object.
exchange.SetProxy(proxy)Examples
-
Configure a
socks5proxy for theexchangeexchange object:javascriptfunction main() { exchange.SetProxy("socks5://192.168.1.10:8080") // If the exchange market data interface cannot be accessed, set an available socks5 proxy to access the market data interface Log(exchange.GetTicker()) }pythondef main(): exchange.SetProxy("socks5://192.168.1.10:8080") Log(exchange.GetTicker())rustfn main() { exchange.SetProxy("socks5://192.168.1.10:8080"); // If the exchange market data interface cannot be accessed, set an available socks5 proxy to access the market data interface Log!(exchange.GetTicker(None)); }c++void main() { exchange.SetProxy("socks5://192.168.1.10:8080"); Log(exchange.GetTicker()); } -
In addition to **globally specifying** the IP address used by the
exchangeexchange object to send requests, specifying the IP address individually based on theexchangeis also supported:javascriptfunction main(){ exchange.SetProxy("ip://10.0.3.15") // The IP address used to send requests is 10.0.3.15 exchange.GetTicker() }pythondef main(): exchange.SetProxy("ip://10.0.3.15") exchange.GetTicker()rustfn main() { exchange.SetProxy("ip://10.0.3.15"); // The IP address used to send requests is 10.0.3.15 let _ = exchange.GetTicker(None); }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 a null value.
The proxy setting feature of the exchange.SetProxy() function only supports the rest protocol. Each exchange exchange object can be assigned one proxy. Once a proxy is set, all access to the exchange interface bound to that exchange exchange object will go through this proxy.
Setting a socks5 proxy is supported. Taking the first added exchange object exchange (i.e. exchanges[0]) as an example:
-
Set a proxy with no username and no password:
exchange.SetProxy("socks5://127.0.0.1:8889"). -
Set a proxy with a specified username and password:
exchange.SetProxy("socks5://username:[email protected]:8889"), whereusernameis the username andpasswordis the password. -
Switch back to normal mode without using a proxy:
exchange.SetProxy("").
Specifying the IP address used by the exchange exchange object to send requests is supported. For details, see Global specification.
exchange.SetTimeout
The exchange.SetTimeout() function is used to set the timeout for rest requests of 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())
rust
fn main() {
exchange.SetTimeout(3000);
Log!(exchange.GetTicker(None));
}
c++
void main() {
exchange.SetTimeout(3000);
Log(exchange.GetTicker());
}Arguments
| Name | Type | Required | Description |
timeout | number | Yes | The |
See Also
Remarks
The timeout parameter is a value in milliseconds, where 1000 milliseconds equals 1 second. This setting 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 of 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, it is determined to be a timeout, and the timed-out function call 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 current thread.
eventLoop()
eventLoop(timeout)Examples
Concurrently execute 3 threads, outputting the received event information; when a timeout occurs or it returns immediately, the output is null.
javascript
function main() {
var t1 = threading.Thread(function() {
while (true) {
var eventMsg = threading.currentThread().eventLoop() // Block and wait
// 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) // Return immediately
Log(_D(), "thread2 eventMsg:", eventMsg)
Sleep(5000)
}
})
var t3 = threading.Thread(function() {
while (true) {
var eventMsg = threading.currentThread().eventLoop(3000) // Set a 3-second timeout
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 |
See Also
Remarks
The processing mechanism of the eventLoop() function is consistent with that of 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 the{ a: 30, b: 20, c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" }tuple, as defined in thetypesparameter:tuple(a uint256,b uint8,c address). -
- Variable corresponding to
bytestype:
"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:
exchange.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:exchange.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 is used to set the RPC node address.
exchange.IO(k, address)Examples
javascript
function main() {
var chainRpc = "https://bsc-dataseed.binance.org"
exchange.IO("base", chainRpc) // Switch to the BSC chain
}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 (MACD) indicator.
TA.MACD(inReal)
TA.MACD(inReal, optInFastPeriod, optInSlowPeriod, optInSignalPeriod)Examples
javascript
function main(){
// You can fill in different K-line periods, such as PERIOD_M1, PERIOD_M30, PERIOD_H1......
var records = exchange.GetRecords(PERIOD_M15)
var macd = TA.MACD(records, 12, 26, 9)
// Checking the logs shows that three arrays are returned, corresponding to DIF, DEA, and MACD respectively
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])
rust
fn main() {
// You can fill in different K-line periods, such as PERIOD_M1, PERIOD_M30, PERIOD_H1......
let records = exchange.GetRecords(None, PERIOD_M15, None).unwrap();
let macd = TA.MACD(&records, 12, 26, 9);
// Checking the logs shows that three arrays are returned, corresponding to DIF, DEA, and MACD respectively
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 return value of 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 the algorithms of commonly used indicators and supports calls from JavaScript, Python, and C++ strategies. For details, see the open-source TA library code.
The default values of 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 (KDJ).
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])
rust
fn main() {
let records = exchange.GetRecords(None, PERIOD_M15, None).unwrap();
let kdj = TA.KDJ(&records, 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 return value of 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 of 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 (RSI).
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)
rust
fn main() {
let records = exchange.GetRecords(None, PERIOD_M30, None).unwrap();
let rsi = TA.RSI(&records, 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 of the TA.RSI() function is: 14.
TA.ATR
The TA.ATR() function is used to calculate the Average True Range indicator (ATR).
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)
rust
fn main() {
let records = exchange.GetRecords(None, PERIOD_M30, None).unwrap();
let atr = TA.ATR(&records, 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 return value of the |
Arguments
| Name | Type | Required | Description |
inPriceHLC |
| Yes | The |
optInTimePeriod | number | No | The |
See Also
Remarks
The default value of the optInTimePeriod parameter of the TA.ATR() function is: 14.
TA.OBV
TA.OBV() function is used to calculate the On-Balance Volume (OBV).
TA.OBV(inReal)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)
rust
fn main() {
let records = exchange.GetRecords(None, PERIOD_M30, None).unwrap();
let obv = TA.OBV(&records);
Log!(obv);
}
c++
void main() {
auto r = exchange.GetRecords(PERIOD_M30);
auto obv = TA.OBV(r);
Log(obv);
}Returns
| Type | Description |
array | The return value of the |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
See Also
TA.MA
The TA.MA() function is used to calculate the Moving Average indicator (Moving Average).
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)
rust
fn main() {
let records = exchange.GetRecords(None, PERIOD_M30, None).unwrap();
let ma = TA.MA(&records, 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 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 of the TA.MA() function is: 9.
TA.EMA
The TA.EMA() function is used to calculate the Exponential Moving Average (EMA) indicator.
TA.EMA(inReal)
TA.EMA(inReal, optInTimePeriod)Examples
javascript
function main(){
var records = exchange.GetRecords()
// Check whether the number of K-line Bars meets the period required for indicator calculation
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)
rust
fn main() {
let records = exchange.GetRecords(None, None, None).unwrap();
// Check whether the number of K-line Bars meets the period required for indicator calculation
if records.len() > 9 {
let ema = TA.EMA(&records, 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 of 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)
rust
fn main() {
let records = exchange.GetRecords(None, None, None).unwrap();
if records.len() > 20 {
let boll = TA.BOLL(&records, 20, 2.0);
let [upLine, midLine, downLine] = boll;
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 return value of the |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
period | number | No | The |
multiplier | number | No | The |
See Also
Remarks
The default values of the period and multiplier parameters of the TA.BOLL() function are 20 and 2, respectively.
TA.Alligator
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])
rust
fn main() {
let records = exchange.GetRecords(None, None, None).unwrap();
let alligator = TA.Alligator(&records, None, None, None);
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 return value of 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 of 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 (CMF) indicator.
TA.CMF(inReal)
TA.CMF(inReal, periods)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)
rust
fn main() {
let records = exchange.GetRecords(None, None, None).unwrap();
let cmf = TA.CMF(&records, None);
Log!(cmf);
}
c++
void main() {
auto records = exchange.GetRecords();
auto cmf = TA.CMF(records);
Log(cmf);
}Returns
| Type | Description |
array | The return value of the |
Arguments
| Name | Type | Required | Description |
inReal |
| Yes | The |
periods | number | No | The |
See Also
TA.Highest
The TA.Highest() function is used to calculate the highest price within a 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)
rust
fn main() {
let records = exchange.GetRecords(None, None, None).unwrap();
// Rust's TA.Highest has no attribute name parameter; first extract the opening price numeric sequence, then calculate (not including the current Bar)
let opens: Vec<f64> = records.iter().map(|r| r.Open).collect();
let highestForOpen = TA.Highest(&opens, 10);
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 the TA.Highest(records, 30, "High") function, if the period parameter period is set to 0, it means calculating all Bar in the K-line data passed in by the inReal parameter; if the attribute parameter attr is not specified, the data passed in by the inReal parameter is treated as an ordinary array.
TA.Lowest
The TA.Lowest() function is used to calculate the lowest price over a period.
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)
rust
fn main() {
let records = exchange.GetRecords(None, None, None).unwrap();
// Rust's TA.Lowest has no attribute-name parameter; first extract the opening price numeric sequence, then calculate (not including the current Bar)
let opens: Vec<f64> = records.iter().map(|r| r.Open).collect();
let lowestForOpen = TA.Lowest(&opens, 10);
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 the TA.Lowest(records, 30, "Low") function: if the period parameter period is set to 0, it means calculating over all Bar of the K-line data passed in via the inReal parameter; if the attribute parameter attr is not specified, the K-line data passed in via the inReal parameter is treated as an ordinary array.
When using the TA.Highest() and TA.Lowest() functions in a C++ strategy, note the following: the Highest() and Lowest() functions each have only 2 parameters, and the first parameter passed in is not the K-line data r obtained from calling auto r = exchange.GetRecords(), but rather requires calling a method of r to pass in specific attribute data. For example, pass in r.Close() for closing price data. The calling method for Close, High, Low, Open, Volume is the same as r.Close().
Test example for a C++ language strategy:
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 passed in is not r; you 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 (SMA) 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)
rust
fn main() {
let records = exchange.GetRecords(None, PERIOD_M30, None).unwrap();
let sma = TA.SMA(&records, 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 of 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 a file 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")
let retRename = os.rename(oldFileName, newFileName)
Log("retRename:", retRename) // retRename: true
}Returns
| Type | Description |
bool | Returns true when the operation succeeds, otherwise returns false. |
Arguments
| Name | Type | Required | Description |
oldName | string | Yes | The name or path of the original file. |
newName | string | Yes | The name or path of the new file. |
See Also
File ListFilesResult FileStat open fgets fputs mmap getRootDir listFiles exists remove mkdir rmdir rename stat exit
Remarks
This function can be used to rename a file or move a file to another directory. 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.