The Back Testing Library for Professional Trading Strategy Developers

Back testing is the process of testing trading strategies based on historic market data to attempt to simulate how a trading system might perform in the future.

Back testing is to trading strategy development what research and quality improvement are to the healthcare and transportation industries. Who would want to try out an untested heart monitor or automobile? Nobody. The same holds true for financial trading strategies.

All trading strategies must be back tested, optimized, and validated before going live with real money. Almost any technical analysis trading strategy can be tested.

While it is true that many intermediate level trading applications provide scripting languages which allow traders to develop and back test trading strategies, we found there were no back testing libraries available for advanced trading system developers who prefer to program their trading strategies in low-level programming languages such as C++, C#, and Java.

So, we developed a back testing engine for advanced system developers.

Now developers can create strategies in any programming language, then back test and optimize those strategies to improve performance. BackTestLib lets developers back test their trading systems in C++, C#, VB.NET, F#, R, IronPython, or any other language, using tick or bar data.

It just doesn't matter how your trading system is written. All you have to do is supply a list of trades, and the back testing library does the rest for you.

BackTestLib can calculate your trading system performance using two-dozen risk measurements including Sharpe ratio, Calmar ratio, Sortino ratio, Maximum Draw Down, Monte Carlo Draw Down, Total P&L, Risk to Reward Ratio, Largest Profit, Largest Loss, Average Number of Trades / Month, Trade Logs and more.

Perfect for Strategy Optimization

Professional traders know all good things come to an end. Even the best trading systems eventually fall into losing periods, requiring optimization or trading system retirement. Reasons vary, including changes in liquidity, volatility, and underlying market dynamics, as well as other factors. The BackTestLib outputs results which represent a range of measurements based on the profitability and risk of your trading system when tested with the data with which it was supplied.

Code Example

// Create some simulated trades

List <Trade > trades =  new List<Trade>();


trades.Add( new Trade(DateTime.Parse( "1/1/2014 9:30:45.422 AM" ), SignalType .Buy, 24));

trades.Add( new Trade(DateTime.Parse( "1/1/2014 9:32:33.891 AM" ), SignalType .ExitLong, 24.09));

trades.Add( new Trade(DateTime.Parse( "1/1/2014 9:37:12.839 AM" ), SignalType .Sell, 24.07));

trades.Add( new Trade(DateTime.Parse( "1/1/2014 9:48:27.488 AM" ), SignalType .Exit, 24.19));

trades.Add( new Trade(DateTime.Parse( "1/1/2014 9:49:16.415 AM" ), SignalType .Buy, 24));

trades.Add( new Trade(DateTime.Parse( "1/1/2014 9:50:45.512 AM" ), SignalType .Exit, 24.09));

trades.Add( new Trade(DateTime.Parse( "1/1/2014 9:51:14.212 AM" ), SignalType .Buy, 24.01));


// Run the backtest
double  lastPrice = 24.03;

BacktestResults  results =  Backtester .Backtest(trades, lastPrice);


// Output the results

Console .WriteLine( "Total number of trades: {0:G}" , results.TotalNumberOfTrades);

Console .WriteLine( "Average number of trades per month: {0:G}" , results.AverageTradesPerMonth);

Console .WriteLine( "Total number of profitable trades: {0:G}" , results.NumberOfProfitableTrades);

Console .WriteLine( "Total number of losing trades: {0:G}" , results.NumberOfLosingTrades);

Console .WriteLine( "Total profit: {0:C}" , results.TotalProfit);

Console .WriteLine( "Total loss: {0:C}" , results.TotalLoss);

Console .WriteLine( "Percent profitable trades: {0:P}" , results.PercentProfit);

Console .WriteLine( "Percent profitable trades: {0:P}" , results.PercentProfit);

Console .WriteLine( "Largest profit: {0:C}" , results.LargestProfit);

Console .WriteLine( "Largest loss: {0:C}" , results.LargestLoss);

Console .WriteLine( "Maximum drawdown: {0:C}" , results.MaximumDrawDown);

Console .WriteLine( "Maximum drawdown Monte Carlo: {0:C}" , results.MaximumDrawDownMonteCarlo);

Console .WriteLine( "Standard deviation: {0:G}" , results.StandardDeviation);

Console .WriteLine( "Standard deviation annualized: {0:G}" , results.StandardDeviationAnnualized);

Console .WriteLine( "Downside deviation (MAR = 10%): {0:G}" , results.DownsideDeviationMar10);

Console .WriteLine( "Value Added Monthly Index (VAMI): {0:G}" , results.ValueAddedMonthlyIndex);

Console .WriteLine( "Sharpe ratio: {0:G}" , results.SharpeRatio);

Console .WriteLine( "Sortino ratio: {0:G}" , results.SortinoRatioMAR5);

Console .WriteLine( "Annualized Sortino ratio: {0:G}" , results.AnnualizedSortinoRatioMAR5);

Console .WriteLine( "Sterling ratio: {0:G}" , results.SterlingRatioMAR5);

Console .WriteLine( "Calmar ratio: {0:G}" , results.CalmarRatio);

Console .WriteLine( "Risk to reward ratio: {0:P}" , results.RiskRewardRatio);


// Display the trade log

foreach  (Trade trade in results.Trades)

     Console .WriteLine(trade.Date +  ": "  + trade.Signal.ToString() +  " at "  + trade.Price.ToString()); 

Get Started with BackTestLib >

Why Choose Modulus?

Modulus is a financial technology company. While that may not sound like a real differentiator, it is. It means that our solutions come from our years of experience in the financial technology industry. Our products and services are provided by developers and engineers who have first-hand trading experience. Everyone here at Modulus speaks your language.

Read more about us.