backtrader.observers.buysell 源代码

#!/usr/bin/env python
"""BuySell Observer Module - Buy/sell signal visualization.

This module provides the BuySell observer for visualizing buy and sell
orders on the chart.

Classes:
    BuySell: Observer that plots buy/sell markers on the chart.

Example:
    >>> cerebro = bt.Cerebro()
    >>> cerebro.addobserver(bt.observers.BuySell)
"""

import math

from ..observer import Observer


# Buy and sell point markers
[文档] class BuySell(Observer): """ This observer keeps track of the individual buy/sell orders (individual executions) and will plot them on the chart along the data around the execution price level Params: - ``barplot`` (default: ``False``) Plot buy signals below the minimum and sell signals above the maximum. If `False`, it will plot on the average price of executions during a bar - ``bardist`` (default: ``0.015`` 1.5%) Distance to max/min when ``barplot`` is ``True`` """ lines = ( "buy", "sell", ) plotinfo = dict(plot=True, subplot=False, plotlinelabels=True) plotlines = dict( buy=dict(marker="^", markersize=8.0, color="lime", fillstyle="full", ls=""), sell=dict(marker="v", markersize=8.0, color="red", fillstyle="full", ls=""), ) params = ( ("barplot", False), # plot above/below max/min for clarity in bar plot ("bardist", 0.015), # distance to max/min in absolute perc ) def __init__(self): """Initialize the BuySell observer. Sets up tracking for buy/sell order lengths. """ self.curbuylen = None
[文档] def next(self): """Update buy/sell markers based on executed orders. Calculates average prices for buy and sell orders during the bar. """ buy = list() sell = list() # If there are pending orders for order in self._owner._orderspending: # If no data or size is 0, skip if order.data is not self.data or not order.executed.size: continue # If it's a buy order, add price to buy, if it's a sell order, add price to sell if order.isbuy(): buy.append(order.executed.price) else: sell.append(order.executed.price) # Take into account replay ... something could already be in there # Write down the average buy/sell price # BUY # Get buy price curbuy = self.lines.buy[0] # If NaN, curbuy equals 0, curbuylen=0, otherwise, curbuylen = self.curbuylen if curbuy != curbuy: # NaN curbuy = 0.0 self.curbuylen = curbuylen = 0 else: curbuylen = self.curbuylen # Current total price buyops = curbuy + math.fsum(buy) # Current total order count buylen = curbuylen + len(buy) # Calculate average price value = buyops / float(buylen or "NaN") # If not plotting, get average price, if plotting, get a percentage of lowest price for better display if not self.p.barplot: self.lines.buy[0] = value elif value == value: # Not NaN pbuy = self.data.low[0] * (1 - self.p.bardist) self.lines.buy[0] = pbuy # Update buylen values curbuy = buyops self.curbuylen = buylen # For sell orders, similar logic # SELL cursell = self.lines.sell[0] if cursell != cursell: # NaN cursell = 0.0 self.curselllen = curselllen = 0 else: curselllen = self.curselllen sellops = cursell + math.fsum(sell) selllen = curselllen + len(sell) value = sellops / float(selllen or "NaN") if not self.p.barplot: self.lines.sell[0] = value elif value == value: # Not NaN psell = self.data.high[0] * (1 + self.p.bardist) self.lines.sell[0] = psell # Update selllen values cursell = sellops self.curselllen = selllen