Getting Started
Platform Basics
Writing Strategies
Development Tools
Backtesting System
Advanced Topics
Data and Research
Integrations
onexit()
onexit() is implemented by the user to clean up when the strategy exits; it is optional. It may run for at most 5 minutes and is terminated when it exceeds that. For when each language calls onexit(), see Writing Strategies → Strategy Structure.
Examples
-
Testing the
onexit()function:javascriptfunction main(){ Log("Starting, will stop after 5 seconds and execute cleanup function!") Sleep(1000 * 5) } // cleanup function function onexit(){ var beginTime = new Date().getTime() while(true){ var nowTime = new Date().getTime() Log("Program stop countdown..cleanup started, elapsed time:", (nowTime - beginTime) / 1000, "seconds!") Sleep(1000) } }pythonimport time def main(): Log("Starting, will stop after 5 seconds and execute cleanup function!") Sleep(1000 * 5) def onexit(): beginTime = time.time() * 1000 while True: ts = time.time() * 1000 Log("Program stop countdown..cleanup started, elapsed time:", (ts - beginTime) / 1000, "seconds!") Sleep(1000)rustfn main() { Log!("Starting, will stop after 5 seconds and execute cleanup function!"); Sleep(1000 * 5); } // cleanup function fn onexit() { let beginTime = Unix() * 1000; loop { let nowTime = Unix() * 1000; Log!("Program stop countdown..cleanup started, elapsed time:", (nowTime - beginTime) / 1000, "seconds!"); Sleep(1000); } } -
In the backtesting system a strategy is usually an endless polling loop, so
main()has not returned normally when the backtest data ends, andJavaScriptandPythonstrategies therefore do not runonexit(). In a backtest (IsVirtual()is true) you can catch the exception (EOF) thrown when the backtest ends so thatmain()returns andonexit()runs. InRustthe API calls returnErrwhen the backtest ends, so just leave the loop.javascriptfunction main() { if (exchange.GetName().startsWith("Futures_")) { Log("Exchange is futures") exchange.SetContractType("swap") } else { Log("Exchange is spot") } if (IsVirtual()) { try { onTick() } catch (e) { Log("error:", e) } } else { onTick() } } function onTick() { while (true) { var ticker = exchange.GetTicker() LogStatus(_D(), ticker ? ticker.Last : "--") Sleep(500) } } function onexit() { Log("Executing cleanup function") }pythondef main(): if exchange.GetName().startswith("Futures_"): Log("Exchange is futures") else: Log("Exchange is spot") if IsVirtual(): try: onTick() except Exception as e: Log(e) else: onTick() def onTick(): while True: ticker = exchange.GetTicker() LogStatus(_D(), ticker["Last"] if ticker else "--") Sleep(500) def onexit(): Log("Executing cleanup function")rustfn onTick() { loop { match exchange.GetTicker(None) { Ok(ticker) => LogStatus!(_D(None), ticker.Last), Err(e) => { // API calls return Err when the backtest ends; leaving the loop lets main return, which triggers onexit() Log!("error:", e); break; } } Sleep(500); } } fn main() { if exchange.GetName().starts_with("Futures_") { Log!("Exchange is futures"); let _ = exchange.SetContractType("swap"); } else { Log!("Exchange is spot"); } onTick(); } fn onexit() { Log!("Executing cleanup function"); }