Returns the current version number of the system.
Current system version number, such as 3.6
.
string
Version()
function main() {
Log("version:", Version())
}
def main():
Log("version:", Version())
void main() {
Log("version:", Version());
}
The system version number is the version number of the docker’s program.
The sleep function, causing the program to pause for a period of time.
Sleep(millisecond)
The millisecond
parameter is used to set the duration of sleep and the number of milliseconds.
millisecond
true
number
function main() {
Sleep(1000 * 10) // Wait for 10 seconds
Log("Waited for 10 seconds")
}
def main():
Sleep(1000 * 10)
Log("Waited for 10 seconds")
void main() {
Sleep(1000 * 10);
Log("Waited for 10 seconds");
}
For example, when executing the Sleep(1000)
function, the program will sleep for 1 second. It supports operations with sleep time less than 1 millisecond, for example setting Sleep(0.1)
. It supports a minimum parameter of 0.000001
, i.e. nanosecond hibernation, where 1 nanosecond is equal to 1e-6
milliseconds.
When writing strategies in the Python
language, the Sleep(millisecond)
function should be used for polling interval, time-to-wait operations. It is not recommended to use the time.sleep(second)
function of Python
's time
library. This is because using the time.sleep(second)
function in a strategy makes the strategy program wait for a period of time actually when backtesting (not skipping on the time series of the backtesting system), so it causes the strategy to backtest very slowly.
Determine whether the running environment of the strategy is a backtesting system.
The strategy returns a true value, e.g.: true
when running in the backtesting system environment. The strategy returns a false value, e.g.: false
when running in a live trading environment.
bool
IsVirtual()
function main() {
if (IsVirtual()) {
Log("The current backtest system environment.")
} else {
Log("The current live trading environment.")
}
}
def main():
if IsVirtual():
Log("The current backtest system environment.")
else:
Log("The current live trading environment.")
void main() {
if (IsVirtual()) {
Log("The current backtest system environment.");
} else {
Log("The current live trading environment.");
}
}
Determine whether the current running environment is a backtesting system, which is used to be compatible with the difference between backtesting and live trading.
Send an email.
A successful email delivery returns a true value, e.g., true
, and a failed delivery returns a false value, e.g., false
.
bool
Mail(smtpServer, smtpUsername, smtpPassword, mailTo, title, body)
Used to specify the SMTP
service address of the email sender.
smtpServer
true
string
Used to specify the email address of the email sender.
smtpUsername
true
string
The SMTP
password for the email sender’s mailbox.
smtpPassword
true
string
Used to specify the email address of the email recipient.
mailTo
true
string
Email title.
title
true
string
Email body.
body
true
string
function main(){
Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
}
def main():
Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
void main() {
Mail("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body");
}
The smtpPassword
parameter sets the password for the SMTP
service, not the mailbox password.
When setting the smtpServer
parameter, if you need to change the port, you can add the port number directly in the parameter smtpServer
. For example: QQ mail smtp.qq.com:587
, which is available for testing.
If an error is reported: unencryped connection
, you need to modify the smtpServer
of the Mail
function. The parameter format is: ssl://xxx.com:xxx
, for example, the ssl
method of SMTP
for QQ mail: ssl://smtp.qq.com:465
or smtp://xxx.com:xxx
.
It does not work in the backtesting system.
{@fun/Global/Mail_Go Mail_Go}
Asynchronous version of the Mail
function.
The Mail_Go
function returns a concurrent object immediately, and you can use the wait
method of that concurrent object to get the result of the mail delivery. A successful mail delivery returns a true value, e.g., true
, and a failed delivery returns a false value, e.g., false
.
object
Mail_Go(smtpServer, smtpUsername, smtpPassword, mailTo, title, body)
It’s used to specify the SMTP
service address of the email sender.
smtpServer
true
string
It’s used to specify the email address of the email sender.
smtpUsername
true
string
The SMTP
password for the email sender’s mailbox.
smtpPassword
true
string
It’s used to specify the email address of the email recipient.
mailTo
true
string
Email title.
title
true
string
Email body.
body
true
string
function main() {
var r1 = Mail_Go("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
var r2 = Mail_Go("smtp.163.com", "asdf@163.com", "password", "111@163.com", "title", "body")
var ret1 = r1.wait()
var ret2 = r2.wait()
Log("ret1:", ret1)
Log("ret2:", ret2)
}
# Not supported.
// Not supported.
It does not work in the backtesting system.
{@fun/Global/Mail Mail}
Filter error logs.
SetErrorFilter(filters)
Regular expression string. filters true string
function main() {
SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused")
}
def main():
SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused")
void main() {
SetErrorFilter("502:|503:|tcp|character|unexpected|network|timeout|WSARecv|Connect|GetAddr|no such|reset|http|received|EOF|reused");
}
Filtering common errors.
function main() {
// A random query for a non-existent order with an id of 123, allowing the interface to report an error deliberately
var order = exchange.GetOrder("123")
Log(order)
// Filter http502 errors, GetOrder interface errors, after setting the error filter, the second call to GetOrder will no longer report errors
SetErrorFilter("502:|GetOrder")
order = exchange.GetOrder("123")
Log(order)
}
def main():
order = exchange.GetOrder("123")
Log(order)
SetErrorFilter("502:|GetOrder")
order = exchange.GetOrder("123")
Log(order)
void main() {
TId orderId;
Order order = exchange.GetOrder(orderId);
Log(order);
SetErrorFilter("502:|GetOrder");
order = exchange.GetOrder(orderId);
Log(order);
}
Filter an interface error message.
Error logs matched by this regular expression will not be uploaded to the log system. You can call it multiple times (no limit on the number of times) to set multiple filter conditions. Regular expressions set multiple times will be accumulated and take effect at the same time. You can set an empty string to reset the regular expression used to filter error logs: SetErrorFilter("")
. The filtered logs are no longer written to the database file corresponding to the live trading Id in the docker directory to prevent frequent error reporting from bloating the database file.
Get the live trading process Id.
Return the live trading process Id. string
GetPid()
function main(){
var id = GetPid()
Log(id)
}
def main():
id = GetPid()
Log(id)
void main() {
auto id = GetPid();
Log(id);
}
Get the last error message.
Last error message. string
GetLastError()
function main(){
// Because the order number 123 does not exist, so there will be an error.
exchange.GetOrder("123")
var error = GetLastError()
Log(error)
}
def main():
exchange.GetOrder("123")
error = GetLastError()
Log(error)
void main() {
// Order ID type: TId, so you can't pass in a string, we place an order that doesn't meet the exchange specification to trigger
exchange.GetOrder(exchange.Buy(1, 1));
auto error = GetLastError();
Log(error);
}
It does not work in the backtesting system.
Gets the strategy interaction command.
The format of the returned command is ControlName:Data
. ControlName
is the name of the control, and Data
is the data entered in the control. If the interactive control does not have input boxes, drop-down boxes and other components (for example, a button control without input boxes) then the returned command format is ControlName
, which returns the control name only.
string
GetCommand()
function main(){
while(true) {
var cmd = GetCommand()
if (cmd) {
Log(cmd)
}
Sleep(1000)
}
}
def main():
while True:
cmd = GetCommand()
if cmd:
Log(cmd)
Sleep(1000)
void main() {
while(true) {
auto cmd = GetCommand();
if(cmd != "") {
Log(cmd);
}
Sleep(1000);
}
}
Detects the interaction command and uses the Log
function to output the interaction command when it is detected.
function main() {
while (true) {
LogStatus(_D())
var cmd = GetCommand()
if (cmd) {
Log("cmd:", cmd)
var arr = cmd.split(":")
if (arr[0] == "buy") {
Log("Buy, the control without number")
} else if (arr[0] == "sell") {
Log("Sell, the control with the number of:", arr[1])
} else {
Log("Other controls trigger:", arr)
}
}
Sleep(1000)
}
}
def main():
while True:
LogStatus(_D())
cmd = GetCommand()
if cmd:
Log("cmd:", cmd)
arr = cmd.split(":")
if arr[0] == "buy":
Log("Buy, the control without number")
elif arr[0] == "sell":
Log("Sell, the control with the number of:", arr[1])
else:
Log("Other controls trigger:", arr)
Sleep(1000)
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
void split(const string& s,vector<string>& sv,const char flag = ' ') {
sv.clear();
istringstream iss(s);
string temp;
while (getline(iss, temp, flag)) {
sv.push_back(temp);
}
return;
}
void main() {
while(true) {
LogStatus(_D());
auto cmd = GetCommand();
if (cmd != "") {
vector<string> arr;
split(cmd, arr, ':');
if(arr[0] == "buy") {
Log("Buy, the control without number");
} else if (arr[0] == "sell") {
Log("Sell, the control with the number of:", arr[1]);
} else {
Log("Other controls trigger:", arr);
}
}
Sleep(1000);
}
}
For example, the strategy interactive control adds a control without an input box, the interactive control is named: buy
, the control description information is: buy
, which is a button control. Continue by adding a control with an input box. The interactive control is named: sell
and the control description message is: sell
, which is an interactive control that is a combination of a button and an input box. The interaction code is designed in the strategy to respond to the different interaction controls:
It does not work in the backtesting system.
Get the value of Meta written when generating the strategy registration code.
Meta
data.
string
GetMeta()
function main() {
// The maximum asset value of the denominated currency allowed by the strategy.
var maxBaseCurrency = null
// Get the metadata when creating the registration code.
var level = GetMeta()
// Detecting the conditions corresponding to Meta.
if (level == "level1") {
// -1 for unrestricted
maxBaseCurrency = -1
} else if (level == "level2") {
maxBaseCurrency = 10
} else if (level == "level3") {
maxBaseCurrency = 1
} else {
maxBaseCurrency = 0.5
}
while(1) {
Sleep(1000)
var ticker = exchange.GetTicker()
// Detect asset values
var acc = exchange.GetAccount()
if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks) {
// Stop executing strategy trading logic
LogStatus(_D(), "level:", level, "Positions exceeding the usage limit of the registration code will no longer execute the strategy trading logic!")
continue
}
// Other trading logic
// Normal output of status bar information
LogStatus(_D(), "level:", level, "The strategy is working properly! ticker data: \n", ticker)
}
}
def main():
maxBaseCurrency = null
level = GetMeta()
if level == "level1":
maxBaseCurrency = -1
elif level == "level2":
maxBaseCurrency = 10
elif level == "level3":
maxBaseCurrency = 1
else:
maxBaseCurrency = 0.5
while True:
Sleep(1000)
ticker = exchange.GetTicker()
acc = exchange.GetAccount()
if maxBaseCurrency != -1 and maxBaseCurrency < acc["Stocks"] + acc["FrozenStocks"]:
LogStatus(_D(), "level:", level, "Positions exceeding the usage limit of the registration code will no longer execute the strategy trading logic!")
continue
# Other trading logic
# Normal output of status bar information
LogStatus(_D(), "level:", level, "The strategy is working properly! ticker data: \n", ticker)
void main() {
auto maxBaseCurrency = 0.0;
auto level = GetMeta();
if (level == "level1") {
maxBaseCurrency = -1;
} else if (level == "level2") {
maxBaseCurrency = 10;
} else if (level == "level3") {
maxBaseCurrency = 1;
} else {
maxBaseCurrency = 0.5;
}
while(1) {
Sleep(1000);
auto ticker = exchange.GetTicker();
auto acc = exchange.GetAccount();
if (maxBaseCurrency != -1 && maxBaseCurrency < acc.Stocks + acc.FrozenStocks) {
// Stop execution strategy trading logic.
LogStatus(_D(), "level:", level, "Positions exceeding the usage limit of the registration code will no longer execute the strategy trading logic!");
continue;
}
// Other trading logic
// Normal output of status bar information
LogStatus(_D(), "level:", level, "The strategy is working properly! ticker data: \n", ticker);
}
}
Example application scenario: Use Meta
to limit the amount of assets operated by the strategy.
Application scenario: need to do capital limits for different strategy renters. The length of the Meta
value set when generating the registration code cannot exceed 190 characters, and the GetMeta()
function only supports live trading. If no metadata (Meta
) is set when generating a strategy registration code, the GetMeta()
function returns null. It does not work in the backtesting system.
For primitive Socket
access, supporting tcp
, udp
, tls
, unix
protocols. Support 4 popular communication protocols: mqtt
, nats
, amqp
, kafka
. Support for connecting to databases: sqlite3
, mysql
, postgres
, clickhouse
.
The Dial()
function returns null if it times out. A normal call returns a connection object that has three methods: read
, write
and close
. The read
method is used to read data, the write
method is used to send data and the close
method is used to close the connection.
The read
method supports the following parameters:
ws.read()
.ws.read(2000)
specifies a timeout of two seconds (2000 milliseconds).-1
means that the function returns immediately, regardless of the presence or absence of messages, for example: ws.read(-1)
.
Passing the parameter -2
means that the function returns immediately with or without a message, but only the latest message is returned, and the buffered message is discarded. For example, ws.read(-2)
.read()
function buffer description:
The incoming data pushed by the WebSocket protocol may cause data accumulation if the time interval between strategy read()
function calls is too long. These data are stored in the buffer, which has a data structure of a queue with a maximum of 2000. After 2000 is exceeded, the newest data enters the buffer and the oldest data is cleared out.
Scenario | No parameter | Parameter: -1 | Parameter: -2 | Parameter: 2000, in milliseconds |
---|---|---|---|---|
Data already in the buffer | Return oldest data immediately | Return oldest data immediately | Return latest data immediately | Return oldest data immediately |
No data in the buffer | Return when blocked to data | Return null immediately | Return null immediately | Wait 2000 ms, return null if no data, return null if there is data |
WebSocket connection is disconnected or reconnected by the underlying | read() function returns the empty string, i.e.: “”, and write() function returns 0. The situation is detected. You can close the connection using the close() function, or if you have set up automatic reconnection, you don’t need to close it, the system underlying will reconnect it automatically. |
object
Dial(address) Dial(address, timeout)
Request address. address true string timeout seconds, timeout false number
function main(){
// Dial supports tcp://,udp://,tls://,unix://protocol, you can add a parameter to specify the number of seconds for the timeout
var client = Dial("tls://www.baidu.com:443")
if (client) {
// write can be followed by a numeric parameter to specify the timeout, write returns the number of bytes successfully sent
client.write("GET / HTTP/1.1\nConnection: Closed\n\n")
while (true) {
// read can be followed by a numeric parameter specifying the timeout in milliseconds. Returning null indicates an error or timeout or that the socket has been closed
var buf = client.read()
if (!buf) {
break
}
Log(buf)
}
client.close()
}
}
def main():
client = Dial("tls://www.baidu.com:443")
if client:
client.write("GET / HTTP/1.1\nConnection: Closed\n\n")
while True:
buf = client.read()
if not buf:
break
Log(buf)
client.close()
void main() {
auto client = Dial("tls://www.baidu.com:443");
if(client.Valid) {
client.write("GET / HTTP/1.1\nConnection: Closed\n\n");
while(true) {
auto buf = client.read();
if(buf == "") {
break;
}
Log(buf);
}
client.close();
}
}
Example of a Dial function call:
function main() {
LogStatus("Connecting...")
// Accessing WebSocket interface of Binance
var client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
if (!client) {
Log("Connection failed, program exited")
return
}
while (true) {
// read returns only the data retrieved after the read call
var buf = client.read()
if (!buf) {
break
}
var table = {
type: 'table',
title: 'Ticker Chart',
cols: ['Currency', 'Highest', 'Lowest', 'Buy 1', 'Sell 1', 'Last traded price', 'Volume', 'Update time'],
rows: []
}
var obj = JSON.parse(buf)
_.each(obj, function(ticker) {
table.rows.push([ticker.s, ticker.h, ticker.l, ticker.b, ticker.a, ticker.c, ticker.q, _D(ticker.E)])
})
LogStatus('`' + JSON.stringify(table) + '`')
}
client.close()
}
import json
def main():
LogStatus("Connecting...")
client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr")
if not client:
Log("Connection failed, program exited")
return
while True:
buf = client.read()
if not buf:
break
table = {
"type" : "table",
"title" : "Ticker Chart",
"cols" : ['Currency', 'Highest', 'Lowest', 'Buy 1', 'Sell 1', 'Last traded price', 'Volume', 'Update time'],
"rows" : []
}
obj = json.loads(buf)
for i in range(len(obj)):
table["rows"].append([obj[i]["s"], obj[i]["h"], obj[i]["l"], obj[i]["b"], obj[i]["a"], obj[i]["c"], obj[i]["q"], _D(int(obj[i]["E"]))])
LogStatus('`' + json.dumps(table) + '`')
client.close()
void main() {
LogStatus("Connecting...");
auto client = Dial("wss://stream.binance.com:9443/ws/!ticker@arr");
if(!client.Valid) {
Log("Connection failed, program exited");
return;
}
while(true) {
auto buf = client.read();
if(buf == "") {
break;
}
json table = R"({
"type" : "table",
"title" : "Ticker Chart",
"cols" : ["Currency", "Highest", "Lowest", "Buy 1", "Sell 1", "Last traded price", "Volume", "Update time"],
"rows" : []
})"_json;
json obj = json::parse(buf);
for(auto& ele : obj.items()) {
table["rows"].push_back({ele.value()["s"], ele.value()["h"], ele.value()["l"], ele.value()["b"], ele.value()["a"], ele.value()["c"],
ele.value()["q"], _D(ele.value()["E"])});
}
LogStatus("`" + table.dump() + "`");
}
client.close();
}
To access the WebSocket ticker interface of Binance:
var ws = null
function main(){
var param = {
"op": "subscribe",
"args": [{
"channel": "tickers",
"instId": "BTC-USDT"
}]
}
// When calling Dial function, specify reconnect=true to set reconnection mode and payload to be the message sent when reconnecting. When the WebSocket connection is disconnected, it will reconnect and send messages automatically.
ws = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload="+ JSON.stringify(param))
if(ws){
var pingCyc = 1000 * 20
var lastPingTime = new Date().getTime()
while(true){
var nowTime = new Date().getTime()
var ret = ws.read()
Log("ret:", ret)
if(nowTime - lastPingTime > pingCyc){
var retPing = ws.write("ping")
lastPingTime = nowTime
Log("Send : ping", "#FF0000")
}
LogStatus("Current time:", _D())
Sleep(1000)
}
}
}
function onexit() {
ws.close()
Log("exit")
}
import json
import time
ws = None
def main():
global ws
param = {
"op": "subscribe",
"args": [{
"channel": "tickers",
"instId": "BTC-USDT"
}]
}
ws = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true&payload=" + json.dumps(param))
if ws:
pingCyc = 1000 * 20
lastPingTime = time.time() * 1000
while True:
nowTime = time.time() * 1000
ret = ws.read()
Log("ret:", ret)
if nowTime - lastPingTime > pingCyc:
retPing = ws.write("ping")
lastPingTime = nowTime
Log("Send: ping", "#FF0000")
LogStatus("Current time:", _D())
Sleep(1000)
def onexit():
ws.close()
Log("exit")
auto objWS = Dial("wss://ws.okx.com:8443/ws/v5/public|compress=gzip_raw&mode=recv&reconnect=true");
void main() {
json param = R"({
"op": "subscribe",
"args": [{
"channel": "tickers",
"instId": "BTC-USDT"
}]
})"_json;
objWS.write(param.dump());
if(objWS.Valid) {
uint64_t pingCyc = 1000 * 20;
uint64_t lastPingTime = Unix() * 1000;
while(true) {
uint64_t nowTime = Unix() * 1000;
auto ret = objWS.read();
Log("ret:", ret);
if(nowTime - lastPingTime > pingCyc) {
auto retPing = objWS.write("ping");
lastPingTime = nowTime;
Log("Send: ping", "#FF0000");
}
LogStatus("Current time:", _D());
Sleep(1000);
}
}
}
void onexit() {
objWS.close();
Log("exit");
}
Access to OKX’s WebSocket ticker interface:
var ws = null
function main(){
var param = {"sub": "market.btcusdt.detail", "id": "id1"}
ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload="+ JSON.stringify(param))
if(ws){
while(1){
var ret = ws.read()
Log("ret:", ret)
// Respond to heartbeat packet operations
try {
var jsonRet = JSON.parse(ret)
if(typeof(jsonRet.ping) == "number") {
var strPong = JSON.stringify({"pong" : jsonRet.ping})
ws.write(strPong)
Log("Respond to ping, send pong:", strPong, "#FF0000")
}
} catch(e) {
Log("e.name:", e.name, "e.stack:", e.stack, "e.message:", e.message)
}
LogStatus("Current time:", _D())
Sleep(1000)
}
}
}
function onexit() {
ws.close()
Log("Execute the ws.close() function")
}
import json
ws = None
def main():
global ws
param = {"sub" : "market.btcusdt.detail", "id" : "id1"}
ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + json.dumps(param))
if ws:
while True:
ret = ws.read()
Log("ret:", ret)
# Respond to heartbeat packet operations
try:
jsonRet = json.loads(ret)
if "ping" in jsonRet and type(jsonRet["ping"]) == int:
strPong = json.dumps({"pong" : jsonRet["ping"]})
ws.write(strPong)
Log("Respond to ping, send pong:", strPong, "#FF0000")
except Exception as e:
Log("e:", e)
LogStatus("Current time:", _D())
Sleep(1000)
def onexit():
ws.close()
Log("Execute the ws.close() function")
using namespace std;
void main() {
json param = R"({"sub" : "market.btcusdt.detail", "id" : "id1"})"_json;
auto ws = Dial("wss://api.huobi.pro/ws|compress=gzip&mode=recv&reconnect=true&payload=" + param.dump());
if(ws.Valid) {
while(true) {
auto ret = ws.read();
Log("ret:", ret);
// Respond to heartbeat packet operations
try
{
auto jsonRet = json::parse(ret);
if(jsonRet["ping"].is_number()) {
json pong = R"({"pong" : 0})"_json;
pong["pong"] = jsonRet["ping"];
auto strPong = pong.dump();
ws.write(strPong);
Log("Respond to ping, send pong:", strPong, "#FF0000");
}
} catch(exception &e)
{
Log("e:", e.what());
}
LogStatus("Current time:", _D());
Sleep(1000);
}
}
}
void onexit() {
// ws.close();
Log("Execute the ws.close() function");
}
Access to Huobi’s WebSocket ticker interface:
function getLogin(pAccessKey, pSecretKey, pPassphrase) {
// Signature function for login
var ts = (new Date().getTime() / 1000).toString()
var login = {
"op": "login",
"args":[{
"apiKey" : pAccessKey,
"passphrase" : pPassphrase,
"timestamp" : ts,
"sign" : exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey) // exchange.HMAC has been deprecated and is temporarily supported. Please use the latest exchange.Encode function instead.
}]
}
return login
}
var client_private = null
function main() {
// Because the read function uses a timeout setting, filtering the timeout reports errors that would otherwise be output with redundant errors
SetErrorFilter("timeout")
// Position channel subscription information
var posSubscribe = {
"op": "subscribe",
"args": [{
"channel": "positions",
"instType": "ANY"
}]
}
var accessKey = "xxx"
var secretKey = "xxx"
var passphrase = "xxx"
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
client_private.write(JSON.stringify(getLogin(accessKey, secretKey, passphrase)))
Sleep(3000) // When logging in, you cannot subscribe to private channels immediately, you need to wait for server response
client_private.write(JSON.stringify(posSubscribe))
if (client_private) {
var lastPingTS = new Date().getTime()
while (true) {
var buf = client_private.read(-1)
if (buf) {
Log(buf)
}
// Detect disconnection, reconnect
if (buf == "" && client_private.write(JSON.stringify(posSubscribe)) == 0) {
Log("Disconnection detected, close connection, reconnect")
client_private.close()
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
client_private.write(JSON.stringify(getLogin(accessKey, secretKey, passphrase)))
Sleep(3000)
client_private.write(JSON.stringify(posSubscribe))
}
// Send heartbeat packets
var nowPingTS = new Date().getTime()
if (nowPingTS - lastPingTS > 10 * 1000) {
client_private.write("ping")
lastPingTS = nowPingTS
}
}
}
}
function onexit() {
var ret = client_private.close()
Log("Close the connection!", ret)
}
import json
import time
def getLogin(pAccessKey, pSecretKey, pPassphrase):
ts = str(time.time())
login = {
"op": "login",
"args":[{
"apiKey" : pAccessKey,
"passphrase" : pPassphrase,
"timestamp" : ts,
"sign" : exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey)
}]
}
return login
client_private = None
def main():
global client_private
SetErrorFilter("timeout")
posSubscribe = {
"op": "subscribe",
"args": [{
"channel": "positions",
"instType": "ANY"
}]
}
accessKey = "xxx"
secretKey = "xxx"
passphrase = "xxx"
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
client_private.write(json.dumps(getLogin(accessKey, secretKey, passphrase)))
Sleep(3000)
client_private.write(json.dumps(posSubscribe))
if client_private:
lastPingTS = time.time() * 1000
while True:
buf = client_private.read(-1)
if buf:
Log(buf)
if buf == "" and client_private.write(json.dumps(posSubscribe)) == 0:
Log("Disconnection detected, close connection, reconnect")
ret = client_private.close()
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private")
client_private.write(json.dumps(getLogin(accessKey, secretKey, passphrase)))
Sleep(3000)
client_private.write(json.dumps(posSubscribe))
nowPingTS = time.time() * 1000
if nowPingTS - lastPingTS > 10 * 1000:
client_private.write("ping")
lastPingTS = nowPingTS
def onexit():
ret = client_private.close()
Log("Close the connection!", ret)
auto client_private = Dial("wss://ws.okx.com:8443/ws/v5/private");
json getLogin(string pAccessKey, string pSecretKey, string pPassphrase) {
auto ts = std::to_string(Unix());
json login = R"({
"op": "login",
"args": [{
"apiKey": "",
"passphrase": "",
"timestamp": "",
"sign": ""
}]
})"_json;
login["args"][0]["apiKey"] = pAccessKey;
login["args"][0]["passphrase"] = pPassphrase;
login["args"][0]["timestamp"] = ts;
login["args"][0]["sign"] = exchange.HMAC("sha256", "base64", ts + "GET" + "/users/self/verify", pSecretKey);
return login;
}
void main() {
SetErrorFilter("timeout");
json posSubscribe = R"({
"op": "subscribe",
"args": [{
"channel": "positions",
"instType": "ANY"
}]
})"_json;
auto accessKey = "xxx";
auto secretKey = "xxx";
auto passphrase = "xxx";
client_private.write(getLogin(accessKey, secretKey, passphrase).dump());
Sleep(3000);
client_private.write(posSubscribe.dump());
if (client_private.Valid) {
uint64_t lastPingTS = Unix() * 1000;
while (true) {
auto buf = client_private.read(-1);
if (buf != "") {
Log(buf);
}
if (buf == "") {
if (client_private.write(posSubscribe.dump()) == 0) {
Log("Disconnection detected, close connection, reconnect");
client_private.close();
client_private = Dial("wss://ws.okx.com:8443/ws/v5/private");
client_private.write(getLogin(accessKey, secretKey, passphrase).dump());
Sleep(3000);
client_private.write(posSubscribe.dump());
}
}
uint64_t nowPingTS = Unix() * 1000;
if (nowPingTS - lastPingTS > 10 * 1000) {
client_private.write("ping");
lastPingTS = nowPingTS;
}
}
}
}
void onexit() {
client_private.close();
Log("exit");
}
To access OKX’s WebSocket authentication interface:
var client = null
function main() {
// client = Dial("sqlite3://:memory:") // Using an in-memory database
client = Dial("sqlite3://test1.db") // Open/connect to the database file in the docker's directory
// record handle
var sqlite3Handle = client.fd()
Log("sqlite3Handle:", sqlite3Handle)
// Querying tables in the database
var ret = client.exec("SELECT name FROM sqlite_master WHERE type='table'")
Log(ret)
}
function onexit() {
Log("Execute client.close()")
client.close()
}
// Not supported
// Not supported
The connection object returned by the Dial function when connecting to a database has two method functions that are unique to it:
exec(sqlString)
: Used to execute SQL statements in a manner similar to the DBExec()
function.fd()
: The fd()
function returns a handle (e.g., the handle variable is handle) to be used by other threads to reconnect (even if the object created by Dial has already been closed by the execution of the close()
function to close the connection) by passing the handle into the Dial()
function, for example, Dial(handle)
reuse connection.
The following is an example of the Dial function connecting to a sqlite3
database.Details of the address
parameter, separated by the |
symbol after the normal address: wss://ws.okx.com:8443/ws/v5/public
. If there are |
characters in the parameter string, then ||
is used as the separator sign. The part after that is some function parameter settings, and each parameter is connected with &
characters. For example, the ss5
proxy and compression parameters can be set together as follows: Dial("wss://ws.okx.com:8443/ws/v5/public|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv")
Functions supported by the address parameter of the Dial function | Parameter description |
---|---|
Parameters related to WebSocket protocol data compression: compress=parameter value | compress is the compression method, compress parameter options are: gzip_raw, gzip, etc. If the gzip method is not standard gzip, you can use the extended method: gzip_raw |
Parameters related to WebSocket protocol data compression: mode=parameter value | mode is the compression mode, mode parameter can be dual, send, recv. dual is two-way compression, send compressed data, receive compressed data. send is send compressed data. recv is receive compressed data, local decompression. |
WebSocket protocol sets the underlying auto-reconnect related parameters: reconnect=parameter value | reconnect is whether to set reconnect, reconnect=true is to enable reconnect. The default is no reconnect when this parameter is not set. |
WebSocket protocol sets the underlying auto-reconnect related parameters: interval=parameter value | interval is the retry interval, in milliseconds, interval=10000 is the retry interval of 10 seconds, the default is 1 second when it’s not set, that is, interval=1000. |
WebSocket protocol sets the underlying auto-reconnect related parameters: payload=parameter value | payload is the subscription message that needs to be sent when the WebSocket is reconnected, e.g.: payload=okokok. |
Parameters related to socks5 proxy: proxy=parameter value | proxy is ss5 proxy setting, parameter value format: socks5://name:pwd@192.168.0.1:1080, name is ss5 server username, pwd is ss5 server login password, 1080 is ss5 service port. |
The Dial()
function is only supported for live trading.
When connecting to a database using the Dial function, the connection string is written with reference to the go language driver project for each database.
Databases supported | Driving projects | Connection string | Remarks |
---|---|---|---|
sqlite3 | github.com/mattn/go-sqlite3 | sqlite3://file:test.db?cache=shared&mode=memory | The sqlite3:// prefix indicates that a sqlite3 database is being 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 | – |
Please note that when the payload
content set in the address
parameter contains characters =
or other special characters, it may affect the parsing of the address
parameter of the Dial
function, such as the following example.
backPack Exchange websocket private interface call example:
var client = null
function main() {
// Base64-encoded public key of the key pair, i.e. the access key configured on FMZ
var base64ApiKey = "xxx"
var ts = String(new Date().getTime())
var data = "instruction=subscribe×tamp=" + ts + "&window=5000"
// Since signEd25519 returns a base64 encoding, it contains the character "="
var signature = signEd25519(data)
// The payload may contain the character "=" after being encoded by JSON
payload = {
"method": "SUBSCRIBE",
"params": ["account.orderUpdate"],
"signature": [base64ApiKey, signature, ts, "5000"]
}
client = Dial("wss://ws.backpack.exchange")
client.write(JSON.stringify(payload))
if (!client) {
Log("Connection failed, program exited")
return
}
while (true) {
var buf = client.read()
Log(buf)
}
}
function onexit() {
client.close()
}
function signEd25519(data) {
return exchange.Encode("ed25519.seed", "raw", "base64", data, "base64", "{{secretkey}}")
}
The following call in the code works fine:
client = Dial("wss://ws.backpack.exchange")
client.write(JSON.stringify(payload))
If you write it directly in payload
, it will not work properly, for example:
client = Dial("wss://ws.backpack.exchange|payload=" + JSON.stringify(payload))
Currently, only JavaScript supports the use of the mqtt
, nats
, amqp
, and kafka
communication protocols in the Dial function. The JavaScript language strategy code is used as an example to show the use of the four protocols: mqtt
, nats
, amqp
, and kafka
:
// We need to configure and deploy proxy servers for each protocol first.
// For the sake of demonstration, the subscription (read operation) and publishing (write operation) of the topic test_topic are all performed in the current strategy.
var arrConn = []
var arrName = []
function main() {
LogReset(1)
conn_nats = Dial("nats://admin@127.0.0.1:4222?topic=test_topic")
conn_mqtt = Dial("mqtt://127.0.0.1:1883?topic=test_topic")
conn_amqp = Dial("amqp://q:admin@127.0.0.1:5672/?queue=test_Queue")
conn_kafka = Dial("kafka://localhost:9092/test_topic")
arrConn = [conn_nats, conn_amqp, conn_mqtt, conn_kafka]
arrName = ["nats", "amqp", "mqtt", "kafka"]
while (true) {
for (var i in arrConn) {
var conn = arrConn[i]
var name = arrName[i]
// Write data
conn.write(name + ", time: " + _D() + ", test msg.")
// Read data
var readMsg = conn.read(1000)
Log(name + " readMsg: ", readMsg, "#FF0000")
}
Sleep(1000)
}
}
function onexit() {
for (var i in arrConn) {
arrConn[i].close()
Log("close", arrName[i], "connect")
}
}
Detailed documentation reference: Exploring FMZ: Practice of Communication Protocol Between Live Trading Strategies
Send an Http request.
Returns the response data of the request. If the return value is a JSON
string, it can be parsed by the JSON.parse()
function in the JavaScript
language strategy, and by the json::parse()
function in the C++
language strategy. If debug is set to true in the options structure, the return value is an object (JSON); if debug is set to false, the return value is a string.
string, object
HttpQuery(url) HttpQuery(url, options)
Http request url. url true string Http request-related settings, for example, can be structured as follows:
{
method: "POST",
body: "a=10&b=20&c=30",
charset: "UTF-8",
cookie: "session_id=12345; lang=en",
profile: "chrome_103",
debug: false,
headers: {"TEST-HTTP-QUERY": "123"},
timeout: 1000
}
tls
fingerprints.
The supported settings include the following options:
chrome_:"chrome_103"
, "chrome_104"
, "chrome_105"
, "chrome_106"
, "chrome_107"
, "chrome_108"
, "chrome_109"
, "chrome_110"
, "chrome_111"
, "chrome_112"
, "chrome_117"
,
safari_:"safari_15_6_1"
, "safari_16_0"
, "safari_ipad_15_6"
, "safari_ios_15_5"
, "safari_ios_15_6"
, "safari_ios_16_0"
,
firefox_:"firefox_102"
, "firefox_104"
, "firefox_105"
, "firefox_106"
, "firefox_108"
, "firefox_110"
, "firefox_117"
,
opera_:"opera_89"
, "opera_90"
, "opera_91"
,
zalando_:"zalando_android_mobile"
, "zalando_ios_mobile"
,
nike_:"nike_ios_mobile"
, "nike_android_mobile"
,
cloudscraper:"cloudscraper"
,
mms_:"mms_ios"
,
mesh_:"mesh_ios"
, "mesh_ios_1"
, "mesh_ios_2"
, "mesh_android"
, "mesh_android_1"
, "mesh_android_2"
,
confirmed_:"confirmed_ios"
, "confirmed_android"
,
okhttp4_:"okhttp4_android_7"
, "okhttp4_android_8"
, "okhttp4_android_9"
, "okhttp4_android_10"
, "okhttp4_android_11"
, "okhttp4_android_12"
, "okhttp4_android_13"
,true
, the HttpQuery
function call returns the full reply message. When it’s set to false
, only the data in the Body
of the reply message is returned.profile
field can be left out.options false object
function main(){
// An example of GET access without parameters
var info = JSON.parse(HttpQuery("https://www.okx.com/api/v5/public/time"))
Log(info)
// An example of GET access with parameters
var ticker = JSON.parse(HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT"))
Log(ticker)
}
import json
import urllib.request
def main():
# HttpQuery does not support Python, you can use the urllib/urllib2 library instead
info = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/public/time").read().decode('utf-8'))
Log(info)
ticker = json.loads(urllib.request.urlopen("https://www.okx.com/api/v5/market/books?instId=BTC-USDT").read().decode('utf-8'))
Log(ticker)
void main() {
auto info = json::parse(HttpQuery("https://www.okx.com/api/v5/public/time"));
Log(info);
auto ticker = json::parse(HttpQuery("https://www.okx.com/api/v5/market/books?instId=BTC-USDT"));
Log(ticker);
}
An example of accessing the OKX public ticker API interface.
function main() {
// Setting proxy and sending an http request for this time, no username, no password, this http request will be sent through the proxy
HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/")
// Setting proxy and sending an http request for this time, enter the user name and password, only the current call to HttpQuery takes effect, and then call HttpQuery again ("http://www.baidu.com") so that the proxy will not be used.
HttpQuery("socks5://username:password@127.0.0.1:8889/http://www.baidu.com/")
}
# HttpQuery does not support Python, you can use the urllib/urllib2 library instead
void main() {
HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/");
HttpQuery("socks5://username:password@127.0.0.1:8889/http://www.baidu.com/");
}
The HttpQuery function uses proxy settings.
The HttpQuery()
function only supports JavaScript
, C++
language, Python
language can use the urllib
library to send Http requests directly. The HttpQuery()
is mainly used to access the interfaces of the exchange that do not require a signature, such as public interfaces like ticker information. The HttpQuery()
can be used in the backtesting system to send requests (only GET
requests are supported) to obtain data. Backtesting is limited to using 20 visits to different URLs
, and HttpQuery()
visits will cache data. When the same URL
is accessed a second time, the HttpQuery()
function returns the cached data and no more actual network requests occur.
{@fun/Global/HttpQuery_Go HttpQuery_Go}
Sends an Http request, an asynchronous version of the HttpQuery
function.
The HttpQuery_Go()
function immediately returns a concurrent object that can be used to obtain the result of an Http request using the wait
method of the The JSON.parse()
function can be used to parse the JSON.parse()
function in the JavaScript
language’s strategy.
object
HttpQuery_Go(url) HttpQuery_Go(url, options)
Http request url. url true string Http request-related settings, for example, can be structured as follows:
{
method: "POST",
body: "a=10&b=20&c=30",
charset: "UTF-8",
cookie: "session_id=12345; lang=en",
// profile: "",
debug: false,
headers: {"TEST-HTTP-QUERY": "123"},
timeout: 1000
}
tls
fingerprints.true
, this HttpQuery_Go
function call returns the full reply message. When it’s set to false
, only the data in the Body
of the reply message is returned.profile
field can be left out.options false object
function main() {
// Create the first asynchronous thread
var r1 = HttpQuery_Go("https://www.okx.com/api/v5/market/tickers?instType=SPOT")
// Create the second asynchronous thread
var r2 = HttpQuery_Go("https://api.huobi.pro/market/tickers")
// Get the return value of the first asynchronous thread call
var tickers1 = r1.wait()
// Get the return value of the second asynchronous thread call
var tickers2 = r2.wait()
// Print results
Log("tickers1:", tickers1)
Log("tickers2:", tickers2)
}
# Not supported
// Not supported
Asynchronous access to the exchange’s public interface for aggregated ticker data.
The HttpQuery_Go()
function only supports JavaScript
, the Python
language can be used with the urllib
library to send Http requests directly. The HttpQuery_Go()
is mainly used to access interfaces that do not require a signature on the exchange, such as public interfaces like ticker information. The HttpQuery_Go
function is not supported in the backtesting system.
{@fun/Global/HttpQuery HttpQuery}
This function encodes the data according to the parameters passed in.
The Encode
function returns the data after encoding and encryption.
string
Encode(algo, inputFormat, outputFormat, data) Encode(algo, inputFormat, outputFormat, data, keyFormat, key)
The parameter algo
is the algorithm used in the encoding calculation. The support setting is: raw
(no algorithm is used), the"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 parameter algo
also supports: “text.encoder.utf8”, “text.decoder.utf8”, “text.encoder.gbk”, “text.decoder.gbk”, encode and decode strings. The parameter algo
also supports: “ed25519” algorithm. Supports the use of different hash algorithms, for example, the parameter algo
can be written as “ed25519.md5”, “ed25519.sha512”, etc. It supports ed25519.seed
calculation.
algo
true
string
Used to specify the data format of the data
parameter. The inputFormat
parameter can be set as one of the followings: raw
, hex
, base64
, string
. “raw” means the data is raw data, “hex” means the data is hex
encoded, “base64” means the data is base64
encoded, and “string” means the data is a string.
inputFormat
true
string
Used to specify the data format of the output. The outputFormat
parameter can be set as one of the followings: raw
, hex
, base64
, string
. “raw” means the data is raw data, “hex” means the data is hex
encoded, “base64” means the data is base64
encoded, and “string” means the data is a string.
outputFormat
true
string
The parameter data
is the data to be processed.
data
true
string
Used to specify the data format of the key
parameter. The key
parameter can be set as one of the followings: raw
, hex
, base64
, string
. “raw” means the data is raw data, “hex” means the data is hex
encoded, “base64” means the data is base64
encoded, and “string” means the data is a string.
keyFormat
false
string
The parameter key
is the secret key used for HMAC
encryption. The parameter key
is required when the parameter algo
is set to sign
or signTx
. The key
parameter is not used for HMAC
encryption when the algo
parameter is set to “raw” (because the algorithm must be specified for HMAC encryption).
key
false
string
function main() {
Log(Encode("raw", "raw", "hex", "example", "raw", "123")) // 6578616d706c65
Log(Encode("raw", "raw", "hex", "example")) // 6578616d706c65
Log(Encode("sha256", "raw", "hex", "example", "raw", "123")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "", "123")) // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
Log(Encode("sha256", "raw", "hex", "example", null, "123")) // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
Log(Encode("sha256", "raw", "hex", "example", "string", "123")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("raw", "raw", "hex", "123")) // 313233
Log(Encode("raw", "raw", "base64", "123")) // MTIz
Log(Encode("sha256", "raw", "hex", "example", "hex", "313233")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz")) // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
}
def main():
Log(Encode("raw", "raw", "hex", "example", "raw", "123")) # 6578616d706c65
Log(Encode("raw", "raw", "hex", "example", "", "")) # 6578616d706c65
Log(Encode("sha256", "raw", "hex", "example", "raw", "123")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "", "123")) # 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
Log(Encode("sha256", "raw", "hex", "example", "string", "123")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("raw", "raw", "hex", "123", "", "")) # 313233
Log(Encode("raw", "raw", "base64", "123", "", "")) # MTIz
Log(Encode("sha256", "raw", "hex", "example", "hex", "313233")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz")) # 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
void main() {
Log(Encode("raw", "raw", "hex", "example", "raw", "123")); // 6578616d706c65
Log(Encode("raw", "raw", "hex", "example")); // 6578616d706c65
Log(Encode("sha256", "raw", "hex", "example", "raw", "123")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "", "123")); // 50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c
Log(Encode("sha256", "raw", "hex", "example", "string", "123")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("raw", "raw", "hex", "123")); // 313233
Log(Encode("raw", "raw", "base64", "123")); // MTIz
Log(Encode("sha256", "raw", "hex", "example", "hex", "313233")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
Log(Encode("sha256", "raw", "hex", "example", "base64", "MTIz")); // 698d54f0494528a759f19c8e87a9f99e75a5881b9267ee3926bcf62c992d84ba
}
Example of Encode function call.
function main(){
var ret1 = Encode("text.encoder.utf8", "raw", "hex", "hello") // e4bda0e5a5bd
Log(ret1)
var ret2 = Encode("text.decoder.utf8", "hex", "string", ret1)
Log(ret2)
var ret3 = Encode("text.encoder.gbk", "raw", "hex", "hello") // c4e3bac3
Log(ret3)
var ret4 = Encode("text.decoder.gbk", "hex", "string", ret3)
Log(ret4)
}
def main():
ret1 = Encode("text.encoder.utf8", "raw", "hex", "hello", "", "") # e4bda0e5a5bd
Log(ret1)
ret2 = Encode("text.decoder.utf8", "hex", "string", ret1, "", "")
Log(ret2)
ret3 = Encode("text.encoder.gbk", "raw", "hex", "hello", "", "") # c4e3bac3
Log(ret3)
ret4 = Encode("text.decoder.gbk", "hex", "string", ret3, "", "")
Log(ret4)
void main(){
auto ret1 = Encode("text.encoder.utf8", "raw", "hex", "hello"); // e4bda0e5a5bd
Log(ret1);
auto ret2 = Encode("text.decoder.utf8", "hex", "string", ret1);
Log(ret2);
auto ret3 = Encode("text.encoder.gbk", "raw", "hex", "hello"); // c4e3bac3
Log(ret3);
auto ret4 = Encode("text.decoder.gbk", "hex", "string", ret3);
Log(ret4);
}
The parameter algo
also supports: “text.encoder.utf8”, “text.decoder.utf8”, “text.encoder.gbk”, “text.decoder.gbk” to encode and decode strings.
The Encode()
function is only supported for live trading. If key
and keyFormat
parameters are not passed, then key
encryption is not used.
Get the nanosecond timestamp of the current moment.
The UnixNano()
function returns the nanosecond timestamp.
number
UnixNano()
function main() {
var time = UnixNano() / 1000000
Log(_N(time, 0))
}
def main():
time = UnixNano()
Log(time)
void main() {
auto time = UnixNano();
Log(time);
}
If you need to get millisecond timestamps, you can use the following code:
{@fun/Global/Unix Unix}
Get the timestamp of the current moment at the second level.
Returns the second-level timestamp. number
Unix()
function main() {
var t = Unix()
Log(t)
}
def main():
t = Unix()
Log(t)
void main() {
auto t = Unix();
Log(t);
}
{@fun/Global/UnixNano UnixNano}
Get the system information of the device where the docker is located.
System information. string
GetOS()
function main() {
Log("GetOS:", GetOS())
}
def main():
Log("GetOS:", GetOS())
void main() {
Log("GetOS:", GetOS());
}
For example, a call to the GetOS()
function for a docker running on the Mac OS operating system might return: darwin/amd64
. Because Apple computers have multiple hardware architectures. darwin
is the name of the Mac OS system.
Computes the MD5 hash of the parameter data
.
MD5 hash value. string
MD5(data)
The data that requires MD5 calculation. data true string
function main() {
Log("MD5", MD5("hello world"))
}
def main():
Log("MD5", MD5("hello world"))
void main() {
Log("MD5", MD5("hello world"));
}
Calling the MD5("hello world")
function, the return value is: 5eb63bbbe01eeed093cb22bb8f5acdc3
.
{@fun/Global/Encode Encode}
Database interface functions.
An object containing the result of the execution of a sql statement, for example:
{"columns":["TS","HIGH","OPEN","LOW","CLOSE","VOLUME"],"values":[[1518970320000,100,99.1,90,100,12345.6]]}
object
DBExec(sql)
sql statement string. sql true string
function main() {
var strSql = [
":CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
].join("")
var ret = DBExec(strSql)
Log(ret)
// Add a piece of data
Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
// Query data
Log(DBExec(":SELECT * FROM TEST_TABLE;"))
}
def main():
arr = [
":CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
]
strSql = ""
for i in range(len(arr)):
strSql += arr[i]
ret = DBExec(strSql)
Log(ret)
# Add a piece of data
Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
# Query data
Log(DBExec(":SELECT * FROM TEST_TABLE;"))
void main() {
string strSql = ":CREATE TABLE TEST_TABLE(\
TS INT PRIMARY KEY NOT NULL,\
HIGH REAL NOT NULL,\
OPEN REAL NOT NULL,\
LOW REAL NOT NULL,\
CLOSE REAL NOT NULL,\
VOLUME REAL NOT NULL)";
auto ret = DBExec(strSql);
Log(ret);
// Add a piece of data
Log(DBExec(":INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"));
// Query data
Log(DBExec(":SELECT * FROM TEST_TABLE;"));
}
Support in-memory database, for DBExec
function parameters, if sql statement starts with :
then operate in in-memory database, it will be faster without writing files. It’s suitable for database operations that do not require persistent saving, for example:
function main() {
var strSql = [
"CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
].join("")
var ret = DBExec(strSql)
Log(ret)
}
def main():
arr = [
"CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
]
strSql = ""
for i in range(len(arr)):
strSql += arr[i]
ret = DBExec(strSql)
Log(ret)
void main() {
string strSql = "CREATE TABLE TEST_TABLE(\
TS INT PRIMARY KEY NOT NULL,\
HIGH REAL NOT NULL,\
OPEN REAL NOT NULL,\
LOW REAL NOT NULL,\
CLOSE REAL NOT NULL,\
VOLUME REAL NOT NULL)";
auto ret = DBExec(strSql);
Log(ret);
}
Create a table.
function main() {
var strSql = [
"CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
].join("")
Log(DBExec(strSql))
// Add a piece of data
Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
// Query data
Log(DBExec("SELECT * FROM TEST_TABLE;"))
// Modify data
Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))
// Delete data
Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110))
}
def main():
arr = [
"CREATE TABLE TEST_TABLE(",
"TS INT PRIMARY KEY NOT NULL,",
"HIGH REAL NOT NULL,",
"OPEN REAL NOT NULL,",
"LOW REAL NOT NULL,",
"CLOSE REAL NOT NULL,",
"VOLUME REAL NOT NULL)"
]
strSql = ""
for i in range(len(arr)):
strSql += arr[i]
Log(DBExec(strSql))
# Add a piece of data
Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"))
# Query data
Log(DBExec("SELECT * FROM TEST_TABLE;"))
# Modify data
Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000))
# Delete data
Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110))
void main() {
string strSql = "CREATE TABLE TEST_TABLE(\
TS INT PRIMARY KEY NOT NULL,\
HIGH REAL NOT NULL,\
OPEN REAL NOT NULL,\
LOW REAL NOT NULL,\
CLOSE REAL NOT NULL,\
VOLUME REAL NOT NULL)";
Log(DBExec(strSql));
// Add a piece of data
Log(DBExec("INSERT INTO TEST_TABLE (TS, HIGH, OPEN, LOW, CLOSE, VOLUME) VALUES (1518970320000, 100, 99.1, 90, 100, 12345.6);"));
// Query data
Log(DBExec("SELECT * FROM TEST_TABLE;"));
// Modify data
Log(DBExec("UPDATE TEST_TABLE SET HIGH=? WHERE TS=?", 110, 1518970320000));
// Delete data
Log(DBExec("DELETE FROM TEST_TABLE WHERE HIGH=?", 110));
}
Add, delete, check and change the records in the table.
The function DBExec()
can operate the live trading database (SQLite database) by passing in parameters. Realize the operation of adding, deleting, checking and changing data in the live trading database, supporting SQLite grammar. The system reserved tables in the live trading database: kvdb
, cfg
, log
, profit
, chart
, do not operate on these tables. Currently Transactions are not supported and it is not recommended to perform such operations, which can cause conflicts in the system. The DBExec()
function is only supported for live trading.
{@fun/Global/_G _G}
Create a UUID.
32-bit UUID. string
UUID()
function main() {
var uuid1 = UUID()
var uuid2 = UUID()
Log(uuid1, uuid2)
}
def main():
uuid1 = UUID()
uuid2 = UUID()
Log(uuid1, uuid2)
void main() {
auto uuid1 = UUID();
auto uuid2 = UUID();
Log(uuid1, uuid2);
}
The UUID()
function supports live trading only.
Listen for events, it returns when there is any WebSocket
readable data or concurrent tasks, such as exchange.Go()
, HttpQuery_Go()
, etc. are completed.
If the returned object is not null value, the Event
contained in the return content is the event trigger type. For example, the following return value structure:
{"Seq":1,"Event":"Exchange_GetTrades","ThreadId":0,"Index":3,"Nano":1682068771309583400}
object
EventLoop() EventLoop(timeout)
The parameter timeout
is the timeout setting, in milliseconds. The parameter timeout
waits for an event to occur before returning if it is set to 0. If it is greater than 0, it sets the event to wait for a timeout, and returns the most recent event immediately if it is less than 0.
timeout
false
number
function main() {
var routine_getTicker = exchange.Go("GetTicker")
var routine_getDepth = exchange.Go("GetDepth")
var routine_getTrades = exchange.Go("GetTrades")
// Sleep(2000), if the Sleep statement is used here, it will cause the subsequent EventLoop function to miss the previous events, because after waiting for 2 seconds, the concurrent function has received the data, and the subsequent EventLoop listening mechanism started, it misses these events.
// These events will not be missed unless EventLoop(-1) is called at the beginning of the first line of code to first initialize the EventLoop's listening mechanism.
// Log("GetDepth:", routine_getDepth.wait()) If the wait function is called in advance to retrieve the result of a concurrent call to the GetDepth function, the event that the GetDepth function receives the result of the request will not be returned in the EventLoop function.
var ts1 = new Date().getTime()
var ret1 = EventLoop(0)
var ts2 = new Date().getTime()
var ret2 = EventLoop(0)
var ts3 = new Date().getTime()
var ret3 = EventLoop(0)
Log("The first concurrent task completed was:", _D(ts1), ret1)
Log("The second concurrent task completed was:", _D(ts2), ret2)
Log("The third concurrent task completed was:", _D(ts3), ret3)
Log("GetTicker:", routine_getTicker.wait())
Log("GetDepth:", routine_getDepth.wait())
Log("GetTrades:", routine_getTrades.wait())
}
import time
def main():
routine_getTicker = exchange.Go("GetTicker")
routine_getDepth = exchange.Go("GetDepth")
routine_getTrades = exchange.Go("GetTrades")
ts1 = time.time()
ret1 = EventLoop(0)
ts2 = time.time()
ret2 = EventLoop(0)
ts3 = time.time()
ret3 = EventLoop(0)
Log("The first concurrent task completed was:", _D(ts1), ret1)
Log("The second concurrent task completed was:", _D(ts2), ret2)
Log("The third concurrent task completed was:", _D(ts3), ret3)
Log("GetTicker:", routine_getTicker.wait())
Log("GetDepth:", routine_getDepth.wait())
Log("GetTrades:", routine_getTrades.wait())
void main() {
auto routine_getTicker = exchange.Go("GetTicker");
auto routine_getDepth = exchange.Go("GetDepth");
auto routine_getTrades = exchange.Go("GetTrades");
auto ts1 = Unix() * 1000;
auto ret1 = EventLoop(0);
auto ts2 = Unix() * 1000;
auto ret2 = EventLoop(0);
auto ts3 = Unix() * 1000;
auto ret3 = EventLoop(0);
Log("The first concurrent task completed was:", _D(ts1), ret1);
Log("The second concurrent task completed was:", _D(ts2), ret2);
Log("The third concurrent task completed was:", _D(ts3), ret3);
Ticker ticker;
Depth depth;
Trades trades;
routine_getTicker.wait(ticker);
routine_getDepth.wait(depth);
routine_getTrades.wait(trades);
Log("GetTicker:", ticker);
Log("GetDepth:", depth);
Log("GetTrades:", trades);
}
The first call to the EventLoop()
function in the code initializes the mechanism for that listened event, and if the first EventLoop()
call starts after the event callback, it will miss the previous events. The underlying system wraps a queue structure that caches a maximum of 500 event callbacks. If the EventLoop()
function is not called in time to take them out during program execution, later event callbacks outside the 500 cache will be lost. Calls to the EventLoop()
function do not affect the cache queue of the underlying system WebSocket or the caches of concurrent functions such as exchange.Go()
. For these caches, it is still necessary to use the respective methods to retrieve the data. No return event will be generated in the EventLoop()
function for data that has been retrieved before the EventLoop()
function returns. The main purpose of the EventLoop()
function is to notify the strategy layer that new network data has been received by the underlying system. The whole strategy is driven by events. When the EventLoop()
function returns an event, just traverses all data sources. For example, WebSocket connections, objects created by exchange.Go()
try to get data. The EventLoop()
function supports live trading only.
Listen for events in the main thread when called from the main function main()
. In strategies written in the JavaScript
language, the threading.Thread()
function creates a thread, which can also be called in the thread’s execution function, to listen for events in the current thread.
{@fun/Global/Dial Dial}, {@fun/Trade/exchange.Go exchange.Go}, {@fun/Global/HttpQuery_Go HttpQuery_Go}
The __Serve
function is used to create Http service, TCP service, and Websocket service (based on Http protocol).
Returns a string that records the IP address and port of the created service. For example: 127.0.0.1:8088
, [::]:8089
.
string
__Serve(serveURI, handler) __Serve(serveURI, handler, …args)
The serveURI
parameter is used to configure the protocol, IP address, port and other settings of the service binding, such as http://0.0.0.0:8088?gzip=true
, that is, http://:8088?gzip=true
.
serveURI
parameter setting, such as tcp://127.0.0.1:6666?tls=true
; you can add certificates and private keys, such as tls=true&cert_pem=xxxx&cert_key_pem=xxxx
.serveURI
parameter settings, such as http://127.0.0.1:6666?gzip=true
; you can set compression settings: gzip=true
.
The serveURI
parameter is used for Https, such as https://127.0.0.1:6666?tls=true&gzip=true
; you can add cert_pem
and cert_key_pem
parameters to load the certificate.serveURI
true
string
The handler
parameter is used to pass in the routing processing function (Http protocol), message processing function (TCP protocol), and Stream processing function (Websocket).
The callback function passed in by the parameter handler
can define multiple parameters, the first parameter is the ctx object (context object).
handler
true
function
The actual parameter of the callback function passed as the parameter handler
. There may be multiple parameters arg
, for example:
__Serve("http://:8088", function(ctx, a, b, c) {
Log(`ctx.host():`, ctx.host(), ", a=", a, ", b=", b, ", c=", c)
}, 1, 2, 3)
The parameters 1
, 2
, 3
passed in when calling the __Serve()
function correspond to the parameters a
, b
, c
passed in the callback function.
arg false string, number, bool, object, array, function, null value and other types supported by the system
function main() {
let httpServer = __Serve("http://:8088?gzip=true", function (ctx) {
Log("http connect from: ", ctx.remoteAddr(), "->", ctx.localAddr())
let path = ctx.path()
if (path == "/") {
ctx.write(JSON.stringify({
path: ctx.path(),
method: ctx.method(),
headers: ctx.headers(),
cookie: ctx.header("Cookie"),
remote: ctx.remoteAddr(),
query: ctx.rawQuery()
}))
} else if (path == "/tickers") {
let ret = exchange.GetTickers()
if (!ret) {
ctx.setStatus(500)
ctx.write(GetLastError())
} else {
ctx.write(JSON.stringify(ret))
}
} else if (path == "/wss") {
if (ctx.upgrade("websocket")) { // upgrade to websocket
while (true) {
let r = ctx.read(10)
if (r == "") {
break
} else if (r) {
if (r == "ticker") {
ctx.write(JSON.stringify(exchange.GetTicker()))
} else {
ctx.write("not support")
}
}
}
Log("websocket closed", ctx.remoteAddr())
}
} else {
ctx.setStatus(404)
}
})
let echoServer = __Serve("tcp://:8089", function (ctx) {
Log("tcp connect from: ", ctx.remoteAddr(), "->", ctx.localAddr())
while (true) {
let d = ctx.read()
if (!d) {
break
}
ctx.write(d)
}
Log("connect closed")
})
Log("http serve on", httpServer, "tcp serve on", echoServer)
for (var i = 0; i < 5; i++) {
if (i == 2) {
// test Http
var retHttp = HttpQuery("http://127.0.0.1:8088?num=123&limit=100", {"debug": true})
Log("retHttp:", retHttp)
} else if (i == 3) {
// test TCP
var tcpConn = Dial("tcp://127.0.0.1:8089")
tcpConn.write("Hello TCP Server")
var retTCP = tcpConn.read()
Log("retTCP:", retTCP)
} else if (i == 4) {
// test Websocket
var wsConn = Dial("ws://127.0.0.1:8088/wss|compress=gzip")
wsConn.write("ticker")
var retWS = wsConn.read(1000)
Log("retWS:", retWS)
// no depth
wsConn.write("depth")
retWS = wsConn.read(1000)
Log("retWS:", retWS)
}
Sleep(1000)
}
}
# Unsupported
// Unsupported
Websocket
service is implemented based on the Http protocol. You can set a routing branch in the path and design the implementation code for Websocket
message subscription/push. You can refer to the sample code in this section.The callback function passed in by the parameter handler
receives a ctx
parameter. The ctx
parameter is a context object used to get and write data, with the following methods:
HTTP/1.1
, tcp
.http://127.0.0.1:8088?num=123
, and the callback processing function passed in by the parameter handler
returns "123"
when ctx.query("num")
is called.User-Agent
in the headers of the current request: ctx.header("User-Agent")
.GET
, POST
, etc.ctx
context object to the Websocket protocol; returning a Boolean value (true) if the switch is successful, and a Boolean value (false) if it fails.read
method is not supported in ordinary Http protocol. You can specify the timeout parameter timeout_ms
in milliseconds.JSON.stringify()
to encode the JSON object into a string and then write it. For the WebSocket
protocol, you can use this method to pass the encoded string to the client.{@fun/Global/HttpQuery HttpQuery}, {@fun/Global/HttpQuery_Go HttpQuery_Go}
Persistently save data, the function implements a global dictionary function that can be saved. The data structure is a KV table that is permanently saved in the docker’s local database file.
Persistent saved key-value data in k-v
key-value pairs.
string, number, bool, object, array, null value
_G() _G(k) _G(k, v)
The parameter k
is the name of the key in the saved key-value pair, and is not case-sensitive.
k
false
string, null value
The parameter v
is the key value in the saved key-value pair, which can be any data that can be JSON
serialized.
v
false
string, number, bool, object, array, null value
function main(){
// Set a global variable num with a value of 1
_G("num", 1)
// Change a global variable num to the value of the string ok
_G("num", "ok")
// Delete the global variable num
_G("num", null)
// Returns the value of the global variable num
Log(_G("num"))
// Delete all global variables
_G(null)
// Return to live trading ID
var robotId = _G()
}
def main():
_G("num", 1)
_G("num", "ok")
_G("num", None)
Log(_G("num"))
_G(None)
robotId = _G()
void main() {
_G("num", 1);
_G("num", "ok");
_G("num", NULL);
Log(_G("num"));
_G(NULL);
// Not support auto robotId = _G();
}
A separate database for each live trading, the data saved by the _G()
function will always be there if the strategy is restarted or the docker stops running. If the backtesting is finished, the data saved in the backtesting system by the _G()
function will be cleared. When using the _G()
function to persist the saved data, it should be used reasonably according to the memory and hard disk space of the hardware device, and should not be abused.
When calling the _G()
function in a live trading and no parameters are passed, the _G()
function returns the Id
of the current live trading. When calling the _G()
function, the parameter v
is passed as null to indicate the deletion of the k-v
key-value pair. When calling the _G()
function, only the parameter k
is passed in the string, and the _G()
function returns the key value corresponding to the saved parameter k
. When calling the _G()
function, only the parameter k
is passed in a null value, indicating that all records of the k-v
key-value pair is deleted. When the k-v
key-value pairs have been saved persistently, the _G()
function is called again, passing in the name of the key that has been saved persistently as parameter k
. Passing in the new key value as parameter v
will update that k-v
key-value pair.
{@fun/Global/DBExec DBExec}
Converts millisecond timestamps or Date
objects to time strings.
Time string. string
_D() _D(timestamp) _D(timestamp, fmt)
Millisecond timestamp or Date
object.
timestamp
false
number、object
Format string, JavaScript
language default format: yyyy-MM-dd hh:mm:ss
; Python
language default format: %Y-%m-%d %H:%M:%S
; C++
language default format: %Y-%m-%d %H:%M:%S
.
fmt
false
string
function main(){
var time = _D()
Log(time)
}
def main():
strTime = _D()
Log(strTime)
void main() {
auto strTime = _D();
Log(strTime);
}
Get and print the current time string:
function main() {
Log(_D(1574993606000))
}
def main():
# Running this code on a server in Beijing time: 2019-11-29 10:13:26 , a docker on another server in another region results in: 2019-11-29 02:13:26
Log(_D(1574993606))
void main() {
Log(_D(1574993606000));
}
The timestamp is 1574993606000, using the code conversion:
function main() {
Log(_D(1574993606000, "yyyy--MM--dd hh--mm--ss")) // 2019--11--29 10--13--26
}
def main():
# 1574993606 is timestamped in seconds.
Log(_D(1574993606, "%Y--%m--%d %H--%M--%S")) # 2019--11--29 10--13--26
void main() {
Log(_D(1574993606000, "%Y--%m--%d %H--%M--%S")); // 2019--11--29 10--13--26
}
Formatting with the parameter fmt
is different for JavaScript
, Python
, and C++
languages, as shown in the following examples:
Returns the current time string without passing any parameters. When using the _D()
function in the Python
strategy, you need to be aware that the parameters passed are second-level timestamps (millisecond-level timestamps in the JavaScript and C++ strategies, where 1 second is equal to 1000 milliseconds). When using the _D()
function to parse a time string with a readable timestamp in the live trading, you need to pay attention to the time zone and time setting of the operating system where the docker program is located. The _D()
function parses a timestamp into a readable time string depending on the time of the docker’s system.
{@fun/Global/UnixNano UnixNano}, {@fun/Global/Unix Unix}
Format a floating point number.
The formatted floating point number according to the precision setting. number
_N() _N(num) _N(num, precision)
The floating point number that needs to be formatted.
num
true
number
The precision setting for formatting, the parameter precision
is an integer, and the parameter precision
defaults to 4.
precision
false
number
function main(){
var i = 3.1415
Log(i)
var ii = _N(i, 2)
Log(ii)
}
def main():
i = 3.1415
Log(i)
ii = _N(i, 2)
Log(ii)
void main() {
auto i = 3.1415;
Log(i);
auto ii = _N(i, 2);
Log(ii);
}
For example, _N(3.1415, 2)
will delete the value after 3.1415
two decimal places and the function returns 3.14
.
function main(){
var i = 1300
Log(i)
var ii = _N(i, -3)
// Check the logs and see that it is 1000
Log(ii)
}
def main():
i = 1300
Log(i)
ii = _N(i, -3)
Log(ii)
void main() {
auto i = 1300;
Log(i);
auto ii = _N(i, -3);
Log(ii);
}
If you need to change all the N digits to the left of the decimal point to 0, you can write it like this:
The parameter precision
can be a positive integer, negative integer.
{@fun/Trade/exchange.SetPrecision exchange.SetPrecision}
Retry function for interface fault tolerance.
The return value of the callback function when it is executed. All types are supported by the system except logical false value and null value.
_C(pfn) _C(pfn, …args)
The parameter pfn
is a function reference, which is a callback function.
pfn
true
function
Parameters to callback functions, there may be more than one parameter arg
. The type and number of parameters arg
depends on the parameters of the callback function.
arg
false
string, number, bool, object, array, function, all types are supported by the system, such as null values
function main(){
var ticker = _C(exchange.GetTicker)
// Adjust _C() function retry interval to 2 seconds
_CDelay(2000)
var depth = _C(exchange.GetDepth)
Log(ticker)
Log(depth)
}
def main():
ticker = _C(exchange.GetTicker)
_CDelay(2000)
depth = _C(exchange.GetDepth)
Log(ticker)
Log(depth)
void main() {
auto ticker = _C(exchange.GetTicker);
_CDelay(2000);
auto depth = _C(exchange.GetDepth);
Log(ticker);
Log(depth);
}
For error-tolerant functions without parameters:
function main(){
var records = _C(exchange.GetRecords, PERIOD_D1)
Log(records)
}
def main():
records = _C(exchange.GetRecords, PERIOD_D1)
Log(records)
void main() {
auto records = _C(exchange.GetRecords, PERIOD_D1);
Log(records);
}
For functions with parameters that are error tolerant:
var test = function(a, b){
var time = new Date().getTime() / 1000
if(time % b == 3){
Log("Eligible!", "#FF0000")
return true
}
Log("Retry!", "#FF0000")
return false
}
function main(){
var ret = _C(test, 1, 5)
Log(ret)
}
import time
def test(a, b):
ts = time.time()
if ts % b == 3:
Log("Eligible!", "#FF0000")
return True
Log("Retry!", "#FF0000")
return False
def main():
ret = _C(test, 1, 5)
Log(ret)
// C++ does not support fault tolerance for custom functions in this way
It can also be used for fault tolerance of custom functions:
The _C()
function will keep calling the specified function until it returns successfully (the function referenced by the parameter pfn
returns null or false when called will retry calling pfn
). For example _C(exchange.GetTicker)
. The default retry interval is 3 seconds, you can call the _CDelay()
function to set the retry interval. For example, _CDelay(1000)
means to change the retry interval of the _C()
function to 1 second.
Fault tolerance can be done for, but is not limited to, the following functions:
exchange.GetTicker()
exchange.GetDepth()
exchange.GetTrades()
exchange.GetRecords()
exchange.GetAccount()
exchange.GetOrders()
exchange.GetOrder()
exchange.GetPositions()
All can be called by the _C()
function for fault tolerance. The _C()
function is not limited to the above listed function fault tolerance, the parameter pfn
is a function reference rather than a function call.
Note that it is _C(exchange.GetTicker)
, not _C(exchange.GetTicker())
.Returns the number of intersection periods of the array arr1
and the array arr2
.
The number of cross periods of the array arr1
and the array arr2
.
number
_Cross(arr1, arr2)
Elements are arrays of type number
.
arr1
true
array
Elements are arrays of type number
.
arr2
true
array
// Fast line indicator
var arr1 = [1,2,3,4,5,6,8,8,9]
// Slow line indicator
var arr2 = [2,3,4,5,6,7,7,7,7]
function main(){
Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
}
arr1 = [1,2,3,4,5,6,8,8,9]
arr2 = [2,3,4,5,6,7,7,7,7]
def main():
Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2))
Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1))
void main() {
vector<double> arr1 = {1,2,3,4,5,6,8,8,9};
vector<double> arr2 = {2,3,4,5,6,7,7,7,7};
Log("_Cross(arr1, arr2) : ", _Cross(arr1, arr2));
Log("_Cross(arr2, arr1) : ", _Cross(arr2, arr1));
}
A set of data can be simulated to test the _Cross(Arr1, Arr2) function:
If the return value of the _Cross()
function is a positive number, it indicates the period of upward penetration, if it’s a negative number, it indicates the period of downward penetration, 0 means the same as the current price. Specific instructions for use: Analysis and instructions for use about built-in function _Cross.
The function JSONParse()
is used to parse JSON
strings.
JSON
object.
object
JSONParse(s)
JSON
string.
s
true
string
function main() {
let s1 = '{"num": 8754613216564987646512354656874651651358}'
Log("JSON.parse:", JSON.parse(s1)) // JSON.parse: {"num":8.754613216564988e+39}
Log("JSONParse:", JSONParse(s1)) // JSONParse: {"num":"8754613216564987646512354656874651651358"}
let s2 = '{"num": 123}'
Log("JSON.parse:", JSON.parse(s2)) // JSON.parse: {"num":123}
Log("JSONParse:", JSONParse(s2)) // JSONParse: {"num":123}
}
import json
def main():
s1 = '{"num": 8754613216564987646512354656874651651358}'
Log("json.loads:", json.loads(s1)) # json.loads: map[num:8.754613216564987e+39]
Log("JSONParse:", JSONParse(s1)) # JSONParse: map[num:8754613216564987646512354656874651651358]
s2 = '{"num": 123}'
Log("json.loads:", json.loads(s2)) # json.loads: map[num:123]
Log("JSONParse:", JSONParse(s2)) # JSONParse: map[num:123]
void main() {
auto s1 = "{\"num\":8754613216564987646512354656874651651358}";
Log("json::parse:", json::parse(s1));
// Log("JSONParse:", JSONParse(s1)); // The function is not supported.
auto s2 = "{\"num\":123}";
Log("json::parse:", json::parse(s2));
// Log("JSONParse:", JSONParse(s2)); // The function is not supported.
}
JSON strings with large values can be parsed correctly, and it will parse large values as string types. The JSONParse()
function is not supported in the backtest system.
Output logs.
Log(…msgs)
The parameter msg
is the content of the output, and the parameter msg
can be passed more than one.
msg
false
string, number, bool, object, array, any type supported by the system such as null.
function main() {
Log("msg1", "msg2", "msg3")
}
def main():
Log("msg1", "msg2", "msg3")
void main() {
Log("msg1", "msg2", "msg3");
}
Multiple msg
parameters can be passed:
function main() {
Log("Hello, FMZ Quant!@")
Sleep(1000 * 5)
// Add #ff0000 to the string to print the log in red and push the message
Log("Hello, #ff0000@")
}
def main():
Log("Hello, FMZ Quant!@")
Sleep(1000 * 5)
Log("Hello, #ff0000@")
void main() {
Log("Hello, FMZ Quant!@");
Sleep(1000 * 5);
Log("Hello, #ff0000@");
}
It supports setting the color of output message, if we use setting color and push at the same time, we need to set color first and use @
character to set push last.
function main() {
Log("`data:image/png;base64,AAAA`")
}
def main():
Log("`data:image/png;base64,AAAA`")
void main() {
Log("`data:image/png;base64,AAAA`");
}
The Log()
function supports printing base64
encoded images, starting with `
and ending with `
, for example:
import matplotlib.pyplot as plt
def main():
plt.plot([3,6,2,4,7,1])
Log(plt)
The Log()
function supports direct printing of Python
's matplotlib.pyplot
object. As long as the object contains the savefig
method, it can be printed directly using the Log
function, for example:
function main() {
Log("[trans]中文|abc[/trans]")
}
def main():
Log("[trans]中文|abc[/trans]")
void main() {
Log("[trans]中文|abc[/trans]");
}
The Log()
function supports language switching. The Log()
function outputs text that will switch to the corresponding language automatically based on the language setting on the platform page, for example:
The Log()
function outputs a log message in the log area of the live trading or backtesting system, and the log is saved in the live trading database when the live trading is running. The Log()
function outputs a log message ending with the @
character, then this log will enter the message push queue. Push to the email address, WebHook address, etc. configured in the Push Settings of the current FMZ Quant Trading Platform account. Message pushing is not supported by Debugging Tools, backtesting system. There is a frequency limit for message push. The specific restriction rules are as follows: within a 20-second cycle of a live trading, only the last push message will be retained and pushed, and other messages will be filtered and not pushed (the push log output by the Log function will be printed and displayed normally in the log area).
For WebHook
push, you can use the service program written by 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 WebHook
in Push Settings: http://XXX.XX.XXX.XX:9090/data?data=Hello_FMZ
.
After running the written Golang
service program, we start running the strategy live trading, the following is the strategy written in JavaScript
language, the strategy runs by executing the Log()
function and pushing the message:
function main() {
Log("msg", "@")
}
A service program written in the Golang
language receives the push and the service program prints the message:
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
{@fun/Log/LogReset LogReset}, {@fun/Log/LogVacuum LogVacuum}
Record the P&L value, print the P&L value and plot the return curve based on the P&L value.
LogProfit(profit) LogProfit(profit, …args)
The parameter profit
is the revenue data, which is given by the design algorithm and calculation in the strategy.
profit
true
number
Extended parameter to output incidental information to the revenue log, arg
parameters can be passed more than one.
arg
false
string, number, bool, object, array, any type supported by the system such as null.
function main() {
// Print 30 points on the earnings chart
for(var i = 0; i < 30; i++) {
LogProfit(i, '&')
Sleep(500)
}
}
def main():
for i in range(30):
LogProfit(i, '&')
Sleep(500)
void main() {
for(int i = 0; i < 30; i++) {
LogProfit(i, '&');
Sleep(500);
}
}
The LogProfit
function, if it ends with the character &
, draws the revenue chart only and does not print the revenue log. For example:
{@fun/Log/LogProfitReset LogProfitReset}
Clear all revenue logs, revenue charts.
LogProfitReset() LogProfitReset(remain)
The remain
parameter is used to specify the number of log entries (integer value) to keep.
remain
false
number
function main() {
// Print 30 points on the revenue chart, then reset and keep only the last 10 points
for(var i = 0; i < 30; i++) {
LogProfit(i)
Sleep(500)
}
LogProfitReset(10)
}
def main():
for i in range(30):
LogProfit(i)
Sleep(500)
LogProfitReset(10)
void main() {
for(int i = 0; i < 30; i++) {
LogProfit(i);
Sleep(500);
}
LogProfitReset(10);
}
{@fun/Log/LogProfit LogProfit}
Output information in the status bar of the backtesting system or live trading page.
LogStatus(…msgs)
The parameter msg
is the content of the output, and the parameter msg
can be passed more than one.
msg
false
string, number, bool, object, array, any type supported by the system such as null.
function main() {
LogStatus('This is a general status alert')
LogStatus('This is a status alert in red font #ff0000')
LogStatus('This is a multi-line status message \n I am the second line')
}
def main():
LogStatus('This is a general status alert')
LogStatus('This is a status alert in red font #ff0000')
LogStatus('This is a multi-line status message \n I am the second line')
void main() {
LogStatus("This is a general status alert");
LogStatus("This is a status alert in red font #ff0000");
LogStatus("This is a multi-line status message \n I am the second line");
}
It supports setting the color of the output content:
function main() {
var table = {type: 'table', title: 'Position information', cols: ['Column 1', 'Column 2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
// JSON serialization with the ` character on both sides, as a complex message format (support tables currently)
LogStatus('`' + JSON.stringify(table) + '`')
// Table information can also appear in multiple rows
LogStatus('First line of message\n`' + JSON.stringify(table) + '`\n third line of message')
// It supports multiple tables at the same time, will be displayed in a group with TAB
LogStatus('`' + JSON.stringify([table, table]) + '`')
// You can also construct a button in the form, and use the GetCommand strategy to receive the contents of the cmd attribute
var table = {
type: 'table',
title: 'Position operations',
cols: ['Column 1', 'Column 2', 'Action'],
rows: [
['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'Close out positions'}]
]
}
LogStatus('`' + JSON.stringify(table) + '`')
// Or construct a separate button
LogStatus('`' + JSON.stringify({'type':'button', 'cmd': 'coverAll', 'name': 'Close out positions'}) + '`')
// Customizable button style (bootstrap's button attribute)
LogStatus('`' + JSON.stringify({'type':'button', 'class': 'btn btn-xs btn-danger', 'cmd': 'coverAll', 'name': 'Close out positions'}) + '`')
}
import json
def main():
table = {"type": "table", "title": "Position information", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]}
LogStatus('`' + json.dumps(table) + '`')
LogStatus('First line of message\n`' + json.dumps(table) + '`\n third line of message')
LogStatus('`' + json.dumps([table, table]) + '`')
table = {
"type" : "table",
"title" : "Position operations",
"cols" : ["Column 1", "Column 2", "Action"],
"rows" : [
["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close out positions"}]
]
}
LogStatus('`' + json.dumps(table) + '`')
LogStatus('`' + json.dumps({"type": "button", "cmd": "coverAll", "name": "Close out positions"}) + '`')
LogStatus('`' + json.dumps({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "Close out positions"}) + '`')
void main() {
json table = R"({"type": "table", "title": "Position information", "cols": ["Column 1", "Column 2"], "rows": [["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
LogStatus("`" + table.dump() + "`");
LogStatus("First line of message\n`" + table.dump() + "`\n third line of message");
json arr = R"([])"_json;
arr.push_back(table);
arr.push_back(table);
LogStatus("`" + arr.dump() + "`");
table = R"({
"type" : "table",
"title" : "Position operations",
"cols" : ["Column 1", "Column 2", "Action"],
"rows" : [
["abc", "def", {"type": "button", "cmd": "coverAll", "name": "Close out positions"}]
]
})"_json;
LogStatus("`" + table.dump() + "`");
LogStatus("`" + R"({"type": "button", "cmd": "coverAll", "name": "Close out positions"})"_json.dump() + "`");
LogStatus("`" + R"({"type": "button", "class": "btn btn-xs btn-danger", "cmd": "coverAll", "name": "Close out positions"})"_json.dump() + "`");
}
Example of data output in the status bar:
function main() {
var table = {
type: "table",
title: "status bar button style",
cols: ["default", "original", "success", "info", "warning", "danger"],
rows: [
[
{"type":"button", "class": "btn btn-xs btn-default", "name": "default"},
{"type":"button", "class": "btn btn-xs btn-primary", "name": "original"},
{"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) + "`")
}
import json
def main():
table = {
"type": "table",
"title": "status bar button style",
"cols": ["default", "original", "success", "info", "warning", "danger"],
"rows": [
[
{"type":"button", "class": "btn btn-xs btn-default", "name": "default"},
{"type":"button", "class": "btn btn-xs btn-primary", "name": "original"},
{"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) + "`")
void main() {
json table = R"({
"type": "table",
"title": "status bar button style",
"cols": ["default", "original", "success", "info", "warning", "danger"],
"rows": [
[
{"type":"button", "class": "btn btn-xs btn-default", "name": "default"},
{"type":"button", "class": "btn btn-xs btn-primary", "name": "original"},
{"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() + "`");
}
It supports for designing button controls in the status bar (old button structure):
function main() {
var table = {
type: "table",
title: "Status bar button disable, description function test",
cols: ["Column 1", "Column 2", "Column 3"],
rows: []
}
var button1 = {"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button"}
var button2 = {"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": true}
var button3 = {"type": "button", "name": "button3", "cmd": "button3", "description": "This is the third button, set to enable", "disabled": false}
table.rows.push([button1, button2, button3])
LogStatus("`" + JSON.stringify(table) + "`")
}
import json
def main():
table = {
"type": "table",
"title": "Status bar button disable, description function test",
"cols": ["Column 1", "Column 2", "Column 3"],
"rows": []
}
button1 = {"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button"}
button2 = {"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": True}
button3 = {"type": "button", "name": "button3", "cmd": "button3", "description": "This is the third button, set to enable", "disabled": False}
table["rows"].append([button1, button2, button3])
LogStatus("`" + json.dumps(table) + "`")
void main() {
json table = R"({
"type": "table",
"title": "Status bar button disable, description function test",
"cols": ["Column 1", "Column 2", "Column 3"],
"rows": []
})"_json;
json button1 = R"({"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button"})"_json;
json button2 = R"({"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button, set to disabled", "disabled": true})"_json;
json button3 = R"({"type": "button", "name": "button3", "cmd": "button3", "description": "This is the third button, set to enable", "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() + "`");
}
Set the disabled, description function of the status bar button (old button structure):
function test1() {
Log("Calling custom functions")
}
function main() {
while (true) {
var table = {
type: 'table',
title: 'operation',
cols: ['column1', 'column2', 'Action'],
rows: [
['a', '1', {
'type': 'button',
'cmd': "CoverAll",
'name': 'Close out positions'
}],
['b', '1', {
'type': 'button',
'cmd': 10,
'name': 'Send values'
}],
['c', '1', {
'type': 'button',
'cmd': _D(),
'name': 'Calling functions'
}],
['d', '1', {
'type': 'button',
'cmd': 'test1',
'name': 'Calling custom functions'
}]
]
}
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)
}
}
import json
def test1():
Log("Calling custom functions")
def main():
while True:
table = {
"type": "table",
"title": "operation",
"cols": ["column1", "column2", "Action"],
"rows": [
["a", "1", {
"type": "button",
"cmd": "CoverAll",
"name": "Close out positions"
}],
["b", "1", {
"type": "button",
"cmd": 10,
"name": "Send values"
}],
["c", "1", {
"type": "button",
"cmd": _D(),
"name": "Calling functions"
}],
["d", "1", {
"type": "button",
"cmd": "test1",
"name": "Calling custom functions"
}]
]
}
LogStatus(_D(), "\n", "`" + json.dumps(table) + "`")
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)
void test1() {
Log("Calling custom functions");
}
void main() {
while(true) {
json table = R"({
"type": "table",
"title": "operation",
"cols": ["column1", "column2", "Action"],
"rows": [
["a", "1", {
"type": "button",
"cmd": "CoverAll",
"name": "Close out positions"
}],
["b", "1", {
"type": "button",
"cmd": 10,
"name": "Send values"
}],
["c", "1", {
"type": "button",
"cmd": "",
"name": "Calling functions"
}],
["d", "1", {
"type": "button",
"cmd": "test1",
"name": "Calling custom functions"
}]
]
})"_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:", typeof(str_cmd), "value:", str_cmd);
if(str_cmd == "test1") {
test1();
}
}
Sleep(500);
}
}
In combination with the GetCommand()
function, construct the status bar button interaction function (old button structure):
function main() {
var tbl = {
type: "table",
title: "operation",
cols: ["column1", "column2"],
rows: [
["Open position operation", {"type": "button", "cmd": "open", "name": "open position", "input": {"name": "number of open positions", "type": "number", "defValue": 1}}],
["Close position operation", {"type": "button", "cmd": "coverAll", "name": "close all positions"}]
]
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
while (true) {
var cmd = GetCommand()
if (cmd) {
Log("cmd:", cmd)
}
Sleep(1000)
}
}
import json
def main():
tbl = {
"type": "table",
"title": "operation",
"cols": ["column1", "column2"],
"rows": [
["Open position operation", {"type": "button", "cmd": "open", "name": "open position", "input": {"name": "number of open positions", "type": "number", "defValue": 1}}],
["Close position operation", {"type": "button", "cmd": "coverAll", "name": "close all positions"}]
]
}
LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`")
while True:
cmd = GetCommand()
if cmd:
Log("cmd:", cmd)
Sleep(1000)
void main() {
json tbl = R"({
"type": "table",
"title": "operation",
"cols": ["column1", "column2"],
"rows": [
["Open position operation", {"type": "button", "cmd": "open", "name": "open position", "input": {"name": "number of open positions", "type": "number", "defValue": 1}}],
["Close position operation", {"type": "button", "cmd": "coverAll", "name": "close all positions"}]
]
})"_json;
LogStatus(_D(), "\n", "`" + tbl.dump() + "`");
while(true) {
auto cmd = GetCommand();
if(cmd != "") {
Log("cmd:", cmd);
}
Sleep(1000);
}
}
Input data is also supported when constructing status bar buttons for interaction, and the interaction commands are captured by the GetCommand()
function eventually. Add input
items (old button structure) to the data structure of the button control in the status bar, for example, adding "input": {"name": "number of open positions", "type": "number", "defValue": 1}
to {"type": "button", "cmd": "open", "name": "open position"}
will cause a popup with an input box control to appear when the button is clicked (the default value in the input box is 1, which is the data set by defValue
). You can enter a data to be sent along with the button command. For example, when the following test code runs, after clicking the "open position’’ button, a popup window with an input box pops up. Enter 111 in the input box and click “OK”. The GetCommand()
function will then capture the message: open:111
.
function main() {
var tbl = {
type: "table",
title: "Demonstrate grouping button control",
cols: ["operation"],
rows: []
}
// Creating a grouping button control structure
var groupBtn = {
type: "button",
cmd: "open",
name: "open positions",
group: [
{"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "market order|pending order"},
{"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100},
{"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100},
{"name": "boolean", "description": "yes/no|boolean", "type": "boolean", "defValue": true}
]
}
// test button 1
var testBtn1 = {"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button."}
var testBtn2 = {"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button.", "input": {"name": "number of positions opened", "type": "number", "defValue": 1}}
// Add groupBtn to tbl
tbl.rows.push([groupBtn])
// It supports multiple buttons in a cell of a status bar table, i.e. the data in a cell is an array of button structures: [testBtn1, testBtn2].
tbl.rows.push([[testBtn1, testBtn2]])
while (true) {
LogStatus("`" + JSON.stringify(tbl) + "`", "\n", "The grouping button control can also be set directly on the status bar in addition to being set on the status bar form:", "`" + JSON.stringify(groupBtn) + "`")
var cmd = GetCommand()
if (cmd) {
Log("cmd:", cmd)
}
Sleep(5000)
}
}
import json
def main():
tbl = {
"type": "table",
"title": "Demonstrate grouping button control",
"cols": ["operation"],
"rows": []
}
groupBtn = {
"type": "button",
"cmd": "open",
"name": "open positions",
"group": [
{"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "market order|pending order"},
{"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100},
{"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100},
{"name": "boolean", "description": "yes/no|boolean", "type": "boolean", "defValue": True}
]
}
testBtn1 = {"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button."}
testBtn2 = {"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button.", "input": {"name": "number of positions opened", "type": "number", "defValue": 1}}
tbl["rows"].append([groupBtn])
tbl["rows"].append([[testBtn1, testBtn2]])
while True:
LogStatus("`" + json.dumps(tbl) + "`", "\n", "The grouping button control can also be set directly on the status bar in addition to being set on the status bar form:", "`" + json.dumps(groupBtn) + "`")
cmd = GetCommand()
if cmd:
Log("cmd:", cmd)
Sleep(5000)
void main() {
json tbl = R"({
"type": "table",
"title": "Demonstrate grouping button control",
"cols": ["operation"],
"rows": []
})"_json;
json groupBtn = R"({
"type": "button",
"name": "open positions",
"cmd": "open",
"group": [
{"name": "orderType", "description": "下单方式|order type", "type": "selected", "defValue": "market order|pending order"},
{"name": "tradePrice@orderType==1", "description": "交易价格|trade price", "type": "number", "defValue": 100},
{"name": "orderAmount", "description": "委托数量|order amount", "type": "string", "defValue": 100},
{"name": "boolean", "description": "yes/no|boolean", "type": "boolean", "defValue": true}
]})"_json;
json testBtn1 = R"({"type": "button", "name": "button1", "cmd": "button1", "description": "This is the first button."})"_json;
json testBtn2 = R"({"type": "button", "name": "button2", "cmd": "button2", "description": "This is the second button.", "input": {"name": "number of positions opened", "type": "number", "defValue": 1}})"_json;
tbl["rows"].push_back({groupBtn});
tbl["rows"].push_back({{testBtn1, testBtn2}});
while(true) {
LogStatus("`" + tbl.dump() + "`", "\n", "The grouping button control can also be set directly on the status bar in addition to being set on the status bar form:", "`" + groupBtn.dump() + "`");
auto cmd = GetCommand();
if(cmd != "") {
Log("cmd:", cmd);
}
Sleep(5000);
}
}
It supports for grouped button controls (old button structure), functionally consistent with status bar buttons that support data entry (set by using the “input” field). Interactive commands are ultimately captured by the GetCommand()
function. The difference is that with the "group"
field setting, when the button is clicked to trigger the interaction, the dialog that pops up on the page contains a set of group of input controls set up to enter a group of data at once.
A few points to note about the "group"
field in the structure of the status bar button control and the group button control:
type
property in group supports only the following four types, and the defValue
property is the default value.
“selected”: A dropdown box control that uses the |
symbol to separate each option in a dropdown box as it is set.
“number”: Numeric input box control.
“string”: String input box control.
“boolean”: Checkbox control, checked for (Boolean) true, unchecked for (Boolean) false."name": "tradePrice@orderType==1"
setting, which makes the tradePrice input control available only when the orderType drop-down control is selected as a Pending Order.|
symbols to separate the content of the description in Chinese and English.name
, description
in group and name
, description
in the button structure do not have the same definitions even though they have the same field names.
The definition of name
in group is also different from the definition of name
in input.Log("cmd:", cmd)
statement in the following example test:
cmd: open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}
, i.e., what is returned by the GetCommand()
function when an interaction occurs: open:{"orderType":1,"tradePrice":99,"orderAmount":"99","boolean":true}
.type
property of the button control supports only: "button"
.
Button controls that support input data, i.e. controls with the input
property set, the type
property in the configuration information of the input
field supports multiple control types.
Refer to the following examples:function main() {
// Status bar button control (set input field to implement) testBtn1 button triggered by the page in the drop-down box control using the options field to set options, using the defValue field to set the default options. This is different from the other examples in this chapter, which use defValue to set the options directly.
var testBtn1 = {
type: "button",
name: "testBtn1",
cmd: "cmdTestBtn1",
input: {name: "testBtn1ComboBox", type: "selected", options: ["A", "B"], defValue: 1}
}
/*
Status bar button control (set input field implementation) testBtn2 button triggered by the page in the drop-down box control using the options field to set the options, options field in the options field not only supports the string,
the use of the ```{text: "description", value: "value"}``` structure is also supported. Use the defValue field to set the default option, which can be multiple choice (multiple choice via array structure). Multiple choice requires setting the additional field multiple to a true value.
*/
var testBtn2 = {
type: "button",
name: "testBtn2",
cmd: "cmdTestBtn2",
input: {
name: "testBtn2MultiComboBox",
type: "selected",
description: "Implementing dropdown box multi-selection",
options: [{text: "Option A", value: "A"}, {text: "Option B", value: "B"}, {text: "Option C", value: "C"}],
defValue: ["A", "C"],
multiple: true
}
}
// Status bar grouping button control (set group field implementation) testBtn3 button triggered by the page in the drop-down box control using the options field to set options, also supports the direct use of defValue set options.
var testBtn3 = {
type: "button",
name: "testBtn3",
cmd: "cmdTestBtn3",
group: [
{name: "comboBox1", label: "labelComboBox1", description: "Dropdown box 1", type: "selected", defValue: 1, options: ["A", "B"]},
{name: "comboBox2", label: "labelComboBox2", description: "Dropdown box 2", type: "selected", defValue: "A|B"},
{name: "comboBox3", label: "labelComboBox3", description: "Dropdown box 3", type: "selected", defValue: [0, 2], multiple: true, options: ["A", "B", "C"]},
{
name: "comboBox4",
label: "labelComboBox4",
description: "Dropdown box 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)
}
}
import 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": "Implementing dropdown box multi-selection",
"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 box 1", "type": "selected", "defValue": 1, "options": ["A", "B"]},
{"name": "comboBox2", "label": "labelComboBox2", "description": "Dropdown box 2", "type": "selected", "defValue": "A|B"},
{"name": "comboBox3", "label": "labelComboBox3", "description": "Dropdown box 3", "type": "selected", "defValue": [0, 2], "multiple": True, "options": ["A", "B", "C"]},
{
"name": "comboBox4",
"label": "labelComboBox4",
"description": "Dropdown box 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)
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": "Implementing dropdown box multi-selection",
"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 box 1", "type": "selected", "defValue": 1, "options": ["A", "B"]},
{"name": "comboBox2", "label": "labelComboBox2", "description": "Dropdown box 2", "type": "selected", "defValue": "A|B"},
{"name": "comboBox3", "label": "labelComboBox3", "description": "Dropdown box 3", "type": "selected", "defValue": [0, 2], "multiple": true, "options": ["A", "B", "C"]},
{
"name": "comboBox4",
"label": "labelComboBox4",
"description": "Dropdown box 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);
}
}
When the status bar group button control (implemented by setting the group
field) and the status bar button control (implemented by setting the input
field) are clicked to trigger interaction (old button structure), the drop-down box control in the dialog box that pops up on the page also supports multiple selections. The following example demonstrates how to design a drop-down box control with multiple selection options:
var 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 a position and place an order",
"group": [{
"type": "selected",
"name": "tradeType",
"label": "Order type",
"description": "Market order, limit order",
"default": 0,
"group": "Trading setup",
"settings": {
"options": ["Market order", "Limit order"],
"required": true,
}
}, {
"type": "selected",
"name": "direction",
"label": "Trading direction",
"description": "Buy, sell",
"default": "buy",
"group": "Trading setup",
"settings": {
"render": "segment",
"required": true,
"options": [{"name": "buy", "value": "buy"}, {"name": "sell", "value": "sell"}],
}
}, {
"type": "number",
"name": "price",
"label": "price",
"description": "The price of the order",
"group": "Trading setup",
"filter": "tradeType==1",
"settings": {
"required": true,
}
}, {
"type": "number",
"name": "amount",
"label": "Order quantity",
"description": "Order quantity",
"group": "Trading setup",
"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": "Trading instruments", "default": m["symbol"], "settings": {"required": true}}])
tbl["rows"].push([m["symbol"], btnOpen])
})
var cmd = GetCommand()
if (cmd) {
Log("Receive interaction:", cmd)
// Parsing interaction messages: open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111}
// According to the first colon: the previous instruction determines which button template triggers the message
var arrCmd = cmd.split(":", 2)
if (arrCmd[0] == "open") {
var msg = JSON.parse(cmd.slice(5))
Log("Trading instruments:", msg["symbol"], ", Trading direction:", msg["direction"], ", Order type:", msg["tradeType"] == 0 ? "Market order" : "Limit order", msg["tradeType"] == 0 ? ", Order price: current market price" : ", Order price:" + msg["price"], ", Order quantity:", msg["amount"])
}
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
Sleep(1000)
}
}
import 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 a position and place an order",
"group": [{
"type": "selected",
"name": "tradeType",
"label": "Order type",
"description": "Market order, limit order",
"default": 0,
"group": "Trading setup",
"settings": {
"options": ["Market order", "Limit order"],
"required": True,
}
}, {
"type": "selected",
"name": "direction",
"label": "Trading direction",
"description": "Buy, sell",
"default": "buy",
"group": "Trading Setup",
"settings": {
"render": "segment",
"required": True,
"options": [{"name": "买入", "value": "buy"}, {"name": "卖出", "value": "sell"}],
}
}, {
"type": "number",
"name": "price",
"label": "price",
"description": "The price of the order",
"group": "Trading Setup",
"filter": "tradeType==1",
"settings": {
"required": True,
}
}, {
"type": "number",
"name": "amount",
"label": "Order quantity",
"description": "Order quantity",
"group": "Trading Setup",
"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": "交易品种", "default": m["symbol"], "settings": {"required": True}}])
tbl["rows"].append([m["symbol"], btnOpen])
cmd = GetCommand()
if cmd != "" and cmd != None:
Log("Receive interaction:", cmd)
# Parsing interaction messages: open:{"symbol":"LTC_USDT.swap","tradeType":0,"direction":"buy","amount":111}
# According to the first colon: the previous instruction determines which button template triggers the message
arrCmd = cmd.split(":")
if arrCmd[0] == "open":
msg = json.loads(cmd[5:])
Log("Trading instruments:", msg["symbol"], ", Trading direction:", msg["direction"], ", Order type:", "Market order" if msg["tradeType"] == 0 else "Limit order", ", Order price: current market price" if msg["tradeType"] == 0 else ", Order price:" + str(msg["price"]), ", Order quantity:", msg["amount"])
# Output status bar information
LogStatus(_D(), "\n", "`" + json.dumps(tbl) + "`")
Sleep(1000)
// Omit...
Use the latest button structure to construct the buttons in the status bar table. When clicking the button to trigger the interaction, a multi-control pop-up window will pop up. For more details, please refer to: User Guide - Interactive Controls in the Status Bar.
function main() {
var table = {
type: 'table',
title: 'position operation',
cols: ['column1', 'column2', 'Action'],
rows: [
['abc', 'def', {'type':'button', 'cmd': 'coverAll', 'name': 'close positions'}]
]
}
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) + '`')
}
import json
def main():
table = {
"type" : "table",
"title" : "position operation",
"cols" : ["column1", "column2", "Action"],
"rows" : [
["abc", "def", {"type": "button", "cmd": "coverAll", "name": "close positions"}]
]
}
ticker = exchange.GetTicker()
table["rows"].append([{"body": json.dumps(ticker), "colspan": 2}, "abc"])
LogStatus("`" + json.dumps(table) + "`")
void main() {
json table = R"({
"type" : "table",
"title" : "position operation",
"cols" : ["column1", "column2", "Action"],
"rows" : [
["abc", "def", {"type": "button", "cmd": "coverAll", "name": "close positions"}]
]
})"_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() + "`");
}
Horizontal merge of cells within the table drawn by the LogStatus()
function:
function main() {
var table = {
type: 'table',
title: 'table demo',
cols: ['columnA', 'columnB', 'columnC'],
rows: [
['A1', 'B1', {'type':'button', 'cmd': 'coverAll', 'name': 'C1'}]
]
}
var ticker = exchange.GetTicker()
var name = exchange.GetName()
table.rows.push([{body : "A2 + B2:" + JSON.stringify(ticker), colspan : 2}, "C2"])
table.rows.push([{body : "A3 + A4 + A5:" + name, rowspan : 3}, "B3", "C3"])
// A3 is merged by the first cell in the previous row
table.rows.push(["B4", "C4"])
// A2 is merged by the first cell of the previous row
table.rows.push(["B5", "C5"])
table.rows.push(["A6", "B6", "C6"])
LogStatus('`' + JSON.stringify(table) + '`')
}
import json
def main():
table = {
"type" : "table",
"title" : "table demo",
"cols" : ["columnA", "columnB", "columnC"],
"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) + "`")
void main() {
json table = R"({
"type" : "table",
"title" : "table demo",
"cols" : ["columnA", "columnB", "columnC"],
"rows" : [
["A1", "B1", {"type": "button", "cmd": "coverAll", "name": "C1"}]
]
})"_json;
// For testing purposes, the code is short and easy to read, and the constructed data is used here
json jsonTicker = R"({"High": 0, "Low": 0, "Buy": 0, "Sell": 0, "Last": 0, "Time": 0, "Volume": 0})"_json;
auto name = exchange.GetName();
json arr1 = R"([{"body": "", "colspan": 2}, "C2"])"_json;
arr1[0]["body"] = "A2 + B2:" + jsonTicker.dump();
json arr2 = R"([{"body": "", "rowspan": 3}, "B3", "C3"])"_json;
arr2[0]["body"] = "A3 + A4 + A5:" + name;
table["rows"].push_back(arr1);
table["rows"].push_back(arr2);
table["rows"].push_back(R"(["B4", "C4"])"_json);
table["rows"].push_back(R"(["B5", "C5"])"_json);
table["rows"].push_back(R"(["A6", "B6", "C6"])"_json);
LogStatus("`" + table.dump() + "`");
}
Vertically merge the cells in the table drawn by the LogStatus()
function:
function main() {
var table1 = {type: 'table', title: 'table1', cols: ['column1', 'column2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
var table2 = {type: 'table', title: 'table2', cols: ['column1', 'column2'], rows: [ ['abc', 'def'], ['ABC', 'support color #ff0000']]}
LogStatus('`' + JSON.stringify([table1, table2]) + '`')
}
import json
def main():
table1 = {"type": "table", "title": "table1", "cols": ["column1", "column2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]}
table2 = {"type": "table", "title": "table2", "cols": ["column1", "column2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]}
LogStatus("`" + json.dumps([table1, table2]) + "`")
void main() {
json table1 = R"({"type": "table", "title": "table1", "cols": ["column1", "column2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
json table2 = R"({"type": "table", "title": "table2", "cols": ["column1", "column2"], "rows": [ ["abc", "def"], ["ABC", "support color #ff0000"]]})"_json;
json arr = R"([])"_json;
arr.push_back(table1);
arr.push_back(table2);
LogStatus("`" + arr.dump() + "`");
}
Status bar table pagination display:
function main(){
var tab1 = {
type : "table",
title : "table1",
cols : ["1", "2"],
rows : []
}
var tab2 = {
type : "table",
title : "table2",
cols : ["1", "2", "3"],
rows : []
}
var tab3 = {
type : "table",
title : "table3",
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")
}
import json
def main():
tab1 = {
"type": "table",
"title": "table1",
"cols": ["1", "2"],
"rows": []
}
tab2 = {
"type": "table",
"title": "table2",
"cols": ["1", "2", "3"],
"rows": []
}
tab3 = {
"type": "table",
"title": "table3",
"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) + "`")
void main() {
json tab1 = R"({
"type": "table",
"title": "table1",
"cols": ["1", "2"],
"rows": []
})"_json;
json tab2 = R"({
"type": "table",
"title": "table2",
"cols": ["1", "2", "3"],
"rows": []
})"_json;
json tab3 = R"({
"type": "table",
"title": "table3",
"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() + "`");
}
In addition to displaying tables in pages, multiple tables can also be displayed in a top-down order:
function 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) + "`")
}
import 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) + "`")
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() + "`");
}
Support to set horizontal and vertical scroll mode of status bar table. Set scroll
attribute to "auto"
, when the number of vertical rows of the status bar table exceeds 20 rows, the content will be scrolled. When the number of horizontal columns exceeds the page display range, the scroll
attribute can be used to alleviate the lagging problem of writing a large amount of data in the status bar during live trading. Refer to the following test example:
The information output from the LogStatus()
function when the live trading is running is not saved to the live trading database, but it updates the current live trading’s status bar content only.
The LogStatus()
function supports printing base64
encoded images, starting with `
and ending with `
. For example: LogStatus("`data:image/png;base64,AAAA`")
.
The LogStatus()
function supports passing matplotlib.pyplot
objects directly into Python
, as long as the object contains the savefig
method, it can be passed as a parameter to the LogStatus()
function, for example:
import matplotlib.pyplot as plt
def main():
plt.plot([3,6,2,4,7,1])
LogStatus(plt)
When the strategy is running live trading, if you go through the history on the live trading page, the status bar will sleep and stop updating. Only the status bar data will be refreshed when the log is on the first page. It supports outputting base64
encoded images in the status bar, and it also supports outputting base64
encoded images in the table displayed in the status bar. Since the string data of the encoded image is generally very long, the sample code is not shown.
{@fun/Global/GetCommand GetCommand}
Turn on or off logging of order information.
EnableLog(enable)
If the enable
parameter is set to a false value, e.g. false
, the order log (i.e. the log generated by functions like exchange.Buy()
) is not printed and is not written to the database of the live trading.
enable
true
bool
function main() {
EnableLog(false)
}
def main():
EnableLog(False)
void main() {
EnableLog(false);
}
{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Trade/exchange.Sell exchange.Sell}, {@fun/Trade/exchange.CancelOrder exchange.CancelOrder}
Customize the chart drawing function.
Chart object. object
Chart(options)
The options
parameter is the chart configuration. The Chart()
function parameter options
is a JSON
serializable HighStocks
parameter for Highcharts.StockChart
. An additional __isStock
attribute is added over the native parameter, and if __isStock:false
is specified, it is displayed as a normal chart. If the __isStock
attribute is set to a false value e.g. false
, i.e. the chart used is a Highcharts
chart. If the __isStock
attribute is set to a true value e.g. true
, i.e. the chart used is a Highstocks
chart (by default __isStock
is true e.g. true
). You can query the HighStocks chart library.
options
true
object, object array
function main() {
var cfgA = {
extension: {
layout: 'single', // No grouping, display separately, default to group 'group'
height: 300, // Specify the height
},
title: {
text: 'handicap chart'
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'buy one',
data: [],
}, {
name: 'sell one',
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],
] // Instead of updating the initial data with the add function, the sequence can be updated by changing the chart configuration directly.
}]
};
var cfgD = {
extension: {
layout: 'single',
col: 8, // Specify the cell value for the width, the total value is 12
height: '300px',
},
title: {
text: 'handicap chart'
},
xAxis: {
type: 'datetime'
},
series: [{
name: 'buy one',
data: [],
}, {
name: 'sell one',
data: [],
}]
}
var cfgE = {
__isStock: false,
extension: {
layout: 'single',
col: 4,
height: '300px',
},
title: {
text: 'pie chart2'
},
series: [{
type: 'pie',
name: 'one',
data: [
["A", 25],
["B", 25],
["C", 25],
["D", 25],
]
}]
};
var chart = Chart([cfgA, cfgB, cfgC, cfgD, cfgE]);
chart.reset()
// Add a number of points to the pie chart, add can only update the data points added by add, 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: 'buy one ' + ticker.Buy + ', sell one ' + 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 the same as resetting the chart's configuration
chart.update([cfgA, cfgB, cfgC, cfgD, cfgE]);
}
}
import random
import time
def main():
cfgA = {
"extension" : {
"layout" : "single",
"height" : 300,
"col" : 8
},
"title" : {
"text" : "handicap chart"
},
"xAxis" : {
"type" : "datetime"
},
"series" : [{
"name" : "buy one",
"data" : []
}, {
"name" : "sell one",
"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" : "handicap chart"
},
"series" : [{
"name" : "buy one",
"data" : []
}, {
"name" : "sell one",
"data" : []
}]
}
cfgE = {
"__isStock" : False,
"extension" : {
"layout" : "single",
"col" : 4,
"height" : "300px"
},
"title" : {
"text" : "pie chart2"
},
"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" : "buy one" + str(ticker["Buy"]) + "sell one" + 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() * 100
void main() {
json cfgA = R"({
"extension" : {
"layout" : "single",
"height" : 300,
"col" : 8
},
"title" : {
"text" : "handicap chart"
},
"xAxis" : {
"type" : "datetime"
},
"series" : [{
"name" : "buy one",
"data" : []
}, {
"name" : "sell one",
"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" : "handicap chart"
},
"series" : [{
"name" : "buy one",
"data" : []
}, {
"name" : "sell one",
"data" : []
}]
})"_json;
json cfgE = R"({
"__isStock" : false,
"extension" : {
"layout" : "single",
"col" : 4,
"height" : "300px"
},
"title" : {
"text" : "pie chart2"
},
"series" : [{
"type" : "pie",
"name" : "one",
"data" : [
["A", 25],
["B", 25],
["C", 25],
["D", 25]
]
}]
})"_json;
auto chart = Chart({cfgA, cfgB, cfgC, cfgD, cfgE});
chart.reset();
json zz = R"({
"name" : "ZZ",
"y" : 0
})"_json;
zz["y"] = rand() % 100;
chart.add(3, zz);
while(true) {
Sleep(1000);
auto ticker = exchange.GetTicker();
if(!ticker.Valid) {
continue;
}
auto diff = ticker.Sell - ticker.Buy;
json cfgASubTitle = R"({"text" : ""})"_json;
cfgASubTitle["text"] = format("buy one %f , sell one %f", ticker.Buy, ticker.Sell);
cfgA["subtitle"] = cfgASubTitle;
json cfgBSubTitle = R"({"text" : ""})"_json;
cfgBSubTitle["text"] = format("spread %f", diff);
cfgB["subtitle"] = cfgBSubTitle;
chart.add(0, {Unix() * 1000, ticker.Buy});
chart.add(1, {Unix() * 1000, ticker.Sell});
chart.add(2, {Unix() * 1000, diff});
chart.add(4, {Unix() * 1000, ticker.Buy});
chart.add(5, {Unix() * 1000, ticker.Buy});
cfgC["series"][0]["data"][0][1] = rand() % 100;
cfgE["series"][0]["data"][0][1] = rand() % 100;
chart.update({cfgA, cfgB, cfgC, cfgD, cfgE});
}
}
Multi-chart drawing configuration:
extension.layout
attribute
If the attribute is set with the value “single”, the charts will not be stacked (not displayed as tabs), but will be displayed separately (tiled).extension.height
attribute
The attribute is used to set the height of the chart, either as a numeric value, or as “300px”.extension.col
attribute
The attribute is used to set the width of the chart, the page width is divided into 12 cells, set 8 ,that is, the chart occupies 8 cells width.// This chart is an object in the JavaScript language, and before using the Chart function, we need to declare an object variable chart to configure the chart. var chart = {
// This field marks whether the chart is a general chart or not, if you are interested, you can change it to false and run it.
__isStock: true,
// Scaling tool
tooltip: {xDateFormat: '%Y-%m-%d %H:%M:%S, %A'},
// title
title : { text : 'spread analysis chart'},
// selection range
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
},
// Coordinate axis horizontal axis that is: x-axis, the current setting type is: time
xAxis: { type: 'datetime'},
// Coordinate axis vertical axis that is: y-axis, default value adjusted with the size of the data
yAxis : {
// title
title: {text: 'spread'},
// Whether to enable the right vertical axis
opposite: false
},
// Data series, this sttribute holds the individual data series (lines, K-charts, labels, etc...)
series : [
// The index is 0, and the data array holds the data of the index series
{name : "line1", id : "line1,buy1Price", data : []},
// Index is 1, set dashStyle:'shortdash' i.e.: set the dashed line
{name : "line2", id : "line2,lastPrice", dashStyle : 'shortdash', data : []}
]
} function main(){
// Call the Chart function to initialize the chart
var ObjChart = Chart(chart)
// Clear out
ObjChart.reset()
while(true){
// Gets the timestamp of this poll, i.e. a millisecond timestamp. It's used to determine the position of the X-axis written to the chart.
var nowTime = new Date().getTime()
// Get the ticker data
var ticker = _C(exchange.GetTicker)
// Get buy one price from the return value of the ticker data
var buy1Price = ticker.Buy
// To obtain the final transaction price, we add 1 in order not to overlap the 2 lines
var lastPrice = ticker.Last + 1
// Data sequence with timestamp as X-value and buy one price as Y-value passed into index 0
ObjChart.add(0, [nowTime, buy1Price])
// ditto
ObjChart.add(1, [nowTime, lastPrice])
Sleep(2000)
}
}```
```python
import 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": "line1,buy1Price", "data": []
}, {
"name": "line2", "id": "line2,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)
void main() {
// When writing strategies in C++, try not to declare global variables that are not of the base type, 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": "line1,buy1Price", "data": []
}, {
"name": "line2", "id": "line2,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 a simple drawing:
// Objects used to initialize the chart
var chart = {
// Chart title
title: {text: "line value triggers the plotLines value"},
// Y-axis related settings
yAxis: {
// A horizontal line perpendicular to the Y-axis, used as a trigger line, is a structural array that can set multiple trigger lines
plotLines: [{
// The value of the trigger line, how much it set, this line will be displayed in the corresponding value position
value: 0,
// Set the color of the trigger line
color: 'red',
// Width
width: 2,
// Displaying labels
label: {
// Label text
text: 'Trigger value',
// Centered label position
align: 'center'
}
}]
},
// X-axis related settings, here the setting type is time axis
xAxis: {type: "datetime"},
series: [
{name: "sin", type: "spline", data: []},
// This is an important data series, you can set multiple data series, according to the array index control
{name: "cos", type: "spline", data: []}
]
}
function main(){
// Circumference
var pi = 3.1415926535897
// Variables for recording timestamps
var time = 0
// Angle
var angle = 0
// Coordinate y values for receiving sine and cosine values
var y = 0
// Call the API interface to initialize the chart with the chart object
var objChart = Chart(chart)
// Initially, clear the chart
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()
// Angle increases by 5 degrees every 500ms and calculates the sine value
y = Math.sin(angle * 2 * pi / 360)
// Write the calculated y value to the data series of the corresponding index of 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 drawing too often and growing data too fast
Sleep(5000)
}
}
import math
import time
chart = {
"title": {"text": "line value triggers the 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)
void main() {
json chart = R"({
"title": {"text": "line value triggers the 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);
}
}
Example of trigonometric curve drawing:
/*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;
}
}
'''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 = t
/*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;
}
}
Complex examples of using hybrid charts:
// update pie
chartCfg.series[chartCfg.series.length-1].data = [
["A", Math.random()*100],
["B", Math.random()*100],
];
c.update(chartCfg)
# update pie
chartCfg["series"][len(chartCfg["series"]) - 1]["data"] = [
["A", random.random() * 100],
["B", random.random() * 100]
]
c.update(chartCfg)
// 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);
Charts of type pie
are charts without a timeline, and you need to update the chart configuration directly when updating the data. For example, the code in the above example updates the chart using c.update(chartCfg)
after updating the data, as follows:
The Chart()
function returns a chart object that has 4 methods: add()
, reset()
, update()
, del()
.
update()
method:
The update()
method can update the chart configuration information. The parameter of this method is the Chart configuration object (JSON).del()
method:
The del()
method can delete the data series of the specified index based on the passed series parameter.add()
method:
The add()
method can write data to the chart, with the following parameters in order:series
: used to set the data series index, which is an integer.data
: used to set the specific data to be written, it is an array.index
(optional): used to set the data index, it’s an integer. Specify the specific index position of the modified data, and it supports negative numbers, the setting is -1
refers to the last data in the data set.
For example, when drawing a line, modify the data on the last point of the line: chart.add(0, [1574993606000, 13.5], -1)
, that is, change the data on the penultimate first point of the chart series[0].data
.
The index
parameter is not set, which means that the data is added to the last point of the current data series.reset()
method:
The reset()
method is used to empty the chart data. The reset()
method can take a parameter remain
to specify the number of entries to keep. No parameter remain
is passed to clear all data.{@fun/Log/KLineChart KLineChart}
The function is used for custom drawing at strategy runtime using a drawing method similar to the Pine
language.
The chart object. The KLineChart()
function returns a chart object with several methods, among which you need to pay attention to begin()
and close()
. The drawing operation must start with a begin()
function call and end with a close()
function call when traversing over the KLine data to perform the drawing operation.
object
KLineChart(options)
The options
parameter is the chart configuration.
options
true
object, object array
function main() {
// Call the KLineChart function to create a chart control object c
let c = KLineChart({
overlay: true
})
// Use the Spot Exchange object test to get K-line data. If you use the futures exchange object test, you need to set up the contract first.
let bars = exchange.GetRecords()
if (!bars) {
return
}
// Execute the drawing operation by traversing over the K-line data. The drawing operation must start with the ```c.begin(bar)``` function call and end with the ```c.close()``` 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()
})
}
def main():
# Call the KLineChart function to create a chart control object c
c = KLineChart({
"overlay": True
})
# Use the Spot Exchange object test to get K-line data. If you use the futures exchange object test, you need to set up 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()
// Not supported for now
If a chart control object is necessary to draw in the strategy custom drawing area, use the KLineChart()
function to create the object. The parameter to the KLineChart()
function is a chart configuration structure, the one used in the reference code is simple: {overlay: true}
. This chart configuration structure only sets the drawing content to be output on the main chart. If overlay
is set to a false value, e.g. false
, the content on the chart is output on the secondary chart. If you need to specify a drawing function to draw on the main chart, you can also specify the parameter overlay
as a true value in the specific function call, for example: true
.
c.barcolor(bar.Close > bar.Open ? 'rgba(255, 0, 0, 0.2)' : 'rgba(0, 0, 0, 0.2)') // Use the example illustrated in the reference code in this example, without further ado
c.barcolor('rgba(255, 0, 0, 0.2)' if bar.Close > bar.Open else 'rgba(0, 0, 0, 0.2)')
// Not supported for now
The drawing interface functions of the Pine
language supported in the drawing operation are:
barcolor
, which sets the K-line color.
barcolor(color, offset, editable, show_last, title, display) display parameters are optional: “none”, “all”
c.bgcolor('rgba(0, 255, 0, 0.5)')
c.bgcolor('rgba(0, 255, 0, 0.5)')
// Not supported for now
bgcolor
, fills the background of the K-line with the specified color.
bgcolor(color, offset, editable, show_last, title, display, overlay) display parameters are optional: “none”, “all”
c.plot(bar.High, 'high')
c.plot(bar.Open < bar.Close ? NaN : bar.Close, "Close", {style: "linebr"}) // Support for drawing discontinuous data lines
h = c.plot(bar.High, 'high')
h = c.plot(None if bar.Open < bar.Close else bar.Close, "Close", style = "linebr") # Support for drawing discontinuous data lines
// Not supported for now
plot
, plot a series of data on a chart.
plot(series, title, color, linewidth, style, trackprice, histbase, offset, join, editable, show_last, display) style parameters are optional: “stepline_diamond”, “stepline”, “cross”, “areabr”, “area”, “circles”, “columns”, “histogram”, “linebr”, “line” display parameters are optional: “none”, “all”
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)'})
h = 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)'})
// Not supported for now
fill
, fill the background between two plots or hline
with the provided colors.
fill(hline1, hline2, color, title, editable, fillgaps, display) display parameters are optional: “none”, “all”
Since the JavaScript
language cannot specify incoming parameters based on the names of function formal parameters, to solve this problem, you can use a {key: value}
structure to specify the parameters to be passed to a certain formal parameter name.
For example, the reference code uses {color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0, 0.2)'}
specifies the color
parameter of the fill
function.
If you need to specify multiple parameters with consecutive form parameter names, you can use {key1: value1, key2: value2, key3: value3}
.
For example, in this example, an additional title
parameter is specified: {color: bar.Close > bar.Open ? 'rgba(255, 0, 0, 0, 0.2)' : 'rgba(255, 0, 0, 0, 0.2)', title: 'fill'}
.
For the color value, you can set it with 'rgba(255, 0, 0, 0, 0.2)'
or with '#FF0000'
.
c.hline(bar.High)
c.hline(bar.High)
// Not supported for now
hline
, the horizontal line is presented at a given fixed price level.
hline(price, title, color, linestyle, linewidth, editable, display) linestyle parameters are optional: “dashed”, “dotted”, “solid” display parameters are optional: “none”, “all”
c.plotarrow(bar.Close - bar.Open)
c.plotarrow(bar.Close - bar.Open)
// Not supported for now
plotarrow
, plot up and down arrows on the chart.
plotarrow(series, title, colorup, colordown, offset, minheight, maxheight, editable, show_last, display) display parameters are optional: “none”, “all”
c.plotshape(bar.Low, {style: 'diamond'})
c.plotshape(bar.Low, style = 'diamond')
// Not supported for now
plotshape
, draw visual shapes on the chart.
plotshape(series, title, style, location, color, offset, text, textcolor, editable, size, show_last, display) style parameters are optional: “diamond”, “square”, “label_down”, “label_up”, “arrow_down”, “arrow_up”, “circle”, “flag”, “triangle_down”, “triangle_up”, “cross”, “xcross” location parameters are optional: “abovebar”, “belowbar”, “top”, “bottom”, “absolute” size parameters are optional: “10px”, “14px”, “20px”, “40px”, “80px”, comparing size.tiny, size.small, size.normal, size.large, size.huge in Pine language. size.auto is size.small. display parameters are optional: “none”, “all”
c.plotchar(bar.Close, {char: 'X'})
c.plotchar(bar.Close, char = 'X')
// Not supported for now
plotchar
, draw visual shapes on the chart using any given Unicode character.
plotchar(series, title, char, location, color, offset, text, textcolor, editable, size, show_last, display) location parameters are optional: “abovebar”, “belowbar”, “top”, “bottom”, “absolute” size parameters are optional: “10px”, “14px”, “20px”, “40px”, “80px”, comparing size.tiny, size.small, size.normal, size.large, size.huge in Pine language. size.auto is size.small. display parameters are optional: “none”, “all”
c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
c.plotcandle(bar.Open*0.9, bar.High*0.9, bar.Low*0.9, bar.Close*0.9)
// Not supported for now
plotcandle
, plot a K-line chart on a chart.
plotcandle(open, high, low, close, title, color, wickcolor, editable, show_last, bordercolor, display) display parameters are optional: “none”, “all”
c.signal("long", bar.High, 1.5)
c.signal("long", bar.High, 1.5)
// Not supported for now
signal
, a function not available on the Pine language, is used to draw buy and sell signals here.
signal(direction, price, qty, id) The parameter ‘‘long’’ is passed in to indicate the direction of the transaction, you can choose ‘‘long’’, ‘‘closelong’’, ‘‘short’’, ‘‘closeshort’’. The parameter
bar.High
is the Y-axis position of the marker signal. The passed parameter 1.5 indicates the number of transactions of the signal. The fourth parameter can be passed to replace the default text content drawn, and the default text of the drawn signal marker is the direction of the transaction, e.g. ‘‘closelong’’.
c.reset()
c.reset()
// Not supported for now
reset
, a function not available on the Pine language, is used to empty the chart data.
reset(remain) The
reset()
method can take one parameter,remain
, to specify the number of data to keep. Not passingremain
means clearing all data.
Strategy custom drawing can only use one of the ways of KLineChart()
function or Chart()
function. For some color and style settings used in the KLineChart()
function call, please refer to the Use the KLineChart function to make strategy drawing design easier.
{@fun/Log/Chart Chart}
Clear the log.
LogReset(remain)
The remain
parameter is used to set the number of recent log entries to keep.
remain
false
number
function main() {
// Keep the last 10 logs and clear the rest
LogReset(10)
}
def main():
LogReset(10)
void main() {
LogReset(10);
}
The startup log for each start of the strategy live trading counts as one, so if no parameters are passed in and there is no log output at the start of the strategy, no logs will be displayed at all, waiting for the docker log to be returned (not an exception).
{@fun/Log Log}, {@fun/Log/LogVacuum LogVacuum}
Used to reclaim the storage space occupied by SQLite when deleting data after calling the LogReset()
function to clear the log.
LogVacuum()
function main() {
LogReset()
LogVacuum()
}
def main():
LogReset()
LogVacuum()
void main() {
LogReset()
LogVacuum()
}
The reason is that SQLite
does not reclaim the occupied space when deleting data, and it needs to execute VACUUM
to clean up the table and free up space. File move operation occurs when this function is called, and the delay is large, so it is recommended to call at a suitable time interval.
{@fun/Log/LogReset LogReset}
It is used to output debugging information in the “debug information” column in the live trading page. For example, if the live trading Id is 123456
, the console.log
function outputs debugging information on the live trading page, and at the same time, create a log file with the extension .log
and write debugging information in the /logs/storage/123456/
in the directory of the docker to which the live trading belongs, with the filename prefix stdout_
.
console.log(…msgs)
The parameter msg
is the content of the output, and the parameter msg
can be passed more than one.
msg
false
string, number, bool, object, array, null and other types supported by the system.
function main() {
console.log("test console.log")
}
# Not supported
// Not supported
JavaScript
language supports this function.[object Object]
, so try to output as much readable information as possible.{@fun/Log/console.error console.error}
Used for error output in the “Debug message” field on the live trading page. For example, if the live trading Id is 123456
, the console.error
function creates a log file with the extension .log
in the /logs/storage/123456/
directory of the docker where the live trading belongs, and writes the error output with the prefix stderr_
.
console.error(…msgs)
The parameter msg
is the content of the output, and the parameter msg
can be passed more than one.
msg
false
string, number, bool, object, array, null and other types supported by the system.
function main() {
console.error("test console.error")
}
# Not supported
// Not supported
JavaScript
language supports this function.[object Object]
, so try to output as much readable information as possible.{@fun/Log/console.log console.log}
Get the {@struct/Ticker Ticker} structure of the spot or contract corresponding to the currently set trading pair, contract code, i.e. the ticker data. GetTicker ()
function is a member function of the exchange object {@var/EXCHANGE exchange}, the use of exchange
object member functions (methods) only related to exchange
, and it will not be repeated in the document.
The exchange.GetTicker()
function returns the {@struct/Ticker Ticker} structure when the request for data succeeds, and returns null value when the request for data fails.
{@struct/Ticker Ticker}, null value
exchange.GetTicker() exchange.GetTicker(symbol)
The parameter symbol
is used to specify the specific trading pair and contract code corresponding to the requested {@struct/Ticker Ticker} data. If this parameter is not passed, the market data of the currently set trading pair and contract code will be requested by default.
When calling the exchange.GetTicker(symbol)
function, exchange
is the spot exchange object. If you need to request market data with the denominated currency as USDT and the trading currency as BTC, the parameter symbol
is: "BTC_USDT"
, and the format is the trading pair format defined by the FMZ platform.
When calling the exchange.GetTicker(symbol)
function, exchange
is the futures exchange object. If you need to request the market data of BTC’s U-standard perpetual contract, the parameter symbol
is: "BTC_USDT.swap"
, and the format is a combination of the trading pair and contract code defined by the FMZ platform, separated by the character “.”.
When calling the exchange.GetTicker(symbol)
function, exchange
is the futures exchange object. If you need to request the market data of BTC’s U-standard option contract, the parameter symbol
is: "BTC_USDT.BTC-240108-40000-C"
(taking Binance Option BTC-240108-40000-C as an example), the format is the combination of the trading pair defined by the FMZ platform and the specific option contract code defined by the exchange, separated by the character “.”.
symbol false string
function main(){
// If it is a futures exchange object, set the contract code first, e.g. set it as a perpetual contract
// exchange.SetContractType("swap")
var ticker = exchange.GetTicker()
/*
The exchange interface may not be accessible due to network reasons (even if the docker program's device can open the exchange website, the API interface may not be accessible).
At this point, the ticker is null, and it will cause an error when accessing ticker.High, so when testing this code, make sure that the exchange interface can be accessed.
*/
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)
}
def 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"])
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);
}
For futures exchange objects (i.e., exchange
or exchanges[0]
), you need to set the contract code using the exchange.SetContractType()
function before calling the ticker function, which will not be repeated.
function main() {
var ticker = exchange.GetTicker("BTC_USDT")
Log(ticker)
}
def main():
ticker = exchange.GetTicker("BTC_USDT")
Log(ticker)
void main() {
auto ticker = exchange.GetTicker("BTC_USDT");
Log(ticker);
}
Use the symbol
parameter to request market data for a specific symbol (spot symbol).
The Ticker
data returned by the exchange.GetTicker()
function in the backtesting system. Where High
and Low
are simulated values, taken from the sell one and buy one of the market at that time. The Ticker
data returned by the exchange.GetTicker()
function in the real market. Where the High
and Low
values are based on the data returned by the encapsulated exchange Tick
interface, which includes the highest and lowest prices within a certain period (usually a 24-hour period).
Exchanges that do not support the exchange.GetTicker()
function:
Function Name | Unsupported Spot Exchanges | Unsupported Futures Exchanges |
---|---|---|
GetTicker | – | Futures_Aevo |
{@fun/Market/exchange.GetDepth exchange.GetDepth}, {@fun/Market/exchange.GetTrades exchange.GetTrades}, {@fun/Market/exchange.GetRecords exchange.GetRecords}, {@fun/Market/exchange.GetTickers exchange.GetTickers}
Get the {@struct/Depth Depth} structure of the spot or contract corresponding to the currently set trading pair, contract code, i.e. order book data.
The exchange.GetDepth()
function returns the {@struct/Depth Depth} structure if the request for data succeeds, and it returns null if the request for data fails.
{@struct/Depth Depth}, null value
exchange.GetDepth() exchange.GetDepth(symbol)
The parameter symbol
is used to specify the specific trading pair and contract code corresponding to the requested {@struct/Depth Depth} data. If this parameter is not passed, the order book data of the currently set trading pair and contract code will be requested by default. When calling the exchange.GetDepth(symbol)
function, exchange
is the spot exchange object. If you need to request to obtain the order book data with the denominated currency as USDT and the transaction currency as BTC, the parameter symbol
is: "BTC_USDT"
, and the format is the trading pair format defined by the FMZ platform. When calling the exchange.GetDepth(symbol)
function, exchange
is the futures exchange object. If you need to request the order book data of BTC’s U-standard perpetual contract, the parameter symbol
is: "BTC_USDT.swap"
, and the format is a combination of the trading pair and contract code defined by the FMZ platform, separated by the character “.”. When calling the exchange.GetDepth(symbol)
function, exchange
is the futures exchange object. If you need to request the order book data of the BTC’s U-standard option contract, the parameter symbol
is: "BTC_USDT.BTC-240108-40000-C"
(taking Binance Option BTC-240108-40000-C as an example), the format is the combination of the trading pair defined by the FMZ platform and the specific option contract code defined by the exchange, separated by the character “.”.
symbol
false
string
function main(){
var depth = exchange.GetDepth()
/*
The exchange interface may not be accessible due to network reasons (even if the docker program's device can open the exchange website, the API interface may not be accessible).
At this point, the depth is null, which will cause an error when accessing depth.Asks[1].Price, so make sure you can access the exchange interface when testing the code.
*/
var price = depth.Asks[1].Price
Log("Sell 2 price is:", price)
}
def main():
depth = exchange.GetDepth()
price = depth["Asks"][1]["Price"]
Log("Sell 2 price is:", price)
void main() {
auto depth = exchange.GetDepth();
auto price = depth.Asks[1].Price;
Log("Sell 2 price is:", price);
}
Test exchange.GetDepth()
function:
function main() {
// BTC U-based perpetual contract
var depth = exchange.GetDepth("BTC_USDT.swap")
Log(depth)
}
def main():
depth = exchange.GetDepth("BTC_USDT.swap")
Log(depth)
void main() {
auto depth = exchange.GetDepth("BTC_USDT.swap");
Log(depth);
}
When the configured exchange
object is a futures exchange object, use the symbol
parameter to request the order book data of a specific symbol (futures symbol).
In the backtesting system, the data for each grade returned by the exchange.GetDepth()
function when using the Simulate Tick backtesting are all simulated values. In the backtesting system, the data returned by the exchange.GetDepth()
function when using the Real Tick backtesting is a second level deep snapshot.
{@fun/Market/exchange.GetTicker exchange.GetTicker}, {@fun/Market/exchange.GetTrades exchange.GetTrades}, {@fun/Market/exchange.GetRecords exchange.GetRecords}
Get the {@struct/Trade Trade} structure array of the spot or contract corresponding to the currently set trading pair, contract code, i.e. the market transaction data.
The exchange.GetTrades()
function returns an array of {@struct/Trade Trade} structures if the request for data succeeds, and it returns null values if the request for data fails.
{@struct/Trade Trade}arrays, null values
exchange.GetTrades() exchange.GetTrades(symbol)
The parameter symbol
is used to specify the specific trading pair and contract code corresponding to the requested {@struct/Trade Trade} array data. If this parameter is not passed, the latest transaction record data of the currently set trading pair and contract code will be requested by default. When calling the exchange.GetTrades(symbol)
function, exchange
is the spot exchange object. If you need to request to obtain the order book data with the denominated currency as USDT and the trading currency as BTC, the parameter symbol
is: "BTC_USDT"
, and the format is the trading pair format defined by the FMZ platform. When calling the exchange.GetTrades(symbol)
function, exchange
is the futures exchange object. If you need to request the order book data of BTC’s U-standard perpetual contract, the parameter symbol
is: "BTC_USDT.swap"
, and the format is a combination of the trading pair and contract code defined by the FMZ platform, separated by the character “.”. When calling the exchange.GetTrades(symbol)
function, exchange
is the futures exchange object. If you need to request the order book data of BTC’s U-standard option contract, the parameter symbol
is: "BTC_USDT.BTC-240108-40000-C"
(taking Binance Option BTC-240108-40000-C as an example), the format is the combination of the trading pair defined by the FMZ platform and the specific option contract code defined by the exchange, separated by the character “.”.
symbol
false
string
function main(){
var trades = exchange.GetTrades()
/*
The exchange interface may not be accessible due to network reasons (even if the docker program's device can open the exchange website, the API interface may not be accessible).
At this point, trade is null. When accessing trade[0].Id, it will cause an error. Therefore, when testing this code, ensure that you can access the exchange interface.
*/
Log("id:", trades[0].Id, "time:", trades[0].Time, "Price:", trades[0].Price, "Amount:", trades[0].Amount, "type:", trades[0].Type)
}
def 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"])
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);
}
Test the exchange.GetTrades()
function:
function main() {
// BTC's U-based perpetual contract
var trades = exchange.GetTrades("BTC_USDT.swap")
Log(trades)
}
def main():
trades = exchange.GetTrades("BTC_USDT.swap")
Log(trades)
void main() {
auto trades = exchange.GetTrades("BTC_USDT.swap");
Log(trades);
}
When the configured exchange
object is a futures exchange object, use the symbol
parameter to request market transaction record data for a specific symbol (futures symbol).
exchange.GetTrades()
function to get the current trading pairs, the market’s transaction history (not their own) corresponding to contracts. Some exchanges do not support this function, and the specific data returned is how much of the range of transaction records depends on the exchange and needs to be handled according to the specific situation. The return data is an array, where each element of the chronological order and exchange.GetRecords ()
function returns the same order of data, that is, the last element of the array is the data closest to the current time.
The exchange.GetTrades()
function returns an empty array when using Simulate Tick backtesting in the backtesting system. The data returned by the exchange.GetTrades()
function when using Real Tick backtesting in the backtesting system is the order flow snapshot data, i.e. the {@struct/Trade Trade} structure array.
Exchanges that do not support the exchange.GetTrades()
function:
Function Name | Unsupported Spot Exchanges | Unsupported Futures Exchanges |
---|---|---|
GetTrades | – | Futures_BitMart / Futures_Bibox |
{@fun/Market/exchange.GetTicker exchange.GetTicker}, {@fun/Market/exchange.GetDepth exchange.GetDepth}, {@fun/Market/exchange.GetRecords exchange.GetRecords}
Get the {@struct/Record Record} structure array of the spot or contract corresponding to the currently set trading pair, contract code, i.e. K-line data.
The exchange.GetRecords()
function returns an array of {@struct/Record Record} structures when the request for data succeeds, and it returns null values when the request for data fails.
{@struct/Record Record}arrays, null values
exchange.GetRecords() exchange.GetRecords(symbol) exchange.GetRecords(symbol, period) exchange.GetRecords(symbol, period, limit) exchange.GetRecords(period) exchange.GetRecords(period, limit)
The parameter symbol
is used to specify the specific trading pair and contract code corresponding to the requested {@struct/Record Record} array data. If this parameter is not passed, the K-line data of the currently set trading pair and contract code will be requested by default. When calling the exchange.GetRecords(symbol)
function, exchange
is the spot exchange object. If you need to request to obtain the data with the denominated currency as USDT and the transaction currency as BTC, the parameter symbol
is: "BTC_USDT"
, and the format is the trading pair format defined by the FMZ platform. When calling the exchange.GetRecords(symbol)
function, exchange
is the futures exchange object. If you need to request the order book data of BTC’s U-standard perpetual contract, the parameter symbol
is: "BTC_USDT.swap"
, and the format is a combination of the trading pair and contract code defined by the FMZ platform, separated by the character “.”. When calling the exchange.GetRecords(symbol)
function, exchange
is the futures exchange object. If you need to request the order book data of BTC’s U-standard option contract, the parameter symbol
is: "BTC_USDT.BTC-240108-40000-C"
(taking Binance Option BTC-240108-40000-C as an example), the format is the combination of the trading pair defined by the FMZ platform and the specific option contract code defined by the exchange, separated by the character “.”.
symbol
false
string
The parameter period
specifies the period of the requested K-line data, for example: {@var/PERIOD/PERIOD_M1 PERIOD_M1}, {@var/PERIOD/PERIOD_M5 PERIOD_M5}, {@var/PERIOD/PERIOD_M15 PERIOD_M15}, etc. The value of parameter period
can be passed not only the defined standard period, but also integer values in seconds. If this parameter is not passed, the period of the K-line data requested by default is the default K-line period of the current strategy real-time/backtest configuration.
period
false
number
The parameter limit
is used to specify the length of the requested K-line data. If this parameter is not passed, the default request length is the maximum number of K-line bars requested at a time of the exchange K-line interface. This parameter may cause paging to query the exchange K-line data, and the time consumption of the function call will increase during paging query.
limit
false
number
function 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))
}
def main():
Log(exchange.GetRecords(60 * 2))
Log(exchange.GetRecords(PERIOD_M5))
void main() {
Log(exchange.GetRecords(60 * 2)[0]);
Log(exchange.GetRecords(PERIOD_M5)[0]);
}
Get K-line data for a custom period.
function main() {
var records = exchange.GetRecords(PERIOD_H1)
/*
The exchange interface may not be accessible due to network reasons (even if the docker program's device can open the exchange website, the API interface may not be accessible).
At this point, records is null. When accessing records[0].Time, it will cause an error. Therefore, when testing this code, ensure that you can access the exchange interface.
*/
Log("The first k-line data is Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High)
Log("The second k-line data is Time:", records[1].Time ,"Close:", records[1].Close)
Log("Current K-line (latest)", records[records.length-1], "Previous K-line", records[records.length-2])
}
def main():
records = exchange.GetRecords(PERIOD_H1)
Log("The first k-line data is Time:", records[0]["Time"], "Open:", records[0]["Open"], "High:", records[0]["High"])
Log("The second k-line data Time:", records[1]["Time"], "Close:", records[1]["Close"])
Log("Current K-line (latest)", records[-1], "Previous K-line", records[-2])
void main() {
auto records = exchange.GetRecords(PERIOD_H1);
Log("The first k-line data is Time:", records[0].Time, "Open:", records[0].Open, "High:", records[0].High);
Log("The 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]);
}
Output K-line bar data:
function main() {
var records = exchange.GetRecords("BTC_USDT.swap", 60, 100)
Log(records)
}
def main():
records = exchange.GetRecords("BTC_USDT.swap", 60, 100)
Log(records)
void main() {
auto records = exchange.GetRecords("BTC_USDT.swap", 60, 100);
Log(records);
}
When the configured exchange
object is a futures exchange object, use the symbol
, period
, and limit
parameters to request the K-line data of a specific product (futures product).
The default K-line period can be set in the backtest and real trading pages. If you specify a parameter when calling the exchange.GetRecords()
function, the K-line data corresponding to that parameter period will be obtained. If no parameter is specified when the function is called, the corresponding K-line data will be returned according to the K-line period set in the backtest and real market parameters.
The return value is an array of Record
structures, the returned K-line data will be accumulated over time, the upper limit of the accumulated K-line bars is affected by the exchange.SetMaxBarLen()
function setting. The default limit is 5000 bars when it’s not set. When the K-line data reaches the K-line bar accumulation limit, it will be updated by adding a K-line bar and deleting the earliest K-line bar (e.g. queue in/out). Some exchanges do not provide a K-line interface, so the docker collects market transaction record data (Trade
structured array) in real time to generate K-lines.
If the exchange’s K-line interface supports paging queries, multiple API requests will be made when calling the exchange.SetMaxBarLen()
function to set a larger K-line length.
When the exchange.GetRecords()
function is called initially, the number of K-line bars obtained differs between backtesting and real trading: - The backtesting system will obtain a certain number of K-line bars before the start of the backtesting time range in advance (the default is 5000, the settings of the backtesting system and the amount of data will affect the final number returned), as the initial K-line data. - The number of K-line bars obtained during the actual trading is based on the maximum amount of data that can be obtained from the K-line interface of the exchange.
The period
parameter is set to 5, which is a request to get K-line data with a period of 5 seconds. If the period
parameter is not divisible by 60 (i.e., the period represented is not divisible by minutes). The underlying system uses the relevant interface of exchange.GetTrades()
to obtain the transaction record data and synthesize the required K-line data. If the period
parameter is divisible by 60, then the required K-line data is synthesized using a minimum of 1-minute K-line data (if possible, the required K-line data is synthesized using a larger period).
The simulated level backtesting in the backtesting system requires the setting of the underlying K-line period (when the backtesting system simulates level backtesting, the corresponding K-line data is used to generate Tick data according to the set underlying K-line period). It should be noted that the period of the K-line data obtained in the strategy should not be smaller than the underlying K-line period. Because in the simulation level backtesting, the K-line data of each period in the backtesting system is synthesized from the K-line data of the underlying K-line period.
The C++
language has the following code example if you need to construct your own K-line data:
#include <sstream>
void main() {
Records r;
r.Valid = true;
for (auto i = 0; i < 10; i++) {
Record ele;
ele.Time = i * 100000;
ele.High = i * 10000;
ele.Low = i * 1000;
ele.Close = i * 100;
ele.Open = i * 10;
ele.Volume = i * 1;
r.push_back(ele);
}
// Output display: Records[10]
Log(r);
auto ma = TA.MA(r,10);
// Output display: [nan,nan,nan,nan,nan,nan,nan,nan,nan,450]
Log(ma);
}
Exchanges that do not support the exchange.GetRecords()
function:
Function Name | Unsupported Spot Exchanges | Unsupported Futures Exchanges |
---|---|---|
GetRecords | Zaif / Coincheck / BitFlyer | Futures_Aevo |
{@fun/Market/exchange.GetTicker exchange.GetTicker}, {@fun/Market/exchange.GetDepth exchange.GetDepth}, {@fun/Market/exchange.GetTrades exchange.GetTrades}, {@fun/Market/exchange.SetMaxBarLen exchange.SetMaxBarLen}
Get the K-line period set on the FMZ Quant Trading platform website page when backtesting and running the strategy in live trading, i.e. the default K-line period used when calling the exchange.GetRecords()
function without passing parameters.
K-line period in seconds, integer value in seconds. number
exchange.GetPeriod()
function main() {
// For example, the K-line period set on the website page of the FMZ Quant Trading platform during backtesting and live trading is 1 hour.
var period = exchange.GetPeriod()
Log("K-line period:", period / (60 * 60), "hours")
}
def main():
period = exchange.GetPeriod()
Log("K-line period:", period / (60 * 60), "hours")
void main() {
auto period = exchange.GetPeriod();
Log("K-line period:", period / (60 * 60.0), "hours");
}
{@fun/Market/exchange.GetRecords exchange.GetRecords}
Set the maximum length of the K-line.
exchange.SetMaxBarLen(n)
The parameter n
is used to specify the maximum K-line length.
n
true
number
function main() {
exchange.SetMaxBarLen(50)
var records = exchange.GetRecords()
Log(records.length, records)
}
def main():
exchange.SetMaxBarLen(50)
r = exchange.GetRecords()
Log(len(r), r)
void main() {
exchange.SetMaxBarLen(50);
auto r = exchange.GetRecords();
Log(r.size(), r[0]);
}
The exchange.SetMaxBarLen()
function affects two aspects for cryptocurrency strategy runtime:
{@fun/Market/exchange.GetRecords exchange.GetRecords}
Get the original content returned by the last rest
request for the current exchange object ({@var/EXCHANGE exchange}, {@var/EXCHANGE/exchanges exchanges}).
The response data for the rest
request.
string
exchange.GetRawJSON()
function main(){
exchange.GetAccount();
var obj = JSON.parse(exchange.GetRawJSON());
Log(obj);
}
import json
def main():
exchange.GetAccount()
obj = json.loads(exchange.GetRawJSON())
Log(obj)
void main() {
auto obj = exchange.GetAccount();
// C++ does not support the GetRawJSON function
Log(obj);
}
The exchange.GetRawJSON()
function is only supported for the real trading. The function is not supported by strategies in the C++
language.
{@var/EXCHANGE exchange}
Get the exchange rate currently set for the exchange object.
The current value of the exchange rate of the exchange object. number
exchange.GetRate()
function main(){
Log(exchange.GetTicker())
// Set up exchange rate conversion
exchange.SetRate(7)
Log(exchange.GetTicker())
Log("Current exchange rate:", exchange.GetRate())
}
def main():
Log(exchange.GetTicker())
exchange.SetRate(7)
Log(exchange.GetTicker())
Log("Current exchange rate:", exchange.GetRate())
void main() {
Log(exchange.GetTicker());
exchange.SetRate(7);
Log(exchange.GetTicker());
Log("Current exchange rate:", exchange.GetRate());
}
If exchange.SetRate()
has not been called to set the conversion rate, the exchange.GetRate()
function returns a default rate value of 1. That is, the data related to the currently displayed currency (quoteCurrency) has not been converted.
If an exchange rate value has been set using exchange.SetRate()
, for example, exchange.SetRate(7)
. Then all price information, such as quotes, depths, and order prices obtained through the exchange
exchange object will be converted by multiplying by the set exchange rate 7
.
If exchange
corresponds to an exchange with USD as the denomination currency, after calling exchange.SetRate(7)
, all prices in the live market will be converted to a price close to CNY by multiplying 7
. At this point, the exchange rate value obtained using exchange.GetRate()
is 7
.
{@fun/Trade/exchange.SetRate exchange.SetRate}
The exchange.SetData()
function is used to set the data loaded when the strategy is running.
The length of the string after parameter value
JSON encoding.
number
exchange.SetData(key, value)
The name of the data collection.
key
true
string
The data to be loaded by the exchange.SetData()
function has a data structure of an array. The data structure is the same as the data format requested by the exchange.GetData()
function when requesting external data, i.e.: "schema": ["time", "data"]
.
value
true
array
/*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)
}
}
'''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)
/*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);
}
}
It requires that the data for the parameter value
be in the same format as the data
variable in the following example. You can see that the timestamp 1579622400000
corresponds to the time 2020-01-22 00:00:00
, and that when the strategy program is run after this time, call the exchange.GetData()
function to get the data before the next data timestamp 1579708800000
, that is, time 2020-01-23 00:00:00
. What you get are [1579622400000, 123]
the contents of that data, as the program continues to run, the time changes, and so on to get the data item by item. In the following example, at runtime (backtesting or live trading), the current moment reaches or exceeds the timestamp 1579795200000
, the exchange.GetData()
function is called and the return value is: {"Time":1579795200000,"Data":["abc", 123,{"price":123}]}
. "Time":1579795200000
corresponds to 1579795200000
in data [1579795200000, ["abc", 123, {"price": 123}]]
. "Data":["abc", 123, {"price": 123}]
corresponds to data ["abc", 123, {"price": 123}]]
in [1579795200000, ["abc", 123, {"price": 123}]]
.
The loaded data can be any economic indicators, industry data, relevant indicators, etc., used for strategy quantitative assessment of all quantifiable information.
{@fun/Market/exchange.GetData exchange.GetData}
The exchange.GetData()
function is used to get data loaded by the exchange.SetData()
function or provided by an external link.
Records in the data collection. object
exchange.GetData(key) exchange.GetData(key, timeout)
The name of the data collection. key true string Used to set the cache timeout in milliseconds. Defaults to a one minute cache timeout for live tradings. timeout false number
/*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)
}
}
'''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)
/*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);
}
}
The call to get the data written directly.
/*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)
}
}
'''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)
/*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);
}
}
It support for requesting data through external links, the format of the data requested to:
{
"schema":["time","data"],
"data":[
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]
}
Where schema
is the data format for each record in the body of the loaded data, which is fixed to ["time", "data"]
corresponding to the format of the entry-by-entry data in the data
attribute.
What is stored in the data
attribute is the body of the data, with each entry consisting of a millisecond-level timestamp and the data content (which can be any JSON-encodable data).
The service program for testing, written in Go:
package main
import (
"fmt"
"net/http"
"encoding/json"
)
func Handle (w http.ResponseWriter, r *http.Request) {
defer func() {
fmt.Println("req:", *r)
ret := map[string]interface{}{
"schema": []string{"time","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 program’s response data upon receipt of the request:
{
"schema":["time","data"],
"data":[
[1579536000000, "abc"],
[1579622400000, 123],
[1579708800000, {"price": 123}],
[1579795200000, ["abc", 123, {"price": 123}]]
]
}
Test strategy code:
function main() {
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"))
}
def main():
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"))
Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"))
void main() {
Log(exchange.GetData("http://xxx.xx.x.xx:9090/data"));
Log(exchange.GetData("https://www.fmz.com/upload/asset/32bf73a69fc12d36e76.json"));
}
The call method to get the data of an external link.
function main() {
Log(exchange.GetData("https://www.datadata.com/api/v1/query/xxx/data")) // The xxx part of the link is the code of the query data, here xxx is an example.
}
def main():
Log(exchange.GetData("https://www.datadata.com/api/v1/query/xxx/data"))
void main() {
Log(exchange.GetData("https://www.datadata.com/api/v1/query/xxx/data"));
}
Request data for a query created on the platform datadata, requesting that the data format of the answer be (must have time, data fields described in schema):
{
"data": [],
"schema": ["time", "data"]
}
The “data” field is the required data content, and the data in the “data” field needs to be the same as what is agreed in the “schema”. When the exchange.GetData()
function is called, a JSON object is returned, e.g.: {"Time":1579795200000, "Data":"..."}
.
Get the data at once for backtesting and cache one minute of data for live trading. In the backtesting system, when requesting data using the access interface, the backtesting system automatically adds from
(timestamped in seconds), to
(timestamped in seconds) to the request, parameters such as period
(underlying K-line period, timestamped in milliseconds) are used to determine the time frame over which the data is to be acquired.
{@fun/Market/exchange.SetData exchange.SetData}
The exchange.GetMarkets()
function is used to get exchange market information.
Dictionary containing the {@struct/Market Market} structure. object
exchange.GetMarkets()
function main() {
var markets = exchange.GetMarkets()
var currency = exchange.GetCurrency()
// Get the current contract code can also use exchange.GetContractType() function
var ct = "swap"
var key = currency + "." + ct
Log(key, ":", markets[key])
}
def main():
markets = exchange.GetMarkets()
currency = exchange.GetCurrency()
ct = "swap"
key = currency + "." + ct
Log(key, ":", markets[key])
void main() {
auto markets = exchange.GetMarkets();
auto currency = exchange.GetCurrency();
auto ct = "swap";
auto key = currency + "." + ct;
Log(key, ":", markets[key]);
}
Example of a call to a futures exchange object:
/*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]) + "`")
}
'''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]) + "`")
/*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() + "`");
}
Use the futures exchange object to call the exchange.GetMarkets()
function in the backtesting system. Before calling any market function, GetMarkets only returns the market data of the current default trading pair. After calling the market function, it returns the market data of all requested varieties. You can refer to the following test example:
The exchange.GetMarkets()
function returns a dictionary with a key named the name of the trade variety, and for spot fixes formatted as a trading pair, for example:
{
"BTC_USDT" : {...}, // The key value is the Market structure
"LTC_USDT" : {...},
...
}
For futures contract exchanges, as there may be multiple contracts for a single variety, e.g. BTC_USDT
trading pairs, there are perpetual contracts, quarterly contracts, and so on. The exchange.GetMarkets()
function returns a dictionary with the key name of the pair combined with the contract code, for example:
{
"BTC_USDT.swap" : {...}, // The key value is the Market structure
"BTC_USDT.quarter" : {...},
"LTC_USDT.swap" : {...},
...
}
exchange.GetMarkets()
function supports live tradings, backtesting system.exchange.GetMarkets()
function returns market information only for the varieties that are traded on line on the exchange.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 | – |
{@struct/Market Market}
The exchange.GetTickers()
function is used to get exchange aggregated ticker data (the array of {@struct/Ticker Ticker} structure). exchange
returns ticker data for all trading pairs when it is a spot exchange object; exchange
returns ticker data for all contracts when it is a futures exchange object.
The exchange.GetTickers()
function returns an array of {@struct/Ticker Ticker} structures when it succeeds in requesting data, and null when it fails.
{@struct/Ticker Ticker} arrays, null values
exchange.GetTickers()
function main() {
var tickers = exchange.GetTickers()
if (tickers && tickers.length > 0) {
Log("Number of tradable items on the exchange:", tickers.length)
}
}
def main():
tickers = exchange.GetTickers()
if tickers and len(tickers) > 0:
Log("Number of tradable items on the exchange:", len(tickers))
void main() {
auto tickers = exchange.GetTickers();
if (tickers.Valid && tickers.size() > 0) {
Log("Number of tradable items on the exchange:", tickers.size());
}
}
Call the exchange.GetTickers()
function to obtain aggregated market data.
/*backtest
start: 2024-05-21 00:00:00
end: 2024-09-05 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
function main() {
var arrSymbol = ["ADA_USDT", "LTC_USDT", "ETH_USDT", "SOL_USDT"]
// Before requesting other trading pair market data, call Get Tickers
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 market data for 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]) + "`")
}
'''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]) + "`")
/*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() + "`");
}
Use the spot exchange object and call the exchange.GetTickers()
function in the backtest system. Before calling any market function, GetTickers only returns the ticker data of the current default trading pair. After calling the market function, it returns the ticker data of all requested varieties. You can refer to the following test example:
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 |
{@struct/Ticker Ticker}, {@fun/Market/exchange.GetTicker exchange.GetTicker}
The exchange.Buy()
function is used to place buy orders. The Buy()
function is a member function of the exchange object {@var/EXCHANGE 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
, and it will not be repeated after the documentation.
A successful order returns the order Id, a failed order returns a null value.
The attribute Id
of the order {@struct/Order Order} structure of the FMZ platform consists of the exchange product code and the exchange original order ID, separated by English commas. For example, the attribute Id
format of the spot trading pair ETH_USDT
order of the OKX exchange is: ETH-USDT,1547130415509278720
.
When calling the exchange.Buy()
function to place an order, the return value order Id
is consistent with the Id
attribute of the order {@struct/Order Order} structure.
string, null value
exchange.Buy(price, amount) exchange.Buy(price, amount, …args)
The price
parameter is used to set the order price.
price
true
number
The amount
parameter is used to set the order amount.
amount
true
number
Extended parameters that can output accompanying information to this order log, arg
parameters can be passed more than one.
arg
false
string, number, bool, object, array, null and any other type supported by the system
function main() {
var id = exchange.Buy(100, 1);
Log("id:", id);
}
def main():
id = exchange.Buy(100, 1)
Log("id:", id)
void main() {
auto id = exchange.Buy(100, 1);
Log("id:", id);
}
The order number returned by exchange.Buy()
can be used to query the order information and cancel the order.
// The following is an error call
function main() {
exchange.SetContractType("quarter")
// Set the shorting direction
exchange.SetDirection("sell")
// If you place a buy order, an error will be reported, and shorting can only be sold
var id = exchange.Buy(50, 1)
// Set the long direction
exchange.SetDirection("buy")
// If you place a sell order, it will report an error, go long, only buy
var id2 = exchange.Sell(60, 1)
// Set direction to close long positions
exchange.SetDirection("closebuy")
// If you place a buy order, it will report an error, close long, only sell
var id3 = exchange.Buy(-1, 1)
// Set direction to close short positions
exchange.SetDirection("closesell")
// If you place a sell order, it will report an error, close short, only buy
var id4 = exchange.Sell(-1, 1)
}
# The following is an error call
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)
// The following is an error call
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);
}
When placing an order for a cryptocurrency futures contract, care must be taken to ensure that the trade direction is set correctly, as a mismatch between the trade direction and the trade function will result in an error:
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
// For example, the trading pair: ETH_BTC, place a buy order at the market price
function main() {
// Place a buy order at the market price and buy ETH coins with a value of 0.1 BTC (denominated currency)
exchange.Buy(-1, 0.1)
}
def main():
exchange.Buy(-1, 0.1)
void main() {
exchange.Buy(-1, 0.1);
}
Spot market order.
When placing an order for a futures contract, you must pay attention to whether the trade direction is set correctly, as an error will be reported if the trade direction and the trade function do not match. The order size for cryptocurrency futures contracts is the number of contracts if not specified.
The parameter price
is set to -1
for placing market orders, which requires the exchange’s order placement interface to support market orders. When placing market orders for cryptocurrency spot contracts, the parameter amount
is the amount of money in the currency of the order. When placing market orders for cryptocurrency futures contracts, the amount parameter amount
is the number of contracts. There are a few cryptocurrency exchanges that do not support market order interface during live trading. The order quantity for market buy orders on some spot exchanges is the number of trading coins. Please refer to the Special Instructions for Exchanges in the “User Guide” for details.
If you are using an older version of the docker, the return value of the order Id
of the exchange.Buy()
function may be different from the return value of the order Id
described in the current document.
{@fun/Trade/exchange.Sell exchange.Sell}, {@fun/Futures/exchange.SetContractType exchange.SetContractType}, {@fun/Futures/exchange.SetDirection exchange.SetDirection}
The exchange.Sell()
function is used to place sell orders.
A successful order returns the order Id, a failed order returns a null value. The attribute Id
of the order {@struct/Order Order} structure of the FMZ platform consists of the exchange product code and the exchange original order ID, separated by English commas. For example, the attribute Id
format of the spot trading pair ETH_USDT
order of the OKX exchange is: ETH-USDT,1547130415509278720
. When calling the exchange.Sell()
function to place an order, the return value order Id
is consistent with the Id
attribute of the order {@struct/Order Order} structure.
string, null value
exchange.Sell(price, amount) exchange.Sell(price, amount, …args)
The price
parameter is used to set the order price.
price
true
number
The amount
parameter is used to set the order amount.
amount
true
number
Extended parameters that can output accompanying information to this order log, arg
parameters can be passed more than one.
arg
false
string, number, bool, object, array, null and any other type supported by the system
function main(){
var id = exchange.Sell(100, 1)
Log("id:", id)
}
def main():
id = exchange.Sell(100, 1)
Log("id:", id)
void main() {
auto id = exchange.Sell(100, 1);
Log("id:", id);
}
The order number returned by exchange.Sell()
can be used to query order information and cancel orders.
// The following is an error call
function main() {
exchange.SetContractType("quarter")
// Set the shorting direction
exchange.SetDirection("sell")
// If you place a buy order, an error will be reported, and shorting can only be sold
var id = exchange.Buy(50, 1)
// Set the long direction
exchange.SetDirection("buy")
// If you place a sell order, it will report an error, go long, only buy
var id2 = exchange.Sell(60, 1)
// Set direction to close long positions
exchange.SetDirection("closebuy")
// If you place a buy order, it will report an error, close long, only sell
var id3 = exchange.Buy(-1, 1)
// Set direction to close short positions
exchange.SetDirection("closesell")
// If you place a sell order, it will report an error, close short, only buy
var id4 = exchange.Sell(-1, 1)
}
# The following is an error call
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)
// The following is an error call
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);
}
When placing an order for a cryptocurrency futures contract, care must be taken to ensure that the trade direction is set correctly, as a mismatch between the trade direction and the trade function will result in an error:
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
// For example, the trading pair: ETH_BTC, place a sell order at the market price
function main() {
// Note: place a market order to sell, sell 0.2 ETH
exchange.Sell(-1, 0.2)
}
def main():
exchange.Sell(-1, 0.2)
void main() {
exchange.Sell(-1, 0.2);
}
Spot market order.
When placing an order for a futures contract, you must pay attention to whether the trade direction is set correctly, as an error will be reported if the trade direction and the trade function do not match. The order amount for cryptocurrency futures contracts is the number of contracts if not specified.
The parameter price
is set to -1
for placing market orders, which requires the exchange’s order placement interface to support market orders. When placing market orders for cryptocurrency spot contracts, the amount parameter amount
is the amount in trading currency. When placing market orders for cryptocurrency futures contracts, the amount parameter amount
is the number of contracts. There are a few cryptocurrency exchanges that do not support market order interface during live trading.
If you are using an older version of the docker, the return value of the order Id
of the exchange.Sell()
function may be different from the return value of the order Id
described in the current document.
{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Futures/exchange.SetContractType exchange.SetContractType}, {@fun/Futures/exchange.SetDirection exchange.SetDirection}
The exchange.CreateOrder()
function is used to place an order.
If the order is successfully placed, the order ID is returned; if the order fails, a null value is returned. The attribute Id
of the order {@struct/Order Order} structure of the FMZ platform consists of the exchange product code and the exchange original order ID, separated by English commas. For example, the attribute Id
format of the order of the spot trading pair ETH_USDT
of the OKX exchange is: ETH-USDT,1547130415509278720
. When calling the exchange.CreateOrder(symbol, side, price, amount)
function to place an order, the return value of the order Id
is consistent with the Id
property of the order {@struct/Order Order} structure.
string, null value
exchange.CreateOrder(symbol, side, price, amount) exchange.CreateOrder(symbol, side, price, amount, …args)
The parameter symbol
is used to specify the specific trading pair and contract code of the order. When calling the exchange.CreateOrder(symbol, side, price, amount)
function to place an order, exchange
is the spot exchange object. If the order denominated currency is USDT and the tranding currency is BTC, the parameter symbol
is: "BTC_USDT"
, in the format of the trading pair defined by the FMZ platform. When calling the exchange.CreateOrder(symbol, side, price, amount)
function to place an order, exchange
is the futures exchange object. If the order is a BTC’s U-standard perpetual contract order, the parameter symbol
is: "BTC_USDT.swap"
, and the format is a combination of the trading pair and contract code defined by the FMZ platform, separated by the character “.”. When calling the exchange.CreateOrder(symbol, side, price, amount)
function to place an order, exchange
is the futures exchange object. If the order is a BTC’s U-standard option contract order, the parameter symbol
is: "BTC_USDT.BTC-240108-40000-C"
(taking Binance Option BTC-240108-40000-C as an example), and the format is a combination of the trading pair defined by the FMZ platform and the specific option contract code defined by the exchange, separated by the character “.”.
symbol
true
string
The side
parameter is used to specify the trading direction of the order.
For spot exchange objects, the optional values of the side
parameter are: buy
, sell
. buy
means buying, and sell
means selling.
For futures exchange objects, the optional values of the side
parameter are: buy
, closebuy
, sell
, closesell
. buy
means opening a long position, closebuy
means closing a long position, sell
means opening a short position, and closesell
means closing a short position.
side
true
string
The parameter price
is used to set the price of the order. A price of -1 indicates that the order is a market order.
price
true
number
The parameter amount
is used to set the order quantity. Please note that when the order is a market buy order, the order quantity is the purchase amount; the order quantity of the market buy order of some spot exchanges is the number of trading coins. For details, please refer to the Special Instructions for Exchanges in the “User Guide”.
amount
true
number
Extended parameters can output additional information to this order log. Multiple arg
parameters can be passed.
arg
false
Any type supported by the system, such as string, number, bool, object, array, null value, etc.
function main() {
var id = exchange.CreateOrder("BTC_USDT", "buy", 60000, 0.01) // Spot exchange objects place orders for currency-to-currency transactions BTC_USDT trading pairs
// var id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01) // Futures exchange objects place orders for BTC's U-standard perpetual contracts
Log("Order Id:", id)
}
def main():
id = exchange.CreateOrder("BTC_USDT", "buy", 60000, 0.01) # Spot exchange objects place orders for currency-to-currency transactions BTC_USDT trading pairs
# id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01) # Futures exchange objects place orders for BTC's U-standard perpetual contracts
Log("Order Id:", id)
void main() {
auto id = exchange.CreateOrder("BTC_USDT", "buy", 60000, 0.01); // Spot exchange objects place orders for currency-to-currency transactions BTC_USDT trading pairs
// auto id = exchange.CreateOrder("BTC_USDT.swap", "buy", 60000, 0.01); // Futures exchange objects place orders for BTC's U-standard perpetual contracts
Log("Order Id:", id);
}
Spot exchange objects and futures exchange objects call the exchange.CreateOrder()
function to place an order.
{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Trade/exchange.Sell exchange.Sell}
The exchange.CancelOrder()
function is used to cancel the order.
The attribute Id
of the order {@struct/Order Order} structure of the FMZ platform consists of the exchange product code and the exchange original order ID, separated by English commas. For example, the attribute Id
format of the order of the spot trading pair ETH_USDT
of the OKX exchange is: ETH-USDT,1547130415509278720
.
The parameter orderId
passed in when calling the exchange.CancelOrder()
function to cancel an order is consistent with the Id
property of the order {@struct/Order Order} structure.
The exchange.CancelOrder()
function returns a true value, for example true
means that the cancel order request was sent successfully. If it returns a false value, such as false
, means that the cancel order request failed to be sent. The return value only represents the success or failure of the request sent to determine whether the exchange cancels the order. You can call exchange.GetOrders()
to determine if the order is cancelled.
bool
exchange.CancelOrder(orderId) exchange.CancelOrder(orderId, …args)
The orderId
parameter is used to specify the order to be cancelled.
orderId
true
number, string
Extended parameters, you can output the attached information to this withdrawal log, arg
parameters can be passed more than one.
arg
false
string, number, bool, object, array, null and any other type supported by the system
function main(){
var id = exchange.Sell(99999, 1)
exchange.CancelOrder(id)
}
def main():
id = exchange.Sell(99999, 1)
exchange.CancelOrder(id)
void main() {
auto id = exchange.Sell(99999, 1);
exchange.CancelOrder(id);
}
Cancel the order.
function main() {
if (exchange.GetName().includes("Futures_")) {
Log("Set the contract as: perpetual contract, set the trade direction as: open long position.")
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, "Cancelled orders:", orders[i])
Sleep(500)
}
}
def main():
if exchange.GetName().find("Futures_") != -1:
Log("Set the contract as: perpetual contract, set the trade direction as: open long position.")
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"], "Cancelled orders:", orders[i])
Sleep(500)
void main() {
if (exchange.GetName().find("Futures_") != std::string::npos) {
Log("Set the contract as: perpetual contract, set the trade direction as: open long position.");
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, "Cancelled orders:", orders[i]);
Sleep(500);
}
}
FMZ API functions that can produce log output functions such as: Log()
, exchange.Buy()
, exchange.CancelOrder()
can be followed by some accompanying output parameters after the necessary parameters. For example: exchange.CancelOrder(orders[i].Id, orders[i])
, so that when canceling the order whose Id is orders[i].Id
, the order’s information is output with it. That is, the {@struct/Order Order} structure of orders[i]
.
If you are using an older version of the docker, the orderId parameter of the exchange.CancelOrder() function may be different from the orderId described in the current document.
{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Trade/exchange.Sell exchange.Sell}, {@fun/Trade/exchange.GetOrders exchange.GetOrders}
The exchange.GetOrder()
function is used to get the order information.
Query the order details according to the order number, and return the {@struct/Order Order} structure if the query succeeds, or return null if the query fails. {@struct/Order Order}, null value
exchange.GetOrder(orderId)
The orderId
parameter is used to specify the order to be queried.
The attribute Id
of the order {@struct/Order Order} structure of the FMZ platform consists of the exchange product code and the exchange original order ID, separated by English commas. For example, the attribute Id
format of the order of the spot trading pair ETH_USDT
of the OKX exchange is: ETH-USDT,1547130415509278720
.
The parameter orderId
passed in when calling the exchange.GetOrder()
function to query an order is consistent with the Id
property of the order {@struct/Order Order} structure.
orderId true string
function main(){
var id = exchange.Sell(1000, 1)
// Parameter id is the order number, you need to 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)
}
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"])
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);
}
The exchange.GetOrder()
function is not supported by some exchanges. The AvgPrice
attribute in the {@struct/Order Order} structure of the return value is the average price of the transaction. Some exchanges do not support this field, and if they do not, it is 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 | – |
{@struct/Order Order}, {@fun/Trade/exchange.GetOrders exchange.GetOrders}, {@fun/Trade/exchange.GetHistoryOrders exchange.GetHistoryOrders}
The exchange.GetOrders()
function is used to get outstanding orders.
The exchange.GetOrders()
function returns an array of {@struct/Order Order} structures if the request for data succeeds, and it returns null values if the request for data fails.
{@struct/Order Order} array, null value
exchange.GetOrders() exchange.GetOrders(symbol)
The parameter symbol
is used to set the transaction symbol or transaction symbol range to be queried.
For spot exchange objects, if the symbol
parameter is not passed, the uncompleted order data of all spot products will be requested.
For futures exchange objects, if the symbol
parameter is not passed, the default is to request the uncompleted order data of all varieties in the dimension range of the current trading pair and contract code.
symbol false string
/*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 out the information once and then return to prevent the order from being executed during the subsequent backtest and affecting data observation
return
}
'''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) + "`")
return
/*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 spot exchange object to place buy orders for multiple different trading pairs at half the current price, and then query the outstanding order information.
/*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 out the information once and then return to prevent the order from being executed during the subsequent backtest and affecting data observation
return
}
'''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) + "`")
return
/*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 type in the Order structure is TId, which is encoded using a C++ function to_string built into the FMZ platform.
arrJson.push_back(order.Price);
arrJson.push_back(order.Amount);
arrJson.push_back(order.DealAmount);
arrJson.push_back(order.AvgPrice);
arrJson.push_back(order.Status);
arrJson.push_back(order.Type);
arrJson.push_back(order.Offset);
arrJson.push_back(order.ContractType);
tbl["rows"].push_back(arrJson);
}
tbls.push_back(tbl);
}
LogStatus(_D(), "\n", "`" + tbls.dump() + "`");
return;
}
Use futures exchange objects to place orders for multiple different trading pairs and contract codes. Place orders at prices far away from the counterparty price, keep orders in an unfulfilled state, and query orders in multiple ways.
function main() {
var orders = exchange.GetOrders("BTC_USDT") // Examples of spot products
// var orders = exchange.GetOrders("BTC_USDT.swap") // Examples of futures products
Log("orders:", orders)
}
def main():
orders = exchange.GetOrders("BTC_USDT") # Examples of spot products
# orders = exchange.GetOrders("BTC_USDT.swap") # Examples of futures products
Log("orders:", orders)
void main() {
auto orders = exchange.GetOrders("BTC_USDT"); // Examples of spot products
// auto orders = exchange.GetOrders("BTC_USDT.swap"); // Examples of futures products
Log("orders:", orders);
}
When calling the exchange.GetOrders()
function, pass in the Symbol
parameter to request order data for a specific trading pair and contract code.
In the GetOrders
function, the usage scenarios of the symbol parameter are summarized as follows:
Exchange Object Classification | symbol Parameters | Query Scope | Remark |
---|---|---|---|
Spot | Do not pass symbol parameter | Query all spot trading pairs | For all calling scenarios, if the exchange interface does not support it, an error will be reported and a null value will be returned. No further explanation will be given. |
Spot | Specify the trading type, the symbol parameter is: “BTC_USDT” | Query the specified BTC_USDT trading pair | For spot exchange objects, the symbol parameter format is: “BTC_USDT” |
Futures | Do not pass symbol parameter | Query all trading products within the current trading pair and contract code dimension range | If the current trading pair is BTC_USDT and the contract code is swap, all USDT-margined perpetual contracts will be queried. This is equivalent to calling GetOrders("USDT.swap") |
Futures | Specify the trading type, the symbol parameter is: “BTC_USDT.swap” | Query the USDT-based perpetual contract for a specified BTC | For futures exchange objects, the parameter symbol format is: a combination of trading pair and contract code defined by the FMZ platform, separated by the characters ". . |
Futures | Specify the range of trading products, the symbol parameter is: “USDT.swap” | Query all USDT-based perpetual contracts | - |
Futures exchanges that support options | Do not pass symbol parameter | Query all option contracts within the current trading pair dimension range | If the current trading pair is BTC_USDT, the contract is set to an option contract, for example, Binance option contract: BTC-240108-40000-C |
Futures exchanges that support options | Specify specific trading products | Query the specified option contract | For example, for Binance Futures Exchange, the symbol parameter is: BTC_USDT.BTC-240108-40000-C |
Futures exchanges that support options | Specify the range of trading products, the symbol parameter is: “USDT.option” | Query all USDT-based options contracts | - |
In the GetOrders
function, the futures exchange object query
dimension range is summarized as follows:
symbol Parameters | Request Range Definition | Remark |
---|---|---|
USDT.swap | USDT-based perpetual contract range. | For |
dimensions that are not supported by the exchange API interface, an error will be reported and a null value will be returned when calling. | | USDT.futures | USDT-based delivery contract range. | - | | USD.swap | Range of currency-based perpetual contracts. | - | | USD.futures | Range of currency-based delivery contracts. | - | | USDT.option | USDT-based options contract range. | - | | USD.option | Currency-based options contract range. | - | | USDT.futures_combo | Range of CFD combinations. | Futures_Deribit Exchange | | USD.futures_ff | Range of mixed margin delivery contracts. | Futures_Kraken Exchange | | USD.swap_pf | Range of mixed margin perpetual contracts. | Futures_Kraken Exchange |
When the account represented by the exchange object exchange
has no pending orders within the query range or specified trading instruments (active orders in an unfulfilled state), calling this function returns an empty array, that is: []
.
The following exchanges require the instrument to pass in the instrument parameter when querying the currently uncompleted orders. When calling the GetOrders function with these exchanges, if the instrument parameter is not passed in, only the uncompleted orders of the current instrument are requested, not the uncompleted orders of all instruments (because the exchange interface does not support this).
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 |
{@struct/Order Order}, {@fun/Trade/exchange.GetOrder exchange.GetOrder}, {@fun/Trade/exchange.GetHistoryOrders exchange.GetHistoryOrders}
The exchange.GetHistoryOrders()
function is used to obtain the current trading pair, the historical orders for contracts; it supports the specification of specific trading varieties.
The exchange.GetHistoryOrders()
function returns an array of {@struct/Order Order} structures if the request for data succeeds, and null if the request fails.
{@struct/Order Order} arrays, null values
exchange.GetHistoryOrders() exchange.GetHistoryOrders(symbol) exchange.GetHistoryOrders(symbol, since) exchange.GetHistoryOrders(symbol, since, limit) exchange.GetHistoryOrders(since) exchange.GetHistoryOrders(since, limit)
The symbol
parameter is used to specify the trade symbol. In the case of the BTC_USDT
trading pair, for example, when the exchange
is a spot exchange object, the parameter format for symbol
is BTC_USDT
; if it’s a futures exchange object, taking perpetual contract as an example, the parameter format for symbol
is: BTC_USDT.swap
.
If you are querying the order data of option contracts, set the parameter symbol
to "BTC_USDT.BTC-240108-40000-C"
(taking Binance Option BTC-240108-40000-C as an example). The format is a combination of the trading pair defined by the FMZ platform and the specific option contract code defined by the exchange, separated by the character “.”.
If this parameter is not passed, the order data of the currently set trading pair and contract code will be requested by default.
symbol
false
string
The since
parameter is used to specify the starting timestamp of the query in milliseconds.
since
false
number
The limit
parameter is used to specify the number of orders to query.
limit
false
number
function main() {
var historyOrders = exchange.GetHistoryOrders()
Log(historyOrders)
}
def main():
historyOrders = exchange.GetHistoryOrders()
Log(historyOrders)
void main() {
auto historyOrders = exchange.GetHistoryOrders();
Log(historyOrders);
}
symbol
, since
, limit
parameters are not specified, the default query is the current trading pair, the historical orders of contract. Queries the historical orders within a certain range nearest to the current time, the query range depends on the single query range of the exchange interface.symbol
parameter is specified, query the history of orders for the set trade type.since
parameter is specified, query in the direction of the current time using the since
timestamp as the start time.limit
parameter is specified, the query is returned after a sufficient number of entries.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_dYdX / Futures_Bibox / Futures_ApolloX |
{@struct/Order Order}, {@fun/Trade/exchange.GetOrder exchange.GetOrder}, {@fun/Trade/exchange.GetOrders exchange.GetOrders}
exchange.SetPrecision()
function is used to set the precision of the exchange
exchange object price and order amount, after setting, the system will ignore the excess data automatically.
exchange.SetPrecision(pricePrecision, amountPrecision)
The pricePrecision
parameter is used to control the precision of the price data.
pricePrecision
true
number
The amountPrecision
parameter is used to control the precision of the amount of data to be ordered.
amountPrecision
true
number
function main(){
// Set the decimal precision of price to 2 bits, and the decimal precision of variety order amount to 3 bits
exchange.SetPrecision(2, 3)
}
def main():
exchange.SetPrecision(2, 3)
void main() {
exchange.SetPrecision(2, 3);
}
The backtesting system does not support this function, and the numerical accuracy of the backtesting system is handled automatically.
{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Trade/exchange.Sell exchange.Sell}
Set the current exchange rate of the exchange object.
exchange.SetRate(rate)
The rate
parameter is used to specify the conversion exchange rate.
rate
true
number
function main(){
Log(exchange.GetTicker())
// Set exchange rate conversion
exchange.SetRate(7)
Log(exchange.GetTicker())
// Set to 1, no conversion
exchange.SetRate(1)
}
def main():
Log(exchange.GetTicker())
exchange.SetRate(7)
Log(exchange.GetTicker())
exchange.SetRate(1)
void main() {
Log(exchange.GetTicker());
exchange.SetRate(7);
Log(exchange.GetTicker());
exchange.SetRate(1);
}
If an exchange rate value has been set using the exchange.SetRate()
function, such as 7. Then all price information such as tickers, depths, order prices, etc. for the exchange represented by the current exchange
exchange object will be converted by multiplying it by the set exchange rate of 7. For example, exchange
is an exchange with the US dollar as the denomination currency. After executing exchange.SetRate(7)
, all prices on the live market will be converted to prices close to CNY denomination by multiplying by 7.
{@fun/Market/exchange.GetRate exchange.GetRate}
The exchange.IO()
function is used for other interface calls related to the exchange object.
The exchange.IO()
function calls other interfaces related to the exchange object, returning the requested response data on a successful call and it returns null on a failed call.
string, number, bool, object, array, null, and any other type supported by the system
exchange.IO(k, …args)
The k
parameter is used to set the call type, with optional values "api"
, "currency"
, "base"
, "trade_margin"
, "trade_normal"
, "public_base"
, "mbase"
, selfTradePreventionMode
, simulate
, cross
, dual
, unified
and so on.
k
true
string
Extended parameters, passed according to the specific call scenario, arg
parameters can be passed more than one. Due to the polymorphic mechanism of the exchange.IO()
function, different parameter settings correspond to different functions. The number and type of parameters to the exchange.IO()
function are indeterminate.
arg
true
string, number, bool, object, array, null and any other types supported by the system
function 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 access the exchange's bulk order interface directly
var ret = exchange.IO("api", "POST", "/api/v5/trade/batch-orders", "", JSON.stringify(arrOrders))
Log(ret)
}
import 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)
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);
}
Using the exchange.IO("api", httpMethod, resource, params, raw)
call form of the exchange.IO()
function, it is necessary to understand the API interface of the exchange and check the relevant documentation first. This will allow you to extend the functionality that is not added to the FMZ platform. Submitting a POST
request does not require you to worry about encrypting, signing, or verifying the parameters, which are already handled by FMZ at the bottom, as long as you fill in the corresponding parameters. You can refer to the batch order example of OKX Exchange futures contracts, and use the parameter raw
to pass the order parameters:
var amount = 1
var price = 10
var basecurrency = "ltc"
function main () {
// Note that both amount.toString() and price.toString() have a ' character on the left and right side
var message = "symbol=" + basecurrency + "&amount='" + amount.toString() + "'&price='" + price.toString() + "'&side=buy" + "&type=limit"
var id = exchange.IO("api", "POST", "/v1/order/new", message)
}
amount = 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)
void main() {
auto amount = 1.0;
auto price = 10.0;
auto basecurrency = "ltc";
string message = format("symbol=%s&amount=\"%.1f\"&price=\"%.1f\"&side=buy&type=limit", basecurrency, amount, price);
auto id = exchange.IO("api", "POST", "/v1/order/new", message);
}
If the key value in the params
parameter (i.e., Http request parameter) is a string, it needs to be written in single quotes (i.e., the symbol ') around the parameter value to wrap the parameter value.
function main() {
var ret = exchange.IO("api", "GET", "https://www.okx.com/api/v5/account/max-withdrawal", "ccy=BTC")
Log(ret)
}
def main():
ret = exchange.IO("api", "GET", "https://www.okx.com/api/v5/account/max-withdrawal", "ccy=BTC")
Log(ret)
void main() {
auto ret = exchange.IO("api", "GET", "https://www.okx.com/api/v5/account/max-withdrawal", "ccy=BTC");
Log(ret);
}
It supports passing in complete url parameters, which can omit the operation of switching the base address (calling the exchange.SetBase()
function).
function main(){
var ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT")
Log(ret)
}
def main():
ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT")
Log(ret)
void main() {
auto ret = exchange.IO("api", "GET", "/api/v5/trade/orders-pending", "instType=SPOT");
Log(ret);
}
Example of a call without the parameter raw
:
function main() {
// For example, if you set the current trading pair of the exchange object to BTC_USDT at the beginning of the live trading, print the current trading pair tickers
Log(exchange.GetTicker())
// Switch the trading pair to LTC_BTC
exchange.IO("currency", "LTC_BTC")
Log(exchange.GetTicker())
}
def main():
Log(exchange.GetTicker())
exchange.IO("currency", "LTC_BTC")
Log(exchange.GetTicker())
void main() {
Log(exchange.GetTicker());
exchange.IO("currency", "LTC_BTC");
Log(exchange.GetTicker());
}
Switch the trading pair of current exchange, so that it will switch the trading pair configured by code at live trading creation or at backtest.
function main () {
// exchanges[0] is the first exchange object added when the live trading is created
exchanges[0].IO("base", "https://api.huobi.pro")
}
def main():
exchanges[0].IO("base", "https://api.huobi.pro")
void main() {
exchanges[0].IO("base", "https://api.huobi.pro");
}```
For example, the default base address when the exchange object is wrapped is ```https://api.huobipro.com```, and when you need to switch to ```https://api.huobi.pro```, use the following code to switch:
```javascript
function main() {
exchange.SetBase("https://api.bitfinex.com")
exchange.IO("mbase", "https://api-pub.bitfinex.com")
}
def main():
exchange.SetBase("https://api.bitfinex.com")
exchange.IO("mbase", "https://api-pub.bitfinex.com")
void main() {
exchange.SetBase("https://api.bitfinex.com");
exchange.IO("mbase", "https://api-pub.bitfinex.com");
}
For exchanges with different base addresses for the ticker interface and trading interface, for example, Bitfinex Futures have two addresses, one for the ticker interface and the other for the trading interface. Bitfinex futures switch private interface base address using exchange.SetBase("xxx")
. Bitfinex futures switch public interface base address using exchange.IO("mbase", "xxx")
.
I. For cryptocurrency-centric exchanges other API interface calls that are not uniformly encapsulated, with parameter k
set to "api"
:
exchange.IO("api", httpMethod, resource, params, raw)
POST
, GET
, etc.URL
.The exchange.IO("api", httpMethod, resource, params, raw)
function call will access the exchange interface and return null if the call fails and an error occurs.
Only the real trading supports calling the exchange.IO("api", httpMethod, resource, params, raw)
function.
II. For switching trading pairs, the parameter k
is set to "currency"
:
exchange.IO("currency", currency)
currency : The parameter is a string type with a uniform upper case format, using an underscore to separate baseCurrency
from quoteCurrency
, such as BTC_USDT
.
ETH_BTC
can only switch to LTC_BTC
, not to LTC_USDT
.exchange.IO("currency", currency)
to switch trading pairs.III. Used to switch the cryptocurrency spot exchange object leveraged account mode:
k
is set to "trade_margin"
to switch to the spot leverage account mode. Placing orders and obtaining account assets will access the exchange’s spot leveraged interface.
If the exchange distinguishes between full margin and isolated margin in spot leverage, use: exchange.IO("trade_super_margin")
to switch to full margin for leveraged account, and exchange.IO("trade_margin")
to switch to isolated margin for leveraged account.k
is set to "trade_normal"
to switch back to normal spot account mode.Spot exchanges that support switching between leveraged account models:
Exchanges | Special remarks |
---|---|
OKX | Trading pairs in leveraged account mode are different from normal ones, some trading pairs may not have them. Use exchange.IO("trade_super_margin") to switch to full position for leveraged accounts and use exchange.IO("trade_margin") to switch to position by position. Use trade_normal to switch to normal spot mode. Use exchange.IO("tdMode", "cross") to directly specify the leverage mode. |
Huobi | Leveraged account mode trading pairs are different from normal ones, some trading pairs may not have them. There are full positions and position-by-position in Huobi leveraged accounts. Use trade_margin to switch to leverage account position by position, use trade_super_margin to switch to leverage account full position. Use trade_normal to switch to normal currency-currency mode. |
Binance | Leveraged account mode is divided into position by position and full position, use trade_margin to switch to position by position, use trade_super_margin to switch to full position, use trade_normal to switch to normal currency-currency mode. |
GateIO | Leveraged account mode is divided into position by position and full position, use trade_margin to switch to position by position, use trade_super_margin to switch to full position, use trade_normal to switch to normal currency-currency mode. |
AscendEx | Use exchange.IO("trade_margin") to switch to leverage account mode and exchange.IO("trade_normal") to switch back to normal account mode. |
WOO | Use exchange.IO("trade_margin") to switch to leverage account mode and exchange.IO("trade_normal") to switch back to normal account mode. |
CoinEx | Use exchange.IO("trade_margin") to switch to leveraged account mode and exchange.IO("trade_normal") to switch back to normal account mode. |
IV. Other switching functions:
Check out the exchange.IO()
function for Other switching functions in the User Guide.
{@fun/NetSettings/exchange.SetBase exchange.SetBase}, {@fun/Account/exchange.SetCurrency exchange.SetCurrency}, {@var EXCHANGE_OP_IO_CONTROL}
The exchange.Log()
function is used to output the log of order placement and withdrawal in the log column area. When called, no orders are placed, only the transaction log is output and recorded.
exchange.Log(orderType, price, amount) exchange.Log(orderType, price, amount, …args)
The orderType
parameter is used to set the output log type, the optional values are {@var/LOG_TYPE/LOG_TYPE_BUY LOG_TYPE_BUY}, {@var/LOG_TYPE/LOG_TYPE_SELL LOG_TYPE_SELL}, {@var/LOG_TYPE/LOG_TYPE_CANCEL LOG_TYPE_CANCEL}.
orderType
true
number
The price
parameter is used to set the price displayed in the output log.
price
true
number
The amount
parameter is used to set the amount of orders placed displayed in the output log.
amount
true
number
Extended parameters that can output accompanying information to this log, arg
parameters can be passed more than one.
arg
false
string, number, bool, object, array, null and any other type supported by the system
var id = 123
function main() {
// Order type buy, price 999, amount 0.1
exchange.Log(LOG_TYPE_BUY, 999, 0.1)
// Cancel the order
exchange.Log(LOG_TYPE_CANCEL, id)
}
id = 123
def main():
exchange.Log(LOG_TYPE_BUY, 999, 0.1)
exchange.Log(LOG_TYPE_CANCEL, id)
void main() {
auto id = 123;
exchange.Log(LOG_TYPE_BUY, 999, 0.1);
exchange.Log(LOG_TYPE_CANCEL, id);
}
Using exchange.Log(orderType, price, amount)
can be used for live trading order following tests, simulated order placement, and it can assist in logging order placement. One of the most common scenarios is to use the {@fun/Trade/exchange.IO exchange.IO} function to access the exchange’s interface for creating conditional orders, but using the exchange.IO()
function does not output the transaction log information in the live trading log record. This is where the exchange.Log()
function can be used to supplement the output log in order to record order placement information, and the same is true for order withdrawal operations.
When the orderType
parameter is LOG_TYPE_CANCEL
, the price
parameter is the order Id of the withdrawn order, which is used to print the withdrawal log when the order is withdrawn directly using the exchange.IO()
function. The exchange.Log()
function is a member function of the {@var/EXCHANGE exchange} exchange object, as distinguished from the global function {@fun/Log Log}.
{@fun/Log Log}, {@var/EXCHANGE exchange}, {@var/LOG_TYPE/LOG_TYPE_BUY LOG_TYPE_BUY}, {@var/LOG_TYPE/LOG_TYPE_SELL LOG_TYPE_SELL}, {@var/LOG_TYPE/LOG_TYPE_CANCEL LOG_TYPE_CANCEL}
The exchange.Encode()
function is used for signature encryption calculations.
The exchange.Encode()
function returns the calculated hash value encoding.
string
exchange.Encode(algo, inputFormat, outputFormat, data) exchange.Encode(algo, inputFormat, outputFormat, data, keyFormat, key)
The parameter algo
is the algorithm used for encoding calculation. Supported settings are: “raw” (no algorithm used), “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 parameter algo
also supports: “text.encoder.utf8”, “text.decoder.utf8”, “text.encoder.gbk”, “text.decoder.gbk”, for encoding and decoding strings. The parameter algo
also supports: “ed25519” algorithm. It supports the use of different hash algorithms, for example, the parameter algo
can be written as “ed25519.md5”, “ed25519.sha512”, etc. Supports ed25519.seed
calculation.
algo
true
string
Used to specify the data format of the data
parameter. The inputFormat
parameter can be set to one of: “raw”, “hex”, “base64”, and “string”. “raw” means the data is raw data, “hex” means the data is hex
encoded, “base64” means the data is base64
encoded, and “string” means the data is a string.
inputFormat
true
string
Used to specify the output data format. The outputFormat
parameter supports the following settings: “raw”, “hex”, “base64”, “string”. “raw” means the data is raw data, “hex” means the data is hex
encoded, “base64” means the data is base64
encoded, and “string” means the data is a string.
outputFormat
true
string
The parameter data
is the data to be processed.
data
true
string
Used to specify the data format of the key
parameter. The key
parameter can be set to one of: “raw”, “hex”, “base64”, and “string”. “raw” means the data is raw data, “hex” means the data is hex
encoded, “base64” means the data is base64
encoded, and “string” means the data is a string.
keyFormat
false
string
The key
parameter is used to specify the key used in the signature calculation, and it can be used as a plaintext string. You can also use "{{accesskey}}"
, "{{secretkey}}"
to refer to the accessKey
and secretKey
configured in the {@var/EXCHANGE exchange} exchange object.
key
false
string
function main() {
var APIKEY = "your Access Key(Bitmex API ID)"
var expires = parseInt(Date.now() / 1000) + 10
var signature = exchange.Encode("sha256", "string", "hex", "GET/realtime" + expires, "hex", "{{secretkey}}")
var client = Dial("wss://www.bitmex.com/realtime", 60)
var auth = JSON.stringify({args: [APIKEY, expires, signature], op: "authKeyExpires"})
var pos = 0
client.write(auth)
client.write('{"op": "subscribe", "args": "position"}')
while (true) {
bitmexData = client.read()
if(bitmexData.table == 'position' && pos != parseInt(bitmexData.data[0].currentQty)){
Log('position change', pos, parseInt(bitmexData.data[0].currentQty), '@')
pos = parseInt(bitmexData.data[0].currentQty)
}
}
}
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"]
void main() {
auto APIKEY = "your Access Key(Bitmex API ID)";
auto expires = Unix() + 10;
auto signature = exchange.Encode("sha256", "string", "hex", format("GET/realtime%d", expires), "hex", "{{secretkey}}");
auto client = Dial("wss://www.bitmex.com/realtime", 60);
json auth = R"({"args": [], "op": "authKeyExpires"})"_json;
auth["args"].push_back(APIKEY);
auth["args"].push_back(expires);
auth["args"].push_back(signature);
auto pos = 0;
client.write(auth.dump());
client.write("{\"op\": \"subscribe\", \"args\": \"position\"}");
while(true) {
auto bitmexData = json::parse(client.read());
if(bitmexData["table"] == "position" && bitmexData["data"][0].find("currentQty") != bitmexData["data"][0].end() && pos != bitmexData["data"][0]["currentQty"]) {
Log("test");
Log("position change", pos, bitmexData["data"][0]["currentQty"], "@");
pos = bitmexData["data"][0]["currentQty"];
}
}
}
Example of BitMEX position change push (wss protocol):
Only the real trading supports calling the exchange.Encode()
function. The "{{accesskey}}"
, "{{secretkey}}"
references are only valid when the exchange.Encode()
function is used.
{@var/EXCHANGE exchange}, {@fun/Global/Encode Encode}
Multi-threaded asynchronous support functions can turn the operations of all supported functions into asynchronous concurrent execution.
The exchange.Go()
function returns a concurrent object immediately, and you can use the wait()
method of that concurrent object to get the result of the concurrent request.
object
exchange.Go(method) exchange.Go(method, …args)
The method
parameter is used to specify the name of the concurrent function. Note that the parameter is a function name string, not a function reference.
method
true
string
Parameters to concurrently executing functions, there may be more than one parameter arg
. The type and number of parameter arg
depends on the parameters of the concurrent execution function.
arg
false
string, number, bool, object, array, function, null, and all other types supported by the system
function main(){
// The following four operations are concurrently executed asynchronously by multiple threads and do not take 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 return of the ticker results asynchronously
var ticker = a.wait()
// Returns the depth, or null if it fails
var depth = b.wait()
// return order number, limited to 1 second timeout, if timeout, returns undefined, the object can continue to call wait if the last wait timeout
var orderId = c.wait(1000)
if(typeof(orderId) == "undefined") {
// Timeout, reacquire
orderId = c.wait()
}
var records = d.wait()
}
def 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()
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);
}
Exchange.Go()
function usage example, to determine undefined
to use typeof(xx) === "undefined"
, because null == undefined
is valid in JavaScript.
function main() {
var d = exchange.Go("GetRecords", PERIOD_H1)
// Waiting for K-line results
var records = d.wait()
// Here waits an asynchronous operation that has been waited and finished, it will return null, and log the error message
var ret = d.wait()
}
def main():
d = exchange.Go("GetRecords", PERIOD_H1)
records, ok = d.wait()
ret, ok = d.wait()
void main() {
auto d = exchange.Go("GetRecords", PERIOD_H1);
Records records;
d.wait(records);
Records ret;
d.wait(ret);
}
Calling the wait()
method on a concurrent object that has been released will report an error:
function 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: "ticker",
cols: ["index", "name", "latest-deal-price"],
rows: []
}
for(var i = 0; i < arrTicker.length; i++) {
tbl.rows.push([i, arrName[i], arrTicker[i].Last])
}
LogStatus(_D(), "Total time taken to obtain tickers from multiple exchanges concurrently:", endTS - beginTS, "millisecond", "\n", "`" + JSON.stringify(tbl) + "`")
Sleep(500)
}
}
import 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": "ticker",
"cols": ["index", "name", "latest-deal-price"],
"rows": []
}
for i in range(len(arrTicker)):
tbl["rows"].append([i, arrName[i], arrTicker[i]["Last"]])
LogStatus(_D(), "Total time taken to obtain tickers from multiple exchanges concurrently:", endTS - beginTS, "second", "\n", "`" + json.dumps(tbl) + "`")
Sleep(500)
void main() {
while(true) {
int length = exchanges.size();
auto beginTS = UnixNano() / 1000000;
Ticker arrTicker[length] = {};
string arrName[length] = {};
// Note that to add several exchange objects, several exchanges[n].Go functions have to be executed here, this example is to add four exchange objects, the details can be modified
auto r0 = exchanges[0].Go("GetTicker");
auto r1 = exchanges[1].Go("GetTicker");
auto r2 = exchanges[2].Go("GetTicker");
auto r3 = exchanges[3].Go("GetTicker");
GoObj *arrRoutine[length] = {&r0, &r1, &r2, &r3};
for(int i = 0; i < length; i++) {
arrName[i] = exchanges[i].GetName();
}
for(int i = 0; i < length; i++) {
Ticker ticker;
arrRoutine[i]->wait(ticker);
arrTicker[i] = ticker;
}
auto endTS = UnixNano() / 1000000;
json tbl = R"({
"type": "table",
"title": "ticker",
"cols": ["index", "name", "latest-deal-price"],
"rows": []
})"_json;
for(int i = 0; i < length; i++) {
json arr = R"(["", "", ""])"_json;
arr[0] = format("%d", i);
arr[1] = arrName[i];
arr[2] = format("%f", arrTicker[i].Last);
tbl["rows"].push_back(arr);
}
LogStatus(_D(), "Total time taken to obtain tickers from multiple exchanges concurrently:", format("%d", endTS - beginTS), "millisecond", "\n", "`" + tbl.dump() + "`");
Sleep(500);
}
}
Concurrent access to multiple exchange tickers:
function main() {
/*
Testing with OKX futures order interface
POST /api/v5/trade/order
*/
var beginTS = new Date().getTime()
var param = {"instId":"BTC-USDT-SWAP","tdMode":"cross","side":"buy","ordType":"limit","px":"16000","sz":"1","posSide":"long"}
var ret1 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", JSON.stringify(param))
var ret2 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", JSON.stringify(param))
var ret3 = exchange.Go("IO", "api", "POST", "/api/v5/trade/order", "", JSON.stringify(param))
var id1 = ret1.wait()
var id2 = ret2.wait()
var id3 = ret3.wait()
var endTS = new Date().getTime()
Log("id1:", id1)
Log("id2:", id2)
Log("id3:", id3)
Log("Concurrent order placement time consumption:", endTS - beginTS, "millisecond")
}
import 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 placement time consumption:", endTS - beginTS, "second")
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 placement time consumption:", endTS - beginTS, "millisecond");
}
Concurrent calls for exchange.IO("api", ...)
function:
This function only creates multi-threaded execution tasks when running in real trading, backtesting does not support multi-threaded concurrent task execution (backtesting is available, but still executed sequentially).
After the exchange.Go()
function returns an object, its wait()
function is called through that object to get the data returned by the thread. The wait()
function must be called to get the data before the thread will be released automatically. If the timeout parameter of the wait()
function is specified, the thread will not be released automatically even if a timeout occurs. The result of the thread must be obtained before it will be released automatically (regardless of the success or failure of the interface call for concurrent access). In simple terms, the requested thread must be obtained by the wait()
function regardless of whether the execution succeeds or fails, and the resource of the thread requested by the exchange.Go()
function must be released automatically by the docker.
The wait()
method supports a timeout parameter:
Without a timeout parameter, that is, wait()
, or with a timeout parameter of 0, that is, wait(0)
. The wait()
function blocks and waits until the concurrent thread has finished running, returning the result of the concurrent thread’s execution.
Set the timeout parameter -1, i.e. wait(-1)
. The wait()
function returns immediately, with different return values for different programming languages, see this subsection for an example call.
Set the specific timeout parameter, wait(300)
, and the wait()
function will wait a maximum of 300 milliseconds before returning.
If the return result of the final wait()
function is not obtained, the thread resources will not be released automatically, which will lead to the accumulation of threads requested, and more than 2000 will report an error: "too many routine wait, max is 2000"
.
Supported functions: GetTicker
, GetDepth
, GetTrades
, GetRecords
, GetAccount
, GetOrders
, GetOrder
, CancelOrder
, Buy
, Sell
, GetPositions
, IO
. All these functions are executed based on the current {@var/EXCHANGE exchange} exchange object when called concurrently.
The difference between Python language and JavaScript language is that the wait()
function of concurrent objects in Python language returns two parameters. The first parameter is the result returned by an asynchronous API call, and the second parameter indicates whether the asynchronous call is completed.
def main():
d = exchange.Go("GetRecords", PERIOD_D1)
# ok will return True definitely, unless the strategy is stopped
ret, ok = d.wait()
# If the wait times out, or if it waits for an instance that has already ended, ok returns False
ret, ok = d.wait(100)
{@fun/Global/Mail_Go Mail_Go}, {@fun/Global/HttpQuery_Go HttpQuery_Go}, {@fun/Global/EventLoop EventLoop}
The exchange.GetAccount()
function is used to request exchange account information. The GetAccount()
function is a member function of the exchange object {@var/EXCHANGE exchange}. The purpose of the member functions (methods) of the exchange
object is only related to exchange
, and it will not be repeated after the documentation.
Query the account asset information and return the {@struct/Account Account} structure if the query succeeds or null if it fails. {@struct/Account Account}, null value
exchange.GetAccount()
function main(){
// Switching trading pairs
exchange.IO("currency", "BTC_USDT")
// Take OKX futures as an example, set the contract as the current week's contract, the current trading pair is BTC_USDT, so the current contract is BTC's U-nominal current week contract
exchange.SetContractType("this_week")
// Get current account asset data
var account = exchange.GetAccount()
// Available balance of USDT as margin
Log(account.Balance)
// USDT freeze amount as margin
Log(account.FrozenBalance)
// Current asset equity
Log(account.Equity)
// The unrealized profit and loss of all positions held with the current asset as margin
Log(account.UPnL)
}
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"])
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"])
}
Set up trading pairs, contract codes, and get current account information.
If the exchange object is set to a cryptocurrency futures contract exchange, and switched to a contract with USDT
as margin (see {@fun/Account/exchange.SetCurrency exchange.SetCurrency}, {@fun/Futures/exchange.SetContractType exchange.SetContractType} functions for how to switch). The asset is USDT
as margin, which is recorded in the Balance
, FrozenBalance
attributes of the {@struct/Account Account} structure.
If the exchange object is set to a cryptocurrency futures contract exchange, and switched to a currency-based contract, the asset is in currency as margin and is recorded in the Stocks
, FrozenStocks
attributes of the {@struct/Account Account} structure.
When using the Binance Futures unified account, when calling the exchange.GetAccount()
function to request account information, the encapsulated data is the amount of all assets converted into USD. It is displayed in the Balance
field of the {@struct/Account Account} structure. If you need to calculate the conversion amount of other assets, you can use the USD conversion amount divided by the index price (of the asset to be converted) and then divided by the pledge rate (of the asset to be converted) to calculate it.
{@struct/Account Account}, {@fun/Account/exchange.SetCurrency exchange.SetCurrency}, {@fun/Futures/exchange.SetContractType exchange.SetContractType}
The exchange.GetAssets
function is used to request exchange account asset information.
The exchange.GetAssets()
function returns an array of {@struct/Asset Asset} structures if the request for data succeeds, or null if the request fails.
{@struct/Asset Asset} array, null value
exchange.GetAssets()
function main() {
// exchange.SetCurrency("BTC_USDT") // You can set up trading pairs
// exchange.SetContractType("swap") // You can set up contracts
var assets = exchange.GetAssets()
Log(assets)
}
def main():
# exchange.SetCurrency("BTC_USDT") # You can set up trading pairs
# exchange.SetContractType("swap") # You can set up contracts
assets = exchange.GetAssets()
Log(assets)
void main() {
// exchange.SetCurrency("BTC_USDT"); // You can set up trading pairs
// exchange.SetContractType("swap"); // You can set up contracts
auto assets = exchange.GetAssets();
Log(assets);
}
Get information about the assets of an exchange account, exchange.GetAssets()
returns an array with elements of the Asset structure.
The GetAssets()
function of the Futures Exchange object returns the margin assets under the current trading pair (currency-based, USDT-based, USDC-based, etc.).
{@struct/Asset Asset}
The exchange.GetName()
function is used to get the name of the exchange to which the current exchange object is bound.
The exchange.GetName()
function returns the name of the exchange defined by the FMZ Quant Trading platform.
string
exchange.GetName()
function main() {
Log("The exchange object exchange is judged to be Binance spot, and the result is judged to be:", exchange.GetName() == "Binance")
}
def main():
Log("The exchange object exchange is judged to be Binance spot, and the result is judged to be:", exchange.GetName() == "Binance")
void main() {
Log("The exchange object exchange is judged to be Binance spot, and the result is judged to be:", exchange.GetName() == "Binance");
}
The exchange.GetName()
function is generally used to identify the exchange objects, such as exchange
or exchanges[1]
, exchanges[2]
in the strategy code. The names of cryptocurrency futures contract exchanges have the fixed prefix Futures_
.
{@fun/Account/exchange.GetLabel exchange.GetLabel}
The exchange.GetLabel()
function is used to get the custom label that was set when the exchange object was configured.
The exchange.GetLabel()
function returns the custom label that was set when the exchange object was configured.
string
exchange.GetLabel()
function main() {
Log("exchange label:", exchange.GetLabel())
}
def main():
Log("exchange label:", exchange.GetLabel())
void main() {
Log("exchange label:", exchange.GetLabel());
}
Exchange objects such as exchange
or exchanges[1]
, exchanges[2]
in the strategy code are identified by the set tag.
{@var/EXCHANGE exchange}
The exchange.GetCurrency()
function is used to get the currently set trading pair.
The exchange.GetCurrency()
function returns the trading pair set by the current {@var/EXCHANGE exchange} exchange object.
string
exchange.GetCurrency()
function main() {
Log("the current trading pair of exchange is:", exchange.GetCurrency())
}
def main():
Log("the current trading pair of exchange is:", exchange.GetCurrency())
void main() {
Log("the current trading pair of exchange is:", exchange.GetCurrency());
}
The trading pair format is uppercase uniformly, using underscores to separate baseCurrency
and quoteCurrency
, such as BTC_USDT
.
{@fun/Account/exchange.SetCurrency exchange.SetCurrency}
The exchange.SetCurrency()
function is used to switch the current trading pair of the exchange object {@var/EXCHANGE exchange}.
exchange.SetCurrency(currency)
The currency
parameter is used to set the trading pair to be switched. The trading pair format is uppercase uniformly, using an underscore to separate baseCurrency
from quoteCurrency
, such as BTC_USDT
.
currency
true
string
function main() {
var ticker = exchange.GetTicker()
Log(ticker)
Log(exchange.GetAccount())
// Switching trading pairs, pay attention to the changes of ticker data and account information after switching
exchange.SetCurrency("LTC_USDT")
Log("Switch to LTC_USDT")
ticker = exchange.GetTicker()
Log(ticker)
Log(exchange.GetAccount())
}
def main():
ticker = exchange.GetTicker()
Log(ticker)
Log(exchange.GetAccount())
exchange.SetCurrency("LTC_USDT")
Log("Switch to LTC_USDT")
ticker = exchange.GetTicker()
Log(ticker)
Log(exchange.GetAccount())
void main() {
auto ticker = exchange.GetTicker();
Log(ticker);
Log(exchange.GetAccount());
exchange.SetCurrency("LTC_USDT");
Log("Switch to LTC_USDT");
ticker = exchange.GetTicker();
Log(ticker);
Log(exchange.GetAccount());
}
exchange.IO("currency", "BTC_USDT")
switching method, please refer to {@fun excahnge.IO}.BTC_USDT
can be switched to LTC_USDT
, not to LTC_BTC
.BTC_USDT
, the number of BTC
is 3, the number of USDT
is 10000. At this time, switch to LTC_USDT
immediately, the number of trading currencies is 0 after switching, i.e. the number of LTC_USDT
in the account is 0. That is, the number of LTC
in the account is 0, and the switched trading pair shares the number of USDT
, which is 10000.{@fun/Account/exchange.GetCurrency exchange.GetCurrency}
The exchange.GetQuoteCurrency()
function is used to get the name of the denominated currency of the current trading pair, i.e. quoteCurrency
.
The exchange.GetQuoteCurrency()
function returns the name of the denominated currency of the current trading pair.
string
exchange.GetQuoteCurrency()
function main() {
exchange.SetCurrency("BTC_USDT")
Log("BTC_USDT denominated currency name:", exchange.GetQuoteCurrency())
// exchange.SetCurrency("ETH_BTC")
// Log("ETH_BTC denominated currency name:", exchange.GetQuoteCurrency())
}
def main():
exchange.SetCurrency("BTC_USDT")
Log("BTC_USDT denominated currency name:", exchange.GetQuoteCurrency())
# exchange.SetCurrency("ETH_BTC")
# Log("ETH_BTC denominated currency name:", exchange.GetQuoteCurrency())
void main() {
exchange.SetCurrency("BTC_USDT");
Log("BTC_USDT denominated currency name:", exchange.GetQuoteCurrency());
// exchange.SetCurrency("ETH_BTC")
// Log("ETH_BTC denominated currency name:", exchange.GetQuoteCurrency())
}
For example: {@var/EXCHANGE exchange} exchange object’s current transaction pair is BTC_USDT
, the exchange.GetQuoteCurrency()
function returns USDT
. If the current trading pair is ETH_BTC
, the exchange.GetQuoteCurrency()
function returns BTC
.
{@fun/Account/exchange.GetCurrency exchange.GetCurrency}, {@fun/Account/exchange.SetCurrency exchange.SetCurrency}
The exchange.GetPositions()
function is used to get the position information; The GetPositions()
function is a member function of the exchange object {@var/EXCHANGE exchange}. The GetPositions()
function gets 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
and will not be repeated here.
The exchange.GetPositions()
function returns an array of {@struct/Position Position} structures if the request for data succeeds, and it returns null value if the request for data fails.
{@struct/Position Position} arrays, null values
exchange.GetPositions() exchange.GetPositions(symbol)
The parameter symbol
is used to set the trading symbol or trading symbol range to be queried.
If the symbol
parameter is not passed, the default is to request the position data of all symbols in the dimension range of the current trading pair and contract code.
symbol false string
/*backtest
start: 2024-05-21 00:00:00
end: 2024-09-05 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
function main() {
var arrSymbol = ["BTC_USDT.swap", "BTC_USDT.quarter", "ETH_USDT.swap", "ETH_USDT.quarter"]
for (var symbol of arrSymbol) {
exchange.CreateOrder(symbol, "buy", -1, 1)
exchange.CreateOrder(symbol, "sell", -1, 1)
}
var defaultPositions = exchange.GetPositions()
var swapPositions = exchange.GetPositions("USDT.swap")
var futuresPositions = exchange.GetPositions("USDT.futures")
var btcUsdtSwapPositions = exchange.GetPositions("BTC_USDT.swap")
var tbls = []
var arr = [defaultPositions, swapPositions, futuresPositions, btcUsdtSwapPositions]
var tblDesc = ["defaultPositions", "swapPositions", "futuresPositions", "btcUsdtSwapPositions"]
for (var index in arr) {
var positions = arr[index]
var tbl = {type: "table", title: tblDesc[index], cols: ["Symbol", "MarginLevel", "Amount", "FrozenAmount", "Price", "Profit", "Type", "ContractType", "Margin"], rows: [] }
for (var pos of positions) {
tbl.rows.push([pos.Symbol, pos.MarginLevel, pos.Amount, pos.FrozenAmount, pos.Price, pos.Profit, pos.Type, pos.ContractType, pos.Margin])
}
tbls.push(tbl)
}
LogStatus("`" + JSON.stringify(tbls) + "`")
// Print out the information once and then return to prevent the order from being executed during the subsequent backtest and affecting data observation
return
}
'''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
/*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;
}
Use futures exchange objects to place market orders for multiple different trading pairs and contract codes. Query positions in multiple ways.
Cryptocurrency futures contracts are different from cryptocurrency spot, which has only the logical concept of a position. In the system of FMZ Quant Trading platform, the specific types of cryptocurrency futures contracts are identified by trading pairs, contract code together. Please refer to {@fun/Account/exchange.SetCurrency exchange.SetCurrency}, {@fun/Futures/exchange.SetContractType exchange.SetContractType} functions.
In the GetPositions
function, the usage scenarios of the symbol parameter are summarized as follows:
Exchange Object Classification | symbol Parameters | Query Scope | Remark |
---|---|---|---|
Futures | Do not pass symbol parameter | Query all trading products within the current trading pair and contract code dimension range | If the current trading pair is BTC_USDT and the contract code is swap, all USDT-based perpetual contracts will be queried. This is equivalent to calling GetPositions("USDT.swap") |
Futures | Specify the trading product, the symbol parameter is: “BTC_USDT.swap” | Query the USDT-based perpetual contract of a specified BTC | For futures exchange objects, the format of parameter symbol is: a combination of trading pair and contract code defined by the FMZ platform, separated by the characters ". . |
Futures | Specify the range of trading products, the symbol parameter is: “USDT.swap” | Query all USDT-based perpetual contracts | - |
Futures exchanges that support options | Do not pass symbol parameter | Query all option contracts within the current trading pair dimension range | If the current trading pair is BTC_USDT, the contract is set to an option contract, for example, Binance option contract: BTC-240108-40000-C |
Futures exchanges that support options | Specify specific trading product | Query the specified option contract | For example, for Binance Futures Exchange, the symbol parameter is: BTC_USDT.BTC-240108-40000-C |
Futures exchanges that support options | Specify the range of trading products, the symbol parameter is: “USDT.option” | Query all USDT-based options contracts | - |
In the GetPositions
function, the futures exchange object
query dimension range is summarized as follows:
symbol Parameters | Request Scope Definition | Remark |
---|---|---|
USDT.swap | USDT-based perpetual contract range. | For |
dimensions that are not supported by the exchange API interface, an error will be reported and a null value will be returned when calling. |
| USDT.futures | USDT-based delivery contract range. | - |
| USD.swap | Scope of currency-based perpetual contracts. | - |
| USD.futures | Scope of currency-based delivery contracts. | - |
| USDT.option | USDT-based options contract range. | - |
| USD.option | Currency-based options contract range. |
| USDT.futures_combo | Range of CFD combinations. | Futures_Deribit Exchange |
| USD.futures_ff | Scope of mixed margin delivery contracts. | Futures_Kraken Exchange |
| USD.swap_pf | Mixed margin perpetual contract range. | Futures_Kraken Exchange |
Compatible with exchange.GetPosition()
call, GetPosition
is exactly the same as GetPositions
.
When the account represented by the exchange object exchange
has no positions in the query range or specified trading instruments, the exchange.GetPositions()
function returns an empty array, for example: []
.
{@struct/Position Position}, {@fun/Account/exchange.SetCurrency exchange.SetCurrency}, {@fun/Futures/exchange.SetContractType exchange.SetContractType}
The exchange.SetMarginLevel()
function is used to set the leverage value of the trading pair or contract specified by the symbol
parameter. Compatible with only passing in the parameter marginLevel
to set the leverage value of the current trading pair or contract of the {@var/EXCHANGE exchange} exchange object.
exchange.SetMarginLevel(symbol, marginLevel) exchange.SetMarginLevel(marginLevel)
The symbol
parameter is used to specify the trading pair or contract for which the leverage value needs to be adjusted. The format of the symbol
parameter of the SetMarginLevel()
function is consistent with the format of the symbol
parameter of the GetTicker()
function.
symbol
false
string
The marginLevel
parameter is used to set the leverage value, which is usually an integer for exchanges and it also supports floating point leverage value settings for some exchanges.
marginLevel
true
number
function main() {
exchange.SetMarginLevel(10)
// Set the leverage of BTC’s USDT-margined perpetual contract to 15
exchange.SetMarginLevel("BTC_USDT.swap", 15)
}
def main():
exchange.SetMarginLevel(10)
exchange.SetMarginLevel("BTC_USDT.swap", 15)
void main() {
exchange.SetMarginLevel(10);
exchange.SetMarginLevel("BTC_USDT.swap", 15);
}
The exchange.SetMarginLevel()
function supports cryptocurrency futures contract exchange objects only. The backtesting system supports calling the exchange.SetMarginLevel()
function to set the leverage value.
For cryptocurrency futures contracts, the leverage mechanism is not uniform due to the cryptocurrency futures contract exchanges. In some exchanges, the leverage value of the futures contract is a parameter in the order placement interface, when calling the exchange.SetMarginLevel()
function does not generate a network request, but only sets the leverage variable in the underlying FMZ system (used for passing parameters in the order placement interface). The leverage value of some exchange futures contracts is a setting of the exchange, which needs to be set on the exchange website page or using the API interface. In this case calling the exchange.SetMarginLevel()
function will generate a network request and may fail to set leverage. There can be many reasons for this, for example: there is a current position or pending order, which makes it impossible to set a new leverage value for this 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 |
{@var/EXCHANGE exchange}
The exchange.SetDirection()
function is used to set the order direction of the {@fun/Trade/exchange.Buy exchange.Buy} function, {@fun/Trade/exchange.Sell exchange.Sell} function when placing orders for futures contracts.
exchange.SetDirection(direction)
The direction
parameter is used to set the direction of the futures contract when the order is placed. The optional values are: "buy"
, "closesell"
, "sell"
, "closebuy"
.
direction
true
string
function main(){
// For example, set to OKX futures contract of this week
exchange.SetContractType("this_week")
// Set leverage to 5 times
exchange.SetMarginLevel(5)
// Set the order type to long
exchange.SetDirection("buy")
// Place an order for 2 contracts at 10,000
exchange.Buy(10000, 2)
exchange.SetMarginLevel(5)
exchange.SetDirection("closebuy")
exchange.Sell(1000, 2)
}
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)
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);
}
The exchange.SetDirection()
function sets the correspondence between the direction of the futures contract transaction and the order placement function:
Order placement functions | The direction set by the parameters of the SetDirection function | Remarks |
---|---|---|
exchange.Buy | “buy” | Buy and open long positions |
exchange.Buy | “closesell” | Buy and close short positions |
exchange.Sell | “sell” | Sell and open short positions |
exchange.Sell | “closebuy” | Sell and close long positions |
{@fun/Trade/exchange.Buy exchange.Buy}, {@fun/Trade/exchange.Sell exchange.Sell}
The exchange.SetContractType()
function is used to set the current contract code of the {@var/EXCHANGE exchange} exchange object.
The exchange.SetContractType()
function returns a structure that contains the exchange contract code corresponding to the current contract code. For example, for the Binance Futures contract exchange, the current contract code is quarter
, and the return value structure of this function is: {"InstrumentID": "BTCUSD_230630", "instrument": "BTCUSD_230630"}
.
object
exchange.SetContractType(symbol)
The symbol
parameter is used to set the contract code, the optional values are: "this_week"
, "next_week"
, "quarter"
, "next_quarter"
, "swap"
, etc.
Cryptocurrency futures contracts delivery contract codes, if not specified, generally have:
this_week
: the current week’s contract.next_week
: the next week’s contract.quarter
: quarterly contract.next_quarter
: the next quarterly contract.
Permanent contracts codes in cryptocurrency futures contracts, if not specified, generally have:swap
: perpetual contract.symbol true string
function main() {
// Set to this week contract
exchange.SetContractType("this_week")
}
def main():
exchange.SetContractType("this_week")
void main() {
exchange.SetContractType("this_week");
}
Set the current contract as the current week’s contract:
function main() {
// The default trading pair is BTC_USD, set the contract for this week, and the contract is a currency standard contract
exchange.SetContractType("this_week")
Log("ticker:", exchange.GetTicker())
// Switching trading pairs, then setting up contracts, switching to USDT as margin contracts, as opposed to currency standard contracts
exchange.IO("currency", "BTC_USDT")
exchange.SetContractType("swap")
Log("ticker:", exchange.GetTicker())
}
def main():
exchange.SetContractType("this_week")
Log("ticker:", exchange.GetTicker())
exchange.IO("currency", "BTC_USDT")
exchange.SetContractType("swap")
Log("ticker:", exchange.GetTicker())
void main() {
exchange.SetContractType("this_week");
Log("ticker:", exchange.GetTicker());
exchange.IO("currency", "BTC_USDT");
exchange.SetContractType("swap");
Log("ticker:", exchange.GetTicker());
}
When setting up a contract with USDT
as margin, you need to switch the trading pair in the code (you can also set the trading pair directly when adding the exchange object):
function main(){
// Set the contract for this week
var ret = exchange.SetContractType("this_week")
// Return information about the current week's contracts
Log(ret)
}
def main():
ret = exchange.SetContractType("this_week")
Log(ret)
void main() {
auto ret = exchange.SetContractType("this_week");
Log(ret);
}
Print the return value of the exchange.SetContractType()
function:
In the cryptocurrency futures contract strategy, take an example of switching to the BTC_USDT
trading pair: When switching trading pairs using the exchange.SetCurrency("BTC_USDT")
or exchange.IO("currency", "BTC_USDT")
functions, after switching, you need to use the exchange.SetContractType()
function to reset the contract in order to determine the current contract to be operated under the new trading pair. The system determines whether it is a currency standard contract or a USDT standard contract based on the trading pair. For example, if a trading pair is set to BTC_USDT
, use the exchange.SetContractType("swap")
function to set the contract code to swap
. At this point, it is set to BTC
for the USDT standard perpetual contract. If the trading pair is BTC_USD
, use the exchange.SetContractType("swap")
function to set the contract code to swap
. At this point, it is set to BTC
's currency standard perpetual contract.
Details of the supported cryptocurrency futures contract exchanges, with contract names for each exchange as follows:
Futures_OKCoin (OKX)
Set to perpetual contracts: exchange.SetContractType("swap")
Set to the contract of this week: exchange.SetContractType("this_week")
Set to next week’s contract: exchange.SetContractType("next_week")
Set to monthly contract: exchange.SetContractType("month")
Set to next month contract: exchange.SetContractType("next_month")
Set to quarterly contracts: exchange.SetContractType("quarter")
Set to next quarter contract: exchange.SetContractType("next_quarter")
OKX has pre-market trading contracts: the contract delivery date is a fixed time. The contract code defined by the exchange is, for example: HMSTR-USDT-250207
. Set the trading pair to HMSTR_USDT
on the FMZ platform, and then use exchange.SetContractType("HMSTR-USDT-250207")
to set the contract.
For functions that support the symbol
parameter, such as: exchange.GetTicker()
, exchange.CreateOrder()
, etc. You can specify the symbol
parameter as: HMSTR_USDT.HMSTR-USDT-250207
to obtain the market data of this contract or place an order.
Futures_HuobiDM (Huobi futures)
Set to the contract of this week: exchange.SetContractType("this_week")
.
Set to next week’s contract: exchange.SetContractType("next_week")
.
Set to quarterly contracts: exchange.SetContractType("quarter")
.
Set to next quarter contract: exchange.SetContractType("next_quarter")
.
Set to perpetual contracts: exchange.SetContractType("swap")
.
It supports contracts with USDT
as margin, take BTC
contract as an example: use exchange.IO("currency", "BTC_USDT")
to switch to a contract that uses USDT
as margin.
Or set the current trading pair to BTC_USDT
directly when configuring live trading parameters and adding exchange objects. After switching trading pairs, you need to call exchange.SetContractType()
function again to set the contract.
Futures_BitMEX (BitMEX)
Set to perpetual contracts: exchange.SetContractType("swap")
.
Futures_BitMEX exchange delivery contracts are monthly contracts with the following contract codes (from January to December):
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
Setting up delivery contracts: exchange.SetContractType("December")
. For example, when the trading pair is set to XBT_USDT
, the exchange.SetContractType("December")
function is called to set the contract for December delivery in the USDT based of BTC (corresponding to the actual contract code of XBTUSDTZ23
).
Futures_BitMEX Contract Information Summary
Contract code defined by Futures_BitMEX | The corresponding trading pair in FMZ | The corresponding contract code in FMZ | Remark |
---|---|---|---|
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, XBT settled. |
USDTUSDC | USDT_USDC | swap | USDC denominated, XBT settled. |
ETHUSD_ETH | ETH_USD_ETH | swap | USD denominated, ETH settled. |
XBTH24 | XBT_USD | March | Expiration date: March 24, month code is: H; USD denominated, XBT settled. |
ETHUSDZ23 | ETH_USD | December | Expiration date: Dec 23, month code is: Z; USD denominated, XBT settled. |
XBTUSDTZ23 | XBT_USDT | December | Expiration date: December 23, month code is: Z ; USDT denominated, USDT settled. |
ADAZ23 | ADA_XBT | December | Expiration date: December 23, month code is: Z ; XBT billing, XBT settled. |
P_XBTETFX23 | USDT_XXX | P_XBTETFX23 | Expiration: 11/23/23; denominated as a percentage and settled in USDT. |
Futures_GateIO
Set to the contract of this week: exchange.SetContractType("this_week")
.
Set to next week’s contract: exchange.SetContractType("next_week")
.
Set to quarterly contracts: exchange.SetContractType("quarter")
.
Set to next quarter contract: exchange.SetContractType("next_quarter")
.
Set to perpetual contracts: exchange.SetContractType("swap")
.
It supports contracts with USDT
as margin, take BTC
contract as an example: use exchange.IO("currency", "BTC_USDT")
to switch to a contract that uses USDT
as margin.
Or set the current trading pair to BTC_USDT
directly when configuring live trading parameters and adding exchange objects. After switching trading pairs, you need to call exchange.SetContractType()
function again to set the contract.
Futures_Deribit
Set to perpetual contracts: exchange.SetContractType("swap")
.
It supports Deribit’s USDC
contract.
The delivery contracts are: "this_week"
, "next_week"
, "month"
, "quarter"
, "next_quarter"
, "third_quarter"
, "fourth_quarter"
.
CFD (future_combo): "this_week,swap"
, "next_week,swap"
, "next_quarter,this_week"
, "third_quarter,this_week"
, "month,next_week"
, there are many combinations.
For option contracts you need to pass in the specific option contract code defined by the exchange, see the Deribit website for details.
Futures_KuCoin
For example, if the trading pair is set to BTC_USD
and the contract code is set, it is a currency-based contract:
Set to perpetual contracts: exchange.SetContractType("swap")
.
Set to quarterly contracts: exchange.SetContractType("quarter")
.
Set to next quarter contract: exchange.SetContractType("next_quarter")
.
USDT as margin contract:
For example, if the trading pair is set to BTC_USDT
, and then set the contract code, it is a contract with USDT as margin.
Set to perpetual contracts: exchange.SetContractType("swap")
.
Futures_Binance
Binance Futures Exchange defaults to the perpetual contract of the current trading pair, contract code: swap
.
Set to perpetual contracts: exchange.SetContractType("swap")
, the perpetual contracts of Binance have contracts that use USDT
as margin. For example, USDT
standard perpetual contract of BTC
can be used as a margin contract, and the trading pair is set to BTC_USDT
. Binance also supports perpetual contracts that use coins as margin, for example, BTC
's Binance standard perpetual contract, with the trading pair set to BTC_USD
.
Set to quarterly contracts: exchange.SetContractType("quarter")
, the delivery contract has a currency standard contract (i.e., using currencies as margin), for example, BTC
's quarterly contract, the trading pair is set to: BTC_USD
and then set the contract exchange.SetContractType("quarter")
, it is set to BTC
quarterly contract with a currency standard contract.
Set to next quarter contract: exchange.SetContractType("next_quarter")
, for example, BTC
of the currency standard quarterly contract, the trading pair set to: BTC_USD
, and then set the contract exchange.SetContractType("next_quarter")
.
Binance supports partial USDT
as margin delivery contract, take BTC
as an example, set trading pair to BTC_USDT
, then set the contract code.
Support for Binance Options contracts:
The format of the option contract code is based on the option contract code defined by the exchange: BTC-241227-15000-C
, XRP-240112-0.5-C
, BTC-241227-15000-P
. Take the Binance option contract code BTC-241227-15000-P
as an example: BTC is the option currency code, 241227 is the exercise date, 15000 is the exercise price, P represents a put option, and C represents a call option.
For details on the option type, whether it is European option or American option, please refer to the relevant information of the exchange’s option contract.
The exchange may restrict option sellers and require them to apply for qualifications separately. Binance options require seller qualifications.
Futures_Bibox
Contract code for Bibox perpetual contracts: swap
.
Set to perpetual contracts: exchange.SetContractType("swap")
.
Futures_Bybit
The default is the perpetual contract for the current trading pair, contract code: swap
.
This 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
.
Futures_Kraken
The default is the perpetual contract of the current trading pair, contract code: swap
.
swap
: perpetual contract.
month
: current month contract.
quarter
: quarterly contract.
next_quarter
: next quarter contract.
swap_pf
: Mixed margin perpetual contract.
quarter_ff
: Mixed margin quarterly contract.
month_ff
: Mixed margin current month contract.
next_quarter_ff
: Mixed margin next quarter contract.
Futures_Bitfinex
Default is the perpetual contract for the current trading pair, contract code: swap
.
Futures_Bitget
Default is the perpetual contract for the current trading pair, contract code: swap
.
The trading pair is set to BTC_USD
for currency standard contracts, and the trading pair is set to BTC_USDT
for contracts settled by USDT
. Demo contracts can be set up with trading pairs as SBTC_USD
, BTC_SUSDT
.
Futures_dYdX
Contract code for dYdX perpetual contracts: swap
.
Set to perpetual contracts: exchange.SetContractType("swap")
, dYdX has USDT standard contracts only.
Futures_MEXC
Contract code for MEXC perpetual contracts: swap
.
Set to perpetual contracts: exchange.SetContractType("swap")
. Set trading pair to BTC_USD
, which is currency standard contract, and set trading pair to BTC_USDT
, which is USDT
-settled contract.
Futures_Crypto
Tokens in an account on the crypto.com exchange can be converted into USD-denominated credits to be used as margin for contract trading.
Set to perpetual contract: exchange.SetContractType("swap")
. Example of calling the exchange.SetContractType("swap")
function to set a perpetual contract for BTC when the trading pair is set to BTC_USD
.
The crypto.com exchange delivery contracts are monthly contracts with the following contract codes (from January to December):
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
Set the delivery contract: exchange.SetContractType("October")
. For example, when the trading pair is set to BTC_USD
, call the function exchange.SetContractType("October")
to set the October delivery contract for BTC.
The corresponding contract code at the current moment is: BTCUSD-231027
.
Futures_WOO
Futures_WOO exchange supports USDT
based contracts with a perpetual contract code of swap
. For example, when the trading pair is set to BTC_USDT
, the function exchange.SetContractType("swap")
is called to set the current contract to be a USDT based perpetual contract for BTC.
{@fun/Futures/exchange.GetContractType exchange.GetContractType}, {@fun/Account/exchange.SetCurrency exchange.SetCurrency}
The exchange.GetContractType()
function is used to get the contract code for the current setting of the {@var/EXCHANGE exchange} exchange object.
The exchange.GetContractType()
function returns the contract code defined by the FMZ platform, for example: this_week
, swap
, etc.
string
exchange.GetContractType()
function main () {
Log(exchange.SetContractType("this_week"))
Log(exchange.GetContractType())
}
def main():
Log(exchange.SetContractType("this_week"))
Log(exchange.GetContractType())
void main() {
Log(exchange.SetContractType("this_week"));
Log(exchange.GetContractType());
}
{@fun/Futures/exchange.SetContractType exchange.SetContractType}
The exchange.GetFundings()
function is used to obtain the funding rate data for the current period.
The exchange.GetFundings()
function returns an array of {@struct/Funding Funding} structures when the data request is successful, and returns a null value when the data request fails.
{@struct/Funding Funding} array, null value
exchange.GetFundings() exchange.GetFundings(symbol)
The parameter symbol
is used to set the transaction symbol or transaction symbol range to be queried. When the symbol
parameter is not passed, the current funding rate data of all instruments will be requested by default in the dimension range of the current trading pair and contract code.
symbol false string
/*backtest
start: 2024-10-01 00:00:00
end: 2024-10-23 00:05:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"SOL_USDC"}]
*/
function main() {
// LPT_USDT.swap 4-hour period
var symbols = ["SOL_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "SOL_USDC.swap", "ETH_USDC.swap", "BTC_USD.swap", "BTC_USDT.quarter", "LPT_USDT.swap"]
for (var symbol of symbols) {
exchange.GetTicker(symbol)
}
var arr = []
var arrParams = ["no param", "LTC_USDT.swap", "USDT.swap", "USD.swap", "USDC.swap", "USDT.futures", "BTC_USDT.quarter"]
for (p of arrParams) {
if (p == "no param") {
arr.push(exchange.GetFundings())
} else {
arr.push(exchange.GetFundings(p))
}
}
var tbls = []
var index = 0
for (var fundings of arr) {
var tbl = {
"type": "table",
"title": arrParams[index],
"cols": ["Symbol", "Interval", "Time", "Rate"],
"rows": [],
}
for (var f of fundings) {
tbl["rows"].push([f.Symbol, f.Interval / 3600000, _D(f.Time), f.Rate * 100 + " %"])
}
tbls.push(tbl)
index++
}
LogStatus(_D(), "\n Requested market types:", symbols, "\n`" + JSON.stringify(tbls) + "`")
}
'''backtest
start: 2024-10-01 00:00:00
end: 2024-10-23 00:05:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"SOL_USDC"}]
'''
import json
def main():
# LPT_USDT.swap 4-hour period
symbols = ["SOL_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "SOL_USDC.swap", "ETH_USDC.swap", "BTC_USD.swap", "BTC_USDT.quarter", "LPT_USDT.swap"]
for symbol in symbols:
exchange.GetTicker(symbol)
arr = []
arrParams = ["no param", "LTC_USDT.swap", "USDT.swap", "USD.swap", "USDC.swap", "USDT.futures", "BTC_USDT.quarter"]
for p in arrParams:
if p == "no param":
arr.append(exchange.GetFundings())
else:
arr.append(exchange.GetFundings(p))
tbls = []
index = 0
for fundings in arr:
tbl = {
"type": "table",
"title": arrParams[index],
"cols": ["Symbol", "Interval", "Time", "Rate"],
"rows": [],
}
for f in fundings:
tbl["rows"].append([f["Symbol"], f["Interval"] / 3600000, _D(f["Time"]), str(f["Rate"] * 100) + " %"])
tbls.append(tbl)
index += 1
LogStatus(_D(), "\n Requested market types:", symbols, "\n`" + json.dumps(tbls) + "`")
/*backtest
start: 2024-10-01 00:00:00
end: 2024-10-23 00:05:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"SOL_USDC"}]
*/
void main() {
// LPT_USDT.swap 4-hour period
json arrSymbol = R"([])"_json;
std::string symbols[] = {"SOL_USDT.swap", "ETH_USDT.swap", "LTC_USDT.swap", "SOL_USDC.swap", "ETH_USDC.swap", "BTC_USD.swap", "BTC_USDT.quarter", "LPT_USDT.swap"};
for (const std::string& symbol : symbols) {
exchange.GetTicker(symbol);
arrSymbol.push_back(symbol);
}
std::vector<std::vector<Funding>> arr = {};
std::string arrParams[] = {"no param", "LTC_USDT.swap", "USDT.swap", "USD.swap", "USDC.swap", "USDT.futures", "BTC_USDT.quarter"};
for (const std::string& p : arrParams) {
if (p == "no param") {
arr.push_back(exchange.GetFundings());
} else {
arr.push_back(exchange.GetFundings(p));
}
}
json tbls = R"([])"_json;
int index = 0;
for (int i = 0; i < arr.size(); i++) {
auto fundings = arr[i];
json tbl = R"({
"type": "table",
"cols": ["Symbol", "Interval", "Time", "Rate"],
"rows": []
})"_json;
tbl["title"] = arrParams[index];
for (int j = 0; j < fundings.size(); j++) {
auto f = fundings[j];
// json arrJson = {f.Symbol, f.Interval / 3600000, _D(f.Time), string(f.Rate * 100) + " %"};
json arrJson = {f.Symbol, f.Interval / 3600000, _D(f.Time), f.Rate};
tbl["rows"].push_back(arrJson);
}
tbls.push_back(tbl);
index++;
}
LogStatus(_D(), "\n Requested market types:", arrSymbol.dump(), "\n`" + tbls.dump() + "`");
}
Use the futures exchange object to call the exchange.GetFundings()
function in the backtesting system. Before calling any market function, GetFundings only returns the Funding data of the current default trading pair. After calling the market function, it returns the Funding data of all requested varieties. You can refer to the following test example:
For futures exchanges that do not support batch query of funding rate data, if the symbol
parameter is specified as the query range, for example: USDT.swap
or the symbol
parameter is not passed, the interface will report an error. When calling the GetFundings()
function using this type of futures exchange object, you must specify the symbol
parameter as a specific perpetual contract type in order to query the current funding rate data of the type.
The exchange.GetFundings()
function supports real trading and backtesting systems.
Exchanges that do not support batch acquisition of funding rate data: Futures_Bitget, Futures_OKX, Futures_MEXC, Futures_Deribit, Futures_Crypto. Need to pass in the symbol
parameter with the specific symbol 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 |
{@struct/Funding Funding}
The exchange.SetBase()
function is used to set the base address of the exchange API interface configured in the {@var/EXCHANGE exchange} exchange object.
exchange.SetBase(s)
The s
parameter is used to specify the exchange API interface base address.
s
true
string
function main() {
// Use default base address
Log(exchange.GetTicker())
// Switch to https://aws.okx.com
exchange.SetBase("https://aws.okx.com")
Log(exchange.GetTicker())
}
def main():
Log(exchange.GetTicker())
exchange.SetBase("https://aws.okx.com")
Log(exchange.GetTicker())
void main() {
Log(exchange.GetTicker());
exchange.SetBase("https://aws.okx.com");
Log(exchange.GetTicker());
}
Switching the exchange API base address is not supported in the backtesting system, because the backtesting system is a sandbox simulation environment and it does not really access the exchange API interface.
{@fun/Trade/exchange.IO exchange.IO}
The exchange.GetBase()
function is used to get the current exchange API interface base address.
The current exchange API interface base address. string
exchange.GetBase()
function main() {
Log(exchange.GetBase())
}
def main():
Log(exchange.GetBase())
void main() {
Log(exchange.GetBase());
}
{@fun/NetSettings/exchange.SetBase exchange.SetBase}
The exchange.SetProxy()
function is used to set the proxy configuration of the {@var/EXCHANGE exchange} exchange object.
exchange.SetProxy(proxy)
The proxy
parameter is used to specify the proxy configuration.
proxy
true
string
function main() {
exchange.SetProxy("socks5://192.168.1.10:8080")
// If you can't access the exchange ticker interface, set up an available ss5 proxy and you can access the ticker interface
Log(exchange.GetTicker())
}
def main():
exchange.SetProxy("socks5://192.168.1.10:8080")
Log(exchange.GetTicker())
void main() {
exchange.SetProxy("socks5://192.168.1.10:8080");
Log(exchange.GetTicker());
}
Configure the {@var/EXCHANGE exchange} exchange object socks5
proxy:
function main(){
exchange.SetProxy("ip://10.0.3.15")
// The requested IP address is 10.0.3.15
exchange.GetTicker()
}
def main():
exchange.SetProxy("ip://10.0.3.15")
exchange.GetTicker()
void main() {
exchange.SetProxy("ip://10.0.3.15");
exchange.GetTicker();
}
In addition to global specification of the IP address of the request from the {@var/EXCHANGE exchange} exchange object, there is also support for specifying an IP address based on {@var/EXCHANGE exchange}:
If the proxy setting fails, the exchange.SetProxy()
function will return null when called. The exchange.SetProxy()
function sets the proxy for the rest
protocol only. One proxy can be set for each {@var/EXCHANGE exchange} exchange object, and access to the exchange interface bound to the {@var/EXCHANGE exchange} exchange object after setting the proxy will be accessed through the proxy.
Support for setting socks5
proxy, taking the first exchange object added {@var/EXCHANGE exchange} i.e.: exchanges[0]
as an example:
exchange.SetProxy("socks5://127.0.0.1:8889")
.exchange.SetProxy("socks5://username:password@127.0.0.1:8889")
. username
is the user name and password
is the password.exchange.SetProxy("")
.Supports setting the IP address of the request from the {@var/EXCHANGE exchange} exchange object, globally specified.
{@var/EXCHANGE exchange}
The exchange.SetTimeout()
function is used to set the timeout of the rest
request for the {@var/EXCHANGE exchange} exchange object.
exchange.SetTimeout(timeout)
The timeout
parameter is used to specify the number of milliseconds for the timeout setting.
timeout
true
number
function main() {
exchange.SetTimeout(3000)
Log(exchange.GetTicker())
}
def main():
exchange.SetTimeout(3000)
Log(exchange.GetTicker())
void main() {
exchange.SetTimeout(3000);
Log(exchange.GetTicker());
}
The parameter timeout
is a millisecond value, 1000 milliseconds equals 1 second. Restricted to the rest
protocol only, used to set the timeout on rest
requests, it takes effect by setting once only. For example, exchange.SetTimeout(3000)
, sets the rest
request timeout for the exchange
exchange object to 3 seconds. Calling functions with network requests such as exchange.GetTicker()
that do not receive an answer for more than 3 seconds will time out, and function calls that do time out will return null values.
SetTimeout()
is not a global function, it is a method of the {@var/EXCHANGE exchange} exchange object.
{@var/EXCHANGE exchange}
The FMZ Quant Trading Platform truly supports the multi-threaded function of the JavaScript
language strategy from the bottom of the system, and implements the following objects:
Objects | Directions | Remarks |
---|---|---|
threading | Multithreaded global object | Member functions: Thread , getThread , mainThread , etc. |
Thread | Thread object | Member functions: peekMessage , postMessage , join , etc. |
ThreadLock | Thread lock object | Member functions: acquire , release . They can be passed into the thread environment as parameters of the thread execution function. |
ThreadEvent | Event object | Member functions: set , clear , wait , isSet . They can be passed into the thread environment as a parameter of the thread execution function. |
ThreadCondition | Condition object | Member functions: notify , notifyAll , wait , acquire , release . They can be passed into the thread environment as a parameter of the thread execution function. |
ThreadDict | Dictionary object | Member functions: get , set . They can be passed into the thread environment as parameters of the thread execution function. |
The threading
object is a global multithreading management tool that provides functions such as creating concurrent threads, thread locks, and condition objects. This section introduces the member functions of the threading
object. This object is only supported by the JavaScript
language strategy.
The Thread()
function is used to create concurrent threads.
The Thread()
function returns a Thread
object, which is used to manage created concurrent threads, thread communication, etc.
Thread
object
Thread(func, …args) Thread(…items)
The parameter func
is a function for concurrent execution (passed by reference), and supports passing in anonymous functions. func
can accept multiple parameters, which will be passed in through ...args
during concurrent execution. Therefore, the parameter list of func
needs to be consistent with ...args
.
func
true
function
The parameter arg
is the actual parameter passed to func
(i.e. the concurrent thread execution function) when the callback is executed; there may be multiple parameters arg
, and the parameter list of func
needs to be consistent with ...args
.
arg
false
string, number, bool, object, array, function, null value and other types supported by the system
The parameter item
is an array containing the function references and their parameters to be executed concurrently. Multiple groups of item
parameters can be passed in when calling the Thread
function.
item true array
function 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()
}
Create concurrent threads for both a custom function and an anonymous function.
function 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()
}
Use the Thread(...items)
form to create concurrent threads and execute multiple functions sequentially.
function 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()
}
It supports passing parameters to concurrently executed functions.
function 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)
}
It supports passing in function strings and can import external libraries dynamically for concurrent computing.
The thread function func
passed into the Thread()
function for concurrent execution runs in an isolated environment, so variables outside the thread cannot be directly referenced, and compilation will fail when referenced. At the same time, references to other closure functions are not supported within the thread. All APIs provided by the platform can be called within the thread, but other user-defined functions cannot be called.
It supports backtesting system and live trading environment. All concurrent thread-related functions are only supported as code compatibility in the backtesting system and will not be actually executed by concurrent threads, so they will not be repeated in this chapter.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The getThread()
function is used to get the thread object based on the specified thread Id.
The getThread()
function returns the Thread
object with the threadId specified by the parameter
Thread
object
getThread(threadId)
The parameter threadId
is the thread object ID. Get the corresponding thread object by specifying the parameter.
threadId true number
function main() {
var t1 = threading.Thread(function () {
Log("Hello thread1")
})
// The Thread object has a method: id(), which is used to get the thread ID. You can view the section of the document corresponding to the Thread object.
var threadId = t1.id()
var threadName = t1.name()
Log("threadId:", threadId, ", threadName:", threadName)
var t2 = threading.getThread(threadId)
Log(`threadId == t2.id():`, threadId == t2.id(), `, threadName == t2.name():`, threadName == t2.name())
}
Get the specified thread object through threadId
.
It supports backtesting system and live trading environment.
If the thread you want to obtain has been executed and released, you cannot use threading.getThread(threadId)
to obtain the thread object of the thread.
{@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The mainThread()
function is used to obtain the thread object of the main thread, that is, the thread where the main()
function in the strategy is located.
The mainThread()
function returns the thread object of the main thread.
Thread
object
mainThread()
function main() {
Log("The threadId of the main thread:", threading.mainThread().id())
}
Get the Thread
object of the main thread and output the threadId
of the main thread.
function test() {
Log("Output the main thread ID in the test function:", threading.mainThread().id())
}
function main() {
var t1 = threading.Thread(test)
t1.join()
}
The thread object of the main thread can also be obtained in concurrent threads.
It supports backtesting system and live trading environment.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The currentThread()
function is used to get the thread object of the current thread.
The currentThread()
function returns the thread object of the current thread.
Thread
object
currentThread()
function test() {
Log("Id of the current thread:", threading.currentThread().id())
}
function main() {
var t1 = threading.Thread(test)
t1.join()
}
Get the Thread
object of the current thread and output the threadId
of the current thread.
It supports backtesting system and live trading environment.
{@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The Lock()
function is used to create a thread lock object.
The Lock()
function returns a thread lock object.
ThreadLock
object
Lock()
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()
}
Two concurrent threads access a common resource.
It supports backtesting system and live trading environment.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The Condition()
function is used to create a condition variable object, which is used to achieve synchronization and communication between threads in a multi-threaded concurrent environment. Through Condition()
, a thread can wait when certain conditions are not met until another thread notifies it that the condition has been met.
The Condition()
function returns a ThreadCondition
object.
ThreadCondition
object
Condition()
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()
}
Two concurrent threads access a common resource.
The backtesting system does not implement this functionality, it only defines it.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
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.
The Event()
function returns a ThreadEvent
object.
ThreadEvent
object
Event()
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()
}
Two concurrent threads access a common resource.
It supports backtesting system and live trading environment.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The Dict()
function is used to create a dictionary object for passing to concurrent threads.
The Dict()
function returns a ThreadDict
object.
ThreadDict
object
Dict()
function 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 normal object to the concurrent thread execution function to test whether modifying the key value of the object will cause changes in the key value of the object in other threads.
function 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()
}
Pass the ThreadDict
object created by the Dict()
function to the concurrent thread execution function, and test whether modifying the key value of the object will cause the key value of the object in other threads to change.
When a common object is passed to a concurrent thread function, it is passed as a deep copy. Modifying the key value in a concurrent thread will not affect the dictionary in other threads.
It supports backtesting system and live trading environment.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/pending pending}, {@fun/Threads/threading/eventLoop eventLoop}
The pending
function is used to obtain the number of concurrent threads running in the current strategy program.
The pending()
function returns the number of concurrent threads that the current strategy program is running.
number
pending()
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())
}
Create two concurrently running threads and call the pending()
function at different time nodes.
When the strategy main()
function starts running, calling the function pending()
directly will return 1, because the main thread where the strategy main()
function is located is also a pending thread.
It supports backtesting system and live trading environment.
{@fun/Threads/threading/getThread getThread}, {@fun/Threads/threading/mainThread mainThread}, {@fun/Threads/threading/currentThread currentThread}, {@fun/Threads/threading/Lock Lock}, {@fun/Threads/threading/Condition Condition}, {@fun/Threads/threading/Event Event}, {@fun/Threads/threading/Dict Dict}, {@fun/Threads/threading/Thread Thread}, {@fun/Threads/threading/eventLoop eventLoop}
Thread
objects can be created or returned by threading.Thread()
, threading.getThread()
, threading.mainThread()
, and threading.currentThread()
.
The peekMessage()
function is used to get a message from a thread.
The peekMessage()
function returns the message received by the thread associated with the current thread object.
string, number, bool, object, array, null value and other types supported by the system
peekMessage() peekMessage(timeout)
The parameter timeout
is the timeout setting. It will block and wait for the number of milliseconds set by the parameter and return data. If there is no data and the timeout exceeds the limit, a null value will be returned. If timeout
is set to 0 or the timeout
parameter is not passed, it means that the process will block and wait until data is received from the channel. If timeout
is set to -1, it means that the process will not block and return data immediately. If there is no data, a null value will be returned.
timeout false number
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()
}
Send messages to the main thread from a concurrent thread.
When writing programs, we need to pay attention to thread deadlock problems.
{@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}
The postMessage()
function is used to send a message to a thread.
postMessage(msg)
The parameter msg
is the message to be sent.
msg true Any type supported by the system, such as string, number, bool, object, array, function, null value, etc.
function 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()
}
Send messages in concurrent threads and use eventLoop()
to receive message notifications.
function 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()
}
It supports sending a function.
When a thread’s execution function calls the postMessage()
function to send a signal or data, a message event is also generated. We can use the eventLoop()
function to receive message notifications.
{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}
The join()
function is used to wait for the thread to exit and reclaim system resources.
The ThreadRet
object contains data about the execution result. The properties include the following:
ThreadRet
object
join() join(timeout)
The timeout
parameter is used to set the timeout in milliseconds for waiting for the thread to finish. When the timeout
parameter is set to 0 or the timeout
parameter is not set, the join()
function will block and wait until the thread finishes executing. When the timeout
parameter is set to -1, the join()
function will return immediately.
timeout false number
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}
}
Test the join()
function for timeout and output the return value.
The join()
function times out and returns undefined
.
{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}
The terminate()
function is used to forcibly terminate a thread and release the hardware resources used by the created thread.
terminate()
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)
}
}
Terminate the execution of a thread forcefully. After forcibly terminating a thread, there will be no output from this thread in the log.
For threads that are forcibly terminated by the terminate()
function, we can no longer use the join()
function to wait for them to terminate.
{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}
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 exit success) and has not executed the terminate()
function (terminating the thread forcibly).
The getData()
function returns the key value corresponding to the key
parameter in the key-value pair stored in the current thread context.
string, number, bool, object, array, null value and other types supported by the system
getData() getData(key)
The key
parameter is the key name of the stored key-value pair.
key true string
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()
}
Record the value of the key count
in the concurrent thread environment, and then read the key value of count
in the main thread.
{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}
The setData()
function is used to store variables in the thread context.
setData(key, value)
The key
parameter is used to specify the key name of the stored key-value pair.
key
true
string
The value
parameter is used to specify the key value of the stored key-value pair.
value true Any type supported by the system, such as string, number, bool, object, array, function, null value, etc.
function main() {
var t1 = threading.Thread(function() {
threading.currentThread().setData("data", 100)
})
Sleep(1000)
Log(`t1.getData("data"):`, t1.getData("data"))
t1.join()
}
Set the key-value pair in the concurrent thread and read the key-value pair in the main thread.
function 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()
}
It supports key-value passing into functions.
The data is valid when the thread has not executed the join()
function (waiting for exit success) and has not executed the terminate()
function (terminating the thread forcibly). The value of the parameter value
must be a serializable variable.
{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}
The id()
function is used to return the threadId
of the current multithreaded object instance.
The return value of the id()
function is threadId
.
number
id()
function main() {
var t1 = threading.Thread(function() {
threading.currentThread().setData("data", 100)
})
Log(`t1.id():`, t1.id())
t1.join()
}
Create a concurrently running thread and output the threadId
of this concurrent thread in the main thread.
{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/name name}, {@fun/Threads/Thread/eventLoop eventLoop}
The name()
function is used to return the name of the current multithreaded object instance.
The name()
function returns the concurrent thread name.
string
name()
function main() {
var t1 = threading.Thread(function() {
threading.currentThread().setData("data", 100)
})
Log(`t1.name():`, t1.name()) // t1.name(): Thread-1
t1.join()
}
Create a concurrent thread and output the name of the concurrent thread in the main thread.
{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/eventLoop eventLoop}
The eventLoop()
function is used to listen for events received by the thread.
The eventLoop()
function returns the event information received by the current thread. See Event Information Structure.
object, null value
eventLoop() eventLoop(timeout)
The parameter timeout
is the timeout setting in milliseconds. If the parameter timeout
is set to 0, it will wait for an event to occur before returning. If it is greater than 0, it will set the event waiting timeout. If it is less than 0, it will return the latest event immediately.
timeout false number
function main() {
var t1 = threading.Thread(function() {
while (true) {
var eventMsg = threading.currentThread().eventLoop() // Blocking 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()
}
Execute three threads concurrently and output the received event information. If the timeout occurs or the function returns immediately, the output value is null.
The processing mechanism of the eventLoop()
function is the same as the global function EventLoop()
.
{@fun/Threads/Thread/peekMessage peekMessage}, {@fun/Threads/Thread/postMessage postMessage}, {@fun/Threads/Thread/join join}, {@fun/Threads/Thread/terminate terminate}, {@fun/Threads/Thread/getData getData}, {@fun/Threads/Thread/setData setData}, {@fun/Threads/Thread/id id}, {@fun/Threads/Thread/name name}
Thread lock object, used for multi-thread synchronization processing.
The acquire()
function is used to request a thread lock (lock).
acquire()
Please refer to the threading.Lock()
section for examples.
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 successfully acquires the lock and continues execution. If the lock is already held by another thread, the thread calling acquire()
will be blocked until the lock is released.
{@fun/Threads/threading/Lock Lock}, {@fun/Threads/ThreadLock/release release}
The release()
function is used to release a thread lock (unlock).
release()
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() placed after pLock.acquire() will not cause deadlock
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()
}
Testing deadlock scenarios
It should be noted that improper use of thread locks may lead to deadlock.
{@fun/Threads/threading/Lock Lock}, {@fun/Threads/ThreadLock/acquire acquire}
Event object, used for multi-threaded event notification and signal.
The set()
function is used to notify events (set signals).
set()
Please refer to the threading.Event()
section for examples.
If the signal has been set using set()
, it cannot be set again. We need to clear the signal and set it again.
{@fun/Threads/ThreadEvent/clear clear}, {@fun/Threads/ThreadEvent/wait wait}, {@fun/Threads/ThreadEvent/isSet isSet}
The clear()
function is used to clear the signal.
clear()
Please refer to the threading.Event()
section for examples.
{@fun/Threads/ThreadEvent/set set}, {@fun/Threads/ThreadEvent/wait wait}, {@fun/Threads/ThreadEvent/isSet isSet}
The wait()
function is used to set an event (signal) wait, and will block before the event (signal) is set; it supports setting a timeout parameter.
The wait()
function returns whether the timeout has occurred. If so, it returns a true value.
bool
wait() wait(timeout)
The timeout
parameter is used to set the waiting timeout in milliseconds.
timeout false number
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()
}
Test the return value of the wait()
function.
{@fun/Threads/ThreadEvent/set set}, {@fun/Threads/ThreadEvent/clear clear}, {@fun/Threads/ThreadEvent/isSet isSet}
The isSet()
function is used to determine whether an event (signal) has been set.
The isSet()
function returns whether the event (signal) has been set; if the event (signal) has been set, it returns a true value.
bool
isSet()
Please refer to the threading.Event()
section for examples.
{@fun/Threads/ThreadEvent/set set}, {@fun/Threads/ThreadEvent/clear clear}, {@fun/Threads/ThreadEvent/wait wait}
Condition object, used for multi-thread synchronization.
The notify()
function is used to wake up a waiting thread (if any). Only threads that have called the wait()
method will be woken up.
notify()
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)
}
}
Use the notify()
function to wake up the waiting thread.
The notify()
function wakes up a thread in the waiting queue.
When the notify()
function wakes up a thread, the thread will reacquire the thread lock.
{@fun/Threads/ThreadCondition/notifyAll notifyAll}, {@fun/Threads/ThreadCondition/wait wait}, {@fun/Threads/ThreadCondition/acquire acquire}, {@fun/Threads/ThreadCondition/release release}
The notifyAll()
function wakes up all waiting threads.
notifyAll()
Please refer to the ThreadCondition.notify()
section for examples.
The notifyAll()
function wakes up all waiting threads one by one, and the awakened threads reacquire the thread lock.
{@fun/Threads/ThreadCondition/notify notify}, {@fun/Threads/ThreadCondition/wait wait}, {@fun/Threads/ThreadCondition/acquire acquire}, {@fun/Threads/ThreadCondition/release release}
The wait()
function is used to make a thread wait under certain designed conditions.
wait()
Please refer to the ThreadCondition.notify()
section for examples.
The wait()
function releases the thread lock and reacquires the thread lock when woken up.
{@fun/Threads/ThreadCondition/notify notify}, {@fun/Threads/ThreadCondition/notifyAll notifyAll}, {@fun/Threads/ThreadCondition/acquire acquire}, {@fun/Threads/ThreadCondition/release release}
The acquire()
function is used to request a thread lock (lock).
acquire()
Please refer to the ThreadCondition.notify()
section for examples.
Before using wait()
, you need to request the thread lock (lock) of the current condition object.
{@fun/Threads/ThreadCondition/notify notify}, {@fun/Threads/ThreadCondition/notifyAll notifyAll}, {@fun/Threads/ThreadCondition/wait wait}, {@fun/Threads/ThreadCondition/release release}
The release()
function is used to release a thread lock (unlock).
release()
Please refer to the ThreadCondition.notify()
section for examples.
After using wait()
, we need to release the thread lock (unlock) of the current condition object.
{@fun/Threads/ThreadCondition/notify notify}, {@fun/Threads/ThreadCondition/notifyAll notifyAll}, {@fun/Threads/ThreadCondition/wait wait}, {@fun/Threads/ThreadCondition/acquire acquire}
Dictionary object, used for data sharing.
The get()
function is used to get the key value recorded in the dictionary object.
The get()
function returns the value of the key specified by the key
parameter.
string, number, bool, object, array, null value and other types supported by the system
get(key)
The key
parameter is used to specify the key name corresponding to the key to be obtained.
key true string
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"))
}
Use event objects to notify threads to read and modify data.
{@fun/Threads/ThreadDict/set set}
The set()
function is used to set a key-value pair.
set(key, value)
The parameter key
is used to set the key name to be modified.
key
true
string
The parameter value
is used to set the key value to be modified.
value true string, number, bool, object, array, function, null value and other types supported by the system
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()
}
It supports key-value passing into functions.
{@fun/Threads/ThreadDict/get get}
In the FMZ Quant Trading Platform, it mainly implements various functions, calls related to blockchain through exchange.IO()
function. The following document describes the exchange.IO()
function separately according to its function. The call method of the exchange.IO("abi", ...)
function is used to register an ABI.
exchange.IO(k, address, abiContent)
The k
parameter is used to set the function of the exchange.IO()
function, set to "abi"
means that the function is used to register ABI
.
k
true
string
The address
parameter is used to specify the address of the smart contract.
address
true
string
The abiContent
parameter is used to specify the ABI
of the smart contract.
abiContent
true
string
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"}]`
// Get the ```ABI``` content of the contract can be obtained with the following URL, taking the ```result``` field only, e.g:
exchange.IO("abi", routerAddress, abi)
}
The methods of calling smart contract do not need to be registered if they are standard ERC20 methods.
Get the ABI
content of the contract can be obtained with the following URL, taking the result
field only, e.g:
https://api.etherscan.io/api?module=contract&action=getabi&address=0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45
The calling method of exchange.IO("api", "eth", ...)
function is used to call the Ethereum RPC method.
The exchange.IO("api", "eth", ...)
function returns the return value of the called RPC method.
string, number, bool, object, array, null and all other types supported by the system
exchange.IO(k, blockChain, rpcMethod) exchange.IO(k, blockChain, rpcMethod, …args)
The k
parameter is used to set the function of the exchange.IO()
function, set to "api"
indicates that the function is used to extend the call request.
k
true
string
The blockChain
parameter is used to set the function of the exchange.IO()
function, set to "eth"
indicates that the function is used for RPC method calls on the Ethereum Network.
blockChain
true
string
The rpcMethod
parameter is used to set the RPC method to be called by the exchange.IO()
function.
rpcMethod
true
string
The arg
parameter is used to specify the parameters of the RPC method to be called. There may be more than one arg
parameter. The type and number of arg
parameters depend on the RPC method specified by the rpcMethod
parameter.
arg
false
string, number, bool, object, array, function, null, and all other types supported by the system
function main() {
// "owner" needs to be replaced with the specific wallet address
// Parameter labels for the "latest" string position: 'latest', 'earliest' or 'pending', please refrer to https://eth.wiki/json-rpc/API#the-default-block-parameter
// The return value ethBalance is a hexadecimal string: 0x9b19ce56113070
var ethBalance = exchange.IO("api", "eth", "eth_getBalance", "owner", "latest")
// ETH has a precision unit of 1e18
var ethDecimal = 18
// Because of the JavaScript language precision, it is necessary to use the system underlying package function BigInt, BigDecimal to process
// Convert ethBalance to readable amount, 0x9b19ce56113070 to 0.043656995388076145
Log(Number((BigDecimal(BigInt(ethBalance))/BigDecimal(Math.pow(10, ethDecimal))).toString()))
}
Check the balance of ETH in your wallet:
function mian() {
// ETH has a precision unit of 1e18
var ethDecimal = 18
// Number of transfers, readable amount e.g. 0.01 ETH
var sendAmount = 0.01
// Due to the JavaScript language precision, it is necessary to use the system underlying encapsulated functions BigInt, BigDecimal to process, and to convert the readable amount to the data processed on the chain
var toAmount = (BigDecimal(sendAmount)*BigDecimal(Math.pow(10, ethDecimal))).toFixed(0)
// "toAddress" is the address of the recipient's ETH wallet at the time of the transfer, which needs to be filled in specifically, and toAmount is the number of transfers
exchange.IO("api", "eth", "send", "toAddress", toAmount)
}
For ETH transfers, you can set the {gasPrice: 11, gasLimit: 111, nonce: 111}
parameter, which is set on the last parameter of the exchange.IO()
function, according to your specific needs. You can omit the nonce
and use the system default, or leave gasLimit/gasPrice/nonce
unset and use the system default value for all.
function 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 gasPrice
:
function toAmount(s, decimals) {
// The toAmount function can convert hex-encoded values to decimal values
return Number((BigDecimal(BigInt(s))/BigDecimal(Math.pow(10, decimals))).toString())
}
function main() {
// Coding approve (authorization) method calls
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)
}
Query eth_estimateGas
:
The second parameter of the exchange.IO()
function with "eth"
can directly call the RPC methods available to the Ethereum node server.
{@fun BigDecimal}, {@fun BigInt}
The exchange.IO("encode", ...)
function is called for data encoding.
The exchange.IO("encode", ...)
function returns the encoded data.
string
exchange.IO(k, dataFormat, …args) exchange.IO(k, address, dataFormat) exchange.IO(k, address, dataFormat, …args)
The k
parameter is used to set the function of the exchange.IO()
function, set to "encode"
means the function is used for data encoding.
k
true
string
The address
parameter is used to set the address of the smart contract. When calling the exchange.IO("encode", ...)
function, passing in the address
parameter indicates encoding the method call on the smart contract. When calling the exchange.IO("encode", ...)
function, if the address
parameter is not passed, the function is used to encode the specified type order and is functionally equivalent to abi.encode
in Solidity
.
address
false
string
The dataFormat
parameter is used to specify the method, type, and order of the encoded data.
dataFormat
true
string
The arg
parameter is used to specify the specific data value that matches the dataFormat
parameter. There may be more than one arg
parameter, and the type and number of arg
parameters depends on the dataFormat
parameter setting.
arg
false
string, number, tuple, array, and all other types supported by the system
function main() {
// Main network address of ContractV3SwapRouterV2: 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45
// Calling the unwrapWETH9 method requires registering the ABI first, which is omitted here
// "owner" represents the wallet address, which need to fill in the specific, 1 represents the number of unpacking, unpacking a WETH into ETH
var data = exchange.IO("encode", "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", "unwrapWETH9(uint256,address)", 1, "owner")
Log(data)
}
For example, calling the encoding method unwrapWETH9
:
function 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 i.e. uint256 , the type length needs to be specified on FMZ
Log("ret:", ret)
/*
000000000000000000000000000000000000000000000000000000000000000a // x
00000000000000000000000002a5fbb259d20a3ad2fdf9ccadef86f6c1c1ccc9 // address
0000000000000000000000000000000000000000000000000000000000000080 // Offset of str
00000000000000000000000000000000000000000000000000000000000000c0 // Offset of array
000000000000000000000000000000000000000000000000000000000000000b // The length of str
48656c6c6f20576f726c64000000000000000000000000000000000000000000 // str data
0000000000000000000000000000000000000000000000000000000000000003 // The length of the array
0000000000000000000000000000000000000000000000000000000000000001 // array the first data
0000000000000000000000000000000000000000000000000000000000000002 // array the second data
0000000000000000000000000000000000000000000000000000000000000003 // array the third data
*/
}
It’s equivalent to the encoding example of abi.encode
in Solidity
:
function 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)
}
It supports encoding a tuple or a type order containing a tuple.
This type order consists of tuple
, bytes
, so when calling exchange.IO()
for encoding, you need to continue passing two parameters:
{
a: 30,
b: 20,
c: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
}
The parameters passed in must also be consistent with the structure and type of tuple
, as defined in the types
parameter of the form: tuple(a uint256,b uint8,c address)
.
bytes
:"0011"
function main() {
var path = ["0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "0xdac17f958d2ee523a2206206994597c13d831ec7"] // ETH address, USDT address
var ret = exchange.IO("encode", "address[]", path)
Log("encode: ", ret)
}
It supports for sequential encoding of arrays or types containing arrays:
The exchange.IO()
function encapsulates the encode
method, which can return the function call code to hex
string format. For specific use, you can refer to the platform’s publicly available “Uniswap V3 Trade” Template.
When coding method calls on smart contracts, the corresponding ABI needs to be registered first.
The exchange.IO("encodePacked", ...)
function is called in a way that is used for encodePacked
encoding.
The exchange.IO("encodePacked", ...)
function returns the encodePacked
encoded data.
string
exchange.IO(k, dataFormat, …args)
The k
parameter is used to set the function of the exchange.IO()
function, set to "encodePacked"
means that the function is used for data encodePacked
encoding.
k
true
string
The dataFormat
parameter is used to specify the type and order of the encodePacked
encoded data.
dataFormat
true
string
The arg
parameter is used to specify the specific data value that matches the dataFormat
parameter. There may be more than one arg
parameter, and the type and number of arg
parameters depends on the dataFormat
parameter setting.
arg
true
string, number, tuple, array, and all other types supported by the system
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)
}
When using Uniswap V3
, you need to pass in parameters like the exchange path, you need to use the encodePacked
encoding operation:
The exchange.IO("decode", ...)
function is called in a way that is used for decoding.
The exchange.IO("decode", ...)
function returns the decoded data. Returns a string when there is only one data specified by the dataFormat
parameter. Returns an array when there is more than one data specified by the dataFormat
parameter.
array、string
exchange.IO(k, dataFormat, data)
The k
parameter is used to set the function of the exchange.IO()
function, and setting it to "decode"
means that the function is used for data decoding.
k
true
string
The dataFormat
parameter is used to specify the type and order of the decoded data.
dataFormat
true
string
The data
parameter is used to set the data to be decoded.
data
true
string
function 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)
}
Inverse operation of the exchange.IO("encode", ...)
function:
function 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 only uses the contents of the local exactOutput method, the full abi can be searched on the Internet
// 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)
}
The following example first performs an encodePacked
operation on the path
parameter processing, because the exactOutput
method call that needs to be encoded later requires path
as a parameter. Then encode
the exactOutput
method of the routing contract, which has only one parameter of type tuple
. The method name exactOutput
is encoded as: 0x09b81346
, and using the exchange.IO("decode", ...)
method to decode the resulting decodeRaw
, consistent with the variable dataTuple
.
For data processing, the exchange.IO()
function supports not only encoding, but also decoding.
The exchange.IO("key", ...)
function is called in a way to switch private keys.
exchange.IO(k, key)
The parameter k
is used to set the function of the exchange.IO()
function, set to "key"
means the function is used to switch the private key.
k
true
string
The key
parameter is used to set the private key.
key
true
string
function main() {
exchange.IO("key", "Private Key") // "Private Key" represents the private key string, which needs to be filled in specifically
}
The exchange.IO()
function supports switching private keys and it can manipulate multiple wallet addresses. It is also possible to add multiple exchange objects (see: {@var/EXCHANGE/exchanges exchanges}) for manipulating multiple wallet addresses.
The exchange.IO("api", ...)
function is called in a way that is used to call the methods of the smart contract.
The exchange.IO("api", ...)
function returns the return value of the called smart contract method.
string, number, bool, object, array, null and all other types supported by the system
exchange.IO(k, address, method) exchange.IO(k, address, method, …args) exchange.IO(k, address, method, value, …args)
The k
parameter is used to set the function of the exchange.IO()
function, set to "api"
indicates that the function is used to extend the call request.
k
true
string
The address
parameter is used to specify the address of the smart contract.
address
true
string
The method
parameter is used to specify the method of the smart contract to be called.
method
true
string
The value
parameter is used to set the amount of ETH to be sent. The stateMutability
attribute of the smart contract method to be executed is payable
, then the value
parameter needs to be passed. The "stateMutability": "payable"
attribute can be viewed from the ABI. The exchange.IO()
function will determine the required parameter based on the stateMutability
attribute in the ABI that has been registered. If the stateMutability
attribute is nonpayable
, then the value
parameter does not need to be passed.
value
false
number、string
The arg
parameter is used to specify the parameters of the method of the smart contract to be called. There may be more than one arg
parameter, and the type and number of arg
parameters depends on the method of the smart contract to be called.
arg
false
string, number, bool, and all other types supported by the system
function main(){
var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302" // The contract address of the token, the token is 1INCH in the example
Log(exchange.IO("api", tokenAddress, "decimals")) // Query, print 1INCH tokens with precision index of 18
}
The decimals
method is a constant
method of ERC20 that does not incur gas consumption and it can query the precision data of a token. The decimals
method has no parameters. Return value: the precision data of the token.
function main(){
// The contract address of the token, in the example the token is 1INCH
var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302"
// For example, the query yields 1000000000000000000, divided by the precision unit of the token 1e18, the wallet to which the current exchange object is bound has authorized 1 1INCH to the spender address
Log(exchange.IO("api", tokenAddress, "allowance", "owner", "spender"))
}
The allowance
method is a constant
method of ERC20 that does not generate gas consumption and can query the authorized amount of a token for a certain contract address. The allowance
method takes 2 parameters, the first one is the wallet address and the second one is the authorized address. Return value: the authorization amount of the token.
owner
: the address of the wallet, the example is replaced by the string “owner”, the actual use needs to fill in the specific address. spender
: the address of the authorized contract, the example is replaced by the string “spender”, the actual use needs to fill in the specific address, for example, it can be Uniswap V3 router v1
address.
function main(){
// The contract address of the token, the token is 1INCH in the example
var tokenAddress = "0x111111111117dC0aa78b770fA6A738034120C302"
// The hexadecimal string of the authorization amount: 0xde0b6b3a7640000 , the corresponding decimal string: 1e18 , 1e18 divided by the precision unit of the token, i.e. 1 token amount, so this refers to the authorization of one token
Log(exchange.IO("api", tokenAddress, "approve", "spender", "0xde0b6b3a7640000"))
}```
The ```approve``` method is a non-```constant``` method of ERC20, which generates gas consumption and is used to authorize the operation amount of a token to a contract address. The ```approve``` method takes 2 parameters, the first one is the address to be authorized and the second one is the amount to be authorized. Return value: txid.
```spender```: the address of the authorized contract, the example is replaced by the string "spender", the actual use needs to fill in the specific address, for example, it can be ```Uniswap V3 router v1``` address. ```0xde0b6b3a7640000```: the number of authorizations, here is the hexadecimal string, the corresponding decimal value is 1e18, divided by the token precision unit in the example (i.e. 1e18). The result is that 1 token is authorized. The third parameter of the ```exchange.IO()``` function is passed to the method name ```approve```, which can also be written in the form of methodId, such as "0x571ac8b0". It is also possible to write the full standard method name, for example: "approve(address,uint256)".
```javascript
function main() {
var ContractV3SwapRouterV2 = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"
var tokenInName = "ETH"
var amountIn = 0.01
var options = {gasPrice: 5000000000, gasLimit: 21000, nonce: 100} // This is an example, depending on the actual scene settings
var data = "" // The encoded data, here is the empty string, depending on the actual scene settings
var tx = exchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", (tokenInName == 'ETH' ? amountIn : 0), (new Date().getTime() / 1000) + 3600, data, options || {})
}
The multicall
method is a non-constant
method of Uniswap V3
that generates gas consumption and is used to redeem tokens in multiple ways.
The multicall
method may have various ways of passing parameters, you can check the ABI that contains the method specifically, you need to register the ABI before calling the method. Return value: txid.
For specific examples of multicall
method calls, you can refer to the platform’s publicly available “Uniswap V3 Trade” Template
Some details are described here using pseudo-code:
exchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", value, deadline, data)
ContractV3SwapRouterV2
: address of router v2 of Uniswap V3.
value
: the amount of ETH to transfer, set to 0 if the tokenIn token of the exchange operation is not ETH.
deadline
: deadline
is the parameter of the multicall
method, which can be set to (new Date().getTime() / 1000) + 3600, indicating that it is valid for one hour.
data
: data
is the parameter of the multicall
method, the data of the packing operation to be performed.
Similar to exchange.IO("api", "eth", "send", "toAddress", toAmount)
, the gasLimit/gasPrice/nonce
setting of the method call can be specified when calling the multicall
method.
Again, we use pseudo-code to describe:
exchange.IO("api", ContractV3SwapRouterV2, "multicall(uint256,bytes[])", value, deadline, data, {gasPrice: 123456, gasLimit: 21000})
The parameter {gasPrice: 11, gasLimit: 111, nonce: 111}
can be set according to specific needs, which is set to the last parameter of the exchange.IO()
function.
You can omit the nonce
and use the system default value, or leave gasLimit/gasPrice/nonce
unset and use the system default value for all.
The exchange.IO("address")
function is called in such a way as to get the address of the wallet configured by the {@var/EXCHANGE exchange} exchange object.
The exchange.IO("address")
function returns the configured wallet address.
string
exchange.IO(k)
The k
parameter is used to set the function of the exchange.IO()
function, set to "address"
means that the function is used to get the configured wallet address.
k
true
string
function main() {
Log(exchange.IO("address")) // Print the wallet address of the private key configured on the exchange object
}
The exchange.IO("base", ...)
function is called in a way to set the RPC node address.
exchange.IO(k, address)
The k
parameter is used to set the function of the exchange.IO()
function, set to "base"
means the function is used to switch RPC nodes.
k
true
string
The address
parameter is used to set the RPC node address.
address
true
string
function main() {
var chainRpc = "https://bsc-dataseed.binance.org"
e.IO("base", chainRpc) // Switching to BSC chain
}
The TA.MACD()
function is used to calculate the exponential smoothed dissimilarity and similarity MACD indicator.
The return value of the TA.MACD()
function is a two-dimensional array with the structure: [DIF, DEA, MACD]
.
array
TA.MACD(inReal) TA.MACD(inReal, optInFastPeriod, optInSlowPeriod, optInSignalPeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInFastPeriod
parameter is used to set the fast period.
optInFastPeriod
false
number
The optInSlowPeriod
parameter is used to set the slow period.
optInSlowPeriod
false
number
The optInSignalPeriod
parameter is used to set the signal period.
optInSignalPeriod
false
number
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)
// Watching the logs, you can see that three arrays are returned, corresponding to DIF, DEA and MACD.
Log("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2])
}
def main():
r = exchange.GetRecords(PERIOD_M15)
macd = TA.MACD(r, 12, 26, 9)
Log("DIF:", macd[0], "DEA:", macd[1], "MACD:", macd[2])
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]);
}
The TA
indicator library of FMZ Quant, optimized for common indicator algorithms. It supports JavaScript
, Python
, C++
language strategy calls, 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
.
{@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}
The TA.KDJ()
function is used to calculate stochastic indicators.
The return value of the TA.KDJ()
function is a two-dimensional array with the structure: [K, D, J]
.
array
TA.KDJ(inReal) TA.KDJ(inReal, period, kPeriod, dPeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The period
parameter is used to set period 1.
period
false
number
The kPeriod
parameter is used to set period 2.
kPeriod
false
number
The dPeriod
parameter is used to set period 3.
dPeriod
false
number
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])
}
def main():
r = exchange.GetRecords(PERIOD_M15)
kdj = TA.KDJ(r, 9, 3, 3)
Log("k:", kdj[0], "d:", kdj[1], "j:", kdj[2])
void main() {
auto r = exchange.GetRecords();
auto kdj = TA.KDJ(r, 9, 3, 3);
Log("k:", kdj[0], "d:", kdj[1], "j:", kdj[2]);
}
The default values for the period
, kPeriod
, and dPeriod
parameters of the TA.KDJ()
function are: 9
, 3
, and 3
.
{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}
The TA.RSI()
function is used to calculate the Strength Indicator.
The return value of the TA.RSI()
function is: a one-dimensional array.
array
TA.RSI(inReal) TA.RSI(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period.
optInTimePeriod
false
number
function main(){
var records = exchange.GetRecords(PERIOD_M30)
var rsi = TA.RSI(records, 14)
Log(rsi)
}
def main():
r = exchange.GetRecords(PERIOD_M30)
rsi = TA.RSI(r, 14)
Log(rsi)
void main() {
auto r = exchange.GetRecords(PERIOD_M30);
auto rsi = TA.RSI(r, 14);
Log(rsi);
}
The default value of the optInTimePeriod
parameter of the TA.RSI()
function is: 14
.
{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}
The TA.ATR()
function is used to calculate the Average True Volatility Indicator.
The return value of the TA.ATR()
function is: a one-dimensional array.
array
TA.ATR(inPriceHLC) TA.ATR(inPriceHLC, optInTimePeriod)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period.
optInTimePeriod
false
number
function main(){
var records = exchange.GetRecords(PERIOD_M30)
var atr = TA.ATR(records, 14)
Log(atr)
}
def main():
r = exchange.GetRecords(PERIOD_M30)
atr = TA.ATR(r, 14)
Log(atr)
void main() {
auto r = exchange.GetRecords(PERIOD_M30);
auto atr = TA.ATR(r, 14);
Log(atr);
}
The default value of the optInTimePeriod
parameter of the TA.ATR()
function is: 14
.
{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}
The TA.OBV()
function is used to calculate the energy tide indicator.
The return value of the TA.OBV()
function is: a one-dimensional array.
array
TA.OBV(inReal) TA.OBV(inReal, inPriceV)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The inPriceV
parameter is used to specify the transaction amount data.
inPriceV
false
{@struct/Record Record} structure array
function main(){
var records = exchange.GetRecords(PERIOD_M30)
var obv = TA.OBV(records)
Log(obv)
}
def main():
r = exchange.GetRecords(PERIOD_M30)
obv = TA.OBV(r)
Log(obv)
void main() {
auto r = exchange.GetRecords(PERIOD_M30);
auto obv = TA.OBV(r);
Log(obv);
}
{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}
The TA.MA()
function is used to calculate the MACD Indicator.
The return value of the TA.MA()
function is: a one-dimensional array.
array
TA.MA(inReal) TA.MA(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period.
optInTimePeriod
false
number
function main(){
var records = exchange.GetRecords(PERIOD_M30)
var ma = TA.MA(records, 14)
Log(ma)
}
def main():
r = exchange.GetRecords(PERIOD_M30)
ma = TA.MA(r, 14)
Log(ma)
void main() {
auto r = exchange.GetRecords(PERIOD_M30);
auto ma = TA.MA(r, 14);
Log(ma);
}
The default value of the optInTimePeriod
parameter of the TA.MA()
function is: 9
.
{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}
The TA.EMA()
function is used to calculate the exponential average indicator.
The return value of the TA.EMA()
function is: a one-dimensional array.
array
TA.EMA(inReal) TA.EMA(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period.
optInTimePeriod
false
number
function main(){
var records = exchange.GetRecords()
// Determine if the number of K-line bars meets the calculation period of the indicator
if (records && records.length > 9) {
var ema = TA.EMA(records, 9)
Log(ema)
}
}
def main():
r = exchange.GetRecords()
if r and len(r) > 9:
ema = TA.EMA(r, 9)
Log(ema)
void main() {
auto r = exchange.GetRecords();
if(r.Valid && r.size() > 9) {
auto ema = TA.EMA(r, 9);
Log(ema);
}
}
The default value of the optInTimePeriod
parameter of the TA.EMA()
function is: 9
.
{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}
The TA.BOLL()
function is used to calculate the Bollinger Band indicator.
The return value of the TA.BOLL()
function is a two-dimensional array with the structure: [upLine, midLine, downLine]
.
array
TA.BOLL(inReal) TA.BOLL(inReal, period, multiplier)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The period
parameter is used to set the period.
period
false
number
The multiplier
parameter is used to set the multiplier.
multiplier
false
number
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)
}
}
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)
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);
}
}
The default values for the period
and multiplier
parameters of the TA.BOLL()
function are: 20
and 2
.
{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}
The TA.Alligator()
function is used to calculate the Alligator Indicator.
The return value of the TA.Alligator()
function is a two-dimensional array with the structure: [jawLine, teethLine, lipsLine]
.
array
TA.Alligator(inReal) TA.Alligator(inReal, jawLength, teethLength, lipsLength)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The jawLength
parameter is used to set the jaw period.
jawLength
false
number
The teethLength
parameter is used to set the teeth period.
teethLength
false
number
The lipsLength
parameter is used to set the upper lip period.
lipsLength
false
number
function main(){
var records = exchange.GetRecords()
var alligator = TA.Alligator(records)
Log("jawLine:", alligator[0])
Log("teethLine:", alligator[1])
Log("lipsLine:", alligator[2])
}
def main():
records = exchange.GetRecords()
alligator = TA.Alligator(records)
Log("jawLine:", alligator[0])
Log("teethLine:", alligator[1])
Log("lipsLine:", alligator[2])
void main() {
auto records = exchange.GetRecords();
auto alligator = TA.Alligator(records);
Log("jawLine:", alligator[0]);
Log("teethLine:", alligator[1]);
Log("lipsLine:", alligator[2]);
}
The default values of the jawLength
, teethLength
, and lipsLength
parameters of the TA.Alligator()
function are: 13
, 8
, and 5
.
{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}
The TA.CMF()
function is used to calculate the Chaikin Money Flow Indicator.
The return value of the TA.CMF()
function is: a one-dimensional array.
array
TA.CMF(inReal) TA.CMF(inReal, inPriceV)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The inPriceV
parameter is used to specify the volume data.
inPriceV
false
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var cmf = TA.CMF(records)
Log(cmf)
}
def main():
records = exchange.GetRecords()
cmf = TA.CMF(records)
Log(cmf)
void main() {
auto records = exchange.GetRecords();
auto cmf = TA.CMF(records);
Log(cmf);
}
{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}
The TA.Highest()
function is used to calculate the period highest price.
The TA.Highest()
function returns the maximum value of an attribute in the last certain period, excluding the current Bar.
number
TA.Highest(inReal) TA.Highest(inReal, period, attr)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The period
parameter is used to set the period.
period
false
number
The attr
parameter is used to set the attributes, optionally: Open
, Close
, Low
, High
, Volume
, OpenInterest
.
attr
false
string
function main() {
var records = exchange.GetRecords()
var highestForOpen = TA.Highest(records, 10, "Open")
Log(highestForOpen)
}
def main():
records = exchange.GetRecords()
highestForOpen = TA.Highest(records, 10, "Open")
Log(highestForOpen)
void main() {
auto records = exchange.GetRecords();
auto highestForOpen = TA.Highest(records.Open(), 10);
Log(highestForOpen);
}
For example, if the TA.Highest(records, 30, "High")
function is called, if the period parameter period
is set to 0
, it means to calculate all Bars
of the K-line data passed in by the inReal
parameter; if the attribute parameter attr
is not specified, the K-line data passed in by the inReal
parameter is considered to be an ordinary array.
{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Lowest TA.Lowest}
The TA.Lowest()
function is used to calculate the period lowest price.
The TA.Lowest()
function returns the minimum value of an attribute in the last certain period, excluding the current Bar.
number
TA.Lowest(inReal) TA.Lowest(inReal, period, attr)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The period
parameter is used to set the period.
period
false
number
The attr
parameter is used to set the attributes, optionally: Open
, Close
, Low
, High
, Volume
, OpenInterest
.
attr
false
string
function main() {
var records = exchange.GetRecords()
var lowestForOpen = TA.Lowest(records, 10, "Open")
Log(lowestForOpen)
}
def main():
records = exchange.GetRecords()
lowestForOpen = TA.Lowest(records, 10, "Open")
Log(lowestForOpen)
void main() {
auto records = exchange.GetRecords();
auto lowestForOpen = TA.Lowest(records.Open(), 10);
Log(lowestForOpen);
}
For example, if the TA.Lowest(records, 30, "Low")
function is called, if the period parameter period
is set to 0
, it means to calculate all Bars
of the K-line data passed in by the inReal
parameter; if the attribute parameter attr
is not specified, the K-line data passed in by the inReal
parameter is considered to be an ordinary array.
The use of the TA.Highest()
and TA.Lowest()
functions in the C++
strategy needs to be noted that the Highest()
and Lowest()
functions each have only 2 parameters.
And the first parameter passed in is not the K-line data r
obtained when the function auto r = exchange.GetRecords()
was called.
You need to call the r
method and pass in the specific attribute data. For example, pass in the r.Close()
closing price data.
Close
, High
, Low
, Open
, Volume
as in the r.Close()
call method.
Example test of C++
language strategy:
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 is not r, you need to call r.Close()
auto highest = TA.Highest(r.Close(), 8);
Log(highest);
}
{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}
The TA.SMA()
function is used to calculate the simple moving average indicator.
The return value of the TA.SMA()
function is: a one-dimensional array.
array
TA.SMA(inReal) TA.SMA(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period.
optInTimePeriod
false
number
function main(){
var records = exchange.GetRecords(PERIOD_M30)
var sma = TA.SMA(records, 14)
Log(sma)
}
def main():
r = exchange.GetRecords(PERIOD_M30)
sma = TA.SMA(r, 14)
Log(sma)
void main() {
auto r = exchange.GetRecords(PERIOD_M30);
auto sma = TA.SMA(r, 14);
Log(sma);
}
The default value of the optInTimePeriod
parameter of the TA.SMA()
function is: 9
.
{@fun/TA/TA.MACD TA.MACD}, {@fun/TA/TA.KDJ TA.KDJ}, {@fun/TA/TA.RSI TA.RSI}, {@fun/TA/TA.ATR TA.ATR}, {@fun/TA/TA.OBV TA.OBV}, {@fun/TA/TA.MA TA.MA}, {@fun/TA/TA.EMA TA.EMA}, {@fun/TA/TA.BOLL TA.BOLL}, {@fun/TA/TA.Alligator TA.Alligator}, {@fun/TA/TA.CMF TA.CMF}, {@fun/TA/TA.Highest TA.Highest}, {@fun/TA/TA.Lowest TA.Lowest}
The talib.CDL2CROWS()
function is used to calculate Two Crows (K-line chart - Two Crows).
The return value of the talib.CDL2CROWS()
function is a one-dimensional array.
array
talib.CDL2CROWS(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL2CROWS(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL2CROWS(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL2CROWS(records);
Log(ret);
}
The CDL2CROWS()
function is described in the talib library documentation as: CDL2CROWS(Records[Open,High,Low,Close]) = Array(outInteger)
For calls in the Python
language, passing parameters is different and needs to be based on the above description: Records[Open,High,Low,Close]
.
Example of splitting a variable records
(i.e. parameter inPriceOHLC
, type {@struct/Record Record} array of structures) into:
Open
list: written in Python as records.Open
.
High
list: written as records.High
in Python.
Low
list: written in Python as records.Low
.
Close
list: written in Python as records.Close
.
Called in Python strategy code:
talib.CDL2CROWS(records.Open, records.High, records.Low, records.Close)
The other talib
indicators are described in the same way and they will not be repeated.
The talib.CDL3BLACKCROWS()
function is used to calculate Three Black Crows (K-line chart - Three Black Crows).
The return value of the talib.CDL3BLACKCROWS()
function is: a one-dimensional array.
array
talib.CDL3BLACKCROWS(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL3BLACKCROWS(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL3BLACKCROWS(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL3BLACKCROWS(records);
Log(ret);
}
The CDL3BLACKCROWS()
function is described in the talib library documentation as: CDL3BLACKCROWS(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDL3INSIDE()
function is used to calculate Three Inside Up/Down (K-line chart: Three Inside Up/Down).
The return value of the talib.CDL3INSIDE()
function is: a one-dimensional array.
array
talib.CDL3INSIDE(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL3INSIDE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL3INSIDE(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL3INSIDE(records);
Log(ret);
}
The CDL3INSIDE()
function is described in the talib library documentation as: CDL3INSIDE(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDL3LINESTRIKE()
function is used to calculate the Three-Line Strike (K-line chart: Three-Line Strike).
The return value of the talib.CDL3LINESTRIKE()
function is: a one-dimensional array.
array
talib.CDL3LINESTRIKE(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL3LINESTRIKE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL3LINESTRIKE(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL3LINESTRIKE(records);
Log(ret);
}
The CDL3LINESTRIKE()
function is described in the talib library documentation as: CDL3LINESTRIKE(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDL3OUTSIDE()
function is used to calculate Three Outside Up/Down (K-line chart: Three Outside Up/Down).
The return value of the talib.CDL3OUTSIDE()
function is: a one-dimensional array.
array
talib.CDL3OUTSIDE(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL3OUTSIDE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL3OUTSIDE(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL3OUTSIDE(records);
Log(ret);
}
The CDL3OUTSIDE()
function is described in the talib library documentation as: CDL3OUTSIDE(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDL3STARSINSOUTH()
function is used to calculate Three Stars In The South (K-line chart: Three Stars In The South).
The return value of the talib.CDL3STARSINSOUTH()
function is: a one-dimensional array.
array
talib.CDL3STARSINSOUTH(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL3STARSINSOUTH(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL3STARSINSOUTH(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL3STARSINSOUTH(records);
Log(ret);
}
The CDL3STARSINSOUTH()
function is described in the talib library documentation as: CDL3STARSINSOUTH(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDL3WHITESOLDIERS()
function is used to calculate Three Advancing White Soldiers (K-line chart: Three Advancing White Soldiers).
The return value of the talib.CDL3WHITESOLDIERS()
function is: a one-dimensional array.
array
talib.CDL3WHITESOLDIERS(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDL3WHITESOLDIERS(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDL3WHITESOLDIERS(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDL3WHITESOLDIERS(records);
Log(ret);
}
The CDL3WHITESOLDIERS()
function is described in the talib library documentation as: CDL3WHITESOLDIERS(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLABANDONEDBABY()
function is used to calculate Abandoned Baby (K-line chart: Abandoned Baby).
The return value of the talib.CDLABANDONEDBABY()
function is: a one-dimensional array.
array
talib.CDLABANDONEDBABY(inPriceOHLC) talib.CDLABANDONEDBABY(inPriceOHLC, optInPenetration)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
The optInPenetration
parameter is used to set the Penetration, the default value is 0.3.
optInPenetration
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLABANDONEDBABY(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLABANDONEDBABY(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLABANDONEDBABY(records);
Log(ret);
}
The CDLABANDONEDBABY()
function is described in the talib library documentation as: CDLABANDONEDBABY(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)
The talib.CDLADVANCEBLOCK()
function is used to calculate the Advance Block (K-line chart: Advance).
The return value of the talib.CDLADVANCEBLOCK()
function is a one-dimensional array.
array
talib.CDLADVANCEBLOCK(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLADVANCEBLOCK(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLADVANCEBLOCK(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLADVANCEBLOCK(records);
Log(ret);
}
The CDLADVANCEBLOCK()
function is described in the talib library documentation as: CDLADVANCEBLOCK(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLBELTHOLD()
function is used to calculate the Belt-hold (K-line chart: Belt-hold).
The return value of the talib.CDLBELTHOLD()
function is: a one-dimensional array.
array
talib.CDLBELTHOLD(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLBELTHOLD(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLBELTHOLD(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLBELTHOLD(records);
Log(ret);
}
The CDLBELTHOLD()
function is described in the talib library documentation as: CDLBELTHOLD(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLBREAKAWAY()
function is used to calculate the Breakaway (K-line chart: Breakaway).
The return value of the talib.CDLBREAKAWAY()
function is: a one-dimensional array.
array
talib.CDLBREAKAWAY(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLBREAKAWAY(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLBREAKAWAY(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLBREAKAWAY(records);
Log(ret);
}
CDLBREAKAWAY()
function is described in the talib library documentation as: CDLBREAKAWAY(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLCLOSINGMARUBOZU()
function is used to calculate Closing Marubozu (K-line chart: closing bareheaded and barefoot).
The return value of the talib.CDLCLOSINGMARUBOZU()
function is: a one-dimensional array.
array
talib.CDLCLOSINGMARUBOZU(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLCLOSINGMARUBOZU(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLCLOSINGMARUBOZU(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLCLOSINGMARUBOZU(records);
Log(ret);
}
The CDLCLOSINGMARUBOZU()
function is described in the talib library documentation as: CDLCLOSINGMARUBOZU(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLCONCEALBABYSWALL()
function is used to calculate the Concealing Baby Swallow (K-line chart: Concealing Baby Swallow pattern).
The return value of the talib.CDLCONCEALBABYSWALL()
function is: a one-dimensional array.
array
talib.CDLCONCEALBABYSWALL(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLCONCEALBABYSWALL(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLCONCEALBABYSWALL(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLCONCEALBABYSWALL(records);
Log(ret);
}
The CDLCONCEALBABYSWALL()
function is described in the talib library documentation as: CDLCONCEALBABYSWALL(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLCOUNTERATTACK()
function is used to calculate Counterattack (K-line chart:Counterattack).
The return value of the talib.CDLCOUNTERATTACK()
function is a one-dimensional array.
array
talib.CDLCOUNTERATTACK(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLCOUNTERATTACK(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLCOUNTERATTACK(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLCOUNTERATTACK(records);
Log(ret);
}
The CDLCOUNTERATTACK()
function is described in the talib library documentation as: CDLCOUNTERATTACK(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLDARKCLOUDCOVER()
function is used to calculate Dark Cloud Cover (K-line chart: dark cloud cover).
The return value of the talib.CDLDARKCLOUDCOVER()
function is a one-dimensional array.
array
talib.CDLDARKCLOUDCOVER(inPriceOHLC) talib.CDLDARKCLOUDCOVER(inPriceOHLC, optInPenetration)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
The optInPenetration
parameter is used to set the Penetration, the default value is 0.5.
optInPenetration
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLDARKCLOUDCOVER(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLDARKCLOUDCOVER(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLDARKCLOUDCOVER(records);
Log(ret);
}
The CDLDARKCLOUDCOVER()
function is described in the talib library documentation as: CDLDARKCLOUDCOVER(Records[Open,High,Low,Close],Penetration = 0.5) = Array(outInteger)
The talib.CDLDOJI()
function is used to calculate Doji (K-line chart: Doji).
The return value of the talib.CDLDOJI()
function is: a one-dimensional array.
array
talib.CDLDOJI(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLDOJI(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLDOJI(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLDOJI(records);
Log(ret);
}
The CDLDOJI()
function is described in the talib library documentation as: CDLDOJI(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLDOJISTAR()
function is used to calculate the Doji Star (K-line chart: Doji Star).
The return value of the talib.CDLDOJISTAR()
function is: a one-dimensional array.
array
talib.CDLDOJISTAR(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLDOJISTAR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLDOJISTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLDOJISTAR(records);
Log(ret);
}
The CDLDOJISTAR()
function is described in the talib library documentation as: CDLDOJISTAR(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLDRAGONFLYDOJI()
function is used to calculate Dragonfly Doji (K-line chart: Dragonfly Doji).
The return value of the talib.CDLDRAGONFLYDOJI()
function is: a one-dimensional array.
array
talib.CDLDRAGONFLYDOJI(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLDRAGONFLYDOJI(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLDRAGONFLYDOJI(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLDRAGONFLYDOJI(records);
Log(ret);
}
The CDLDRAGONFLYDOJI()
function is described in the talib library documentation as: CDLDRAGONFLYDOJI(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLENGULFING()
function is used to calculate the Engulfing Pattern (K-line chart: engulfing).
The return value of the talib.CDLENGULFING()
function is a one-dimensional array.
array
talib.CDLENGULFING(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLENGULFING(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLENGULFING(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLENGULFING(records);
Log(ret);
}
The CDLENGULFING()
function is described in the talib library documentation as: CDLENGULFING(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLEVENINGDOJISTAR()
function is used to calculate the Evening Doji Star (K-line chart: Evening Doji Star).
The return value of the talib.CDLEVENINGDOJISTAR()
function is: a one-dimensional array.
array
talib.CDLEVENINGDOJISTAR(inPriceOHLC) talib.CDLEVENINGDOJISTAR(inPriceOHLC, optInPenetration)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
The optInPenetration
parameter is used to set the Penetration, the default value is 0.3.
optInPenetration
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLEVENINGDOJISTAR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLEVENINGDOJISTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLEVENINGDOJISTAR(records);
Log(ret);
}
The CDLEVENINGDOJISTAR()
function is described in the talib library documentation as: CDLEVENINGDOJISTAR(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)
The talib.CDLEVENINGSTAR()
function is used to calculate the Evening Star (K-line chart: Evening Star).
The return value of the talib.CDLEVENINGSTAR()
function is: a one-dimensional array.
array
talib.CDLEVENINGSTAR(inPriceOHLC) talib.CDLEVENINGSTAR(inPriceOHLC, optInPenetration)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
The optInPenetration
parameter is used to set the Penetration, the default value is 0.3.
optInPenetration
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLEVENINGSTAR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLEVENINGSTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLEVENINGSTAR(records);
Log(ret);
}
The CDLEVENINGSTAR()
function is described in the talib library documentation as: CDLEVENINGSTAR(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)
The talib.CDLGAPSIDESIDEWHITE()
function is used to calculate Up/Down-gap side-by-side white lines (K-line chart: Up/Down gap side-by-side white lines).
The return value of the talib.CDLGAPSIDESIDEWHITE()
function is: a one-dimensional array.
array
talib.CDLGAPSIDESIDEWHITE(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLGAPSIDESIDEWHITE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLGAPSIDESIDEWHITE(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLGAPSIDESIDEWHITE(records);
Log(ret);
}
The CDLGAPSIDESIDEWHITE()
function is described in the talib library documentation as: CDLGAPSIDESIDEWHITE(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLGRAVESTONEDOJI()
function is used to calculate the Gravestone Doji (K-line chart: Gravestone Doji).
The return value of the talib.CDLGRAVESTONEDOJI()
function is: a one-dimensional array.
array
talib.CDLGRAVESTONEDOJI(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLGRAVESTONEDOJI(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLGRAVESTONEDOJI(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLGRAVESTONEDOJI(records);
Log(ret);
}
The CDLGRAVESTONEDOJI()
function is described in the talib library documentation as: CDLGRAVESTONEDOJI(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLHAMMER()
function is used to calculate Hammer (K-line chart: Hammer).
The return value of the talib.CDLHAMMER()
function is: a one-dimensional array.
array
talib.CDLHAMMER(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHAMMER(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHAMMER(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHAMMER(records);
Log(ret);
}
The CDLHAMMER()
function is described in the talib library documentation as: CDLHAMMER(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLHANGINGMAN()
function is used to calculate Hanging Man (K-line chart: Hanging Man).
The return value of the talib.CDLHANGINGMAN()
function is a one-dimensional array.
array
talib.CDLHANGINGMAN(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHANGINGMAN(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHANGINGMAN(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHANGINGMAN(records);
Log(ret);
}
The CDLHANGINGMAN()
function is described in the talib library documentation as: CDLHANGINGMAN(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLHARAMI()
function is used to calculate the Harami Pattern (K-line chart: negative and positive lines).
The return value of the talib.CDLHARAMI()
function is a one-dimensional array.
array
talib.CDLHARAMI(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHARAMI(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHARAMI(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHARAMI(records);
Log(ret);
}
The CDLHARAMI()
function is described in the talib library documentation as: CDLHARAMI(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLHARAMICROSS()
function is used to calculate the Harami Cross Pattern (K-line chart: cross negative and positive lines).
The return value of the talib.CDLHARAMICROSS()
function is: a one-dimensional array.
array
talib.CDLHARAMICROSS(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHARAMICROSS(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHARAMICROSS(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHARAMICROSS(records);
Log(ret);
}
The CDLHARAMICROSS()
function is described in the talib library documentation as: CDLHARAMICROSS(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLHIGHWAVE()
function is used to calculate the High-Wave Candle (K-line chart: Long Leg Cross).
The return value of the talib.CDLHIGHWAVE()
function is a one-dimensional array.
array
talib.CDLHIGHWAVE(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHIGHWAVE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHIGHWAVE(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHIGHWAVE(records);
Log(ret);
}
The CDLHIGHWAVE()
function is described in the talib library documentation as: CDLHIGHWAVE(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLHIKKAKE()
function is used to calculate the Hikkake Pattern (K-line chart: trap).
The return value of the talib.CDLHIKKAKE()
function is a one-dimensional array.
array
talib.CDLHIKKAKE(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHIKKAKE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHIKKAKE(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHIKKAKE(records);
Log(ret);
}
The CDLHIKKAKE()
function is described in the talib library documentation as: CDLHIKKAKE(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLHIKKAKEMOD()
function is used to calculate the Modified Hikkake Pattern (K-line chart: Modified Trap).
The return value of the talib.CDLHIKKAKEMOD()
function is: a one-dimensional array.
array
talib.CDLHIKKAKEMOD(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHIKKAKEMOD(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHIKKAKEMOD(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHIKKAKEMOD(records);
Log(ret);
}
The CDLHIKKAKEMOD()
function is described in the talib library documentation as: CDLHIKKAKEMOD(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLHOMINGPIGEON()
function is used to calculate the Homing Pigeon (K-line chart: Pigeon).
The return value of the talib.CDLHOMINGPIGEON()
function is: a one-dimensional array.
array
talib.CDLHOMINGPIGEON(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLHOMINGPIGEON(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLHOMINGPIGEON(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLHOMINGPIGEON(records);
Log(ret);
}
The CDLHOMINGPIGEON()
function is described in the talib library documentation as: CDLHOMINGPIGEON(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLIDENTICAL3CROWS()
function is used to calculate Identical Three Crows (K-line chart: same three crows).
The return value of the talib.CDLIDENTICAL3CROWS()
function is: a one-dimensional array.
array
talib.CDLIDENTICAL3CROWS(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLIDENTICAL3CROWS(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLIDENTICAL3CROWS(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLIDENTICAL3CROWS(records);
Log(ret);
}
The CDLIDENTICAL3CROWS()
function is described in the talib library documentation as: CDLIDENTICAL3CROWS(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLINNECK()
function is used to calculate the In-Neck Pattern (K-line chart: neckline).
The return value of the talib.CDLINNECK()
function is: a one-dimensional array.
array
talib.CDLINNECK(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLINNECK(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLINNECK(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLINNECK(records);
Log(ret);
}
The CDLINNECK()
function is described in the talib library documentation as: CDLINNECK(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLINVERTEDHAMMER()
function is used to calculate the Inverted Hammer (K-line chart: Inverted Hammer).
The return value of the talib.CDLINVERTEDHAMMER()
function is: a one-dimensional array.
array
talib.CDLINVERTEDHAMMER(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLINVERTEDHAMMER(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLINVERTEDHAMMER(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLINVERTEDHAMMER(records);
Log(ret);
}
The CDLINVERTEDHAMMER()
function is described in the talib library documentation as: CDLINVERTEDHAMMER(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLKICKING()
function is used to calculate Kicking (K-line chart: kicking).
The return value of the talib.CDLKICKING()
function is a one-dimensional array.
array
talib.CDLKICKING(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLKICKING(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLKICKING(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLKICKING(records);
Log(ret);
}
The CDLKICKING()
function is described in the talib library documentation as: CDLKICKING(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLKICKINGBYLENGTH()
function is used to calculate the kick - bull/bear determined by the longer Marubozu (K-line chart: kick bull/kick bear).
The return value of the talib.CDLKICKINGBYLENGTH()
function is: a one-dimensional array.
array
talib.CDLKICKINGBYLENGTH(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLKICKINGBYLENGTH(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLKICKINGBYLENGTH(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLKICKINGBYLENGTH(records);
Log(ret);
}
The CDLKICKINGBYLENGTH()
function is described in the talib library documentation as: CDLKICKINGBYLENGTH(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLLADDERBOTTOM()
function is used to calculate the Ladder Bottom (K-line chart: Ladder Bottom).
The return value of the talib.CDLLADDERBOTTOM()
function is: a one-dimensional array.
array
talib.CDLLADDERBOTTOM(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLLADDERBOTTOM(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLLADDERBOTTOM(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLLADDERBOTTOM(records);
Log(ret);
}
The CDLLADDERBOTTOM()
function is described in the talib library documentation as: CDLLADDERBOTTOM(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLLONGLEGGEDDOJI()
function is used to calculate the Long Legged Doji (K-line chart: Long Legged Doji).
The return value of the talib.CDLLONGLEGGEDDOJI()
function is: a one-dimensional array.
array
talib.CDLLONGLEGGEDDOJI(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLLONGLEGGEDDOJI(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLLONGLEGGEDDOJI(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLLONGLEGGEDDOJI(records);
Log(ret);
}
The CDLLONGLEGGEDDOJI()
function is described in the talib library documentation as: CDLLONGLEGGEDDOJI(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLLONGLINE()
function is used to calculate the Long Line Candle (K-line chart: Long Line).
The return value of the talib.CDLLONGLINE()
function is: a one-dimensional array.
array
talib.CDLLONGLINE(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLLONGLINE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLLONGLINE(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLLONGLINE(records);
Log(ret);
}
The CDLLONGLINE()
function is described in the talib library documentation as: CDLLONGLINE(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLMARUBOZU()
function is used to calculate the Marubozu (K-line chart: bare head and bare foot).
The return value of the talib.CDLMARUBOZU()
function is a one-dimensional array.
array
talib.CDLMARUBOZU(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLMARUBOZU(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLMARUBOZU(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLMARUBOZU(records);
Log(ret);
}
The CDLMARUBOZU()
function is described in the talib library documentation as: CDLMARUBOZU(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLMATCHINGLOW()
function is used to calculate Matching Low (K-line chart: Matching Low).
The return value of the talib.CDLMATCHINGLOW()
function is: a one-dimensional array.
array
talib.CDLMATCHINGLOW(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLMATCHINGLOW(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLMATCHINGLOW(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLMATCHINGLOW(records);
Log(ret);
}
The CDLMATCHINGLOW()
function is described in the talib library documentation as: CDLMATCHINGLOW(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLMATHOLD()
function is used to calculate Mat Hold (K-line chart: Mat Hold).
The return value of the talib.CDLMATHOLD()
function is: a one-dimensional array.
array
talib.CDLMATHOLD(inPriceOHLC) talib.CDLMATHOLD(inPriceOHLC, optInPenetration)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
The optInPenetration
parameter is optional and is used to specify the percentage of the width of the rising/falling trend line, the default value is 0.5.
optInPenetration
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLMATHOLD(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLMATHOLD(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLMATHOLD(records);
Log(ret);
}
The CDLMATHOLD()
function is described in the talib library documentation as: CDLMATHOLD(Records[Open,High,Low,Close],Penetration = 0.5) = Array(outInteger)
The talib.CDLMORNINGDOJISTAR()
function is used to calculate the Morning Doji Star (K-line chart: Morning Doji Star).
The return value of the talib.CDLMORNINGDOJISTAR()
function is: a one-dimensional array.
array
talib.CDLMORNINGDOJISTAR(inPriceOHLC) talib.CDLMORNINGDOJISTAR(inPriceOHLC, optInPenetration)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
The optInPenetration
parameter is used to specify the degree of overlap between the validation opening price and the solid part, the default value is 0.3.
optInPenetration
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLMORNINGDOJISTAR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLMORNINGDOJISTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLMORNINGDOJISTAR(records);
Log(ret);
}
The CDLMORNINGDOJISTAR()
function is described in the talib library documentation as: CDLMORNINGDOJISTAR(Records[Open,High,Low,Close],Penetration = 0.3) = Array(outInteger)
The talib.CDLMORNINGSTAR()
function is used to calculate Morning Star (K-line chart: Morning Star).
The return value of the talib.CDLMORNINGSTAR()
function is: a one-dimensional array.
array
talib.CDLMORNINGSTAR(inPriceOHLC) talib.CDLMORNINGSTAR(inPriceOHLC, optInPenetration)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
The optInPenetration
parameter is the price float percentage threshold required for trend confirmation and takes a value in the range [0,1], with a default value of 0.3.
optInPenetration
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLMORNINGSTAR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLMORNINGSTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLMORNINGSTAR(records);
Log(ret);
}
The CDLMORNINGSTAR()
function is described in the talib library documentation as: CDLMORNINGSTAR(Records[Open,High,Low,Close],Penetration=0.3) = Array(outInteger)
The talib.CDLONNECK()
function is used to calculate the On-Neck Pattern (K-line chart: On-Neck Pattern).
The return value of the talib.CDLONNECK()
function is a one-dimensional array.
array
talib.CDLONNECK(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLONNECK(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLONNECK(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLONNECK(records);
Log(ret);
}
The CDLONNECK()
function is described in the talib library documentation as: CDLONNECK(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLPIERCING()
function is used to calculate the Piercing Pattern (K-line chart: Piercing Pattern).
The return value of the talib.CDLPIERCING()
function is a one-dimensional array.
array
talib.CDLPIERCING(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLPIERCING(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLPIERCING(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLPIERCING(records);
Log(ret);
}
The CDLPIERCING()
function is described in the talib library documentation as: CDLPIERCING(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLRICKSHAWMAN()
function is used to calculate Rickshaw Man (K-line chart: Rickshaw Man).
The return value of the talib.CDLRICKSHAWMAN()
function is: a one-dimensional array.
array
talib.CDLRICKSHAWMAN(inPriceOHLC)
The inPriceOHLC
parameter is used to specify K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLRICKSHAWMAN(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLRICKSHAWMAN(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLRICKSHAWMAN(records);
Log(ret);
}
The CDLRICKSHAWMAN()
function is described in the talib library documentation as: CDLRICKSHAWMAN(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLRISEFALL3METHODS()
function is used to calculate Rising/Falling Three Methods (K-line chart: Rising/Falling Three Methods).
The return value of the talib.CDLRISEFALL3METHODS()
function is: a one-dimensional array.
array
talib.CDLRISEFALL3METHODS(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLRISEFALL3METHODS(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLRISEFALL3METHODS(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLRISEFALL3METHODS(records);
Log(ret);
}
The CDLRISEFALL3METHODS()
function is described in the talib library documentation as: CDLRISEFALL3METHODS(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLSEPARATINGLINES()
function is used to calculate Separating Lines (K-line chart: Separating Lines).
The return value of the talib.CDLSEPARATINGLINES()
function is a one-dimensional array.
array
talib.CDLSEPARATINGLINES(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLSEPARATINGLINES(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLSEPARATINGLINES(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLSEPARATINGLINES(records);
Log(ret);
}
The CDLSEPARATINGLINES()
function is described in the talib library documentation as: CDLSEPARATINGLINES(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLSHOOTINGSTAR()
function is used to calculate the Shooting Star (K-line chart: Shooting Star).
The return value of the talib.CDLSHOOTINGSTAR()
function is a one-dimensional array.
array
talib.CDLSHOOTINGSTAR(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLSHOOTINGSTAR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLSHOOTINGSTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLSHOOTINGSTAR(records);
Log(ret);
}
The CDLSHOOTINGSTAR()
function is described in the talib library documentation as: CDLSHOOTINGSTAR(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLSHORTLINE()
function is used to calculate the Short Line Candle (K-line chart: Short Line).
The return value of the talib.CDLSHORTLINE()
function is: a one-dimensional array.
array
talib.CDLSHORTLINE(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLSHORTLINE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLSHORTLINE(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLSHORTLINE(records);
Log(ret);
}
The CDLSHORTLINE()
function is described in the talib library documentation as: CDLSHORTLINE(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLSPINNINGTOP()
function is used to calculate Spinning Top (K-line chart: Spinning Top).
The return value of the talib.CDLSPINNINGTOP()
function is: a one-dimensional array.
array
talib.CDLSPINNINGTOP(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLSPINNINGTOP(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLSPINNINGTOP(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLSPINNINGTOP(records);
Log(ret);
}
The CDLSPINNINGTOP()
function is described in the talib library documentation as: CDLSPINNINGTOP(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLSTALLEDPATTERN()
function is used to calculate Stalled Pattern (K-line chart: Stalled Pattern).
The return value of the talib.CDLSTALLEDPATTERN()
function is: a one-dimensional array.
array
talib.CDLSTALLEDPATTERN(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLSTALLEDPATTERN(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLSTALLEDPATTERN(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLSTALLEDPATTERN(records);
Log(ret);
}
The CDLSTALLEDPATTERN()
function is described in the talib library documentation as: CDLSTALLEDPATTERN(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLSTICKSANDWICH()
function is used to calculate the Stick Sandwich (K-line chart: Stick Sandwich).
The return value of the talib.CDLSTICKSANDWICH()
function is a one-dimensional array.
array
talib.CDLSTICKSANDWICH(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLSTICKSANDWICH(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLSTICKSANDWICH(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLSTICKSANDWICH(records);
Log(ret);
}
The CDLSTICKSANDWICH()
function is described in the talib library documentation as: CDLSTICKSANDWICH(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLTAKURI()
function is used to calculate Takuri (dragonfly doji with a very long lower shadow line) (K-line chart: Takuri).
The return value of the talib.CDLTAKURI()
function is a one-dimensional array.
array
talib.CDLTAKURI(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLTAKURI(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLTAKURI(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLTAKURI(records);
Log(ret);
}
The CDLTAKURI()
function is described in the talib library documentation as: CDLTAKURI(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLTASUKIGAP()
function is used to calculate the Tasuki Gap (K-line chart: Tasuki Gap).
The return value of the talib.CDLTASUKIGAP()
function is a one-dimensional array.
array
talib.CDLTASUKIGAP(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLTASUKIGAP(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLTASUKIGAP(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLTASUKIGAP(records);
Log(ret);
}
The CDLTASUKIGAP()
function is described in the talib library documentation as: CDLTASUKIGAP(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLTHRUSTING()
function is used to calculate the Thrusting Pattern (K-line chart: Thrusting Pattern).
The return value of the talib.CDLTHRUSTING()
function is: a one-dimensional array.
array
talib.CDLTHRUSTING(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLTHRUSTING(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLTHRUSTING(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLTHRUSTING(records);
Log(ret);
}
The CDLTHRUSTING()
function is described in the talib library documentation as: CDLTHRUSTING(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLTRISTAR()
function is used to calculate the Tristar Pattern (K-line chart: Tristar Pattern).
The return value of the talib.CDLTRISTAR()
function is: a one-dimensional array.
array
talib.CDLTRISTAR(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLTRISTAR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLTRISTAR(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLTRISTAR(records);
Log(ret);
}
The CDLTRISTAR()
function is described in the talib library documentation as: CDLTRISTAR(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLUNIQUE3RIVER()
function is used to calculate the Unique 3 River (K-line chart: Unique 3 River).
The return value of the talib.CDLUNIQUE3RIVER()
function is: a one-dimensional array.
array
talib.CDLUNIQUE3RIVER(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLUNIQUE3RIVER(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLUNIQUE3RIVER(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLUNIQUE3RIVER(records);
Log(ret);
}
The CDLUNIQUE3RIVER()
function is described in the talib library documentation as: CDLUNIQUE3RIVER(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLUPSIDEGAP2CROWS()
function is used to calculate Upside Gap Two Crows (K-line chart: Upside Gap Two Crows).
The return value of the talib.CDLUPSIDEGAP2CROWS()
function is: a one-dimensional array.
array
talib.CDLUPSIDEGAP2CROWS(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLUPSIDEGAP2CROWS(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLUPSIDEGAP2CROWS(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLUPSIDEGAP2CROWS(records);
Log(ret);
}
The CDLUPSIDEGAP2CROWS()
function is described in the talib library documentation as: CDLUPSIDEGAP2CROWS(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.CDLXSIDEGAP3METHODS()
function is used to calculate Upside/Downside Gap Three Methods (K-line chart: Upside/Downside Gap Three Methods).
The return value of the talib.CDLXSIDEGAP3METHODS()
function is: a one-dimensional array.
array
talib.CDLXSIDEGAP3METHODS(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.CDLXSIDEGAP3METHODS(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CDLXSIDEGAP3METHODS(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CDLXSIDEGAP3METHODS(records);
Log(ret);
}
The CDLXSIDEGAP3METHODS()
function is described in the talib library documentation as: CDLXSIDEGAP3METHODS(Records[Open,High,Low,Close]) = Array(outInteger)
The talib.AD()
function is used to calculate the Chaikin A/D Line (line stochastic indicator).
The return value of the talib.AD()
function is: a one-dimensional array.
array
talib.AD(inPriceHLCV)
The inPriceHLCV
parameter is used to specify the K-line data.
inPriceHLCV
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.AD(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.AD(records.High, records.Low, records.Close, records.Volume)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.AD(records);
Log(ret);
}
The AD()
function is described in the talib library documentation as: AD(Records[High,Low,Close,Volume]) = Array(outReal)
The talib.ADOSC()
function is used to calculate the Chaikin A/D Oscillator (Chaikin Oscillator).
The return value of the talib.ADOSC()
function is a one-dimensional array.
array
talib.ADOSC(inPriceHLCV) talib.ADOSC(inPriceHLCV, optInFastPeriod, optInSlowPeriod)
The inPriceHLCV
parameter is used to specify the K-line data.
inPriceHLCV
true
{@struct/Record Record} structure array
The optInFastPeriod
parameter is used to set the fast period.
optInFastPeriod
false
number
The optInSlowPeriod
parameter is used to set the slow period.
optInSlowPeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.ADOSC(records, 3, 10)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.ADOSC(records.High, records.Low, records.Close, records.Volume, 3, 10)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ADOSC(records, 3, 10);
Log(ret);
}
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)
The talib.OBV()
function is used to calculate On Balance Volume (energy tide).
The return value of the talib.OBV()
function is a one-dimensional array.
array
talib.OBV(inReal) talib.OBV(inReal, inPriceV)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The inPriceV
parameter is used to specify the K-line data.
inPriceV
false
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.OBV(records, records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.OBV(records.Close, records.Volume)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.OBV(records);
Log(ret);
}
The OBV()
function is described in the talib library documentation as: OBV(Records[Close],Records[Volume]) = Array(outReal)
The talib.ACOS()
function is used to calculate Vector Trigonometric ACos (inverse cosine function).
The return value of the talib.ACOS()
function is a one-dimensional array.
array
talib.ACOS(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var data = [-1, 0, 1]
var ret = talib.ACOS(data)
Log(ret)
}
import talib
import numpy as np
def main():
data = [-1.0, 0, 1.0]
ret = talib.ACOS(np.array(data))
Log(ret)
void main() {
std::vector<double> data = {-1, 0, 1};
auto ret = talib.ACOS(data);
Log(ret);
}
The ACOS()
function is described in the talib library documentation as: ACOS(Records[Close]) = Array(outReal)
The talib.ASIN()
function is used to calculate the Vector Trigonometric ASin (inverse sine function).
The return value of the talib.ASIN()
function is a one-dimensional array.
array
talib.ASIN(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var data = [-1, 0, 1]
var ret = talib.ASIN(data)
Log(ret)
}
import talib
import numpy as np
def main():
data = [-1.0, 0, 1.0]
ret = talib.ASIN(np.array(data))
Log(ret)
void main() {
std::vector<double> data = {-1, 0, 1};
auto ret = talib.ASIN(data);
Log(ret);
}
The ASIN()
function is described in the talib library documentation as: ASIN(Records[Close]) = Array(outReal)
The talib.ATAN()
function is used to calculate the Vector Trigonometric ATan (inverse tangent function).
The return value of the talib.ATAN()
function is: a one-dimensional array.
array
talib.ATAN(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var data = [-3.14/2, 0, 3.14/2]
var ret = talib.ATAN(data)
Log(ret)
}
import talib
import numpy as np
def main():
data = [-3.14/2, 0, 3.14/2]
ret = talib.ATAN(np.array(data))
Log(ret)
void main() {
std::vector<double> data = {-3.14/2, 0, 3.14/2};
auto ret = talib.ATAN(data);
Log(ret);
}
The ATAN()
function is described in the talib library documentation as: ATAN(Records[Close]) = Array(outReal)
The talib.CEIL()
function is used to calculate Vector Ceil (rounding function).
The return value of the talib.CEIL()
function is a one-dimensional array.
array
talib.CEIL(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var records = exchange.GetRecords()
var ret = talib.CEIL(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CEIL(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CEIL(records);
Log(ret);
}
The CEIL()
function is described in the talib library documentation as: CEIL(Records[Close]) = Array(outReal)
The talib.COS()
function is used to calculate the Vector Trigonometric Cos (cosine function).
The return value of the talib.COS()
function is: a one-dimensional array.
array
talib.COS(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var data = [-3.14, 0, 3.14]
var ret = talib.COS(data)
Log(ret)
}
import talib
import numpy as np
def main():
data = [-3.14, 0, 3.14]
ret = talib.COS(np.array(data))
Log(ret)
void main() {
std::vector<double> data = {-3.14, 0, 3.14};
auto ret = talib.COS(data);
Log(ret);
}
The COS()
function is described in the talib library documentation as: COS(Records[Close]) = Array(outReal)
The talib.COSH()
function is used to calculate Vector Trigonometric Cosh (hyperbolic cosine value).
The return value of the talib.COSH()
function is a one-dimensional array.
array
talib.COSH(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var data = [-1, 0, 1]
var ret = talib.COSH(data)
Log(ret)
}
import talib
import numpy as np
def main():
data = [-1.0, 0, 1.0]
ret = talib.COSH(np.array(data))
Log(ret)
void main() {
std::vector<double> data = {-1, 0, 1};
auto ret = talib.COSH(data);
Log(ret);
}
The COSH()
function is described in the talib library documentation as: COSH(Records[Close]) = Array(outReal)
The talib.EXP()
function is used to calculate the Vector Arithmetic Exp (exponential function).
The return value of the talib.EXP()
function is: a one-dimensional array.
array
talib.EXP(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var data = [0, 1, 2]
var ret = talib.EXP(data) // e^0, e^1, e^2
Log(ret)
}
import talib
import numpy as np
def main():
data = [0, 1.0, 2.0]
ret = talib.EXP(np.array(data))
Log(ret)
void main() {
std::vector<double> data = {0, 1.0, 2.0};
auto ret = talib.EXP(data);
Log(ret);
}
The EXP()
function is described in the talib library documentation as: EXP(Records[Close]) = Array(outReal)
The talib.FLOOR()
function is used to calculate the Vector Floor (rounded down).
The return value of the talib.FLOOR()
function is a one-dimensional array.
array
talib.FLOOR(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var records = exchange.GetRecords()
var ret = talib.FLOOR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.FLOOR(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.FLOOR(records);
Log(ret);
}
The FLOOR()
function is described in the talib library documentation as: FLOOR(Records[Close]) = Array(outReal)
The talib.LN()
function is used to calculate the Vector Log Natural (natural logarithm).
The return value of the talib.LN()
function is a one-dimensional array.
array
talib.LN(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var data = [1, 2, 3]
var ret = talib.LN(data)
Log(ret)
}
import talib
import numpy as np
def main():
data = [1.0, 2.0, 3.0]
ret = talib.LN(np.array(data))
Log(ret)
void main() {
std::vector<double> data = {1, 2, 3};
auto ret = talib.LN(data);
Log(ret);
}
The LN()
function is described in the talib library documentation as: LN(Records[Close]) = Array(outReal)
The talib.LOG10()
function is used to calculate Vector Log10 (logarithmic function).
The return value of the talib.LOG10()
function is a one-dimensional array.
array
talib.LOG10(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var data = [10, 100, 1000]
var ret = talib.LOG10(data)
Log(ret)
}
import talib
import numpy as np
def main():
data = [10.0, 100.0, 1000.0]
ret = talib.LOG10(np.array(data))
Log(ret)
void main() {
std::vector<double> data = {10, 100, 1000};
auto ret = talib.LOG10(data);
Log(ret);
}
The LOG10()
function is described in the talib library documentation as: LOG10(Records[Close]) = Array(outReal)
The talib.SIN()
function is used to calculate Vector Trigonometric Sin (sine value).
The return value of the talib.SIN()
function is a one-dimensional array.
array
talib.SIN(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var data = [-3.14/2, 0, 3.14/2]
var ret = talib.SIN(data)
Log(ret)
}
import talib
import numpy as np
def main():
data = [-3.14/2, 0, 3.14/2]
ret = talib.SIN(np.array(data))
Log(ret)
void main() {
std::vector<double> data = {-3.14/2, 0, 3.14/2};
auto ret = talib.SIN(data);
Log(ret);
}
The SIN()
function is described in the talib library documentation as: SIN(Records[Close]) = Array(outReal)
The talib.SINH()
function is used to calculate the Vector Trigonometric Sinh (hyperbolic sine function).
The return value of the talib.SINH()
function is: a one-dimensional array.
array
talib.SINH(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var data = [-1, 0, 1]
var ret = talib.SINH(data)
Log(ret)
}
import talib
import numpy as np
def main():
data = [-1.0, 0, 1.0]
ret = talib.SINH(np.array(data))
Log(ret)
void main() {
std::vector<double> data = {-1, 0, 1};
auto ret = talib.SINH(data);
Log(ret);
}
The SINH()
function is described in the talib library documentation as: SINH(Records[Close]) = Array(outReal)
The talib.SQRT()
function is used to calculate the Vector Square Root (square root).
The return value of the talib.SQRT()
function is: a one-dimensional array.
array
talib.SQRT(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var data = [4, 64, 100]
var ret = talib.SQRT(data)
Log(ret)
}
import talib
import numpy as np
def main():
data = [4.0, 64.0, 100.0]
ret = talib.SQRT(np.array(data))
Log(ret)
void main() {
std::vector<double> data = {4, 64, 100};
auto ret = talib.SQRT(data);
Log(ret);
}
The SQRT()
function is described in the talib library documentation as: SQRT(Records[Close]) = Array(outReal)
The talib.TAN()
function is used to calculate the Vector Trigonometric Tan (tangent).
The return value of the talib.TAN()
function is a one-dimensional array.
array
talib.TAN(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var data = [-1, 0, 1]
var ret = talib.TAN(data)
Log(ret)
}
import talib
import numpy as np
def main():
data = [-1.0, 0, 1.0]
ret = talib.TAN(np.array(data))
Log(ret)
void main() {
std::vector<double> data = {-1, 0, 1};
auto ret = talib.TAN(data);
Log(ret);
}
The TAN()
function is described in the talib library documentation as: TAN(Records[Close]) = Array(outReal)
The talib.TANH()
function is used to calculate the Vector Trigonometric Tanh (hyperbolic tangent function).
The return value of the talib.TANH()
function is: a one-dimensional array.
array
talib.TANH(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var data = [-1, 0, 1]
var ret = talib.TANH(data)
Log(ret)
}
import talib
import numpy as np
def main():
data = [-1.0, 0, 1.0]
ret = talib.TANH(np.array(data))
Log(ret)
void main() {
std::vector<double> data = {-1, 0, 1};
auto ret = talib.TANH(data);
Log(ret);
}
The TANH()
function is described in the talib library documentation as: TANH(Records[Close]) = Array(outReal)
The talib.MAX()
function is used to calculate the highest (maximum) value for a specific period.
The return value of the talib.MAX()
function is: a one-dimensional array.
array
talib.MAX(inReal) talib.MAX(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MAX(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MAX(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MAX(records);
Log(ret);
}
The MAX()
function is described in the talib library documentation as: MAX(Records[Close],Time Period = 30) = Array(outReal)
The talib.MAXINDEX()
function is used to calculate the index of the highest value in the specified period (maximum index).
The return value of the talib.MAXINDEX()
function is: a one-dimensional array.
array
talib.MAXINDEX(inReal) talib.MAXINDEX(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MAXINDEX(records, 5)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MAXINDEX(records.Close, 5)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MAXINDEX(records, 5);
Log(ret);
}
The MAXINDEX()
function is described in the talib library documentation as: MAXINDEX(Records[Close],Time Period = 30) = Array(outInteger)
The talib.MIN()
function is used to calculate the lowest value (minimum value)** for the specified period.
The return value of the talib.MIN()
function is: a one-dimensional array.
array
talib.MIN(inReal) talib.MIN(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MIN(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MIN(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MIN(records);
Log(ret);
}
The MIN()
function is described in the talib library documentation as: MIN(Records[Close],Time Period = 30) = Array(outReal)
The talib.MININDEX()
function is used to calculate the lowest value index (minimum value index) for the specified period.
The return value of the talib.MININDEX()
function is: a one-dimensional array.
array
talib.MININDEX(inReal) talib.MININDEX(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MININDEX(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MININDEX(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MININDEX(records);
Log(ret);
}
The MININDEX()
function is described in the talib library documentation as: MININDEX(Records[Close],Time Period = 30) = Array(outInteger)
The talib.MINMAX()
function is used to calculate the lowest and highest (minimum and maximum) values for the specified period.
The return value of the talib.MINMAX()
function is a two-dimensional array. The first element of this two-dimensional array is the array of minimum values, and the second element is the array of maximum values.
array
talib.MINMAX(inReal) talib.MINMAX(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MINMAX(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MINMAX(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MINMAX(records);
Log(ret);
}
The MINMAX()
function is described in the talib library documentation as: MINMAX(Records[Close],Time Period = 30) = [Array(outMin),Array(outMax)]
The talib.MINMAXINDEX()
function is used to calculate the index of the lowest and highest (minimum and maximum index) values in the specified period.
The return value of the talib.MINMAXINDEX()
function is: a two-dimensional array. The first element of this two-dimensional array is the minimum indexed array, and the second element is the maximum indexed array.
array
talib.MINMAXINDEX(inReal) talib.MINMAXINDEX(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MINMAXINDEX(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MINMAXINDEX(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MINMAXINDEX(records);
Log(ret);
}
The MINMAXINDEX()
function is described in the talib library documentation as: MINMAXINDEX(Records[Close],Time Period = 30) = [Array(outMinIdx),Array(outMaxIdx)]
The talib.SUM()
function is used to calculate Summation.
The return value of the talib.SUM()
function is: a one-dimensional array.
array
talib.SUM(inReal) talib.SUM(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.SUM(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.SUM(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.SUM(records);
Log(ret);
}
The SUM()
function is described in the talib library documentation as: SUM(Records[Close],Time Period = 30) = Array(outReal)
The talib.HT_DCPERIOD()
function is used to calculate the Hilbert Transform - Dominant Cycle Period (Hilbert Transform, Dominant Period).
The return value of the talib.HT_DCPERIOD()
function is: a one-dimensional array.
array
talib.HT_DCPERIOD(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var records = exchange.GetRecords()
var ret = talib.HT_DCPERIOD(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.HT_DCPERIOD(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.HT_DCPERIOD(records);
Log(ret);
}
The HT_DCPERIOD()
function is described in the talib library documentation as: HT_DCPERIOD(Records[Close]) = Array(outReal)
The talib.HT_DCPHASE()
function is used to calculate the Hilbert Transform - Dominant Cycle Phase (Hilbert Transform, Dominant Cycle Phase).
The return value of the talib.HT_DCPHASE()
function is: a one-dimensional array.
array
talib.HT_DCPHASE(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var records = exchange.GetRecords()
var ret = talib.HT_DCPHASE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.HT_DCPHASE(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.HT_DCPHASE(records);
Log(ret);
}
The HT_DCPHASE()
function is described in the talib library documentation as: HT_DCPHASE(Records[Close]) = Array(outReal)
The talib.HT_PHASOR()
function is used to calculate the Hilbert Transform - Phasor Components (Hilbert Transform, Phase Components).
The return value of the talib.HT_PHASOR()
function is a two-dimensional array.
array
talib.HT_PHASOR(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var records = exchange.GetRecords()
var ret = talib.HT_PHASOR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.HT_PHASOR(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.HT_PHASOR(records);
Log(ret);
}
The HT_PHASOR()
function is described in the talib library documentation as: HT_PHASOR(Records[Close]) = [Array(outInPhase),Array(outQuadrature)]
The talib.HT_SINE()
function is used to calculate the Hilbert Transform - SineWave (Hilbert Transform, Sine Wave).
The return value of the talib.HT_SINE()
function is: a two-dimensional array.
array
talib.HT_SINE(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var records = exchange.GetRecords()
var ret = talib.HT_SINE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.HT_SINE(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.HT_SINE(records);
Log(ret);
}
The HT_SINE()
function is described in the talib library documentation as: HT_SINE(Records[Close]) = [Array(outSine),Array(outLeadSine)]
The talib.HT_TRENDMODE()
function is used to calculate the Hilbert Transform - Trend and Cycle Mode.
The return value of the talib.HT_TRENDMODE()
function is: a one-dimensional array.
array
talib.HT_TRENDMODE(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var records = exchange.GetRecords()
var ret = talib.HT_TRENDMODE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.HT_TRENDMODE(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.HT_TRENDMODE(records);
Log(ret);
}
The HT_TRENDMODE()
function is described in the talib library documentation as: HT_TRENDMODE(Records[Close]) = Array(outInteger)
The talib.ATR()
function is used to calculate the Average True Range.
The return value of the talib.ATR()
function is a one-dimensional array.
array
talib.ATR(inPriceHLC) talib.ATR(inPriceHLC, optInTimePeriod)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.ATR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.ATR(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ATR(records);
Log(ret);
}
The ATR()
function is described in the talib library documentation as: ATR(Records[High,Low,Close],Time Period = 14) = Array(outReal)
The talib.NATR()
function is used to calculate the Normalized Average True Range.
The return value of the talib.NATR()
function is a one-dimensional array.
array
talib.NATR(inPriceHLC) talib.NATR(inPriceHLC, optInTimePeriod)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.NATR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.NATR(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.NATR(records);
Log(ret);
}
The NATR()
function is described in the talib library documentation as: NATR(Records[High,Low,Close],Time Period = 14) = Array(outReal)
The talib.TRANGE()
function is used to calculate the True Range.
The return value of the talib.TRANGE()
function is: a one-dimensional array.
array
talib.TRANGE(inPriceHLC)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.TRANGE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.TRANGE(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.TRANGE(records);
Log(ret);
}
The TRANGE()
function is described in the talib library documentation as: TRANGE(Records[High,Low,Close]) = Array(outReal)
The talib.BBANDS()
function is used to calculate Bollinger Bands.
The return value of the talib.BBANDS()
function is: a two-dimensional array. The array contains three elements which are: the upper line array, the middle line array, and the lower line array.
array
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)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 5.
optInTimePeriod
false
number
The optInNbDevUp
parameter is used to set the upline multiplier, the default value is 2.
optInNbDevUp
false
number
The optInNbDevDn
parameter is used to set the lower line multiplier, the default value is 2.
optInNbDevDn
false
number
The optInMAType
parameter is used to set the mean type, the default value is 0.
optInMAType
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.BBANDS(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.BBANDS(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.BBANDS(records);
Log(ret);
}
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)]
The talib.DEMA()
function is used to calculate the Double Exponential Moving Average.
The return value of the talib.DEMA()
function is a one-dimensional array.
array
talib.DEMA(inReal) talib.DEMA(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.DEMA(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.DEMA(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.DEMA(records);
Log(ret);
}
The DEMA()
function is described in the talib library documentation as: DEMA(Records[Close],Time Period = 30) = Array(outReal)
The talib.EMA()
function is used to calculate the Exponential Moving Average.
The return value of the talib.EMA()
function is a one-dimensional array.
array
talib.EMA(inReal) talib.EMA(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.EMA(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.EMA(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.EMA(records);
Log(ret);
}
The EMA()
function is described in the talib library documentation as: EMA(Records[Close],Time Period = 30) = Array(outReal)
The talib.HT_TRENDLINE()
function is used to calculate the Hilbert Transform - Instantaneous Trendline (Hilbert Transform, Instantaneous Trend).
The return value of the talib.HT_TRENDLINE()
function is: a one-dimensional array.
array
talib.HT_TRENDLINE(inReal)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
function main() {
var records = exchange.GetRecords()
var ret = talib.HT_TRENDLINE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.HT_TRENDLINE(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.HT_TRENDLINE(records);
Log(ret);
}
The HT_TRENDLINE()
function is described in the talib library documentation as: HT_TRENDLINE(Records[Close]) = Array(outReal)
The talib.KAMA()
function is used to calculate the Kaufman Adaptive Moving Average.
The return value of the talib.KAMA()
function is: a one-dimensional array.
array
talib.KAMA(inReal) talib.KAMA(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.KAMA(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.KAMA(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.KAMA(records);
Log(ret);
}
The KAMA()
function is described in the talib library documentation as: KAMA(Records[Close],Time Period = 30) = Array(outReal)
The talib.MA()
function is used to calculate the Moving average.
The return value of the talib.MA()
function is: a one-dimensional array.
array
talib.MA(inReal) talib.MA(inReal, optInTimePeriod) talib.MA(inReal, optInTimePeriod, optInMAType)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
The optInMAType
parameter is used to set the mean type, the default value is 0.
optInMAType
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MA(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MA(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MA(records);
Log(ret);
}
The MA()
function is described in the talib library documentation as: MA(Records[Close],Time Period = 30,MA Type = 0) = Array(outReal)
The talib.MAMA()
function is used to calculate the MESA Adaptive Moving Average.
The return value of the talib.MAMA()
function is: a two-dimensional array.
array
talib.MAMA(inReal) talib.MAMA(inReal, optInFastLimit) talib.MAMA(inReal, optInFastLimit, optInSlowLimit)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInFastLimit
parameter is used to set the Fast Limit, the default value is 0.5.
optInFastLimit
false
number
The optInSlowLimit
parameter is used to set the Slow Limit, the default value is 0.05.
optInSlowLimit
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MAMA(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MAMA(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MAMA(records);
Log(ret);
}
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)]
The talib.MIDPOINT()
function is used to calculate the MidPoint over period (midpoint).
The return value of the talib.MIDPOINT()
function is a one-dimensional array.
array
talib.MIDPOINT(inReal) talib.MIDPOINT(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MIDPOINT(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MIDPOINT(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MIDPOINT(records);
Log(ret);
}
The MIDPOINT()
function is described in the talib library documentation as: MIDPOINT(Records[Close],Time Period = 14) = Array(outReal)
The talib.MIDPRICE()
function is used to calculate the Midpoint Price over period (midpoint price).
The return value of the talib.MIDPRICE()
function is a one-dimensional array.
array
talib.MIDPRICE(inPriceHL) talib.MIDPRICE(inPriceHL, optInTimePeriod)
The inPriceHL
parameter is used to specify the K-line data.
inPriceHL
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MIDPRICE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MIDPRICE(records.High, records.Low)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MIDPRICE(records);
Log(ret);
}
The MIDPRICE()
function is described in the talib library documentation as: MIDPRICE(Records[High,Low],Time Period = 14) = Array(outReal)
The talib.SAR()
function is used to calculate the Parabolic SAR.
The return value of the talib.SAR()
function is: a one-dimensional array.
array
talib.SAR(inPriceHL) talib.SAR(inPriceHL, optInAcceleration) talib.SAR(inPriceHL, optInAcceleration, optInMaximum)
The inPriceHL
parameter is used to specify the K-line data.
inPriceHL
true
{@struct/Record Record} structure array
The optInAcceleration
parameter is used to set the Acceleration Factor, the default value is 0.02.
optInAcceleration
false
number
The optInMaximum
parameter is used to set the AF Maximum, the default value is 0.2.
optInMaximum
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.SAR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.SAR(records.High, records.Low)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.SAR(records);
Log(ret);
}
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)
The talib.SAREXT()
function is used to calculate the Parabolic SAR - Extended (enhanced parabolic steering).
The return value of the talib.SAREXT()
function is a one-dimensional array.
array
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)
The inPriceHL
parameter is used to specify the K-line data.
inPriceHL
true
{@struct/Record Record} structure array
The optInStartValue
parameter is used to set the Start Value, the default value is 0.
optInStartValue
false
number
The optInOffsetOnReverse
parameter is used to set Offset on Reverse, the default value is 0.
optInOffsetOnReverse
false
number
The optInAccelerationInitLong
parameter is used to set the AF Init Long, the default value is 0.02.
optInAccelerationInitLong
false
number
The optInAccelerationLong
parameter is used to set the AF Long, the default value is 0.02.
optInAccelerationLong
false
number
The optInAccelerationMaxLong
parameter is used to set the AF Max Long, the default value is 0.2.
optInAccelerationMaxLong
false
number
The optInAccelerationInitShort
parameter is used to set AF Init Short, the default value is 0.02.
optInAccelerationInitShort
false
number
The optInAccelerationShort
parameter is used to set AF Short, the default value is 0.02.
optInAccelerationShort
false
number
The optInAccelerationMaxShort
parameter is used to set AF Max Short, the default value is 0.2.
optInAccelerationMaxShort
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.SAREXT(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.SAREXT(records.High, records.Low)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.SAREXT(records);
Log(ret);
}
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)
The talib.SMA()
function is used to calculate Simple Moving Average.
The return value of the talib.SMA()
function is: a one-dimensional array.
array
talib.SMA(inReal) talib.SMA(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.SMA(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.SMA(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.SMA(records);
Log(ret);
}
The SMA()
function is described in the talib library documentation as: SMA(Records[Close],Time Period = 30) = Array(outReal)
The talib.T3()
function is used to calculate the Triple Exponential Moving Average (T3) (triple exponential moving average).
The return value of the talib.T3()
function is a one-dimensional array.
array
talib.T3(inReal) talib.T3(inReal, optInTimePeriod) talib.T3(inReal, optInTimePeriod, optInVFactor)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 5.
optInTimePeriod
false
number
The optInVFactor
parameter is used to set the Volume Factor, the default value is 0.7.
optInVFactor
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.T3(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.T3(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.T3(records);
Log(ret);
}
The T3()
function is described in the talib library documentation as: T3(Records[Close],Time Period = 5,Volume Factor = 0.7) = Array(outReal)
The talib.TEMA()
function is used to calculate Triple Exponential Moving Average.
The return value of the talib.TEMA()
function is a one-dimensional array.
array
talib.TEMA(inReal) talib.TEMA(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.TEMA(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.TEMA(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.TEMA(records);
Log(ret);
}
The TEMA()
function is described in the talib library documentation as: TEMA(Records[Close],Time Period = 30) = Array(outReal)
The talib.TRIMA()
function is used to calculate the Triangular Moving Average (tri-exponential moving average).
The return value of the talib.TRIMA()
function is a one-dimensional array.
array
talib.TRIMA(inReal) talib.TRIMA(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.TRIMA(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.TRIMA(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.TRIMA(records);
Log(ret);
}
The TRIMA()
function is described in the talib library documentation as: TRIMA(Records[Close],Time Period = 30) = Array(outReal)
The talib.WMA()
function is used to calculate the Weighted Moving Average (WMA).
The return value of the talib.WMA()
function is a one-dimensional array.
array
talib.WMA(inReal) talib.WMA(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.WMA(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.WMA(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.WMA(records);
Log(ret);
}
The WMA()
function is described in the talib library documentation as: WMA(Records[Close],Time Period = 30) = Array(outReal)
The talib.LINEARREG()
function is used to calculate Linear Regression.
The return value of the talib.LINEARREG()
function is a one-dimensional array.
array
talib.LINEARREG(inReal) talib.LINEARREG(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.LINEARREG(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.LINEARREG(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.LINEARREG(records);
Log(ret);
}
The LINEARREG()
function is described in the talib library documentation as: LINEARREG(Records[Close],Time Period = 14) = Array(outReal)
The talib.LINEARREG_ANGLE()
function is used to calculate the Linear Regression Angle.
The return value of the talib.LINEARREG_ANGLE()
function is: a one-dimensional array.
array
talib.LINEARREG_ANGLE(inReal) talib.LINEARREG_ANGLE(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.LINEARREG_ANGLE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.LINEARREG_ANGLE(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.LINEARREG_ANGLE(records);
Log(ret);
}
The LINEARREG_ANGLE()
function is described in the talib library documentation as: LINEARREG_ANGLE(Records[Close],Time Period = 14) = Array(outReal)
The talib.LINEARREG_INTERCEPT()
function is used to calculate the Linear Regression Intercept.
The return value of the talib.LINEARREG_INTERCEPT()
function is: a one-dimensional array.
array
talib.LINEARREG_INTERCEPT(inReal) talib.LINEARREG_INTERCEPT(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.LINEARREG_INTERCEPT(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.LINEARREG_INTERCEPT(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.LINEARREG_INTERCEPT(records);
Log(ret);
}
The LINEARREG_INTERCEPT()
function is described in the talib library documentation as: LINEARREG_INTERCEPT(Records[Close],Time Period = 14) = Array(outReal)
The talib.LINEARREG_SLOPE()
function is used to calculate the Linear Regression Slope.
The return value of the talib.LINEARREG_SLOPE()
function is: a one-dimensional array.
array
talib.LINEARREG_SLOPE(inReal) talib.LINEARREG_SLOPE(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.LINEARREG_SLOPE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.LINEARREG_SLOPE(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.LINEARREG_SLOPE(records);
Log(ret);
}
The LINEARREG_SLOPE()
function is described in the talib library documentation as: LINEARREG_SLOPE(Records[Close],Time Period = 14) = Array(outReal)
The talib.STDDEV()
function is used to calculate Standard Deviation.
The return value of the talib.STDDEV()
function is: a one-dimensional array.
array
talib.STDDEV(inReal) talib.STDDEV(inReal, optInTimePeriod) talib.STDDEV(inReal, optInTimePeriod, optInNbDev)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 5.
optInTimePeriod
false
number
The optInNbDev
parameter is used to set the Deviations, the default value is 1.
optInNbDev
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.STDDEV(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.STDDEV(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.STDDEV(records);
Log(ret);
}
The STDDEV()
function is described in the talib library documentation as: STDDEV(Records[Close],Time Period = 5,Deviations = 1) = Array(outReal)
The talib.TSF()
function is used to calculate Time Series Forecast.
The return value of the talib.TSF()
function is a one-dimensional array.
array
talib.TSF(inReal) talib.TSF(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.TSF(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.TSF(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.TSF(records);
Log(ret);
}
The TSF()
function is described in the talib library documentation as: TSF(Records[Close],Time Period = 14) = Array(outReal)
The talib.VAR()
function is used to calculate Variance.
The return value of the talib.VAR()
function is: a one-dimensional array.
array
talib.VAR(inReal) talib.VAR(inReal, optInTimePeriod) talib.VAR(inReal, optInTimePeriod, optInNbDev)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 5.
optInTimePeriod
false
number
The optInNbDev
parameter is used to set the Deviations, the default value is 1.
optInNbDev
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.VAR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.VAR(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.VAR(records);
Log(ret);
}
The VAR()
function is described in the talib library documentation as: VAR(Records[Close],Time Period = 5,Deviations = 1) = Array(outReal)
The talib.ADX()
function is used to calculate the Average Directional Movement Index.
The return value of the talib.ADX()
function is a one-dimensional array.
array
talib.ADX(inPriceHLC) talib.ADX(inPriceHLC, optInTimePeriod)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.ADX(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.ADX(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ADX(records);
Log(ret);
}
The ADX()
function is described in the talib library documentation as: ADX(Records[High,Low,Close],Time Period = 14) = Array(outReal)
The talib.ADXR()
function is used to calculate the Average Directional Movement Index Rating (assessment index).
The return value of the talib.ADXR()
function is a one-dimensional array.
array
talib.ADXR(inPriceHLC) talib.ADXR(inPriceHLC, optInTimePeriod)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.ADXR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.ADXR(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ADXR(records);
Log(ret);
}
The ADXR()
function is described in the talib library documentation as: ADXR(Records[High,Low,Close],Time Period = 14) = Array(outReal)
The talib.APO()
function is used to calculate the Absolute Price Oscillator.
The return value of the talib.APO()
function is: a one-dimensional array.
array
talib.APO(inReal) talib.APO(inReal, optInFastPeriod) talib.APO(inReal, optInFastPeriod, optInSlowPeriod) talib.APO(inReal, optInFastPeriod, optInSlowPeriod, optInMAType)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInFastPeriod
parameter is used to set the fast period, the default value is 12.
optInFastPeriod
false
number
The optInSlowPeriod
parameter is used to set the slow period, the default value is 26.
optInSlowPeriod
false
number
The optInMAType
parameter is used to set the mean type, the default value is 0.
optInMAType
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.APO(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.APO(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.APO(records);
Log(ret);
}
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)
The talib.AROON()
function is used to calculate the Aroon (Aroon indicator).
The return value of the talib.AROON()
function is a two-dimensional array.
array
talib.AROON(inPriceHL) talib.AROON(inPriceHL, optInTimePeriod)
The inPriceHL
parameter is used to specify the K-line data.
inPriceHL
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.AROON(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.AROON(records.High, records.Low)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.AROON(records);
Log(ret);
}
The AROON()
function is described in the talib library documentation as: AROON(Records[High,Low],Time Period = 14) = [Array(outAroonDown),Array(outAroonUp)]
The talib.AROONOSC()
function is used to calculate the Aroon Oscillator.
The return value of the talib.AROONOSC()
function is: a one-dimensional array.
array
talib.AROONOSC(inPriceHL) talib.AROONOSC(inPriceHL, optInTimePeriod)
The inPriceHL
parameter is used to specify the K-line data.
inPriceHL
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.AROONOSC(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.AROONOSC(records.High, records.Low)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.AROONOSC(records);
Log(ret);
}
The AROONOSC()
function is described in the talib library documentation as: AROONOSC(Records[High,Low],Time Period = 14) = Array(outReal)
The talib.BOP()
function is used to calculate the Balance Of Power.
The return value of the talib.BOP()
function is a one-dimensional array.
array
talib.BOP(inPriceOHLC)
The inPriceOHLC
parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.BOP(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.BOP(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.BOP(records);
Log(ret);
}
The BOP()
function is described in the talib library documentation as: BOP(Records[Open,High,Low,Close]) = Array(outReal)
The talib.CCI()
function is used to calculate the Commodity Channel Index (homeopathic indicator).
The return value of the talib.CCI()
function is a one-dimensional array.
array
talib.CCI(inPriceHLC) talib.CCI(inPriceHLC, optInTimePeriod)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.CCI(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CCI(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CCI(records);
Log(ret);
}
The CCI()
function is described in the talib library documentation as: CCI(Records[High,Low,Close],Time Period = 14) = Array(outReal)
The talib.CMO()
function is used to calculate the Chande Momentum Oscillator (CMO).
The return value of the talib.CMO()
function is: a one-dimensional array.
array
talib.CMO(inReal) talib.CMO(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.CMO(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.CMO(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.CMO(records);
Log(ret);
}
The CMO()
function is described in the talib library documentation as: CMO(Records[Close],Time Period = 14) = Array(outReal)
The talib.DX()
function is used to calculate the Directional Movement Index.
The return value of the talib.DX()
function is: a one-dimensional array.
array
talib.DX(inPriceHLC) talib.DX(inPriceHLC, optInTimePeriod)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.DX(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.DX(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.DX(records);
Log(ret);
}
The DX()
function is described in the talib library documentation as: DX(Records[High,Low,Close],Time Period = 14) = Array(outReal)
The talib.MACD()
function is used to calculate Moving Average Convergence/Divergence (exponentially smoothed moving average).
The return value of the talib.MACD()
function is: a two-dimensional array.
array
talib.MACD(inReal) talib.MACD(inReal, optInFastPeriod) talib.MACD(inReal, optInFastPeriod, optInSlowPeriod) talib.MACD(inReal, optInFastPeriod, optInSlowPeriod, optInSignalPeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInFastPeriod
parameter is used to set the fast period, the default value is 12.
optInFastPeriod
false
number
The optInSlowPeriod
parameter is used to set the slow period, the default value is 26.
optInSlowPeriod
false
number
The optInSignalPeriod
parameter is used to set the signal period, the default value is 9.
optInSignalPeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MACD(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MACD(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MACD(records);
Log(ret);
}
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)]
The talib.MACDEXT()
function is used to calculate MACD with controllable MA type.
The return value of the talib.MACDEXT()
function is a two-dimensional array.
array
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)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInFastPeriod
parameter is used to set the fast period, the default value is 12.
optInFastPeriod
false
number
The optInFastMAType
parameter is used to set the fast average type, the default value is 0.
optInFastMAType
false
number
The optInSlowPeriod
parameter is used to set the slow period, the default value is 26.
optInSlowPeriod
false
number
The optInSlowMAType
parameter is used to set the slow mean type, the default value is 0.
optInSlowMAType
false
number
The optInSignalPeriod
parameter is used to set the signal period, the default value is 9.
optInSignalPeriod
false
number
The optInSignalMAType
parameter is used to set the signal mean type, the default value is 0.
optInSignalMAType
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MACDEXT(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MACDEXT(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MACDEXT(records);
Log(ret);
}
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)]
The talib.MACDFIX()
function is used to calculate Moving Average Convergence/Divergence Fix 12/26.
The return value of the talib.MACDFIX()
function is a two-dimensional array.
array
talib.MACDFIX(inReal) talib.MACDFIX(inReal, optInSignalPeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInSignalPeriod
parameter is used to set the signal period, the default value is 9.
optInSignalPeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MACDFIX(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MACDFIX(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MACDFIX(records);
Log(ret);
}
The MACDFIX()
function is described in the talib library documentation as: MACDFIX(Records[Close],Signal Period = 9) = [Array(outMACD),Array(outMACDSignal),Array(outMACDHist)]
The talib.MFI()
function is used to calculate the Money Flow Index.
The return value of the talib.MFI()
function is a one-dimensional array.
array
talib.MFI(inPriceHLCV) talib.MFI(inPriceHLCV, optInTimePeriod)
The inPriceHLCV
parameter is used to specify the K-line data.
inPriceHLCV
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MFI(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MFI(records.High, records.Low, records.Close, records.Volume)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MFI(records);
Log(ret);
}
The MFI()
function is described in the talib library documentation as: MFI(Records[High,Low,Close,Volume],Time Period = 14) = Array(outReal)
The talib.MINUS_DI()
function is used to calculate the Minus Directional Indicator (negative indicator).
The return value of the talib.MINUS_DI()
function is a one-dimensional array.
array
talib.MINUS_DI(inPriceHLC) talib.MINUS_DI(inPriceHLC, optInTimePeriod)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MINUS_DI(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MINUS_DI(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MINUS_DI(records);
Log(ret);
}
The MINUS_DI()
function is described in the talib library documentation as: MINUS_DI(Records[High,Low,Close],Time Period = 14) = Array(outReal)
The talib.MINUS_DM()
function is used to calculate the Minus Directional Movement (negative motion).
The return value of the talib.MINUS_DM()
function is a one-dimensional array.
array
talib.MINUS_DM(inPriceHL) talib.MINUS_DM(inPriceHL, optInTimePeriod)
The inPriceHL
parameter is used to specify the K-line data.
inPriceHL
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MINUS_DM(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MINUS_DM(records.High, records.Low)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MINUS_DM(records);
Log(ret);
}
The MINUS_DM()
function is described in the talib library documentation as: MINUS_DM(Records[High,Low],Time Period = 14) = Array(outReal)
The talib.MOM()
function is used to calculate Momentum.
The return value of the talib.MOM()
function is a one-dimensional array.
array
talib.MOM(inReal) talib.MOM(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 10.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.MOM(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MOM(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MOM(records);
Log(ret);
}
The MOM()
function is described in the talib library documentation as: MOM(Records[Close],Time Period = 10) = Array(outReal)
The talib.PLUS_DI()
function is used to calculate the Plus Directional Indicator.
The return value of the talib.PLUS_DI()
function is: a one-dimensional array.
array
talib.PLUS_DI(inPriceHLC) talib.PLUS_DI(inPriceHLC, optInTimePeriod)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.PLUS_DI(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.PLUS_DI(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.PLUS_DI(records);
Log(ret);
}
The PLUS_DI()
function is described in the talib library documentation as: PLUS_DI(Records[High,Low,Close],Time Period = 14) = Array(outReal)
The talib.PLUS_DM()
function is used to calculate Plus Directional Movement.
The return value of the talib.PLUS_DM()
function is a one-dimensional array.
array
talib.PLUS_DM(inPriceHL) talib.PLUS_DM(inPriceHL, optInTimePeriod)
The inPriceHL
parameter is used to specify the K-line data.
inPriceHL
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.PLUS_DM(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.PLUS_DM(records.High, records.Low)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.PLUS_DM(records);
Log(ret);
}
The PLUS_DM()
function is described in the talib library documentation as: PLUS_DM(Records[High,Low],Time Period = 14) = Array(outReal)
The talib.PPO()
function is used to calculate the Percentage Price Oscillator.
The return value of the talib.PPO()
function is a one-dimensional array.
array
talib.PPO(inReal) talib.PPO(inReal, optInFastPeriod) talib.PPO(inReal, optInFastPeriod, optInSlowPeriod) talib.PPO(inReal, optInFastPeriod, optInSlowPeriod, optInMAType)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInFastPeriod
parameter is used to set the fast period, the default value is 12.
optInFastPeriod
false
number
The optInSlowPeriod
parameter is used to set the slow period, the default value is 26.
optInSlowPeriod
false
number
The optInMAType
parameter is used to set the mean type, the default value is 0.
optInMAType
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.PPO(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.PPO(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.PPO(records);
Log(ret);
}
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)
The talib.ROC()
function is used to calculate Rate of change : ((price/prevPrice)-1)*100 (rate of change indicator).
The return value of the talib.ROC()
function is a one-dimensional array.
array
talib.ROC(inReal) talib.ROC(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 10.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.ROC(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.ROC(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ROC(records);
Log(ret);
}
The ROC()
function is described in the talib library documentation as: ROC(Records[Close],Time Period = 10) = Array(outReal)
The talib.ROCP()
function is used to calculate Rate of change Percentage: (price-prevPrice)/prevPrice (rate of price change).
The return value of the talib.ROCP()
function is: a one-dimensional array.
array
talib.ROCP(inReal) talib.ROCP(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 10.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.ROCP(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.ROCP(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ROCP(records);
Log(ret);
}
The ROCP()
function is described in the talib library documentation as: ROCP(Records[Close],Time Period = 10) = Array(outReal)
The talib.ROCR()
function is used to calculate the Rate of change ratio: (price/prevPrice) (price change ratio).
The return value of the talib.ROCR()
function is a one-dimensional array.
array
talib.ROCR(inReal) talib.ROCR(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 10.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.ROCR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.ROCR(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ROCR(records);
Log(ret);
}
The ROCR()
function is described in the talib library documentation as: ROCR(Records[Close],Time Period = 10) = Array(outReal)
The talib.ROCR100()
function is used to calculate Rate of change ratio 100 scale: (price/prevPrice)*100 (price change ratio).
The return value of the talib.ROCR100()
function is: a one-dimensional array.
array
talib.ROCR100(inReal) talib.ROCR100(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 10.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.ROCR100(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.ROCR100(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ROCR100(records);
Log(ret);
}
The ROCR100()
function is described in the talib library documentation as: ROCR100(Records[Close],Time Period = 10) = Array(outReal)
The talib.RSI()
function is used to calculate the Relative Strength Index.
The return value of the talib.RSI()
function is a one-dimensional array.
array
talib.RSI(inReal) talib.RSI(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.RSI(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.RSI(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.RSI(records);
Log(ret);
}
The RSI()
function is described in the talib library documentation as: RSI(Records[Close],Time Period = 14) = Array(outReal)
The talib.STOCH()
function is used to calculate the Stochastic (STOCH indicator).
The return value of the talib.STOCH()
function is a two-dimensional array.
array
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)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
The optInFastK_Period
parameter is used to set the Fast-K period, the default value is 5.
optInFastK_Period
false
number
The optInSlowK_Period
parameter is used to set the Slow-K period, the default value is 3.
optInSlowK_Period
false
number
The optInSlowK_MAType
parameter is used to set the Slow-K average type, the default value is 0.
optInSlowK_MAType
false
number
The optInSlowD_Period
parameter is used to set the Slow-D period, the default value is 3.
optInSlowD_Period
false
number
The optInSlowD_MAType
parameter is used to set the Slow-D average type, the default value is 0.
optInSlowD_MAType
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.STOCH(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.STOCH(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.STOCH(records);
Log(ret);
}
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)]
The talib.STOCHF()
function is used to calculate the Stochastic Fast (fast STOCH indicator).
The return value of the talib.STOCHF()
function is a two-dimensional array.
array
talib.STOCHF(inPriceHLC) talib.STOCHF(inPriceHLC, optInFastK_Period) talib.STOCHF(inPriceHLC, optInFastK_Period, optInFastD_Period) talib.STOCHF(inPriceHLC, optInFastK_Period, optInFastD_Period, optInFastD_MAType)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
The optInFastK_Period
parameter is used to set the Fast-K period, the default value is 5.
optInFastK_Period
false
number
The optInFastD_Period
parameter is used to set the Fast-D period, the default value is 3.
optInFastD_Period
false
number
The optInFastD_MAType
parameter is used to set the Fast-D average type, the default value is 0.
optInFastD_MAType
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.STOCHF(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.STOCHF(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.STOCHF(records);
Log(ret);
}
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)]
The talib.STOCHRSI()
function is used to calculate the Stochastic Relative Strength Index.
The return value of the talib.STOCHRSI()
function is: a two-dimensional array.
array
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)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
The optInFastK_Period
parameter is used to set the Fast-K period, the default value is 5.
optInFastK_Period
false
number
The optInFastD_Period
parameter is used to set the Fast-D period, the default value is 3.
optInFastD_Period
false
number
The optInFastD_MAType
parameter is used to set the Fast-D average type, the default value is 0.
optInFastD_MAType
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.STOCHRSI(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.STOCHRSI(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.STOCHRSI(records);
Log(ret);
}
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)]
The talib.TRIX()
function is used to calculate the 1-day Rate-Of-Change (ROC) of a Triple Smooth EMA.
The return value of the talib.TRIX()
function is: a one-dimensional array.
array
talib.TRIX(inReal) talib.TRIX(inReal, optInTimePeriod)
The inReal
parameter is used to specify the K-line data.
inReal
true
{@struct/Record Record} structure arrays, numeric arrays
The optInTimePeriod
parameter is used to set the period, the default value is 30.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.TRIX(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.TRIX(records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.TRIX(records);
Log(ret);
}
The TRIX()
function is described in the talib library documentation as: TRIX(Records[Close],Time Period = 30) = Array(outReal)
The talib.ULTOSC()
function is used to calculate the Ultimate Oscillator.
The return value of the talib.ULTOSC()
function is a one-dimensional array.
array
talib.ULTOSC(inPriceHLC) talib.ULTOSC(inPriceHLC, optInTimePeriod1) talib.ULTOSC(inPriceHLC, optInTimePeriod1, optInTimePeriod2) talib.ULTOSC(inPriceHLC, optInTimePeriod1, optInTimePeriod2, optInTimePeriod3)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
The optInTimePeriod1
parameter is used to set the first period, the default value is 7.
optInTimePeriod1
false
number
The optInTimePeriod2
parameter is used to set the second period, the default value is 14.
optInTimePeriod2
false
number
The optInTimePeriod3
parameter is used to set the third period, the default value is 28.
optInTimePeriod3
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.ULTOSC(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.ULTOSC(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.ULTOSC(records);
Log(ret);
}
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)
The talib.WILLR()
function is used to calculate Williams’ %R.
The return value of the talib.WILLR()
function is: a one-dimensional array.
array
talib.WILLR(inPriceHLC) talib.WILLR(inPriceHLC, optInTimePeriod)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
The optInTimePeriod
parameter is used to set the period, the default value is 14.
optInTimePeriod
false
number
function main() {
var records = exchange.GetRecords()
var ret = talib.WILLR(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.WILLR(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.WILLR(records);
Log(ret);
}```
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**.
The return value of the ```talib.AVGPRICE()``` function is a one-dimensional array.
array
talib.AVGPRICE(inPriceOHLC)
The ```inPriceOHLC``` parameter is used to specify the K-line data.
inPriceOHLC
true
{@struct/Record Record} structure array
```javascript
function main() {
var records = exchange.GetRecords()
var ret = talib.AVGPRICE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.AVGPRICE(records.Open, records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.AVGPRICE(records);
Log(ret);
}
The AVGPRICE()
function is described in the talib library documentation as: AVGPRICE(Records[Open,High,Low,Close]) = Array(outReal)
The talib.MEDPRICE()
function is used to calculate the Median Price.
The return value of the talib.MEDPRICE()
function is a one-dimensional array.
array
talib.MEDPRICE(inPriceHL)
The inPriceHL
parameter is used to specify the K-line data.
inPriceHL
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.MEDPRICE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.MEDPRICE(records.High, records.Low)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.MEDPRICE(records);
Log(ret);
}
The MEDPRICE()
function is described in the talib library documentation as: MEDPRICE(Records[High,Low]) = Array(outReal)
The talib.TYPPRICE()
function is used to calculate Typical Price.
The return value of the talib.TYPPRICE()
function is a one-dimensional array.
array
talib.TYPPRICE(inPriceHLC)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.TYPPRICE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.TYPPRICE(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.TYPPRICE(records);
Log(ret);
}
The TYPPRICE()
function is described in the talib library documentation as: TYPPRICE(Records[High,Low,Close]) = Array(outReal)
The talib.WCLPRICE()
function is used to calculate the Weighted Close Price.
The return value of the talib.WCLPRICE()
function is a one-dimensional array.
array
talib.WCLPRICE(inPriceHLC)
The inPriceHLC
parameter is used to specify the K-line data.
inPriceHLC
true
{@struct/Record Record} structure array
function main() {
var records = exchange.GetRecords()
var ret = talib.WCLPRICE(records)
Log(ret)
}
import talib
def main():
records = exchange.GetRecords()
ret = talib.WCLPRICE(records.High, records.Low, records.Close)
Log(ret)
void main() {
auto records = exchange.GetRecords();
auto ret = talib.WCLPRICE(records);
Log(ret);
}
The WCLPRICE()
function is described in the talib library documentation as: WCLPRICE(Records[High,Low,Close]) = Array(outReal)