{"id":216029,"date":"2024-12-06T11:04:14","date_gmt":"2024-12-06T16:04:14","guid":{"rendered":"https:\/\/ibkrcampus.com\/campus\/?post_type=trading-lessons&#038;p=216029"},"modified":"2025-09-29T13:57:23","modified_gmt":"2025-09-29T17:57:23","slug":"implementing-donchian-channel-trading-app","status":"publish","type":"trading-lessons","link":"https:\/\/www.interactivebrokers.com\/campus\/trading-lessons\/implementing-donchian-channel-trading-app\/","title":{"rendered":"Implementing Donchian Channel Trading App"},"content":{"rendered":"\n<p><strong>Building our trading application<\/strong><\/p>\n\n\n\n<p>The `TradingApp` class is a Python application that interacts with the Interactive Brokers (IB) API. It extends `EClient` and `EWrapper` classes to manage connections, handle data, and execute trades. Below is a concise explanation of its key components:<\/p>\n\n\n\n<p><strong>Class Overview<\/strong><\/p>\n\n\n\n<p><strong>Parent Classes**<\/strong>: Inherits from `EClient` and `EWrapper`, enabling communication and interaction with the IB API.<\/p>\n\n\n\n<p><strong>Attributes<\/strong>:<\/p>\n\n\n\n<p>&#8211; `data`: A dictionary storing historical data fetched from IB, indexed by request IDs.<\/p>\n\n\n\n<p>&#8211; `nextOrderId`: An integer storing the next valid order ID needed to place trades.<\/p>\n\n\n\n<p><\/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 time\nimport threading\nfrom datetime import datetime\nfrom typing import Dict, Optional\nimport pandas as pd\nimport warnings\nwarnings.filterwarnings(\"ignore\")<\/pre>\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=\"\">from ibapi.client import EClient\nfrom ibapi.wrapper import EWrapper\nfrom ibapi.contract import Contract\nfrom ibapi.order import Order\nfrom ibapi.common import BarData<\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Donchian Channel Overview<\/strong><\/p>\n\n\n\n<p>The Donchian Channel is a trend-following indicator widely used by traders to identify market trends, breakouts, and trading opportunities. It consists of three key lines:<\/p>\n\n\n\n<p><strong>Upper Band<\/strong>: The highest high over a specified period.<\/p>\n\n\n\n<p><strong>Lower Band<\/strong>: The lowest low over the same period.<\/p>\n\n\n\n<p><strong>Middle Line<\/strong>: The average of the upper and lower bands.<\/p>\n\n\n\n<p><strong>How Traders Use Donchian Channels<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>1. Identifying Breakouts<\/strong><\/p>\n\n\n\n<p>&#8211; Traders use the upper and lower bands to spot breakouts. A price crossing above the upper band signals a bullish breakout, indicating a potential buy opportunity. Conversely, a price crossing below the lower band suggests a bearish breakout, signaling a potential sell opportunity.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>2. Trend Confirmation<\/strong><\/p>\n\n\n\n<p>&#8211; The Donchian Channel helps confirm existing trends. If the price stays near or above the upper band, it indicates strong upward momentum, suggesting the trend may continue. If the price stays near or below the lower band, it reflects strong downward momentum, guiding traders on whether to stay in or exit a trade.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>3. Setting Entry and Exit Points<\/strong><\/p>\n\n\n\n<p>&#8211; Traders use the Donchian Channel to set entry and exit points. They might enter a long position when the price breaks above the upper band and exit when the price falls toward the middle or lower band. For short positions, traders enter when the price breaks below the lower band and exit as it rises back.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>4. Risk Management<\/strong><\/p>\n\n\n\n<p>&#8211; The Donchian Channel is also used for risk management. Traders set stop-loss orders based on the lower band for long positions or the upper band for short positions, helping to limit potential losses if the market moves against their trade.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>5. Range Trading<\/strong><\/p>\n\n\n\n<p>&#8211; During sideways markets, traders can trade within the Donchian Channel\u2019s range. They buy near the lower band and sell near the upper band, profiting from price reversals within the channel.<\/p>\n\n\n\n<p>The Donchian Channel is a versatile tool that helps traders identify breakouts, confirm trends, and improve their trading strategies. By analyzing price movements relative to the channel\u2019s bands, traders can make better-informed decisions on entry, exit, and risk management, enhancing their overall trading effectiveness.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Building our trading application<\/strong><\/p>\n\n\n\n<p>The `TradingApp` class is a Python application that interacts with the Interactive Brokers (IB) API. It extends `EClient` and `EWrapper` classes to manage connections, handle data, and execute trades. <\/p>\n\n\n\n<p><strong>Class Overview<\/strong><\/p>\n\n\n\n<p><strong>Parent Classes<\/strong>: Inherits from `EClient` and `EWrapper`, enabling communication and interaction with the IB API.<\/p>\n\n\n\n<p><strong>Attributes<\/strong>:<\/p>\n\n\n\n<p>&#8211; `data`: A dictionary storing historical data fetched from IB, indexed by request IDs.<\/p>\n\n\n\n<p>&#8211; `nextOrderId`: An integer storing the next valid order ID needed to place trades.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Key Methods<\/strong><\/p>\n\n\n\n<p>1. <strong>Initialization (`__init__`)<\/strong>:<\/p>\n\n\n\n<p>&#8211; Initializes the `TradingApp` class.<\/p>\n\n\n\n<p>&#8211; Sets up the client and wrapper, and initializes the `data` dictionary to store historical data.<\/p>\n\n\n\n<p>2. <strong>Error Handling (`error`)<\/strong>:<\/p>\n\n\n\n<p>&#8211; Handles errors received from IB API.<\/p>\n\n\n\n<p>&#8211; Prints the error details including request ID, error code, and descriptive error message.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>3. <strong>Order ID Management (`nextValidId`)<\/strong>:<\/p>\n\n\n\n<p>&#8211; Receives and sets the next valid order ID from IB.<\/p>\n\n\n\n<p>&#8211; Updates the `nextOrderId` attribute to ensure correct order placement.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>4. <strong>Fetching Historical Data (`get_historical_data`)<\/strong>:<\/p>\n\n\n\n<p>&#8211; Requests historical market data for a given contract.<\/p>\n\n\n\n<p>&#8211; Stores the data in a Pandas DataFrame, indexed by time with columns for &#8216;high&#8217;, &#8216;low&#8217;, and &#8216;close&#8217; prices.<\/p>\n\n\n\n<p>&#8211; Returns the DataFrame containing the historical data.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>5. <strong>Storing Historical Data (`historicalData`)<\/strong>:<\/p>\n\n\n\n<p>&#8211; Processes and stores historical data received from IB callbacks.<\/p>\n\n\n\n<p>&#8211; Updates the DataFrame with high, low, and close prices based on the received data.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>6. <strong>Creating Contract (`get_contract`)<\/strong>:<\/p>\n\n\n\n<p>&#8211; Creates a contract object for a stock based on the provided symbol.<\/p>\n\n\n\n<p>&#8211; Configures the contract to trade on the SMART exchange in USD.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>7. <strong>Placing Orders (`place_order`)<\/strong>:<\/p>\n\n\n\n<p>&#8211; Places an order using the provided contract, action (buy\/sell), order type (e.g., market, limit), and quantity.<\/p>\n\n\n\n<p>&#8211; Uses the `nextOrderId`, places the order, increments the order ID, and confirms the order placement.<\/p>\n\n\n\n<p>The `TradingApp` class facilitates automated trading by directly interacting with the IB API. It manages error handling, data requests, and order executions programmatically, providing a framework for developing automated trading strategies.<\/p>\n\n\n\n<p><\/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=\"\">class TradingApp(EClient, EWrapper):\n    \"\"\"\n    A trading application class that interacts with the Interactive Brokers (IB) API.\n    This class handles connections, data requests, and order placements using \n    the IB API by extending the EClient and EWrapper classes.\n\n    Attributes\n    ----------\n    data : dict\n        A dictionary to store historical data fetched from IB, with request IDs as keys.\n    nextOrderId : int or None\n        Stores the next valid order ID to be used for placing trades.\n\n    Methods\n    -------\n    error(reqId, errorCode, errorString, advanced)\n        Handles error messages received from IB.\n    nextValidId(orderId)\n        Receives and sets the next valid order ID for placing trades.\n    get_historical_data(reqId, contract)\n        Requests and retrieves historical market data for a given contract.\n    historicalData(reqId, bar)\n        Processes and stores historical data received from IB callbacks.\n    get_contract(symbol)\n        Creates and returns a stock contract object based on the provided symbol.\n    place_order(contract, action, order_type, quantity)\n        Places an order using the provided contract, action, order type, and quantity.\n    \"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"\n        Initializes the TradingApp instance, setting up the client and wrapper \n        components, and initializing data storage.\n        \"\"\"\n        EClient.__init__(self, self)\n        self.data: Dict[int, pd.DataFrame] = {}\n        self.nextOrderId: Optional[int] = None\n\n    def error(self, reqId: int, errorCode: int, errorString: str, advanced: any) -> None:\n        \"\"\"\n        Handles errors received from the IB API.\n\n        Parameters\n        ----------\n        reqId : int\n            The request ID associated with the error.\n        errorCode : int\n            The error code received from IB.\n        errorString : str\n            A descriptive error message.\n        advanced : any\n            Additional advanced error information (not commonly used).\n        \"\"\"\n        print(f\"Error: {reqId}, {errorCode}, {errorString}\")\n def nextValidId(self, orderId: int) -> None:\n        \"\"\"\n        Receives and sets the next valid order ID for placing trades.\n\n        Parameters\n        ----------\n        orderId : int\n            The next valid order ID received from IB.\n        \"\"\"\n        super().nextValidId(orderId)\n        self.nextOrderId = orderId\n\n    def get_historical_data(self, reqId: int, contract: Contract) -> pd.DataFrame:\n        \"\"\"\n        Requests and retrieves historical market data for a given contract.\n\n        Parameters\n        ----------\n        reqId : int\n            The request ID to associate with this historical data request.\n        contract : ibapi.contract.Contract\n            The contract object representing the financial instrument for which\n            historical data is requested.\n\n        Returns\n        -------\n        pandas.DataFrame\n            A DataFrame containing the historical data, indexed by time with \n            columns for 'high', 'low', and 'close' prices.\n        \"\"\"\n        self.data[reqId] = pd.DataFrame(columns=[\"time\", \"high\", \"low\", \"close\"])\n        self.data[reqId].set_index(\"time\", inplace=True)\n        self.reqHistoricalData(\n            reqId=reqId,\n            contract=contract,\n            endDateTime=\"\",\n            durationStr=\"1 D\",\n            barSizeSetting=\"1 min\",\n            whatToShow=\"MIDPOINT\",\n            useRTH=0,\n            formatDate=2,\n            keepUpToDate=False,\n            chartOptions=[],\n        )\n        time.sleep(5)\n        return self.data[reqId]\n\n  def historicalData(self, reqId: int, bar: BarData) -> None:\n        \"\"\"\n        Processes and stores historical data received from IB callbacks.\n\n        Parameters\n        ----------\n        reqId : int\n            The request ID associated with this historical data.\n        bar : ibapi.common.BarData\n            The bar data received from IB containing high, low, and close prices.\n        \"\"\"\n        # Get the current DataFrame at the request ID\n        df = self.data[reqId]\n\n        # Set the current bar data into the DataFrame\n        df.loc[\n            pd.to_datetime(bar.date, unit=\"s\"), \n            [\"high\", \"low\", \"close\"]\n        ] = [bar.high, bar.low, bar.close]\n\n        # Cast data to floats\n        df = df.astype(float)\n\n        # Assign the DataFrame at the request ID\n        self.data[reqId] = df\n\n    @staticmethod\n    def get_contract(symbol: str) -> Contract:\n        \"\"\"\n        Creates and returns a stock contract object based on the provided symbol.\n\n        Parameters\n        ----------\n        symbol : str\n            The ticker symbol of the stock.\n\n        Returns\n        -------\n        ibapi.contract.Contract\n            A Contract object configured for the specified stock symbol.\n        \"\"\"\n        contract = Contract()\n        contract.symbol = symbol\n        contract.secType = \"STK\"\n        contract.exchange = \"SMART\"\n        contract.currency = \"USD\"\n        return contract\n\ndef place_order(self, contract: Contract, action: str, order_type: str, quantity: int) -> None:\n        \"\"\"\n        Places an order using the provided contract, action, order type, and quantity.\n\n        Parameters\n        ----------\n        contract : ibapi.contract.Contract\n            The financial instrument to be traded.\n        action : str\n            The action to take ('BUY' or 'SELL').\n        order_type : str\n            The type of order ('MKT', 'LMT', etc.).\n        quantity : int\n            The number of shares\/contracts to trade.\n        \"\"\"\n        order = Order()\n        order.action = action\n        order.orderType = order_type\n        order.totalQuantity = quantity\n\n        self.placeOrder(self.nextOrderId, contract, order)\n        self.nextOrderId += 1\n        print(\"Buy order placed\")<\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Areas to improve the app<\/strong><\/p>\n\n\n\n<p><strong>1. Concurrency and Asynchronous Handling<\/strong><\/p>\n\n\n\n<p><strong>Asynchronous Calls<\/strong>: Utilize Python\u2019s `asyncio` or multi-threading to manage multiple data requests and order executions concurrently. This prevents the application from blocking during data fetches or order placements, enhancing overall responsiveness and performance.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Non-Blocking Operations<\/strong>: Replace `time.sleep()` with asynchronous waiting methods to avoid freezing the main thread, allowing other tasks to continue executing seamlessly.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>2. Enhanced Error Handling and Logging<\/strong><\/p>\n\n\n\n<p><strong>Robust Logging<\/strong>: Implement a logging framework (e.g., Python\u2019s `logging` module) to record errors and events with timestamps and log levels (INFO, WARNING, ERROR). This approach provides better insights into the app\u2019s behavior, aiding in troubleshooting and monitoring.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Error Recovery Mechanisms<\/strong>: Develop error recovery protocols, such as automatic retries for failed data requests or order placements, enhancing the app\u2019s resilience in live trading environments.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>3. Order Management and Risk Controls<\/strong><\/p>\n\n\n\n<p><strong>Order Status Tracking<\/strong>: Extend order handling to include real-time tracking of order statuses (e.g., filled, partially filled, canceled) and integrate callbacks to update these statuses within the app.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Risk Management Features<\/strong>: Integrate basic risk management tools, such as setting maximum position sizes, stop-loss, and take-profit orders. This will help protect against significant losses and maintain disciplined trading practices.<\/p>\n\n\n\n<p>These improvements will make the `TradingApp` more efficient, resilient, and safer to use in live trading scenarios, providing a solid foundation for further development and strategy implementation.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong><em>This is a third-party open-source library. It is not associated, supported, or managed by Interactive Brokers, completely independent. And if you\u2019re using Pandas with your IB API or your trading apps, Interactive Brokers cannot help or offer support with Pandas specifically.<\/em><\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>PyQuant News Site:\u00a0<a href=\"https:\/\/www.pyquantnews.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/www.pyquantnews.com\/<\/a><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Code walk-through of the sample Python code for the Donchian Channel trading app using Pandas and the TWS API.<\/p>\n","protected":false},"author":1087,"featured_media":216048,"parent":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"_acf_changed":true,"footnotes":""},"contributors-categories":[17813],"traders-academy":[13117,13125,13128,13132],"class_list":{"0":"post-216029","1":"trading-lessons","2":"type-trading-lessons","3":"status-publish","4":"has-post-thumbnail","6":"contributors-categories-pyquantnews","7":"traders-academy-api","8":"traders-academy-beginner-trading","9":"traders-academy-level","10":"traders-academy-trading-lesson"},"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>Archives | Traders&#039; Academy | IBKR Campus<\/title>\n<meta name=\"description\" content=\"Donchian Channel Trading App sample code TWS API.\" \/>\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\/trading-lessons\/216029\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Implementing Donchian Channel Trading App | IBKR Campus US\" \/>\n<meta property=\"og:description\" content=\"Donchian Channel Trading App sample code TWS API.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.interactivebrokers.com\/campus\/trading-lessons\/implementing-donchian-channel-trading-app\/\" \/>\n<meta property=\"og:site_name\" content=\"IBKR Campus US\" \/>\n<meta property=\"article:modified_time\" content=\"2025-09-29T17:57:23+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/12\/DonChan-thumb-3.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1080\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"5 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\": \"WebPage\",\n\t            \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/trading-lessons\\\/implementing-donchian-channel-trading-app\\\/\",\n\t            \"url\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/trading-lessons\\\/implementing-donchian-channel-trading-app\\\/\",\n\t            \"name\": \"Implementing Donchian Channel Trading App | 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\\\/trading-lessons\\\/implementing-donchian-channel-trading-app\\\/#primaryimage\"\n\t            },\n\t            \"image\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/trading-lessons\\\/implementing-donchian-channel-trading-app\\\/#primaryimage\"\n\t            },\n\t            \"thumbnailUrl\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/12\\\/DonChan-thumb-3.jpg\",\n\t            \"datePublished\": \"2024-12-06T16:04:14+00:00\",\n\t            \"dateModified\": \"2025-09-29T17:57:23+00:00\",\n\t            \"description\": \"Donchian Channel Trading App sample code TWS API.\",\n\t            \"breadcrumb\": {\n\t                \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/trading-lessons\\\/implementing-donchian-channel-trading-app\\\/#breadcrumb\"\n\t            },\n\t            \"inLanguage\": \"en-US\",\n\t            \"potentialAction\": [\n\t                {\n\t                    \"@type\": \"ReadAction\",\n\t                    \"target\": [\n\t                        \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/trading-lessons\\\/implementing-donchian-channel-trading-app\\\/\"\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\\\/trading-lessons\\\/implementing-donchian-channel-trading-app\\\/#primaryimage\",\n\t            \"url\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/12\\\/DonChan-thumb-3.jpg\",\n\t            \"contentUrl\": \"https:\\\/\\\/www.interactivebrokers.com\\\/campus\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/12\\\/DonChan-thumb-3.jpg\",\n\t            \"width\": 1920,\n\t            \"height\": 1080,\n\t            \"caption\": \"Implementing Donchian Channel Trading App\"\n\t        },\n\t        {\n\t            \"@type\": \"BreadcrumbList\",\n\t            \"@id\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/trading-lessons\\\/implementing-donchian-channel-trading-app\\\/#breadcrumb\",\n\t            \"itemListElement\": [\n\t                {\n\t                    \"@type\": \"ListItem\",\n\t                    \"position\": 1,\n\t                    \"name\": \"Academy Lessons\",\n\t                    \"item\": \"https:\\\/\\\/ibkrcampus.com\\\/campus\\\/trading-lessons\\\/\"\n\t                },\n\t                {\n\t                    \"@type\": \"ListItem\",\n\t                    \"position\": 2,\n\t                    \"name\": \"Implementing Donchian Channel Trading App\"\n\t                }\n\t            ]\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}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Archives | Traders' Academy | IBKR Campus","description":"Donchian Channel Trading App sample code TWS API.","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\/trading-lessons\/216029\/","og_locale":"en_US","og_type":"article","og_title":"Implementing Donchian Channel Trading App | IBKR Campus US","og_description":"Donchian Channel Trading App sample code TWS API.","og_url":"https:\/\/www.interactivebrokers.com\/campus\/trading-lessons\/implementing-donchian-channel-trading-app\/","og_site_name":"IBKR Campus US","article_modified_time":"2025-09-29T17:57:23+00:00","og_image":[{"width":1920,"height":1080,"url":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/12\/DonChan-thumb-3.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/ibkrcampus.com\/campus\/trading-lessons\/implementing-donchian-channel-trading-app\/","url":"https:\/\/ibkrcampus.com\/campus\/trading-lessons\/implementing-donchian-channel-trading-app\/","name":"Implementing Donchian Channel Trading App | IBKR Campus US","isPartOf":{"@id":"https:\/\/ibkrcampus.com\/campus\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ibkrcampus.com\/campus\/trading-lessons\/implementing-donchian-channel-trading-app\/#primaryimage"},"image":{"@id":"https:\/\/ibkrcampus.com\/campus\/trading-lessons\/implementing-donchian-channel-trading-app\/#primaryimage"},"thumbnailUrl":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/12\/DonChan-thumb-3.jpg","datePublished":"2024-12-06T16:04:14+00:00","dateModified":"2025-09-29T17:57:23+00:00","description":"Donchian Channel Trading App sample code TWS API.","breadcrumb":{"@id":"https:\/\/ibkrcampus.com\/campus\/trading-lessons\/implementing-donchian-channel-trading-app\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ibkrcampus.com\/campus\/trading-lessons\/implementing-donchian-channel-trading-app\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ibkrcampus.com\/campus\/trading-lessons\/implementing-donchian-channel-trading-app\/#primaryimage","url":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/12\/DonChan-thumb-3.jpg","contentUrl":"https:\/\/www.interactivebrokers.com\/campus\/wp-content\/uploads\/sites\/2\/2024\/12\/DonChan-thumb-3.jpg","width":1920,"height":1080,"caption":"Implementing Donchian Channel Trading App"},{"@type":"BreadcrumbList","@id":"https:\/\/ibkrcampus.com\/campus\/trading-lessons\/implementing-donchian-channel-trading-app\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Academy Lessons","item":"https:\/\/ibkrcampus.com\/campus\/trading-lessons\/"},{"@type":"ListItem","position":2,"name":"Implementing Donchian Channel Trading App"}]},{"@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\/"}]}},"_links":{"self":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/trading-lessons\/216029","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/trading-lessons"}],"about":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/types\/trading-lessons"}],"author":[{"embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/users\/1087"}],"replies":[{"embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/comments?post=216029"}],"version-history":[{"count":0,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/trading-lessons\/216029\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/media\/216048"}],"wp:attachment":[{"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/media?parent=216029"}],"wp:term":[{"taxonomy":"contributors-categories","embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/contributors-categories?post=216029"},{"taxonomy":"traders-academy","embeddable":true,"href":"https:\/\/ibkrcampus.com\/campus\/wp-json\/wp\/v2\/traders-academy?post=216029"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}