<?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>Forem: Shridhar G Vatharkar</title>
    <description>The latest articles on Forem by Shridhar G Vatharkar (@shridhargv).</description>
    <link>https://forem.com/shridhargv</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%2F943800%2Fb38d8c01-e716-42d4-a53b-0d84edad3eee.jpeg</url>
      <title>Forem: Shridhar G Vatharkar</title>
      <link>https://forem.com/shridhargv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/shridhargv"/>
    <language>en</language>
    <item>
      <title>Create a Market Profile Dashboard Using Python</title>
      <dc:creator>Shridhar G Vatharkar</dc:creator>
      <pubDate>Tue, 24 Jun 2025 09:18:28 +0000</pubDate>
      <link>https://forem.com/shridhargv/create-a-market-profile-dashboard-using-python-4coo</link>
      <guid>https://forem.com/shridhargv/create-a-market-profile-dashboard-using-python-4coo</guid>
      <description>&lt;p&gt;In this guide, you’ll learn how to build a Market Profile dashboard using Python. We’ll walk through how to use Streamlit, Plotly, and our Forex, CFD, and Crypto Data API to bring market data to life. Whether you're a trader, analyst, or developer, this tutorial will help you visualize key market structure components like Value Areas, Points of Control (POC), and TPO (Time Price Opportunity) Counts.&lt;/p&gt;

&lt;p&gt;Here’s what you’ll learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to retrieve minute-level market data using the TraderMade API&lt;/li&gt;
&lt;li&gt;How to calculate Market Profile elements such as Value Areas and POC&lt;/li&gt;
&lt;li&gt;How to display your analysis interactively using Streamlit and Plotly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What You’ll Need Before You Start
&lt;/h3&gt;

&lt;p&gt;To follow along, you should have a basic understanding of Python, some familiarity with Market Profile concepts, and access to a &lt;a href="https://tradermade.com/signup" rel="noopener noreferrer"&gt;TraderMade Forex API key&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Get Started
&lt;/h2&gt;

&lt;p&gt;We’ve broken down this tutorial into clear, manageable steps to make it easy to follow. First, we’ll begin by setting up your environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Setting Up Your Environment
&lt;/h3&gt;

&lt;p&gt;Make sure the following tools and libraries are installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install streamlit plotly pandas numpy python-dateutil tradermade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;p&gt;Begin by importing the necessary libraries and setting up the API connection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import streamlit as st
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import datetime
from dateutil.relativedelta import relativedelta
import streamlit.components.v1 as components
import tradermade as tm

tm.set_rest_api_key('Your_API_Key')  # Replace with your TraderMade API Key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Retrieve Minute-Level Data Using the TraderMade API
&lt;/h3&gt;

&lt;p&gt;In this step, we'll create a function to fetch the market data required for building our Market Profile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def get_data_raw(currency_pair, start_time, end_time, interval='minute'):
    try:
        # Fetch data using TraderMade SDK
        data = tm.timeseries(
            currency=currency_pair,
            start=start_time,
            end=end_time,
            interval=interval,
            period=30,
            fields=["open", "high", "low", "close"]
        )
        # print(data)
        # Print the response to see its structure
        # print("API Response:", data)

        # Convert the response directly into a DataFrame
        df = pd.DataFrame(data)
        df['volume'] = df['close']
        # Convert the 'date' column to datetime if it exists
        df = df.replace(0, np.nan)
        df = df.dropna()
        df.set_index("date", inplace=True)
        df = np.round(df, 4)
        if 'date' in df.columns:
            df['date'] = pd.to_datetime(df['date'])
            df.set_index('date', inplace=True)

        # Sort the DataFrame by index
        df.sort_index(inplace=True)
        return df


    except KeyError as e:
        print(f"KeyError: {e}")
        return pd.DataFrame()  # Return an empty DataFrame in case of an error

    except Exception as e:
        print(f"An error occurred: {e}")
        return pd.DataFrame()  # Return an empty DataFrame in case of a general error

def get_data_MP(g, p, f, F, cur, st, ed):
    df = get_data_raw(cur, st, ed)
    return df
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Helper Functions
&lt;/h3&gt;

&lt;p&gt;We’ll start by defining a function that identifies the most recent working day—this helps us skip non-trading days like weekends.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def last_work_date(date, format):
    if datetime.datetime.strptime(date, "%Y-%m-%d").weekday() == 6:
        return (datetime.datetime.strptime(date, "%Y-%m-%d")-relativedelta(days=2)).strftime(format)
    elif datetime.datetime.strptime(date, "%Y-%m-%d").weekday() == 0:
        return (datetime.datetime.strptime(date, "%Y-%m-%d")-relativedelta(days=3)).strftime(format)
    else:
        return (datetime.datetime.strptime(date, "%Y-%m-%d")-relativedelta(days=1)).strftime(format)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we'll define two additional functions to set the desired level of detail for our TPO and Market Profile views.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def get_rd(currency):
    od_list = ["UKOIL", "OIL", "XAGUSD","EVAUST","LUNUST",'LTCUST','XMRUST']
    od2_list = ["JPY"]
    od3_list = ["AAPL", "AMZN", "NFLX", "TSLA", "GOOGL", "BABA", "TWTR", "BAC", "BIDU", 
    'XAUUSD','SOLUST','BNBUST','BCHUST','DSHUST','EGLUST']
    od4_list = ["UK100", "SPX500","FRA40", "GER30","JPN225","NAS100","USA30", "HKG33", 
    "AUS200","BTC","BTCUST",'ETHUSD',"ETHUST"]
    cfd_list = ["EURNOK", "EURSEK", "USDSEK","USDNOK","NEOUST","ETCUST","DOTUST", "UNIUST"]
    if currency in od_list or currency[3:6] in od2_list:
        ad = .01
        rd = 2
    elif currency in od3_list:
        ad = 0.1
        rd = 1
    elif currency in od4_list:
        ad = 2
        rd = 0
    elif currency in cfd_list:
        ad = .001
        rd = 3
    else:
        ad = 0.0001
        rd = 4
    return rd, ad

def get_ad(ad, max, min):
    if (max-min) &amp;gt; ad*2000:
        return ad*50
    if (max-min) &amp;gt; ad*1000:
        return ad*20
    if (max-min) &amp;gt; ad*300:
        return ad*5
    elif (max-min) &amp;gt; ad*100:
        return ad*2
    else:
        return ad
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Compute TPO and Value Area
&lt;/h3&gt;

&lt;p&gt;The first function, &lt;em&gt;midmax_idx&lt;/em&gt;, helps identify the index of the highest value in an array that’s closest to its midpoint. The second function, &lt;em&gt;calculate_value_area&lt;/em&gt;, builds a value area around the Point of Control (POC) within the market profile (&lt;em&gt;mp&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;It does this by accumulating TPO counts from price levels near the POC until the sum reaches a specified target volume (&lt;em&gt;target_vol&lt;/em&gt;). The function then returns the price range—from &lt;em&gt;min_idx&lt;/em&gt; to &lt;em&gt;max_idx&lt;/em&gt;—that defines the value area. Note that this refers to TPO volume, which differs from actual trading volume.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def midmax_idx(array):
    if len(array) == 0:
        return None

    # Find candidate maxima
    # maxima_idxs = np.argwhere(array.to_numpy() == np.amax(array.to_numpy()))[:, 0]
    maxima_idxs = np.argwhere(array == np.amax(array))[:,0]
    if len(maxima_idxs) == 1:
        return maxima_idxs[0]
    elif len(maxima_idxs) &amp;lt;= 1:
        return None

    # Find the distances from the midpoint to find
    # the maxima with the least distance
    midpoint = len(array) / 2
    v_norm = np.vectorize(np.linalg.norm)
    maximum_idx = np.argmin(v_norm(maxima_idxs - midpoint))
    return maxima_idxs[maximum_idx]

def calculate_value_area(poc_volume, target_vol, poc_idx, mp):
    min_idx = poc_idx
    max_idx = poc_idx
    while poc_volume &amp;lt; target_vol:
        last_min = min_idx
        last_max = max_idx

        next_min_idx = np.clip(min_idx - 1, 0, len(mp) - 1)
        next_max_idx = np.clip(max_idx + 1, 0, len(mp) - 1)

        low_volume = mp.iloc[next_min_idx].vol if next_min_idx != last_min else None
        high_volume = mp.iloc[next_max_idx].vol if next_max_idx != last_max else None

        if not high_volume or (low_volume and low_volume &amp;gt; high_volume):
            poc_volume += low_volume
            min_idx = next_min_idx
        elif not low_volume or (high_volume and low_volume &amp;lt;= high_volume):
            poc_volume += high_volume
            max_idx = next_max_idx
        else:
            break
    return mp.iloc[min_idx].value, mp.iloc[max_idx].value

mp_dict = {"0000":"A","0030":"B","0100":"C","0130":"D","0200":"E","0230":"F","0300":"G","0330":"H","0400":"I","0430":"J","0500":"K","0530":"L","0600":"M","0630":"N","0700":"O","0730":"P","0800":"Q","0830":"R","0900":"S","0930":"T","1000":"U","1030":"V","1100":"W","1130":"X","1200":"a","1230":"b","1300":"c","1330":"d","1400":"e","1430":"f","1500":"g","1530":"h","1600":"i","1630":"j","1700":"k","1730":"l","1800":"m","1830":"n","1900":"o","1930":"p","2000":"q","2030":"r","2100":"s","2130":"t","2200":"u","2230":"v","2300":"w","2330":"x",}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Bringing It All Together
&lt;/h3&gt;

&lt;p&gt;To wrap things up, we’ll use the following function to generate the complete Market Profile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def cal_mar_pro(currency, study, freq, period, mode, fp, mp_st, mp_ed, date):
    st = datetime.datetime.strptime(mp_st, "%Y-%m-%d-%H:%M")
    print(currency, mp_st, mp_ed)
    # try:
    rf = get_data_MP("M", str(freq), "%Y-%m-%d-%H:%M" , "%Y-%m-%d-%H:%M",currency, mp_st, mp_ed)
    hf = rf.copy()
    last_price = rf.iloc[-1]["close"]

    rf = rf[["high","low"]]
    rf.index = pd.to_datetime(rf.index)
    #rf = rf[:96]
    rd, ad = get_rd(currency)
    max = round(rf.high.max(), rd)
    min = round(rf.low.min(), rd)
    ad = get_ad(ad, max, min)
    try:
      x_data = np.round(np.arange(min, max, ad).tolist(), rd)
    except:
      print("MP loop failed", currency)
    # x_data = x_data[::-1]
    y_data= []
    z_data = []
    y_data1= []
    z_data1 = []
    tocount1 = 0
    for item in x_data:
        alpha = ""
        alpha1 = ""
        alpha2 = ""
        for i in range(len(rf)):
            if rf.index[i] &amp;lt; date:
                if round(rf.iloc[i]["high"], rd) &amp;gt;= item &amp;gt;= round(rf.iloc[i]["low"], rd):
                    alpha += mp_dict[rf.index[i].strftime("%H%M")]
            elif rf.index[i] &amp;gt;= date:
                if round(rf.iloc[i]["high"], rd) &amp;gt;= item &amp;gt;= round(rf.iloc[i]["low"], rd):
                    alpha1 += mp_dict[rf.index[i].strftime("%H%M")]
        tocount1 += len(alpha1)
        y_data.append(len(alpha))
        y_data1.append(len(alpha1))
        z_data.append(alpha)
        z_data1.append(alpha1)
    # y_data = y_data[::-1]
    # y_data1 = y_data1[::-1]
    mp = pd.DataFrame([x_data, y_data1]).T
    mp = mp[::-1]
    mp = mp.rename(columns={0:"value",1:"vol"})
    #poc_idx = midmax_idx(mp.vol)
    poc_idx = midmax_idx(mp.vol.values)
    poc_vol = mp.iloc[poc_idx].vol
    poc_price = mp.iloc[poc_idx].value
    target_vol = 0.7*tocount1


    value_high,value_low = calculate_value_area(poc_vol, target_vol, poc_idx, mp)
    print("Value area",tocount1, 0.7*tocount1)


    return x_data, y_data,y_data1, z_data, z_data1, value_high, value_low, poc_price, last_price, hf

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we’ve set up the Market Profile data, it’s time to build the dashboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Streamlit Dashboard
&lt;/h3&gt;

&lt;p&gt;We’ll structure the Streamlit app into two main sections: the sidebar and the main display area. The sidebar will handle user inputs and configuration options to make the dashboard interactive, while the main area will present the Market Profile charts and tables.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sidebar
&lt;/h3&gt;

&lt;p&gt;Let’s start by setting up the sidebar—it’s straightforward and intuitive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Streamlit code to take input
st.set_page_config(layout="wide")
st.title("Market Profile Dashboard")

# currency = st.sidebar.text_input("Enter Currency Pair (e.g., EURUSD):", "EURUSD")
category = st.sidebar.selectbox("Select Category", ["CFD", "Forex"], index=["CFD", "Forex"].index(st.session_state.category))

item_list = tm.cfd_list() if category == "CFD" else ["EURUSD", "GBPUSD", "AUDUSD", "USDCAD", "EURNOK", "USDJPY", "EURGBP", "BTCUSD", "USDCHF", "NZDUSD", "USDINR", "USDZAR", "ETHUSD", "EURSEK"]

# Ensure item_list is a list and contains the default currency
if isinstance(item_list, list) and st.session_state.currency in item_list:
    index = item_list.index(st.session_state.currency)
else:
    index = 0  # Default to the first item if the currency is not in the list

currency = st.sidebar.selectbox("Select an Item", item_list, index=index)
study = st.sidebar.selectbox("Select Study Type:", ["MP"])
date = st.sidebar.date_input("Select Date")

# Subtract one day using relativedelta to get the previous day at 00:00 hours
mp_st = last_work_date(date.strftime('%Y-%m-%d'), '%Y-%m-%d-00:00')
if date != datetime.datetime.now().date():
   mp_ed = date.strftime('%Y-%m-%d-23:59')
else:
   mp_ed = datetime.datetime.now().strftime('%Y-%m-%d-%H:%M')    

# Convert to string format
# mp_st = previous_day.strftime("%Y-%m-%d-%H:%M")
freq = st.sidebar.selectbox("Select Minutes per period:", [30])
period = st.sidebar.selectbox("Select periods:", [24])
mode = st.sidebar.selectbox("Select Mode:", ["tpo"])
fp = int((60/int(freq))*period)

if date.weekday() in [5, 6]:  # 5 = Saturday, 6 = Sunday
   st.warning("Please select a weekday (Monday to Friday). Weekends are not allowed.")
   st.stop()  # Stop the app execution if the date is a weekend

# Check if the button has been clicked using session state
if "button_clicked" not in st.session_state:
   st.session_state.button_clicked = False

# Create the Market Profile chart only when the button is clicked
if st.sidebar.button("Get Market Profile"):
   st.session_state.button_clicked = True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Visualize with Streamlit &amp;amp; Plotly
&lt;/h3&gt;

&lt;p&gt;Before we render the charts and TPO Profile, we’ll check if the user has clicked the button. Once confirmed, we’ll go ahead and display the visual output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if st.session_state.button_clicked:
  #Get Market profile
  x_data, y_data,y_data1, z_data, z_data1, value_high, value_low, poc_price, last_price, hf = cal_mar_pro(currency, study, freq, period, mode, fp, mp_st,mp_ed, date)

  # Separate data for the previous day and current day
  previous_day_prices = x_data
  current_day_prices = x_data
  previous_day_counts = y_data
  current_day_counts = y_data1

  # Create the Market Profile chart for previous day
  candlestick = go.Candlestick(
      x=hf.index,
      open=hf['open'],
      high=hf['high'],
      low=hf['low'],
      close=hf['close'],
      name=f'{currency} Candlestick Chart',
  )
  tpo_dict = {}
  # Map index to date, using '00:00' hours formatting if necessary
  for i in range(len(hf.index)):
      tpo_dict[i] = hf.index[i]

  previous_day_dates = []
  current_day_dates = [] 

  for i in previous_day_counts:
      previous_day_dates.append(tpo_dict[i])
  for i in current_day_counts:
      current_day_dates.append(tpo_dict[i])

  # Create a vertical bar chart using the same x-axis (dates) and y-axis (volume)
  bar_chart = go.Bar(
      x=previous_day_dates,  # Use the same dates for x-axis
      y=previous_day_prices,  # Volume data for y-axis
      orientation='h',
      name="TPO Count previous day",
      marker=dict(
          color='rgba(50, 171, 96, 0.6)',
          line=dict(color='rgba(50, 171, 96, 1.0)', width=1)
      ),
      opacity=0.5,  # Adjust opacity to make both charts visible
      hoverinfo='skip'
  )

  bar_chart2 = go.Bar(
          x=current_day_dates,  # Use the same dates for x-axis
          y=current_day_prices,  # Volume data for y-axis
          orientation='h',
          name=f"TPO Count {date}",
          marker=dict(
          color='rgba(100, 149, 237, 0.6)',
          line=dict(color='rgba(100, 149, 237, 1.0)', width=1),
      ),
      opacity=0.5,  # Adjust opacity to make both charts visible
      hoverinfo='skip'
  )

  # Initialize the figure and add both traces
  fig1 = go.Figure()
  fig1.add_trace(candlestick)
  fig1.add_trace(bar_chart)
  fig1.add_trace(bar_chart2)
  print(y_data[0],y_data[-1:], poc_price)
  num_ticks = 6  # Number of ticks to display
  tick_indices = np.linspace(0, len(hf.index) - 1, num_ticks, dtype=int)
  tickvals = [hf.index[i] for i in tick_indices]
  ticktext = [hf.index[i] for i in tick_indices]

  # Update x-axis to show fewer date labels
  fig1.update_xaxes(
      tickvals=tickvals,  # Specify which dates to show
      ticktext=ticktext,  # Specify the labels for those dates
      tickangle=0,  # Keep the tick labels horizontal
      title_text='Date',
      showgrid=True,
  )
  fig1.update_yaxes(
      showgrid=True,
  )

  # Update layout for the combined chart
  fig1.update_layout(
      title=f'{currency} Candlestick Chart with TPO Bars',
      xaxis_title='Date/TPO Count',
      yaxis_title='Price',
      yaxis=dict(range=[x_data[0], x_data[-1]]),  # Reverse the y-axis
      height=600,
      xaxis=dict(
          type='category',  # Use 'category' type to skip missing dates
          categoryorder='category ascending',  # Order categories in ascending order
          showgrid=True,
      ),
      xaxis_rangeslider_visible=False  # Hide the range slider
  )

  # Create the Market Profile chart for current day
  fig2 = go.Figure()
  fig2.add_trace(go.Bar(
      x=previous_day_counts,  # Count on the x-axis
      y=previous_day_prices,  # Price levels on the y-axis
      orientation='h',
      name=f"TPO Count Previous day",
      marker=dict(
          color='rgba(50, 171, 96, 0.6)',
          line=dict(color='rgba(50, 171, 96, 1.0)', width=1)
      ),
      opacity=0.5
  ))

  fig2.add_trace(go.Bar(
      x=current_day_counts,  # Count on the x-axis
      y=current_day_prices,  # Price levels on the y-axis
      orientation='h',
      name=f"TPO Count {date}",
      marker=dict(
          color='rgba(100, 149, 237, 0.6)',
          line=dict(color='rgba(100, 149, 237, 1.0)', width=1),
      ),
  ))
  fig2.update_xaxes(
      showgrid=True,
  )
  fig2.update_yaxes(
      showgrid=True,
  )
  fig2.update_layout(
      title=f"{currency} Two-day Market Profile",
      xaxis_title="TPO Count",
      yaxis_title="Price Levels",
      template="plotly_white",
      height=600,
      width=600
  )

  # Create two columns to display charts side by side
  col1, col2 = st.columns([1, 1])

  with col1:
      st.plotly_chart(fig1, use_container_width=True)  # Adjusts the chart to fit the column width

  with col2:
      st.plotly_chart(fig2, use_container_width=True)

  style = """
  &amp;lt;style&amp;gt;
  table {
      width: 100%;
      border-collapse: collapse;
      font-family: 'Courier New', Courier, monospace;  /* Monospaced font */
  }
  th, td {
      border: 1px solid #ddd;
      padding: 8px;
      text-align: left;
      white-space: nowrap;  /* Ensure no text wrapping */
      font-weight: bold;
  }
  th {
      background-color: #f2f2f2;
      font-weight: bold;
  }
  tr:nth-child(even) {
      background-color: #f9f9f9;  /* Light gray background for even rows */
  }
  tr:hover {
      background-color: #f1f1f1;  /* Highlight row on hover */
  }
  &amp;lt;/style&amp;gt;"""

  html_table = style
  html_table += "&amp;lt;table style='width:100%; border: 1px solid black; font-size: 12px; border-collapse: collapse;font-family: 'Courier New', Courier, monospace;'&amp;gt;"
  html_table += "&amp;lt;tr&amp;gt;&amp;lt;th style='border: 1px solid black; padding: 2px;'&amp;gt;Prices&amp;lt;/th&amp;gt;"
  html_table += "&amp;lt;th style='border: 1px solid black;padding: 2px;'&amp;gt;Previous Day&amp;lt;/th&amp;gt;"
  html_table += f"&amp;lt;th style='border: 1px solid black;padding: 2px;'&amp;gt;{date}&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;"

  # Populate the table rows
  for x, z, z1 in zip(reversed(x_data), reversed(z_data), reversed(z_data1)):
      if x in [value_low, poc_price, value_high]:
          html_table += f"&amp;lt;tr&amp;gt;&amp;lt;td style='color:#FF6961; border: 1px solid black; padding: 0px;'&amp;gt;{x}&amp;lt;/td&amp;gt;"
          html_table += f"&amp;lt;td style='color:#FF6961; border: 1px solid black; padding: 0px;'&amp;gt;{z}&amp;lt;/td&amp;gt;"
          html_table += f"&amp;lt;td style='color:#FF6961; border: 1px solid black; padding: 0px;'&amp;gt;{z1}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;"
      else:       
          html_table += f"&amp;lt;tr&amp;gt;&amp;lt;td style='border: 1px solid black; padding: 0px;'&amp;gt;{x}&amp;lt;/td&amp;gt;"
          html_table += f"&amp;lt;td style='border: 1px solid black; padding: 0px;'&amp;gt;{z}&amp;lt;/td&amp;gt;"
          html_table += f"&amp;lt;td style='border: 1px solid black; padding: 0px;'&amp;gt;{z1}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;"

  html_table += "&amp;lt;/table&amp;gt;"

  html_table2 = style
  html_table2 += f"""
  &amp;lt;table style='width:100%; border: 1px solid black; border-collapse: collapse; font-size: 10px;'&amp;gt;
      &amp;lt;tr&amp;gt;
          &amp;lt;th style='border: 1px solid black; padding: 2px;'&amp;gt;Letter&amp;lt;/th&amp;gt;
          &amp;lt;th style='border: 1px solid black; padding: 2px;'&amp;gt;Period&amp;lt;/th&amp;gt;
      &amp;lt;/tr&amp;gt;
  """

  # Populate the second table rows in reverse order or different formatting
  for letter, period in mp_dict.items():
      html_table2 += f"""
      &amp;lt;tr&amp;gt;
          &amp;lt;td style='border: 1px solid black; padding: 2px;'&amp;gt;{letter}&amp;lt;/td&amp;gt;
          &amp;lt;td style='border: 1px solid black; padding: 2px;'&amp;gt;{period}&amp;lt;/td&amp;gt;
      &amp;lt;/tr&amp;gt;
      """

  html_table2 += f"&amp;lt;/table&amp;gt;"

  html_table3 = style
  html_table3 += f"""
  &amp;lt;table style='width:100%; border: 1px solid black; border-collapse: collapse; font-size: 10px;'&amp;gt;
      &amp;lt;tr&amp;gt;
          &amp;lt;th style='border: 1px solid black; padding: 2px;'&amp;gt;Key Prices&amp;lt;/th&amp;gt;
          &amp;lt;th style='border: 1px solid black; padding: 2px;'&amp;gt;Values&amp;lt;/th&amp;gt;
      &amp;lt;/tr&amp;gt;
  """

  html_table3 += f"""
      &amp;lt;tr&amp;gt;
          &amp;lt;td style='border: 1px solid black; padding: 2px;'&amp;gt;Value Area High&amp;lt;/td&amp;gt;
          &amp;lt;td style='border: 1px solid black; padding: 2px;'&amp;gt;{value_high}&amp;lt;/td&amp;gt;
      &amp;lt;/tr&amp;gt;
      &amp;lt;tr&amp;gt;
          &amp;lt;td style='border: 1px solid black; padding: 2px;'&amp;gt;Point of Control (POC)&amp;lt;/td&amp;gt;
          &amp;lt;td style='border: 1px solid black; padding: 2px;'&amp;gt;{poc_price}&amp;lt;/td&amp;gt;
      &amp;lt;/tr&amp;gt;
      &amp;lt;tr&amp;gt;
          &amp;lt;td style='border: 1px solid black; padding: 2px;'&amp;gt;Value Area Low&amp;lt;/td&amp;gt;
          &amp;lt;td style='border: 1px solid black; padding: 2px;'&amp;gt;{value_low}&amp;lt;/td&amp;gt;
      &amp;lt;/tr&amp;gt;
      &amp;lt;/table&amp;gt;
      """
  col3, col4 = st.columns([2, 2])
  with col1:
      components.html(html_table, height=2000, scrolling=True)
  with col2:
      components.html(html_table3,height=90, scrolling=True)
      components.html(html_table2, height=1200, scrolling=True)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final section of the code is somewhat lengthy, but it primarily focuses on displaying the data using HTML tables and Plotly charts. If you're interested in customizing or learning more, you can explore Plotly and HTML documentation. For now, feel free to copy and paste this part as is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;You now have a fully functional and interactive Market Profile dashboard that works with Forex, CFD, and Crypto data. In just a few minutes, you can analyze different currency pairs, timeframes, and market structures.&lt;/p&gt;

&lt;p&gt;To view the complete code, head over to our &lt;a href="https://github.com/tradermade/Python-SDK/blob/main/examples/market_profile.py" rel="noopener noreferrer"&gt;GitHub Market Profile examples&lt;/a&gt; page.&lt;/p&gt;

&lt;p&gt;You can also enhance your dashboard by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Experimenting with different time intervals, such as hourly or daily&lt;/li&gt;
&lt;li&gt;Incorporating Volume Profile analysis&lt;/li&gt;
&lt;li&gt;Adding alerts or triggers based on your trading strategies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please go through the original tutorial on our website: &lt;br&gt;
&lt;strong&gt;&lt;a href="https://tradermade.com/tutorials/build-a-market-profile-dashboard-in-python" rel="noopener noreferrer"&gt;Build a Market Profile Dashboard with Python&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>streamlit</category>
      <category>marketprofiledashboard</category>
      <category>forexdata</category>
    </item>
    <item>
      <title>Kotlin Guide for Retrieving Forex Market Data</title>
      <dc:creator>Shridhar G Vatharkar</dc:creator>
      <pubDate>Thu, 12 Jun 2025 13:54:08 +0000</pubDate>
      <link>https://forem.com/shridhargv/kotlin-guide-for-retrieving-forex-market-data-ikd</link>
      <guid>https://forem.com/shridhargv/kotlin-guide-for-retrieving-forex-market-data-ikd</guid>
      <description>&lt;p&gt;In today’s interconnected financial landscape, currency exchange rates have a significant impact on the global economy. For software developers, having access to reliable and real-time foreign exchange (forex) data is crucial for creating robust financial tools and applications. &lt;a href="https://tradermade.com/forex" rel="noopener noreferrer"&gt;TraderMade&lt;/a&gt; offers a robust API that delivers real-time market data, historical exchange rates, and currency conversion information for a diverse range of currency pairs.&lt;/p&gt;

&lt;p&gt;This Kotlin-based tutorial will guide you through using the TraderMade API with the Kotlin programming language. It covers the entire process—from setting up your Kotlin development environment to retrieving and displaying forex data from the API.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Key
&lt;/h2&gt;

&lt;p&gt;To start using the TraderMade API, &lt;a href="https://tradermade.com/signup" rel="noopener noreferrer"&gt;create an account&lt;/a&gt;, go to the API section of the dashboard, select a suitable plan, and copy your unique API key for integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Begin Coding
&lt;/h2&gt;

&lt;p&gt;To ensure clarity, we’ve broken down this Kotlin tutorial into manageable steps. Let's start by setting up the development environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Environment Setup
&lt;/h3&gt;

&lt;p&gt;The following essential libraries are imported at the beginning of the code:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Retrofit&lt;/strong&gt; – This library facilitates HTTP communication with REST APIs. It streamlines the process by enabling you to define API endpoints through Kotlin interfaces.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. GsonConverterFactory&lt;/strong&gt; – Used for converting API JSON responses into Kotlin data classes. This factory uses the popular Gson library to handle the JSON parsing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. OkHttpClient&lt;/strong&gt; – Acts as the underlying HTTP client for Retrofit. It provides customization options for your network requests, such as timeout settings and interceptors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Logger&lt;/strong&gt; – This utility records log messages during runtime, making it easier to debug and trace the application’s behavior.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Query
import okhttp3.OkHttpClient
import java.util.concurrent.TimeUnit
import java.util.logging.Logger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Defining Data Models
&lt;/h2&gt;

&lt;p&gt;In this step, we create two Kotlin data classes that mirror the structure of the API response:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. LiveCurrencyResponse&lt;/strong&gt; – This class captures the complete response returned by the API. It includes a list of Quote objects, each representing a real-time forex quote.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Quote&lt;/strong&gt; – This class contains the detailed attributes for each currency rate, including:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a) Ask&lt;/strong&gt; – The selling price at which the currency is offered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;b) Bid&lt;/strong&gt; – The buying price that a trader is willing to pay.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;c) Mid&lt;/strong&gt; – The average of the bid and ask prices, representing the mid-market rate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;d) base_currency and quote_currency&lt;/strong&gt; – Indicate the pair of currencies being exchanged (e.g., USD as the base and EUR as the quote).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data class LiveCurrencyResponse(val quotes: List&amp;lt;Quote&amp;gt;)
data class Quote(val ask: Double, val bid: Double, val mid: Double, val base_currency: String, val quote_currency: String)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating the API Interface
&lt;/h3&gt;

