{"id":6423,"date":"2025-06-25T12:01:58","date_gmt":"2025-06-25T12:01:58","guid":{"rendered":"https:\/\/eodhd.com\/financial-academy\/?p=6423"},"modified":"2025-06-25T12:02:04","modified_gmt":"2025-06-25T12:02:04","slug":"using-sentiment-in-our-trading-strategy","status":"publish","type":"post","link":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy","title":{"rendered":"Using sentiment in our trading strategy"},"content":{"rendered":"\n<p>Trading can be a highly emotional experience. It can significantly disrupt your progress if you can\u2019t manage your emotions. That\u2019s why experienced trading professionals (not just those who claim to be experts online) consistently stress one key principle: thoroughly backtest your strategies and strive to separate your emotions from your decision-making process.<\/p>\n\n\n\n<p>But let\u2019s be honest: it\u2019s hard to stay completely unemotional, especially when reacting to news events. This raises an interesting question: can we actually measure the market\u2019s emotional response to news and use that data to inform our trading decisions?<\/p>\n\n\n\n<p>Before we get started, it\u2019s important to clarify that this article isn\u2019t about handing you a ready-made trading strategy to use tomorrow. Instead, my aim is to demonstrate that sentiment can, in fact, be quantified and applied across different types of automation. And here\u2019s a hint\u200a: the answer is a resounding YES!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-can-the-eodhd-api-for-sentiment-help-nbsp-us\">How can the EODHD API for sentiment help&nbsp;us?<\/h3>\n\n\n\n<p>Well, EODHD can&#8217;t help us control our emotions, but it can definitely help us gauge the emotions of others.<\/p>\n\n\n\n<p>EODHD provides an <a href=\"https:\/\/eodhd.com\/financial-apis\/stock-market-financial-news-api\">API<\/a> that delivers daily sentiment scores for major stocks, ETFs, and cryptocurrencies by analysing both news sources and social media. These sentiment scores are normalised on a scale from -1, representing very negative sentiment, to 1, indicating very positive sentiment. This allows traders and analysts to quantify and incorporate market sentiment into their trading strategies.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-let-s-check-out-some-data\">Let\u2019s check out some data.<\/h3>\n\n\n\n<p>First, we start with the imports and parameters. We will initially use Apple stock prices for the last two years.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code class=\"\">import requests\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport os\nfrom datetime import datetime, timedelta\nimport seaborn as sns\n\napi_token = os.environ.get('EODHD_API_TOKEN')\n\nTICKER = 'AAPL.US'\n# Using a 2-year period for analysis\nend_date = datetime.now()\nstart_date = end_date - timedelta(days=730)\nfrom_date = start_date.strftime('%Y-%m-%d')\nto_date = end_date.strftime('%Y-%m-%d')<\/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>In the second step, we will retrieve the price from the <a href=\"https:\/\/eodhd.com\/financial-apis\/api-for-historical-data-and-volumes\">EODHD API<\/a>.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code class=\"\">def get_price_data(ticker, from_date, to_date):\n    url = f'https:\/\/eodhd.com\/api\/eod\/{ticker}'\n    query = {'api_token': api_token, 'fmt': 'json', 'from': from_date, 'to': to_date}\n    response = requests.get(url, params=query)\n    if response.status_code != 200:\n            print(f\"Error retrieving price data: {response.status_code}\")\n            print(response.text)\n            return None\n    price_data = response.json()\n    price_df = pd.DataFrame(price_data)\n    # Convert date string to datetime for easier manipulation\n    price_df['date'] = pd.to_datetime(price_df['date'])\n    # Set date as index\n    price_df.set_index('date', inplace=True)\n    # Sort by date (ascending)\n    price_df.sort_index(inplace=True)\n    return price_df\nprice_df = get_price_data(TICKER, from_date, to_date)\nprice_df['pct_change'] = price_df['adjusted_close'].pct_change() * 100<\/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 then, using the <a href=\"https:\/\/eodhd.com\/financial-apis\/stock-market-financial-news-api\">EODHD API<\/a> for sentiment, we\u2019ll gather the sentiment data.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code class=\"\">def get_sentiment_data(ticker, from_date, to_date):\n    url = f'https:\/\/eodhd.com\/api\/sentiments'\n    query = {'api_token': api_token, 's': ticker, 'from': from_date, 'to': to_date, 'fmt': 'json'}\n    response = requests.get(url, params=query)\n    if response.status_code != 200:\n            print(f\"Error retrieving sentiment data: {response.status_code}\")\n            print(response.text)\n            return None\n    sentiment_data = response.json()\n    # Access the sentiment data using the ticker symbol as a key\n    sentiment_df = pd.DataFrame(sentiment_data[ticker])\n    # Convert date string to datetime\n    sentiment_df['date'] = pd.to_datetime(sentiment_df['date'])\n    # Set date as index\n    sentiment_df.set_index('date', inplace=True)\n    # Sort by date (ascending)\n    sentiment_df.sort_index(inplace=True)\n    # Rename column normalized to sentiment\n    sentiment_df.rename(columns={'normalized': 'sentiment'}, inplace=True)\n    return sentiment_df\nsentiment_df = get_sentiment_data(TICKER, from_date, to_date)<\/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>For this analysis, the daily sentiment column is our main indicator. I\u2019ll start by combining all the sentiment data into a single dataframe, making it easier to analyse trends across different assets. To highlight the underlying trend, I\u2019ll calculate a rolling average and remove any outliers from the data. This approach ensures the resulting trend line is both clear and visually distinct, allowing us to better observe sentiment shifts over time.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code class=\"\">merged_df = pd.merge(\n    price_df[['adjusted_close','pct_change']],\n    sentiment_df[['sentiment']],\n    left_index=True,\n    right_index=True,\n    how='inner'\n)\n\n# Rename columns for clarity\nmerged_df.columns = ['price', 'price_pct_change', 'sentiment']\nclean_df = merged_df[['price_pct_change','sentiment']].dropna().replace([np.inf, -np.inf], np.nan).dropna()\n# Calculate IQR and bounds for both variables\ndef remove_outliers(df, columns):\n    df_clean = df.copy()\n    for column in columns:\n        Q1 = df[column].quantile(0.25)\n        Q3 = df[column].quantile(0.75)\n        IQR = Q3 - Q1\n        lower_bound = Q1 - 1.5 * IQR\n        upper_bound = Q3 + 1.5 * IQR\n        df_clean = df_clean[df_clean[column].between(lower_bound, upper_bound)]\n    return df_clean\n# Apply outlier removal\nclean_df = remove_outliers(clean_df, ['price_pct_change', 'sentiment'])\n\n# Create a scatter plot to visualize the relationship\nplt.figure(figsize=(10, 6))\nplt.scatter(clean_df['sentiment'], clean_df['price_pct_change'], alpha=0.6)\nplt.xlabel('Sentiment Change')\nplt.ylabel('Daily Price Percentage Change (%)')\nplt.grid(True)\n# Add a trend line\nif len(clean_df) &gt; 1:  # Only add trend line if we have enough data points\n    try:\n        z = np.polyfit(clean_df['sentiment'], clean_df['price_pct_change'], 1)\n        p = np.poly1d(z)\n        plt.plot(sorted(clean_df['sentiment']), p(sorted(clean_df['sentiment'])), \"r--\", alpha=0.8)\n    except np.linalg.LinAlgError as e:\n        print(f\"Could not fit trend line: {e}\")\nplt.tight_layout()\nplt.show()<\/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<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/0*eqFOSpx13Ovw2AcS.png\" alt=\"\"\/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>Interestingly, even though the trend line isn\u2019t particularly steep, it clearly points upward, reflecting the impact of increasingly positive news sentiment on daily price movements. In short, positive news tends to correlate with more substantial returns.<\/p>\n\n\n\n<p>Of course, this insight only becomes actionable when we translate it into a practical strategy. So, let\u2019s dive into building one!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Moving Average Sentiment Strategy<\/h3>\n\n\n\n<p>I\u2019ll use a straightforward slow-fast moving-average strategy applied to both price and sentiment data. This generates two distinct strategy variations:<\/p>\n\n\n\n<p>Strategy 1: LONGSHORT<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Long Entry: When both price and sentiment fast MAs cross above their slow MAs (confirming bullish alignment).<\/li>\n\n\n\n<li>Short Entry: When both slow MAs exceed their fast counterparts (confirming bearish alignment).<\/li>\n\n\n\n<li>Neutral: When price and sentiment signals disagree.<\/li>\n<\/ul>\n\n\n\n<p>Strategy 2: ALWAYSLONG_OUTWHEN_NEGSENT<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Long Entry: Always hold long positions when the sentiment\u2019s fast MA is above its slow MA.<\/li>\n\n\n\n<li>Exit: Immediately close positions when sentiment\u2019s fast MA drops below its slow MA.<\/li>\n<\/ul>\n\n\n\n<p>Implementation Workflow<\/p>\n\n\n\n<p>We\u2019ll define two core functions:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Equity Curve Calculation: Quantifies strategy performance over time.<\/li>\n\n\n\n<li>Signal Execution: Translates MA crossovers into trade actions.<\/li>\n<\/ol>\n\n\n\n<p>This code transforms quantified sentiment into actionable signals while systematically minimising emotional interference.<\/p>\n\n\n\n<p>First the equity curve:<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code class=\"\">def calculate_equity_curve(prices, signals):\n    # Ensure index alignment\n    signals = signals.shift(1)  # Shift signals to align with the period for trade execution\n    signals = signals.reindex(prices.index).fillna(0)\n    # Calculate percentage changes\n    pct_changes = prices.pct_change().fillna(0)\n    # Calculate equity curve\n    equity_curve = (1 + pct_changes * signals).cumprod() * 100\n    return equity_curve<\/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 then the actual strategy:<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code class=\"\">def analyze_ma_crossover_strategy(ticker, fast_window, slow_window, from_date, to_date, strategy_type = \"LONGSHORT\"):\n\n    # Retrieve price data\n    price_df = get_price_data(ticker, from_date, to_date)\n    if price_df is None or len(price_df) == 0:\n        print(f\"Error: Could not retrieve price data for {ticker}\")\n        return None\n    # Retrieve sentiment data\n    sentiment_df = get_sentiment_data(ticker, from_date, to_date)\n    if sentiment_df is None or len(sentiment_df) == 0:\n        print(f\"Error: Could not retrieve sentiment data for {ticker}\")\n        return None\n    # Create a combined dataframe\n    df = pd.DataFrame(index=price_df.index)\n    df['adjusted_close'] = price_df['adjusted_close']\n    # Merge sentiment data (may have different dates)\n    df = df.join(sentiment_df['sentiment'], how='left')\n    # Forward fill missing sentiment values\n    df['sentiment'] = df['sentiment'].ffill()\n    # Calculate moving averages for price\n    df[f'price_fast_ma'] = df['adjusted_close'].rolling(window=fast_window).mean()\n    df[f'price_slow_ma'] = df['adjusted_close'].rolling(window=slow_window).mean()\n    # Calculate moving averages for sentiment\n    df[f'sentiment_fast_ma'] = df['sentiment'].rolling(window=fast_window).mean()\n    df[f'sentiment_slow_ma'] = df['sentiment'].rolling(window=slow_window).mean()\n    # Generate signals\n    if strategy_type == \"LONGSHORT\":\n        # 1 when fast MA &gt; slow MA for both price and sentiment\n        # -1 when fast MA &lt; slow MA for both price and sentiment\n        # 0 otherwise\n        df['price_signal'] = np.where(df[f'price_fast_ma'] &gt; df[f'price_slow_ma'], 1, -1)\n        df['sentiment_signal'] = np.where(df[f'sentiment_fast_ma'] &gt; df[f'sentiment_slow_ma'], 1, -1)\n        df['signal'] = np.where((df['price_signal'] == 1) &amp; (df['sentiment_signal'] == 1), 1,\n                               np.where((df['price_signal'] == -1) &amp; (df['sentiment_signal'] == -1), -1, 0))\n    elif strategy_type == 'ALWAYSLONG_OUTWHEN_NEGSENT':\n        # Always 1 except when sentiment signal is\n        df['price_signal'] = pd.Series(1, index=df.index)\n        df['sentiment_signal'] = np.where(df[f'sentiment_fast_ma'] &gt; df[f'sentiment_slow_ma'], 1, -1)\n        df['signal'] = np.where((df['sentiment_signal'] == -1), 0, df[f'price_signal'])\n    else:\n        raise ValueError(\"Invalid strategy type\")\n    # Calculate returns\n    df['pct_change'] = df['adjusted_close'].pct_change().fillna(0)\n    # Calculate equity curves using the calculate_equity_curve function\n    # For buy and hold, we use a signal of 1 (always long)\n    buy_hold_signal = pd.Series(1, index=df.index)\n    df['buy_hold_equity'] = calculate_equity_curve(df['adjusted_close'], buy_hold_signal) \/ 100\n    # For strategy equity, we use the generated signals\n    df['strategy_equity'] = calculate_equity_curve(df['adjusted_close'], df['signal']) \/ 100\n    return df<\/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>We\u2019ll implement the LONSHORT strategy with a 5-day fast and 15-day slow window for price and sentiment moving averages. After generating the signals, we\u2019ll visualise the results in a performance plot to assess effectiveness.<\/p>\n\n\n\n<p>Here&#8217;s a hands-on test that shows how combining quantified sentiment with technical indicators produces actionable trading signals. Let\u2019s see how it performs!<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code class=\"\">def plot_strategy_results(df):\n    # Create a figure with single plot for equity curves\n    plt.figure(figsize=(12, 6))\n    # Plot equity curves\n    plt.plot(df.index, df['buy_hold_equity'], label='Buy &amp; Hold')\n    plt.plot(df.index, df['strategy_equity'], label='MA Crossover Strategy')\n    plt.title('Equity Curves')\n    plt.ylabel('Equity (Starting at 1)')\n    plt.xlabel('Date')\n    plt.legend()\n    plt.grid(True)\n    plt.tight_layout()\n    plt.show()\nresult_df = analyze_ma_crossover_strategy(TICKER, fast_window=5, slow_window=15, from_date=from_date, to_date=to_date, strategy_type=\"LONGSHORT\")\nplot_strategy_results(result_df)<\/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<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/0*t4OSu5YiQMS6lXHc.png\" alt=\"\"\/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>The outcome is underwhelming\u200a. This approach failed to capture the mid-2024 uptrend and ultimately led to losses. To address this, let\u2019s tighten the moving average windows to 1 and 5 and apply the second strategy variation for a fresh perspective.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code class=\"\">result_df = analyze_ma_crossover_strategy(TICKER, fast_window=1, slow_window=5, from_date=from_date, to_date=to_date, strategy_type=\"ALWAYSLONG_OUTWHEN_NEGSENT\")\nplot_strategy_results(result_df)<\/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<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/0*07CW8Ka4ZptLzgeV.png\" alt=\"\"\/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>This time, the strategy\u2019s performance improved noticeably. The key advantage came from remaining neutral in the days immediately following the US tariff announcements\u200a\u2014\u200aa period when buy-and-hold investors suffered significant losses. By avoiding exposure during this volatile window and then leveraging the surge in positive sentiment that followed, the strategy was able to deliver strong returns.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-who-said-overfitting-is-bad\">Who said overfitting is bad?<\/h3>\n\n\n\n<p>Absolutely, I\u2019m aware that overfitting is undesirable. However, it can sometimes help uncover patterns, reinforcing our core idea: news sentiment is quantifiable! We are going to work with stocks from various sectors. Practically, we will use the functions developed before to calculate the returns.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code class=\"\">tickers = ['AAPL.US', 'MSFT.US', 'NVDA.US', 'GOOGL.US', 'META.US', 'AMZN.US', 'TSLA.US', 'HD.US', 'JNJ.US', 'UNH.US', 'PFE.US', 'MRK.US', 'JPM.US', 'V.US', 'MA.US', 'PG.US', 'KO.US', 'PEP.US', 'XOM.US', 'CVX.US', 'NEE.US', 'DUK.US', 'LIN.US', 'BA.US', 'CAT.US', 'RTX.US', 'SPG.US', 'AMT.US', 'MO.US']\n# Create lists to store the data\ndata = []\nfast_windows = range(1, 6)  # 1 to 5\nslow_windows = range(5, 21, 5)  # 5, 10, 15, 20\n\n# Loop through each ticker\nfor ticker in tickers:\n    # Initialize variables to track the best parameters and results for this ticker\n    best_fast_window = None\n    best_slow_window = None\n    best_strategy_type = None\n    best_return = -float('inf')\n    best_buy_hold_return = None\n    # Rest of the loop logic remains the same...\n    for fast_window in fast_windows:\n        for slow_window in slow_windows:\n            for strategy_type in [\"LONGSHORT\", \"ALWAYSLONG_OUTWHEN_NEGSENT\"]:\n                if fast_window &gt;= slow_window:\n                    continue\n                result_df = analyze_ma_crossover_strategy(ticker, fast_window, slow_window,\n                                                          from_date=from_date, to_date=to_date,\n                                                          strategy_type=strategy_type)\n                if result_df is not None:\n                    strategy_return = result_df['strategy_equity'].iloc[-1]\n                    buy_hold_return = result_df['buy_hold_equity'].iloc[-1]\n                    if strategy_return &gt; best_return:\n                        best_return = strategy_return\n                        best_fast_window = fast_window\n                        best_slow_window = slow_window\n                        best_strategy_type = strategy_type\n                        best_buy_hold_return = buy_hold_return\n    # Instead of concatenating each time, append to the list\n    data.append({\n        'ticker': ticker,\n        'fast_window': best_fast_window,\n        'slow_window': best_slow_window,\n        'strategy_type': best_strategy_type,\n        'strategy_return': best_return,\n        'buy_hold_return': best_buy_hold_return\n    })\n# Create the DataFrame once with all the data\noptimal_params_df = pd.DataFrame(data)\noptimal_params_df['str_bnh_diff'] = optimal_params_df['strategy_return'] - optimal_params_df['buy_hold_return']\noptimal_params_df<\/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>Now let&#8217;s plot the results.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code class=\"\">plt.figure(figsize=(12, 10))\n# Create horizontal bar positions\ny_pos = np.arange(len(optimal_params_df))\n# Create color array for strategy returns based on comparison with buy &amp; hold\nstrategy_colors = ['green' if s &gt; b else 'red' for s, b in zip(optimal_params_df['strategy_return'], optimal_params_df['buy_hold_return'])]\n# Plot the bars with new colors\nplt.barh(y_pos - 0.2, optimal_params_df['strategy_return'], height=0.4, label='Strategy Return', color=strategy_colors)\nplt.barh(y_pos + 0.2, optimal_params_df['buy_hold_return'], height=0.4, label='Buy &amp; Hold Return', color='grey')\nplt.yticks(y_pos, optimal_params_df['ticker'])\nplt.xlabel('Return')\nplt.title('Strategy vs Buy &amp; Hold Returns by Ticker')\nplt.legend()\nplt.grid(True, alpha=0.3)\nplt.tight_layout()\nplt.show()<\/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<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/0*4eoLQrdgFTNkHLu3.png\" alt=\"\"\/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>Most of our strategy variations beat the buy-and-hold approach, as shown by the green returns in our analysis. What&#8217;s notable is that every asset that lost money under buy-and-hold made at least some gains using our method, and some actually lost no money at all.<\/p>\n\n\n\n<p>Before wrapping up, I\u2019ll skip optimisation and instead compile every possible combination of fast and slow windows. This complete dataset will be visualised as a heatmap, directly comparing the effectiveness of window pairs across all tested parameters.<\/p>\n\n\n\n<p>This transparent approach avoids cherry-picking and reveals the full spectrum of strategy performance.<\/p>\n\n\n\n            <div class=\"code__wrapper\">\n                <div class=\"code__content\">\n                    \n<pre class=\"wp-block-code\"><code class=\"\">tickers = ['AAPL.US', 'MSFT.US', 'NVDA.US', 'GOOGL.US', 'META.US', 'AMZN.US', 'TSLA.US', 'HD.US', 'JNJ.US', 'UNH.US', 'PFE.US', 'MRK.US', 'JPM.US', 'V.US', 'MA.US', 'PG.US', 'KO.US', 'PEP.US', 'XOM.US', 'CVX.US', 'NEE.US', 'DUK.US', 'LIN.US', 'BA.US', 'CAT.US', 'RTX.US', 'SPG.US', 'AMT.US', 'MO.US']\n# Create lists to store the data\ndata = []\nfast_windows = range(1, 6)  # 1 to 5\nslow_windows = range(5, 21, 5)  # 5, 10, 15, 20\n\n# Loop through each ticker\nfor ticker in tickers:\n    # Initialize variables to track the best parameters and results for this ticker\n    best_fast_window = None\n    best_slow_window = None\n    best_strategy_type = None\n    best_return = -float('inf')\n    best_buy_hold_return = None\n    # Rest of the loop logic remains the same...\n    for fast_window in fast_windows:\n        for slow_window in slow_windows:\n            for strategy_type in [\"LONGSHORT\", \"ALWAYSLONG_OUTWHEN_NEGSENT\"]:\n                if fast_window &gt;= slow_window:\n                    continue\n                result_df = analyze_ma_crossover_strategy(ticker, fast_window, slow_window,\n                                                          from_date=from_date, to_date=to_date,\n                                                          strategy_type=strategy_type)\n                if result_df is not None:\n                    strategy_return = result_df['strategy_equity'].iloc[-1]\n                    buy_hold_return = result_df['buy_hold_equity'].iloc[-1]\n                    data.append({\n                        'ticker': ticker,\n                        'fast_window': fast_window,\n                        'slow_window': slow_window,\n                        'strategy_type': strategy_type,\n                        'strategy_return': strategy_return,\n                        'buy_hold_return': buy_hold_return\n                    })\n# Create the DataFrame once with all the data\nall_runs_df = pd.DataFrame(data)\nall_runs_df['str_bnh_diff'] = optimal_params_df['strategy_return'] - optimal_params_df['buy_hold_return']\n# First, let's create the aggregated data\ngrouped_df = all_runs_df.groupby(['fast_window', 'slow_window', 'strategy_type']).agg({\n    'strategy_return': 'mean',\n    'buy_hold_return': 'mean',\n}).reset_index()\n# Calculate the difference for coloring\ngrouped_df['str_bnh_diff'] = grouped_df['strategy_return'] - grouped_df['buy_hold_return']\nplt.figure(figsize=(12, 8))\n# Pivot the data to create a matrix suitable for heatmap\nheatmap_data = grouped_df.pivot_table(\n    index='fast_window',\n    columns='slow_window',\n    values='str_bnh_diff',\n    aggfunc='mean'\n)\n# Create heatmap\nsns.heatmap(heatmap_data,\n            annot=True,\n            fmt='.2f',\n            cmap='RdYlGn',\n            center=0,\n            cbar_kws={'label': 'Strategy Return - Buy &amp; Hold Return'}\n            )\nplt.title('Strategy Performance by Window Combinations')\nplt.xlabel('Slow Window')\nplt.ylabel('Fast Window')\nplt.tight_layout()\nplt.show()<\/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<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/0*KDw9_UIxZvHWKZPW.png\" alt=\"\"\/><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>The heatmap reveals two key insights:<\/p>\n\n\n\n<p>First, while optimising the fast and slow windows for each stock individually produced encouraging results, the strategy underperforms buy-and-hold on average across all stocks. This suggests that sensitivity to news sentiment varies significantly between different assets.<\/p>\n\n\n\n<p>Second, it\u2019s clear that setting the fast window to 1\u200a\u2014\u200aessentially using the previous day\u2019s sentiment\u200a\u2014\u200aconsistently outperforms strategies with larger window sizes. This highlights the immediate impact of news sentiment on short-term price movements.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Conclusion and food for&nbsp;thought<\/h3>\n\n\n\n<p>To wrap up, here are a few key takeaways:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sentiment scores extracted from news and social media can be quantified and integrated into trading strategies, and they show a clear positive correlation with daily price movements.<\/li>\n\n\n\n<li>Tailoring moving average windows to individual stocks often led to better results than a buy-and-hold approach, especially for assets that typically underperform.<\/li>\n\n\n\n<li>Some stocks are inherently more responsive to news events than others.<\/li>\n\n\n\n<li>Speed matters\u200a. Comparing yesterday\u2019s sentiment with the previous five-day average consistently delivered the most substantial returns, underscoring how quickly news impacts the market.<\/li>\n\n\n\n<li>The EODHD API effectively captured major market shocks, such as the US tariff announcements, helping the strategy avoid significant drawdowns1.<\/li>\n<\/ul>\n\n\n\n<p>If you\u2019re interested in exploring this area further, consider these ideas:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Investigate how historical sentiment trends relate to multi-day returns, rather than focusing solely on daily changes.<\/li>\n\n\n\n<li>Analyse the volatility of sentiment and see if it correlates with trading volume.<\/li>\n\n\n\n<li>Identify sideways or ranging markets and examine whether sentiment remains flat during these periods.<\/li>\n\n\n\n<li>Look for patterns in asset sensitivity to news and explore the reasons behind these differences.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Trading can be a highly emotional experience. It can significantly disrupt your progress if you can\u2019t manage your emotions. That\u2019s why experienced trading professionals (not just those who claim to be experts online) consistently stress one key principle: thoroughly backtest your strategies and strive to separate your emotions from your decision-making process. But let\u2019s be [&hellip;]<\/p>\n","protected":false},"author":30,"featured_media":0,"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":[65],"tags":[],"coding-language":[],"ready-to-go-solution":[],"qualification":[],"financial-apis-category":[],"financial-apis-manuals":[],"class_list":["post-6423","post","type-post","status-publish","format-standard","hentry","category-backtesting-strategies-examples"],"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>Using sentiment in our trading strategy | EODHD APIs Academy<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using sentiment in our trading strategy\" \/>\n<meta property=\"og:description\" content=\"Trading can be a highly emotional experience. It can significantly disrupt your progress if you can\u2019t manage your emotions. That\u2019s why experienced trading professionals (not just those who claim to be experts online) consistently stress one key principle: thoroughly backtest your strategies and strive to separate your emotions from your decision-making process. But let\u2019s be [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy\" \/>\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=\"2025-06-25T12:01:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-25T12:02:04+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn-images-1.medium.com\/max\/800\/0*eqFOSpx13Ovw2AcS.png\" \/>\n<meta name=\"author\" content=\"Filippos Tzimopoulos\" \/>\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=\"Filippos Tzimopoulos\" \/>\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\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#article\",\"isPartOf\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy\"},\"author\":{\"name\":\"Filippos Tzimopoulos\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/62bea60a15bb6cf5f09511bbcad2c448\"},\"headline\":\"Using sentiment in our trading strategy\",\"datePublished\":\"2025-06-25T12:01:58+00:00\",\"dateModified\":\"2025-06-25T12:02:04+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy\"},\"wordCount\":1151,\"publisher\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#organization\"},\"image\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#primaryimage\"},\"thumbnailUrl\":\"https:\/\/cdn-images-1.medium.com\/max\/800\/0*eqFOSpx13Ovw2AcS.png\",\"articleSection\":[\"Backtesting Strategies Examples\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy\",\"url\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy\",\"name\":\"Using sentiment in our trading strategy | EODHD APIs Academy\",\"isPartOf\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#primaryimage\"},\"image\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#primaryimage\"},\"thumbnailUrl\":\"https:\/\/cdn-images-1.medium.com\/max\/800\/0*eqFOSpx13Ovw2AcS.png\",\"datePublished\":\"2025-06-25T12:01:58+00:00\",\"dateModified\":\"2025-06-25T12:02:04+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#primaryimage\",\"url\":\"https:\/\/cdn-images-1.medium.com\/max\/800\/0*eqFOSpx13Ovw2AcS.png\",\"contentUrl\":\"https:\/\/cdn-images-1.medium.com\/max\/800\/0*eqFOSpx13Ovw2AcS.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/eodhd.com\/financial-academy\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using sentiment in our trading strategy\"}]},{\"@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\/62bea60a15bb6cf5f09511bbcad2c448\",\"name\":\"Filippos Tzimopoulos\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/4c3f487ab4ce0733b492937a98b5f56bf39f6c2c5ff51e85f849f7d09d5405f2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/4c3f487ab4ce0733b492937a98b5f56bf39f6c2c5ff51e85f849f7d09d5405f2?s=96&d=mm&r=g\",\"caption\":\"Filippos Tzimopoulos\"},\"description\":\"Seasoned Business and Data Analyst with over 30+ years of experience | Python advocate | Finance and Quantitative enthusiast\",\"sameAs\":[\"https:\/\/medium.com\/@phitzi\"],\"url\":\"https:\/\/eodhd.com\/financial-academy\/author\/filippos\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Using sentiment in our trading strategy | EODHD APIs Academy","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\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy","og_locale":"en_US","og_type":"article","og_title":"Using sentiment in our trading strategy","og_description":"Trading can be a highly emotional experience. It can significantly disrupt your progress if you can\u2019t manage your emotions. That\u2019s why experienced trading professionals (not just those who claim to be experts online) consistently stress one key principle: thoroughly backtest your strategies and strive to separate your emotions from your decision-making process. But let\u2019s be [&hellip;]","og_url":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy","og_site_name":"Financial Academy","article_publisher":"https:\/\/www.facebook.com\/eodhistoricaldata","article_published_time":"2025-06-25T12:01:58+00:00","article_modified_time":"2025-06-25T12:02:04+00:00","og_image":[{"url":"https:\/\/cdn-images-1.medium.com\/max\/800\/0*eqFOSpx13Ovw2AcS.png","type":"","width":"","height":""}],"author":"Filippos Tzimopoulos","twitter_card":"summary_large_image","twitter_creator":"@EOD_data","twitter_site":"@EOD_data","twitter_misc":{"Written by":"Filippos Tzimopoulos","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#article","isPartOf":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy"},"author":{"name":"Filippos Tzimopoulos","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/62bea60a15bb6cf5f09511bbcad2c448"},"headline":"Using sentiment in our trading strategy","datePublished":"2025-06-25T12:01:58+00:00","dateModified":"2025-06-25T12:02:04+00:00","mainEntityOfPage":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy"},"wordCount":1151,"publisher":{"@id":"https:\/\/eodhd.com\/financial-academy\/#organization"},"image":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#primaryimage"},"thumbnailUrl":"https:\/\/cdn-images-1.medium.com\/max\/800\/0*eqFOSpx13Ovw2AcS.png","articleSection":["Backtesting Strategies Examples"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy","url":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy","name":"Using sentiment in our trading strategy | EODHD APIs Academy","isPartOf":{"@id":"https:\/\/eodhd.com\/financial-academy\/#website"},"primaryImageOfPage":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#primaryimage"},"image":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#primaryimage"},"thumbnailUrl":"https:\/\/cdn-images-1.medium.com\/max\/800\/0*eqFOSpx13Ovw2AcS.png","datePublished":"2025-06-25T12:01:58+00:00","dateModified":"2025-06-25T12:02:04+00:00","breadcrumb":{"@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#primaryimage","url":"https:\/\/cdn-images-1.medium.com\/max\/800\/0*eqFOSpx13Ovw2AcS.png","contentUrl":"https:\/\/cdn-images-1.medium.com\/max\/800\/0*eqFOSpx13Ovw2AcS.png"},{"@type":"BreadcrumbList","@id":"https:\/\/eodhd.com\/financial-academy\/backtesting-strategies-examples\/using-sentiment-in-our-trading-strategy#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/eodhd.com\/financial-academy\/"},{"@type":"ListItem","position":2,"name":"Using sentiment in our trading strategy"}]},{"@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\/62bea60a15bb6cf5f09511bbcad2c448","name":"Filippos Tzimopoulos","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/eodhd.com\/financial-academy\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/4c3f487ab4ce0733b492937a98b5f56bf39f6c2c5ff51e85f849f7d09d5405f2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4c3f487ab4ce0733b492937a98b5f56bf39f6c2c5ff51e85f849f7d09d5405f2?s=96&d=mm&r=g","caption":"Filippos Tzimopoulos"},"description":"Seasoned Business and Data Analyst with over 30+ years of experience | Python advocate | Finance and Quantitative enthusiast","sameAs":["https:\/\/medium.com\/@phitzi"],"url":"https:\/\/eodhd.com\/financial-academy\/author\/filippos"}]}},"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pdOdVT-1FB","jetpack_sharing_enabled":true,"acf":[],"_links":{"self":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/6423","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\/30"}],"replies":[{"embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/comments?post=6423"}],"version-history":[{"count":9,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/6423\/revisions"}],"predecessor-version":[{"id":6433,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/posts\/6423\/revisions\/6433"}],"wp:attachment":[{"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/media?parent=6423"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/categories?post=6423"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/tags?post=6423"},{"taxonomy":"coding-language","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/coding-language?post=6423"},{"taxonomy":"ready-to-go-solution","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/ready-to-go-solution?post=6423"},{"taxonomy":"qualification","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/qualification?post=6423"},{"taxonomy":"financial-apis-category","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/financial-apis-category?post=6423"},{"taxonomy":"financial-apis-manuals","embeddable":true,"href":"https:\/\/eodhd.com\/financial-academy\/wp-json\/wp\/v2\/financial-apis-manuals?post=6423"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}