arleigh418 / python-and-Taiwan-stock-market

Python 金融市場賺大錢聖經:寫出你的專屬指標
54 stars 17 forks source link

backtrader問題 #35

Open wst0310 opened 1 year ago

wst0310 commented 1 year ago

不好意思打擾了 照著書本複製官方文件程式碼逐步修改 至P4-46執行時發生錯誤 麻煩您指導了 謝謝

Traceback (most recent call last): File "D:\Trading\test.py", line 141, in cerebro.run() File "D:\Trading\env\lib\site-packages\backtrader\cerebro.py", line 1127, in run runstrat = self.runstrategies(iterstrat) File "D:\Trading\env\lib\site-packages\backtrader\cerebro.py", line 1210, in runstrategies data._start() File "D:\Trading\env\lib\site-packages\backtrader\feed.py", line 203, in _start self.start() File "D:\Trading\env\lib\site-packages\backtrader\feeds\yahoo.py", line 355, in start super(YahooFinanceData, self).start() File "D:\Trading\env\lib\site-packages\backtrader\feeds\yahoo.py", line 94, in start super(YahooFinanceCSVData, self).start() File "D:\Trading\env\lib\site-packages\backtrader\feed.py", line 674, in start self.f = io.open(self.p.dataname, 'r') FileNotFoundError: [Errno 2] No such file or directory: '2330.TW'

程式碼如下 from future import (absolute_import, division, print_function, unicode_literals)

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)

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 enough cash
    if order.status in [order.Completed]:
        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)

    elif order.status in [order.Canceled, order.Margin, order.Rejected]:
        self.log('Order Canceled/Margin/Rejected')

    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.dataclose[0] > self.sma[0]:

            # 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.dataclose[0] < self.sma[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()

if name == 'main':

Create a cerebro entity

cerebro = bt.Cerebro()

# Add a strategy
cerebro.addstrategy(TestStrategy)

# Datas are in a subfolder of the samples. Need to find where the script is
# because it could have been called from anywhere
# modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
# datapath = os.path.join(modpath, '../../datas/orcl-1995-2014.txt')

# Create a Data Feed
data = bt.feeds.YahooFinanceData(
    dataname='2330.TW',
    # Do not pass values before this date
    fromdate=datetime.datetime(2014, 1, 1),
    # Do not pass values before this date
    todate=datetime.datetime(2020, 12, 31),
    # Do not pass values after this date
    reverse=False)

# Add the Data Feed to Cerebro
cerebro.adddata(data)

# Set our desired cash start
cerebro.broker.setcash(1000000.0)

# Add a FixedSize sizer according to the stake
cerebro.addsizer(bt.sizers.FixedSize, stake=1000)

# Set the commission
cerebro.broker.setcommission(commission=0.0015)

# Print out the starting conditions
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())

# Run over everything
cerebro.run()

cerebro.plot()

# Print out the final result
print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
arleigh418 commented 1 year ago

您好, 這是backtrader從某一個版本以來的錯誤, 原因應是他使用了yfinance這個套件, yfinance這個套件有更新, 但是backtrader尚未配合更新,因此您參考看看4-48~4-50的Backtrader的可能問題之一 - FileNotFoundError,看看是否能解決您的問題

wst0310 commented 1 year ago

原來後面有提及 因執行挫折沒再往後翻 非常感謝您