yabte.backtest
Strategy
- class yabte.backtest.strategy.Strategy(*, orders: Orders | None = None, params: Series | None = None, books: Dict[str, Book] | None = None, assets: Dict[str, Asset] | None = None, _ts: Timestamp | None = None, _data_lock: bool = True, _mask_open: bool = False)[source]
Bases:
objectTrading strategy base class.
This class should be derived from and will be instantiated by
StrategyRunner.
- params: Series | None = None
Parameters supplied to strategy.
- property ts: Timestamp | None
Stores the current timestamp.
- property data: DataFrame
Provides window of data available up to current timestamp self.ts and masks out data not availble at open (like high, low, close, volume).
StrategyRunner
- class yabte.backtest.strategyrunner.StrategyRunnerResult(*, books: List[yabte.backtest.book.Book], strategies: List[yabte.backtest.strategy.Strategy], assets: List[yabte.backtest.asset.Asset], _orders_unprocessed: yabte.backtest.order.Orders = <factory>, _orders_processed: List[yabte.backtest.order.Order] = <factory>, _book_history: Optional[pandas.core.frame.DataFrame] = None)[source]
Bases:
object
- property book_history: DataFrame
Dataframe with book cash, mtm and total value history.
- property transaction_history: DataFrame
Dataframe with trade history.
- class yabte.backtest.strategyrunner.StrategyRunner(*, data: ~pandas.core.frame.DataFrame, assets: ~typing.List[~yabte.backtest.asset.Asset], strategies: ~typing.List[~yabte.backtest.strategy.Strategy], mandates: ~typing.Dict[str, ~yabte.backtest.book.BookMandate] = <factory>, books: ~typing.List[~yabte.backtest.book.Book] = <factory>)[source]
Bases:
objectEncapsulates the execution of multiple strategies.
Orders are captured in orders_processed and orders_unprocessed. books is a list of books and if none provided a single book is created called ‘Main’. After execution summary book and trade histories are captured in book_history and transaction_history.
- data: DataFrame
Dataframe of price data including columns High, Low, Open, Close, Volume for each asset.
Both asset name and field make a multiindex column. The index should consist of order pandas timestamps.
- mandates: Dict[str, BookMandate]
Dictionary of asset mandates (experimental).
- books: List[Book]
Books available to strategies.
If not supplied will be populated with single book named ‘Main’ denominated in USD.
- run(params: Dict[str, Any] | None = None) StrategyRunnerResult[source]
Execute each strategy through time.
- run_batch(params_iterable: Iterable[Dict[str, Any]], executor: ProcessPoolExecutor | None = None) List[StrategyRunnerResult][source]
Run a set of parameter combinations.
Order
- class yabte.backtest.order.OrderStatus(value)[source]
Bases:
EnumVarious statuses.
- MANDATE_FAILED = 1
Order failed due to mandate.
- CANCELLED = 2
Order was cancelled.
- OPEN = 3
Order is open.
- COMPLETE = 4
Order completed succesfully.
- REPLACED = 5
Order was replaced.
- class yabte.backtest.order.OrderSizeType(value)[source]
Bases:
EnumVarious size types.
- QUANTITY = 1
Size is a quantity.
- NOTIONAL = 2
Size represent notional amount.
- BOOK_PERCENT = 3
Size is a percentage of book value.
- class yabte.backtest.order.Order(*, status: ~yabte.backtest.order.OrderStatus = OrderStatus.OPEN, book: str | ~yabte.backtest.book.Book | None = None, suborders: ~typing.List[~yabte.backtest.order.Order] = <factory>, label: str | None = None, priority: int = 0, key: str | None = None)[source]
Bases:
objectBase class for all orders.
- status: OrderStatus = 3
Status of order.
- label: str | None = None
Label to assist in matching / filtering.
- priority: int = 0
Each day orders are sorted by this field and executed in order.
- key: str | None = None
Unique key for this order.
If a key is set then only the newest order with this key is kept. Older orders with the same key will be removed.
- class yabte.backtest.order.SimpleOrder(*, status: ~yabte.backtest.order.OrderStatus = OrderStatus.OPEN, book: str | ~yabte.backtest.book.Book | None = None, suborders: ~typing.List[~yabte.backtest.order.Order] = <factory>, label: str | None = None, priority: int = 0, key: str | None = None, asset_name: str, size: ~decimal.Decimal, size_type: ~yabte.backtest.order.OrderSizeType = OrderSizeType.QUANTITY)[source]
Bases:
OrderSimple market order.
- asset_name: str
Asset name for order.
- size: Decimal
Order size.
- size_type: OrderSizeType = 1
Order size type.
Can be a quantity, notional or book percent.
- pre_execute_check(ts: Timestamp, trade_price: Decimal) OrderStatus | None[source]
Called with the current timestep and calculated trade price before the trade is executed.
If it returns None, the trade is executed as normal. It can return OrderStatus.CANCELLED to indicate the trade should be cancelled or OrderStatus.OPEN to indicate the trade should not be executed in the current timestep and processed in the following timestep.
- apply(ts: Timestamp, day_data: Series, asset_map: Dict[str, Asset])[source]
Applies order to self.book for time ts using provided day_data and dictionary of asset information asset_map.
- key: str | None = None
Unique key for this order.
If a key is set then only the newest order with this key is kept. Older orders with the same key will be removed.
- label: str | None = None
Label to assist in matching / filtering.
- post_complete(trades: List[Trade])
Called after and with trades that have been successfully booked.
It can append new orders to suborders for execution in the following timestep.
- priority: int = 0
Each day orders are sorted by this field and executed in order.
- status: OrderStatus = 3
Status of order.
- class yabte.backtest.order.PositionalOrder(*, status: ~yabte.backtest.order.OrderStatus = OrderStatus.OPEN, book: str | ~yabte.backtest.book.Book | None = None, suborders: ~typing.List[~yabte.backtest.order.Order] = <factory>, label: str | None = None, priority: int = 0, key: str | None = None, asset_name: str, size: ~decimal.Decimal, size_type: ~yabte.backtest.order.OrderSizeType = OrderSizeType.QUANTITY, check_type: ~yabte.backtest.order.PositionalOrderCheckType = PositionalOrderCheckType.POS_TQ_DIFFER)[source]
Bases:
SimpleOrderEnsures current position is size and will close out existing positions to achieve this.
- key: str | None = None
Unique key for this order.
If a key is set then only the newest order with this key is kept. Older orders with the same key will be removed.
- label: str | None = None
Label to assist in matching / filtering.
- post_complete(trades: List[Trade])
Called after and with trades that have been successfully booked.
It can append new orders to suborders for execution in the following timestep.
- pre_execute_check(ts: Timestamp, trade_price: Decimal) OrderStatus | None
Called with the current timestep and calculated trade price before the trade is executed.
If it returns None, the trade is executed as normal. It can return OrderStatus.CANCELLED to indicate the trade should be cancelled or OrderStatus.OPEN to indicate the trade should not be executed in the current timestep and processed in the following timestep.
- priority: int = 0
Each day orders are sorted by this field and executed in order.
- size_type: OrderSizeType = 1
Order size type.
Can be a quantity, notional or book percent.
- status: OrderStatus = 3
Status of order.
- asset_name: str
Asset name for order.
- size: Decimal
Order size.
- check_type: PositionalOrderCheckType = 1
Condition type to determine if a trade is required.
- class yabte.backtest.order.BasketOrder(asset_names: ~typing.List[str], weights: ~typing.List[~decimal.Decimal], size: ~decimal.Decimal, size_type: ~yabte.backtest.order.OrderSizeType = OrderSizeType.QUANTITY, *, status: ~yabte.backtest.order.OrderStatus = OrderStatus.OPEN, book: str | ~yabte.backtest.book.Book | None = None, suborders: ~typing.List[~yabte.backtest.order.Order] = <factory>, label: str | None = None, priority: int = 0, key: str | None = None)[source]
Bases:
OrderCombine multiple assets into a single order.
- key: str | None = None
Unique key for this order.
If a key is set then only the newest order with this key is kept. Older orders with the same key will be removed.
- label: str | None = None
Label to assist in matching / filtering.
- post_complete(trades: List[Trade])
Called after and with trades that have been successfully booked.
It can append new orders to suborders for execution in the following timestep.
- priority: int = 0
Each day orders are sorted by this field and executed in order.
- status: OrderStatus = 3
Status of order.
- asset_names: List[str]
List of asset names in basket.
- weights: List[Decimal]
Corresponding weights for each asset.
- size: Decimal
Combined size of order.
- size_type: OrderSizeType = 1
Size type.
- class yabte.backtest.order.PositionalBasketOrder(asset_names: ~typing.List[str], weights: ~typing.List[~decimal.Decimal], size: ~decimal.Decimal, size_type: ~yabte.backtest.order.OrderSizeType = OrderSizeType.QUANTITY, *, status: ~yabte.backtest.order.OrderStatus = OrderStatus.OPEN, book: str | ~yabte.backtest.book.Book | None = None, suborders: ~typing.List[~yabte.backtest.order.Order] = <factory>, label: str | None = None, priority: int = 0, key: str | None = None, check_type: ~yabte.backtest.order.PositionalOrderCheckType = PositionalOrderCheckType.POS_TQ_DIFFER)[source]
Bases:
BasketOrderSimilar to a
BasketOrderbut will close out existing positions if they do not match requested weights.
- key: str | None = None
Unique key for this order.
If a key is set then only the newest order with this key is kept. Older orders with the same key will be removed.
- label: str | None = None
Label to assist in matching / filtering.
- post_complete(trades: List[Trade])
Called after and with trades that have been successfully booked.
It can append new orders to suborders for execution in the following timestep.
- priority: int = 0
Each day orders are sorted by this field and executed in order.
- size_type: OrderSizeType = 1
Size type.
- status: OrderStatus = 3
Status of order.
- asset_names: List[str]
List of asset names in basket.
- weights: List[Decimal]
Corresponding weights for each asset.
- size: Decimal
Combined size of order.
Transaction
- class yabte.backtest.transaction.Transaction(*, ts: Timestamp, total: Decimal = Decimal('0'), desc: str = '')[source]
Bases:
objectA frozen record of a transaction.
- ts: Timestamp
Transaction time.
- total: Decimal = Decimal('0')
Total transaction value.
Negative values are costs and positive values are benefits.
- desc: str = ''
Description.
- class yabte.backtest.transaction.CashTransaction(*, ts: Timestamp, total: Decimal = Decimal('0'), desc: str = '')[source]
Bases:
TransactionA frozen record of a cash transaction.
- desc: str = ''
Description.
- total: Decimal = Decimal('0')
Total transaction value.
Negative values are costs and positive values are benefits.
- ts: Timestamp
Transaction time.
- class yabte.backtest.transaction.Trade(*, ts: pd.Timestamp, total: Decimal = Decimal('0'), desc: str = '', quantity: Decimal, price: Decimal, asset_name: AssetName, order_label: str | None)[source]
Bases:
TransactionA frozen record of a trade transaction.
A negative quantity represents a sell trade and a positive quantity represents a buy trade.
- quantity: Decimal
Traded quantity.
- desc: str = ''
Description.
- total: Decimal = Decimal('0')
Total transaction value.
Negative values are costs and positive values are benefits.
- ts: pd.Timestamp
Transaction time.
- price: Decimal
Traded price.
- asset_name: AssetName
Traded asset.
- order_label: str | None
Associated Order label.
Book
- yabte.backtest.book.BookName
Book name string.
- class yabte.backtest.book.Book(*, name: str, mandates: ~typing.Dict[str, ~yabte.backtest.book.BookMandate] = <factory>, positions: ~typing.Dict[str, ~decimal.Decimal] = <factory>, transactions: ~typing.List[~yabte.backtest.transaction.Transaction] = <factory>, denom: str = 'USD', cash: ~decimal.Decimal = Decimal('0'), rate: ~decimal.Decimal = Decimal('0'), interest_round_dp: int = 3, _history: ~typing.List[~typing.List[~typing.Any]] = <factory>)[source]
Bases:
objectRecord of asset trades and positions including cash.
A name can be provided and the default cash value can be changed to a non-zero amount.
- name: str
Name of book.
- mandates: Dict[str, BookMandate]
Dictionary mapping assets to mandates (experimental).
- positions: Dict[str, Decimal]
Dictionary tracking positions of each asset.
- transactions: List[Transaction]
List of executed trades.
- denom: str = 'USD'
Book currency.
- cash: Decimal = Decimal('0')
Cash value of book.
- rate: Decimal = Decimal('0')
Daily interest rate applied to cash at end of day.
- interest_round_dp: int = 3
Number of decimal places to round interest.
- property history: DataFrame
Dataframe with book cash, mtm and total value history.
- test_trades(trades: Sequence[Trade]) bool[source]
Checks whether list of trades will be successful by not failing any mandates.
- add_transactions(transactions: Sequence[Transaction])[source]
Records the transactions and adjusts internal dictionary of positions and value of cash accordingly.
Asset
- yabte.backtest.asset.AssetName
Asset name string.
- class yabte.backtest.asset.Asset(*, name: str, denom: str = 'USD', price_round_dp: int = 2, quantity_round_dp: int = 2, data_label: str | None = None)[source]
Bases:
objectAnything that has a price.
- name: str
Name string.
- denom: str = 'USD'
Denominated currency.
- price_round_dp: int = 2
Number of decimal places to round prices to.
- quantity_round_dp: int = 2
Number of decimal places to round quantities to.
- data_label: str | None = None
StrategyRunner.data column index 1st level label.
Defaults to name
- intraday_traded_price(asset_day_data: Series, size: Decimal | None = None) Decimal[source]
Calculate price during market hours with given row of asset_day_data and the order size.
The size can be used to determine a price from say, bid / ask spreads.
- end_of_day_price(asset_day_data: Series) Decimal[source]
Calculate price at end of day with given row of asset_day_data.
- class yabte.backtest.asset.OHLCAsset(*, name: str, denom: str = 'USD', price_round_dp: int = 2, quantity_round_dp: int = 2, data_label: str | None = None)[source]
Bases:
AssetAssets whose price history is represented by High, Low, Open, Close and Volume fields.
- data_label: str | None = None
StrategyRunner.data column index 1st level label.
Defaults to name
- denom: str = 'USD'
Denominated currency.
- price_round_dp: int = 2
Number of decimal places to round prices to.
- quantity_round_dp: int = 2
Number of decimal places to round quantities to.
- round_quantity(quantity) Decimal
Round quantity.
- name: str
Name string.
- intraday_traded_price(asset_day_data: Series, size: Decimal | None = None) Decimal[source]
Calculate price during market hours with given row of asset_day_data and the order size.
The size can be used to determine a price from say, bid / ask spreads.