Backtrader-Python初始化指标更改投资组合价值而未更改买/卖逻辑

时间:2020-09-14 17:27:29

标签: python finance backtrader

内部策略中,我初始化了一些新指标,但没有触及买卖逻辑。但是,我最终的投资组合价值却发生了变化。经过多次测试,这是一个一致的变化。在添加了这些指标以定义初始值后,我再也没有强调过这一点,我再也没有触及过买卖逻辑。我一直在init的“检查长期趋势”部分中进行切换,以得到不同的结果。如果有人看到我做错了事,将不胜感激。

import backtrader as bt
import numpy as np
import pandas as pd
from stockstats import StockDataFrame as sdf
import talib
import math

desired_width=320
pd.set_option('display.width', desired_width)

pd.set_option('display.max_columns',36)

f = open("backtrader_output.txt", "a")

cash = 6000


class MainStrat(bt.Strategy):
    params = (('BBandsperiod', 20), ('order_pct', 1), ('fast', 50), ('slow', 200))

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

        f.write(row_output)
        f.write('\n')

    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
        self.buy_close = None
        self.counter1 = 0
        self.stake_to_cash = None
        self.six_thousand = None
        self.cash_to_trade = 6000
        self.sell_check = 0

        # Check long term trends
        self.fast_moving_average = bt.indicators.SMA(
            self.data.close, period=self.params.fast, plotname='50 day moving average'
        )
        self.slow_moving_average = bt.indicators.SMA(
            self.data.close, period=self.params.slow, plotname='200 day moving average'
        )

        self.crossover = bt.indicators.CrossOver(self.fast_moving_average, self.slow_moving_average)

        # Add a BBand indicator
        self.bband = bt.indicators.BBands(self.data.close, period=self.params.BBandsperiod)

    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])

        self.stake_to_cash = (1 / self.data.close[0])
        self.six_thousand = self.cash_to_trade * self.stake_to_cash
        self.six_thousand = math.floor(self.six_thousand)

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

        if self.dataclose <= self.bband.lines.bot and not self.position:
            # 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
            # if self.broker.cash >=6000:
            #     self.order = self.buy(size=self.six_thousand)
            # else:
            #     self.order = self.buy(size=math.floor(self.broker.cash * self.stake_to_cash))
            self.buy_close = self.data.close[0]
            self.order = self.buy()


         # Gain/Loss
        # if self.buy_close != None and self.data.close[0] != None:
        #      x = self.data.close[0] / self.buy_close
        #      print(str(x))
        #      print('Ratio')

        # Acceptable gain stop
        if self.position:
            self.sell_check = 0
            if (self.dataclose / self.buy_close) > 1.025:
                self.order = self.sell()
                # print('dskjlsdskljnsfkjnfskjnfdkjndfkjndfkjnfd')
                self.sell_check = 1
            # Check if pos has already been sold
            if self.sell_check != 1:
                # Check if we need to sell because it hit upper band
                if self.dataclose >= self.bband.lines.top and self.position:
                    # SELL, SELL, SELL!!! (with all possible default parameters)
                    self.log('SELL CREATE, %.2f' % self.dataclose[0])
                    # Keep track of the created o

避免第二次订购 self.order = self.sell()

0 个答案:

没有答案