<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Volker Bohn</title>
    <description>The latest articles on DEV Community by Volker Bohn (@darwintiq).</description>
    <link>https://dev.to/darwintiq</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3827447%2Fb227fe60-a95d-4f5c-b217-cd96afd964b8.png</url>
      <title>DEV Community: Volker Bohn</title>
      <link>https://dev.to/darwintiq</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/darwintiq"/>
    <language>en</language>
    <item>
      <title>Building AI Market Briefings in Python with the Charlie API</title>
      <dc:creator>Volker Bohn</dc:creator>
      <pubDate>Wed, 20 May 2026 15:32:25 +0000</pubDate>
      <link>https://dev.to/darwintiq/building-ai-market-briefings-in-python-with-the-charlie-api-4cpp</link>
      <guid>https://dev.to/darwintiq/building-ai-market-briefings-in-python-with-the-charlie-api-4cpp</guid>
      <description>&lt;p&gt;Market preparation can be repetitive.&lt;/p&gt;

&lt;p&gt;Before looking at charts, many traders and analysts ask themselves the same questions every day:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the current market tone?&lt;/li&gt;
&lt;li&gt;Is the market trending, ranging, or noisy?&lt;/li&gt;
&lt;li&gt;Are there any relevant signals or risk factors?&lt;/li&gt;
&lt;li&gt;What should I pay attention to before making a decision?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted to automate part of this workflow with a small Python script.&lt;/p&gt;

&lt;p&gt;Not a trading bot.&lt;br&gt;&lt;br&gt;
Not a blind signal generator.&lt;br&gt;&lt;br&gt;
Not financial advice.&lt;/p&gt;

&lt;p&gt;Just a simple command-line tool that calls an API and returns a structured market briefing.&lt;/p&gt;

&lt;p&gt;In this article, I will show a minimal Python example that calls the darwintIQ Charlie API and prints a readable market briefing.&lt;/p&gt;

&lt;p&gt;The full example script is available here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/darwintIQ/API/blob/main/Python/charlie_market_briefing_example.py" rel="noopener noreferrer"&gt;GitHub example script&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  What we are building
&lt;/h2&gt;

&lt;p&gt;The script does five things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reads an API token from an environment variable or command-line argument&lt;/li&gt;
&lt;li&gt;Builds a market briefing request&lt;/li&gt;
&lt;li&gt;Sends a POST request to the Charlie API&lt;/li&gt;
&lt;li&gt;Handles basic HTTP and network errors&lt;/li&gt;
&lt;li&gt;Prints either the full JSON response or a formatted summary&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The default use case is a DAX market briefing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python charlie_market_briefing_example.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also request another symbol:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python charlie_market_briefing_example.py &lt;span class="nt"&gt;--symbol&lt;/span&gt; XAUUSD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or ask a more specific question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python charlie_market_briefing_example.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--symbol&lt;/span&gt; EURUSD &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--prompt&lt;/span&gt; &lt;span class="s2"&gt;"Give me a trader's desk briefing on EURUSD. What is currently driving the tone?"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why market briefings?
&lt;/h2&gt;

&lt;p&gt;Most trading tools focus on either raw data or final buy/sell signals.&lt;/p&gt;

&lt;p&gt;But there is a useful layer in between:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;structured market context&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A market briefing can help summarize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;current tone&lt;/li&gt;
&lt;li&gt;directional bias&lt;/li&gt;
&lt;li&gt;confidence&lt;/li&gt;
&lt;li&gt;main risks&lt;/li&gt;
&lt;li&gt;relevant observations&lt;/li&gt;
&lt;li&gt;supporting evidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is useful for human decision-making because it does not replace your own analysis. It gives you a structured starting point.&lt;/p&gt;

&lt;p&gt;I like to think of it as a trader's desk briefing generated from quantitative context.&lt;/p&gt;




&lt;h2&gt;
  
  
  No external Python dependencies
&lt;/h2&gt;

&lt;p&gt;This example intentionally does not use any external packages.&lt;/p&gt;

&lt;p&gt;It only uses Python's standard library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urllib.error&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urllib.request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That keeps the script easy to run in almost any Python environment.&lt;/p&gt;

&lt;p&gt;No virtual environment required.&lt;br&gt;&lt;br&gt;
No &lt;code&gt;pip install requests&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
No additional setup beyond an API token.&lt;/p&gt;


&lt;h2&gt;
  
  
  Basic configuration
&lt;/h2&gt;