&lt;p&gt;This interface outlines the API endpoints and the methods used to interact with them:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. &lt;a class="mentioned-user" href="https://dev.to/get"&gt;@get&lt;/a&gt;("live")&lt;/strong&gt; – This annotation indicates that the request is a GET call directed to the API’s “live” endpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. getLiveCurrencyData&lt;/strong&gt; – This method defines the necessary parameters for the GET request:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a) apiKey&lt;/strong&gt; – Your personal API key used for authenticating requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;b) currencyPair&lt;/strong&gt; – The specific currency pair you want data for (e.g., "USDEUR").&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt; The method returns a Call object, which represents an asynchronous request. When executed, it retrieves the response from the API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface LiveCurrencyApiService {
    @GET("live")
    fun getLiveCurrencyData(@Query("api_key") apiKey: String, @Query("currency") currencyPair: String): Call&amp;lt;LiveCurrencyResponse&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setting Up the Main Function
&lt;/h3&gt;

&lt;p&gt;The main function begins by creating an instance of the Logger to enable logging. Next, it defines the API key and specifies the currency pair to be tracked—here, USD to EUR. This configuration is essential, as these values are required to perform the API call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fun main() {
    val logger = Logger.getLogger("TraderMadeLogger")
    // Replace your API key
    val apiKey = "API_KEY"
    val baseCurrency = "USD"
    val quoteCurrency = "EUR"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuring OkHttpClient
&lt;/h3&gt;

&lt;p&gt;In this step, we set up the OkHttpClient with specific timeout configurations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Connect Timeout&lt;/strong&gt; – Specifies the maximum time the client will wait while attempting to establish a connection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Write Timeout&lt;/strong&gt; – Specifies the maximum duration allowed for sending data to the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Read Timeout&lt;/strong&gt; – Sets the limit for how long the client will wait to receive a response from the server.&lt;/p&gt;

&lt;p&gt;These configurations help prevent the application from freezing and allow it to handle network delays or failures more effectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// OkHttpClient setup
    val client = OkHttpClient.Builder()
        .connectTimeout(10, TimeUnit.SECONDS)
        .writeTimeout(10, TimeUnit.SECONDS)
        .readTimeout(30, TimeUnit.SECONDS)
        .build()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuring Retrofit
&lt;/h3&gt;

&lt;p&gt;Next, we set up Retrofit:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1) baseUrl:&lt;/strong&gt; This is the base URL of the API you're working with. In this case, it's the TraderMade API. Note that this URL directs you to the endpoint where you can access live currency data; however, you can modify the URL to access other services, such as currency conversions or forex historical data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2) Client:&lt;/strong&gt; The OkHttpClient instance was configured earlier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3) addConverterFactory:&lt;/strong&gt; We add the GsonConverterFactory to handle JSON-to-Kotlin object conversion.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Retrofit setup
    val retrofit = Retrofit.Builder()
        .baseUrl("https://marketdata.tradermade.com/api/v1/")
        .client(client)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Making the API Request
&lt;/h3&gt;

&lt;p&gt;At this stage. We need to perform an API call to retrieve data:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create&lt;/strong&gt; – An instance of LiveCurrencyApiService is initialized using the configured Retrofit object.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. getLiveCurrencyData&lt;/strong&gt; – This method is invoked with the API key and desired currency pair as arguments. It returns a Call object representing the pending request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Execute&lt;/strong&gt; – The execute function sends a synchronous request to the API. The Logger is used to monitor and log the request's progress for better visibility and debugging.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Fetch live currency data
    val liveCurrencyService = retrofit.create(LiveCurrencyApiService::class.java)
    val liveCurrencyCall = liveCurrencyService.getLiveCurrencyData(apiKey, "$baseCurrency$quoteCurrency")
    logger.info("Starting live currency request...")
    val liveCurrencyResponse = liveCurrencyCall.execute()
    logger.info("Live currency request finished.")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Handling the Response
&lt;/h3&gt;

