{"id":2067,"date":"2023-09-19T20:56:53","date_gmt":"2023-09-19T20:56:53","guid":{"rendered":"https:\/\/eodhd.com\/financial-academy\/?p=2067"},"modified":"2025-02-05T11:36:14","modified_gmt":"2025-02-05T11:36:14","slug":"create-trading-candlesticks-from-a-websocket-with-python","status":"publish","type":"post","link":"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python","title":{"rendered":"Create Trading Candlesticks from a Websocket with Python"},"content":{"rendered":"\n\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-introduction\">Introduction<\/h2>\n\n\n\n<p>This method will work with any websocket data containing a timestamp and price. I&#8217;m going to demonstrate this using EODHD&#8217;s &#8220;crypto&#8221; websocket end-point.  It&#8217;s important to note that websocket end-points for different asset types may be presented differently. If that is the case you will need to make the adjustments to the code. For example in the cryptocurrencies end-point the price is represented as &#8220;p&#8221; and the timestamp is represented as &#8220;t&#8221; as a UNIX timestamp. If you are going to try this with the &#8220;us&#8221;, &#8220;us-quote&#8221;, or &#8220;forex&#8221; end-points, you need to make sure this looks the same for those end-points. If it isn&#8217;t, then just map the fields accordingly. It would also be worth checking the format of the timestamp field. For the &#8220;crypto&#8221; example below the timestamp is a UNIX timestamp. If you are working with source data where this isn&#8217;t the case, then just adjust the date format accordingly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-how-to-create-trading-and-candlesticks-from-a-websocket-stream\">How to create trading and candlesticks from a websocket stream<\/h2>\n\n\n\n<p>Learn how to use Python to craft trading candlesticks from live WebSocket data with the EODHD API. This article breaks down the process in easy-to-follow steps, helping you dive into real-time trading analysis with confidence. Whether you&#8217;re a seasoned trader or just getting started, we&#8217;ve got you covered with practical insights to turn raw data into actionable strategies.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-receiving-the-eodhd-api-s-websocket-in-python\">Receiving the EODHD API&#8217;s WebSocket in Python<\/h2>\n\n\n\n<p>I will break the code up into sections and build it up from there. It will be easier to understand than looking at the final code without seeing how we got there. Also, you can find how Real-time Websockets API works <a href=\"https:\/\/eodhd.com\/financial-apis\/new-real-time-data-api-websockets\/\">here<\/a>.<\/p>\n\n\n\n<p>Accessing the raw websocket stream in Python is fairly straight forward. You will use the &#8220;<strong>websocket-client<\/strong>&#8221; and &#8220;<strong>threading<\/strong>&#8221; libraries. <a href=\"https:\/\/eodhd.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">EODHD API&#8217;s<\/a> supports four endpoints, &#8220;<strong>us<\/strong>&#8220;, &#8220;<strong>us-quote<\/strong>&#8220;, &#8220;<strong>forex<\/strong>&#8221; and &#8220;<strong>crypto<\/strong>&#8220;. <\/p>\n\n\n\n<p>This example will use the &#8220;<strong>websocket-client<\/strong>&#8221; library.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">python3 -m pip install websocket-client<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>A very basic example of what this could look like is as follows:<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">import websocket\nimport threading\nimport time\nimport json\n\nstop_event = threading.Event()\n\ndef collect_data():\n    uri = \"wss:\/\/ws.eodhistoricaldata.com\/ws\/<strong>crypto<\/strong>?api_token=<strong>OeAFFmMliFG5orCUuwAKQ8l4WWFQ67YX<\/strong>\"\n\n    ws = websocket.create_connection(uri)\n\n    payload = {\n        \"action\": \"subscribe\",\n        \"symbols\": \"<strong>BTC-USD<\/strong>\",\n    }\n    ws.send(json.dumps(payload))\n\n    while not stop_event.is_set():\n        message = ws.recv()\n        print(message)\n        <strong>time.sleep(0.25)<\/strong>\n\n    ws.close()\n\n\nt = threading.Thread(target=collect_data)\nt.start()\n\n<strong><strong>time.sleep(0.25)<\/strong><\/strong>\n\nstop_event.set()\nt.join()<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1420\" height=\"512\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-13-at-10.27.26.png\" alt=\"\" class=\"wp-image-2069\" style=\"width:840px;height:302px\"\/><\/figure>\n\n\n\n<p>I&#8217;ve highlighted some points of interest in the code above.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>&#8220;<strong>crypto<\/strong>&#8221; is the endpoint.<\/li>\n\n\n\n<li>&#8220;<strong>OeAFFmMliFG5orCUuwAKQ8l4WWFQ67YX<\/strong>&#8221; is the demo API key for testing.<\/li>\n\n\n\n<li>&#8220;<strong>BTC-USD<\/strong>&#8221; is the market to subscribe too, this can be a comma separated list.<\/li>\n\n\n\n<li>&#8220;<strong>time.sleep(0.25)<\/strong>&#8221; delay between printing on the screen &#8211; be careful removing this or reducing it too low.<\/li>\n\n\n\n<li>&#8220;<strong>time.sleep(0.25)<\/strong>&#8221; duration that the script should run before gracefully exiting.<\/li>\n<\/ol>\n\n\n\n<p class=\"has-text-align-center\"><a class=\"maxbutton-1 maxbutton maxbutton-subscribe-to-api external-css btn\" href=\"https:\/\/eodhd.com\/register\"><span class='mb-text'>Register &amp; Get Data<\/span><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-creating-a-websocket-class\">Creating a WebSocket class<\/h2>\n\n\n\n<p>I have already added this to the Official &#8220;<strong>eodhd<\/strong>&#8221; Python library in version 1.0.23.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">import websocket\nimport threading\nimport signal\nimport time\nimport json\nimport re\nimport pandas as pd\n\npd.set_option('display.float_format', '{:.8f}'.format)\n\n\nclass WebSocketClient:\n    def __init__(\n        self,\n        api_key: str,\n        endpoint: str,\n        symbols: list,\n        store_data: bool = False,\n        display_stream: bool = False,\n        display_candle_1m: bool = False,\n        display_candle_5m: bool = False,\n        display_candle_1h: bool = False,\n    ) -&gt; None:\n        # Validate API key\n        prog = re.compile(r\"^[A-z0-9.]{16,32}$\")\n        if not prog.match(api_key):\n            raise ValueError(\"API key is invalid\")\n\n        # Validate endpoint\n        if endpoint not in [\"us\", \"us_quote\", \"forex\", \"crypto\"]:\n            raise ValueError(\"Endpoint is invalid\")\n\n        # Validate symbol list\n        if len(symbols) == 0:\n            raise ValueError(\"No symbol(s) provided\")\n\n        # Validate individual symbols\n        prog = re.compile(r\"^[A-z0-9-$]{1,48}$\")\n        for symbol in symbols:\n            if not prog.match(symbol):\n                raise ValueError(f\"Symbol is invalid: {symbol}\")\n\n        # Validate max symbol subscriptions\n        if len(symbols) &gt; 50:\n            raise ValueError(\"Max symbol subscription count is 50!\")\n\n        # Map class arguments to private variables\n        self._api_key = api_key\n        self._endpoint = endpoint\n        self._symbols = symbols\n        self._store_data = store_data\n        self._display_stream = display_stream\n        self._display_candle_1m = display_candle_1m\n        self._display_candle_5m = display_candle_5m\n        self._display_candle_1h = display_candle_1h\n\n        self.running = True\n        self.message = None\n        self.stop_event = threading.Event()\n        self.data_list = []\n        self.ws = None\n\n        # Register signal handlers\n        signal.signal(signal.SIGINT, self._signal_handler)\n        signal.signal(signal.SIGTERM, self._signal_handler)\n\n    def _signal_handler(self, signum, frame):\n        print(\"Stopping websocket...\")\n        self.running = False\n        self.stop_event.set()\n        self.thread.join()\n        print(\"Websocket stopped.\")\n\n    def _floor_to_nearest_interval(self, timestamp_ms, interval):\n        # Convert to seconds\n        timestamp_s = timestamp_ms \/\/ 1000\n\n        # Define the number of seconds for each interval\n        seconds_per_minute = 60\n        seconds_per_hour = seconds_per_minute * 60\n\n        # Determine the number of seconds for the given interval\n        if interval == \"1 minute\":\n            interval_seconds = seconds_per_minute\n        elif interval == \"5 minutes\":\n            interval_seconds = 5 * seconds_per_minute\n        elif interval == \"1 hour\":\n            interval_seconds = seconds_per_hour\n        else:\n            raise ValueError(f\"Unsupported interval: {interval}\")\n\n        # Floor to the nearest interval\n        floored_s = (timestamp_s \/\/ interval_seconds) * interval_seconds\n\n        # Convert back to milliseconds\n        floored_ms = floored_s * 1000\n\n        return floored_ms\n\n    def _collect_data(self):\n        self.ws = websocket.create_connection(f\"wss:\/\/ws.eodhistoricaldata.com\/ws\/{self._endpoint}?api_token={self._api_key}\")\n\n        # Send the subscription message\n        payload = {\n            \"action\": \"subscribe\",\n            \"symbols\": \",\".join(self._symbols),\n        }\n        self.ws.send(json.dumps(payload))\n\n        candle_1m = {}\n        candle_5m = {}\n        candle_1h = {}\n\n        # Collect data until the stop event is set\n        while not self.stop_event.is_set():\n            self.message = self.ws.recv()\n            message_json = json.loads(self.message)\n\n            if self._store_data:\n                self.data_list.append(self.message)\n\n            if self._display_stream:\n                print(self.message)\n\n            if self._display_candle_1m:\n                if \"t\" in message_json:\n                    candle_date = self._floor_to_nearest_interval(message_json[\"t\"], \"1 minute\")\n\n                    if \"t\" in candle_1m and (candle_date != candle_1m[\"t\"]):\n                        print(candle_1m)\n\n                        # New candle\n                        candle_1m = {}\n\n                    candle_1m[\"t\"] = candle_date\n\n                if \"s\" in message_json:\n                    candle_1m[\"m\"] = message_json[\"s\"]\n                    candle_1m[\"g\"] = 60\n\n                if \"p\" in message_json and \"o\" not in candle_1m:\n                    # Forming candle\n                    candle_1m[\"o\"] = message_json[\"p\"]\n                    candle_1m[\"h\"] = message_json[\"p\"]\n                    candle_1m[\"l\"] = message_json[\"p\"]\n                    candle_1m[\"c\"] = message_json[\"p\"]\n                    if \"q\" in message_json:\n                        candle_1m[\"v\"] = float(message_json[\"q\"])\n                elif \"p\" in message_json and \"o\" in candle_1m:\n                    # Update candle\n                    candle_1m[\"c\"] = message_json[\"p\"]\n\n                    if message_json[\"p\"] &gt; candle_1m[\"h\"]:\n                        candle_1m[\"h\"] = message_json[\"p\"]\n\n                    if message_json[\"p\"] &lt; candle_1m[\"l\"]:\n                        candle_1m[\"l\"] = message_json[\"p\"]\n\n                    # Sum volume\n                    candle_1m[\"v\"] += float(message_json[\"q\"])\n\n                # Uncomment this to see the candle forming\n                # print(candle_1m)\n\n            if self._display_candle_5m:\n                if \"t\" in message_json:\n                    candle_date = self._floor_to_nearest_interval(message_json[\"t\"], \"5 minutes\")\n\n                    if \"t\" in candle_5m and (candle_date != candle_5m[\"t\"]):\n                        print(candle_5m)\n\n                        # New candle\n                        candle_5m = {}\n\n                    candle_5m[\"t\"] = candle_date\n\n                if \"s\" in message_json:\n                    candle_5m[\"m\"] = message_json[\"s\"]\n                    candle_5m[\"g\"] = 60\n\n                if \"p\" in message_json and \"o\" not in candle_5m:\n                    # Forming candle\n                    candle_5m[\"o\"] = message_json[\"p\"]\n                    candle_5m[\"h\"] = message_json[\"p\"]\n                    candle_5m[\"l\"] = message_json[\"p\"]\n                    candle_5m[\"c\"] = message_json[\"p\"]\n                    if \"q\" in message_json:\n                        candle_5m[\"v\"] = float(message_json[\"q\"])\n                elif \"p\" in message_json and \"o\" in candle_5m:\n                    # Update candle\n                    candle_5m[\"c\"] = message_json[\"p\"]\n\n                    if message_json[\"p\"] &gt; candle_5m[\"h\"]:\n                        candle_5m[\"h\"] = message_json[\"p\"]\n\n                    if message_json[\"p\"] &lt; candle_5m[\"l\"]:\n                        candle_5m[\"l\"] = message_json[\"p\"]\n\n                    # Sum volume\n                    candle_5m[\"v\"] += float(message_json[\"q\"])\n\n                # Uncomment this to see the candle forming\n                # print(candle_5m)\n\n            if self._display_candle_1h:\n                if \"t\" in message_json:\n                    candle_date = self._floor_to_nearest_interval(message_json[\"t\"], \"1 hour\")\n\n                    if \"t\" in candle_1h and (candle_date != candle_1h[\"t\"]):\n                        print(candle_1h)\n\n                        # New candle\n                        candle_1h = {}\n\n                    candle_1h[\"t\"] = candle_date\n\n                if \"s\" in message_json:\n                    candle_1h[\"m\"] = message_json[\"s\"]\n                    candle_1h[\"g\"] = 60\n\n                if \"p\" in message_json and \"o\" not in candle_1h:\n                    # Forming candle\n                    candle_1h[\"o\"] = message_json[\"p\"]\n                    candle_1h[\"h\"] = message_json[\"p\"]\n                    candle_1h[\"l\"] = message_json[\"p\"]\n                    candle_1h[\"c\"] = message_json[\"p\"]\n                    if \"q\" in message_json:\n                        candle_1h[\"v\"] = float(message_json[\"q\"])\n                elif \"p\" in message_json and \"o\" in candle_1h:\n                    # Update candle\n                    candle_1h[\"c\"] = message_json[\"p\"]\n\n                    if message_json[\"p\"] &gt; candle_1h[\"h\"]:\n                        candle_1h[\"h\"] = message_json[\"p\"]\n\n                    if message_json[\"p\"] &lt; candle_1h[\"l\"]:\n                        candle_1h[\"l\"] = message_json[\"p\"]\n\n                    # Sum volume\n                    candle_1h[\"v\"] += float(message_json[\"q\"])\n\n                # Uncomment this to see the candle forming\n                # print(candle_1h)\n\n        # Close the WebSocket connection\n        self.ws.close()\n\n    def _keepalive(self, interval=30):\n        if (self.ws is not None) and (hasattr(self.ws, \"connected\")):\n            while self.ws.connected:\n                self.ws.ping(\"keepalive\")\n                time.sleep(interval)\n\n    def start(self):\n        self.thread = threading.Thread(target=self._collect_data)\n        self.keepalive = threading.Thread(target=self._keepalive)\n        self.thread.start()\n        self.keepalive.start()\n\n    def stop(self):\n        self.stop_event.set()\n        self.thread.join()\n        self.keepalive.join()\n\n    def get_data(self):\n        return self.data_list\n\n\nif __name__ == \"__main__\":\n    client = WebSocketClient(\n        api_key=\"OeAFFmMliFG5orCUuwAKQ8l4WWFQ67YX\",\n        endpoint=\"crypto\",\n        symbols=[\"BTC-USD\"],\n        display_stream=False,\n        display_candle_1m=True,\n        display_candle_5m=False,\n        display_candle_1h=False,\n    )\n    client.start()\n\n    try:\n        while client.running:\n            time.sleep(1)\n    except KeyboardInterrupt:\n        print(\"\\nStopping due to user request.\")\n        client.stop()\n<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>You don&#8217;t need to add all this code yourself now. You just need to access the code via the &#8220;<strong>eodhd<\/strong>&#8221; library like this.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">import time\nfrom eodhd import WebSocketClient\n\nclient = WebSocketClient(\n    api_key=\"OeAFFmMliFG5orCUuwAKQ8l4WWFQ67YX\",\n    endpoint=\"crypto\",\n    symbols=[\"BTC-USD\"],\n    display_stream=True,\n    display_candle_1m=False,\n    display_candle_5m=False,\n    display_candle_1h=False,\n)\nclient.start()\n\ntry:\n    msg = None\n    while client.running:\n        if msg is not None and client.message != msg:\n            print(client.message)\n        msg = client.message\nexcept KeyboardInterrupt:\n    print(\"\\nStopping due to user request.\")\n    client.stop()\n<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1422\" height=\"204\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-13-at-11.30.19.png\" alt=\"\" class=\"wp-image-2071\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-creating-trading-candles-from-websocket-data\">Creating Trading Candles from Websocket data<\/h2>\n\n\n\n<p>A websocket trading data stream is great if you want to create a fancy dashboard and ticker, as the data being received is real-time. It&#8217;s not all that great if you want to store the data and analyse it. <\/p>\n\n\n\n<p>In order to do this we&#8217;ll need to create trading candlesticks for a desired interval. The way it will work is as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Collect the stream data for a current candle.<\/li>\n\n\n\n<li>Store the first price in the &#8220;open&#8221;, &#8220;high&#8221;, &#8220;low&#8221;, &#8220;close&#8221; fields.<\/li>\n\n\n\n<li>Store the volume in the &#8220;volume&#8221; field.<\/li>\n\n\n\n<li>For subsequent prices, if the price is higher than the &#8220;high&#8221; then update it, if the price is lower than the &#8220;low&#8221; then update it, store the price in the &#8220;close&#8221;, and add the current volume to the &#8220;volume&#8221;.<\/li>\n\n\n\n<li>When the candle completes finalise it and start over.<\/li>\n<\/ul>\n\n\n\n<p>At the end of the candlestick period we should have a standard OHLCV candle that shows the opening price, high within the interval, low within the interval&#8221;, the last price of the interval in &#8220;close&#8221;, and a sum of all the volume in &#8220;volume&#8221;. <\/p>\n\n\n\n<p>So that&#8217;s the theory, how does it look in practice?<\/p>\n\n\n\n<p>A normal &#8220;crypto&#8221; websocket stream looks like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1422\" height=\"204\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-13-at-11.30.19.png\" alt=\"\" class=\"wp-image-2071\"\/><\/figure>\n\n\n\n<p>We are going to want to extract the market (&#8220;s&#8221;), price (&#8220;p&#8221;), volume (&#8220;q&#8221;), and the unix timestamp in milliseconds (&#8220;t&#8221;).<\/p>\n\n\n\n<p>I&#8217;ll show you how to create a 1 minute candle, the process will be the same for the others. I have actually added this code into the <a href=\"https:\/\/github.com\/EodHistoricalData\/EODHD-APIs-Python-Financial-Library\">Official EODHD Python library<\/a> code as well for reference (&#8220;<a href=\"https:\/\/github.com\/EodHistoricalData\/EODHD-APIs-Python-Financial-Library\/blob\/main\/eodhd\/websocketclient.py\">webstocketclient.py<\/a>&#8220;).<\/p>\n\n\n\n<p>We will need to calculate the floor of the closest minute to the unix timestamp. I&#8217;ve created a function that will do this.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">def _floor_to_nearest_interval(self, timestamp_ms, interval):\n    # Convert to seconds\n    timestamp_s = timestamp_ms \/\/ 1000\n\n    # Define the number of seconds for each interval\n    seconds_per_minute = 60\n    seconds_per_hour = seconds_per_minute * 60\n    seconds_per_day = seconds_per_hour * 24\n\n    # Determine the number of seconds for the given interval\n    if interval == \"1 minute\":\n        interval_seconds = seconds_per_minute\n    elif interval == \"5 minutes\":\n        interval_seconds = 5 * seconds_per_minute\n    elif interval == \"1 hour\":\n        interval_seconds = seconds_per_hour\n    else:\n        raise ValueError(f\"Unsupported interval: {interval}\")\n\n    # Floor to the nearest interval\n    floored_s = (timestamp_s \/\/ interval_seconds) * interval_seconds\n\n    # Convert back to milliseconds\n    floored_ms = floored_s * 1000\n\n    return floored_ms<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>So this <strong>_floor_to_nearest_interval(1695155147166, &#8220;1 minute&#8221;)<\/strong> will return <strong>1695155100000<\/strong>. Every time the next minute starts it will be rounded down to the floor of the current minute.<\/p>\n\n\n\n<p>We will want to start with an empty candle called &#8220;candle_1m&#8221; that we will reset every minute.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">candle_1m = {}<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>And the process to creating 1 minute candles will look like this:<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\"># Collect data until the stop event is set\nwhile not self.stop_event.is_set():\n    self.message = self.ws.recv()\n    message_json = json.loads(self.message)\n\n    if \"t\" in message_json:\n        candle_date = self._floor_to_nearest_interval(message_json[\"t\"], \"1 minute\")\n\n        if \"t\" in candle_1m and (candle_date != candle_1m[\"t\"]):\n            print(candle_1m)\n\n            # New candle\n            candle_1m = {}\n\n        candle_1m[\"t\"] = candle_date\n\n    if \"s\" in message_json:\n        candle_1m[\"m\"] = message_json[\"s\"]\n        candle_1m[\"g\"] = 60\n\n    if \"p\" in message_json and \"o\" not in candle_1m:\n        # Forming candle\n        candle_1m[\"o\"] = message_json[\"p\"]\n        candle_1m[\"h\"] = message_json[\"p\"]\n        candle_1m[\"l\"] = message_json[\"p\"]\n        candle_1m[\"c\"] = message_json[\"p\"]\n        if \"q\" in message_json:\n            candle_1m[\"v\"] = float(message_json[\"q\"])\n    elif \"p\" in message_json and \"o\" in candle_1m:\n        # Update candle\n        candle_1m[\"c\"] = message_json[\"p\"]\n\n        if message_json[\"p\"] &gt; candle_1m[\"h\"]:\n            candle_1m[\"h\"] = message_json[\"p\"]\n\n        if message_json[\"p\"] &lt; candle_1m[\"l\"]:\n            candle_1m[\"l\"] = message_json[\"p\"]\n\n        # Sum volume\n        candle_1m[\"v\"] += float(message_json[\"q\"])\n\n    # Uncomment this to see the candle forming\n    #print(candle_1m)<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>Hopefully you can see what&#8217;s happening here&#8230;<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>A new websocket entry is received as per the screenshot above.<\/li>\n\n\n\n<li>Convert the websocket string data to a JSON object.<\/li>\n\n\n\n<li>If &#8220;t&#8221; exists in the message, run our function to calculate the floor.<\/li>\n\n\n\n<li>All subsequent floored timestamps will be associated with the same candle, if it changes it assumes it is a new candle and resets the candle_1m object.<\/li>\n\n\n\n<li>Add the market to the candle as &#8220;m&#8221;.<\/li>\n\n\n\n<li>Add the granularity \/ interval to the candle as &#8220;g&#8221;.<\/li>\n\n\n\n<li>If the candle is newly created set the price &#8220;p&#8221; in &#8220;o&#8221; for open, &#8220;h&#8221; for high&#8221;, &#8220;l&#8221; for low, &#8220;c&#8221; for close, and &#8220;v&#8221; for volume.<\/li>\n\n\n\n<li>For subsequent messages that are part of the same candle, if the price is higher than the high then update it, if the price is lower than the low then update it, and add the volume to the volume.<\/li>\n<\/ol>\n\n\n\n<p>The code will only print a completed candle so there will be &lt; 60 second delay before you see anything. If you want to see the candle forming in real time, you can comment out that print at the bottom.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"2262\" height=\"90\" src=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/Screenshot-2023-09-19-at-21.39.17.png\" alt=\"\" class=\"wp-image-2258\"\/><\/figure>\n\n\n\n<p>If you want to run this code using the &#8220;<strong>eodhd<\/strong>&#8221; library you can run it like this&#8230;<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python\">import time\nimport pandas as pd\nfrom eodhd import WebSocketClient\n\npd.set_option('display.float_format', '{:.8f}'.format)\n\nclient = WebSocketClient(\n    api_key=\"OeAFFmMliFG5orCUuwAKQ8l4WWFQ67YX\",\n    endpoint=\"crypto\",\n    symbols=[\"BTC-USD\"],\n    display_stream=False,\n    display_candle_1m=True,\n    display_candle_5m=False,\n    display_candle_1h=False,\n)\nclient.start()\n\ntry:\n    while client.running:\n        time.sleep(1)\nexcept KeyboardInterrupt:\n    print(\"\\nStopping due to user request.\")\n    client.stop()<\/code><\/pre>\n\n                <\/div>\n                <div class=\"code__btns\">\n                    <button class=\"code__copy\" class=\"copy\" title=\"Copy url\">\n                        <svg class=\"code__copy__icon\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n                            <use xlink:href=\"\/img\/icons\/copy.svg#copy\"><\/use>\n                        <\/svg>\n                        <img decoding=\"async\" class=\"code__copy__approve\" alt=\"\" src=\"\/img\/approve_ico.svg\" loading=\"eager\">\n                    <\/button>\n                <\/div>\n            <\/div>\n        \n\n\n<p>The API key above is the demo API key, you should replace it with your own.<\/p>\n\n\n\n<p>I&#8217;ve set it up so you can toggle the data on and off depending on what you want to see.<\/p>\n\n\n\n<p>Give it ago, if you have any issues feel free to add an Issue in the Github repo and I&#8217;ll take a look.<\/p>\n\n\n\n<p class=\"has-text-align-center\"><a class=\"maxbutton-1 maxbutton maxbutton-subscribe-to-api external-css btn\" href=\"https:\/\/eodhd.com\/register\"><span class='mb-text'>Register &amp; Get Data<\/span><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction This method will work with any websocket data containing a timestamp and price. I&#8217;m going to demonstrate this using EODHD&#8217;s &#8220;crypto&#8221; websocket end-point. It&#8217;s important to note that websocket end-points for different asset types may be presented differently. If that is the case you will need to make the adjustments to the code. For [&hellip;]<\/p>\n","protected":false},"author":8,"featured_media":2068,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[42,48],"tags":[],"coding-language":[30],"ready-to-go-solution":[56],"qualification":[31,32],"financial-apis-category":[34,36],"financial-apis-manuals":[38,57],"class_list":["post-2067","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-stocks-data-analysis-examples","category-stocks-data-processing-examples","coding-language-python","ready-to-go-solution-eodhd-python-financial-library","qualification-experienced","qualification-guru","financial-apis-category-crypto-market-prices","financial-apis-category-stock-market-prices","financial-apis-manuals-intraday","financial-apis-manuals-real-time","has_thumb"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.9 (Yoast SEO v26.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Create Trading Candlesticks from a Websocket with Python | EODHD APIs Academy<\/title>\n<meta name=\"description\" content=\"Learn how to access WebSocket API using Python and build real-time connections with the EODHD API. Get a step-by-step guide and example code.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Create Trading Candlesticks from a Websocket with Python\" \/>\n<meta property=\"og:description\" content=\"Learn how to access WebSocket API using Python and build real-time connections with the EODHD API. Get a step-by-step guide and example code.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python\" \/>\n<meta property=\"og:site_name\" content=\"Financial Academy\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/eodhistoricaldata\" \/>\n<meta property=\"article:published_time\" content=\"2023-09-19T20:56:53+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-02-05T11:36:14+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/christopher-robin-ebbinghaus-pgSkeh0yl8o-unsplash.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"4272\" \/>\n\t<meta property=\"og:image:height\" content=\"2848\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Michael Whittle\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@EOD_data\" \/>\n<meta name=\"twitter:site\" content=\"@EOD_data\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Michael Whittle\" \/>\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\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#article\",\"isPartOf\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python\"},\"author\":{\"name\":\"Michael Whittle\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/50784c270b6267df5969514d80d510ad\"},\"headline\":\"Create Trading Candlesticks from a Websocket with Python\",\"datePublished\":\"2023-09-19T20:56:53+00:00\",\"dateModified\":\"2025-02-05T11:36:14+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python\"},\"wordCount\":1067,\"publisher\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#organization\"},\"image\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#primaryimage\"},\"thumbnailUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/christopher-robin-ebbinghaus-pgSkeh0yl8o-unsplash.jpg\",\"articleSection\":[\"Stocks Data Analysis Examples\",\"Stocks Data Processing Examples\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python\",\"name\":\"Create Trading Candlesticks from a Websocket with Python | EODHD APIs Academy\",\"isPartOf\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#primaryimage\"},\"image\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#primaryimage\"},\"thumbnailUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/christopher-robin-ebbinghaus-pgSkeh0yl8o-unsplash.jpg\",\"datePublished\":\"2023-09-19T20:56:53+00:00\",\"dateModified\":\"2025-02-05T11:36:14+00:00\",\"description\":\"Learn how to access WebSocket API using Python and build real-time connections with the EODHD API. Get a step-by-step guide and example code.\",\"breadcrumb\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#primaryimage\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/christopher-robin-ebbinghaus-pgSkeh0yl8o-unsplash.jpg\",\"contentUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/christopher-robin-ebbinghaus-pgSkeh0yl8o-unsplash.jpg\",\"width\":4272,\"height\":2848},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/eodhd.com\/financial-academy\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Create Trading Candlesticks from a Websocket with Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#website\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/\",\"name\":\"Financial APIs Academy | EODHD\",\"description\":\"Financial Stock Market Academy\",\"publisher\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/eodhd.com\/financial-academy\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#organization\",\"name\":\"EODHD (EOD Historical Data)\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/12\/EODHD-Logo.png\",\"contentUrl\":\"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/12\/EODHD-Logo.png\",\"width\":159,\"height\":82,\"caption\":\"EODHD (EOD Historical Data)\"},\"image\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/eodhistoricaldata\",\"https:\/\/x.com\/EOD_data\",\"https:\/\/www.reddit.com\/r\/EODHistoricalData\/\",\"https:\/\/eod-historical-data.medium.com\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/50784c270b6267df5969514d80d510ad\",\"name\":\"Michael Whittle\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5076af85c7ee0445454257247cad4970ae8cf5d7d4940d2b32c521f51c0a0f5a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5076af85c7ee0445454257247cad4970ae8cf5d7d4940d2b32c521f51c0a0f5a?s=96&d=mm&r=g\",\"caption\":\"Michael Whittle\"},\"description\":\"Solution architect, developer, and analyst with over 20+ years experience (TOP author on Medium).\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/author\/michaelwhittle\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Create Trading Candlesticks from a Websocket with Python | EODHD APIs Academy","description":"Learn how to access WebSocket API using Python and build real-time connections with the EODHD API. Get a step-by-step guide and example code.","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:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python","og_locale":"en_US","og_type":"article","og_title":"Create Trading Candlesticks from a Websocket with Python","og_description":"Learn how to access WebSocket API using Python and build real-time connections with the EODHD API. Get a step-by-step guide and example code.","og_url":"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python","og_site_name":"Financial Academy","article_publisher":"https:\/\/www.facebook.com\/eodhistoricaldata","article_published_time":"2023-09-19T20:56:53+00:00","article_modified_time":"2025-02-05T11:36:14+00:00","og_image":[{"width":4272,"height":2848,"url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/christopher-robin-ebbinghaus-pgSkeh0yl8o-unsplash.jpg","type":"image\/jpeg"}],"author":"Michael Whittle","twitter_card":"summary_large_image","twitter_creator":"@EOD_data","twitter_site":"@EOD_data","twitter_misc":{"Written by":"Michael Whittle","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#article","isPartOf":{"@id":"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python"},"author":{"name":"Michael Whittle","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/50784c270b6267df5969514d80d510ad"},"headline":"Create Trading Candlesticks from a Websocket with Python","datePublished":"2023-09-19T20:56:53+00:00","dateModified":"2025-02-05T11:36:14+00:00","mainEntityOfPage":{"@id":"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python"},"wordCount":1067,"publisher":{"@id":"https:\/\/eodhd.com\/financial-academy\/#organization"},"image":{"@id":"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#primaryimage"},"thumbnailUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/christopher-robin-ebbinghaus-pgSkeh0yl8o-unsplash.jpg","articleSection":["Stocks Data Analysis Examples","Stocks Data Processing Examples"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python","url":"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python","name":"Create Trading Candlesticks from a Websocket with Python | EODHD APIs Academy","isPartOf":{"@id":"https:\/\/eodhd.com\/financial-academy\/#website"},"primaryImageOfPage":{"@id":"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#primaryimage"},"image":{"@id":"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#primaryimage"},"thumbnailUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/christopher-robin-ebbinghaus-pgSkeh0yl8o-unsplash.jpg","datePublished":"2023-09-19T20:56:53+00:00","dateModified":"2025-02-05T11:36:14+00:00","description":"Learn how to access WebSocket API using Python and build real-time connections with the EODHD API. Get a step-by-step guide and example code.","breadcrumb":{"@id":"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#primaryimage","url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/christopher-robin-ebbinghaus-pgSkeh0yl8o-unsplash.jpg","contentUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/christopher-robin-ebbinghaus-pgSkeh0yl8o-unsplash.jpg","width":4272,"height":2848},{"@type":"BreadcrumbList","@id":"https:\/\/eodhd.com\/financial-academy\/stocks-data-analysis-examples\/create-trading-candlesticks-from-a-websocket-with-python#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/eodhd.com\/financial-academy\/"},{"@type":"ListItem","position":2,"name":"Create Trading Candlesticks from a Websocket with Python"}]},{"@type":"WebSite","@id":"https:\/\/eodhd.com\/financial-academy\/#website","url":"https:\/\/eodhd.com\/financial-academy\/","name":"Financial APIs Academy | EODHD","description":"Financial Stock Market Academy","publisher":{"@id":"https:\/\/eodhd.com\/financial-academy\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/eodhd.com\/financial-academy\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/eodhd.com\/financial-academy\/#organization","name":"EODHD (EOD Historical Data)","url":"https:\/\/eodhd.com\/financial-academy\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/logo\/image\/","url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/12\/EODHD-Logo.png","contentUrl":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/12\/EODHD-Logo.png","width":159,"height":82,"caption":"EODHD (EOD Historical Data)"},"image":{"@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/eodhistoricaldata","https:\/\/x.com\/EOD_data","https:\/\/www.reddit.com\/r\/EODHistoricalData\/","https:\/\/eod-historical-data.medium.com\/"]},{"@type":"Person","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/50784c270b6267df5969514d80d510ad","name":"Michael Whittle","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5076af85c7ee0445454257247cad4970ae8cf5d7d4940d2b32c521f51c0a0f5a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5076af85c7ee0445454257247cad4970ae8cf5d7d4940d2b32c521f51c0a0f5a?s=96&d=mm&r=g","caption":"Michael Whittle"},"description":"Solution architect, developer, and analyst with over 20+ years experience (TOP author on Medium).","url":"https:\/\/eodhd.com\/financial-academy\/author\/michaelwhittle"}]}},"jetpack_featured_media_url":"https:\/\/eodhd.com\/financial-academy\/wp-content\/uploads\/2023\/09\/christopher-robin-ebbinghaus-pgSkeh0yl8o-unsplash.jpg","jetpack_shortlink":"https:\/\/wp.me\/pdOdVT-xl","jetpack_sharing_enabled":true,"acf":[],"_links":{"self":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/2067","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/comments?post=2067"}],"version-history":[{"count":16,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/2067\/revisions"}],"predecessor-version":[{"id":6227,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/2067\/revisions\/6227"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/media\/2068"}],"wp:attachment":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/media?parent=2067"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/categories?post=2067"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/tags?post=2067"},{"taxonomy":"coding-language","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/coding-language?post=2067"},{"taxonomy":"ready-to-go-solution","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/ready-to-go-solution?post=2067"},{"taxonomy":"qualification","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/qualification?post=2067"},{"taxonomy":"financial-apis-category","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/financial-apis-category?post=2067"},{"taxonomy":"financial-apis-manuals","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/financial-apis-manuals?post=2067"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}