Welcome to FMZ Quant Trading Platform
Programming Languages
Key Security
Live Trading
Strategy Library
Docker
Exchange
Strategy Editor
Backtesting System
Backtesting System Modes
Impact of Backtest Data Granularity on Backtesting
The backtesting system supports multiple programming languages
Exchanges Supported by Backtesting System
Backtest System Parameter Optimization
Save Backtest Settings
Custom Data Source
Local Backtesting Engine
Backtest Page Shortcuts
Backtest Data Download
Backtest System Sharpe Ratio Algorithm
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
Plugin Use Cases
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 }pythondef 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 tblrustfn 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 }pythonchart = { "__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 chartc++// 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.