&lt;p&gt;The script defines a few defaults:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;DEFAULT_BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.darwintiq.com/v1/charlie&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;DEFAULT_SYMBOL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DAX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;DEFAULT_WORKFLOW_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;market_briefing&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;DEFAULT_PROMPT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Give me a trader&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s desk briefing on DAX. &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is actually driving the current tone?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default workflow is &lt;code&gt;market_briefing&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The default symbol is &lt;code&gt;DAX&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The default prompt asks Charlie to explain what is currently driving the market tone.&lt;/p&gt;

&lt;p&gt;You can override all of this from the command line.&lt;/p&gt;




&lt;h2&gt;
  
  
  Authentication
&lt;/h2&gt;

&lt;p&gt;The script expects an API token.&lt;/p&gt;

&lt;p&gt;You can either set it as an environment variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DARWINTIQ_API_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your_api_token_here"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or pass it directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python charlie_market_briefing_example.py &lt;span class="nt"&gt;--token&lt;/span&gt; your_api_token_here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For local development, the environment variable is usually cleaner.&lt;/p&gt;

&lt;p&gt;The script reads it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DARWINTIQ_API_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;API token. Defaults to DARWINTIQ_API_TOKEN.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no token is available, the script exits with a clear error message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;missing API token. Set DARWINTIQ_API_TOKEN or pass --token.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Building the API payload
&lt;/h2&gt;

&lt;p&gt;The request payload contains three required parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;symbol&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;workflowId&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;messages&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Namespace&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;symbol&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;workflowId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;workflow_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timeframe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timeframe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timeframe&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signal_mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;signalMode&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signal_mode&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This structure makes the script flexible.&lt;/p&gt;

&lt;p&gt;You can use the default briefing workflow, but you can still adapt the prompt, symbol, timeframe, or signal mode from the CLI.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python charlie_market_briefing_example.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--symbol&lt;/span&gt; DAX &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeframe&lt;/span&gt; H1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--prompt&lt;/span&gt; &lt;span class="s2"&gt;"Give me a short briefing for the next trading session."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Calling the API
&lt;/h2&gt;

&lt;p&gt;The API request is a normal HTTP POST request with a JSON body and Bearer token authentication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Accept&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is decoded and parsed as JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script also handles common error cases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTPError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;replace&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;detail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JSONDecodeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;detail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;SystemExit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTTP &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; calling Charlie API:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;urllib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URLError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;SystemExit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Network error calling Charlie API: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful because API examples often show only the happy path.&lt;/p&gt;

&lt;p&gt;In practice, good error messages matter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Printing a readable briefing
&lt;/h2&gt;

&lt;p&gt;The API response can be printed as raw JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python charlie_market_briefing_example.py &lt;span class="nt"&gt;--json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But for daily usage, a formatted summary is easier to read.&lt;/p&gt;

&lt;p&gt;The script extracts fields such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;symbol&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;workflowLabel&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;language&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;summary&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;answer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;evidence&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print_formatted_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;workflow_label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;workflowLabel&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;symbol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;symbol&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;language&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;language&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;summary&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="n"&gt;evidence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;evidence&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Symbol: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;symbol&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Workflow: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;workflow_label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Language: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a summary is available, it prints the most important fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;bottom_line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bottomLine&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bias&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bias&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;confidence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;confidence&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;main_risk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mainRisk&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives the briefing a clean structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Symbol: DAX
Workflow: Market Briefing
Language: en
Bottom line: ...
Bias: ...
Confidence: ...
Main risk: ...

Answer:

...

Evidence:
- ...
- ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the output useful as a command-line briefing, a journal entry, or an input for another automation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example usage
&lt;/h2&gt;

&lt;p&gt;Default DAX briefing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python charlie_market_briefing_example.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Briefing for another symbol:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python charlie_market_briefing_example.py &lt;span class="nt"&gt;--symbol&lt;/span&gt; XAUUSD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Custom prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python charlie_market_briefing_example.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--symbol&lt;/span&gt; DAX &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--prompt&lt;/span&gt; &lt;span class="s2"&gt;"Give me a concise trader's desk briefing before the European session."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Timeframe override:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python charlie_market_briefing_example.py &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--symbol&lt;/span&gt; EURUSD &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--timeframe&lt;/span&gt; H1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full JSON response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python charlie_market_briefing_example.py &lt;span class="nt"&gt;--symbol&lt;/span&gt; DAX &lt;span class="nt"&gt;--json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Example output
&lt;/h2&gt;

&lt;p&gt;A formatted response could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Symbol: DAX
Workflow: Market Briefing
Language: en
Bottom line: The market tone is cautious, with direction still depending on follow-through.
Bias: Neutral to slightly bullish
Confidence: Medium
Main risk: Volatility around macro headlines

