The underlying system has a variable to record the interactive command. When the GetCommand() function is called, the interactive command will be taken out (if there is no interactive command, return null), and the variable content of the underlying system will be emptied. When GetCommand() is not called, the new interactive command in the underlying system will overwrite the old interactive command. For example, when the strategy program is processing an interactively triggered strategy code segment, if there are multiple interactive commands sent from the strategy interface at this time, if the strategy is still executing a certain section of code at this time, when the strategy again GetCommand() At this time, only the last interactive command can be obtained.

Examples of using interactive controls, set interactive controls on the strategy editing interface.

At the normal address: wss://real.okex.com:10441/websocket?Compress separated by the “|” symbol, if there are | characters in the parameter string, Then use “||” as the delimiter. Connect each parameter with “&”, for example, ss5 proxy and compression parameters are set together: Dial(“wss://baidu.com/stream|proxy=socks5://xxx:9999&compress=gzip_raw&mode=recv”)

compress is the compression method, compress parameter, optional gzip_raw, gzip, etc. OKEX’s gzip method is non-standard gzip. So you need to use the extension method: gzip_raw, that is, add the setting compress=gzip_raw after the separator “|”, and use the “&” symbol and the next mode parameter to separate.

“mode” is the mode, and dual, send, recv are optional. dual is bidirectional, sending compressed data and receiving compressed data. send is to send compressed data. Recv is to receive compressed data and decompress it locally.

When used in the WS protocol, set the underlying auto-reconnect related parameters: reconnect=parameter value

“reconnect” is whether to set reconnect, reconnect=true is to enable reconnect, the default setting is not to reconnect

When used in the ws protocol, set 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, and the default setting is 1 second, that is, interval=1000

When used in the ws protocol, set the underlying auto-reconnect related parameters: payload=parameter value

“payload” is the subscription message to be sent when ws reconnects, for example: payload=okok

function main(){
// Dial supports tcp://, udp://, tls://, unix:// protocol, you can add a parameter to specify the number of seconds to 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 to specify the timeout, in milliseconds. Return null to indicate error or timeout or socket has been closed
var buf = client.read()
if (!buf) {
break
}
Log(buf)
}
client.close()
}
}

Not passing parameters means blocking until there is a message, such as ws.read().

Milliseconds specify the message wait timeout, such as ws.read(2000) specifies the timeout to be two seconds.

The following two parameters are only valid for websocket:
-1 means to return immediately regardless of whether there is any message, such as ws.read(-1).
-2 means to return immediately regardless of whether there is any message, but only the latest message is returned, and the message in the buffer is discarded as ws.read(-2).

read() function buffer description:
If the data pushed by the ws protocol is too long between the strategy read() function calls, it may cause data accumulation, and these data are stored in the buffer. The buffer data structure is a queue, with an upper limit of 2000. After exceeding 2000, the latest data enters the buffer, and the oldest data is cleared.

read function parameter:

no parameter

parameter: -1

parameter: -2

parameter: 2000, unit is ms

Buffer already has data

Return the oldest data immediately

Return the oldest data immediately

Return the latest data immediately

Return the oldest data immediately

No data in the buffer

Return when there is data blocked

Return null immediately

Return null immediately

Wait for 2000ms, return null if there is no data, return if there is data

ws connection is disconnected, when the bottom layer is reconnected

the read() function returns an empty string, that is: “”, the write() function returns 0. If this situation is detected, the close() function can be used to close the connection. If set to reconnect automatically, it won’t need to close. the bottom layer of the system will automatically reconnect.

