{"id":203568,"date":"2024-03-19T11:16:18","date_gmt":"2024-03-19T15:16:18","guid":{"rendered":"https:\/\/ibkrcampus.com\/?p=203568"},"modified":"2024-08-12T15:25:38","modified_gmt":"2024-08-12T19:25:38","slug":"blankly-python-backtesting-guide","status":"publish","type":"post","link":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/","title":{"rendered":"Blankly &#8211; Python Backtesting Guide"},"content":{"rendered":"\n<p><em>The article &#8220;<a href=\"https:\/\/algotrading101.com\/learn\/blankly-backtesting-guide\/\">Blankly &#8211; Python Backtesting Guide<\/a>&#8221; first appeared on AlgoTrading101 blog.<\/em><\/p>\n\n\n\n<p><em>Excerpt<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-is-blankly\">What is Blankly?<\/h2>\n\n\n\n<p>Blankly is an open-source Python backtester that allows algorithmic traders to build, backtest, and run their trading algorithms for stocks, crypto, futures, and forex.<\/p>\n\n\n\n<p><a>Link:&nbsp;<\/a><a href=\"https:\/\/github.com\/blankly-finance\/blankly\">https:\/\/github.com\/blankly-finance\/blankly<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-is-blankly-used-for\">What is Blankly used for?<\/h2>\n\n\n\n<p>Blankly is mainly used by algorithmic traders for backtesting and running trading strategies in Python.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-why-should-i-use-blankly\">Why should I use Blankly?<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Blankly is completely free.<\/li>\n\n\n\n<li>Blankly is easy to use and beginner-friendly.<\/li>\n\n\n\n<li>Is precise.<\/li>\n\n\n\n<li>Has built-in support for exchanges such as Binance, Coinbase, and Alpaca.<\/li>\n\n\n\n<li>Allows for backtesting using alternative data<\/li>\n\n\n\n<li>Is maintained.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-why-shouldn-t-i-use-blankly\">Why shouldn\u2019t I use Blankly?<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Doesn\u2019t have advanced orders (OCO, straddle, etc.)<\/li>\n\n\n\n<li>Doesn\u2019t have advanced position handling.<\/li>\n\n\n\n<li>Should have more features.<\/li>\n\n\n\n<li>Some parts of the website and documentation are outdated.<\/li>\n\n\n\n<li>It seems that the development has slowed down.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-is-blankly-free\">Is Blankly free?<\/h2>\n\n\n\n<p>Yes, Blankly is completely free and all the code for it is open-sourced. The upcoming premium part of it will feature a cloud-hosted solution.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-are-some-blankly-alternatives\">What are some Blankly alternatives?<\/h2>\n\n\n\n<p>Blankly can be replaced with other software that can be more suitable for your needs. Here are some of them:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a><\/a><a href=\"https:\/\/algotrading101.com\/learn\/quantconnect-guide\/\">QuantConnect<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/algotrading101.com\/learn\/pine-script-tradingview-guide\/\">TradingView (Pine Script)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/algotrading101.com\/learn\/vectorbt-guide\/\">VectorBT<\/a><\/li>\n\n\n\n<li>Trality<\/li>\n\n\n\n<li>QuantRocket<\/li>\n\n\n\n<li>cTrader<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-exchanges-and-brokers-does-blankly-support\">What exchanges and brokers does Blankly support?<\/h2>\n\n\n\n<p>Blankly supports the following exchanges and brokers at the time of writing this article:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a><\/a><a href=\"https:\/\/algotrading101.com\/learn\/alpaca-trading-review\/\">Alpaca<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/algotrading101.com\/learn\/binance-python-api-guide\/\">Binance<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/algotrading101.com\/learn\/coinbase-pro-api-guide\/\">Coinbase Pro<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/algotrading101.com\/learn\/kucoin-api-guide\/\">Kucoin<\/a><\/li>\n\n\n\n<li>Oanda<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-how-does-blankly-work\">How does Blankly work?<\/h2>\n\n\n\n<p>Blankly works by running an initialization layer that sets up your algorithm and the overall state that it will be using. Then, there are chains that you can add which can be executed on events such as each bar, each price, and each order.<\/p>\n\n\n\n<p>Once the algorithm backtest is done, or once you stop your live trading it will start a teardown process to gracefully stop. This can be observed from the picture below:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"1095\" height=\"703\" data-src=\"\/campus\/wp-content\/uploads\/sites\/2\/2024\/03\/blankly-strategy-AlgoTrading101.jpg\" alt=\"\" class=\"wp-image-203571 lazyload\" data-srcset=\"https:\/\/ibkrcampus.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/03\/blankly-strategy-AlgoTrading101.jpg 1095w, https:\/\/ibkrcampus.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/03\/blankly-strategy-AlgoTrading101-700x449.jpg 700w, https:\/\/ibkrcampus.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/03\/blankly-strategy-AlgoTrading101-300x193.jpg 300w, https:\/\/ibkrcampus.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/03\/blankly-strategy-AlgoTrading101-768x493.jpg 768w\" data-sizes=\"(max-width: 1095px) 100vw, 1095px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1095px; aspect-ratio: 1095\/703;\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">How to get started with Blankly?<\/h2>\n\n\n\n<p>To get started with Blankly, all you need to do is to install the Blankly library and initialize the project. We do this by writing the following commands:<\/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=\"\">pip install blankly\nmkdir blankly-project\ncd blankly-project\nblankly init<\/pre>\n\n\n\n<p>Now, you will be presented with different options that will help you customize blankly to fit your project\u2019s needs. It will start you off with a question asking you to choose an exchange to connect to or go without one.<\/p>\n\n\n\n<p><a>Blankly suggests users pick an exchange to get more accurate data, have the option to get live data, and have the ability to easily switch to a live trading algorithm. I\u2019ll go with&nbsp;<\/a><a href=\"https:\/\/algotrading101.com\/learn\/alpaca-trading-review\/\">Alpaca<\/a>.<\/p>\n\n\n\n<p>After that, you will be asked to select what type of model you want to use. In our case, we will be creating a Strategy. For the next question, we will select that we don\u2019t need a template, but feel free to select that option if you want to inspect it.<\/p>\n\n\n\n<p>Finally, you can choose to add your API key for Alpaca now or later. I\u2019ll choose later as I want to show you how you can do this by changing a file.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to set API keys in Blankly?<\/h2>\n\n\n\n<p>To set API keys in Blankly, you can navigate to the&nbsp;<code>keys.json<\/code>&nbsp;file where you will find the supported exchanges and be able to set your API keys by changing the file. You will also see the&nbsp;<code>sandbox<\/code>&nbsp;parameter which can be set to True to use a paper trading account.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"json\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{\n    \"alpaca\": {\n        \"example-portfolio\": {\n            \"API_KEY\": \"********************\",\n            \"API_SECRET\": \"********************\",\n            \"sandbox\": false\n        }\n    },<\/pre>\n\n\n\n<p>Above, I\u2019ll place my Alpaca API keys and set the sandbox parameter to&nbsp;<code>true<\/code>.<a><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What are the components of Blankly\u2019s strategies?<\/h2>\n\n\n\n<p>The main two components of Blankly\u2019s strategies are the initializer and price data event handler. The initializer is used to lay out the foundation of your algorithm and set the state variables that are to be used.<\/p>\n\n\n\n<p>For example, here is a state that is aware of the traded symbol and constrains the data that will be passed to a deque that can hold a maximum of 150 candles. Once a new candle arrives, the oldest one will be pushed out. It also sets the position to be false.<\/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=\"\">def init(symbol, state: blankly.StrategyState):\n    # This gets the past 150 data points as a deque to reduce memory usage\n    state.variables['history'] = state.interface.history(\n        symbol, to=150, return_as='deque'\n    )['close']\n    state.variables['owns_position'] = False<\/pre>\n\n\n\n<p>When it comes to the price events, here is an example of a price event that takes in the candles and calculates the RSI upon which it makes a market buy order and sets the position state to&nbsp;<code>True<\/code>&nbsp;if the RSI is oversold:<\/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=\"\">def price_event(price, symbol, state: StrategyState):\n    state.variables['history'].append(price)\n    rsi = blankly.indicators.rsi(state.variables['history'])\n    if rsi[-1] &lt; 30 and not state.variables['owns_position']:\n        buy = int(state.interface.cash \/ price) # calculate number of shares\n        state.interface.market_order(symbol, side='buy', size=buy)\n        state.variables['owns_position'] = True<\/pre>\n\n\n\n<p>Now that you have a sense of how Blankly functions, we can go into it a bit deeper and code a pairs trading strategy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to create orders with Blankly?<\/h2>\n\n\n\n<p>To create orders with Blankly, we can utilise the state to execute orders such as the market, limit, and stop orders. An example of a Blankly order is as follows:<\/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=\"\">order = interface.market_order('BTC-USD', 'buy', 10)<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">How to create a pairs trading strategy in Blankly?<\/h2>\n\n\n\n<p>To create a pairs trading strategy in Blankly, we will need to build out the main components of the trading strategy that we\u2019ll be using.<\/p>\n\n\n\n<p>In this case, it is a pairs trade strategy that bets that if the two assets diverge \u2013 they will likely converge again. As you can see, this strategy relies on a couple of prerequisites such as cointegration between the two assets.<\/p>\n\n\n\n<p><a>To learn more about pairs trading, read our blog&nbsp;<\/a><a href=\"https:\/\/algotrading101.com\/learn\/pairs-trading-guide\/\">here<\/a>&nbsp;and if you want to find out how you can obtain plausible pairs with machine learning, check out this&nbsp;<a href=\"https:\/\/algotrading101.com\/learn\/cluster-analysis-guide\/\">blog post<\/a>.<\/p>\n\n\n\n<p>The assets that we will use for this example are Box (BOX) and Dropbox (DBX) as we already have a sense of their cointegrated nature based on our previous articles and analyses. For this example, we will hold at maximum only one position (1 short and 1 long) at a time and deploy 100% of our cash.<\/p>\n\n\n\n<p>We will enter a position if one stock has moved 5% or more than the other one over the course of the last five days. We will short the top one and long the bottom one until it reverses.<\/p>\n\n\n\n<p>Let\u2019s build out the initializer while thinking about what the primary state variables of our strategy will be.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to initialise a Blankly strategy?<\/h2>\n\n\n\n<p>To initialize a Blankly strategy, we will build out the Blankly initializer with a state that will support the execution of our strategy.<\/p>\n\n\n\n<p>Our state will need to keep track of the following parts:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>The close price history of BOX<\/li>\n\n\n\n<li>The close price history of DBX<\/li>\n\n\n\n<li>Percentage move<\/li>\n\n\n\n<li>Position status<\/li>\n\n\n\n<li>Trade status (did we long BOX or DBX)<\/li>\n<\/ol>\n\n\n\n<p>We will cap the close histories for both prices to hold a maximum of 5 candles as we don\u2019t need more than that. We will also be using the Futures version of the Blankly strategy state as we will be longing and shorting the stocks.<\/p>\n\n\n\n<p>Let\u2019s code out the state that we want to be initialised:<\/p>\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 blankly\n\ndef init(symbol, state: blankly.FuturesStrategyState):\n    state.variables[\"dbx_history\"] = state.interface.history(\n        \"BOX\", to=5, return_as=\"deque\"\n    )[\"close\"]\n    state.variables[\"box_history\"] = state.interface.history(\n        \"DBX\", to=5, return_as=\"deque\"\n    )[\"close\"]\n\n    state.variables[\"dbx_change\"] = 0\n    state.variables[\"box_change\"] = 0\n\n    state.variables[\"in_position\"] = False\n    state.variables[\"dbx_long\"] = False\n    state.variables[\"box_long\"] = False\n\n    state.variables[\"dbx_size\"] = 0\n    state.variables[\"box_size\"] = 0<\/pre>\n\n\n\n<p>The next step is to create a&nbsp;<code>price_event<\/code>&nbsp;that will be intaking the asset data. The issue here, as with most backtesting libraries, is that the initialised state is often localised to a single asset.<\/p>\n\n\n\n<p>In other words, if we passed the price_event in the usually way of attaching each stock separately, we would have issues with:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Synchronising the dequeues<\/li>\n\n\n\n<li>Sharing a state (would need to build custom solutions or use global variables)<\/li>\n\n\n\n<li>Executing orders properly<\/li>\n<\/ul>\n\n\n\n<p>Thankfully, Blankly offers an arbitrage event which is a wrapper for the usual&nbsp;<code>price_event<\/code>.<\/p>\n\n\n\n<p><em>Visit <a href=\"https:\/\/algotrading101.com\/learn\/blankly-backtesting-guide\/\">AlgoTrading101<\/a> to learn about the Blankly arbitrage event.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Blankly is mainly used by algorithmic traders for backtesting and running trading strategies in Python.<\/p>\n","protected":false},"author":815,"featured_media":203583,"comment_status":"open","ping_status":"closed","sticky":true,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[339,343,349,338,341],"tags":[851,4873,16838,865,595],"contributors-categories":[13746],"class_list":{"0":"post-203568","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-data-science","8":"category-programing-languages","9":"category-python-development","10":"category-ibkr-quant-news","11":"category-quant-development","12":"tag-algo-trading","13":"tag-backtesting","14":"tag-blankly","15":"tag-github","16":"tag-python","17":"contributors-categories-algotrading101"},"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 v27.5) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Blankly &#8211; Python Backtesting Guide | IBKR Quant<\/title>\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\/203568\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Blankly - Python Backtesting Guide\" \/>\n<meta property=\"og:description\" content=\"Blankly is mainly used by algorithmic traders for backtesting and running trading strategies in Python.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/\" \/>\n<meta property=\"og:site_name\" content=\"IBKR Campus US\" \/>\n<meta property=\"article:published_time\" content=\"2024-03-19T15:16:18+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-08-12T19:25:38+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/03\/python-scrabble-board.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=\"Igor Radovanovic\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Igor Radovanovic\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 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:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/blankly-python-backtesting-guide\\\/#article\",\n\t            \"isPartOf\": {\n\t                \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/blankly-python-backtesting-guide\\\/\"\n\t            },\n\t            \"author\": {\n\t                \"name\": \"Igor Radovanovic\",\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#\\\/schema\\\/person\\\/b43b33f424bad38d84a7b78eb0193592\"\n\t            },\n\t            \"headline\": \"Blankly &#8211; Python Backtesting Guide\",\n\t            \"datePublished\": \"2024-03-19T15:16:18+00:00\",\n\t            \"dateModified\": \"2024-08-12T19:25:38+00:00\",\n\t            \"mainEntityOfPage\": {\n\t                \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/blankly-python-backtesting-guide\\\/\"\n\t            },\n\t            \"wordCount\": 1231,\n\t            \"commentCount\": 0,\n\t            \"publisher\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#organization\"\n\t            },\n\t            \"image\": {\n\t                \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/blankly-python-backtesting-guide\\\/#primaryimage\"\n\t            },\n\t            \"thumbnailUrl\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/03\\\/python-scrabble-board.jpg\",\n\t            \"keywords\": [\n\t                \"Algo Trading\",\n\t                \"backtesting\",\n\t                \"Blankly\",\n\t                \"GitHub\",\n\t                \"Python\"\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:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/blankly-python-backtesting-guide\\\/#respond\"\n\t                    ]\n\t                }\n\t            ]\n\t        },\n\t        {\n\t            \"@type\": \"WebPage\",\n\t            \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/blankly-python-backtesting-guide\\\/\",\n\t            \"url\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/blankly-python-backtesting-guide\\\/\",\n\t            \"name\": \"Blankly - Python Backtesting Guide | IBKR Campus US\",\n\t            \"isPartOf\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/#website\"\n\t            },\n\t            \"primaryImageOfPage\": {\n\t                \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/blankly-python-backtesting-guide\\\/#primaryimage\"\n\t            },\n\t            \"image\": {\n\t                \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/blankly-python-backtesting-guide\\\/#primaryimage\"\n\t            },\n\t            \"thumbnailUrl\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/03\\\/python-scrabble-board.jpg\",\n\t            \"datePublished\": \"2024-03-19T15:16:18+00:00\",\n\t            \"dateModified\": \"2024-08-12T19:25:38+00:00\",\n\t            \"inLanguage\": \"en-US\",\n\t            \"potentialAction\": [\n\t                {\n\t                    \"@type\": \"ReadAction\",\n\t                    \"target\": [\n\t                        \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/blankly-python-backtesting-guide\\\/\"\n\t                    ]\n\t                }\n\t            ]\n\t        },\n\t        {\n\t            \"@type\": \"ImageObject\",\n\t            \"inLanguage\": \"en-US\",\n\t            \"@id\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/ibkr-quant-news\\\/blankly-python-backtesting-guide\\\/#primaryimage\",\n\t            \"url\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/03\\\/python-scrabble-board.jpg\",\n\t            \"contentUrl\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/03\\\/python-scrabble-board.jpg\",\n\t            \"width\": 1000,\n\t            \"height\": 563,\n\t            \"caption\": \"Python\"\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\\\/b43b33f424bad38d84a7b78eb0193592\",\n\t            \"name\": \"Igor Radovanovic\",\n\t            \"url\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/author\\\/igor-radovanovic\\\/\"\n\t        }\n\t    ]\n\t}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Blankly &#8211; Python Backtesting Guide | IBKR Quant","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\/203568\/","og_locale":"en_US","og_type":"article","og_title":"Blankly - Python Backtesting Guide","og_description":"Blankly is mainly used by algorithmic traders for backtesting and running trading strategies in Python.","og_url":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/","og_site_name":"IBKR Campus US","article_published_time":"2024-03-19T15:16:18+00:00","article_modified_time":"2024-08-12T19:25:38+00:00","og_image":[{"width":1000,"height":563,"url":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/03\/python-scrabble-board.jpg","type":"image\/jpeg"}],"author":"Igor Radovanovic","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Igor Radovanovic","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/#article","isPartOf":{"@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/"},"author":{"name":"Igor Radovanovic","@id":"https:\/\/ibkrcampus.com\/campus\/#\/schema\/person\/b43b33f424bad38d84a7b78eb0193592"},"headline":"Blankly &#8211; Python Backtesting Guide","datePublished":"2024-03-19T15:16:18+00:00","dateModified":"2024-08-12T19:25:38+00:00","mainEntityOfPage":{"@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/"},"wordCount":1231,"commentCount":0,"publisher":{"@id":"https:\/\/ibkrcampus.com\/campus\/#organization"},"image":{"@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/#primaryimage"},"thumbnailUrl":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/03\/python-scrabble-board.jpg","keywords":["Algo Trading","backtesting","Blankly","GitHub","Python"],"articleSection":["Data Science","Programming Languages","Python Development","Quant","Quant Development"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/","url":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/","name":"Blankly - Python Backtesting Guide | IBKR Campus US","isPartOf":{"@id":"https:\/\/ibkrcampus.com\/campus\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/#primaryimage"},"image":{"@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/#primaryimage"},"thumbnailUrl":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/03\/python-scrabble-board.jpg","datePublished":"2024-03-19T15:16:18+00:00","dateModified":"2024-08-12T19:25:38+00:00","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.interactivebrokers.com\/campus\/ibkr-quant-news\/blankly-python-backtesting-guide\/#primaryimage","url":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/03\/python-scrabble-board.jpg","contentUrl":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/03\/python-scrabble-board.jpg","width":1000,"height":563,"caption":"Python"},{"@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\/b43b33f424bad38d84a7b78eb0193592","name":"Igor Radovanovic","url":"https:\/\/www.interactivebrokers.com\/campus\/author\/igor-radovanovic\/"}]}},"jetpack_featured_media_url":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/03\/python-scrabble-board.jpg","_links":{"self":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/posts\/203568","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\/815"}],"replies":[{"embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/comments?post=203568"}],"version-history":[{"count":0,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/posts\/203568\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/media\/203583"}],"wp:attachment":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/media?parent=203568"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/categories?post=203568"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/tags?post=203568"},{"taxonomy":"contributors-categories","embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/contributors-categories?post=203568"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}