Skip to content
All library documents

Backtrader Order Observer for Pending and Expired Buy Orders

Code backtrader

Summary

The document presents a Backtrader observer that plots the creation price of buy orders while they are submitted or accepted, and marks that price when a buy order expires. Separate plot markers distinguish created and expired orders. The observer filters pending orders to the data series it is watching and ignores sell orders, on the stated assumption that the strategy’s sells are market orders executed immediately.

This is an implementation example for visualizing order lifecycle events in a backtest. It does not describe a trading signal, execution study, or performance evaluation, and it provides no evidence about whether the underlying strategy is profitable. Its usefulness depends on the surrounding strategy’s order types and Backtrader behavior; the sell-order simplification may not apply in strategies that use pending or expiring sell orders.

Key ideas

  • The observer plots buy-order creation prices for submitted and accepted orders.
  • It marks the creation price when a buy order expires.
  • It filters events by the data series associated with the observer.
  • Sell orders are ignored because the example assumes they execute immediately as market orders.

Tags

Full text
# orderobserver.py


```py
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
###############################################################################
#
# Copyright (C) 2015-2023 Daniel Rodriguez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import math

import backtrader as bt


class OrderObserver(bt.observer.Observer):
    lines = ('created', 'expired',)

    plotinfo = dict(plot=True, subplot=True, plotlinelabels=True)

    plotlines = dict(
        created=dict(marker='*', markersize=8.0, color='lime', fillstyle='full'),
        expired=dict(marker='s', markersize=8.0, color='red', fillstyle='full')
    )

    def next(self):
        for order in self._owner._orderspending:
            if order.data is not self.data:
                continue

            if not order.isbuy():
                continue

            # Only interested in "buy" orders, because the sell orders
            # in the strategy are Market orders and will be immediately
            # executed

            if order.status in [bt.Order.Accepted, bt.Order.Submitted]:
                self.lines.created[0] = order.created.price

            elif order.status in [bt.Order.Expired]:
                self.lines.expired[0] = order.created.price

```

Shown in full with attribution under the source's licence. Licence: GPL-3.0

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.