{"id":260921,"date":"2026-11-09T12:10:40","date_gmt":"2026-11-09T17:10:40","guid":{"rendered":"https:\/\/ibkrcampus.com\/campus\/?p=260921"},"modified":"2026-11-09T12:11:48","modified_gmt":"2026-11-09T17:11:48","slug":"how-to-backtest-a-moving-average-strategy-with-backtrader-python","status":"publish","type":"post","link":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/","title":{"rendered":"How to Backtest a Moving Average Strategy with Backtrader Python"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><em>The article &#8220;How to Backtest a Moving Average Strategy with Backtrader Python&#8221; was originally posted on <a href=\"https:\/\/www.pyquantnews.com\/free-python-resources\/backtest-moving-average-strategy-backtrader-python\">PyQuant News<\/a> blog.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Backtrader Python<\/strong> is an open-source framework for testing trading strategies on historical price data before you risk real money. If you&#8217;ve wondered whether a rule like &#8220;buy when the short-term average crosses above the long-term average&#8221; actually makes money, backtrader lets you answer that question with code instead of guesswork. This <a href=\"https:\/\/www.pyquantnews.com\/the-pyquant-newsletter\/backtesting-with-backtrader-step-by-step\">step-by-step backtrader walkthrough<\/a> covers the foundations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The official backtrader site shows a feature overview and a short code snippet, but it doesn&#8217;t walk you through a complete working example. That&#8217;s what this article does. You&#8217;ll install the library, load daily stock prices from a CSV, write a moving average crossover strategy, and read the output, all in about 60 lines of Python.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One thing is worth knowing up front. Backtrader is mature software. The core library is stable and widely used in tutorials, but development has slowed and some built-in integrations, such as the Yahoo Finance data feed, are outdated. Community examples on Stack Overflow are often the quickest help when you hit unusual cases.<\/p>\n\n\n\n<h2 id=\"h-what-backtrader-python-does\" class=\"wp-block-heading\">What Backtrader Python Does<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Backtesting means running a trading strategy on past price data to see how it would have performed. You feed the system historical prices, define your buy and sell rules, and the framework simulates trades day by day. At the end you get a final portfolio value and can inspect every trade.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Backtrader takes care of the mechanics. It keeps track of your simulated cash and holdings, figures out when orders fill, and can calculate common indicators like moving averages for you. You focus on the strategy logic.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This matters because testing ideas manually is slow and error-prone. Scrolling through charts and imagining &#8220;I would have bought here&#8221; doesn&#8217;t account for transaction timing or position sizing. Backtrader forces you to spell out your rules, then applies them consistently across every day of data.<\/p>\n\n\n\n<h3 id=\"h-how-backtrader-organizes-a-test\" class=\"wp-block-heading\">How Backtrader Organizes a Test<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Backtrader uses a class-based structure. You write a strategy class that inherits from <code>bt.Strategy<\/code> and define two key methods. The <code>__init__<\/code> method sets up any indicators you need. The <code>next<\/code> method runs once per bar of data (typically once per trading day) and contains your buy and sell logic.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A separate engine called <code>Cerebro<\/code> (Spanish for &#8220;brain&#8221;) ties everything together. You create a Cerebro instance, add your data and strategy, set your starting cash, and call <code>run()<\/code>. Cerebro steps through the data one bar at a time and calls your strategy&#8217;s <code>next<\/code> method at each step.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One detail trips up many beginners. When you place an order inside <code>next()<\/code>, it usually doesn&#8217;t execute on that same bar. By default, the order fills on the next bar&#8217;s open price. Keep that in mind when you compare your results to what you see on a chart.<\/p>\n\n\n\n<h2 id=\"h-build-a-backtrader-python-strategy\" class=\"wp-block-heading\">Build a Backtrader Python Strategy<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A moving average crossover is one of the simplest rule-based trading strategies. You compute two averages of the closing price over different time periods. When the shorter average crosses above the longer one, you buy. When it crosses below, you sell. The idea is that the short average reacts faster to price changes, so a crossover suggests that the overall direction of prices is shifting.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For other strategy patterns, the guide on <a href=\"https:\/\/www.pyquantnews.com\/free-python-resources\/creating-and-backtesting-trading-strategies-with-backtrader\">creating and backtesting strategies with backtrader<\/a> covers several variations.<\/p>\n\n\n\n<h3 id=\"h-install-backtrader\" class=\"wp-block-heading\">Install Backtrader<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">pip install backtrader<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Backtrader works with Python 3.6 and above. If you want the built-in plotting feature, install <code>matplotlib<\/code> too.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prepare Your Data File<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The code below expects a CSV file called <code>daily_prices.csv<\/code> with no header row and columns in this order: date, open, high, low, close, volume. You can download free daily data from <a href=\"https:\/\/finance.yahoo.com\/\">Yahoo Finance<\/a> for any stock. Yahoo&#8217;s files usually include a header row, so delete that first line or add <code>header=True<\/code> to the feed configuration.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s what the first few rows should look like:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">2023-01-03,130.28,131.04,129.04,130.15,89134500\n2023-01-04,130.06,131.63,129.60,131.02,80379300\n2023-01-05,131.25,131.26,128.12,128.38,87754700<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">The Complete Code<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import backtrader as bt\n\n\nclass SmaCross(bt.Strategy):\n    \"\"\"Buys when a fast moving average crosses above a slow\n    moving average, and sells when it crosses below.\"\"\"\n\n    params = (\n        (\"fast_period\", 10),\n        (\"slow_period\", 30),\n    )\n\n    def __init__(self):\n        fast_ma = bt.indicators.SimpleMovingAverage(\n            self.data.close, period=self.params.fast_period\n        )\n        slow_ma = bt.indicators.SimpleMovingAverage(\n            self.data.close, period=self.params.slow_period\n        )\n        # CrossOver returns +1 when fast crosses above slow,\n        # -1 when it crosses below\n        self.crossover = bt.indicators.CrossOver(fast_ma, slow_ma)\n\n    def next(self):\n        if not self.position:\n            # No current holding. Buy if fast crosses above slow.\n            if self.crossover &gt; 0:\n                self.buy()\n        else:\n            # Currently holding. Sell if fast crosses below slow.\n            if self.crossover &lt; 0:\n                self.sell()\n\n    def notify_trade(self, trade):\n        if trade.isclosed:\n            print(\n                f\"Trade profit or loss: gross={trade.pnl:.2f}, \"\n                f\"net={trade.pnlcomm:.2f}\"\n            )\n\n\n# Set up the test engine\ncerebro = bt.Cerebro()\ncerebro.addstrategy(SmaCross)\n\n# Load your CSV (adjust the path to match your file)\ndata = bt.feeds.GenericCSVData(\n    dataname=\"daily_prices.csv\",\n    dtformat=\"%Y-%m-%d\",\n    datetime=0,\n    open=1,\n    high=2,\n    low=3,\n    close=4,\n    volume=5,\n    openinterest=-1,\n)\n\ncerebro.adddata(data)\ncerebro.broker.setcash(100000.0)\ncerebro.broker.setcommission(commission=0.001)\n\nprint(f\"Starting portfolio value: {cerebro.broker.getvalue():.2f}\")\nresults = cerebro.run()\nprint(f\"Final portfolio value: {cerebro.broker.getvalue():.2f}\")\n\ncerebro.plot()<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Walking Through the Code<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>SmaCross<\/code> class defines two parameters at the top, <code>fast_period<\/code> and <code>slow_period<\/code>. These control how many past days each moving average uses. Putting them in <code>params<\/code> instead of hardcoding numbers makes it easy to test different values later.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In <code>__init__<\/code>, we create two <code>SimpleMovingAverage<\/code> indicators and a <code>CrossOver<\/code> indicator. Backtrader computes these automatically as it steps through the data. You never need to write your own loop to calculate them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>next<\/code> method is where decisions happen. On each bar, we check <code>self.position<\/code>, which tells you whether the strategy currently holds the asset. If it doesn&#8217;t and the crossover value is positive (the fast average just crossed above the slow one), we buy. If it does hold the asset and the crossover goes negative, we sell. Because of the <code>if not self.position<\/code> check, the strategy won&#8217;t keep buying on every bar where the fast average stays above the slow one. It buys once and waits.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>notify_trade<\/code> method is optional. It prints the profit or loss each time a trade has both an entry and an exit. This helps you see each trade result without digging through logs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Below the class, we set up Cerebro, load the CSV, set starting cash to $100,000, and add a commission of 0.1% per trade. The <code>run()<\/code> call executes the entire test. The <code>plot()<\/code> call generates a chart with the price series and the trades the strategy placed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to Read Backtrader Python Results<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When you run the script, you&#8217;ll see output like this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Starting portfolio value: 100000.00\nTrade profit or loss: gross=1250.40, net=1230.15\nTrade profit or loss: gross=-320.80, net=-340.92\nTrade profit or loss: gross=870.60, net=851.22\nFinal portfolio value: 103740.45<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Each &#8220;Trade profit or loss&#8221; line shows one completed trade. The gross number is the raw profit or loss. The net number subtracts commission costs. The final portfolio value tells you where you ended up.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the final value is higher than the starting value, the strategy made money on that dataset. But that alone doesn&#8217;t mean the strategy is good. You judged it on the same historical data you used to inspect it. That&#8217;s called in-sample testing, which means you test on the same data you used to examine the idea, and it can make results look better than they really are.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A strategy can look profitable on one stretch of old data because its rules matched quirks in that period. For example, a 10-day and 30-day setting might look best only because it happened to catch a few lucky price swings. When you try fresh data, those same rules may stop working. That problem is called overfitting, which means the rules fit this dataset too closely and don&#8217;t hold up on new data.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Also consider that final portfolio value is just one number. A strategy that ended with a profit but only made three trades in two years, or lost 40% of the account before recovering, might not be worth using. Check the number of trades and the size of the worst losses too.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To get a more honest estimate, split your data into two parts. Run the strategy on the first part, then test it on the second part that the strategy never touched. Backtrader doesn&#8217;t do this split for you, but you can load different CSV files or filter date ranges in the data feed. The <a href=\"https:\/\/www.pyquantnews.com\/free-python-resources\/comprehensive-guide-to-using-backtrader\">comprehensive guide to backtrader<\/a> explains how to configure date filtering.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Extending Your Backtrader Python Strategy<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once the basic crossover works, there are practical improvements you can make. For a deeper look at tuning, see the guide on <a href=\"https:\/\/www.pyquantnews.com\/free-python-resources\/mastering-trading-with-backtrader-effective-backtesting\">effective backtesting with backtrader<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Adding a Position Sizer<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">By default, backtrader buys one share per trade. That&#8217;s not realistic. You can tell Cerebro to invest a percentage of your portfolio on each buy signal.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">cerebro.addsizer(bt.sizers.PercentSizer, percents=95)<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This invests 95% of available cash when the strategy buys. The remaining 5% acts as a buffer for commission costs.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Optimizing Parameters<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Backtrader has a built-in optimizer that tests many parameter combinations. Replace <code>addstrategy<\/code> with <code>optstrategy<\/code>.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">cerebro.optstrategy(SmaCross, fast_period=range(5, 15), slow_period=range(20, 40))<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This runs the strategy for every combination of fast periods from 5 to 14 and slow periods from 20 to 39. Be careful here. Testing hundreds of combinations on the same data increases the chance of finding a parameter set that worked by luck. Always validate optimized parameters on data the optimizer never touched.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Adding Analyzers<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Analyzers calculate extra report numbers from your historical strategy test. One useful analyzer calculates the Sharpe ratio, which estimates how much return the strategy produced compared with how much the account value bounced up and down. A higher number means the strategy delivered smoother returns.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name=\"sharpe\")<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After running, access the result with <code>results[0].analyzers.sharpe.get_analysis()<\/code>. The <a href=\"https:\/\/www.pyquantnews.com\/free-python-resources\/build-backtest-algorithmic-trading-strategy-python\">build and backtest a strategy guide<\/a> shows how to combine multiple analyzers into a full performance report.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Go Deeper With Free Python Guides<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The free <a href=\"https:\/\/www.pyquantnews.com\/topics\/algorithmic-trading-with-python\">Algorithmic Trading With Python<\/a> guides go deeper on this. They show more strategy examples and explain how to connect backtrader to live market data for simulated trading with no real money at stake.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Backtrader Python is an open-source framework for testing trading strategies on historical price data before you risk real money.<\/p>\n","protected":false},"author":1518,"featured_media":186234,"comment_status":"open","ping_status":"closed","sticky":true,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[339,343,349,338,341],"tags":[851,11809,22357,4659,3625,595,5545],"contributors-categories":[17813],"class_list":["post-260921","post","type-post","status-publish","format-standard","has-post-thumbnail","category-data-science","category-programing-languages","category-python-development","category-ibkr-quant-news","category-quant-development","tag-algo-trading","tag-backtrader","tag-data-sience","tag-matplotlib","tag-moving-average","tag-python","tag-sharpe-ratio","contributors-categories-pyquantnews"],"pp_statuses_selecting_workflow":false,"pp_workflow_action":"current","pp_status_selection":"publish","acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.9 (Yoast SEO v28.8) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How to Backtest a Moving Average Strategy with Backtrader Python<\/title>\n<meta name=\"description\" content=\"Backtrader Python is an open-source framework for testing trading strategies on historical price data before you risk real money.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.interactivebrokers.com\/campus\/wp-json\/wp\/v2\/posts\/260921\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Backtest a Moving Average Strategy with Backtrader Python\" \/>\n<meta property=\"og:description\" content=\"Backtrader Python is an open-source framework for testing trading strategies on historical price data before you risk real money.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/\" \/>\n<meta property=\"og:site_name\" content=\"IBKR Campus US\" \/>\n<meta property=\"article:published_time\" content=\"2026-11-09T17:10:40+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-11-09T17:11:48+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/03\/python-blue-grid-dots.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1000\" \/>\n\t<meta property=\"og:image:height\" content=\"563\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Jason\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jason\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\n\t    \"@context\": \"https:\\\/\\\/schema.org\",\n\t    \"@graph\": [\n\t        {\n\t            \"@type\": \"NewsArticle\",\n\t            \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/ibkr-quant-news\\\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\\\/#article\",\n\t            \"isPartOf\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/ibkr-quant-news\\\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\\\/\"\n\t            },\n\t            \"author\": {\n\t                \"name\": \"Jason\",\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#\\\/schema\\\/person\\\/288f5f80a63d81b02dba7b1157a95125\"\n\t            },\n\t            \"headline\": \"How to Backtest a Moving Average Strategy with Backtrader Python\",\n\t            \"datePublished\": \"2026-11-09T17:10:40+00:00\",\n\t            \"dateModified\": \"2026-11-09T17:11:48+00:00\",\n\t            \"mainEntityOfPage\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/ibkr-quant-news\\\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\\\/\"\n\t            },\n\t            \"wordCount\": 1443,\n\t            \"commentCount\": 0,\n\t            \"publisher\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#organization\"\n\t            },\n\t            \"image\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/ibkr-quant-news\\\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\\\/#primaryimage\"\n\t            },\n\t            \"thumbnailUrl\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/03\\\/python-blue-grid-dots.jpg\",\n\t            \"keywords\": [\n\t                \"Algo Trading\",\n\t                \"Backtrader\",\n\t                \"Data Sience\",\n\t                \"Matplotlib\",\n\t                \"moving average\",\n\t                \"Python\",\n\t                \"Sharpe Ratio\"\n\t            ],\n\t            \"articleSection\": [\n\t                \"Data Science\",\n\t                \"Programming Languages\",\n\t                \"Python Development\",\n\t                \"Quant\",\n\t                \"Quant Development\"\n\t            ],\n\t            \"inLanguage\": \"en-US\",\n\t            \"potentialAction\": [\n\t                {\n\t                    \"@type\": \"CommentAction\",\n\t                    \"name\": \"Comment\",\n\t                    \"target\": [\n\t                        \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/ibkr-quant-news\\\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\\\/#respond\"\n\t                    ]\n\t                }\n\t            ]\n\t        },\n\t        {\n\t            \"@type\": \"WebPage\",\n\t            \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/ibkr-quant-news\\\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\\\/\",\n\t            \"url\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/ibkr-quant-news\\\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\\\/\",\n\t            \"name\": \"How to Backtest a Moving Average Strategy with Backtrader Python | IBKR Campus US\",\n\t            \"isPartOf\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#website\"\n\t            },\n\t            \"primaryImageOfPage\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/ibkr-quant-news\\\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\\\/#primaryimage\"\n\t            },\n\t            \"image\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/ibkr-quant-news\\\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\\\/#primaryimage\"\n\t            },\n\t            \"thumbnailUrl\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/03\\\/python-blue-grid-dots.jpg\",\n\t            \"datePublished\": \"2026-11-09T17:10:40+00:00\",\n\t            \"dateModified\": \"2026-11-09T17:11:48+00:00\",\n\t            \"description\": \"Backtrader Python is an open-source framework for testing trading strategies on historical price data before you risk real money.\",\n\t            \"inLanguage\": \"en-US\",\n\t            \"potentialAction\": [\n\t                {\n\t                    \"@type\": \"ReadAction\",\n\t                    \"target\": [\n\t                        \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/ibkr-quant-news\\\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\\\/\"\n\t                    ]\n\t                }\n\t            ]\n\t        },\n\t        {\n\t            \"@type\": \"ImageObject\",\n\t            \"inLanguage\": \"en-US\",\n\t            \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/ibkr-quant-news\\\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\\\/#primaryimage\",\n\t            \"url\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/03\\\/python-blue-grid-dots.jpg\",\n\t            \"contentUrl\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2023\\\/03\\\/python-blue-grid-dots.jpg\",\n\t            \"width\": 1000,\n\t            \"height\": 563,\n\t            \"caption\": \"Python Quant\"\n\t        },\n\t        {\n\t            \"@type\": \"WebSite\",\n\t            \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#website\",\n\t            \"url\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/\",\n\t            \"name\": \"IBKR Campus US\",\n\t            \"description\": \"Financial Education from Interactive Brokers\",\n\t            \"publisher\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#organization\"\n\t            },\n\t            \"potentialAction\": [\n\t                {\n\t                    \"@type\": \"SearchAction\",\n\t                    \"target\": {\n\t                        \"@type\": \"EntryPoint\",\n\t                        \"urlTemplate\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/?s={search_term_string}\"\n\t                    },\n\t                    \"query-input\": {\n\t                        \"@type\": \"PropertyValueSpecification\",\n\t                        \"valueRequired\": true,\n\t                        \"valueName\": \"search_term_string\"\n\t                    }\n\t                }\n\t            ],\n\t            \"inLanguage\": \"en-US\"\n\t        },\n\t        {\n\t            \"@type\": \"Organization\",\n\t            \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#organization\",\n\t            \"name\": \"Interactive Brokers\",\n\t            \"alternateName\": \"IBKR\",\n\t            \"url\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/\",\n\t            \"logo\": {\n\t                \"@type\": \"ImageObject\",\n\t                \"inLanguage\": \"en-US\",\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#\\\/schema\\\/logo\\\/image\\\/\",\n\t                \"url\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/05\\\/ibkr-campus-logo.jpg\",\n\t                \"contentUrl\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/05\\\/ibkr-campus-logo.jpg\",\n\t                \"width\": 669,\n\t                \"height\": 669,\n\t                \"caption\": \"Interactive Brokers\"\n\t            },\n\t            \"image\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#\\\/schema\\\/logo\\\/image\\\/\"\n\t            },\n\t            \"publishingPrinciples\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/about-ibkr-campus\\\/\",\n\t            \"ethicsPolicy\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/cyber-security-notice\\\/\"\n\t        },\n\t        {\n\t            \"@type\": \"Person\",\n\t            \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#\\\/schema\\\/person\\\/288f5f80a63d81b02dba7b1157a95125\",\n\t            \"name\": \"Jason\",\n\t            \"url\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/author\\\/jasonpyquantnews\\\/\"\n\t        }\n\t    ]\n\t}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How to Backtest a Moving Average Strategy with Backtrader Python","description":"Backtrader Python is an open-source framework for testing trading strategies on historical price data before you risk real money.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.interactivebrokers.com\/campus\/wp-json\/wp\/v2\/posts\/260921\/","og_locale":"en_US","og_type":"article","og_title":"How to Backtest a Moving Average Strategy with Backtrader Python","og_description":"Backtrader Python is an open-source framework for testing trading strategies on historical price data before you risk real money.","og_url":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/","og_site_name":"IBKR Campus US","article_published_time":"2026-11-09T17:10:40+00:00","article_modified_time":"2026-11-09T17:11:48+00:00","og_image":[{"width":1000,"height":563,"url":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/03\/python-blue-grid-dots.jpg","type":"image\/jpeg"}],"author":"Jason","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jason","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/ibkrcampus.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/#article","isPartOf":{"@id":"https:\/\/ibkrcampus.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/"},"author":{"name":"Jason","@id":"https:\/\/ibkrcampus.com\/campus\/#\/schema\/person\/288f5f80a63d81b02dba7b1157a95125"},"headline":"How to Backtest a Moving Average Strategy with Backtrader Python","datePublished":"2026-11-09T17:10:40+00:00","dateModified":"2026-11-09T17:11:48+00:00","mainEntityOfPage":{"@id":"https:\/\/ibkrcampus.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/"},"wordCount":1443,"commentCount":0,"publisher":{"@id":"https:\/\/ibkrcampus.com\/campus\/#organization"},"image":{"@id":"https:\/\/ibkrcampus.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/03\/python-blue-grid-dots.jpg","keywords":["Algo Trading","Backtrader","Data Sience","Matplotlib","moving average","Python","Sharpe Ratio"],"articleSection":["Data Science","Programming Languages","Python Development","Quant","Quant Development"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/ibkrcampus.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/ibkrcampus.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/","url":"https:\/\/ibkrcampus.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/","name":"How to Backtest a Moving Average Strategy with Backtrader Python | IBKR Campus US","isPartOf":{"@id":"https:\/\/ibkrcampus.com\/campus\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ibkrcampus.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/#primaryimage"},"image":{"@id":"https:\/\/ibkrcampus.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/03\/python-blue-grid-dots.jpg","datePublished":"2026-11-09T17:10:40+00:00","dateModified":"2026-11-09T17:11:48+00:00","description":"Backtrader Python is an open-source framework for testing trading strategies on historical price data before you risk real money.","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ibkrcampus.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ibkrcampus.com\/campus\/ibkr-quant-news\/how-to-backtest-a-moving-average-strategy-with-backtrader-python\/#primaryimage","url":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/03\/python-blue-grid-dots.jpg","contentUrl":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/03\/python-blue-grid-dots.jpg","width":1000,"height":563,"caption":"Python Quant"},{"@type":"WebSite","@id":"https:\/\/ibkrcampus.com\/campus\/#website","url":"https:\/\/ibkrcampus.com\/campus\/","name":"IBKR Campus US","description":"Financial Education from Interactive Brokers","publisher":{"@id":"https:\/\/ibkrcampus.com\/campus\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ibkrcampus.com\/campus\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/ibkrcampus.com\/campus\/#organization","name":"Interactive Brokers","alternateName":"IBKR","url":"https:\/\/ibkrcampus.com\/campus\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ibkrcampus.com\/campus\/#\/schema\/logo\/image\/","url":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/05\/ibkr-campus-logo.jpg","contentUrl":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/05\/ibkr-campus-logo.jpg","width":669,"height":669,"caption":"Interactive Brokers"},"image":{"@id":"https:\/\/ibkrcampus.com\/campus\/#\/schema\/logo\/image\/"},"publishingPrinciples":"https:\/\/www.interactivebrokers.com\/campus\/about-ibkr-campus\/","ethicsPolicy":"https:\/\/www.interactivebrokers.com\/campus\/cyber-security-notice\/"},{"@type":"Person","@id":"https:\/\/ibkrcampus.com\/campus\/#\/schema\/person\/288f5f80a63d81b02dba7b1157a95125","name":"Jason","url":"https:\/\/www.interactivebrokers.com\/campus\/author\/jasonpyquantnews\/"}]}},"jetpack_featured_media_url":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2023\/03\/python-blue-grid-dots.jpg","_links":{"self":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/posts\/260921","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/users\/1518"}],"replies":[{"embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/comments?post=260921"}],"version-history":[{"count":11,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/posts\/260921\/revisions"}],"predecessor-version":[{"id":260936,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/posts\/260921\/revisions\/260936"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/media\/186234"}],"wp:attachment":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/media?parent=260921"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/categories?post=260921"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/tags?post=260921"},{"taxonomy":"contributors-categories","embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/contributors-categories?post=260921"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}