Backtrader 是 Daniel Rodriguez 於 2013 年基於個人交易需求所開發的策略回測和實盤交易框架, 是 Python 量化交易領域最經典, 架構最完整的開放原始碼回測 (Backtesting) 框架之一, 後來經由社群貢獻了大量文檔, 範例和功能擴展. 隨著框架趨近穩定更新頻率隨之降低, 原作者轉移重心於 2021 年宣布不再主動維護和更新此框架, 但由於 Backtrader 的架構極其成熟且功能齊全, 使用社群仍非常活躍, 是入門到進階量化研究不可或缺的工具, 參考 :
# https://www.backtrader.com/docu/ (教學文件)
# https://github.com/backtrader/backtrader (GitHub)
iT 邦幫忙也有兩篇值得參考的文章 :
以下摘要整理從谷歌與 AI 搜尋到的 backtrader 資料.
1. 功能簡介 :
Backtrader 的核心功能是讓量化交易者可用 Python 清晰地描述一個交易策略, 並在歷史資料上精確模擬實際交易的結果, 其模擬的內容如下 :
- K 線逐根推進 (逐 tick 逐 bar)
- 依照策略邏輯決定買賣點
- 手續費, 稅, 滑價
- 部位, 資金, 風險控管
- 訂單與成交機制 (市價單, 限價單, 停損單)
- 資金單位, 合約單位
- 多部位, 空單
- 多股票組合 (Portfolio)
- 交易日, 非交易日跳空
- 交易時間同步, 資料對齊
它是真正模擬交易過程, 而非簡單地計算 "如果收盤價 > MA20 就買進". 這些功能若自行使用 pandas 來寫非常繁雜 (事實上 backtrader 內部就使用了 pandas 的 DataFrame 來處理和管理交易資料), 而這些功能 backtrader 都已實作出來. 它提供如下功能 :
- 回測 (Backtest)
- 多策略比較
- 多個股票同時回測 (Portfolio)
- 參數最佳化 (Optimizer)
- 技術指標 (150+)
- 自訂指標
- 自訂手續費, 稅
- 市價單, 限價單, 停損單
- 部分成交 (matching engine)
- 實盤交易 (支援 Interactive Brokers 與 CCXT crypto)
- 視覺化 (K 線, 指標, 買賣訊號)
Backtrader 是一個非常成熟的交易模擬器, 幾乎能涵蓋 95% 的量化交易研究需求.
一個完整的量化交易流程如下 :
資料抓取 → 資料清洗 → 策略設計 → 回測 → 參數優化 → 風險控管 → 策略組合 → 監控 → 實盤下單
而 backtrader 負責其中的策略設計, 回測, 參數優化, 再加上交易模擬與石盤交易 :
策略設計 → 回測 → 參數優化 → 交易模擬 → 實盤交易
Backtrader 資料來源支援下列四種 :
- Yahoo Finance
- FinLab
- pandas-datareader
- API
不過 backtrader 並非依賴 yfinance 從 Yahoo Finance 取得 K 線資料, 而是官方自己寫的爬蟲.
在回測領域除 backtrader 外還有諸如 vectorbt, backtesting.py, 與 Zipline 等類似的框架, 優缺點比較如下表 :
| 套件 | 優點 | 缺點 | 適合對象 |
|---|---|---|---|
| Backtrader | 最完整的交易模擬 + 實盤 | 官方停更 (2021) | 策略研究者、工程師 |
| vectorbt | 超快(NumPy/Numba) | 不易寫出複雜策略 | 量化團隊、研究速度 |
| backtesting.py | 超簡單、學習快 | 功能少 | 新手 |
| Zipline | 以前由 Quantopian 使用 | 安裝極難、老舊 | 不推薦 |
Backtrader 架構具有如下優點 :
- API 設計優美 (物件導向), 語法清楚可讀性高
- 極完整的回測功能 :多策略, 多股票, Portfolio 都能一次回測
- 相容性佳且可擴充性高 : 可自訂指標, 策略, Broker, 下單方法, 手續費與滑價模型
- 內建圖表有進場箭頭, K 線, 指標 : 不需寫任何 matplotlib 程式碼
- 教學文件非常豐富
其他框架常缺少像交易一樣的細節, backtrader 模擬交易細緻度是最頂級的.
2. 核心架構 :
Backtrader 將回測模擬成一個正在運轉的交易系統, 其核心由下列五個元件組成 :
- Cerebro :
Cerebro 是 Backtrader 的主引擎, 負責整合所有的策略, 資料源, 分析結果等. 它是執行回測和實盤交易的核心組件, 並且管理著整個交易過程. - Strategy :
Strategy 是用戶定義的策略邏輯, 包含了交易的決策過程. 用戶可以在這個類別中定義進出場的條件 (買賣點), 技術指標, 倉位控管 (風險管理) 等. - Data Feed :
DataFeed 是用來載入和管理股票或其他金融資產的 K 線資料 (Pandas DataFrame). Backtrader 支持多種資料源, 包括 CSV 文件, Yahoo Finance, Interactive Brokers 等. - Indicators :
Indicators 是用來計算和使用技術指標的元件, backtrader 提供了許多內建的技術指標, 例如移動平均, 相對強弱指標 (RSI) 等, 用戶也可以自定義指標. - Analyzer :
Analyzers 用於分析和評估策略的績效, 這些分析器可以計算各種指標, 例如年化報酬率, 夏普比率 (Sharpe Ratio), 最大回撤 (Maximum Drawdown) 等, 幫助用戶評估策略的表現. - Observers (附加元件) :
其中 Cerebro 是 backtrader 的大腦, 是整個系統的控制中心, 相當於是一台車的引擎, 而 Strategy 則是負責交易策略邏輯, 內建了技術指標, 下單買賣, 與部位控管功能, 其上下關係結構如下 :
Cerebro (大腦)
├── Strategy (買賣邏輯=策略)
│ ├── Indicators (技術指標)
│ ├── Orders (Buy/Sell) (下單)
│ └── Position (持倉部位)
├── DataFeed (K 線量價資料來源)
├── Broker (Cash/Value) (資金管理)
├── Sizers (下單大小)
├── Analyzers (Sharpe/Drawdown) (績效分析例如 Sharpe, 回撤)
└── Plot (視覺化)
3. 安裝 backtrader 套件 :
只要用 pip 即可安裝此套件 :
D:\python\test>pip install backtrader
Collecting backtrader
Downloading backtrader-1.9.78.123-py2.py3-none-any.whl.metadata (6.8 kB)
Downloading backtrader-1.9.78.123-py2.py3-none-any.whl (419 kB)
Installing collected packages: backtrader
Successfully installed backtrader-1.9.78.123
安裝好後匯入 backtrader 檢視版本 :
>>> import backtrader as bt
>>> bt.__version__
'1.9.78.123'
然後用自訂模組 members 的 list_members() 函式檢視 backtrader 內容, 參考 :
>>> from members import list_members
>>> list_members(bt)
AbstractDataBase <class 'backtrader.feed.MetaAbstractDataBase'>
All <class 'backtrader.linebuffer.MetaLineActions'>
Analyzer <class 'backtrader.analyzer.MetaAnalyzer'>
And <class 'backtrader.linebuffer.MetaLineActions'>
Any <class 'backtrader.linebuffer.MetaLineActions'>
AutoDictList <class 'type'>
AutoInfoClass <class 'type'>
AutoOrderedDict <class 'type'>
BackBroker <class 'backtrader.broker.MetaBroker'>
BacktraderError <class 'type'>
BrokerBase <class 'backtrader.broker.MetaBroker'>
BuyOrder <class 'backtrader.metabase.MetaParams'>
CSVDataBase <class 'backtrader.feed.MetaCSVDataBase'>
CSVFeedBase <class 'backtrader.metabase.MetaParams'>
Cerebro <class 'backtrader.metabase.MetaParams'>
Cmp <class 'backtrader.linebuffer.MetaLineActions'>
CmpEx <class 'backtrader.linebuffer.MetaLineActions'>
CommInfoBase <class 'backtrader.metabase.MetaParams'>
CommissionInfo <class 'backtrader.metabase.MetaParams'>
DTFaker <class 'type'>
DataAccessor <class 'backtrader.lineiterator.MetaLineIterator'>
DataBase <class 'backtrader.feed.MetaAbstractDataBase'>
DataClone <class 'backtrader.feed.MetaAbstractDataBase'>
DataSeries <class 'backtrader.lineseries.MetaLineSeries'>
DivByZero <class 'backtrader.linebuffer.MetaLineActions'>
DivZeroByZero <class 'backtrader.linebuffer.MetaLineActions'>
DotDict <class 'type'>
FeedBase <class 'backtrader.metabase.MetaParams'>
Filter <class 'backtrader.metabase.MetaParams'>
If <class 'backtrader.linebuffer.MetaLineActions'>
Indicator <class 'backtrader.indicator.MetaIndicator'>
IndicatorBase <class 'backtrader.lineiterator.MetaLineIterator'>
ItemCollection <class 'type'>
LineActions <class 'backtrader.linebuffer.MetaLineActions'>
LineAlias <class 'type'>
LineBuffer <class 'backtrader.lineroot.MetaLineRoot'>
LineCoupler <class 'function'>
LineDelay <class 'function'>
LineIterator <class 'backtrader.lineiterator.MetaLineIterator'>
LineMultiple <class 'backtrader.lineroot.MetaLineRoot'>
LineNum <class 'function'>
LineOwnOperation <class 'backtrader.linebuffer.MetaLineActions'>
LinePlotterIndicator <class 'backtrader.indicator.MtLinePlotterIndicator'>
LineRoot <class 'backtrader.lineroot.MetaLineRoot'>
LineSeries <class 'backtrader.lineseries.MetaLineSeries'>
LineSeriesMaker <class 'function'>
LineSeriesStub <class 'backtrader.lineseries.MetaLineSeries'>
LineSingle <class 'backtrader.lineroot.MetaLineRoot'>
Lines <class 'type'>
LinesCoupler <class 'function'>
LinesOperation <class 'backtrader.linebuffer.MetaLineActions'>
Lines_LineSeries <class 'type'>
Lines_LineSeries_LineSeriesStub <class 'type'>
List <class 'type'>
Logic <class 'backtrader.linebuffer.MetaLineActions'>
MAXINT <class 'int'>
Max <class 'backtrader.linebuffer.MetaLineActions'>
MetaAbstractDataBase <class 'type'>
MetaAnalyzer <class 'type'>
MetaBroker <class 'type'>
MetaCSVDataBase <class 'type'>
MetaIndicator <class 'type'>
MetaLineActions <class 'type'>
MetaLineIterator <class 'type'>
MetaLineSeries <class 'type'>
MetaObserver <class 'type'>
MetaParams <class 'type'>
MetaSigStrategy <class 'type'>
MetaStrategy <class 'type'>
MetaTimeFrameAnalyzerBase <class 'type'>
Min <class 'backtrader.linebuffer.MetaLineActions'>
MtLinePlotterIndicator <class 'type'>
MultiCoupler <class 'backtrader.lineiterator.MetaLineIterator'>
MultiLogic <class 'backtrader.linebuffer.MetaLineActions'>
MultiLogicReduce <class 'backtrader.linebuffer.MetaLineActions'>
NAN <class 'float'>
OHLC <class 'backtrader.lineseries.MetaLineSeries'>
OHLCDateTime <class 'backtrader.lineseries.MetaLineSeries'>
Observer <class 'backtrader.observer.MetaObserver'>
ObserverBase <class 'backtrader.lineiterator.MetaLineIterator'>
OptReturn <class 'type'>
Or <class 'backtrader.linebuffer.MetaLineActions'>
Order <class 'backtrader.metabase.MetaParams'>
OrderBase <class 'backtrader.metabase.MetaParams'>
OrderData <class 'type'>
OrderExecutionBit <class 'type'>
OrderedDict <class 'type'>
PandasMarketCalendar <class 'backtrader.metabase.MetaParams'>
Position <class 'type'>
PseudoArray <class 'type'>
Reduce <class 'backtrader.linebuffer.MetaLineActions'>
Replayer <class 'backtrader.metabase.MetaParams'>
ReplayerDaily <class 'backtrader.metabase.MetaParams'>
ReplayerMinutes <class 'backtrader.metabase.MetaParams'>
ReplayerMonthly <class 'backtrader.metabase.MetaParams'>
ReplayerSeconds <class 'backtrader.metabase.MetaParams'>
ReplayerTicks <class 'backtrader.metabase.MetaParams'>
ReplayerWeekly <class 'backtrader.metabase.MetaParams'>
Resampler <class 'backtrader.metabase.MetaParams'>
ResamplerDaily <class 'backtrader.metabase.MetaParams'>
ResamplerMinutes <class 'backtrader.metabase.MetaParams'>
ResamplerMonthly <class 'backtrader.metabase.MetaParams'>
ResamplerSeconds <class 'backtrader.metabase.MetaParams'>
ResamplerTicks <class 'backtrader.metabase.MetaParams'>
ResamplerWeekly <class 'backtrader.metabase.MetaParams'>
ResamplerYearly <class 'backtrader.metabase.MetaParams'>
SESSION_END <class 'int'>
SESSION_START <class 'int'>
SESSION_TIME <class 'int'>
SIGNAL_LONG <class 'int'>
SIGNAL_LONGEXIT <class 'int'>
SIGNAL_LONGEXIT_ANY <class 'int'>
SIGNAL_LONGEXIT_INV <class 'int'>
SIGNAL_LONGSHORT <class 'int'>
SIGNAL_LONG_ANY <class 'int'>
SIGNAL_LONG_INV <class 'int'>
SIGNAL_NONE <class 'int'>
SIGNAL_SHORT <class 'int'>
SIGNAL_SHORTEXIT <class 'int'>
SIGNAL_SHORTEXIT_ANY <class 'int'>
SIGNAL_SHORTEXIT_INV <class 'int'>
SIGNAL_SHORT_ANY <class 'int'>
SIGNAL_SHORT_INV <class 'int'>
SellOrder <class 'backtrader.metabase.MetaParams'>
Signal <class 'backtrader.indicator.MetaIndicator'>
SignalStrategy <class 'backtrader.strategy.MetaSigStrategy'>
SignalTypes <class 'list'>
SimpleFilterWrapper <class 'type'>
SingleCoupler <class 'backtrader.linebuffer.MetaLineActions'>
Sizer <class 'backtrader.metabase.MetaParams'>
SizerBase <class 'backtrader.metabase.MetaParams'>
SizerFix <class 'backtrader.metabase.MetaParams'>
StopBuyOrder <class 'backtrader.metabase.MetaParams'>
StopLimitBuyOrder <class 'backtrader.metabase.MetaParams'>
StopLimitSellOrder <class 'backtrader.metabase.MetaParams'>
StopSellOrder <class 'backtrader.metabase.MetaParams'>
Store <class 'backtrader.store.MetaSingleton'>
Strategy <class 'backtrader.strategy.MetaStrategy'>
StrategyBase <class 'backtrader.lineiterator.MetaLineIterator'>
StrategySkipError <class 'type'>
Sum <class 'backtrader.linebuffer.MetaLineActions'>
TimeFrame <class 'type'>
TimeFrameAnalyzerBase <class 'backtrader.analyzer.MetaTimeFrameAnalyzerBase'>
Timer <class 'backtrader.metabase.MetaParams'>
Trade <class 'type'>
TradeHistory <class 'type'>
TradingCalendar <class 'backtrader.metabase.MetaParams'>
TradingCalendarBase <class 'backtrader.metabase.MetaParams'>
WriterBase <class 'backtrader.metabase.MetaParams'>
WriterFile <class 'backtrader.metabase.MetaParams'>
WriterStringIO <class 'backtrader.metabase.MetaParams'>
absolute_import <class '__future__._Feature'>
analyzer <class 'module'>
analyzers <class 'module'>
array <class 'module'>
backtrader <class 'module'>
broker <class 'module'>
brokers <class 'module'>
bt <class 'module'>
calendar <class 'module'>
cerebro <class 'module'>
cmp <class 'function'>
collections <class 'module'>
collectionsAbc <class 'module'>
comminfo <class 'module'>
commissions <class 'module'>
comms <class 'module'>
copy <class 'module'>
dataseries <class 'module'>
date <class 'type'>
date2num <class 'function'>
datetime <class 'module'>
division <class '__future__._Feature'>
errors <class 'module'>
feed <class 'module'>
feeds <class 'module'>
filler <class 'module'>
fillers <class 'module'>
filter <class 'type'>
filters <class 'module'>
findowner <class 'function'>
flt <class 'module'>
functions <class 'module'>
functools <class 'module'>
ind <class 'module'>
indicator <class 'module'>
indicators <class 'module'>
inspect <class 'module'>
integer_types <class 'tuple'>
io <class 'module'>
islice <class 'type'>
iteritems <class 'function'>
itertools <class 'module'>
itervalues <class 'function'>
keys <class 'function'>
linebuffer <class 'module'>
lineiterator <class 'module'>
lineroot <class 'module'>
lineseries <class 'module'>
map <class 'type'>
math <class 'module'>
mathsupport <class 'module'>
metabase <class 'module'>
multiprocessing <class 'module'>
num2date <class 'function'>
num2time <class 'function'>
obs <class 'module'>
observer <class 'module'>
observers <class 'module'>
operator <class 'module'>
order <class 'module'>
os <class 'module'>
position <class 'module'>
pp <class 'module'>
print_function <class '__future__._Feature'>
range <class 'type'>
resamplerfilter <class 'module'>
signal <class 'module'>
signals <class 'module'>
sizer <class 'module'>
sizers <class 'module'>
store <class 'module'>
stores <class 'module'>
strategies <class 'module'>
strategy <class 'module'>
strats <class 'module'>
string_types <class 'tuple'>
studies <class 'module'>
sys <class 'module'>
talib <class 'module'>
time2num <class 'function'>
timedelta <class 'type'>
timer <class 'module'>
trade <class 'module'>
tradingcal <class 'module'>
tzparse <class 'function'>
unicode_literals <class '__future__._Feature'>
utils <class 'module'>
version <class 'module'>
with_metaclass <class 'function'>
writer <class 'module'>
zip <class 'type'>
其中 Cerebro 是在使用 Backtrader 時最常接觸的類別.
4. 回測程式結構 :
撰寫回測程式必須繼承 backtrader.Strategy 類別自訂一個策略類別, 其基本結構如下 :
# my_strategy.py
import backtrader as bt
class MyStrategy(bt.Strategy)
# 1. 定義參數
params=()
# 2. 定義會用到的資料
def __init__(self):
pass
# 3. 輸出策略運行訊息 (可有可無)
def log():
pass
# 4. 追蹤訂單狀態 & 發出通知 (可有可無)
def notify_order(self, order):
pass
# 5. 交易結果通知 (可有可無)
def notify_trade(self, trade):
pass
# 6. 交易策略 (核心部分)
def next(self):
pass
其中初始化方法 __init__(), 與交易策略方法 next() 兩者為必要的; 類別變數 params 與 log(), notify_order(), 與 notify_trade() 則是可有可無的, 其功用說明如下 :
- params 變數 :
用來定義策略的可配置參數, 讓使用者在建立策略物件時可以傳遞不同的參數值, 例如定義移動平均 ma 的週期或幾點停損, 風險管理參數等, 這樣在撰寫回測或實盤交易策略時可以輕鬆調整這些值, 而不必修改策略的程式碼. 另外一個常見用途是設定一個 range() 值來跑最優參數. 此類別變數值為一個 tuple, 元素也是一個 tuple, 例如 :
params=(('maperiod', 5),) - __init__() 方法 :
此為呼叫類別建構式時首先執行的函式, 用來初始化物件, 傳入參數 self 為物件本身, 在此方法中會利用此 self 定義物件的屬性並賦值 (此即初始化), 以便在其它方法中可以使用這些屬性值. - log() 方法 :
用來在策略運行時輸出重要的日誌訊息, 以便於觀察並記錄策略的表現, 提升策略的可讀性和可維護性. 可根據需求來定義 log() 方法, 以便將訊息輸出到控制台, 文件或其他日誌系統中. - notify_order() 方法 :
用於接收訂單狀態的通知, 當訂單的狀態發生變化時 (例如已提交, 已執行, 已取消等), 此方法會被自動呼叫, 功用類似券商軟體的委託單查詢. - notify_trade() 方法 :
用於接收交易狀態的通知, 當交易的狀態發生變化時, 例如開倉 (股票為買入) 平倉 (股票為賣出) 等, 此方法會被自動呼叫, 平倉時可以輸出獲利訊息; 開倉時可以輸出庫存價格與持倉量, 也可以不做任何動作. 此方法功用類似券商軟體的已/未實現損益查詢. - next() 方法 :
此為策略的核心方法, 用來定義交易邏輯, 例如進出場的條件, 可根據當前價格與指標值進行交易決策, 每當有新的資料點進入時就會自動呼叫 next() 方法. 此方法相當於一個隱形的迴圈, Backtrader 程式會從資料起始處逐一讀取每根 K 線, 然後呼叫 next() 執行一次交易策略, 在此方法中可以用 self.data 屬性取得量價資料與技術指標 (都是 Series), 例如 :
self.data.close[0] : 最新一根 K 線收盤價
self.data.close[-1] : 前一根 K 線收盤價
self.data.close[-2] : 前兩根 K 線收盤價
self.sma[0] : 最新一根 K 線 SMA 值
self.rsi[-1] : 前一根 K 線 SRI 值
建立一個 Backtrader 回測程式的步驟如下 :
(2). 建立 Cerebro 物件 :
(3). 載入 K 線資料
(4). 設定 Broker (資金, 手續費)
(5). 加入 Strategy
(6). 加入 Analyzer / Sizer / Observer
(7). 執行 cerebro.run()
(8). 輸出績效
(9). 繪圖
下面是一個簡單的 5ma 向上突破 20 ma 買進, 向下跌破賣出台積電的回測範例 :
# backtrader_test_1.py
import backtrader as bt
import yfinance as yf
class MyStrategy(bt.Strategy):
def __init__(self):
self.fast=bt.ind.SMA(self.data.close, period=5)
self.slow=bt.ind.SMA(self.data.close, period=20)
self.crossover=bt.ind.CrossOver(self.fast, self.slow)
def next(self):
if not self.position:
if self.crossover > 0:
self.buy()
else:
if self.crossover < 0:
self.close()
# 建立 Cerebro 主引擎物件
cerebro=bt.Cerebro()
# 加上策略
cerebro.addstrategy(MyStrategy)
# 加上 K 線資料
df=yf.download('2330.TW', start='2024-01-01', end='2025-01-01', auto_adjust=False)
df.columns=df.columns.map(lambda x: x[0]) # 欄位單層化
data=bt.feeds.PandasData(dataname=df)
cerebro.adddata(data)
# 設定初始資金
cerebro.broker.setcash(1_000_000)
print('初始資金: %.2f' % cerebro.broker.getvalue())
# 跑回測
result=cerebro.run()
# 輸出期末資產總額
print('期末資金: %.2f' % cerebro.broker.getvalue())
# 畫圖
cerebro.plot()
此例繼承 bt.Strategy 定義一個 MyStrategy 類別, 在 __init__() 初始化時呼叫內建的 SMA() 與 CrossOver() 函式計算移動平均線的快線 (5ma), 慢線 (20 ma), 以及是否發生交越的屬性 slow, fast, 與 crossover; 並於 next() 中定義交易策略, cross 屬性黃金交叉時買進; 死亡交叉時賣出. 接著呼叫 bt.Cerebro() 建立 Cerebro 物件後呼叫其 addstrategy() 方法並傳入 MyStrategy 類別.
然後利用 yfinance 取得台積電 (2330.TW) 2024 年的量價資料並轉成 PandasData 物件, 呼叫 Cerebro 物件的 adddata() 方法傳入此 PandasData 物件做為資料源, 最後設定初始資金 100 萬元, 呼叫 Cerebro 物件的 run() 方法跑回測, 結果如下 :
>>> %Run backtrader_test_1.py
[*********************100%***********************] 1 of 1 completed
初始資金: 1000000.00
期末資金: 1000157.00
哈哈, 用這策略交易了一年才賺到 157 元!
如果納入手續費會更少, 例如 :
# backtrader_test_2.py
import backtrader as bt
import yfinance as yf
class MyStrategy(bt.Strategy):
def __init__(self):
self.fast=bt.ind.SMA(self.data.close, period=5)
self.slow=bt.ind.SMA(self.data.close, period=20)
self.crossover=bt.ind.CrossOver(self.fast, self.slow)
def next(self):
if not self.position:
if self.crossover > 0:
self.buy()
else:
if self.crossover < 0:
self.close()
# 建立 Cerebro 主引擎物件
cerebro=bt.Cerebro()
# 加上策略
cerebro.addstrategy(MyStrategy)
# 加上 K 線資料
df=yf.download('2330.TW', start='2024-01-01', end='2025-01-01', auto_adjust=True)
df.columns=df.columns.map(lambda x: x[0]) # 欄位單層化
data=bt.feeds.PandasData(dataname=df)
cerebro.adddata(data)
# 設定初始資金
cerebro.broker.setcash(1_000_000)
print('初始資金: %.2f' % cerebro.broker.getvalue())
# 跑回測
cerebro.broker.setcommission(commission=0.001425) # 設定手續費率
result=cerebro.run()
# 輸出期末資產總額
print('期末資金: %.2f' % cerebro.broker.getvalue())
# 畫圖
cerebro.plot()
回測結果如下 :
>>> %Run backtrader_test_2.py
[*********************100%***********************] 1 of 1 completed
初始資金: 1000000.00
期末資金: 1000146.17

沒有留言 :
張貼留言