Answer:

The current DAX tone appears to be driven by a mix of short-term momentum,
risk sentiment, and uncertainty around upcoming macro catalysts.

Evidence:
- Recent model context shows mixed but improving conditions.
- Momentum is present, but not strong enough to remove downside risk.
- The next session may depend heavily on whether buyers can maintain pressure.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is only an illustrative example. Real API output depends on the selected symbol, market conditions, workflow, and prompt.&lt;/p&gt;




&lt;h2&gt;
  
  
  Possible extensions
&lt;/h2&gt;

&lt;p&gt;Once you have a basic CLI client, you can build more useful workflows around it.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Save briefings as Markdown
&lt;/h3&gt;

&lt;p&gt;You could store each briefing in a daily trading journal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;-DAX-briefing.md&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Send the briefing to Telegram or Discord
&lt;/h3&gt;

&lt;p&gt;Instead of printing to the terminal, the script could send the briefing to a private channel every morning.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Generate briefings for multiple symbols
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;symbols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DAX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;XAUUSD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EURUSD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GBPUSD&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;symbol&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;symbols&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# call API for each symbol
&lt;/span&gt;    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Use it as part of a dashboard
&lt;/h3&gt;

&lt;p&gt;The same API response could be displayed in a web dashboard, internal tool, or trading assistant interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Connect it to MetaTrader workflows
&lt;/h3&gt;

&lt;p&gt;A Python script like this could also act as a bridge between an external analysis API and a MetaTrader-based workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;p&gt;This kind of tool should not be misunderstood.&lt;/p&gt;

&lt;p&gt;It is not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a trading bot&lt;/li&gt;
&lt;li&gt;a guaranteed signal generator&lt;/li&gt;
&lt;li&gt;financial advice&lt;/li&gt;
&lt;li&gt;a replacement for risk management&lt;/li&gt;
&lt;li&gt;a promise of future performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to make market context easier to consume.&lt;/p&gt;

&lt;p&gt;A good briefing should support your thinking, not replace it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;I like the idea of treating market briefings as an API workflow.&lt;/p&gt;

&lt;p&gt;Instead of manually collecting information from different dashboards, a developer can call an API, request structured market context, and turn the response into a readable briefing.&lt;/p&gt;

&lt;p&gt;For this example, I used the Charlie API from darwintIQ.&lt;/p&gt;

&lt;p&gt;Charlie is designed to work like a personal Quant analyst: it turns quantitative market context into readable briefings and helps traders understand what may be driving the current tone.&lt;/p&gt;

&lt;p&gt;The focus is not automated trade execution.&lt;/p&gt;

&lt;p&gt;The focus is better market preparation.&lt;/p&gt;

&lt;p&gt;If you are building trading tools, dashboards, journals, or MetaTrader workflows and want to add AI-generated market context, Charlie can be used as a briefing layer via API.&lt;/p&gt;

&lt;p&gt;It is not designed to place trades for you.&lt;/p&gt;

&lt;p&gt;It is designed to help you understand the current market tone faster.&lt;/p&gt;

&lt;p&gt;You can find the full Python example here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/darwintIQ/API/blob/main/Python/charlie_market_briefing_example.py" rel="noopener noreferrer"&gt;GitHub example script&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And more about Charlie here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.darwintiq.com/docs/getting-started/charlie-explained" rel="noopener noreferrer"&gt;Charlie documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

</description>
      <category>quantitativetrading</category>
      <category>python</category>
      <category>marketbriefing</category>
      <category>ai</category>
    </item>
    <item>
      <title>Why static trading strategies fail in non-stationary markets</title>
      <dc:creator>Volker Bohn</dc:creator>
      <pubDate>Mon, 16 Mar 2026 14:16:10 +0000</pubDate>
      <link>https://dev.to/darwintiq/why-static-trading-strategies-fail-in-non-stationary-markets-4j24</link>
      <guid>https://dev.to/darwintiq/why-static-trading-strategies-fail-in-non-stationary-markets-4j24</guid>
      <description>&lt;h1&gt;
  
  
  Why static trading strategies fail in non-stationary markets
&lt;/h1&gt;

&lt;p&gt;One of the most persistent assumptions in systematic trading is that a&lt;br&gt;
strategy, once discovered, can remain valid indefinitely.&lt;/p&gt;

&lt;p&gt;In practice, this assumption rarely holds.&lt;/p&gt;