&lt;p&gt;Once the API call completes, the response is processed as follows:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. isSuccessful&lt;/strong&gt; – Verifies whether the request was completed successfully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Quote&lt;/strong&gt; – If the response is valid, the first Quote object from the returned list is retrieved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. resultText&lt;/strong&gt; – The details of the quote, including ask, bid, and mid prices, are displayed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Error Handling&lt;/strong&gt; – If no quote is available or the request fails, informative messages are printed to indicate the issue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (liveCurrencyResponse.isSuccessful) {
        val quote = liveCurrencyResponse.body()?.quotes?.firstOrNull()
        if (quote != null) {
            val resultText = "Ask: ${quote.ask}\nBid: ${quote.bid}\nMid: ${quote.mid}"
            println(resultText)
        } else {
            println("No quotes found.")
        }
    } else {
        println("Live currency request failed with code: ${liveCurrencyResponse.code()}")
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cleaning Up
&lt;/h3&gt;

&lt;p&gt;To ensure efficient resource management and avoid memory leaks, the OkHttpClient is properly closed:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. shutdown&lt;/strong&gt; – Terminates the executor service responsible for handling network operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Evict All&lt;/strong&gt; – Clears all unused or idle connections from the connection pool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Logger&lt;/strong&gt; – Logs the end of the program, indicating that execution has completed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;client.dispatcher.executorService.shutdown()
    client.connectionPool.evictAll()
    logger.info("Program finished.")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
In this Kotlin tutorial, we demonstrated how to work with the live currency data endpoint using the base URL &lt;a href="https://marketdata.tradermade.com/api/v1/" rel="noopener noreferrer"&gt;https://marketdata.tradermade.com/api/v1/&lt;/a&gt;. TraderMade, however, provides various other endpoints that can be accessed by adjusting the URL. For instance, you can retrieve historical exchange rates or perform currency conversions by modifying the endpoint path accordingly. Check TraderMade's &lt;a href="https://tradermade.com/docs/restful-api" rel="noopener noreferrer"&gt;Data Documentation&lt;/a&gt; to explore API endpoints and other details.&lt;/p&gt;
&lt;h3&gt;
  
  
  Compiling the Kotlin Code
&lt;/h3&gt;

&lt;p&gt;To convert your Kotlin source file (Realtime.kt) into bytecode executable by the Java Virtual Machine (JVM), use the following command:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. kotlinc&lt;/strong&gt; – This is the Kotlin compiler that transforms your Kotlin code into Java-compatible bytecode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. -cp&lt;/strong&gt; – Short for "classpath," this option tells the compiler where to locate any external libraries your project depends on. Here, it includes multiple JAR files stored in the libs/ directory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. -d out&lt;/strong&gt; – Specifies the output directory for the compiled bytecode. The compiled files will be saved to the out folder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. src/Realtime.kt&lt;/strong&gt; – This indicates the file path to your Kotlin source code, which in this case is located in the src directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kotlinc -cp "libs/okio-jvm-3.9.0.jar;libs/retrofit-2.11.0.jar;libs/converter-gson-2.11.0.jar;libs/okhttp-4.12.0.jar;libs/okhttp-urlconnection-4.12.0.jar;libs/gson-2.11.0.jar;libs/annotations-24.1.0.jar;libs/kotlin-stdlib-2.0.0.jar" -d out src/Realtime.kt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running the Compiled Kotlin Code
&lt;/h3&gt;

&lt;p&gt;To execute the compiled Kotlin application, use the following command, which runs the program through the Java Virtual Machine (JVM):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Java&lt;/strong&gt; – This command launches the Java Virtual Machine (JVM) and runs the specified class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. -cp "out; libs/..."&lt;/strong&gt; – The -cp option sets the classpath, pointing to both the out directory (where compiled classes are stored) and the libs/ directory (containing required external libraries), so the JVM knows where to locate all dependencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. com.api.RealtimeKt&lt;/strong&gt; – This refers to the fully qualified name of the class containing the main function. Kotlin appends Kt to the class name when compiling, so Realtime.kt becomes RealtimeKt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;java -cp "out;libs/okio-jvm-3.9.0.jar;libs/retrofit-2.11.0.jar;libs/converter-gson-2.11.0.jar;libs/okhttp-4.12.0.jar;libs/okhttp-urlconnection-4.12.0.jar;libs/gson-2.11.0.jar;libs/annotations-24.1.0.jar;libs/kotlin-stdlib-2.0.0.jar" com.api.RealtimeKt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Putting It All Together
&lt;/h2&gt;

&lt;p&gt;These commands work in sequence: the first compiles your Kotlin source code into JVM-compatible bytecode while linking the necessary JAR files, and the second runs the compiled program, utilizing those same dependencies at runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Output
&lt;/h3&gt;

&lt;p&gt;Below is the resulting output from running the program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Aug 09, 2024 4:04:10 PM com.api.RealtimeKt main
INFO: Starting live currency request...
Aug 09, 2024 4:04:12 PM com.api.RealtimeKt main
INFO: Live currency request finished.
Ask: 0.9155665
Bid: 0.9155581
Mid: 0.9155581
Aug 09, 2024 4:04:12 PM com.api.RealtimeKt main
INFO: Program finished.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You’ve now completed the journey of using Kotlin to connect with the TraderMade API. This tutorial has provided you with the essential skills to access and utilize live forex data—a vital capability for developing modern financial software.&lt;/p&gt;

&lt;p&gt;The same approach can be extended to support currency conversion and historical exchange rate features, giving you a versatile and scalable setup. As you continue building on this foundation, you’ll be well-equipped to develop more interactive and finance-focused applications.&lt;br&gt;
If you need help or have any questions, please don't hesitate to reach out to us via our live chat or email support.&lt;/p&gt;

&lt;p&gt;Please refer to the original tutorial published on our website: &lt;a href="https://tradermade.com/tutorials/a-kotlin-tutorial-to-fetch-market-data" rel="noopener noreferrer"&gt;A Kotlin Tutorial to Fetch Market Data&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlintutorial</category>
      <category>forexdata</category>
      <category>mobileapp</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Access The Latest Gold And Silver Prices With The Precious Metals API</title>
      <dc:creator>Shridhar G Vatharkar</dc:creator>
      <pubDate>Wed, 04 Jun 2025 12:20:14 +0000</pubDate>
      <link>https://forem.com/shridhargv/access-the-latest-gold-and-silver-prices-with-the-precious-metals-api-16g1</link>
      <guid>https://forem.com/shridhargv/access-the-latest-gold-and-silver-prices-with-the-precious-metals-api-16g1</guid>
      <description>&lt;p&gt;In today's ever-changing financial landscape, understanding the current prices of precious metals is essential for everyone, from investors to software developers and hobbyists alike. This guide will teach you how to retrieve gold and silver prices using the precious metals API. &lt;/p&gt;

&lt;p&gt;This tutorial provides you with the resources to obtain accurate, up-to-the-minute information, regardless of your level of experience. It thoroughly explains how to get spot prices for precious metals data through TraderMade's REST API using various programming languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Precious Metals Data Matters
&lt;/h2&gt;

&lt;p&gt;For hundreds of years, gold, silver, and other precious metals have been highly valued because they are rare and possess inherent worth. Precise pricing information for these metals is essential for making decisions in investment, manufacturing, jewelry, and financial analysis. Knowing how to retrieve and interpret data from the Precious Metals Prices API is necessary for informed decisions in these fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methods to Receive Real-Time Financial Data
&lt;/h2&gt;

&lt;h3&gt;
  
  
  APIs
&lt;/h3&gt;

&lt;p&gt;What is an API? An Application Programming Interface (API) enables you to obtain current financial data from various platforms programmatically.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sign Up:&lt;/strong&gt; To obtain an API key, you must &lt;a href="https://tradermade.com/signup" rel="noopener noreferrer"&gt;register&lt;/a&gt; on the provider's website. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Choose a Plan:&lt;/strong&gt; Pick a free or paid &lt;a href="https://tradermade.com/pricing" rel="noopener noreferrer"&gt;subscription&lt;/a&gt; that fits your data requirements. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Access Data:&lt;/strong&gt; Then, use your API key to request the data with your chosen programming language, such as Python or JavaScript.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;

&lt;p&gt;This Python code uses the requests library to fetch real-time Gold prices from an API. The same request also retrieves Silver and Platinum prices, as demonstrated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import requests
from pprint import PrettyPrinter

url = "https://marketdata.tradermade.com/api/v1/live"
currency = "XAUUSD,XAGUSD,XPTUSD,XPDUSD"
api_key = "API_KEY"  # Replace with your actual API key
querystring = {"currency": currency, "api_key": api_key}

response = requests.get(url, params=querystring)

# Check if the request was successful
if response.status_code == 200:
    pp = PrettyPrinter()
    pp.pprint(response.json())
else:
    print(f"Error {response.status_code}: {response.text}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Java Programming
&lt;/h3&gt;

&lt;p&gt;This Java program uses an HTTP GET request to get the Gold price data from the API. You can also expand it to fetch silver and other live precious metal prices. The "FetchMarketData" class sets up the API's URL and necessary parameters, like currency codes and the API key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;

import org.json.JSONArray;
import org.json.JSONObject;

public class RESTClient {

    public static void main(String[] args) throws IOException {

        CloseableHttpClient httpClient = HttpClients.createDefault();

        try {

            HttpGet request = new HttpGet("https://marketdata.tradermade.com/api/v1/live
currency=XAUUSD&amp;amp;api_key=YOUR_API_KEY");
            CloseableHttpResponse response = httpClient.execute(request);
            try {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    // return it as a String
                    String result = EntityUtils.toString(entity);
                    System.out.println(result);
                    JSONObject obj = new JSONObject(result);
                    JSONArray quotes = obj.getJSONArray("quotes");
                    System.out.println(quotes.toString());

                    for (int i = 0; i &amp;lt; quotes.length(); i++) {
                        JSONObject quote = quotes.getJSONObject(i);
                        System.out.println(" Quote " + quote.getString("base_currency") +
quote.getString("quote_currency") + " " + quote.getFloat("bid") + " " + quote.getFloat("ask"));
                    }

                }

            } finally {
                response.close();
            }
        } finally {
            httpClient.close();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Node.js Programming
&lt;/h3&gt;

&lt;p&gt;This Node.js script uses the Axios library to get real-time Gold price data from the live API endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const axios = require('axios');
const util = require('util');

const url = "https://marketdata.tradermade.com/api/v1/live";
const currency = "XAUUSD";
const apiKey = "API_KEY";  // Replace with your actual API key

async function fetchMarketData() {

    try {
        const response = await axios.get(url, {
            params: {
                currency: currency,
                api_key: apiKey
            }
        });

        if (response.status === 200) {
                console.log(util.inspect(response.data, { depth: null, colors: true }));
            } else {
                  console.log("Error");
              }

          } catch (error) {
              console.error("Error");
          }

      }

      fetchMarketData();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  C++ Programming
&lt;/h3&gt;

&lt;p&gt;This C++ code snippet demonstrates how to get Gold prices from the live API endpoint using the libcurl library. The code starts by including the essential libcurl functions and standard input/output headers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#include &amp;lt;curl/curl.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;

int main(void)
{
    CURL *curl;
    CURLcode res;

    // URL to be requested

    const char *url = "https://marketdata.tradermade.com/api/v1/live?currency=XAUUSD&amp;amp;api_key=API_KEY";

    // Initialize global curl environment
    curl_global_init(CURL_GLOBAL_DEFAULT);

    // Initialize curl session
    curl = curl_easy_init();

    if(curl) {

        // Set URL
        curl_easy_setopt(curl, CURLOPT_URL, url);

        // Perform the request
        res = curl_easy_perform(curl);

        // Check for errors
        if(res != CURLE_OK) {

            fprintf(stderr, "Request failed: %s
", curl_easy_strerror(res));
        } else {
            printf("Request was successful!
");
        }


        // Cleanup curl session
        curl_easy_cleanup(curl);
    }

    // Cleanup curl global environment
    curl_global_cleanup();

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This tutorial explains how to access and use precious metals data from a JSON API using various programming languages. By using these methods, you can easily add live market data for Gold, Silver, Platinum, and Palladium prices into your applications and workflows. &lt;/p&gt;

&lt;p&gt;For more examples in other programming languages and information on live and historical rates for world currencies, check our &lt;a href="https://tradermade.com/docs/restful-api" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; page.&lt;/p&gt;

&lt;p&gt;Also, follow our original tutorial published on our website: &lt;a href="https://tradermade.com/tutorials/get-live-gold-silver-prices-instantly-with-precious-metals-api" rel="noopener noreferrer"&gt;Get Live Gold and Silver Prices Instantly with Precious Metals API&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can explore more by reading the blog: &lt;a href="https://tradermade.com/blog/how-the-gold-and-silver-prices-are-determined" rel="noopener noreferrer"&gt;How the Gold and Silver Prices Are Determined&lt;/a&gt;&lt;/p&gt;

</description>
      <category>metalsapi</category>
      <category>cfddata</category>
      <category>cfdapi</category>
      <category>goldsilverdata</category>
    </item>
    <item>
      <title>Integrating Market Data into Your Go Applications with TraderMade's SDK</title>
      <dc:creator>Shridhar G Vatharkar</dc:creator>
      <pubDate>Thu, 22 May 2025 16:27:49 +0000</pubDate>
      <link>https://forem.com/shridhargv/integrating-market-data-into-your-go-applications-with-tradermades-sdk-4m2b</link>
      <guid>https://forem.com/shridhargv/integrating-market-data-into-your-go-applications-with-tradermades-sdk-4m2b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Learn how to fetch real-time and historical market data in Go using TraderMade's easy-to-use SDK.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you're a Go developer aiming to integrate real-time or historical market data into your applications, TraderMade's Go SDK offers a streamlined solution. Whether you're building trading tools, analytics dashboards, or financial applications, this SDK simplifies access to Forex, cryptocurrency, precious metals, and CFD data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;First, use Go version 1.21 or higher to support modules. Then, retrieve the TraderMade Go SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go get github.com/tradermade/Go-SDK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After obtaining the SDK, initialize the REST client with your API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import (
    tradermade "github.com/tradermade/Go-SDK/rest"
)

client := tradermade.NewRESTClient("YOUR_API_KEY")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can acquire your API key by &lt;a href="https://tradermade.com/signup" rel="noopener noreferrer"&gt;signing up&lt;/a&gt; on the TraderMade website.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetching Live Forex Rates
&lt;/h2&gt;

&lt;p&gt;To retrieve live rates for specific currency pairs, such as EUR/USD and Gold (XAU/USD):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;currencyPairs := []string{"EURUSD", "XAUUSD"}
liveRates, err := client.GetLiveRates(currencyPairs)
if err != nil {
    log.Fatalf("Error fetching live rates: %v", err)
}

for _, quote := range liveRates.Quotes {
    fmt.Printf("Base: %s, Quote: %s, Bid: %f, Ask: %f, Mid: %f\n",
        quote.BaseCurrency, quote.QuoteCurrency, quote.Bid, quote.Ask, quote.Mid)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code initializes the REST client, defines the desired currency pairs, fetches their live rates, and prints out the base currency, quote currency, bid, ask, and mid prices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performing Currency Conversion
&lt;/h2&gt;

&lt;p&gt;To convert an amount from one currency to another in real-time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;convertResult, err := client.ConvertCurrency("EUR", "GBP", 1000.0)
if err != nil {
    log.Fatalf("Error fetching conversion data: %v", err)
}

fmt.Printf("Converted %s to %s:\n", convertResult.BaseCurrency, convertResult.QuoteCurrency)
fmt.Printf("Quote: %f\n", convertResult.Quote)
fmt.Printf("Total: %f\n", convertResult.Total)
fmt.Printf("Requested Time: %s\n", convertResult.RequestedTime)
fmt.Printf("Timestamp: %d\n", convertResult.Timestamp)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This snippet converts 1,000 EUR to GBP, displaying the conversion rate, total amount, request time, and timestamp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieving Hourly Time Series Data
&lt;/h2&gt;

&lt;p&gt;For historical analysis or charting, you might need time series data. Here's how to fetch hourly data for EUR/USD:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;timeSeriesDataHourly, err := client.GetTimeSeriesData("EURUSD", "2024-10-01 10:00", "2024-10-02 11:00", "hourly", 4)
if err != nil {
    log.Fatalf("Error fetching hourly time series data: %v", err)
}

for _, data := range timeSeriesDataHourly.TimeSeries {
    fmt.Printf("Time: %s, Open: %f, High: %f, Low: %f, Close: %f\n",
        data.Date, data.Open, data.High, data.Low, data.Close)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code fetches hourly data between October 1, 2024, 10:00 AM and October 2, 2024, 11:00 AM, printing out the open, high, low, and close prices for each hour.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Real-Time Forex Data with WebSocket
&lt;/h2&gt;

&lt;p&gt;WebSocket feeds are ideal for ultra-low-latency applications like trading terminals or automated bots. TraderMade supports WebSocket streaming for live updates.&lt;br&gt;
Here’s a quick example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "github.com/tradermade/Go-SDK/websocket"
)

func main() {
    ws := websocket.NewWebSocketClient("YOUR_API_KEY")
    ws.Connect()
    ws.Subscribe([]string{"EURUSD", "GBPUSD"})

    for msg := range ws.MessageChannel {
        fmt.Printf("Received tick: %v\n", msg)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function opens a WebSocket connection and allows you to subscribe to live updates for EUR/USD and GBP/USD. Each incoming tick is pushed to a channel for real-time processing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the WebSocket Client
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Initialize the WebSocket client with your API key and the currency pairs you wish to subscribe to.&lt;/li&gt;
&lt;li&gt;Configure connection settings, including automatic retries and reconnection behavior.&lt;/li&gt;
&lt;li&gt;Set up event handlers:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Connection Handler:&lt;/strong&gt; Triggered when the WebSocket successfully connects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;client.SetConnectedHandler(func(connectedMsg tradermadews.ConnectedMessage) {
    fmt.Printf("WebSocket connected: %s\n", connectedMsg.Message)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Quote Message Handler:&lt;/strong&gt; Processes incoming real-time market data such as bid/ask quotes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;client.SetMessageHandler(func(quote tradermadews.QuoteMessage, humanTimestamp string) {
    fmt.Printf("Received quote: Symbol=%s Bid=%.5f Ask=%.5f Timestamp=%s (Human-readable: %s)\n",
        quote.Symbol, quote.Bid, quote.Ask, quote.Ts, humanTimestamp)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Reconnection Handler:&lt;/strong&gt; Notifies you when the client is attempting to reconnect.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;client.SetReconnectionHandler(func(attempt int) {
    fmt.Printf("Reconnecting... (Attempt %d)\n", attempt)
})

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enable graceful shutdown on user interrupt (e.g., Ctrl+C).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
&amp;lt;-c
fmt.Println("Shutting down WebSocket client...")

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Connects to the WebSocket feed using secure credentials.&lt;/li&gt;
&lt;li&gt;Receives real-time updates for Forex, stock indices, and precious metals.&lt;/li&gt;
&lt;li&gt;Automatically handles disconnections and attempts to reconnect.&lt;/li&gt;
&lt;li&gt;Provides handlers for key lifecycle events: connection, message, and reconnection.&lt;/li&gt;
&lt;li&gt;Supports clean shutdowns for a robust and reliable client experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The WebSocket client is ideal for apps needing real-time FX market data with minimal latency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Resources
&lt;/h2&gt;

&lt;p&gt;TraderMade's Go SDK also supports fetching historical data, performing currency conversions, and retrieving time series data. For comprehensive details and advanced usage, refer to the &lt;a href="https://tradermade.com/docs/restful-api" rel="noopener noreferrer"&gt;TraderMade REST API Documentation&lt;/a&gt; and explore their &lt;a href="https://github.com/tradermade/Go-SDK" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By integrating TraderMade's Go SDK into your projects, you can efficiently access a wide range of financial data, enhancing the functionality and reliability of your applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;TraderMade’s Go SDK equips you with everything needed to tap into a world of financial data with minimal effort. From real-time streaming to historical insights and currency conversion, it's easily accessible through a clean, idiomatic Go interface.&lt;/p&gt;

&lt;p&gt;Please refer to the originally published tutorial on our website: &lt;a href="https://tradermade.com/tutorials/accessing-market-data-with-tradermade-s-go-library" rel="noopener noreferrer"&gt;Accessing Market Data with TraderMade's Go Library&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, go through the other Golang Tutorials:&lt;br&gt;
&lt;a href="https://tradermade.com/tutorials/how-to-write-your-first-golang-rest-client" rel="noopener noreferrer"&gt;Your First Golang REST API Client&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tradermade.com/tutorials/golang-websocket-client" rel="noopener noreferrer"&gt;Your First Golang WebSocket Client&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>tutorial</category>
      <category>sdk</category>
      <category>marketdata</category>
    </item>
    <item>
      <title>Using Python &amp; WebSockets to Generate Live OHLC Forex Data</title>
      <dc:creator>Shridhar G Vatharkar</dc:creator>
      <pubDate>Wed, 30 Apr 2025 12:03:24 +0000</pubDate>
      <link>https://forem.com/shridhargv/using-python-websockets-to-generate-live-ohlc-forex-data-1082</link>
      <guid>https://forem.com/shridhargv/using-python-websockets-to-generate-live-ohlc-forex-data-1082</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This tutorial guides you through building a real-time Forex OHLC data generator using Python and WebSockets. Learn how to stream FX prices, convert them to OHLC format, and save the results with clean, efficient code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Accessing real-time market data is essential for modern trading and financial analytics. WebSockets provide an efficient method for live, continuous data streaming. In this tutorial, we’ll walk through how to use Python to connect to a WebSocket stream, collect Forex pricing data, and convert it into OHLC (Open, High, Low, Close) bars.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You'll Need
&lt;/h2&gt;

&lt;p&gt;Before we start, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python installed on your machine.&lt;/li&gt;
&lt;li&gt;Basic understanding of how to use Python.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get Your API Key
&lt;/h2&gt;

&lt;p&gt;To stream live Forex data, you’ll need a TraderMade API key. &lt;a href="https://tradermade.com/signup" rel="noopener noreferrer"&gt;Sign up&lt;/a&gt; for a 14-day free trial and find your API key in your account dashboard. Refer to the platform's &lt;a href="https://tradermade.com/docs/streaming-data-api" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for helpful examples and guidance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Get Started
&lt;/h2&gt;

&lt;p&gt;We’ll be using the tradermade Python package to access live FX rates. The data will be processed into OHLC format and written to a text file in real-time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Install the TraderMade Package
&lt;/h3&gt;

&lt;p&gt;Install the required package using pip:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install tradermade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Import Required Libraries
&lt;/h3&gt;

&lt;p&gt;Begin by importing the modules needed to handle WebSocket streaming, manipulate data structures, and format time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from tradermade import stream
import json
from datetime import datetime
from collections import defaultdict
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Initialize Data Structures
&lt;/h3&gt;

&lt;p&gt;Prepare dictionaries and variables for managing OHLC values, tracking intervals, and defining output behaviour.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ohlc_data = defaultdict(lambda: defaultdict(lambda: {'open': 0, 'high': 0, 'low': 0, 'close': 0}))
previous_interval = None
count = 0
interval = 1
format = '%Y-%m-%d %H:%M'
output_file = 'ohlc_output.txt'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Define Utility Functions
&lt;/h3&gt;

&lt;p&gt;Now we’ll create three utility functions to handle time rounding, file writing, and updating OHLC values. Each function plays a specific role:&lt;/p&gt;

&lt;h4&gt;
  
  
  round_timestamp(timestamp, interval_minutes)
&lt;/h4&gt;

&lt;p&gt;This function rounds any incoming timestamp to the nearest defined time interval.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Useful for aligning price data into fixed OHLC intervals.&lt;/li&gt;
&lt;li&gt;Replaces seconds and microseconds, rounding down to the nearest minute block.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  save_to_file(data)
&lt;/h4&gt;

&lt;p&gt;Appends a string to the output text file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensures processed OHLC entries are saved for future use.&lt;/li&gt;
&lt;li&gt;Opens the file in append mode and writes the data with a space separator.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  update_ohlc_data(current_interval, currency, mid)
&lt;/h4&gt;

&lt;p&gt;Updates the OHLC values for each currency pair during the given interval.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If no data exists yet for the interval and currency, it initializes values with the current price.&lt;/li&gt;
&lt;li&gt;The 'open' is set at the start, and the 'high'/'low' are tracked as data flows in.&lt;/li&gt;
&lt;li&gt;The 'close' is updated every time new data is received in that interval.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def round_timestamp(timestamp, interval_minutes):
    rounded_minutes = (timestamp.minute // interval_minutes) * interval_minutes
    rounded_time = timestamp.replace(second=0, microsecond=0, minute=rounded_minutes)
    return rounded_time
def save_to_file(data):
    with open(output_file, 'a') as f:
        f.write(data + ' ')
def update_ohlc_data(current_interval, currency, mid):
    if current_interval not in ohlc_data:
        ohlc_data[current_interval] = defaultdict(lambda: {'open': mid, 'high': mid, 'low': mid, 'close': mid})
    elif currency not in ohlc_data[current_interval]:
        ohlc_data[current_interval][currency] = {'open': mid, 'high': mid, 'low': mid, 'close': mid}
    else:
        ohlc_data[current_interval][currency]['high'] = max(ohlc_data[current_interval][currency]['high'], mid)
        ohlc_data[current_interval][currency]['low'] = min(ohlc_data[current_interval][currency]['low'], mid)
        ohlc_data[current_interval][currency]['close'] = mid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Connect to the WebSocket Stream
&lt;/h3&gt;

&lt;p&gt;You’re now ready to initiate the WebSocket connection. Use your API key and specify the currency symbols you'd like to stream.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stream.set_ws_key("API_KEY")  # Replace with your actual API key
stream.set_symbols("USDJPY,EURGBP")
stream.stream_data(process_data)
stream.connect()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Run Your Script
&lt;/h3&gt;

&lt;p&gt;Finally, execute the script to start processing live data and generating OHLC output.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;After running the program, a file named ohlc_output.txt will appear in your working directory. It will contain a growing log of OHLC data points based on your specified interval.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You’ve just built a working solution for streaming live Forex data and transforming it into OHLC bars using Python and WebSockets. This setup can serve as a foundation for real-time dashboards, trading bots, or analytical tools.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Please refer to:&lt;br&gt;
The tutorial originally published on our website: &lt;a href="https://tradermade.com/tutorials/ohlc-python-websocket" rel="noopener noreferrer"&gt;Create Real-time OHLC Data with Python WebSocket&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, watch the video tutorial: &lt;a href="https://www.youtube.com/watch?v=jM0FbeTNJhw" rel="noopener noreferrer"&gt;Real-time FX Ticks to OHLC Bars With Python&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>websockets</category>
      <category>ohlcdata</category>
      <category>realtimedata</category>
    </item>
    <item>
      <title>Converting Real-Time Forex Data to OHLC Bars Using PHP</title>
      <dc:creator>Shridhar G Vatharkar</dc:creator>
      <pubDate>Tue, 25 Mar 2025 11:01:09 +0000</pubDate>
      <link>https://forem.com/shridhargv/converting-real-time-forex-data-to-ohlc-bars-using-php-1p81</link>
      <guid>https://forem.com/shridhargv/converting-real-time-forex-data-to-ohlc-bars-using-php-1p81</guid>
      <description>&lt;p&gt;Ever wanted to handle real-time data using WebSockets? WebSockets allow seamless live data streaming, making them perfect for applications like Forex trading.&lt;/p&gt;

&lt;p&gt;This guide'll capture real-time Forex data using a WebSocket connection and transform it into minute-by-minute Open, High, Low, and Close (OHLC) bars. These bars provide valuable insights for traders and analysts tracking short-term market trends.&lt;/p&gt;

&lt;p&gt;Even if you're new to PHP, don’t worry! We'll take it step by step. &lt;br&gt;
Please take a look at &lt;a href="https://tradermade.com/docs/streaming-data-api" rel="noopener noreferrer"&gt;WebSockets Documentation&lt;/a&gt; for details on usage and integration.&lt;/p&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting Up Your Environment
&lt;/h3&gt;

&lt;p&gt;Before we get into the coding, let’s ensure our setup is ready.&lt;br&gt;
Check PHP Installation: Open a terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php -version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If PHP isn’t installed, download and install it from the official PHP website.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Get a WebSocket API Key:&lt;/strong&gt; Sign up for a &lt;a href="https://tradermade.com/tutorials/how-to-start-a-websocket-trial-and-subscription-plan" rel="noopener noreferrer"&gt;free 14-day WebSocket trial&lt;/a&gt; via your TraderMade dashboard.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install Composer (PHP Dependency Manager):&lt;/strong&gt; Navigate to your project folder and install the WebSocket library:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require textalk/websocket
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating the WebSocket Client in PHP
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Include Dependencies
&lt;/h3&gt;

&lt;p&gt;First, include Composer's autoload file to manage dependencies efficiently:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;require_once("vendor/autoload.php");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Establish WebSocket Connection
&lt;/h3&gt;

&lt;p&gt;We need to connect to the WebSocket server. This function handles the connection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function connectWebSocket() {
    try {
        $client = new WebSocketClient("wss://marketdata.tradermade.com/feedadv");

        $message = $client-&amp;gt;receive();
        echo $message;

        $client-&amp;gt;text("{\"userKey\":\"api_key\", \"symbol\":\"GBPUSD,EURUSD\"}");

        return $client;
    } catch (WebSocketTimeoutException $e) {
        echo "WebSocket timeout. Reconnecting...\n";
        sleep(5);
        return connectWebSocket();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connects to the WebSocket server.&lt;/li&gt;
&lt;li&gt;Requests real-time data for specific currency pairs.&lt;/li&gt;
&lt;li&gt;Implements auto-reconnection in case of timeouts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Receive and Process WebSocket Data
&lt;/h3&gt;

&lt;p&gt;Once connected, we listen for price updates and store them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$client = connectWebSocket();
$dataArray = [];

while (true) {
    try {
        $message = $client-&amp;gt;receive();

        if ($message !== "connected") {
            $decoded_json = json_decode($message, true);

            $bid = $decoded_json['bid'] ?? null;
            $ask = $decoded_json['ask'] ?? null;

            if ($bid !== null &amp;amp;&amp;amp; $ask !== null) {
                $mid = ($bid + $ask) / 2;

                echo "{$decoded_json['symbol']} {$decoded_json['ts']} $bid $ask $mid\n";

                $dataArray[] = [
                    'symbol' =&amp;gt; $decoded_json['symbol'],
                    'ts' =&amp;gt; $decoded_json['ts'],
                    'bid' =&amp;gt; $bid,
                    'ask' =&amp;gt; $ask,
                    'mid' =&amp;gt; $mid
                ];

                file_put_contents('websocket_data.json', json_encode($dataArray, JSON_PRETTY_PRINT));
            }
        }
    } catch (WebSocketTimeoutException $e) {
        echo "Timeout. Reconnecting...\n";
        sleep(5);
        $client = connectWebSocket();
    } catch (Exception $e) {
        echo "Error: " . $e-&amp;gt;getMessage();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reads live Forex data.&lt;/li&gt;
&lt;li&gt;Extracts bid and ask prices.&lt;/li&gt;
&lt;li&gt;Saves data into websocket_data.json.&lt;/li&gt;
&lt;li&gt;Handles errors and automatically reconnects if necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Load Data from JSON File
&lt;/h3&gt;

&lt;p&gt;Before processing, we ensure our file has valid data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$jsonFilePath = 'websocket_data.json';
$jsonData = file_get_contents($jsonFilePath);
$forexData = json_decode($jsonData, true);

if (empty($forexData)) {
    echo json_encode(["error" =&amp;gt; "No data found in $jsonFilePath"]);
    exit;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Convert Raw Data to OHLC Bars
&lt;/h3&gt;

&lt;p&gt;Now, let’s transform the tick data into minute-based OHLC bars:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$interval = 60;
$ohlcData = [];

foreach ($forexData as $data) {
    $timestamp = strtotime($data['ts']);
    $roundedTimestamp = floor(($timestamp + (5 * 3600) + (30 * 60)) / $interval) * $interval;

    if (!isset($ohlcData[$roundedTimestamp])) {
        $ohlcData[$roundedTimestamp] = [
            'timestamp' =&amp;gt; $roundedTimestamp + (5 * 3600) + (30 * 60),
            'low' =&amp;gt; $data['bid'],
            'high' =&amp;gt; $data['bid'],
            'open' =&amp;gt; $data['bid'],
            'close' =&amp;gt; $data['bid']
        ];
    } else {
        $ohlcData[$roundedTimestamp]['low'] = min($ohlcData[$roundedTimestamp]['low'], $data['bid']);
        $ohlcData[$roundedTimestamp]['high'] = max($ohlcData[$roundedTimestamp]['high'], $data['bid']);
        $ohlcData[$roundedTimestamp]['close'] = $data['bid'];
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rounds timestamps to the nearest minute.&lt;/li&gt;
&lt;li&gt;Generates OHLC bars for each minute.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 6: Save OHLC Data to JSON
&lt;/h3&gt;

&lt;p&gt;Finally, we store the OHLC bars:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$jsonFilePathOutput = 'ohlc_data.json';

if (!file_put_contents($jsonFilePathOutput, json_encode(array_values($ohlcData), JSON_PRETTY_PRINT))) {
    echo json_encode(["error" =&amp;gt; "Failed to write OHLC data"]);
    exit;
}

echo json_encode(["success" =&amp;gt; "OHLC data saved to $jsonFilePathOutput"]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running the Script
&lt;/h3&gt;

&lt;p&gt;To execute, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php webSocket_client.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your script will now fetch live Forex data and convert it into OHLC bars. 🚀&lt;/p&gt;

&lt;h3&gt;
  
  
  Sample Outputs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Raw Forex Data:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
    {"symbol": "GBPUSD", "ts": "1712130980714", "bid": 1.25664, "ask": 1.25668},
    {"symbol": "EURUSD", "ts": "1712130982178", "bid": 1.07712, "ask": 1.07712}
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;OHLC Data Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
    {"timestamp": "1970-01-01 05:30:00", "open": 1.25664, "high": 1.25665, "low": 1.25664, "close": 1.25665}
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conclusion&lt;br&gt;
Congratulations! You’ve successfully streamed real-time Forex data and transformed it into OHLC bars. Try tweaking the script and adding new features. Happy coding! 🎉&lt;/p&gt;

</description>
      <category>php</category>
      <category>websockets</category>
      <category>ohlcdata</category>
      <category>realtimedata</category>
    </item>
    <item>
      <title>Effortlessly Calculate 100+ Technical Indicators in Python – A Quick Guide</title>
      <dc:creator>Shridhar G Vatharkar</dc:creator>
      <pubDate>Mon, 03 Mar 2025 14:29:01 +0000</pubDate>
      <link>https://forem.com/shridhargv/effortlessly-calculate-100-technical-indicators-in-python-a-quick-guide-dk0</link>
      <guid>https://forem.com/shridhargv/effortlessly-calculate-100-technical-indicators-in-python-a-quick-guide-dk0</guid>
      <description>&lt;p&gt;Technical indicators are essential for detailed market analysis and data-driven decision-making. This tutorial will walk you through retrieving historical forex data using the TraderMade API and computing key technical indicators with the Python TA-Lib library. By the end, you will have the necessary tools to integrate these indicators into your applications, platforms, and trading systems.&lt;/p&gt;

&lt;p&gt;Our API provides real-time data on a wide range of tradable assets, including over 32 US stocks, 10 significant indices, precious metals, and access to more than 100 currencies (explore &lt;a href="https://tradermade.com/live-currencies-list" rel="noopener noreferrer"&gt;currencies&lt;/a&gt; &amp;amp; &lt;a href="https://tradermade.com/cfd-list" rel="noopener noreferrer"&gt;CFDs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Before proceeding, it is essential to install the TA-Lib library. Since pip often fails to build this library on specific systems, mainly Windows, we will demonstrate an alternative method using a wheel file.&lt;/p&gt;

&lt;p&gt;Linux users should refer to the official &lt;a href="https://github.com/TA-Lib/ta-lib-python?tab=readme-ov-file" rel="noopener noreferrer"&gt;TA-Lib library&lt;/a&gt;. Windows users should visit the TA-Lib Windows wheel page, download the appropriate wheel file based on their Python version and system architecture (32-bit or 64-bit), and ensure that pip is executed from the exact location as the downloaded file.&lt;/p&gt;

&lt;p&gt;In the example below, we have downloaded a wheel file compatible with 64-bit computers running Python 3.10. Thus, the following download method is recommended:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install requests pandas 
pip install TA_Lib-0.4.32-cp310-cp310-win_amd64.whl

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qcmohml84towq7beevp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qcmohml84towq7beevp.jpg" alt="Image description" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After installing the library, register with TraderMade to get your &lt;a href="https://www.tradermade.com/signup" rel="noopener noreferrer"&gt;free Forex API key&lt;/a&gt;. Next, install TraderMade for seamless integration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install tradermade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Detailed Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Import Required Libraries
&lt;/h3&gt;

&lt;p&gt;Start by importing the essential data retrieval, processing, and analysis libraries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import talib
import tradermade as tm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Configure Your API Key
&lt;/h3&gt;

&lt;p&gt;Insert your TraderMade API key to enable authentication.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Replace Your TraderMade API key
tm.set_rest_api_key("api_key")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Define a Function to Retrieve Market Data
&lt;/h3&gt;

&lt;p&gt;Develop a function to fetch historical forex data for a selected currency pair over a specified date range.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tm.timeseries(currency='EURUSD', start="2024-08-05",end="2024-11-04",interval="daily",fields=["open", "high", "low","close"]) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Compute Essential Technical Indicators
&lt;/h3&gt;

&lt;p&gt;TA-Lib offers numerous indicators, including candlestick pattern recognition. Below are some key technical indicators widely used by traders:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simple Moving Average (SMA)&lt;/strong&gt;&lt;br&gt;
Smooths price data over a defined period (e.g., 20 days) to identify trends.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Relative Strength Index (RSI)&lt;/strong&gt;&lt;br&gt;
A momentum oscillator that measures the speed and change of price movements, helping to detect overbought or oversold conditions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Moving Average Convergence Divergence (MACD)&lt;/strong&gt;&lt;br&gt;
Analyzes the relationship between two moving averages of a financial instrument, aiding in spotting potential market momentum shifts and generating buy/sell signals.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Calculate technical indicators using TA-Lib
df['SMA_20'] = talib.SMA(df['close'], timeperiod=20) # 20-period Simple Moving Average

df['RSI_14'] = talib.RSI(df['close'], timeperiod=14) # 14-period Relative Strength Index
df['MACD'], df['MACD_signal'], df['MACD_hist'] = talib.MACD(df['close'],
                                                                  fastperiod=12,
                                                                  slowperiod=26,
                                                                  signalperiod=9)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: View the Results
&lt;/h3&gt;

&lt;p&gt;Finally, the last few rows of the DataFrame will be displayed to examine the OHLC data alongside the computed indicators.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;df = df.set_index("date")
df = df.dropna()
print(df.head())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              open     high      low    close    SMA_20     RSI_14      MACD  MACD_signal  MACD_hist

date
2024-09-19  1.11172  1.11790  1.10686  1.11621  1.109625  62.318384  0.003357     0.003439  -0.000083
2024-09-20  1.11626  1.11820  1.11362  1.11631  1.109472  62.410940  0.003576     0.003467   0.000109
2024-09-23  1.11646  1.11674  1.10834  1.11114  1.109223  54.902623  0.003295     0.003432  -0.000138
2024-09-24  1.11114  1.11811  1.11036  1.11797  1.109199  61.493338  0.003582     0.003462   0.000119
2024-09-25  1.11799  1.12141  1.11217  1.11329  1.109263  55.507279  0.003392     0.003448  -0.000056
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Complete Code
&lt;/h2&gt;

&lt;p&gt;Below is the full implementation—review it carefully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Display the data with indicators

import talib
import tradermade as tm

tm.set_rest_api_key("api_key")

df = tm.timeseries(currency='EURUSD', start="2024-08-05",end="2024-11-04",interval="daily",fields=["open", "high", "low","close"])

df['SMA_20'] = talib.SMA(df['close'], timeperiod=20) # 20-period Simple Moving Average

df['RSI_14'] = talib.RSI(df['close'], timeperiod=14) # 14-period Relative Strength Index
df['MACD'], df['MACD_signal'], df['MACD_hist'] = talib.MACD(df['close'],
                                                                  fastperiod=12,
                                                                  slowperiod=26,
                                                                  signalperiod=9)

df = df.set_index("date")
df = df.dropna()
print(df.head())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;This tutorial demonstrated how to retrieve historical forex data using the TraderMade SDK and compute key technical indicators such as SMA, RSI, and MACD with the TA-Lib library. However, this is just the beginning—TA-Lib offers over 100 indicators, including candlestick patterns, applicable to various markets.&lt;/p&gt;

&lt;p&gt;If you found this guide helpful, share our tutorials or reference them in your blogs. Don't hesitate to reach out for any questions or assistance with TA-Lib installation. Happy coding!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Also, please review the tutorial initially published on our website: &lt;a href="https://tradermade.com/tutorials/calculate-technical-indicators-in-python-with-ta-lib" rel="noopener noreferrer"&gt;100+ Technical Indicators in Python&lt;/a&gt;.&lt;br&gt;
Here is a tutorial video: &lt;a href="https://youtu.be/YFIvFYN19eo?feature=shared" rel="noopener noreferrer"&gt;Technical Indicators in Python Video Tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>python</category>
      <category>techindicators</category>
      <category>forex</category>
      <category>techtutorial</category>
    </item>
    <item>
      <title>The Future of Forex Trading: AI and Real-Time Data Integration</title>
      <dc:creator>Shridhar G Vatharkar</dc:creator>
      <pubDate>Fri, 21 Feb 2025 10:05:48 +0000</pubDate>
      <link>https://forem.com/shridhargv/the-future-of-forex-trading-ai-and-real-time-data-integration-h06</link>
      <guid>https://forem.com/shridhargv/the-future-of-forex-trading-ai-and-real-time-data-integration-h06</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Discover how AI &amp;amp; real-time data are revolutionizing forex trading. Learn the benefits of Forex APIs for better trading performance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the dynamic world of forex trading, staying ahead requires more than traditional strategies. Integrating Artificial Intelligence (AI) and real-time data has emerged as a game-changer, offering traders unprecedented insights and execution capabilities. &lt;/p&gt;

&lt;p&gt;Central to this evolution is using Forex APIs from reputable data vendors, which significantly enhance the performance of real-time trading applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rise of AI in Forex Trading
&lt;/h2&gt;

&lt;p&gt;AI has revolutionized many industries, including forex trading. It analyzes massive datasets to detect patterns and trends that human traders might overlook. This ability enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Predictive Analysis:&lt;/strong&gt; AI models forecast currency movements based on historical data and market indicators, enabling traders to make informed decisions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automated Trading:&lt;/strong&gt; AI-driven systems can execute trades autonomously, responding to millisecond market changes, which is crucial in the fast-paced forex environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Risk Management:&lt;/strong&gt; AI assesses potential risks by evaluating market volatility and other factors, helping traders mitigate potential losses.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Importance of Real-Time Data
&lt;/h2&gt;

&lt;p&gt;In forex trading, timing is everything. Access to real-time data ensures that traders have the most current information, allowing them to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;React Swiftly:&lt;/strong&gt; Immediate data access enables prompt responses to market shifts, capitalizing on opportunities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhance Accuracy:&lt;/strong&gt; &lt;a href="https://tradermade.com/forex-data-feed" rel="noopener noreferrer"&gt;Real-time forex data&lt;/a&gt; reduces the lag between market events and trader reactions, leading to more precise trading decisions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improve Strategy Testing:&lt;/strong&gt; Traders can &lt;a href="https://tradermade.com/tutorials/backtest-like-a-pro-with-a-forex-api" rel="noopener noreferrer"&gt;backtest strategies&lt;/a&gt; against live data, refining their approaches for better outcomes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Leveraging Forex APIs for Enhanced Performance
&lt;/h2&gt;

&lt;p&gt;Forex Application Programming Interfaces (APIs) bridge trading platforms and data sources. By integrating Forex APIs from reputable data vendors, developers and analysts can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Access Comprehensive Data:&lt;/strong&gt; Reliable APIs provide extensive historical and real-time data, essential for thorough market analysis.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ensure Data Integrity:&lt;/strong&gt; Partnering with reputable vendors guarantees accurate and consistent data, which is critical for practical trading strategies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customize Trading Solutions:&lt;/strong&gt; APIs allow for developing tailored trading applications that align with specific trading styles and requirements.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Choosing the Right Data Vendor
&lt;/h2&gt;

&lt;p&gt;Selecting a reputable data vendor is paramount. Consider the following factors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data Accuracy:&lt;/strong&gt; Ensure the vendor offers precise and up-to-date information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reliability:&lt;/strong&gt; The vendor should have a robust infrastructure to access uninterrupted data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Support Services:&lt;/strong&gt; Quality customer support is essential for addressing any issues promptly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The fusion of AI and real-time data integration reshapes the forex trading landscape. By harnessing the power of AI and utilizing &lt;a href="https://tradermade.com/forex" rel="noopener noreferrer"&gt;Forex APIs&lt;/a&gt; from reputable data vendors, traders can enhance their decision-making processes, execute timely trades, and develop sophisticated, real-time trading applications. Embracing these technological advancements is not just an option but a necessity for those aiming to excel in the modern forex market.&lt;/p&gt;

</description>
      <category>forexapi</category>
      <category>ai</category>
      <category>realtimedata</category>
      <category>forextrading</category>
    </item>
    <item>
      <title>Building Your First C++ WebSocket Client</title>
      <dc:creator>Shridhar G Vatharkar</dc:creator>
      <pubDate>Tue, 18 Feb 2025 14:27:28 +0000</pubDate>
      <link>https://forem.com/shridhargv/building-your-first-c-websocket-client-nb8</link>
      <guid>https://forem.com/shridhargv/building-your-first-c-websocket-client-nb8</guid>
      <description>&lt;p&gt;Welcome to our step-by-step tutorial on accessing real-time Forex, CFD, and Crypto data using TraderMade’s WebSocket with C++. In the fast-paced financial world, staying updated with live data is essential for making informed decisions. This guide will walk you through the entire process seamlessly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;First, &lt;a href="https://tradermade.com/signup" rel="noopener noreferrer"&gt;sign up&lt;/a&gt; for a TraderMade account and get a free API key for a 2-week trial. This key is your gateway to real-time market data. Once you have it, you’ll use it to authenticate your requests. Reviewing the &lt;a href="https://tradermade.com/docs/streaming-data-api" rel="noopener noreferrer"&gt;Streaming Forex API documentation&lt;/a&gt; will also help you understand the available data and how to use it effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Your Coding Environment
&lt;/h2&gt;

&lt;p&gt;C++ development is more convenient in a Linux environment. You can install the Ubuntu app from the search bar if you're using Windows.&lt;/p&gt;

&lt;p&gt;For those new to C++, installing the GCC compiler is essential for running C++ programs. We’ll break everything down into simple steps to make the setup process smooth and efficient.&lt;/p&gt;

&lt;p&gt;Let’s dive in and start building!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you haven’t set a password or can't remember it, you can reset it using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With our system up to date, let's go ahead and install the essential tools for compilation by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install build-essential
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check the version of GCC you're working with, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gcc --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that the C++ compiler is set up, let's import the necessary libraries to run our program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/zaphoyd/websocketpp.git
cd websocketpp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will fetch the WebSocket++ library directly from its GitHub repository. Additionally, we’ll need to install two more libraries: Boost and SSL. You can do so by running the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get install libboost-all-dev
sudo apt-get install libssl-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Writing Code
&lt;/h3&gt;

&lt;p&gt;Now, let's include the libraries necessary to run our program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#include &amp;lt;websocketpp/config/asio_client.hpp&amp;gt; 
#include &amp;lt;websocketpp/client.hpp&amp;gt; 
#include &amp;lt;iostream&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we'll define aliases using &lt;em&gt;typedef&lt;/em&gt; for easier reference in our code. The &lt;em&gt;websocketpp&lt;/em&gt; is a namespace within the WebSocket++ library. The first line represents a complex type that enables WebSocket client support with Asio (for asynchronous I/O) and TLS (for secure communication).&lt;/p&gt;

&lt;p&gt;In the second line, &lt;em&gt;shared_ptr&lt;/em&gt; is a smart pointer from the WebSocket++ library that automatically manages memory for the object. The type of object it will manage is specified after the &lt;em&gt;&amp;lt;&lt;/em&gt; symbol. &lt;em&gt;context_ptr&lt;/em&gt; is an alias that simplifies using the longer type in the second line, making the code more readable and concise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;typedef websocketpp::client&amp;lt;websocketpp::config::asio_tls_client&amp;gt; client;
typedef websocketpp::lib::shared_ptr&amp;lt;websocketpp::lib::asio::ssl::context&amp;gt; context_ptr;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code below should now be clearer. In the first two lines, _&lt;em&gt;1&lt;/em&gt; and _&lt;em&gt;2&lt;/em&gt; represent the first and second arguments, which are passed to the WebSocket++ function objects and callbacks. The third line defines the &lt;em&gt;bind&lt;/em&gt; function, which allows you to create function objects using placeholders.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we've defined the placeholders and bound them to callback functions for handling WebSocket events, we'll explain the functions for each event that we might encounter after establishing a connection.&lt;/p&gt;

&lt;p&gt;First, we define the &lt;em&gt;on_open&lt;/em&gt; callback function, which is triggered when a WebSocket connection is successfully made. It takes two parameters: a handle to the connection (&lt;em&gt;hdl&lt;/em&gt;) and a pointer to the WebSocket client (&lt;em&gt;client* c&lt;/em&gt;).&lt;br&gt;
The second line of the code is a simple print statement. Following that, we include an error code for error handling and a connection pointer (&lt;em&gt;connection_ptr&lt;/em&gt;). The &lt;em&gt;if&lt;/em&gt; statement checks for any errors when retrieving the connection pointer. We send a string payload as text over the WebSocket connection if no error is found.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void on_open(websocketpp::connection_hdl hdl, client* c) {
    std::cout &amp;lt;&amp;lt; "WebSocket connection opened!" &amp;lt;&amp;lt; std::endl;

    websocketpp::lib::error_code ec;
    client::connection_ptr con = c-&amp;gt;get_con_from_hdl(hdl, ec);
    if (ec) {
        std::cout &amp;lt;&amp;lt; "Failed to get connection pointer: " &amp;lt;&amp;lt; ec.message() &amp;lt;&amp;lt; std::endl;
        return;
    }
    std::string payload = "{"userKey":"API_KEY", "symbol":"EURUSD,GBPUSD"}";
    c-&amp;gt;send(con, payload, websocketpp::frame::opcode::text);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we're familiar with the &lt;em&gt;on_open&lt;/em&gt; callback function, the next part of the code is easy to grasp. The &lt;em&gt;on_message&lt;/em&gt; callback function also takes two parameters; the second is &lt;em&gt;message_ptr&lt;/em&gt; msg, which contains the Forex data received. We then print this data inside the &lt;em&gt;on_message&lt;/em&gt; function.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;on_fail&lt;/em&gt; and &lt;em&gt;on_close&lt;/em&gt; callbacks are straightforward and don't require much explanation to proceed to the next section of the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;void on_message(websocketpp::connection_hdl, client::message_ptr msg) {
    std::cout &amp;lt;&amp;lt; "Received message: " &amp;lt;&amp;lt; msg-&amp;gt;get_payload() &amp;lt;&amp;lt; std::endl;

}
void on_fail(websocketpp::connection_hdl hdl) {
    std::cout &amp;lt;&amp;lt; "WebSocket connection failed!" &amp;lt;&amp;lt; std::endl;
}
void on_close(websocketpp::connection_hdl hdl) {
    std::cout &amp;lt;&amp;lt; "WebSocket connection closed!" &amp;lt;&amp;lt; std::endl;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next function configures the SSL context for secure communication in the WebSocket client. We won’t delve into the specifics of this function; instead, we’ll jump straight into the main function, where everything integrates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;context_ptr on_tls_init(const char * hostname, websocketpp::connection_hdl) {
    context_ptr ctx = websocketpp::lib::make_shared&amp;lt;boost::asio::ssl::context&amp;gt;(boost::asio::ssl::context::sslv23);

    try {
        ctx-&amp;gt;set_options(boost::asio::ssl::context::default_workarounds |
                         boost::asio::ssl::context::no_sslv2 |
                         boost::asio::ssl::context::no_sslv3 |
                         boost::asio::ssl::context::single_dh_use);

        ctx-&amp;gt;set_verify_mode(boost::asio::ssl::verify_none);
    } catch (std::exception&amp;amp; e) {
        std::cout &amp;lt;&amp;lt; "TLS Initialization Error: " &amp;lt;&amp;lt; e.what() &amp;lt;&amp;lt; std::endl;
    }
    return ctx;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the main function, we define the client, then specify the URL to connect to the Forex WebSocket and retrieve sub-second data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int main(int argc, char* argv[]) {
    client c;

    std::string hostname = "marketdata.tradermade.com/feedadv";
    std::string uri = "wss://" + hostname;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We set up a try block inside the main function to handle possible exceptions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int main(int argc, char* argv[]) {
....
try {

    } catch (websocketpp::exception const &amp;amp; e) {
        std::cout &amp;lt;&amp;lt; "WebSocket Exception: " &amp;lt;&amp;lt; e.what() &amp;lt;&amp;lt; std::endl;
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within the try block, we begin by configuring the WebSocket++ client and initializing Asio for asynchronous operations. Next, we set up message and event handlers, including the TLS (Transport Layer Security) initialization handler. &lt;/p&gt;

&lt;p&gt;We then declare an error object and check for issues while retrieving the connection. Lastly, we create a connection using &lt;em&gt;c.connect(con)&lt;/em&gt; and initiate the WebSocket event loop with &lt;em&gt;c.run()&lt;/em&gt;, which handles the asynchronous events.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try {
      // Configure WebSocket++ client
      c.set_access_channels(websocketpp::log::alevel::all);
      c.clear_access_channels(websocketpp::log::alevel::frame_payload);
      c.set_error_channels(websocketpp::log::elevel::all);

      c.init_asio();

      // Set message, TLS initialization, open, fail, and close handlers
      c.set_message_handler(&amp;amp;on_message);

      c.set_tls_init_handler(bind(&amp;amp;on_tls_init, hostname.c_str(), ::_1));

      c.set_open_handler(bind(&amp;amp;on_open, ::_1, &amp;amp;c));
      c.set_fail_handler(bind(&amp;amp;on_fail, ::_1));


      c.set_close_handler(bind(&amp;amp;on_close, ::_1));
      // Enable detailed error logging

      c.set_error_channels(websocketpp::log::elevel::all);          

      websocketpp::lib::error_code ec;

      client::connection_ptr con = c.get_connection(uri, ec);

      if (ec) {
                 std::cout &amp;lt;&amp;lt; "Could not create connection because: " &amp;lt;&amp;lt; ec.message() &amp;lt;&amp;lt; std::endl;
                 return 0;
              }

      // Create a connection to the specified url
      c.connect(con);

      c.run();

    } catch (websocketpp::exception const &amp;amp; e) {
      std::cout &amp;lt;&amp;lt; "WebSocket Exception: " &amp;lt;&amp;lt; e.what() &amp;lt;&amp;lt; std::endl;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After writing the code, save it in a file named &lt;em&gt;FX_WebSocket.cpp&lt;/em&gt; (or any name you prefer). Then, compile the program using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;g++ -o ./streaming_forex  FX_WebSocket.cpp -lssl -lcrypto -pthread
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your program should now be compiled into the &lt;em&gt;streaming_forex&lt;/em&gt; file. To run the file, use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./streaming_forex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voila! You should now see a WebSocket connection with your subscribed Forex data. Remember to replace your API key when sending the payload using the on_open function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Output
&lt;/h3&gt;

&lt;p&gt;Great! Our output is ready.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Received message: Connected
Received message: {"symbol":"GBPUSD","ts":"1708403061263","bid":1.25867,"ask":1.25871,"mid" :1.25869}
Received message: {"symbol":"GBPUSD","ts":"1708403070164","bid":1.25867,"ask":1.2587,"mid":1.258685}
Received message: {"symbol":"GBPUSD","ts":"1708403070951","bid":1.25866,"ask":1.2587,"mid":1.25868}
Received message: {"symbol":"GBPUSD","ts":"1708403071022","bid":1.25866,"ask":1.25871,"mid":1.258685}
Received message: {"symbol":"GBPUSD","ts":"1708403071213","bid":1.25866,"ask":1.2587,"mid":1.25868}
Received message: {"symbol":"GBPUSD","ts":"1708403071400","bid":1.25866,"ask":1.25869,"mid":1.258675}
Received message: {"symbol":"EURUSD","ts":"1708403071512","bid":1.07687,"ask":1.07691,"mid":1.07689}
Received message: {"symbol":"EURUSD","ts":"1708403071524","bid":1.07687,"ask":1.0769,"mid":1.076885}
Received message: {"symbol":"GBPUSD","ts":"1708403072138","bid":1.25866,"ask":1.2587,"mid":1.25868}
Received message: {"symbol":"GBPUSD","ts":"1708403074548","bid":1.25866,"ask":1.25869,"mid":1.258675}
Received message: {"symbol":"GBPUSD","ts":"1708403074618","bid":1.25866,"ask":1.2587,"mid":1.25868}
Received message: {"symbol":"GBPUSD","ts":"1708403074921","bid":1.25866,"ask":1.25869,"mid":1.258675}
Received message: {"symbol":"GBPUSD","ts":"1708403075348","bid":1.25866,"ask":1.2587,"mid":1.25868}
Received message: {"symbol":"GBPUSD","ts":"1708403077083","bid":1.25866,"ask":1.25869,"mid":1.258675}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! You've successfully built a real-time Forex data fetcher using C++ and WebSocket++. Feel free to explore and adjust the code to suit your needs, and enjoy access to live financial data at your fingertips.&lt;/p&gt;

&lt;h3&gt;
  
  
  Full Code
&lt;/h3&gt;

&lt;p&gt;Below is the complete code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#include &amp;lt;websocketpp/config/asio_client.hpp&amp;gt;
#include &amp;lt;websocketpp/client.hpp&amp;gt;
#include &amp;lt;iostream&amp;gt;

typedef websocketpp::client&amp;lt;websocketpp::config::asio_tls_client&amp;gt; client;
typedef websocketpp::lib::shared_ptr&amp;lt;websocketpp::lib::asio::ssl::context&amp;gt; context_ptr;

using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;

void on_open(websocketpp::connection_hdl hdl, client* c) {
    std::cout &amp;lt;&amp;lt; "WebSocket connection opened!" &amp;lt;&amp;lt; std::endl;

     websocketpp::lib::error_code ec;
    client::connection_ptr con = c-&amp;gt;get_con_from_hdl(hdl, ec);

    if (ec) {
        std::cout &amp;lt;&amp;lt; "Failed to get connection pointer: " &amp;lt;&amp;lt; ec.message() &amp;lt;&amp;lt; std::endl;
        return;
    }

  std::string payload = "{"userKey":"API_KEY", "symbol":"EURUSD,GBPUSD"}";
    c-&amp;gt;send(con, payload, websocketpp::frame::opcode::text);
}

void on_message(websocketpp::connection_hdl, client::message_ptr msg) {
    std::cout &amp;lt;&amp;lt; "Received message: " &amp;lt;&amp;lt; msg-&amp;gt;get_payload() &amp;lt;&amp;lt; std::endl;
}

void on_fail(websocketpp::connection_hdl hdl) {
    std::cout &amp;lt;&amp;lt; "WebSocket connection failed!" &amp;lt;&amp;lt; std::endl;
}

void on_close(websocketpp::connection_hdl hdl) {
    std::cout &amp;lt;&amp;lt; "WebSocket connection closed!" &amp;lt;&amp;lt; std::endl;
}

context_ptr on_tls_init(const char * hostname, websocketpp::connection_hdl) {
    context_ptr ctx = websocketpp::lib::make_shared&amp;lt;boost::asio::ssl::context&amp;gt;(boost::asio::ssl::context::sslv23);

    try {
        ctx-&amp;gt;set_options(boost::asio::ssl::context::default_workarounds |
                         boost::asio::ssl::context::no_sslv2 |
                         boost::asio::ssl::context::no_sslv3 |
                         boost::asio::ssl::context::single_dh_use);

    } catch (std::exception&amp;amp; e) {
        std::cout &amp;lt;&amp;lt; "TLS Initialization Error: " &amp;lt;&amp;lt; e.what() &amp;lt;&amp;lt; std::endl;
    }


    return ctx;
}

int main(int argc, char* argv[]) {
    client c;

    std::string hostname = "marketdata.tradermade.com/feedadv";
    std::string uri = "wss://" + hostname;


    try {
        c.set_access_channels(websocketpp::log::alevel::all);
        c.clear_access_channels(websocketpp::log::alevel::frame_payload);
        c.set_error_channels(websocketpp::log::elevel::all);
        c.init_asio();


        c.set_message_handler(&amp;amp;on_message);
        c.set_tls_init_handler(bind(&amp;amp;on_tls_init, hostname.c_str(), ::_1));

        c.set_open_handler(bind(&amp;amp;on_open, ::_1, &amp;amp;c));
        c.set_fail_handler(bind(&amp;amp;on_fail, ::_1));
        c.set_close_handler(bind(&amp;amp;on_close, ::_1));
        c.set_error_channels(websocketpp::log::elevel::all);  // Enable detailed error logging

        websocketpp::lib::error_code ec;
        client::connection_ptr con = c.get_connection(uri, ec);
        if (ec) {
            std::cout &amp;lt;&amp;lt; "Could not create connection because: " &amp;lt;&amp;lt; ec.message() &amp;lt;&amp;lt; std::endl;
            return 0;
        }

        c.connect(con);

        c.run();
    } catch (websocketpp::exception const &amp;amp; e) {
        std::cout &amp;lt;&amp;lt; "WebSocket Exception: " &amp;lt;&amp;lt; e.what() &amp;lt;&amp;lt; std::endl;
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;TraderMade’s Live Streaming API is an easy-to-use and powerful resource for building digital solutions and gaining valuable insights. You can use it in C++ to create impressive applications, and we’d love to see what you make!&lt;/p&gt;

&lt;p&gt;Register and explore the details in the Live Streaming API documentation to get started. If you need any help, feel free to reach out via live chat or email us at &lt;a href="mailto:support@tradermade.com"&gt;support@tradermade.com&lt;/a&gt;. We're here to help you on your development journey.&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>websockets</category>
    </item>
    <item>
      <title>Creating Minute-Based HLOC Bars from WebSockets Data with NodeJS</title>
      <dc:creator>Shridhar G Vatharkar</dc:creator>
      <pubDate>Thu, 23 Jan 2025 12:15:20 +0000</pubDate>
      <link>https://forem.com/shridhargv/creating-minute-based-hloc-bars-from-websockets-data-with-nodejs-nc1</link>
      <guid>https://forem.com/shridhargv/creating-minute-based-hloc-bars-from-websockets-data-with-nodejs-nc1</guid>
      <description>&lt;h4&gt;
  
  
  Learn how to convert WebSocket data into minute-based HLOC bars using Node.js. Step-by-step guide for efficient financial data processing.
&lt;/h4&gt;

&lt;p&gt;As WebSockets continues to gain traction in today's tech world, curious developers are eager to explore this exciting technology. Setting up a server-client setup and experimenting with WebSocket data can be pretty thrilling, but the real magic happens when you access WebSockets, which delivers real-time, actionable data.&lt;/p&gt;

&lt;p&gt;This tutorial will focus on something super helpful: turning &lt;a href="https://tradermade.com/tutorials/real-time-forex-and-cfd-data-with-nodejs-websocket" rel="noopener noreferrer"&gt;raw WebSocket data&lt;/a&gt; into minute-based High, Low, Open, and Close (HLOC) bars. This transformation helps developers and analysts track market trends in one-minute intervals.&lt;/p&gt;

&lt;p&gt;The best part? You don't need to be a Node.js pro to follow along! While some essential programming experience (especially with JavaScript) might help, it's unnecessary. Are you not a JavaScript fan? No worries—you can also explore WebSocket implementations in Python or Golang.&lt;/p&gt;

&lt;p&gt;Before starting the setup and coding, let's clarify the plan. We'll fetch real-time Forex data via a WebSocket connection and convert it into minute-based HLOC bars using the TraderMade WebSocket API. The documentation provides more details.&lt;/p&gt;

&lt;p&gt;Here's our game plan, broken into four simple steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install NodeJS and set up your environment.&lt;/li&gt;
&lt;li&gt;Sign up for a free trial and grab your API key.&lt;/li&gt;
&lt;li&gt;Build a Node.js WebSocket client to receive data.&lt;/li&gt;
&lt;li&gt;Process WebSocket data into minute-based HLOC bars with Node.js.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Want a quick walkthrough? Check out this &lt;a href="https://youtu.be/va2w4nRAEnU" rel="noopener noreferrer"&gt;YouTube video&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Install NodeJS and Set Up Your Environment
&lt;/h2&gt;

&lt;p&gt;For Windows and Mac users: Download and install NodeJS.&lt;br&gt;
For Linux fans: Use apt-get to install NodeJS.&lt;/p&gt;

&lt;p&gt;Once NodeJS is installed, open your command prompt (Windows) or terminal (Mac/Linux). Now, let's get the necessary dependencies in place. For our client, we're using the "&lt;strong&gt;&lt;em&gt;ws&lt;/em&gt;&lt;/strong&gt;" library. You can install it with this command:&lt;br&gt;
(And then continue with the step-by-step instructions as needed.)&lt;br&gt;
Let's dive in and get started!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install ws 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Get your free trial and API key
&lt;/h4&gt;

&lt;p&gt;Head over to the tutorial that walks you through &lt;a href="https://tradermade.com/tutorials/how-to-start-a-websocket-trial-and-subscription-plan" rel="noopener noreferrer"&gt;starting a free 14-day trial&lt;/a&gt;.&lt;br&gt;
Once you have your &lt;a href="https://tradermade.com/signup" rel="noopener noreferrer"&gt;API key&lt;/a&gt;, store it somewhere safe—you'll need it soon!&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting Up a Node.js WebSocket Client to Receive Data
&lt;/h3&gt;

&lt;p&gt;Find your NodeJS installation directory and create a new file called forexWsClient.js. Open it with your favorite code editor—Atom, VS Code, Notepad (on Windows), or any text editor on Linux.&lt;br&gt;
Ready for some code magic? Let's dive in!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const WebSocket = require ('ws');
const ws = new WebSocket ('wss://marketdata.tradermade.com/feedadv');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we'll bring in the WebSocket object and set up a connection to TraderMade using their secure WSS URL. Once the connection is live, we'll send over our API key (the one you grabbed during the free trial signup) and the symbols we want to track. For example, let's focus on EURUSD.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ws.on('open', function open() {
     ws.send("{"userKey":"streaming_api_key", "symbol":"EURUSD"}");
  });

  ws.on('message', function incoming(data) {
    if(data != "Connected"){
            data = JSON.parse(data)
            console.log(data)
    }
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running Your WebSocket Client
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Save your &lt;strong&gt;&lt;em&gt;forexWsClient.js&lt;/em&gt;&lt;/strong&gt; file.&lt;/li&gt;
&lt;li&gt;Open your terminal or command prompt and navigate to the file's location.&lt;/li&gt;
&lt;li&gt;Run this command to fire up your client:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node forexWsClient.js 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  And That's a Wrap!
&lt;/h3&gt;

&lt;p&gt;Congrats—you've successfully set up a Node.js WebSocket client to receive real-time Forex data! Now, sit back and watch the financial markets come to life with this smooth integration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transforming WebSocket Data into Minute-Based HLOC Bars with Node.js
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Modules You'll Need
&lt;/h4&gt;

&lt;p&gt;To make this script work, we'll rely on two key Node.js modules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fs:&lt;/strong&gt; This is the File System module, which lets us read from and write to files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Luxon:&lt;/strong&gt; A handy JavaScript library designed for working with dates and times.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Required Modules
const fs = require('fs'); // File System module
const { DateTime } = require('luxon'); // Luxon library for date-time formatting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  File Paths
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;inputFilePath:&lt;/strong&gt; This refers to the location of the input JSON file that holds the WebSocket data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;outputFilePath:&lt;/strong&gt; This is where the processed HLOC data will be saved.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File Paths
const inputFilePath = 'path/to/your/input/file.json'; // Update with your input file path
const outputFilePath = 'path/to/your/output/file.json'; // Update with your output file path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reading Input Data
&lt;/h3&gt;

&lt;p&gt;The script begins by asynchronously reading the input file using &lt;strong&gt;&lt;em&gt;fs.readFile&lt;/em&gt;&lt;/strong&gt;. It splits the file content into individual lines, each treated as a JSON object. This setup assumes that each line represents a separate WebSocket message in JSON format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fs.readFile(inputFilePath, 'utf8', (err, data) =&amp;gt; {
  if (err) {
    console.error('Error reading input file:', err);
    return;
  }

  let jsonData;
  try {
    jsonData = data.split('
').filter(line =&amp;gt; line.trim() !== '').map(line =&amp;gt; {
      try {
        return JSON.parse(line);
      } catch (error) {
        console.error('Error parsing JSON line:', error);
        return null;
      }
    }).filter(Boolean);
  } catch (error) {
    console.error('Error processing JSON data:', error);
    return;
  }

  if (!jsonData || jsonData.length === 0) {
    console.error('No valid JSON data found in the input file.');
    return;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Grouping Data by Time Intervals
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;&lt;em&gt;groupDataByInterval&lt;/em&gt;&lt;/strong&gt; function is key to organizing the data. It groups the WebSocket messages based on a set time interval—1 minute, to be exact. Here's how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It starts by converting each data point's timestamp (ts) into a numerical value.&lt;/li&gt;
&lt;li&gt;This timestamp is then divided by the interval duration (60,000 milliseconds), and the result is rounded down to determine which group (or interval) each data point belongs to.&lt;/li&gt;
&lt;li&gt;All the data points that fall within the same interval are grouped.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const groupedData = groupDataByInterval(jsonData, 60000);
  const hlocData = calculateHLOC(groupedData);

  fs.writeFile(outputFilePath, JSON.stringify(hlocData, null, 2), (err) =&amp;gt; {
    if (err) {
      console.error('Error writing output file:', err);

    } else {
      console.log('HLOC data written to', outputFilePath);
    }
  });
});

function groupDataByInterval(data, interval) {
  const groupedData = {};
  data.forEach(item =&amp;gt; {
    const intervalKey = Math.floor(item.ts / interval) * interval;
    if (!groupedData[intervalKey]) {
      groupedData[intervalKey] = [];

    }
    groupedData[intervalKey].push(item);
  });
  return groupedData;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Calculating HLOC Data
&lt;/h3&gt;

&lt;p&gt;Once intervals group the data, the calculateHLOC function takes over to compute the key HLOC values for each interval:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open:&lt;/strong&gt; The mid-value of the first data point in the interval.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High:&lt;/strong&gt; The highest mid-value observed within the interval.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low:&lt;/strong&gt;The lowest mid-value seen in the interval.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Close:&lt;/strong&gt; The mid-value of the last data point in the interval.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function calculateHLOC(groupedData) {
  const hlocData = [];
  for (const intervalKey in groupedData) {
    const intervalData = groupedData[intervalKey];
    const open = roundToFiveDecimalPlaces(intervalData[0].mid);
    const close = roundToFiveDecimalPlaces(intervalData[intervalData.length - 1].mid);
    const high = roundToFiveDecimalPlaces(Math.max(...intervalData.map(item =&amp;gt; item.mid)));
    const low = roundToFiveDecimalPlaces(Math.min(...intervalData.map(item =&amp;gt; item.mid)));

    hlocData.push({
      interval: Number(intervalKey),
      intervalDateTime: formatDateTime(Number(intervalKey)),
      open,
      high,
      low,
      close
    });
  }
  return hlocData;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Formatting and Writing Output
&lt;/h3&gt;

&lt;p&gt;Once the HLOC values have been calculated for each interval, the data is organized into a well-structured JSON format, which includes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Interval:&lt;/strong&gt; A timestamp marking the start of each minute interval.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IntervalDateTime:&lt;/strong&gt; The date and time corresponding to the interval timestamp, formatted for clarity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open, High, Low, Close:&lt;/strong&gt; The calculated HLOC values.
Finally, the processed HLOC data is saved to an output JSON file using &lt;strong&gt;&lt;em&gt;fs.writeFile&lt;/em&gt;&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function formatDateTime(timestamp) {
  return DateTime.fromMillis(timestamp).toUTC().toFormat('yyyy-MM-dd HH:mm:ss');
}

function roundToFiveDecimalPlaces(value) {
  return Math.round(value * 1e5) / 1e5;
}
  } else {
    console.log('HLOC data written to', outputFilePath);
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our output is all set!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "interval": 1704453720000,
    "intervalDateTime": "2024-01-05 11:22:00",
    "open": 1.09152,
    "high": 1.09152,
    "low": 1.09132,
    "close": 1.09132
  },

  {
    "interval": 1704453780000,
    "intervalDateTime": "2024-01-05 11:23:00",
    "open": 1.09133,
    "high": 1.09153,
    "low": 1.09132,
    "close": 1.09152
  },

  {
    "interval": 1704453840000,
    "intervalDateTime": "2024-01-05 11:24:00",
    "open": 1.09153,
    "high": 1.09153,
    "low": 1.09141,
    "close": 1.09142
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Wrapping Up
&lt;/h3&gt;

&lt;p&gt;This tutorial provides a simple and effective way to turn WebSocket data into valuable insights. By converting raw data into minute-based HLOC bars, developers and analysts can track market trends, spot patterns, and make well-informed decisions. The script's modular structure, combined with the Luxon library for handling dates and times, ensures both efficiency and accuracy in data processing and analysis.&lt;/p&gt;

</description>
      <category>websockets</category>
      <category>node</category>
      <category>hlocdata</category>
      <category>techtutorial</category>
    </item>
    <item>
      <title>Boosting WebSocket Scalability through a Python Proxy</title>
      <dc:creator>Shridhar G Vatharkar</dc:creator>
      <pubDate>Fri, 10 Jan 2025 12:32:24 +0000</pubDate>
      <link>https://forem.com/shridhargv/boosting-websocket-scalability-through-a-python-proxy-2o5c</link>
      <guid>https://forem.com/shridhargv/boosting-websocket-scalability-through-a-python-proxy-2o5c</guid>
      <description>&lt;p&gt;WebSocket protocol has revolutionized real-time communication over the web, making easy bidirectional conversations between clients and servers. Although WebSocket establishes persistent channels using the HTTP protocol and connection upgrade, scalability problems soon arise with rapidly growing applications. This article reveals how a simple Python-based proxy server for the WebSocket can more efficiently manage flow, ensuring superior performance and scalability.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Scalability Problem in WebSocket Applications
&lt;/h2&gt;

&lt;p&gt;The sheer volume of concurrent connections typically stands between most WebSocket applications and the light of day. A single server can quickly become overwhelmed with the client load, causing performance bottlenecks. A WebSocket proxy is a solution to the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is A WebSocket Proxy?
&lt;/h2&gt;

&lt;p&gt;A WebSocket proxy is a middleman between clients and servers, efficiently managing WebSocket traffic. It oversees the WebSocket handshake, distributes connections, and forwards messages to make communication smoother and reduce the load on the original WebSocket server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also Read:&lt;/strong&gt; &lt;a href="https://tradermade.com/tutorials/scaling-websocket-applications-with-a-websocket-proxy-an-overview" rel="noopener noreferrer"&gt;Scaling a Forex WebSocket with Python Proxy&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Case: Scaling a Single WebSocket Source
&lt;/h3&gt;

&lt;p&gt;Consider a real-time WebSocket source feeding live data, such as a financial market feed or chat system. Once the client base grows, this information must be distributed efficiently without overloading the source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python WebSocket Proxy
&lt;/h2&gt;

&lt;h3&gt;
  
  
  WebSocket Proxy Workflow
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Handshake
&lt;/h4&gt;

&lt;p&gt;Client connections to the WebSocket proxy. The proxy then manages the handshake and establishes the connection.&lt;/p&gt;

&lt;h4&gt;
  
  
  Load Balancing
&lt;/h4&gt;

&lt;p&gt;The proxy distributes connections evenly across multiple instances of the WebSocket server so that no single server is overloaded.&lt;/p&gt;

&lt;h4&gt;
  
  
  Efficient Forwarding
&lt;/h4&gt;

&lt;p&gt;WebSocket frames from clients are forwarded to the corresponding server instances for parallel processing, thus improving responsiveness.&lt;/p&gt;

&lt;h4&gt;
  
  
  Response Aggregation
&lt;/h4&gt;

&lt;p&gt;The proxy collects responses from the servers and relays them back to the clients, ensuring transparency in the communication process.&lt;/p&gt;

&lt;h4&gt;
  
  
  Python Libraries for Implementation
&lt;/h4&gt;

&lt;p&gt;Python libraries such as websockets and asyncio can be used to create a scalable WebSocket proxy. For detailed implementation, please refer to our in-depth tutorial on scaling WebSocket with Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages of Python WebSocket Proxies
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;p&gt;It supports horizontal scaling, where the client base can be increased without problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Load Balancing
&lt;/h3&gt;

&lt;p&gt;It uses intelligent algorithms to distribute connections, which prevent server overload.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fault Tolerance
&lt;/h3&gt;

&lt;p&gt;It redirects connections to healthy server instances during failures, which ensures uninterrupted service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Introducing a WebSocket proxy is an effective way of scaling WebSocket applications. With its powerful libraries, such as &lt;strong&gt;websockets&lt;/strong&gt; and &lt;strong&gt;asyncio&lt;/strong&gt;, Python provides flexibility in implementing the solution. Managing live financial feeds, real-time chats, and other dynamic systems powered by WebSocket can significantly improve with a Python WebSocket proxy.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Please go through the published initial tutorial on our website: *&lt;/em&gt;&lt;br&gt;
&lt;a href="https://tradermade.com/tutorials/enhancing-websocket-scalability-with-a-python-websocket-proxy" rel="noopener noreferrer"&gt;Enhancing WebSocket Scalability with a Python Proxy&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>websockets</category>
      <category>websocketproxy</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Implementing a Scalable Forex WebSocket Using a Python Proxy</title>
      <dc:creator>Shridhar G Vatharkar</dc:creator>
      <pubDate>Tue, 31 Dec 2024 12:58:38 +0000</pubDate>
      <link>https://forem.com/shridhargv/implementing-a-scalable-forex-websocket-using-a-python-proxy-3ba0</link>
      <guid>https://forem.com/shridhargv/implementing-a-scalable-forex-websocket-using-a-python-proxy-3ba0</guid>
      <description>&lt;p&gt;This guide will teach you how to create a WebSocket proxy server in Python.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here's what the server will do:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Verify client identity:&lt;/strong&gt; Before allowing clients to connect, it will check whether each has a unique "user key (API Key)."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect to another WebSocket:&lt;/strong&gt; The server will connect to a separate WebSocket server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relay messages:&lt;/strong&gt; The server will receive messages from the connected WebSocket and send them to all verified clients.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Before you begin:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Make sure you have installed Python 3.6 or a newer version. WebSockets need Python 3.6 or higher.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install the WebSockets library:&lt;/strong&gt; You can install it using the following command in your terminal.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install websockets
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Getting Started
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a new folder for your project.&lt;/li&gt;
&lt;li&gt;Create a new Python file inside the folder and name it 'websocket_proxy_server.py.' This file will hold all the code for your server.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Create the WebSocket Server
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Import the required libraries. You'll need the libraries you installed earlier.&lt;/li&gt;
&lt;li&gt;Build the basic structure of your server. Use the WebSockets library to create the foundation for your server.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import asyncio
import websockets
import json

class WebSocketProxy:

    def init(self, source_url, symbols):

        self.source_url = source_url
        self.clients = set()
        self.symbols = symbols
        self.valid_user_key = "yourValidUserKey"  # Single valid user key for authentication

    async def on_open(self, ws):

        print("Connected to source")
        symbols_str = ",".join(self.symbols.keys())
        init_message = f"{{"userKey":"your_api_key", "symbol":"{symbols_str}"}}"
        await ws.send(init_message)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Connect and Verify Clients
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ensure that the server is all set to accept connections from clients.&lt;/li&gt;
&lt;li&gt;Add a check to verify each client's identity. As a client tries to connect, the server should ask for a "user key." Only clients with the correct key will be allowed to connect.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async def client_handler(self, websocket, path):

        try:

            # Wait for a message that should contain the authentication key
            auth_message = await asyncio.wait_for(websocket.recv(), timeout=10)
            auth_data = json.loads(auth_message)
            user_key = auth_data.get("userKey")

            if user_key == self.valid_user_key:
                self.clients.add(websocket)
                print(f"Client authenticated with key: {user_key}")

                try:
                    await websocket.wait_closed()

                finally:
                    self.clients.remove(websocket)

            else:

                print("Authentication failed")
                await websocket.close(reason="Authentication failed")
        except (asyncio.TimeoutError, json.JSONDecodeError, KeyError):
            print("Failed to authenticate")
            await websocket.close(reason="Failed to authenticate")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Connect to the Source and Share Messages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a function that keeps the server connected to the original WebSocket.&lt;/li&gt;
&lt;li&gt;This function should automatically send messages received from the original WebSocket to all successfully verified clients.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async def source_handler(self):
        async with websockets.connect(self.source_url) as websocket:
            await self.on_open(websocket)
            async for message in websocket:
                await self.broadcast(message)

    async def broadcast(self, message):
        if self.clients:
            await asyncio.gather(*(client.send(message) for client in self.clients))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Start the Server
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a function to start the server and listen for connections.&lt;/li&gt;
&lt;li&gt;Add code to run this function, starting your WebSocket proxy server.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def run(self, host="localhost", port=8765):
        start_server = websockets.serve(self.client_handler, host, port)
        asyncio.get_event_loop().run_until_complete(start_server)
        asyncio.get_event_loop().run_until_complete(self.source_handler())
        asyncio.get_event_loop().run_forever()

if name == "main":
    symbols = {"EURUSD": {}, "GBPUSD": {}, "USDJPY": {}, "AUDUSD": {}, "USDCAD": {}}
    source_url = "ws://example.com/source"
    proxy = WebSocketProxy(source_url, symbols)
    proxy.run()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  In Summary
&lt;/h3&gt;

&lt;p&gt;You have successfully developed a Python-based WebSocket proxy server. This server can authenticate client identities, maintain a persistent connection to a designated data source, and effectively distribute messages received from the source to all verified clients. This functionality proves invaluable for applications that necessitate the secure and instantaneous dissemination of data from a singular origin to a diverse user base.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next Steps
&lt;/h3&gt;

&lt;p&gt;Thorough server testing is crucial to ensure optimal performance and reliability. It verifies its proper handling of connections and message transmission. To enhance efficiency, consider implementing load-balancing mechanisms and customizing connection headers. Finally, it is advisable to deploy the server to a suitable environment for production deployment, such as a cloud service specifically designed to accommodate long-term network connections.&lt;/p&gt;

&lt;p&gt;Also, please take a look at the originally published tutorial on our website: &lt;a href="https://tradermade.com/tutorials/scaling-websocket-applications-with-a-websocket-proxy-an-overview" rel="noopener noreferrer"&gt;Scaling a Forex WebSocket with Python Proxy&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>proxy</category>
      <category>websocket</category>
      <category>devtutorial</category>
    </item>
  </channel>
</rss>
