Type/to search
Getting Started
Welcome to FMZ Quant Trading Platform
Quick Start
Key Security
Platform Basics
Account and Billing
Live Robot Billing and Top-up
Sub-accounts
Exchange
General Protocol
Local Credential Files
Exchange-Specific Notes
Securities and Futures
Crypto
Docker
Strategy Library
Live Trading
Writing Strategies
Development Tools
Backtesting System
Advanced Topics
Data and Research
Integrations

Strategies can be written in JavaScript. The runtime is based on the QuickJS engine and supports modern syntax such as async/await, class and BigInt. In live trading the strategy runs on the docker; in backtesting it runs in the browser-side backtesting system. Adding // @ts-check to the code switches to TypeScript (see Programming Languages → TypeScript).

Structure and parameters

The entry point is function main(). The optional init(), onexit() and onerror(msg) are called automatically by the docker (see Writing Strategies → Strategy Structure). Interface parameters are global variables with the same names; they can be read directly and also modified in code (see Writing Strategies → Strategy Parameters).

Errors and return values

When an API call fails (the exchange returns an error, a network problem, etc.) it returns null and writes the error to the log. Check the return value before using it, or retry with _C:

javascript
function main() { var ticker = exchange.GetTicker() // null when the call fails if (ticker) { Log(ticker) } // retry until valid data is returned var account = _C(exchange.GetAccount) Log(account) }

For program exceptions (for example reading a property of undefined) and API business errors, the log shows the line number in the strategy code where the error occurred, which makes debugging easier.

Strings and ArrayBuffer

JavaScript strings are UTF-16. If text returned by a platform API is not a valid UTF-8 byte sequence, an ArrayBuffer (the raw bytes) is returned instead so that no data is lost. Every API parameter that accepts a string also accepts an ArrayBuffer.

javascript
function stringToHex(str) { let hex = '' for (let i = 0; i < str.length; i++) { const charCode = str.charCodeAt(i).toString(16) hex += charCode.length === 1 ? '0' + charCode : charCode } return hex } function main() { // the code point of "𠮷" exceeds 16 bits; it takes two UTF-16 code units in a JavaScript string const inputString = "abc𠮷123" // Encode outputs the UTF-8 bytes as hex const encodedHex = Encode("raw", "string", "hex", inputString) Log(encodedHex) // 616263f0a0aeb7313233 // charCodeAt returns UTF-16 code units, so "𠮷" becomes d842, dfb7 - not UTF-8 const manuallyEncodedHex = stringToHex(inputString) Log(manuallyEncodedHex) // 616263d842dfb7313233 // valid UTF-8 bytes decode back to a string const decodedString = Encode("raw", "hex", "string", encodedHex) Log(decodedString) // abc𠮷123 // bytes that are not valid UTF-8 come back as an ArrayBuffer // (with inputString = "abcG123" both encodings are identical and this is a string) const outputD = Encode("raw", "hex", "string", manuallyEncodedHex) Log(outputD instanceof ArrayBuffer) // true // inspect the raw bytes in the ArrayBuffer const bufferD = new Uint8Array(outputD) let hexBufferD = '' for (let i = 0; i < bufferD.length; i++) { hexBufferD += bufferD[i].toString(16).padStart(2, '0') } Log(hexBufferD) // 616263d842dfb7313233 }

Asynchrony and threads

  • setTimeout/clearTimeout: callbacks run while the main thread is waiting in Sleep(). When main() returns, timers that have not fired yet run first, then onexit() is called.
  • fetch(url): returns a Promise that resolves to a response object (ok, status, headers; text() and json() return the content directly). On the docker, fetch completes the request synchronously when called and returns an already settled Promise, so combining several fetch calls with Promise.all does not make them concurrent.
  • Exchange APIs (such as exchange.GetTicker()) are synchronous blocking calls; wrapping them in a Promise or an async function does not make them concurrent either.
  • For concurrency use exchange.Go, HttpQuery_Go, or create threads with Thread (see Advanced Topics → JavaScript Multithreading).
javascript
async function main() { let resp = await fetch("https://www.okx.com/api/v5/market/books?instId=BTC-USDT") if (resp.ok) { Log(resp.json()) } else { Log("status:", resp.status) } }

Libraries and dependencies

JavaScript strategies can use the built-in TA and talib indicator libraries directly; see Writing Strategies → Built-in Libraries for what each language provides. Other third-party JavaScript libraries can be downloaded at run time and loaded with eval; the same page has an example.