&lt;p&gt;Financial markets are &lt;strong&gt;non-stationary systems&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
The statistical structure of price movements constantly changes due to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;macroeconomic events&lt;/li&gt;
&lt;li&gt;liquidity shifts&lt;/li&gt;
&lt;li&gt;participant behavior&lt;/li&gt;
&lt;li&gt;technological evolution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A strategy that performs well today may degrade months or even weeks&lt;br&gt;
later.&lt;/p&gt;

&lt;p&gt;This is not necessarily because the strategy was poorly designed.&lt;br&gt;&lt;br&gt;
Often it simply means that the &lt;strong&gt;environment has changed&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with static strategies
&lt;/h2&gt;

&lt;p&gt;Most trading systems follow a traditional workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Design a strategy&lt;/li&gt;
&lt;li&gt;Optimize parameters on historical data&lt;/li&gt;
&lt;li&gt;Deploy the strategy&lt;/li&gt;
&lt;li&gt;Periodically re-optimize&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process has two major problems.&lt;/p&gt;

&lt;p&gt;First, optimization often leads to &lt;strong&gt;overfitting&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Parameters become tailored to a specific historical period rather than&lt;br&gt;
capturing persistent structure.&lt;/p&gt;

&lt;p&gt;Second, the adaptation cycle is &lt;strong&gt;slow and manual&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
By the time a trader realizes that performance has degraded, the market&lt;br&gt;
may already have moved into a different regime.&lt;/p&gt;

&lt;p&gt;In other words, static strategies assume a stable world.&lt;/p&gt;

&lt;p&gt;Markets are not stable.&lt;/p&gt;

&lt;h2&gt;
  
  
  An evolutionary perspective
&lt;/h2&gt;

&lt;p&gt;One alternative approach is inspired by evolutionary systems.&lt;/p&gt;

&lt;p&gt;Instead of searching for a single "best" model, we can maintain a&lt;br&gt;
&lt;strong&gt;population of models&lt;/strong&gt; that compete with each other.&lt;/p&gt;

&lt;p&gt;Each model consists of components such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;entry logic&lt;/li&gt;
&lt;li&gt;position management&lt;/li&gt;
&lt;li&gt;filters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The parameters of these components can mutate over time.&lt;/p&gt;

&lt;p&gt;Models are evaluated continuously on recent market data using a fitness&lt;br&gt;
function that considers characteristics such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;profitability&lt;/li&gt;
&lt;li&gt;stability&lt;/li&gt;
&lt;li&gt;drawdown behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Models that perform poorly disappear.&lt;br&gt;&lt;br&gt;
Models that perform well survive.&lt;/p&gt;

&lt;p&gt;Over time, the population adapts to the changing environment.&lt;/p&gt;

&lt;p&gt;This mirrors a simple principle from biology:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Evolution does not produce perfect organisms.&lt;br&gt;
It produces organisms that survive under current conditions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Observing model behavior instead of predicting markets
&lt;/h2&gt;

&lt;p&gt;An interesting shift happens when we think about trading systems this&lt;br&gt;
way.&lt;/p&gt;

&lt;p&gt;The goal is no longer to discover &lt;strong&gt;the perfect strategy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead, the focus becomes observing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which models currently perform well&lt;/li&gt;
&lt;li&gt;how their behavior changes over time&lt;/li&gt;
&lt;li&gt;which structural features survive longer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This turns the problem into something closer to &lt;strong&gt;adaptive model&lt;br&gt;
selection&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Markets are not solved.&lt;br&gt;&lt;br&gt;
They are &lt;strong&gt;continuously explored&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A small experiment
&lt;/h2&gt;

&lt;p&gt;I recently started building a small project around this idea called&lt;br&gt;
darwintIQ.&lt;/p&gt;

&lt;p&gt;The platform maintains a population of trading models and evaluates&lt;br&gt;
their behavior on rolling market data.&lt;/p&gt;

&lt;p&gt;It does not execute trades.&lt;/p&gt;

&lt;p&gt;Instead, it provides insight into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which model structures currently perform best&lt;/li&gt;
&lt;li&gt;how their parameters evolve&lt;/li&gt;
&lt;li&gt;which signal types dominate under certain conditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to observe &lt;strong&gt;how trading models evolve in a drifting&lt;br&gt;
environment&lt;/strong&gt; rather than relying on fixed strategies.&lt;/p&gt;

&lt;p&gt;If you're interested in systematic trading, evolutionary algorithms or&lt;br&gt;
adaptive systems, I'd be curious to hear your thoughts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.darwintiq.com" rel="noopener noreferrer"&gt;https://www.darwintiq.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>geneticalgorithm</category>
      <category>trading</category>
      <category>quanttrading</category>
      <category>technicalanalysis</category>
    </item>
  </channel>
</rss>