#### HttpQuery(...)
```HttpQuery(Url, PostData, Cookies, Headers, IsReturnHeader)```Web URL access. Parameter value: both are of type string.
Note:
* The ```HttpQuery(...)``` function only supports **JavaScript** language.
* For the **Python** language, you can use the **urllib** library to directly send http requests.
```HttpQuery(...)``` is mainly used to access connections that do not require signatures on the exchange, such as public interfaces and market information. An example of an API that does not require a signature to access OKEX: the return value is a JSON string, which can be parsed using the ```JSON.parse()``` function.
```js
function main(){
// An example of GET access without parameters
var info = JSON.parse(HttpQuery("https://www.okex.com/api/spot/v3/instruments"))
Log(info)
// An example of GET access with parameters
var ticker = JSON.parse(HttpQuery("https://www.okex.com/api/spot/v3/instruments/BTC-USDT/book?size=5&depth=0.2"))
Log(ticker)
}

Get the return content of a Url, if the second parameter PostData is a string a=1&b=2&c=abc formsubmit by POST, others by PUT, etc. {method:'PUT', data:'a=1&b=2&c=abc'}

PostData can also be a JSON string.
The form of cookies is as follows: a=10; b=20each parameter uses a semicolon to separate.
The format of the headers parameter is: User-Agent: Mobile\nContent-Type: text/html each parameter is separated by a newline character ‘\n’.

The second parameter, postData, can be customized, for example:
HttpQuery("http://www.abc.com", {method:'PUT', data:'a=1&b=2&c=abc'})Note: if you need to set the timeout for the httpquery function, you can add the timeout attribute in {method:'put',data:'a=1&B=2&C=ABC'} (the default is 60 seconds).

The third parameter is required to pass the Cookie string, but POST is not required to set the second parameter to null.
During the simulation test, because the URL cannot be simulated, the function returns a fixed string Dummy Data.
You can use this interface to send text messages or interact with other APIs.

function main() {
// Set proxy and send http request this time, no username, no password, this time http request will be sent through the proxy
HttpQuery("socks5://127.0.0.1:8889/http://www.baidu.com/")
// Set the proxy and send http request this time, enter the user name and password, only the current call of HttpQuery takes effect, then call HttpQuery ("http://www.baidu.com") again 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 Python's urllib2 library

Data can be retrieved by sending requests (only to Chinese domestic accessible links) using HttpQuery(...) in the backtest system. A limit of 20 times is imposed on the backtest and the HttpQuery(...) access aches the data, while the HttpQuery(...) function returns the cached ata on the second access of the same URL (no more actual web requests).
We can run a service program on a server or device that responds to requests sent by HttpQuery(...) in the strategy program, tested in the Go language as follows:

The strategy backtest uses the HttpQuery(...) function to send requests.

function main() {
// You can write the IP address of the device where you run the service program
Log(HttpQuery("http://xxx.xx.x.xxx:9090/data?msg=hello"));
Log(exchange.GetAccount());
}

# HttpQuery does not support Python and can use Python's urllib2 library

void main() {
// You can write the IP address of the device where you run the service program
Log(HttpQuery("http://xxx.xx.x.xxx:9090/data?msg=hello"));
Log(exchange.GetAccount());
}

Hash(…)

Hash(Algo, OutputAlgo, Data)it supports hash calculation of md5/sha256/sha512/sha1, only support real market. Parameter value: both are of type string.
The second parameter can be set to raw/hex/base64, which refers to the output of the encrypted original content /hex encoded /base64 encoded, respectively.

HMAC(…)

HMAC(Algo, OutputAlgo, Data, Key)it supports HMAC encryption calculation of md5/sha256/sha512/sha1, only support real market. Parameter value: both are of type string.
The second parameter can be set to raw /hex/base64, which refers to the output of the encrypted original content /hex encoded /base64 encoded, respectively.

UnixNano()

UnixNano()Return nanosecond timestamp, if you need to get millisecond timestamp, you can use the following code:

function main() {
var time = UnixNano() / 1000000
Log(_N(time, 0))
}

def main():
time = UnixNano()
Log(time)

void main() {
auto time = UnixNano();
Log(time);
}

Unix()

Unix()Returns the timestamp in seconds.

function main() {
var t = Unix()
Log(t)
}

def main():
t = Unix()
Log(t)

void main() {
auto t = Unix();
Log(t);
}

GetOS()

GetOS()Returns information about the system where the docker is located.

function main() {
Log("GetOS:", GetOS())
}

def main():
Log("GetOS:", GetOS())

void main() {
Log("GetOS:", GetOS());
}

Docker running under the MAC operating system.
Log output:

GetOS:darwin/amd64

darwin:Mac OS system name.

MD5(String)

MD5(String)Parameter value:string type.

function main() {
Log("MD5", MD5("hello world"))
}

def main():
Log("MD5", MD5("hello world"))

void main() {
Log("MD5", MD5("hello world"));
}

Log output:

MD5 5eb63bbbe01eeed093cb22bb8f5acdc3

Built-in Functions

_G(K, V)

_G(K, V)a global dictionary that can be saved, both backtest and real market support. After the backtest, the saved data will be cleared. The KV table is permanently stored in a local file. Each robot has a separate database. It will always exists after restarting or the docker exits. K must be a string, which is not case sensitive. V can be any JSON serializable content.

_D(Timestamp, Fmt)

_D(Timestamp, Fmt), returns the specified timestamp. Parameter value:Timestamp is a numeric type, in milliseconds. Fmt is a string type Fmt defaults to : yyyy-MM-dd hh:mm:ssreturn value: string type.
Returns the specified timestamp(ms) string, returns the current time without passing any parameters, for example: _D() or _D(1478570053241)the default format is yyyy-MM-dd hh:mm:ss.

function main(){
var time = _D()
Log(time)
}

def main():
strTime = _D()
Log(strTime)

void main() {
auto strTime = _D();
Log(strTime);
}

Note:
When using _D() in the Python writing strategyyou need to pay attention that the parameters passed in are timestamps in seconds(in the JavaScript and C ++ strategies, timestamps in the millisecond level, 1 second = 1000 milliseconds).
In the real marketwhen using the _D() function to parse a time string with a readable timestamp, you need to pay attention to the operation of the docker program.$$

As the time zone and time of the system, the _D() function parses a timestamp as a readable time string based on the time of the docker system, that is, if a timestamp is: 1574993606000, use code to parse:

function main() {
Log(_D(1574993606000))
}

def main():
# Beijing time server runs: 2019-11-29 10:13:26, and the docker on another server in another region runs this code will get the results:2019-11-29 02:13:26
Log(_D(1574993606))

void main() {
Log(_D(1574993606000));
}

_N(Num, Precision)

_N(Num, Precision)format a floating point number. Parameter value, Num is number typePrecision is integer number. Return value:number type.
For example:_N(3.1415, 2), will delete the value after two decimal places and return 3.14.

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);
}

If you need to change all N digits to the left of the decimal point to 0, you can write:

_C(…)

_C(function, args…)Retry function

The specified function will be called until it returns successfully (when the function returns null or false, it will keep retry), such as _C(exchange.GetTicker), the default retry interval is 3 seconds, and you can call _CDelay(...) function to control the retry interval, such as _CDelay(1000), refers to changing the _C function retry interval to 1 second, it is recommended:

exchange.GetTicker()

exchange.GetDepth()

exchange.GetTrade()

exchange.GetRecords()

exchange.GetAccount()

exchange.GetOrders()

exchange.GetOrder()
are all called by _C(...) in case an error occurs.

// C++ does not support this method for fault tolerance of custom functions.

_Cross(Arr1,Arr2)

_Cross(Arr1, Arr2)returns the number of crossing cycles of the arrays arr1 and arr2. A positive number is the period of upswing, a negative number is the period of downswings, and 0 means the same as the current price. Parameter value: number array.

You can simulate a set of data to test the _Cross(Arr1, Arr2) function:

Custom Color

Each message string can end with an RGB value such as #ff0000, which represents the foreground color to be displayed.If it is in a format such as #ff0000112233, the last six posteriors represent the background color.

Color hex diagram:

function main() {
Log("Red", "#FF0000")
}

def main():
Log("Red", "#FF0000")

void main() {
Log("Red", "#FF0000");
}

Log Information

Log(…)

Log(message), save a message to the log list. Parameter value: message can be any type.
If you add the @ character after the string, the message will enter the push queue and be pushed to the WeChat account using the binding (bound in the account security) (50 entries/hour, 1 entry /5 seconds limit)
Note:

The information pushed by WeChat cannot be repeated! (Otherwise, only one will be pushed.)

The Log function supports language switching, the Log function outputs text, and it will automatically switch to the corresponding language according to the language setting on the platform page, for example:

function main() {
Log("[trans]Chinese|abc[/trans]")
}

def main():
Log("[trans]Chinese|abc[/trans]")

void main() {
Log("[trans]Chinese|abc[/trans]");
}

LogProfit(Profit)

LogProfit(Profit), record the profit value, this is the value of the total profit, print the profit value, and draw a profit curve according to the value of the profit, the parameter value: Profit is of type number.

It can end with the characters &, to realize only drawing the revenue chart, and not printing the revenue log: LogProfit(10, '&').

LogProfitReset()

LogProfitReset(), to clear all revenue logs, you can take a numeric parameter to specify the number of reserved items.

LogStatus(Msg)

LogStatus(Msg)This information is not saved in the log list, only the current status information of the robot is updated. It is displayed above the log and can be called multiple times to update the status. Parameter value: Msg can be any type.

LogStatus(Msg) supports printing base64-encoded pictures, starting with `and ending with`, such as: LogStatus("`data:image/png;base64,AAAA`").
LogStatus(Msg) supports direct import of Python’s matplotlib.pyplot object, as long as the object contains the savefig method, you can pass in the LogStatus(Msg) function, such as: