Sitemap

Analyzing Adani Group Stock Performance Using Python, SQL, and Tableau

10 min readOct 6, 2026

--

An end-to-end data analytics project exploring historical stock performance, volatility, trading activity, and market behavior.

Introduction

Financial markets generate enormous amounts of data every trading day.

Opening prices, closing prices, trading volume, daily highs and lows, dividends, and stock splits can provide valuable information — but raw financial data by itself doesn’t tell a complete story.

For this project, I wanted to take a historical stock-market dataset and turn it into something more meaningful: an analytical workflow that could identify trends, compare companies, investigate volatility, and communicate findings visually.

I chose historical stock data covering companies within the Adani Group and built an end-to-end analysis using three core tools:

  • Python for data cleaning, transformation, and exploratory analysis
  • SQL for structured analysis and ranking
  • Tableau for interactive dashboards and visualization

The project ultimately became a complete pipeline:

Raw Data
↓
Python
↓
Data Cleaning & Feature Engineering
↓
SQL Analysis
↓
Tableau Dashboards
↓
Insights & Communication

The Questions I Wanted to Answer

Rather than simply creating charts from the dataset, I wanted the analysis to answer specific questions.

Performance

  • How have the companies performed over time?
  • Which companies experienced the strongest cumulative growth?
  • How different was performance between companies?

Risk and volatility

  • Which companies experienced the greatest price volatility?
  • How frequently did companies experience positive trading days?
  • Were periods of large price movements associated with increased volatility?

Trading activity

  • Which companies had the highest average trading volume?
  • When did trading activity increase?
  • Did large price movements coincide with unusual trading activity?

January 2023

I also wanted to investigate stock behavior surrounding January 24, 2023.

Rather than treating this date as proof of causation, I used it as an event date and examined the surrounding period to see whether there were noticeable changes in returns, volatility, and trading activity.

Understanding the Dataset

The dataset contains historical daily stock-market observations for companies within the Adani Group.

The main fields included:

Press enter or click to view image in full size

The dataset contained approximately 40,000+ observations and 11 unique company symbols across a long historical period.

One important issue emerged during the initial exploration: not every company had the same amount of historical data.

For example, Sanghi Industries had only a single observation, making it unsuitable for meaningful long-term performance comparisons.

This was an early reminder that data analysis isn’t just about calculating metrics. Before comparing groups, you need to understand whether the underlying data actually supports the comparison.

Step 1: Cleaning the Data with Python

I started the analysis in Python using Pandas, NumPy, Matplotlib, and Seaborn.

The first stage involved inspecting the dataset for:

  • Missing values
  • Duplicate observations
  • Incorrect data types
  • Date formatting issues
  • Company coverage
  • Inconsistent historical coverage

The original timestamp was converted into a proper datetime field:

df["date"] = pd.to_datetime(
df["timestamp"],
unit="s",
utc=True
).dt.tz_convert(None)

I then sorted the observations by company and date:

df = df.sort_values(
["symbol", "date"]
).reset_index(drop=True)

Duplicate company-date observations were removed:

df = df.drop_duplicates(
subset=["symbol", "date"]
).reset_index(drop=True)

The cleaned dataset was then saved for use in the SQL and Tableau portions of the project.

Step 2: Creating New Analytical Features

The raw dataset contained prices and volume, but I wanted to derive metrics that would allow me to analyze performance and risk.

Daily Returns

One of the most important metrics was daily return.

Daily return measures the percentage change in closing price between consecutive trading days.

df["daily_return"] = (
df.groupby("symbol")["close"]
.pct_change(fill_method=None)
)

This gave me a much more useful metric for comparing companies than simply looking at their raw stock prices.

A company trading at $20 and another trading at $2,000 can’t be meaningfully compared based solely on their prices.

Percentage returns provide a common basis for comparison.

Intraday Return

I also calculated the change between the opening and closing price:

df["intraday_return"] = (
(df["close"] - df["open"]) / df["open"]
)

This helps identify whether a stock generally finished the trading period above or below its opening price.

Daily Price Range

To measure the amount of price movement within a trading day, I calculated:

df["daily_range_pct"] = (
(df["high"] - df["low"]) / df["open"]
)

This provides another way of examining market activity and price movement.

Volume Change

Trading volume can provide useful context when looking at price movements.

I calculated the percentage change in volume between consecutive observations:

df["volume_change_pct"] = (
df.groupby("symbol")["volume"]
.pct_change(fill_method=None)
)

This allowed me to investigate whether periods of significant price movement were accompanied by changes in trading activity.

Step 3: Measuring Volatility

Price performance tells only part of the story.

Two companies could have similar returns while having completely different levels of risk.

To examine this, I calculated annualized volatility based on daily returns.

I also created a 30-day rolling volatility measure:

df["rolling_volatility_30d"] = (
df.groupby("symbol")["daily_return"]
.transform(
lambda x: x.rolling(
window=30,
min_periods=20
).std() * np.sqrt(252)
)
)

The use of 252 reflects the approximate number of trading days in a year.

This allowed me to observe how volatility changed over time rather than relying on a single overall figure.

Step 4: Comparing Cumulative Performance

To compare how companies performed over their available historical periods, I calculated cumulative return.

df["cumulative_return"] = (
df.groupby("symbol")["close"]
.transform(
lambda x:
x / x.dropna().iloc[0] - 1
)
)

I also created a normalized price index, where each company’s starting price was represented as 100.

This makes it much easier to compare companies that have very different absolute stock prices.

Instead of asking:

“Which stock has the highest price?”

I could ask:

“Which stock experienced the greatest relative growth over its available history?”

Step 5: Moving to SQL

After cleaning and exploring the data with Python, I moved to SQL.

This was an important part of the project because I wanted to demonstrate that the analysis wasn’t dependent on a single programming language.

Python was useful for data preparation and exploratory analysis.

SQL allowed me to approach the same dataset from a structured analytical perspective.

The SQL analysis covered:

  • Dataset profiling
  • Data-quality checks
  • Duplicate detection
  • Price statistics
  • Daily price ranges
  • Trading volume
  • Corporate actions
  • Daily returns
  • Positive and negative trading days
  • Volatility
  • Extreme price movements
  • Yearly performance
  • Monthly trading volume
  • Company rankings
  • January 2023 event analysis

Ranking Companies with SQL

One of the more useful SQL techniques in the project was the use of window functions.

For example, I used ranking logic to identify companies with the largest daily movements and highest trading activity.

This is useful because it turns a large dataset into targeted questions such as:

Which companies experienced the largest positive daily movements?

or:

What were the highest-volume trading days for each company?

Rather than manually inspecting thousands of rows, SQL allows these questions to be answered systematically.

Step 6: Investigating January 24, 2023

One of the more interesting parts of the project was the event analysis surrounding January 24, 2023.

Instead of looking only at the event date itself, I created a window around the date.

The Python analysis used approximately 45 days before and after the selected event date.

event_date = pd.Timestamp("2023-01-24")
event_df = df[
(df["date"] >= event_date - pd.Timedelta(days=45))
&
(df["date"] <= event_date + pd.Timedelta(days=45))
].copy()

I then divided the observations into:

  • Before the event
  • After the event

and examined:

  • Average daily return
  • Return volatility
  • Average trading volume
  • Large price movements

This approach provided a more useful view than looking at one trading day in isolation.

Why I Avoided Claiming Causation

One of the most important lessons from this analysis was the difference between correlation and causation.

If stock prices or trading volume changed around January 24, 2023, that doesn’t automatically mean that the selected event caused those changes.

Get Raphiel Collins’s stories in your inbox

Join Medium for free to get updates from this writer.

Stock prices can be affected by many factors:

  • Company announcements
  • Investor sentiment
  • Broader market movements
  • Economic conditions
  • Industry developments
  • News events
  • Trading activity
  • Other external factors

Therefore, this project treats January 24 as an event date for observational analysis, not as proof of causality.

This distinction is important when working with financial data.

Step 7: Building the Tableau Dashboards

Once the Python and SQL analysis was complete, I moved the cleaned dataset into Tableau.

The goal wasn’t simply to reproduce the Python charts.

Instead, I wanted to create an interactive analytical experience where someone could explore the companies and time periods themselves.

I created three main dashboards.

Dashboard 1: Executive Overview

The Executive Overview provides a high-level view of the dataset.

It includes:

  • Closing-price trends
  • Daily returns
  • Trading volume
  • Company filters
  • Date filters
Press enter or click to view image in full size
Executive Overview dashboard created in Tableau.

The dashboard allows users to select individual companies and examine how price, returns, and trading activity changed over time.

Dashboard 2: Company Performance

The second dashboard focuses on comparing companies.

It includes:

  • Cumulative return
  • Annualized volatility
  • Positive trading-day percentage
  • Average daily trading volume
Press enter or click to view image in full size
Company Performance dashboard created in Tableau.

I wanted this dashboard to demonstrate why looking at only one metric can be misleading.

For example, a company may have strong cumulative performance but also exhibit significantly higher volatility.

Similarly, a company with a high percentage of positive trading days isn’t necessarily the company with the highest overall return.

Looking at multiple metrics together provides a more complete picture.

Dashboard 3: January 2023 Event Analysis

The third dashboard focuses specifically on the period surrounding January 24, 2023.

It combines:

  • Closing-price movement
  • Daily returns
  • Trading volume
  • Company-level comparisons
  • Event-date visualization
Press enter or click to view image in full size
January 2023 Event Analysis dashboard created in Tableau.

A visual marker identifies January 24, 2023, allowing the viewer to compare the period before and after the selected event date.

This makes the event-window analysis much easier to interpret than looking at a table of numbers alone.

What I Learned from the Analysis

One of the biggest takeaways from this project was that stock performance cannot be evaluated using a single metric.

A meaningful comparison requires looking at several dimensions simultaneously:

Return

How much did the stock’s value change?

Volatility

How much did the stock’s daily returns fluctuate?

Trading Volume

How active was trading?

Positive Trading Days

How frequently did the stock record a positive daily return?

Time

Did the behavior change during particular periods?

Combining these metrics provides a more complete analytical picture.

What I Learned as a Data Analyst

This project was also valuable because it forced me to work through an entire analytics workflow rather than focusing on a single tool.

I learned that each tool has a different role.

Python

Python was useful for:

  • Cleaning data
  • Transforming data
  • Creating new metrics
  • Exploratory analysis
  • Statistical calculations

SQL

SQL helped me think about the data differently.

Instead of manipulating the dataset primarily through Python, I had to formulate analytical questions using:

  • Aggregations
  • Grouping
  • Window functions
  • Rankings
  • Time-based queries

Tableau

Tableau taught me the importance of communication.

A technically correct analysis isn’t automatically useful if the audience cannot understand it.

The dashboards forced me to think about:

  • Which metrics matter?
  • Which comparisons are useful?
  • How should information be arranged?
  • What should the user be able to filter?
  • How can complex analysis be communicated quickly?

Challenges

The project also came with several challenges.

Unequal historical coverage

Not every company had the same amount of historical data.

This meant I needed to be careful when comparing long-term performance.

Missing values

There were missing closing-price observations in the original dataset.

These had to be considered when calculating returns and other derived metrics.

Financial metrics

Metrics such as volatility and cumulative return required careful interpretation.

A metric can be mathematically correct while still being misleading if the underlying data or context isn’t considered.

Event analysis

The January 2023 analysis required particular caution because observing a change around an event does not establish causation.

These challenges were useful because they reinforced an important principle of data analysis:

Good analysis isn’t just about producing a result. It’s about understanding how trustworthy and meaningful that result actually is.

Limitations

There are several limitations to this project.

First, the analysis is based on historical data and therefore should not be interpreted as a prediction of future stock performance.

Second, companies have different historical coverage, which can affect long-term comparisons.

Third, the January 2023 event analysis is observational. It does not establish that the selected event caused changes in stock prices or trading volume.

Finally, the analysis does not incorporate every possible factor affecting stock prices, such as macroeconomic conditions, broader market indices, investor sentiment, or other company-specific events.

This project is intended as a data analytics portfolio project, not financial advice or an investment recommendation.

Future Improvements

There are several ways I could extend this project.

1. Add a market benchmark

Comparing the companies against an index such as the NIFTY 50 would provide additional context.

Instead of asking only:

“Did the company increase?”

I could ask:

“Did the company outperform the broader market?”

2. Add maximum drawdown

Maximum drawdown would help measure the largest decline from a previous peak.

3. Calculate Sharpe ratios

Risk-adjusted performance would provide another way of comparing companies.

4. Perform a formal event study

The January 2023 analysis could be expanded into a more formal event-study methodology, including expected returns and statistical significance testing.

5. Automate the data pipeline

A future version could automatically retrieve new market data, process it, update the database, and refresh the Tableau dashboard.

Final Thoughts

This project started with a simple question:

What can I actually learn from historical stock-market data?

It turned into a much broader exercise in data analysis.

I learned how to take a relatively messy dataset, clean it, transform it into useful analytical features, analyze it using SQL, and finally communicate the results through interactive dashboards.

More importantly, I learned that being a data analyst isn’t simply about knowing Python, SQL, or Tableau individually.

The real value comes from connecting the pieces:

Raw Data
↓
Clean Data
↓
Good Questions
↓
Analysis
↓
Visualization
↓
Insights
↓
Communication

The tools are important, but the ability to ask meaningful questions and communicate what the data is telling you is just as important.

🔗 Project Resources

The complete project, including the Python notebook, SQL analysis, cleaned dataset, and project documentation, is available on GitHub.

GitHub: https://github.com/raphielcodez/adani-stock-analysis

Tableau Public: https://public.tableau.com/app/profile/raphiel.collins/vizzes

Tools Used

Python • Pandas • NumPy • Matplotlib • Seaborn • SQL • Tableau • GitHub

This project was created as part of my data analytics portfolio to demonstrate an end-to-end workflow for transforming raw data into structured analysis, interactive visualization, and actionable insights.

--

--

Raphiel Collins
Raphiel Collins

Written by Raphiel Collins

0 followers

A young professional who is interested in technology and data analysis. Especially cybersecurity analysis.