内部策略中,我初始化了一些新指标,但没有触及买卖逻辑。但是,我最终的投资组合价值却发生了变化。经过多次测试,这是一个一致的变化。在添加了这些指标以定义初始值后,我再也没有强调过这一点,我再也没有触及过买卖逻辑。我一直在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()