有一个泡菜文件,有许多股票名称(比如10),也有一个文件夹,其中有所有的股票数据,我试图运行的代码做MACD分析,并希望能够写下的结果,买卖时间,价格,头寸,现金在手边。当我走到这一步,试图在所有股票上运行MACD。但是经过两个循环,数据加载是错误的。并重复结果。
'''
import backtrader as bt
import pandas as pd
import pickle
import math
def run_test_macd():
with open("sp500tickers.pickle", "rb") as f:
tickers = pickle.load(f)
cerebro.addstrategy(GoldenCross.gold_cross_class)
for ticker in tickers:
macd_stock_test2(ticker)
def macd_stock_test2(ticker):
# print("stock test")
# print("ticker")
cerebro.broker.set_cash(1000000)
ticker_prices = pd.read_csv('stock_dfs/{}.csv'.format(ticker), index_col='Date', parse_dates=True)
# print(ticker_prices)
# ticker prices
feed = bt.feeds.PandasData(dataname=ticker_prices)
print(feed)
print(ticker)
cerebro.adddata(feed)
# cerebro.addsizer(bt.sizers.FixedSize, stake=1000)
# cerebro.addanalyzer(btanalyzers.DrawDown, _name='drawdown')
# cerebro.addanalyzer(btanalyzers.DrawDown, _name='returns')
print('starting protfolio value: %.2f' % cerebro.broker.getvalue())
cerebro.run()
print('final protfolio value: %.2f' % cerebro.broker.getvalue())
# cerebro.addanalyzer(SQN)
#
# cerebro.addwriter(bt.WriterFile, csv=args.writercsv, rounding=2)
# cerebro.plot(style='candle')
class gold_cross_class(bt.Strategy):
#set parameters to define fast and slow
params = (('fast',40),('slow',150),('order_percentage',0.99),('ticker', "stock"))
#define constractors
def __init__(self):
print("position size:",self.position.size)
self.fast_moving_average=bt.indicators.EMA(
self.data.close, period=self.params.fast, plotname='40 day moving average'
)
self.slow_moving_average = bt.indicators.EMA(
self.data.close, period=self.params.slow, plotname='150 day moving average'
)
self.crossover = bt.indicators.CrossOver(self.fast_moving_average, self.slow_moving_average)
def next(self):
if self.position.size == 0:
if self.crossover >0:
amount_to_invest = (self.params.order_percentage *self.broker.cash)
self.size=math.floor(amount_to_invest/self.data.close)
print("Buy {} shares of {} at {} on {}".format(self.size,self.params.ticker, self.data.close[0],self.data.close[0]))
self.buy(size=self.size)
if self.position.size > 0:
if self.crossover<0:
print("Sell {} shares of {} at {}".format(self.size,self.params.ticker, self.data.close[0]))
self.sell(size=self.size)
'''发布于 2021-04-08 00:16:22
请参阅代码开头的docstring中的注释。我已经注释掉了您的一些数据加载,这样我就可以加载自己的数据,因为我没有您的数据。
import datetime
import backtrader as bt
import pandas as pd
import pickle
import math
"""
You have a number of issues.
1. Establish cerebro in `macd_stock_test2`
2. Call the `run_test_macd` from if __name__ == "__main__":
3. Add in print log
4. Add in order and trade notify.
5. Don't pass in the strategy, create it in `macd_stock_test2`.
6. Change name of GoldCross class to python standard.
"""
def run_test_macd():
# with open("sp500tickers.pickle", "rb") as f:
# tickers = pickle.load(f)
tickers = ["TSLA", "FB"]
for ticker in tickers:
macd_stock_test2(ticker)
def macd_stock_test2(ticker):
# print("stock test")
# print("ticker")
cerebro = bt.Cerebro()
cerebro.addstrategy(GoldCross)
cerebro.broker.set_cash(1000000)
# ticker_prices = pd.read_csv(
# "stock_dfs/{}.csv".format(ticker), index_col="Date", parse_dates=True
# )
# print(ticker_prices)
# ticker prices
# feed = bt.feeds.PandasData(dataname=ticker_prices)
# print(feed)
# print(ticker)
feed = bt.feeds.YahooFinanceData(
dataname=ticker,
timeframe=bt.TimeFrame.Days,
fromdate=datetime.datetime(2019, 1, 1),
todate=datetime.datetime(2020, 12, 31),
reverse=False,
)
cerebro.adddata(feed)
# cerebro.addsizer(bt.sizers.FixedSize, stake=1000)
# cerebro.addanalyzer(btanalyzers.DrawDown, _name='drawdown')
# cerebro.addanalyzer(btanalyzers.DrawDown, _name='returns')
print("starting portfolio value: %.2f" % cerebro.broker.getvalue())
cerebro.run()
print("final portfolio value: %.2f" % cerebro.broker.getvalue())
# cerebro.addanalyzer(SQN)
#
# cerebro.addwriter(bt.WriterFile, csv=args.writercsv, rounding=2)
# cerebro.plot(style='candle')
class GoldCross(bt.Strategy):
# set parameters to define fast and slow
params = (
("fast", 40),
("slow", 150),
("order_percentage", 0.99),
("ticker", "stock"),
)
# define constractors
def __init__(self):
print("position size:", self.position.size)
self.fast_moving_average = bt.indicators.EMA(
self.data.close, period=self.params.fast, plotname="40 day moving average"
)
self.slow_moving_average = bt.indicators.EMA(
self.data.close, period=self.params.slow, plotname="150 day moving average"
)
self.crossover = bt.indicators.CrossOver(
self.fast_moving_average, self.slow_moving_average
)
def log(self, txt, dt=None):
""" Logging function fot this strategy"""
dt = dt or self.data.datetime[0]
if isinstance(dt, float):
dt = bt.num2date(dt)
print("%s, %s" % (dt.date(), txt))
def notify_order(self, order):
""" Triggered upon changes to orders. """
# Suppress notification if it is just a submitted order.
if order.status == order.Submitted:
return
# Print out the date, security name, order number and status.
dt, dn = self.datetime.date(), order.data._name
type = "Buy" if order.isbuy() else "Sell"
self.log(
f"{order.data._name:<6} Order: {order.ref:3d}\tType: {type:<5}\tStatus"
f" {order.getstatusname():<8} \t"
f"Size: {order.created.size:9.4f} Price: {order.created.price:9.4f} "
f"Position: {self.getposition(order.data).size}"
)
if order.status == order.Margin:
return
# Check if an order has been completed
if order.status in [order.Completed]:
self.log(
f"{order.data._name:<6} {('BUY' if order.isbuy() else 'SELL'):<5} "
# f"EXECUTED for: {dn} "
f"Price: {order.executed.price:6.2f} "
f"Cost: {order.executed.value:6.2f} "
f"Comm: {order.executed.comm:4.2f} "
f"Size: {order.created.size:9.4f} "
)
def notify_trade(self, trade):
"""Provides notification of closed trades."""
if trade.isclosed:
self.log(
"{} Closed: PnL Gross {}, Net {},".format(
trade.data._name,
round(trade.pnl, 2),
round(trade.pnlcomm, 1),
)
)
def next(self):
if self.position.size == 0:
if self.crossover > 0:
amount_to_invest = self.params.order_percentage * self.broker.cash
self.size = math.floor(amount_to_invest / self.data.close)
self.log(
"Buy {} shares of {} at {}".format(
self.size,
self.params.ticker,
self.data.close[0],
)
)
self.buy(size=self.size)
if self.position.size > 0:
if self.crossover < 0:
self.log(
"Sell {} shares of {} at {}".format(
self.size, self.params.ticker, self.data.close[0],
)
)
self.sell(size=self.size)
if __name__ == "__main__":
run_test_macd()打印如下:
starting protfolio value: 1000000.00
position size: 0
2019-10-28, Buy 15105 shares of stock at 65.54
2019-10-29, TSLA Order: 1 Type: Buy Status Accepted Size: 15105.0000 Price: 65.5400 Position: 15105
2019-10-29, TSLA Order: 1 Type: Buy Status Completed Size: 15105.0000 Price: 65.5400 Position: 15105
2019-10-29, TSLA BUY Price: 64.00 Cost: 966720.00 Comm: 0.00 Size: 15105.0000
final protfolio value: 10527931.90
starting protfolio value: 1000000.00
position size: 0
2020-05-12, Buy 4712 shares of stock at 210.1
2020-05-13, FB Order: 2 Type: Buy Status Accepted Size: 4712.0000 Price: 210.1000 Position: 4712
2020-05-13, FB Order: 2 Type: Buy Status Completed Size: 4712.0000 Price: 210.1000 Position: 4712
2020-05-13, FB BUY Price: 209.43 Cost: 986834.16 Comm: 0.00 Size: 4712.0000
final protfolio value: 1294217.28
Process finished with exit code 0https://stackoverflow.com/questions/66993608
复制相似问题