Type/to search
Welcome to FMZ Quant Trading Platform
Programming Languages
JavaScript
TypeScript
Python
Rust
C++
MyLanguage
PINE Language
Blockly Visual Programming
Workflow
Key Security
Live Trading
Strategy Library
Docker
Deploy Docker
One-Click Docker Rental
Manual Deployment of Bot
Docker Operation Precautions
Global IP Address Specification
Command Line Parameters for Bot Program
Live Trading Data Migration
Docker Monitor
Exchange
Strategy Editor
Backtesting System
Strategy Entry Functions
Strategy Framework and API Functions
Template Library
Strategy Parameters
Interactive Controls
Options Trading
Rust Strategy Development Guide
C++ Strategy Writing Guide
JavaScript Strategy Writing Guide
Web3
Built-in Libraries
Extended API Interface
MCP Service
Trading Terminal
Data Explorer
Alpha Factor Analysis Tool
General Protocol
Debugging Tool
Remote Editing
Import and Export of Complete Strategies
Multi-language Support
Live Trading and Strategy Grouping
Live Trading Display
Strategy Sharing and Renting
Live Trading Message Push
Common Causes of Live Trading Errors and Abnormal Exits
Exchange-Specific Notes

FMZ Quant Trading Platform provides a modular and customizable Trading Terminal page. Users can freely add various data modules, trading function modules, and even write code to develop custom modules (Trading Terminal plugins).

With its highly flexible and free usage approach, it greatly facilitates manual trading and semi-automated trading users. Various modules on the Trading Terminal page support dragging and resizing, can modify settings such as trading pairs and exchanges bound to modules, and can add multiple modules of the same type.

FMZ Quant Trading Platform continuously improves Trading Terminal functionality and has launched the Trading Terminal plugin feature to better support manual trading.

Trading Terminal related data is stored in the running directory of the docker program (robot executable file), specifically at: logs/storage/0. If the exchange object used by the Trading Terminal is configured using API key file path method, the key file needs to be placed in this directory.

The principle is the same as the Debugging Tool - it sends a code snippet to the selected docker on the trading terminal page for execution, supporting the return of charts and tables (the debugging tool has also been upgraded to support this feature). Like the Debugging Tool, it can only execute for 3 minutes, and this feature is free of charge. It can be used to implement simple functions to assist manual trading, while complex strategies still need to run in live trading.

Create trading terminal plugins by setting the strategy type to "Trading Plugin" on the New Strategy page. Trading plugins support JavaScript, Python, C++, and MyLanguage.

