简体   繁体   中英

Anyone uses backtrader? How can I keep a reference in a method?

I'm trying to use backtrader module( https://www.backtrader.com/ ).

My purpose is just to compare the current price and the price of the last buy execution and execute sell() if the current price is lower than the last execution price.

I asked the same question to its community and the administrator said "You need to keep a reference to the order notified in notify_order, to later use it in next." However, I'm afraid I still don't understand how to do it, after reading through my python textbooks. ( https://community.backtrader.com/topic/298/how-can-i-get-the-price-at-which-buy-executed/5 )

In short, I want to refer to order.executed.price inside def next(self):

I'd appreciate it if I could get some hints on this problem. Thank you!

import datetime  # For datetime objects
import os.path  # To manage paths
import sys  # To find out the script name (in argv[0])

# Import the backtrader platform
import backtrader as bt


# Create a Stratey
class TestStrategy(bt.Strategy):
params = (
    ('maperiod', 15),
)

def log(self, txt, dt=None):
    ''' Logging function fot this strategy'''
    dt = dt or self.datas[0].datetime.date(0)
    print('%s, %s' % (dt.isoformat(), txt))

def __init__(self):
    # Keep a reference to the "close" line in the data[0] dataseries
    self.dataclose = self.datas[0].close

    # To keep track of pending orders and buy price/commission
    self.order = None
    self.buyprice = None
    self.buycomm = None

    # Add a MovingAverageSimple indicator
    self.sma = bt.indicators.SimpleMovingAverage(
        self.datas[0], period=self.params.maperiod)

    self.atr = bt.indicators.ATR(self.datas[0])
    self.stoch = bt.indicators.StochasticSlow(self.datas[0])
    self.ema14 = bt.indicators.ExponentialMovingAverage(self.datas[0], period=14)
    self.ema28 = bt.indicators.ExponentialMovingAverage(self.datas[0], period=28)
    self.rsi = bt.indicators.RSI(self.datas[0])

    # Indicators for the plotting show
    bt.indicators.ExponentialMovingAverage(self.datas[0], period=25)
    bt.indicators.WeightedMovingAverage(self.datas[0], period=25,
                                        subplot=True)
    bt.indicators.StochasticSlow(self.datas[0])
    bt.indicators.MACDHisto(self.datas[0])
    rsi = bt.indicators.RSI(self.datas[0])
    bt.indicators.SmoothedMovingAverage(rsi, period=10)
    bt.indicators.ATR(self.datas[0], plot=False)

def notify_order(self, order):
    if order.status in [order.Submitted, order.Accepted]:
        # Buy/Sell order submitted/accepted to/by broker - Nothing to do
        return

    # Check if an order has been completed
    # Attention: broker could reject order if not enougth cash
    if order.status in [order.Completed, order.Canceled, order.Margin]:
        if order.isbuy():
            self.log(
                'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                (order.executed.price,
                 order.executed.value,
                 order.executed.comm))

            self.buyprice = order.executed.price
            self.buycomm = order.executed.comm
        else:  # Sell
            self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                     (order.executed.price,
                      order.executed.value,
                      order.executed.comm))

        self.bar_executed = len(self)

    # Write down: no pending order
    self.order = None

def notify_trade(self, trade):
    if not trade.isclosed:
        return

    self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
             (trade.pnl, trade.pnlcomm))

def next(self):
    # Simply log the closing price of the series from the reference
    self.log('Close, %.2f' % self.dataclose[0])

    # Check if an order is pending ... if yes, we cannot send a 2nd one
    if self.order:
        return

    # Check if we are in the market
    if not self.position:

        # Not yet ... we MIGHT BUY if ...
        if self.stoch[0] > 80:

            # BUY, BUY, BUY!!! (with all possible default parameters)
            self.log('BUY CREATE, %.2f' % self.dataclose[0])

            # Keep track of the created order to avoid a 2nd order
            self.order = self.buy()

    else:
        if self.position.price < self.dataclose[0]:
            # SELL, SELL, SELL!!! (with all possible default parameters)
            self.log('SELL CREATE, %.2f' % self.dataclose[0])

            # Keep track of the created order to avoid a 2nd order
            self.order = self.sell()

In notify_order() you can say something like this:

self.last_executed_price = order.executed.price

Then you can use that variable inside other functions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM