### Python Backtrader Cerebro Main Engine Setup Source: https://context7.com/cn-vhql/backtrader/llms.txt Initializes and configures the backtrader cerebro engine for backtesting. This includes setting starting capital, commission rates, adding data feeds, incorporating strategies and sizers, and defining analyzers for performance metrics. ```python import backtrader as bt from datetime import datetime # Create cerebro instance cerebro = bt.Cerebro() # Configure broker settings cerebro.broker.set_cash(100000) # Starting capital cerebro.broker.setcommission(commission=0.001) # 0.1% commission # Add data feed data = bt.feeds.BacktraderCSVData( dataname='stock_data.csv', fromdate=datetime(2020, 1, 1), todate=datetime(2021, 12, 31), timeframe=bt.TimeFrame.Days ) cerebro.adddata(data) # Add strategy with parameters cerebro.addstrategy(MyStrategy, period=20, printlog=True) # Add position sizer cerebro.addsizer(bt.sizers.PercentSizer, percents=10) # Add analyzers for performance metrics cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe') cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown') cerebro.addanalyzer(bt.analyzers.Returns, _name='returns') # Print starting conditions print(f'Starting Portfolio Value: {cerebro.broker.getvalue():.2f}') # Run backtest results = cerebro.run() strat = results[0] # Print final results print(f'Final Portfolio Value: {cerebro.broker.getvalue():.2f}') print(f'Sharpe Ratio: {strat.analyzers.sharpe.get_analysis()}') print(f'Max Drawdown: {strat.analyzers.drawdown.get_analysis()["max"]["drawdown"]:.2f}%') # Plot results cerebro.plot(style='candlestick') ``` -------------------------------- ### Backtrader Strategy Lifecycle Methods in Python Source: https://context7.com/cn-vhql/backtrader/llms.txt Demonstrates the core methods of a Backtrader strategy, including initialization (__init__), start, prenext, nextstart, next, and stop. These methods define the execution flow and trading logic throughout the backtesting process. The 'next' method contains the primary trading decisions based on a Simple Moving Average (SMA) indicator. ```python import backtrader as bt class MyStrategy(bt.Strategy): def __init__(self): # Conception phase - create indicators self.sma = bt.indicators.SimpleMovingAverage(self.data, period=15) self.order = None def start(self): # Birth phase - called before backtesting begins self.log('Strategy starting') def prenext(self): # Childhood phase - called before minimum period met self.log(f'Waiting for data: {len(self)} bars processed') def nextstart(self): # Transition from prenext to next (called once) self.log('Minimum period met, entering main strategy') self.next() def next(self): # Adulthood phase - main strategy logic if self.order: return # Pending order exists if not self.position: if self.sma[0] > self.data.close[0]: self.order = self.buy() else: if self.sma[0] < self.data.close[0]: self.order = self.sell() def stop(self): # Death phase - cleanup and final calculations self.log(f'Strategy ending with portfolio value: {self.broker.getvalue()}') def log(self, txt): print(f'{self.data.datetime.date(0)}: {txt}') ``` -------------------------------- ### Manage Portfolio with Backtrader Order Target Methods Source: https://context7.com/cn-vhql/backtrader/llms.txt Shows how to use order target methods in backtrader for rebalancing positions to specific target sizes, values, or portfolio percentages. This is crucial for effective portfolio management and includes examples for single and multiple data feeds. Requires the backtrader library. ```python import backtrader as bt class TargetOrderStrategy(bt.Strategy): def __init__(self): self.counter = 0 def next(self): self.counter += 1 # Rebalance every 20 bars if self.counter % 20 != 0: return # Target specific position size (number of shares) # If position < target: buy difference # If position > target: sell difference self.order_target_size(target=100) # Target specific dollar value # Hold exactly $10,000 worth of the asset self.order_target_value(target=10000.0) # Target percentage of portfolio # Hold 20% of total portfolio value in this asset self.order_target_percent(target=0.2) # Multiple data feeds - rebalance portfolio if len(self.datas) > 1: # 40% in first asset self.order_target_percent(data=self.datas[0], target=0.4) # 30% in second asset self.order_target_percent(data=self.datas[1], target=0.3) # 30% in third asset (remaining cash) self.order_target_percent(data=self.datas[2], target=0.3) ``` -------------------------------- ### Add Backtrader Analyzers and Run Backtest Source: https://context7.com/cn-vhql/backtrader/llms.txt Adds several common analyzers (SharpeRatio, DrawDown, Returns, TradeAnalyzer, SQN, VWR, TimeReturn) to a Backtrader cerebro instance and then executes the backtest. Requires the backtrader library to be installed. The 'cerebro' object is the main engine for backtesting. ```python import backtrader as bt # Assume 'cerebro' is an initialized Backtrader Cerebro instance cerebro = bt.Cerebro() # Add analyzers cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe', riskfreerate=0.01) cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown') cerebro.addanalyzer(bt.analyzers.Returns, _name='returns') cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name='trades') cerebro.addanalyzer(bt.analyzers.SQN, _name='sqn') # System Quality Number cerebro.addanalyzer(bt.analyzers.VWR, _name='vwr') # Variability-Weighted Return cerebro.addanalyzer(bt.analyzers.TimeReturn, _name='timereturn') # Run backtest results = cerebro.run() strat = results[0] ``` -------------------------------- ### Backtrader Analyzers for Performance Metrics Source: https://context7.com/cn-vhql/backtrader/llms.txt Illustrates the integration of backtrader's analyzers to calculate performance metrics such as Sharpe ratio, drawdown, returns, and trade statistics. This setup requires adding a strategy and data feed to the `Cerebro` instance before adding analyzers. ```python import backtrader as bt cerebro = bt.Cerebro() # Add data and strategy data = bt.feeds.BacktraderCSVData(dataname='data.csv') cerebro.adddata(data) cerebro.addstrategy(MyStrategy) ``` -------------------------------- ### Python Backtrader CSV Data Feed Integration Source: https://context7.com/cn-vhql/backtrader/llms.txt Illustrates how to add a CSV data feed to the backtrader cerebro engine. This involves specifying the file path, date range, and time frame for the data. The example shows the setup for daily data. ```python import backtrader as bt from datetime import datetime import pandas as pd cerebro = bt.Cerebro() # CSV Data Feed data_csv = bt.feeds.BacktraderCSVData( dataname='stock_data.csv', fromdate=datetime(2020, 1, 1), todate=datetime(2021, 12, 31), timeframe=bt.TimeFrame.Days, compression=1 ) cerebro.adddata(data_csv) ``` -------------------------------- ### Implement Technical Indicators in Backtrader Source: https://context7.com/cn-vhql/backtrader/llms.txt Details the integration of various built-in technical indicators within a Backtrader strategy. It covers moving averages (SMA, EMA), momentum indicators (RSI, MACD, Stochastic), volatility indicators (Bollinger Bands, ATR), and volume indicators (SMA of volume). Examples show how to use these indicators for generating trading signals. ```python import backtrader as bt class IndicatorStrategy(bt.Strategy): def __init__(self): # Moving averages self.sma = bt.indicators.SimpleMovingAverage(self.data, period=20) self.ema = bt.indicators.ExponentialMovingAverage(self.data, period=12) # Momentum indicators self.rsi = bt.indicators.RSI(self.data, period=14) self.macd = bt.indicators.MACD(self.data) self.stochastic = bt.indicators.Stochastic(self.data) # Volatility indicators self.bbands = bt.indicators.BollingerBands(self.data, period=20, devfactor=2.0) self.atr = bt.indicators.ATR(self.data, period=14) # Volume indicators self.volume_sma = bt.indicators.SMA(self.data.volume, period=20) # Indicator operations create new indicators self.crossover = bt.indicators.CrossOver(self.data.close, self.sma) self.sma_distance = self.data.close - self.sma def next(self): # Use precalculated indicator values if self.crossover > 0: # Price crossed above SMA - bullish signal if self.rsi[0] < 70: # Not overbought self.buy() elif self.crossover < 0: # Price crossed below SMA - bearish signal self.sell() # Bollinger Bands strategy if self.data.close[0] < self.bbands.lines.bot[0]: # Price below lower band - oversold self.buy() elif self.data.close[0] > self.bbands.lines.top[0]: # Price above upper band - overbought self.sell() # MACD crossover if self.macd.macd[0] > self.macd.signal[0] and self.macd.macd[-1] <= self.macd.signal[-1]: # MACD crossed above signal line self.buy() ``` -------------------------------- ### Implement Bracket Orders with Backtrader Source: https://context7.com/cn-vhql/backtrader/llms.txt Demonstrates how to implement bracket orders in backtrader strategies. This includes setting up buy and sell bracket orders with specified stop-loss and take-profit prices for effective risk management. It requires the backtrader library. ```python import backtrader as bt class BracketOrderStrategy(bt.Strategy): def __init__(self): self.order = None self.buyprice = None self.buycomm = None def next(self): if self.order: return # Pending order exists if not self.position: # Entry signal - buy with bracket orders if self.data.close[0] > self.data.close[-1]: # Buy bracket order: main + stop loss + take profit self.order = self.buy_bracket( size=100, price=self.data.close[0], # Limit entry price stopprice=self.data.close[0] * 0.95, # Stop loss at -5% limitprice=self.data.close[0] * 1.10, # Take profit at +10% exectype=bt.Order.Limit ) # Sell bracket order example for short positions if self.position.size < 0: # Already short pass elif not self.position: if self.data.close[0] < self.data.close[-1]: # Sell bracket: short + stop loss + take profit self.order = self.sell_bracket( size=100, price=self.data.close[0], stopprice=self.data.close[0] * 1.05, # Stop loss at +5% limitprice=self.data.close[0] * 0.90, # Take profit at -10% exectype=bt.Order.Limit ) def notify_order(self, order): if order.status == order.Completed: if order.isbuy(): self.buyprice = order.executed.price self.buycomm = order.executed.comm self.log(f'BUY EXECUTED: {self.buyprice:.2f}') else: self.log(f'SELL EXECUTED: {order.executed.price:.2f}') elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Failed') self.order = None ``` -------------------------------- ### Python Backtrader Broker Operations Configuration Source: https://context7.com/cn-vhql/backtrader/llms.txt Demonstrates how to configure the simulated broker in backtrader, including setting initial cash, defining commission (both percentage and fixed), and implementing slippage (percentage and fixed). It also shows how to query broker state (cash, value, position) within a strategy. ```python import backtrader as bt cerebro = bt.Cerebro() # Set initial cash cerebro.broker.set_cash(50000) # Configure commission (0.1% per trade) cerebro.broker.setcommission(commission=0.001) # Alternative: fixed commission per contract cerebro.broker.setcommission( commission=5.0, stocklike=False, commtype=bt.CommInfoBase.COMM_FIXED ) # Set slippage (0.5% price impact) cerebro.broker.set_slippage_perc(0.005) # Fixed slippage in price units cerebro.broker.set_slippage_fixed(0.05) # Inside strategy - query broker state class BrokerStrategy(bt.Strategy): def next(self): # Get current cash and portfolio value cash = self.broker.get_cash() value = self.broker.get_value() # Get position for current data position = self.broker.getposition(self.data) if position.size == 0: # No position, can open new trade available_shares = int(cash / self.data.close[0]) if available_shares > 0: self.buy(size=min(available_shares, 100)) elif position.size > 0 and self.data.close[0] < position.price * 0.95: # Exit if 5% loss self.close() self.log(f'Cash: {cash:.2f}, Value: {value:.2f}, Position: {position.size}') ``` -------------------------------- ### Implement Position Sizing Strategies in Backtrader Source: https://context7.com/cn-vhql/backtrader/llms.txt Explains how to manage trade sizes using Backtrader's sizer system. Covers predefined sizers like `FixedSize`, `PercentSizer`, and `AllInSizer`, along with a custom `RiskSizer` that calculates trade size based on a percentage of capital at risk and a stop-loss. It also demonstrates overriding the sizer on individual orders. ```python import backtrader as bt cerebro = bt.Cerebro() # Fixed size sizer - always trade 100 shares cerebro.addsizer(bt.sizers.FixedSize, stake=100) # Percent sizer - use 20% of available cash cerebro.addsizer(bt.sizers.PercentSizer, percents=20) # All-in sizer - use all available cash cerebro.addsizer(bt.sizers.AllInSizer) # Custom sizer with risk management class RiskSizer(bt.Sizer): params = ( ('risk_percent', 2.0), # Risk 2% per trade ) def _getsizing(self, comminfo, cash, data, isbuy): position = self.broker.getposition(data) if not isbuy: # Selling - return current position size return position.size # Buying - calculate position size based on risk # Assume 5% stop loss stop_loss_pct = 0.05 risk_amount = self.broker.getvalue() * (self.p.risk_percent / 100.0) price = data.close[0] risk_per_share = price * stop_loss_pct if risk_per_share > 0: size = int(risk_amount / risk_per_share) # Ensure we have enough cash max_size = int(cash / price) return min(size, max_size) return 0 cerebro.addsizer(RiskSizer, risk_percent=1.5) # Override sizer in individual orders class SizeOverrideStrategy(bt.Strategy): def next(self): # Use default sizer self.buy() # Override sizer for this order self.buy(size=50) # Dynamic sizing cash = self.broker.get_cash() price = self.data.close[0] shares = int((cash * 0.25) / price) self.buy(size=shares) ``` -------------------------------- ### Access and Utilize Data within a Backtrader Strategy Source: https://context7.com/cn-vhql/backtrader/llms.txt Shows how to access current and historical bar data (open, high, low, close, volume) within a Backtrader strategy's `next` method. It illustrates accessing current bar values using `[0]` and previous bar values using negative indexing. Forward referencing is noted as unavailable in backtesting. ```python import backtrader as bt class DataStrategy(bt.Strategy): def next(self): # Current bar data close = self.data.close[0] high = self.data.high[0] low = self.data.low[0] volume = self.data.volume[0] # Previous bars (negative indexing) prev_close = self.data.close[-1] two_bars_ago = self.data.close[-2] # Forward reference (not available in backtesting) # next_close = self.data.close[1] # Would cause error self.log(f'Close: {close:.2f}, Prev Close: {prev_close:.2f}, Volume: {volume}') ``` -------------------------------- ### Backtrader Order Management in Python Source: https://context7.com/cn-vhql/backtrader/llms.txt Illustrates various order management techniques within Backtrader, including market, limit, stop, and stop-limit orders. It also shows how to close a position and cancel a pending order. These methods are crucial for executing trades based on specific conditions and managing risk. ```python import backtrader as bt class OrderStrategy(bt.Strategy): def next(self): # Market order - executes at next available price order = self.buy(size=100) # Limit order - only execute at specified price or better limit_order = self.buy( exectype=bt.Order.Limit, price=self.data.close[0] * 0.99, size=50 ) # Stop order - triggers when price reaches stop level stop_order = self.sell( exectype=bt.Order.Stop, price=self.data.close[0] * 0.95, size=100 ) # Stop-Limit order - combines stop and limit stoplimit_order = self.buy( exectype=bt.Order.StopLimit, price=self.data.close[0] * 1.02, # Stop price plimit=self.data.close[0] * 1.07, # Limit price size=75 ) # Close entire position if self.position: self.close() # Cancel pending order if order.status == bt.Order.Submitted: self.cancel(order) ``` -------------------------------- ### Use Signals for Backtrader Trading Logic Source: https://context7.com/cn-vhql/backtrader/llms.txt Illustrates how to employ signals in backtrader for a declarative trading approach, abstracting away complex strategy logic. This involves defining custom indicators that generate trading signals and then adding these signals to the backtrader cerebro instance. Dependencies include the backtrader library. ```python import backtrader as bt # Define signal indicator class SMASignal(bt.Indicator): lines = ('signal',) params = (('period', 30),) def __init__(self): # Signal: +1 when above SMA, -1 when below sma = bt.indicators.SMA(self.data, period=self.p.period) self.lines.signal = self.data.close - sma # Custom signal logic class MACDSignal(bt.Indicator): lines = ('signal',) def __init__(self): macd = bt.indicators.MACD(self.data) # Signal when MACD crosses signal line self.lines.signal = macd.macd - macd.signal # Setup with signals cerebro = bt.Cerebro() # Add data data = bt.feeds.BacktraderCSVData(dataname='data.csv') cerebro.adddata(data) # Add signals instead of strategies cerebro.add_signal( bt.SIGNAL_LONGSHORT, # Go long and short SMASignal, period=20 ) # Alternative signal types # bt.SIGNAL_LONG: Only long positions # bt.SIGNAL_SHORT: Only short positions # bt.SIGNAL_LONGEXIT: Exit long positions # bt.SIGNAL_SHORTEXIT: Exit short positions cerebro.add_signal(bt.SIGNAL_LONG, MACDSignal) # Run cerebro.run() ``` -------------------------------- ### Parameter Optimization in Backtrader Source: https://context7.com/cn-vhql/backtrader/llms.txt Shows how to perform parameter optimization for a trading strategy in backtrader. It defines an optimizable strategy with parameters like SMA and RSI periods and thresholds, then uses `cerebro.optstrategy` to run systematic tests and find the best parameter combination. ```python import backtrader as bt class OptimizableStrategy(bt.Strategy): params = ( ('sma_period', 20), ('rsi_period', 14), ('rsi_upper', 70), ('rsi_lower', 30), ) def __init__(self): self.sma = bt.indicators.SMA(period=self.p.sma_period) self.rsi = bt.indicators.RSI(period=self.p.rsi_period) def next(self): if not self.position: if self.data.close[0] > self.sma[0] and self.rsi[0] < self.p.rsi_lower: self.buy() else: if self.rsi[0] > self.p.rsi_upper: self.sell() def stop(self): # Store results for comparison self.final_value = self.broker.getvalue() print(f'SMA: {self.p.sma_period}, RSI: {self.p.rsi_period}, ' f'Final Value: {self.final_value:.2f}') # Run optimization cerebro = bt.Cerebro(optreturn=True) # Add data data = bt.feeds.BacktraderCSVData(dataname='data.csv') cerebro.adddata(data) # Add strategy with parameter ranges cerebro.optstrategy( OptimizableStrategy, sma_period=range(10, 50, 5), # Test 10, 15, 20, ..., 45 rsi_period=range(10, 20, 2), # Test 10, 12, 14, 16, 18 rsi_upper=range(65, 80, 5), # Test 65, 70, 75 rsi_lower=range(25, 40, 5) # Test 25, 30, 35 ) cerebro.broker.set_cash(100000) cerebro.addsizer(bt.sizers.PercentSizer, percents=10) # Run optimization opt_results = cerebro.run() # Find best parameters best_value = 0 best_params = None for result in opt_results: strat = result[0] if strat.final_value > best_value: best_value = strat.final_value best_params = (strat.p.sma_period, strat.p.rsi_period, strat.p.rsi_upper, strat.p.rsi_lower) print(f'Best Parameters: SMA={best_params[0]}, RSI={best_params[1]}, ' f'Upper={best_params[2]}, Lower={best_params[3]}') print(f'Best Final Value: {best_value:.2f}') ``` -------------------------------- ### Custom Indicator Development with Backtrader Source: https://context7.com/cn-vhql/backtrader/llms.txt Demonstrates how to develop custom technical indicators in backtrader using both declarative and imperative approaches. This includes indicators like Donchian Channel, True Range, and a spread indicator using multiple data feeds, along with a strategy that utilizes these custom indicators. ```python import backtrader as bt # Declarative approach - define logic in __init__ class DonchianChannel(bt.Indicator): lines = ('dcm', 'dch', 'dcl') # Middle, high, low lines params = (('period', 20),) plotinfo = dict(subplot=False) # Plot on main chart plotlines = dict( dcm=dict(ls='--'), # Dashed line for middle dch=dict(_samecolor=True), dcl=dict(_samecolor=True) ) def __init__(self): # Highest high and lowest low over period self.l.dch = bt.indicators.Highest(self.data.high, period=self.p.period) self.l.dcl = bt.indicators.Lowest(self.data.low, period=self.p.period) self.l.dcm = (self.l.dch + self.l.dcl) / 2.0 # Imperative approach - calculate in next() class TrueRange(bt.Indicator): lines = ('tr',) def next(self): h = self.data.high[0] l = self.data.low[0] c_prev = self.data.close[-1] # True Range = max(high-low, abs(high-prev_close), abs(low-prev_close)) tr = max(h - l, abs(h - c_prev), abs(l - c_prev)) self.lines.tr[0] = tr # Indicator using multiple data feeds class SpreadIndicator(bt.Indicator): lines = ('spread',) params = (('data2', None),) def __init__(self): # Calculate spread between two assets self.lines.spread = self.data.close - self.p.data2.close # Use custom indicators class CustomIndicatorStrategy(bt.Strategy): def __init__(self): self.donchian = DonchianChannel(self.data, period=20) self.tr = TrueRange(self.data) # Multi-data spread if len(self.datas) > 1: self.spread = SpreadIndicator(self.datas[0], data2=self.datas[1]) def next(self): # Trade based on Donchian breakout if self.data.close[0] > self.donchian.dch[-1]: # Breakout above channel self.buy() elif self.data.close[0] < self.donchian.dcl[-1]: # Breakout below channel self.sell() ``` -------------------------------- ### Monthly Rebalancing Strategy in Backtrader Source: https://context7.com/cn-vhql/backtrader/llms.txt Implements a monthly rebalancing strategy where the portfolio is adjusted to a target percentage of its value at the beginning of each month. It utilizes the backtrader framework for backtesting trading strategies. ```python import backtrader as bt class MonthlyRebalance(bt.Strategy): def __init__(self): self.month = -1 def next(self): current_month = self.data.datetime.date(0).month if current_month != self.month: self.month = current_month # Rebalance to 25% of portfolio portfolio_value = self.broker.getvalue() target_value = portfolio_value * 0.25 self.order_target_value(target=target_value) ``` -------------------------------- ### Extract and Display Backtrader Performance Metrics Source: https://context7.com/cn-vhql/backtrader/llms.txt Extracts analysis results from various analyzers (SharpeRatio, DrawDown, Returns) after a Backtrader backtest has been run. It then prints these performance metrics to the console, formatted for readability. This requires the 'strat' object returned by 'cerebro.run()' and assumes analyzers were added with specific names. ```python # Assume 'strat' is the result of cerebro.run()[0] # Extract analysis from analyzers sharpe = strat.analyzers.sharpe.get_analysis() drawdown = strat.analyzers.drawdown.get_analysis() returns = strat.analyzers.returns.get_analysis() # Display results print('=== Performance Metrics ===') print(f'Sharpe Ratio: {sharpe.get("sharperatio", 0):.3f}') print(f'Max Drawdown: {drawdown["max"]["drawdown"]:.2f}%') print(f'Max Drawdown Duration: {drawdown["max"]["len"]} bars') print(f'Total Return: {returns["rtot"]:.2%}') print(f'Average Return: {returns["ravg"]:.2%}') ``` -------------------------------- ### Python Backtrader Notification Methods Source: https://context7.com/cn-vhql/backtrader/llms.txt Defines callback methods within a backtrader strategy to receive real-time updates on order status, trade executions, portfolio value, and system messages. These methods are crucial for monitoring and reacting to events during a backtest. ```python import backtrader as bt class NotificationStrategy(bt.Strategy): def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: # Order acknowledged by broker return if order.status == order.Completed: if order.isbuy(): self.log(f'BUY EXECUTED - Price: {order.executed.price:.2f}, ' f'Cost: {order.executed.value:.2f}, ' f'Commission: {order.executed.comm:.2f}') else: self.log(f'SELL EXECUTED - Price: {order.executed.price:.2f}, ' f'Cost: {order.executed.value:.2f}, ' f'Commission: {order.executed.comm:.2f}') 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(f'TRADE CLOSED - Gross P&L: {trade.pnl:.2f}, ' f'Net P&L: {trade.pnlcomm:.2f}') def notify_cashvalue(self, cash, value): self.log(f'Cash: {cash:.2f}, Portfolio Value: {value:.2f}') def notify_store(self, msg, *args, **kwargs): self.log(f'STORE NOTIFICATION: {msg}') def log(self, txt): print(f'{self.data.datetime.date(0)}: {txt}') ``` -------------------------------- ### Extract and Display Backtrader Trade Statistics Source: https://context7.com/cn-vhql/backtrader/llms.txt Extracts and displays detailed trade statistics from the TradeAnalyzer and SQN analyzer after a Backtrader backtest. It prints the total number of trades, wins, losses, win rate, average win/loss amounts, and the System Quality Number. This assumes the 'strat' object and the corresponding analyzers ('trades', 'sqn') are available. ```python # Assume 'strat' is the result of cerebro.run()[0] # Extract analysis from analyzers trades = strat.analyzers.trades.get_analysis() sqn = strat.analyzers.sqn.get_analysis() # Display trade statistics print('\n=== Trade Statistics ===') print(f'Total Trades: {trades.get("total", {{}}).get("total", 0)}') print(f'Won Trades: {trades.get("won", {{}}).get("total", 0)}') print(f'Lost Trades: {trades.get("lost", {{}}).get("total", 0)}') if 'won' in trades and 'total' in trades['won'] and 'total' in trades: print(f'Win Rate: {trades["won"]["total"] / trades["total"]["total"]:.2%}') if 'pnl' in trades['won'] and 'average' in trades['won']['pnl']: print(f'Average Win: {trades["won"]["pnl"]["average"]:.2f}') if 'pnl' in trades['lost'] and 'average' in trades['lost']['pnl']: print(f'Average Loss: {trades["lost"]["pnl"]["average"]:.2f}') print(f'\nSQN (System Quality Number): {sqn.get("sqn", 0):.2f}') ``` -------------------------------- ### Load Data from Yahoo Finance and Pandas DataFrame in Backtrader Source: https://context7.com/cn-vhql/backtrader/llms.txt Demonstrates how to load historical price data into Backtrader. It shows fetching data from Yahoo Finance using its ticker symbol and loading data from a Pandas DataFrame read from a CSV file. Both methods are added to the Backtrader Cerebro instance. ```python import backtrader as bt from datetime import datetime import pandas as pd # Assume cerebro is already initialized cerebro = bt.Cerebro() # Yahoo Finance Data data_yahoo = bt.feeds.YahooFinanceData( dataname='AAPL', fromdate=datetime(2020, 1, 1), todate=datetime(2021, 12, 31) ) cerebro.adddata(data_yahoo) # Pandas DataFrame df = pd.read_csv('data.csv', parse_dates=True, index_col='date') data_pandas = bt.feeds.PandasData( dataname=df, datetime=None, # Use index as datetime open='open', high='high', low='low', close='close', volume='volume', openinterest=-1 ) cerebro.adddata(data_pandas) # Multiple timeframes - resample daily to weekly # Assuming data_csv is a pre-loaded feed # cerebro.resampledata(data_csv, timeframe=bt.TimeFrame.Weeks, compression=1) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.