{"id":4197,"date":"2023-05-03T16:36:32","date_gmt":"2023-05-03T23:36:32","guid":{"rendered":"https:\/\/jeremywhittaker.com\/?p=4197"},"modified":"2023-05-04T12:57:06","modified_gmt":"2023-05-04T19:57:06","slug":"a-python-based-alpaca-template-to-process-real-time-market-data","status":"publish","type":"post","link":"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/","title":{"rendered":"A Python Based Alpaca Template to Process Real-time Market Data"},"content":{"rendered":"\n<p>The world of finance and trading has seen a massive surge in the use of technology and data. With the increasing availability of APIs and data streams, it has become essential for traders and developers to harness the power of real-time information to make better-informed decisions. Alpaca, a popular commission-free trading API, is one such service that enables developers to access real-time market data and automate their trading strategies.<\/p>\n\n\n\n<p>However, getting started with Alpaca&#8217;s API and handling WebSocket streams for quotes, trades, and bars can be a challenging task, especially for those who are new to the domain. To help you overcome this hurdle, I have put together a Python template that simplifies the process and serves as a starting point for your custom trading projects. Here is a sample of the outputs. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Quotes:<br><\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"381\" height=\"215\" data-src=\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png\" alt=\"\" class=\"wp-image-4203 lazyload\" data-srcset=\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png 381w, https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4-300x169.png 300w\" data-sizes=\"(max-width: 381px) 100vw, 381px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 381px; --smush-placeholder-aspect-ratio: 381\/215;\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Trades:<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"455\" height=\"173\" data-src=\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-6.png\" alt=\"\" class=\"wp-image-4206 lazyload\" data-srcset=\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-6.png 455w, https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-6-300x114.png 300w\" data-sizes=\"(max-width: 455px) 100vw, 455px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 455px; --smush-placeholder-aspect-ratio: 455\/173;\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Bars:<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"284\" height=\"204\" data-src=\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-3.png\" alt=\"\" class=\"wp-image-4200 lazyload\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 284px; --smush-placeholder-aspect-ratio: 284\/204;\" \/><\/figure>\n\n\n\n<p>In this blog post, I will walk you through the key components of this template, and explain how you can use it to access real-time data from Alpaca&#8217;s API and modify it according to your preferences.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Organizing the Codebase<\/strong><\/li>\n<\/ol>\n\n\n\n<p>The first step towards building a clean and maintainable trading application is to organize your codebase into modular components. In our template, we have separated the code into different modules:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>config.py<\/code>: Contains the API key and secret key for Alpaca authentication.<\/li>\n\n\n\n<li><code>constants.py<\/code>: Stores dictionaries for exchange codes, trade conditions, and quote conditions.<\/li>\n\n\n\n<li><code>subscriptions.py<\/code>: Defines functions for subscribing and unsubscribing from trades, quotes, and bars.<\/li>\n\n\n\n<li><code>message_processing.py<\/code>: Contains a function for processing incoming messages from the WebSocket stream.<\/li>\n<\/ul>\n\n\n\n<p>By organizing the code in this manner, we can easily manage and extend our trading application as needed.<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"2\">\n<li><strong>Establishing a WebSocket Connection<\/strong><\/li>\n<\/ol>\n\n\n\n<p>Our template uses the <code>websocket<\/code> library to establish a connection with Alpaca&#8217;s WebSocket stream. This is done in the <code>create_ws_connection<\/code> function, which takes the list of symbols and the data source (either &#8216;sip&#8217; or &#8216;iex&#8217;) as input, and returns a WebSocketApp object. This object is then used to authenticate, subscribe, and handle incoming messages.<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\">\n<li><strong>Authenticating with Alpaca&#8217;s API<\/strong><\/li>\n<\/ol>\n\n\n\n<p>Before you can access real-time market data from Alpaca, you need to authenticate your WebSocket connection. The <code>authenticate<\/code> function sends an authentication message to the WebSocket, which includes your API key and secret key. Once authenticated, you can subscribe to various data streams.<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"4\">\n<li><strong>Subscribing to Real-time Data<\/strong><\/li>\n<\/ol>\n\n\n\n<p>Our template provides functions for subscribing to trades, quotes, and bars: <code>subscribe_to_trades<\/code>, <code>subscribe_to_quotes<\/code>, and <code>subscribe_to_bars<\/code>. These functions send subscription messages to the WebSocket, specifying the symbols you want to receive updates for.<\/p>\n\n\n\n<p>You can also unsubscribe from any data stream using the corresponding <code>unsubscribe_*<\/code> functions, such as <code>unsubscribe_trade_updates<\/code>.<\/p>\n\n\n\n<ol class=\"wp-block-list\" start=\"5\">\n<li><strong>Processing Incoming Messages<\/strong><\/li>\n<\/ol>\n\n\n\n<p>The <code>on_message<\/code> function handles incoming messages from the WebSocket stream. It parses the message and delegates the processing to the <code>process_message<\/code> function, which is defined in the <code>message_processing.py<\/code> module. This function takes care of processing trade, quote, and bar messages, as well as handling any errors or subscription updates.<\/p>\n\n\n\n<p>This Python template serves as a solid foundation for building custom trading applications using Alpaca&#8217;s API. It simplifies the process of connecting to the WebSocket, authenticating, subscribing to data streams, and processing incoming messages. By using this template as a starting point, you can focus on implementing your trading strategies and refining your application according to your needs.<\/p>\n\n\n\n<p>Feel free to modify and extend the code as required, and embark on your journey of harnessing the power of real-time market data to create sophisticated trading algorithms and applications.<\/p>\n\n\n\n<p>In the future, you may consider incorporating features such as order management, portfolio tracking, and risk management to further enhance your trading application. Additionally, you can explore integrating other data sources and APIs to complement Alpaca&#8217;s data and provide a more comprehensive view of the market.<\/p>\n\n\n\n<p>By leveraging this Alpaca Subscribe Template, you can quickly dive into the world of algorithmic trading and capitalize on the opportunities provided by real-time market data. So go ahead, experiment with the code, and unleash the potential of data-driven trading strategies for better decision-making and profitability. Happy coding!<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>main.py<\/strong><\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>import websocket\nimport json\nimport threading\nimport time\nimport os\nfrom colorama import Fore, Style, init\n\nfrom config import APCA_API_KEY_ID, APCA_API_SECRET_KEY\nfrom constants import exchange_codes, trade_conditions_cts, cqs_quote_conditions, uqdf_quote_conditions\nfrom subscriptions import subscribe_to_trades, subscribe_to_quotes, subscribe_to_bars,\\\n                           unsubscribe_trade_updates, unsubscribe_quote_updates, unsubscribe_bar_updates\nfrom message_processing import process_message\n\n\n\n\n# Function to handle incoming messages\ndef on_message(ws, message):\n    # print(\"Message received: \" + message)\n    messages = json.loads(message)\n    for msg in messages:\n        process_message(msg)\n\n# Function to authenticate\ndef authenticate(ws):\n    auth_data = {\n        \"action\": \"auth\",\n        \"key\": APCA_API_KEY_ID,\n        \"secret\": APCA_API_SECRET_KEY\n    }\n    ws.send(json.dumps(auth_data))\n\n# Function to subscribe to trades\n\ndef create_ws_connection(symbols, source='sip'):\n    base_url = f'wss:\/\/stream.data.alpaca.markets\/v2\/{source}'\n\n    ws = websocket.WebSocketApp(\n        base_url,\n        on_message=on_message\n    )\n\n    # Authenticate and subscribe when the connection is open\n    ws.on_open = lambda ws: authenticate(ws)\n\n    return ws\n\nif __name__ == \"__main__\":\n    # List of symbols to subscribe\n    symbols = &#91;\"AAPL\", \"MSFT\", \"GOOG\", \"FB\", \"AMZN\", \"TSLA\", \"NFLX\", \"NVDA\", \"AMD\", \"TWTR\", \"SNAP\"]\n\n    # Source: 'sip' or 'iex'\n    source = 'sip'\n\n    # Create a connection to the WebSocket\n    ws = create_ws_connection(symbols, source=source)\n\n    # Start the WebSocket connection in a new thread\n    ws_thread = threading.Thread(target=ws.run_forever)\n    ws_thread.start()\n    time.sleep(5)\n\n    # Let the WebSocket run for a while to receive updates\n\n    # Subscribe to trades\n    print('Subscribing to trades')\n    subscribe_to_trades(ws, symbols)\n    # unsubscribe_trade_updates(ws, symbols)\n\n    # Subscribe to quotes\n    print('Subscribing to quotes')\n    subscribe_to_quotes(ws, symbols)\n    # unsubscribe_quote_updates(ws, symbols)\n\n    # Subscribe to bars\n    print('Subscribing to bars')\n    # subscribe_to_bars(ws, symbols)\n    # time.sleep(5)\n    # unsubscribe_bar_updates(ws, symbols)<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">message_processing.py<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>from constants import exchange_codes, trade_conditions_cts, trade_conditions_utdf, cqs_quote_conditions, uqdf_quote_conditions\n\n\ndef process_message(msg):\n    msg_type = msg&#91;'T']\n\n    if msg_type == 't':  # Trade\n        print(\"Message type:\", msg_type)\n\n        symbol = msg&#91;'S']\n        trade_id = msg&#91;'i']\n        exchange_code = msg&#91;'x']\n        exchange_desc = exchange_codes.get(exchange_code, \"Unknown\")\n        trade_price = msg&#91;'p']\n        trade_size = msg&#91;'s']\n        trade_condition = msg&#91;'c']\n        conditions_desc = &#91;trade_conditions_cts.get(c, \"Unknown\") for c in trade_condition]\n        timestamp = msg&#91;'t']\n        tape = msg&#91;'z']\n        if exchange_code in &#91;\"A\", \"N\", \"P\"]:\n            plan = \"CTA\"\n            trade_conditions_desc = &#91;trade_conditions_cts.get(cond, \"Unknown\") for cond in trade_condition]\n        elif exchange_code in &#91;\"B\", \"Q\", \"S\", \"T\", \"X\"]:\n            plan = \"UTP\"\n            trade_conditions_desc = &#91;trade_conditions_utdf.get(cond, \"Unknown\") for cond in trade_condition]\n        elif exchange_code in &#91;\"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"O\", \"R\", \"U\", \"V\", \"W\", \"Y\"]:\n            plan = \"Unknown\"\n            trade_conditions_desc = &#91;trade_conditions_cts.get(cond, \"Unknown\") for cond in trade_condition]\n        else:\n            plan = \"Unknown\"\n            trade_conditions_desc = &#91;trade_conditions_cts.get(cond, \"Unknown\") for cond in trade_condition]\n\n\n        print(\"Trade:\")\n        print(f\"Symbol: {symbol}\")\n        print(f\"Trade ID: {trade_id}\")\n        print(f\"Exchange Code: {exchange_code} ({exchange_desc})\")\n        print(f\"Trade Price: {trade_price}\")\n        print(f\"Trade Size: {trade_size}\")\n        print(f\"Trade Condition: {trade_condition} ({', '.join(conditions_desc)})\")\n        print(f\"Timestamp: {timestamp}\")\n        print(f\"Tape: {tape}\")\n        print(\"-------\")\n\n    elif msg_type == 'q':  # Quote\n        symbol = msg&#91;'S']\n        ask_exchange_code = msg&#91;'ax']\n        ask_exchange_desc = exchange_codes.get(ask_exchange_code, \"Unknown\")\n        ask_price = msg&#91;'ap']\n        ask_size = msg&#91;'as']\n        bid_exchange_code = msg&#91;'bx']\n        bid_exchange_desc = exchange_codes.get(bid_exchange_code, \"Unknown\")\n        bid_price = msg&#91;'bp']\n        bid_size = msg&#91;'bs']\n        quote_condition = msg&#91;'c']\n        timestamp = msg&#91;'t']\n        tape = msg&#91;'z']\n\n        conditions = msg.get(\"c\", &#91;])\n        decoded_conditions = &#91;]\n        for condition_code in conditions:\n            if condition_code in cqs_quote_conditions:\n                decoded_conditions.append(cqs_quote_conditions&#91;condition_code])\n            elif condition_code in uqdf_quote_conditions:\n                decoded_conditions.append(uqdf_quote_conditions&#91;condition_code])\n            else:\n                decoded_conditions.append(f\"Unknown Condition: {condition_code}\")\n\n\n\n        print(\"Quote:\")\n        print(f\"Symbol: {symbol}\")\n        print(f\"Ask Exchange Code: {ask_exchange_code} ({ask_exchange_desc})\")\n        print(f\"Ask Price: {ask_price}\")\n        print(f\"Ask Size: {ask_size}\")\n        print(f\"Bid Exchange Code: {bid_exchange_code} ({bid_exchange_desc})\")\n        print(f\"Bid Price: {bid_price}\")\n        print(f\"Bid Size: {bid_size}\")\n        print(f\"Quote Condition: {quote_condition}\")\n        print(f\"Quote Condition: {decoded_conditions}\")\n        print(f\"Timestamp: {timestamp}\")\n        print(f\"Tape: {tape}\")\n        print(\"-------\")\n\n    elif msg_type in &#91;'b', 'd', 'u']:  # Bar\n        symbol = msg&#91;'S']\n        open_price = msg&#91;'o']\n        high_price = msg&#91;'h']\n        low_price = msg&#91;'l']\n        close_price = msg&#91;'c']\n        volume = msg&#91;'v']\n        timestamp = msg&#91;'t']\n\n        print(\"Bar:\")\n        print(f\"Symbol: {symbol}\")\n        print(f\"Open Price: {open_price}\")\n        print(f\"High Price: {high_price}\")\n        print(f\"Low Price: {low_price}\")\n        print(f\"Close Price: {close_price}\")\n        print(f\"Volume: {volume}\")\n        print(f\"Timestamp: {timestamp}\")\n        print(\"-------\")\n\n\n    elif msg_type == 'error':  # Error\n        code = msg&#91;'code']\n        error_msg = msg&#91;'msg']\n        print(Fore.RED + f\"Error Code: {code}\")\n        print(f\"Error Message: {error_msg}\")\n        print(Style.RESET_ALL + \"-------\")\n\n    elif msg&#91;'T'] == 'success':\n        code = msg&#91;'code']\n        error_msg = msg&#91;'msg']\n        print(Fore.GREEN + f\"Error Code: {code}\")\n        print(f\"Error Message: {error_msg}\")\n        print(Style.RESET_ALL + \"-------\")\n\n\n    elif msg_type == \"subscription\":\n        print(\"Subscription:\")\n        for item, symbols in msg.items():\n            if item != 'T' and symbols:\n                print(f\"{item}: {', '.join(symbols)}\")\n        print(\"-------\")\n\n    else:\n        print(f\"Unknown message type: {msg_type}\")\n\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">subscriptions.py<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>import json\n\ndef subscribe_to_trades(ws, symbols):\n    sub_data = {\n        \"action\": \"subscribe\",\n        \"trades\": symbols\n    }\n    ws.send(json.dumps(sub_data))\n\n# Function to subscribe to quotes\ndef subscribe_to_quotes(ws, symbols):\n    sub_data = {\n        \"action\": \"subscribe\",\n        \"quotes\": symbols\n    }\n    ws.send(json.dumps(sub_data))\n\n# Function to subscribe to bars\ndef subscribe_to_bars(ws, symbols):\n    sub_data = {\n        \"action\": \"subscribe\",\n        \"bars\": symbols\n    }\n    ws.send(json.dumps(sub_data))\n\n\ndef unsubscribe_trade_updates(ws, symbols):\n    sub_data = {\n        \"action\": \"unsubscribe\",\n        \"trades\": symbols\n    }\n    ws.send(json.dumps(sub_data))\n\n\ndef unsubscribe_quote_updates(ws, symbols):\n    sub_data = {\n        \"action\": \"unsubscribe\",\n        \"quotes\": symbols\n    }\n    ws.send(json.dumps(sub_data))\n\n\ndef unsubscribe_bar_updates(ws, symbols):\n    sub_data = {\n        \"action\": \"unsubscribe\",\n        \"bars\": symbols\n    }\n    ws.send(json.dumps(sub_data))\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">constants.py<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>exchange_codes = {\n    \"A\": \"NYSE American (AMEX)\",\n    \"B\": \"NASDAQ OMX BX\",\n    \"C\": \"National Stock Exchange\",\n    \"D\": \"FINRA ADF\",\n    \"E\": \"Market Independent\",\n    \"H\": \"MIAX\",\n    \"I\": \"International Securities Exchange\",\n    \"J\": \"Cboe EDGA\",\n    \"K\": \"Cboe EDGX\",\n    \"L\": \"Long Term Stock Exchange\",\n    \"M\": \"Chicago Stock Exchange\",\n    \"N\": \"New York Stock Exchange\",\n    \"P\": \"NYSE Arca\",\n    \"Q\": \"NASDAQ OMX\",\n    \"S\": \"NASDAQ Small Cap\",\n    \"T\": \"NASDAQ Int\",\n    \"U\": \"Members Exchange\",\n    \"V\": \"IEX\",\n    \"W\": \"CBOE\",\n    \"X\": \"NASDAQ OMX PSX\",\n    \"Y\": \"Cboe BYX\",\n    \"Z\": \"Cboe BZX\",\n}\n\ntrade_conditions_cts = {\n    \" \": \"Regular Sale\",\n    \"B\": \"Average Price Trade\",\n    \"C\": \"Cash Trade (Same Day Clearing)\",\n    \"E\": \"Automatic Execution\",\n    \"F\": \"Inter-market Sweep Order\",\n    \"H\": \"Price Variation Trade\",\n    \"I\": \"Odd Lot Trade\",\n    \"K\": \"Rule 127 (NYSE only) or Rule 155 (NYSE MKT only)\",\n    \"L\": \"Sold Last (Late Reporting)\",\n    \"M\": \"Market Center Official Close\",\n    \"N\": \"Next Day Trade (Next Day Clearing)\",\n    \"O\": \"Market Center Opening Trade\",\n    \"P\": \"Prior Reference Price\",\n    \"Q\": \"Market Center Official Open\",\n    \"R\": \"Seller\",\n    \"T\": \"Extended Hours Trade\",\n    \"U\": \"Extended Hours Sold (Out Of Sequence)\",\n    \"V\": \"Contingent Trade\",\n    \"X\": \"Cross Trade\",\n    \"Z\": \"Sold (Out Of Sequence)\",\n    \"4\": \"Derivatively Priced\",\n    \"5\": \"Market Center Reopening Trade\",\n    \"6\": \"Market Center Closing Trade\",\n    \"7\": \"Qualified Contingent Trade\",\n    \"8\": \"Reserved\",\n    \"9\": \"Corrected Consolidated Close Price as per Listing Market\",\n}\n\n# Quote condition dictionaries for CQS and UQDF plans\ncqs_quote_conditions = {\n    \"A\": \"Slow Quote Offer Side\",\n    \"B\": \"Slow Quote Bid Side\",\n    \"E\": \"Slow Quote LRP Bid Side\",\n    \"F\": \"Slow Quote LRP Offer Side\",\n    \"H\": \"Slow Quote Bid And Offer Side\",\n    \"O\": \"Opening Quote\",\n    \"R\": \"Regular Market Maker Open\",\n    \"W\": \"Slow Quote Set Slow List\",\n    \"C\": \"Closing Quote\",\n    \"L\": \"Market Maker Quotes Closed\",\n    \"U\": \"Slow Quote LRP Bid And Offer\",\n    \"N\": \"Non Firm Quote\",\n    \"4\": \"On Demand Intra Day Auction\",\n}\n\nuqdf_quote_conditions = {\n    \"A\": \"Manual Ask Automated Bid\",\n    \"B\": \"Manual Bid Automated Ask\",\n    \"F\": \"Fast Trading\",\n    \"H\": \"Manual Bid And Ask\",\n    \"I\": \"Order Imbalance\",\n    \"L\": \"Closed Quote\",\n    \"N\": \"Non Firm Quote\",\n    \"O\": \"Opening Quote Automated\",\n    \"R\": \"Regular Two Sided Open\",\n    \"U\": \"Manual Bid And Ask Non Firm\",\n    \"Y\": \"No Offer No Bid One Sided Open\",\n    \"X\": \"Order Influx\",\n    \"Z\": \"No Open No Resume\",\n    \"4\": \"On Demand Intra Day Auction\",\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">constants.py<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>exchange_codes = {\n    \"A\": \"NYSE American (AMEX)\",\n    \"B\": \"NASDAQ OMX BX\",\n    \"C\": \"National Stock Exchange\",\n    \"D\": \"FINRA ADF\",\n    \"E\": \"Market Independent\",\n    \"H\": \"MIAX\",\n    \"I\": \"International Securities Exchange\",\n    \"J\": \"Cboe EDGA\",\n    \"K\": \"Cboe EDGX\",\n    \"L\": \"Long Term Stock Exchange\",\n    \"M\": \"Chicago Stock Exchange\",\n    \"N\": \"New York Stock Exchange\",\n    \"P\": \"NYSE Arca\",\n    \"Q\": \"NASDAQ OMX\",\n    \"S\": \"NASDAQ Small Cap\",\n    \"T\": \"NASDAQ Int\",\n    \"U\": \"Members Exchange\",\n    \"V\": \"IEX\",\n    \"W\": \"CBOE\",\n    \"X\": \"NASDAQ OMX PSX\",\n    \"Y\": \"Cboe BYX\",\n    \"Z\": \"Cboe BZX\",\n}\n\ntrade_conditions_cts = {\n    \"@\": \"\",\n    \" \": \"Regular Sale\",\n    \"B\": \"Average Price Trade\",\n    \"C\": \"Cash Trade (Same Day Clearing)\",\n    \"E\": \"Automatic Execution\",\n    \"F\": \"Inter-market Sweep Order\",\n    \"H\": \"Price Variation Trade\",\n    \"I\": \"Odd Lot Trade\",\n    \"K\": \"Rule 127 (NYSE only) or Rule 155 (NYSE MKT only)\",\n    \"L\": \"Sold Last (Late Reporting)\",\n    \"M\": \"Market Center Official Close\",\n    \"N\": \"Next Day Trade (Next Day Clearing)\",\n    \"O\": \"Market Center Opening Trade\",\n    \"P\": \"Prior Reference Price\",\n    \"Q\": \"Market Center Official Open\",\n    \"R\": \"Seller\",\n    \"T\": \"Extended Hours Trade\",\n    \"U\": \"Extended Hours Sold (Out Of Sequence)\",\n    \"V\": \"Contingent Trade\",\n    \"X\": \"Cross Trade\",\n    \"Z\": \"Sold (Out Of Sequence)\",\n    \"4\": \"Derivatively Priced\",\n    \"5\": \"Market Center Reopening Trade\",\n    \"6\": \"Market Center Closing Trade\",\n    \"7\": \"Qualified Contingent Trade\",\n    \"8\": \"Reserved\",\n    \"9\": \"Corrected Consolidated Close Price as per Listing Market\",\n}\n\ntrade_conditions_utdf = {\n    \"@\": \"Regular Sale\",\n    \"A\": \"Acquisition\",\n    \"B\": \"Bunched Trade\",\n    \"C\": \"Cash Sale\",\n    \"D\": \"Distribution\",\n    \"E\": \"Placeholder\",\n    \"F\": \"Intermarket Sweep\",\n    \"G\": \"Bunched Sold Trade\",\n    \"H\": \"Price Variation Trade\",\n    \"I\": \"Odd Lot Trade\",\n    \"K\": \"Rule 155 Trade (AMEX)\",\n    \"L\": \"Sold Last\",\n    \"M\": \"Market Center Official Close\",\n    \"N\": \"Next Day\",\n    \"O\": \"Opening Prints\",\n    \"P\": \"Prior Reference Price\",\n    \"Q\": \"Market Center Official Open\",\n    \"R\": \"Seller\",\n    \"S\": \"Split Trade\",\n    \"T\": \"Form T\",\n    \"U\": \"Extended trading hours (Sold Out of Sequence)\",\n    \"V\": \"Contingent Trade\",\n    \"W\": \"Average Price Trade\",\n    \"X\": \"Cross Trade\",\n    \"Y\": \"Yellow Flag Regular Trade\",\n    \"Z\": \"Sold (out of sequence)\",\n    \"1\": \"Stopped Stock (Regular Trade)\",\n    \"4\": \"Derivatively priced\",\n    \"5\": \"Re-Opening Prints\",\n    \"6\": \"Closing Prints\",\n    \"7\": \"Qualified Contingent Trade (QCT)\",\n    \"8\": \"Placeholder For 611 Exempt\",\n    \"9\": \"Corrected Consolidated Close (per listing market)\",\n}\n\nquote_conditions_cqs = {\n    \"A\": \"Slow Quote Offer Side\",\n    \"B\": \"Slow Quote Bid Side\",\n    \"E\": \"Slow Quote LRP Bid Side\",\n    \"F\": \"Slow Quote LRP Offer Side\",\n    \"H\": \"Slow Quote Bid And Offer Side\",\n    \"O\": \"Opening Quote\",\n    \"R\": \"Regular Market Maker Open\",\n    \"W\": \"Slow Quote Set Slow List\",\n    \"C\": \"Closing Quote\",\n    \"L\": \"Market Maker Quotes Closed\",\n    \"U\": \"Slow Quote LRP Bid And Offer\",\n    \"N\": \"Non Firm Quote\",\n    \"4\": \"On Demand Intra Day Auction\",\n}\n\n# Quote condition dictionaries for CQS and UQDF plans\ncqs_quote_conditions = {\n    \"A\": \"Slow Quote Offer Side\",\n    \"B\": \"Slow Quote Bid Side\",\n    \"E\": \"Slow Quote LRP Bid Side\",\n    \"F\": \"Slow Quote LRP Offer Side\",\n    \"H\": \"Slow Quote Bid And Offer Side\",\n    \"O\": \"Opening Quote\",\n    \"R\": \"Regular Market Maker Open\",\n    \"W\": \"Slow Quote Set Slow List\",\n    \"C\": \"Closing Quote\",\n    \"L\": \"Market Maker Quotes Closed\",\n    \"U\": \"Slow Quote LRP Bid And Offer\",\n    \"N\": \"Non Firm Quote\",\n    \"4\": \"On Demand Intra Day Auction\",\n}\n\nuqdf_quote_conditions = {\n    \"A\": \"Manual Ask Automated Bid\",\n    \"B\": \"Manual Bid Automated Ask\",\n    \"F\": \"Fast Trading\",\n    \"H\": \"Manual Bid And Ask\",\n    \"I\": \"Order Imbalance\",\n    \"L\": \"Closed Quote\",\n    \"N\": \"Non Firm Quote\",\n    \"O\": \"Opening Quote Automated\",\n    \"R\": \"Regular Two Sided Open\",\n    \"U\": \"Manual Bid And Ask Non Firm\",\n    \"Y\": \"No Offer No Bid One Sided Open\",\n    \"X\": \"Order Influx\",\n    \"Z\": \"No Open No Resume\",\n    \"4\": \"On Demand Intra Day Auction\",\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">config.py<\/h2>\n\n\n\n<h2 class=\"wp-block-heading\"><\/h2>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import os\nimport sys\n\nparent_dir = os.path.abspath(os.path.join(os.getcwd(), '..'))\ndata_dir = os.path.join(parent_dir, 'data\/')\nsys.path.append(data_dir)\n\nimport keys\n\n# LIVE_BASE_URL, APCA_API_KEY_ID, APCA_API_SECRET_KEY = keys.get_live_keys()\nLIVE_BASE_URL, APCA_API_KEY_ID, APCA_API_SECRET_KEY = YOUR_URL, YOUR_API_KEY, YOUR_API_SECRET<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>The world of finance and trading has seen a massive surge in the use of technology and data. With the increasing availability of APIs and data streams, it&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4197","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>A Python Based Alpaca Template to Process Real-time Market Data - Jeremy Whittaker<\/title>\n<meta name=\"robots\" content=\"noindex, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A Python Based Alpaca Template to Process Real-time Market Data\" \/>\n<meta property=\"og:description\" content=\"The world of finance and trading has seen a massive surge in the use of technology and data. With the increasing availability of APIs and data streams, it has become essential for traders and developers to harness the power of real-time information to make better-informed decisions. Alpaca, a popular commission-free trading API, is one such service that enables developers to access real-time market data and automate their trading strategies.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/\" \/>\n<meta property=\"og:site_name\" content=\"Jeremy Whittaker\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/WhittakerJeremy\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/WhittakerJeremy\" \/>\n<meta property=\"article:published_time\" content=\"2023-05-03T23:36:32+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-05-04T19:57:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png\" \/>\n\t<meta property=\"og:image:width\" content=\"381\" \/>\n\t<meta property=\"og:image:height\" content=\"215\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"JeremyWhittaker\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"A Python Based Alpaca Template to Process Real-time Market Data\" \/>\n<meta name=\"twitter:description\" content=\"The world of finance and trading has seen a massive surge in the use of technology and data. With the increasing availability of APIs and data streams, it has become essential for traders and developers to harness the power of real-time information to make better-informed decisions. Alpaca, a popular commission-free trading API, is one such service that enables developers to access real-time market data and automate their trading strategies.\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"JeremyWhittaker\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/\"},\"author\":{\"name\":\"JeremyWhittaker\",\"@id\":\"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c\"},\"headline\":\"A Python Based Alpaca Template to Process Real-time Market Data\",\"datePublished\":\"2023-05-03T23:36:32+00:00\",\"dateModified\":\"2023-05-04T19:57:06+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/\"},\"wordCount\":674,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c\"},\"image\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/\",\"url\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/\",\"name\":\"A Python Based Alpaca Template to Process Real-time Market Data - Jeremy Whittaker\",\"isPartOf\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png\",\"datePublished\":\"2023-05-03T23:36:32+00:00\",\"dateModified\":\"2023-05-04T19:57:06+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#primaryimage\",\"url\":\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png\",\"contentUrl\":\"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png\",\"width\":381,\"height\":215},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/new.jeremywhittaker.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A Python Based Alpaca Template to Process Real-time Market Data\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/new.jeremywhittaker.com\/#website\",\"url\":\"https:\/\/new.jeremywhittaker.com\/\",\"name\":\"Jeremy Whittaker\",\"description\":\"Research, software, markets, housing, and energy\",\"publisher\":{\"@id\":\"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/new.jeremywhittaker.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c\",\"name\":\"JeremyWhittaker\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g\",\"caption\":\"JeremyWhittaker\"},\"logo\":{\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g\"},\"sameAs\":[\"http:\/\/www.jeremywhittaker.com\",\"https:\/\/www.facebook.com\/WhittakerJeremy\",\"https:\/\/www.linkedin.com\/in\/jeremywhittaker\/\"],\"url\":\"https:\/\/new.jeremywhittaker.com\/index.php\/author\/jeremywhittaker\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"A Python Based Alpaca Template to Process Real-time Market Data - Jeremy Whittaker","robots":{"index":"noindex","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"og_locale":"en_US","og_type":"article","og_title":"A Python Based Alpaca Template to Process Real-time Market Data","og_description":"The world of finance and trading has seen a massive surge in the use of technology and data. With the increasing availability of APIs and data streams, it has become essential for traders and developers to harness the power of real-time information to make better-informed decisions. Alpaca, a popular commission-free trading API, is one such service that enables developers to access real-time market data and automate their trading strategies.","og_url":"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/","og_site_name":"Jeremy Whittaker","article_publisher":"https:\/\/www.facebook.com\/WhittakerJeremy","article_author":"https:\/\/www.facebook.com\/WhittakerJeremy","article_published_time":"2023-05-03T23:36:32+00:00","article_modified_time":"2023-05-04T19:57:06+00:00","og_image":[{"width":381,"height":215,"url":"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png","type":"image\/png"}],"author":"JeremyWhittaker","twitter_card":"summary_large_image","twitter_title":"A Python Based Alpaca Template to Process Real-time Market Data","twitter_description":"The world of finance and trading has seen a massive surge in the use of technology and data. With the increasing availability of APIs and data streams, it has become essential for traders and developers to harness the power of real-time information to make better-informed decisions. Alpaca, a popular commission-free trading API, is one such service that enables developers to access real-time market data and automate their trading strategies.","twitter_image":"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png","twitter_misc":{"Written by":"JeremyWhittaker","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#article","isPartOf":{"@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/"},"author":{"name":"JeremyWhittaker","@id":"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c"},"headline":"A Python Based Alpaca Template to Process Real-time Market Data","datePublished":"2023-05-03T23:36:32+00:00","dateModified":"2023-05-04T19:57:06+00:00","mainEntityOfPage":{"@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/"},"wordCount":674,"commentCount":0,"publisher":{"@id":"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c"},"image":{"@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#primaryimage"},"thumbnailUrl":"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/","url":"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/","name":"A Python Based Alpaca Template to Process Real-time Market Data - Jeremy Whittaker","isPartOf":{"@id":"https:\/\/new.jeremywhittaker.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#primaryimage"},"image":{"@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#primaryimage"},"thumbnailUrl":"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png","datePublished":"2023-05-03T23:36:32+00:00","dateModified":"2023-05-04T19:57:06+00:00","breadcrumb":{"@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#primaryimage","url":"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png","contentUrl":"https:\/\/new.jeremywhittaker.com\/wp-content\/uploads\/2023\/05\/image-4.png","width":381,"height":215},{"@type":"BreadcrumbList","@id":"https:\/\/new.jeremywhittaker.com\/index.php\/2023\/05\/03\/a-python-based-alpaca-template-to-process-real-time-market-data\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/new.jeremywhittaker.com\/"},{"@type":"ListItem","position":2,"name":"A Python Based Alpaca Template to Process Real-time Market Data"}]},{"@type":"WebSite","@id":"https:\/\/new.jeremywhittaker.com\/#website","url":"https:\/\/new.jeremywhittaker.com\/","name":"Jeremy Whittaker","description":"Research, software, markets, housing, and energy","publisher":{"@id":"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/new.jeremywhittaker.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/new.jeremywhittaker.com\/#\/schema\/person\/ed0edfdefb3e180693efef453372980c","name":"JeremyWhittaker","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g","caption":"JeremyWhittaker"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/c8ac20e6dfa86b5f27ce9bffee4851099770cbea5ae7338a274865bfbc8c0218?s=96&d=retro&r=g"},"sameAs":["http:\/\/www.jeremywhittaker.com","https:\/\/www.facebook.com\/WhittakerJeremy","https:\/\/www.linkedin.com\/in\/jeremywhittaker\/"],"url":"https:\/\/new.jeremywhittaker.com\/index.php\/author\/jeremywhittaker\/"}]}},"_links":{"self":[{"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/posts\/4197","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/comments?post=4197"}],"version-history":[{"count":0,"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/posts\/4197\/revisions"}],"wp:attachment":[{"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/media?parent=4197"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/categories?post=4197"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/new.jeremywhittaker.com\/index.php\/wp-json\/wp\/v2\/tags?post=4197"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}