A plugin can run a piece of code to perform some simple operations, such as iceberg orders, placing orders, canceling orders, calculations, and other tasks. Like the debugging tool, a plugin returns results via return, and it can also directly return charts and tables. Below are a few examples; you can explore other features on your own.

  • Return a depth snapshot

    javascript
    // Return the depth snapshot function main() { var tbl = { type: 'table', title: 'Depth Snapshot @ ' + _D(), cols: ['#', 'Amount', 'Ask', 'Bid', 'Amount'], rows: [] } var d = exchange.GetDepth() for (var i = 0; i < Math.min(Math.min(d.Asks.length, d.Bids.length), 15); i++) { tbl.rows.push([i, d.Asks[i].Amount, d.Asks[i].Price+'#ff0000', d.Bids[i].Price+'#0000ff', d.Bids[i].Amount]) } return tbl }
    python
    def main(): tbl = { "type": "table", "title": "Depth Snapshot @ " + _D(), "cols": ["#", "Amount", "Ask", "Bid", "Amount"], "rows": [] } d = exchange.GetDepth() for i in range(min(min(len(d["Asks"]), len(d["Bids"])), 15)): tbl["rows"].append([i, d["Asks"][i]["Amount"], str(d["Asks"][i]["Price"]) + "#FF0000", str(d["Bids"][i]["Price"]) + "#0000FF", d["Bids"][i]["Amount"]]) return tbl
    rust
    fn main() { let d = exchange.GetDepth(None).unwrap(); let n = d.Asks.len().min(d.Bids.len()).min(15); let mut rows = Vec::new(); for i in 0..n { rows.push(format!(r#"[{}, {}, "{}#ff0000", "{}#0000ff", {}]"#, i, d.Asks[i].Amount, d.Asks[i].Price, d.Bids[i].Price, d.Bids[i].Amount)); } let tbl = format!( r##"{{"type": "table", "title": "Depth Snapshot @ {}", "cols": ["#", "Amount", "Ask", "Bid", "Amount"], "rows": [{}]}}"##, _D(None), rows.join(",")); LogStatus!(format!("`{}`", tbl)); // Rust does not support returning json to display a table; you can create a live trading bot to display a status bar table }
    c++
    void main() { json tbl = R"({ "type": "table", "title": "abc", "cols": ["#", "Amount", "Ask", "Bid", "Amount"], "rows": [] })"_json; tbl["title"] = "Depth Snapshot @" + _D(); auto d = exchange.GetDepth(); for(int i = 0; i < 5; i++) { tbl["rows"].push_back({format("%d", i), format("%f", d.Asks[i].Amount), format("%f #FF0000", d.Asks[i].Price), format("%f #0000FF", d.Bids[i].Price), format("%f", d.Bids[i].Amount)}); } LogStatus("`" + tbl.dump() + "`"); // C++ does not support returning json to display a table; you can create a live trading bot to display a status bar table }
  • Plot the calendar spread

    javascript
    // Plot the calendar spread var chart = { __isStock: true, title : { text : 'Spread Analysis Chart'}, xAxis: { type: 'datetime'}, yAxis : { title: {text: 'Spread'}, opposite: false }, series : [ {name : "diff", data : []} ] } function main() { exchange.SetContractType('quarter') var recordsA = exchange.GetRecords(PERIOD_M5) exchange.SetContractType('this_week') var recordsB = exchange.GetRecords(PERIOD_M5) for(var i = 0; i < Math.min(recordsA.length, recordsB.length); i++){ var diff = recordsA[recordsA.length - Math.min(recordsA.length, recordsB.length) + i].Close - recordsB[recordsB.length - Math.min(recordsA.length, recordsB.length) + i].Close chart.series[0].data.push([recordsA[recordsA.length - Math.min(recordsA.length, recordsB.length) + i].Time, diff]) } return chart }
    python
    chart = { "__isStock": True, "title": {"text": "Spread Analysis Chart"}, "xAxis": {"type": "datetime"}, "yAxis": { "title": {"text": "Spread"}, "opposite": False }, "series": [ {"name": "diff", "data": []} ] } def main(): exchange.SetContractType("quarter") recordsA = exchange.GetRecords(PERIOD_M5) exchange.SetContractType("this_week") recordsB = exchange.GetRecords(PERIOD_M5) for i in range(min(len(recordsA), len(recordsB))): diff = recordsA[len(recordsA) - min(len(recordsA), len(recordsB)) + i].Close - recordsB[len(recordsB) - min(len(recordsA), len(recordsB)) + i].Close chart["series"][0]["data"].append([recordsA[len(recordsA) - min(len(recordsA), len(recordsB)) + i]["Time"], diff]) return chart
    c++
    // C++ does not support returning json structures to plot charts

The Strategy Square also contains other examples for reference, such as: tick-by-tick small-volume buying/selling.

  • Add Trading Terminal Plugin Module
    Open the module addition menu on the trading terminal page. Trading terminal plugins from the current FMZ account's strategy library will automatically appear in the list. Find the plugin you need to add and click to add it.
    • Run Plugin
      Click the "Execute" button to start running the trading terminal plugin. The plugin will not display log information, but can return and display data tables.
  • Plugin Runtime
    The maximum runtime for trading terminal plugins is 3 minutes. Plugins will automatically stop running after 3 minutes.