BackTestEngine
Table of Contents
BackTestEngine
The BackTestEngine class is used to simulate trading strategies on historical data that is either preloaded or provided
at runtime during the test.
Attributes:
| Name |
Type |
Description |
_data |
BackTestData |
The data used for backtesting. This is the data that is saved to disk when the backtest is stopped. |
mt5 |
MetaTrader |
The MetaTrader instance for the backtest engine. |
config |
Config |
The global configuration instance. |
name |
str |
The name of the backtest. |
stop_testing |
bool |
Whether to stop the backtest. |
use_terminal |
bool |
Whether to use the terminal for backtesting. |
close_open_positions_on_exit |
bool |
Whether to close all open positions when the backtest is stopped. |
stop_time |
int |
The time to stop the backtest. |
preload |
bool |
Whether to preload the ticks for the backtest. |
preloaded_ticks |
dict |
A dictionary of preloaded ticks for the backtest. |
account_lock |
RLock |
A reentrant lock for the account data. |
account_info |
dict |
A dictionary of account information for the backtest. |
_init_
The BackTestEngine class is used to simulate trading strategies on historical data.
It can accept already saved data or create new data for backtesting on the fly. Ideally only one instance of
this class should be created per session. By default it is automatically assigned to the global config instance
during instantiation, replacing any existing backtest engine instance. But this is a configurable behaviour.
The start and end time can still be specified even when test data is provided. In that case it will be used
to set the range of the backtest.
Parameters:
| Name |
Type |
Description |
data |
BackTestData |
The data to use for backtesting. Defaults to None. |
speed |
int |
The speed of the backtest. Defaults to 60 seconds. |
start |
float | datetime |
The start time of the backtest. Defaults to 0. If a float is passed, it is assumed to be a timestamp. |
end |
float | datetime |
The end time of the backtest. Defaults to 0. If a float is passed, it is assumed to be a timestamp. |
restart |
bool |
Whether to restart the backtest from the beginning. Defaults to True. This is useful when resuming a backtest using a saved BackTestData instance. |
use_terminal |
bool |
Whether to use the terminal for backtesting. Defaults to None. If None, it uses the global config setting. If use terminal is true, the backtest engine will use the terminal to get price data, compute margins, profit and check order viability. If false, it will use the data provided in the BackTestData instance and default algorithm for the calculations |
name |
str |
The name of the backtest. Defaults to "". If not provided, it is generated from the start and end times. |
stop_time |
float | datetime |
The time to stop the backtest. Defaults to None. If a float is passed, it is assumed to be a timestamp. If not given it is assumed to be the end of the backtest range. |
close_open_positions_on_exit |
bool |
Whether to close all open positions when the backtest is stopped. Defaults to True. |
preload |
bool |
Whether to preload the ticks for the backtest. Defaults to True. |
assign_to_config |
bool |
Whether to assign the backtest engine to the global config instance. Defaults to True. |
account_info |
dict |
A dictionary of account information to use for the backtest. Defaults to None. Use this to set the account information for the backtest. |
setup_test_range
Setup the test range for the backtest engine. This is used to set the range of the backtest and the speed
at which it runs.
Parameters:
| Name |
Type |
Description |
start |
float | datetime |
The start time of the backtest. Defaults to None. If a float is passed, it is assumed to be a timestamp. |
end |
float | datetime |
The end time of the backtest. Defaults to None. If a float is passed, it is assumed to be a timestamp. |
speed |
int |
The speed of the backtest. Defaults to 60 seconds. |
restart |
bool |
Whether to restart the backtest. Defaults to True. This is useful when resuming a backtest using a saved BackTestData. |
setup_data
Sets up the data for the backtest engine. This includes the orders, positions, deals and account
information. This data is handled by specialized classes such as the BackTestAccount and the TradeManager
classes.
Parameters:
| Name |
Type |
Description |
restart |
bool |
Whether to restart the data. Defaults to True. |
next
Move the cursor to the next time step in the backtest range.
data
The BackTestData instance used for the backtest. If not provided, a new instance is created,
and the data is made persistent when the backtest is stopped.
reset
Reset the backtest engine. This is useful when restarting the backtest from the beginning. Clear trade data if any
when the clear_data parameter is true
go_to
Move the cursor to a specific time in the backtest range. You can pass a datetime object or a timestamp.
You can't go back in time or beyond the limits of the range.
fast_forward
Fast-forward the backtester by the given steps.
tracker
The tracker monitors and updates open positions on every iteration. It is called by the controller.
save_result_to_json
Saves the result to a json file at the end of testing.
close_all_open
Closes all open position at the end of testing
wrap_up
Wraps up the backtest. This is called at the end of testing to save the results and close all open positions.
preload_ticks
Pull a month data on ticks from the terminal. Starting from the current time.
Parameters:
| Name |
Type |
Description |
symbol |
str |
The symbol to preload ticks for. |
get_price_tick
Get the price tick for a symbol at a given time. If the preload option is set to True,
it will use the preloaded ticks when available.
Parameters:
| Name |
Type |
Description |
symbol |
str |
The symbol to get the price tick for. |
time |
int |
The time to get the price tick. |
check_order
Check if the order has reached its take profit or stop loss levels and close the order if it has.
Checks only OrderType.BUY and OrderType.SELL orders that have reached their take profit or stop loss levels.
Parameters:
| Name |
Type |
Description |
ticket |
int |
Order ticket |
check_account
Checks an account status. This method is called at each iteration to check if the account has burned out.
check_position
Update the profit of an open position based on the current price of the symbol. It is called by the
tracker to update the profit of open positions.
Parameters:
| Name |
Type |
Description |
ticket |
int |
Position ticket |
close_position_manually
Close a position manually without. Usually at the end of testing.
close_position
Close an open position for the trading account using the position ticket.
Parameters:
| Name |
Type |
Description |
ticket |
int |
Position ticket |
Returns:
| Type |
Description |
bool |
True if the position is closed successfully, False otherwise |
modify_stops
Modify the stop loss and take profit levels of an open position.
Parameters:
| Name |
Type |
Description |
ticket |
int |
Position ticket |
sl |
int |
stop loss level |
Returns:
| Type |
Description |
bool |
True if the stops are modified successfully, False otherwise |
update_account
Update the account. This method is protected by thread lock.
Parameters:
| Name |
Type |
Description |
profit |
float |
The current profit of one or more open positions. Can be positive or negative. |
margin |
float |
The margin set aside for a trade. It is released when the trade is closed. |
gain |
gain |
The gain realized when the trade is closed. |
deposit
Make deposit to the trading account
withdraw
Make a withdrawal from the trading account. You can not withdraw more than what you have
setup_account
Set up the trading account before the beginning of a backtesting session.
Parameters:
| Name |
Type |
Description |
kwargs |
dict |
Attributes for the backtest account object can be set here. |
setup_account_sync
Set up the backtesting account in sync mode
prices
Get the prices for instruments used in the backtesting. This class is called when the use_terminal option
is set to False and trading data is provided in the data attribute. It makes sure that there is a price for each
symbol for every second covered in the backtesting range, by reindexing the price ticks using the backtesting
time span and filling up missing data using the nearest method.
This method returns a dictionaries of dataframe containing the prices for each symbol.
It's cached and there computed only once per backtesting session.
Returns:
| Type |
Description |
dict |
A dictionary mapping dataframe of prices to symbols. |
ticks
Similar to prices above, but returns prices exactly as they are without reindexing and filling up.
Returns:
| Type |
Description |
dict |
A dictionary mapping dataframe of prices to symbols. |
rates
This property is useful when backtesting with the use_terminal option set to false. It returns a nested dict
that maps symbols to a dict mapping timeframes to rates. The timeframes are mapped using their integer values.
Returns:
| Type |
Description |
dict[str, dict[int, DataFrame]] |
A dictionary containing the symbol rates. |
symbols
A dictionary of symbols and SymbolInfo object. Used when use_terminal is set to false.
Returns:
| Type |
Description |
dict[str, SymbolInfo] |
A dictionary of symbols and SymbolInfo object. |
order_send
Simulates the sending of an order to the broker. An OrderSendResult is object is created at the end of this
operation as would be created if it was done in live trading. When an order is successful a positions object is
created, an order and deal object is created as well. The margin and profit are calculated by sending to the broker
if use_terminal is true. This increases accuracy but slows down the backtester. The check_order method is
called to make sure the order is valid and would go through if it was a live trade.
Parameters:
| Name |
Type |
Description |
request |
dict |
The order request as a dict. |
use_terminal |
bool |
A flag to override the use_terminal attribute. If true, the terminal will be used even if the use_terminal attribute is True. |
Returns:
| Type |
Description |
OrderSendResult |
An object containing the result of the order send operation. |
order_check
Checks the order before placing it. If use_terminal is true, the order is checked with the broker,
but the entire result is not used. Details such as balance, profit, equity, margin, and margin level are calculated
by the backtester.
Parameters:
| Name |
Type |
Description |
request |
dict |
The order request as a dict. |
use_terminal |
bool |
A flag to override the use_terminal attribute. If true, the terminal will used. |
Returns:
| Type |
Description |
OrderCheckResult |
The result of the order check. |
get_terminal_info
Get the terminal information
Returns:
| Type |
Description |
TerminalInfo |
The terminal information |
get_version
Get the version of the terminal.
Returns:
| Type |
Description |
tuple[int, int, str] |
The version of the terminal |
get_symbols_total
Get the total number of symbols available in the terminal.
Returns:
| Type |
Description |
int |
The total number of symbols available. |
get_symbols
Get the symbols available in the terminal. Filter by group if provided.
Parameters:
| Name |
Type |
Description |
group |
str |
The group to filter by (default is "") |
Returns:
| Type |
Description |
tuple[SymbolInfo, ...] |
A tuple of symbol information |
get_account_info
Get the account information
Returns:
| Type |
Description |
AccountInfo |
The account information |
get_symbol_info_tick
Get the price tick for a symbol at the current time
Parameters:
| Name |
Type |
Description |
symbol |
str |
The symbol to get the price tick for. |
Returns:
| Type |
Description |
Tick |
The price tick |
get_symbol_info
Get the symbol information
Parameters:
| Name |
Type |
Description |
symbol |
str |
The symbol to get information for |
Returns:
| Type |
Description |
SymbolInfo |
The symbol information |
get_rates_from
Get rates from a specific date to the current date. Used by the backtester to get rates for a symbol
Parameters:
| Name |
Type |
Description |
symbol |
str |
The symbol to get rates for |
timeframe |
TimeFrame |
The timeframe of the rates |
date_from |
datetime | float |
The date from which to get the rates |
count |
int |
The number of rates to get |
Returns:
| Type |
Description |
np.ndarray |
An array of rates |
get_rates_from_pos
Get a number of rates counting from a specific position. With position zero being the current time.
Parameters:
| Name |
Type |
Description |
symbol |
str |
The symbol to get rates for |
timeframe |
TimeFrame |
The timeframe of the rates |
start_pos |
int |
The position to start from |
count |
int |
The number of rates to get |
Returns:
| Type |
Description |
np.ndarray |
An array of rates |
get_rates_range
Get rates within a specific date range. Used by the backtester to get rates for a symbol
Parameters:
| Name |
Type |
Description |
symbol |
str |
The symbol to get rates for |
timeframe |
TimeFrame |
The timeframe of the rates |
date_from |
datetime | float |
The date from which to get the rates |
date_to |
datetime | float |
The date to which to get the rates |
Returns:
| Type |
Description |
np.ndarray |
An array of rates |
get_ticks_from
Get a specified number of ticks counting from a specific date.
Parameters:
| Name |
Type |
Description |
symbol |
str |
The symbol to get ticks for |
date_from |
datetime | float |
The date from which to get the ticks |
count |
int |
The number of ticks to get |
flags |
CopyTicks |
The flags to use when getting ticks |
Returns:
| Type |
Description |
np.ndarray |
An array of ticks |
get_ticks_range
Get ticks within a specific date range.
Parameters:
| Name |
Type |
Description |
symbol |
str |
The symbol to get ticks for |
date_from |
datetime | float |
The date from which to get the ticks |
date_to |
datetime | float |
The date to which to get the ticks |
flags |
CopyTicks |
The flags to use when getting ticks |
Returns:
| Type |
Description |
np.ndarray |
An array of ticks |
order_calc_margin
Calculate the margin required for a trade.
Parameters:
| Name |
Type |
Description |
action |
Literal[OrderType.BUY, OrderType.SELL] |
Type of order |
symbol |
str |
Symbol name |
volume |
float |
Volume of the trade |
price |
float |
The price at which the trade is opened |
use_terminal |
bool |
A flag to override the use_terminal attribute. If true, the terminal will be used even if the use_terminal attribute is True. |
Returns:
| Type |
Description |
float |
The margin required for the trade |
order_calc_profit
Calculate the profit for a trade.
Parameters:
| Name |
Type |
Description |
action |
Literal[OrderType.BUY, OrderType.SELL] |
Type of order |
symbol |
str |
Symbol name |
volume |
float |
Volume of the trade |
price_open |
float |
The price at which the trade is opened |
price_close |
float |
The price at which the trade is closed |
use_terminal |
bool |
A flag to override the use_terminal attribute. If true, the terminal will be used even if the use_terminal attribute is True. |
Returns:
| Type |
Description |
float |
The profit of the trade |
get_orders_total
Get the total number of pending orders.
Returns:
| Type |
Description |
int |
Total number of pending orders |
get_orders
Get pending orders from the terminal history. This has to do with pending orders, which this backtester
doesn't support yet.
Parameters:
| Name |
Type |
Description |
symbol |
str |
Symbol name |
group |
str |
Group name |
ticket |
int |
Order ticket |
Returns:
| Type |
Description |
tuple[TradeOrder, ...] |
Pending orders |
get_positions_total
Get the total number of open positions.
Returns:
| Type |
Description |
int |
Total number of open positions |
get_positions
Get open positions from the terminal history.
Parameters:
| Name |
Type |
Description |
symbol |
str |
Symbol name |
group |
str |
Group name |
ticket |
int |
Position ticket |
Returns:
| Type |
Description |
tuple[TradePosition, ...] |
Open positions |
get_history_orders_total
Get the total number of orders in the terminal history.
Parameters:
| Name |
Type |
Description |
date_from |
datetime | float |
The start date of the history |
date_to |
datetime | float |
The end date of the history |
Returns:
| Type |
Description |
int |
Total number of orders in the history |
get_history_orders
Get orders from the terminal history.
Parameters:
| Name |
Type |
Description |
date_from |
datetime | float |
Date from which to start the history |
date_to |
datetime | float |
Date to which to end the history |
group |
str |
group keyword to filter by |
ticket |
int |
ticket id to filter by |
position |
int |
position id to filter by |
Returns:
| Type |
Description |
tuple[TradeOrder, ...] |
Orders in the history |
get_history_deals_total
Get the total number of deals in the terminal history.
Parameters:
| Name |
Type |
Description |
date_from |
datetime | float |
Date from which to start the history |
date_to |
datetime | float |
Date to which to end the history |
Returns:
| Type |
Description |
int |
Total number of deals in the history |
get_history_deals
Get deals from the terminal history.
Parameters:
| Name |
Type |
Description |
date_from |
datetime | float |
Date from which to start the history |
date_to |
datetime | float |
Date to which to end the history |
group |
str |
group keyword to filter by |
position |
int |
position id to filter by |
ticket |
int |
ticket id to filter by |
Returns:
| Type |
Description |
tuple[TradeDeal, ...] |
Deals in the history |