我试图复制其中一种策略只是为了练习目的。我收到上述关于我的交叉指标的消息。你能帮忙看看可能出了什么问题吗?非常感谢!
我想在 rsi 小于 30 时买入,在 rsi 高于 55 时卖出
哪一行“日志”是错误的,我该如何解决?
请看下面我的代码:
import FinanceDataReader as fdr
import backtrader as bt
# Create a Stratey
class TestStrategy(bt.Strategy):
params = (
('maperiod', 200),
('rsi_period', 4),
('rsi_entry', 30),
('rsi_exit', 55),
)
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
# Add a MovingAverageSimple indicator
self.sma = bt.indicators.SimpleMovingAverage(self.datas[0], period=self.params.maperiod)
self.rsi = bt.indicators.RSI_Safe(self.datas[0], period=self.params.rsi_period)
self.n_wins = 0
self.n_losses = 0
self.profits = 0
self.losses = 0
def notify_trade(self, trade):
if not trade.isclosed:
return
self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
(trade.pnl, trade.pnlcomm))
if trade.pnl > 0:
self.n_wins += 1
self.profits += trade.pnl
else:
self.n_losses += 1
self.losses += trade.pnl
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.dataclose[0] > self.sma[0] and self.rsi[0] <= self.p.rsi_entry:
# 2003-05-19, BUY CREATE, 92.65
# 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.rsi[0] >= self.p.rsi_exit:
# 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()
def stop(self):
win_ratio = self.n_wins / (self.n_wins + self.n_losses)
avg_profit = self.profits / self.n_wins
avg_loss = self.losses / self.n_losses
profit_loss_ratio = avg_profit / avg_loss
expected_profit_per_trade = win_ratio * avg_profit + (1-win_ratio) * avg_loss
print(f"win_ratio: {win_ratio:.2f}, "
f"profit_loss_ratio: {profit_loss_ratio:.2f}, "
f"expected_profit_per_trade: {expected_profit_per_trade:.2f}")
if __name__ == '__main__':
cerebro = bt.Cerebro()
cerebro.addstrategy(TestStrategy)
# spy = fdr.DataReader('SPY', '2000-01-01', '2005-05-30')
spy = fdr.DataReader('SPY', '2000-01-01', '2010-12-31')
# spy = fdr.DataReader('SPY', '1990-01-01', "1999-12-31")
data = bt.feeds.PandasData(dataname=spy)
cerebro.adddata(data)
# Set our desired cash start
cerebro.broker.setcash(10000.0)
# Add a FixedSize sizer according to the stake
cerebro.addsizer(bt.sizers.PercentSizer, percents=90)
# Print out the starting conditions
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
# Run over everything
cerebro.run()
# Print out the final result
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
cerebro.plot(style='candlestick', barup="red", bardown="blue")
# 1993-11-12 ~ 2021-07-30
# win_ratio: 0.81, profit_loss_ratio: -0.71, expected_profit_per_trade: 166.32
# 1993-11-12 ~ 1999-12-31
# win_ratio: 0.84, profit_loss_ratio: -1.04, expected_profit_per_trade: 151.02
# 2000-01-01 ~ 2010-12-31
# win_ratio: 0.78, profit_loss_ratio: -0.91, expected_profit_per_trade: 69.30
# 2011-01-01 ~ 2021-07-30
# win_ratio: 0.79, profit_loss_ratio: -0.75, expected_profit_per_trade: 75.95