How to Read OHLCV Market Data in a pandas DataFrame

Read OHLCV market data in a pandas DataFrame

In the previous lesson, Python downloaded real Apple market data. You saw a table appear in the VS Code terminal.

Now comes a more important question: What do those numbers actually mean?

Before calculating an indicator, drawing a chart, or testing a strategy, you should be able to read one row of market data with confidence.

In this lesson, we will read the table slowly. No indicators. No trading rules. Just the data.

What you will finish: you will understand rows, columns, the Date index, and the basic meaning of Open, High, Low, Close, and Volume.

1. Start with the Same AAPL Data

Create a new file in your alphesta-lab folder:

read_ohlcv.py

Type:

import FinanceDataReader as fdr

symbol = "AAPL"
start_date = "2025-01-02"
end_date = "2025-01-10"

df = fdr.DataReader(symbol, start_date, end_date)

print(df.head())

This is almost the same code as the previous lesson. That is intentional.

We are not trying to learn a new download method. We are learning how to read the result.

2. A DataFrame Is a Table

FinanceDataReader returns the market data as a pandas DataFrame.

A DataFrame is a two-dimensional table. It has rows and columns.

                 columns
        ┌───────────────────────────────┐
        │ Open High Low Close Volume ...│
        │                               │
rows →  │ day 1                         │
        │ day 2                         │
        │ day 3                         │
        └───────────────────────────────┘

For daily stock data:

one row
= one trading day

one column
= one type of information

This simple idea is the foundation for everything we will do later.

3. Look at the Column Names

Add this line:

print(df.columns)

Your file now contains:

import FinanceDataReader as fdr

symbol = "AAPL"
start_date = "2025-01-02"
end_date = "2025-01-10"

df = fdr.DataReader(symbol, start_date, end_date)

print(df.head())
print(df.columns)

The terminal may show column names such as:

Close
Open
High
Low
Volume
Change

The exact order can vary with the data source or package version. Do not worry about the order. Focus on what each name means.

4. Open — Where Did the Trading Day Begin?

Open is the opening price for that trading day.

Think:

Open
= where the day's trading started

It is not necessarily the same as the previous day's Close. New information can arrive while the market is closed, so the next session may open higher or lower.

5. High — How High Did Price Reach?

High is the highest price reached during that trading day.

High
= highest traded price of the day

High tells you the upper edge of that day's price range.

6. Low — How Low Did Price Fall?

Low is the lowest price reached during the day.

Low
= lowest traded price of the day

High and Low together tell you how wide the day's price range was.

High
  │
  │  today's price range
  │
Low

7. Close — Where Did the Trading Day End?

Close is the closing price for that trading day.

Close
= where the day's trading finished

You will see Close very often in technical analysis. Many beginner indicators and charts start with the Close column.

Later, when we calculate a moving average, we will begin with closing prices.

8. Volume — How Much Trading Happened?

Volume tells you how much trading activity occurred.

Volume
= amount of trading activity during the day

For our AAPL stock example, Volume is related to the number of shares traded.

A day with unusually large Volume can mean that many market participants were active. We will study that later.

For now, simply recognize Volume as a different kind of information from price.

9. Put OHLCV Together

The five names are often written together as OHLCV.

O = Open
H = High
L = Low
C = Close
V = Volume

One daily row can now be read as a short story:

Open
→ where the day started

High
→ highest price reached

Low
→ lowest price reached

Close
→ where the day finished

Volume
→ how much trading activity occurred

That is much more useful than seeing five mysterious numbers.

10. What Is Change?

FinanceDataReader may also return a column named Change.

This is not one of the five letters in OHLCV. It is additional information about the price change from the previous trading day.

You do not need to calculate or use it yet. Just recognize that a market-data table can contain useful columns beyond OHLCV.

11. What Is the Date on the Left?

Look at the far left side of the table. You may see dates rather than a normal numbered column.

In pandas, these row labels are called the index.

Date
2025-01-02
2025-01-03
2025-01-06
...

The Date index answers:

“Which trading day does this row belong to?”

Add:

print(df.index)

pandas uses the index to identify rows. In our market table, the dates are especially useful row labels.

12. Read One Column by Itself

Now type:

print(df["Close"].head())

The square brackets mean:

df["Close"]
= give me the Close column from df

Then:

.head()
= show only the first five rows

So the full expression:

df["Close"].head()

means:

“Show me the first five closing prices.”

13. Read One Trading Day

We can also look at one complete row.

Add:

print(df.iloc[0])

For now, read iloc[0] as:

iloc[0]
= give me the first row

Python starts counting positions from zero, so position 0 means the first row.

That row contains the market information for one trading day.

14. Your Complete File

import FinanceDataReader as fdr

symbol = "AAPL"
start_date = "2025-01-02"
end_date = "2025-01-10"

df = fdr.DataReader(symbol, start_date, end_date)

print("First five rows:")
print(df.head())

print("\nColumns:")
print(df.columns)

print("\nDate index:")
print(df.index)

print("\nFirst five closing prices:")
print(df["Close"].head())

print("\nFirst trading day:")
print(df.iloc[0])

This is still a small program. But now you are doing more than downloading data. You are beginning to inspect it.

15. Change One Thing Yourself

Change:

print(df["Close"].head())

to:

print(df["Volume"].head())

Run the file again.

Ask yourself:

What changed, and what stayed the same?

same DataFrame
     ↓
different column selected
     ↓
different information displayed

This is an important pandas idea: one table can hold many kinds of information, and you can choose the column you need.

Check Your Understanding

You are ready to move on if you can explain these ideas in your own words:

  • One row represents one trading day.
  • One column represents one type of market information.
  • Open is the opening price.
  • High is the highest price of the day.
  • Low is the lowest price of the day.
  • Close is the closing price.
  • Volume represents trading activity.
  • The Date index identifies each trading-day row.
  • df["Close"] selects the Close column.

What You Just Learned

DataFrame
   ├── rows
   │     └── trading days
   │
   ├── columns
   │     ├── Open
   │     ├── High
   │     ├── Low
   │     ├── Close
   │     └── Volume
   │
   └── index
         └── Date

You can now look at a market-data table and understand its basic structure.

That means we are ready to do something new with it.

Where Do We Go Next?

So far, we asked FinanceDataReader for one symbol: AAPL.

But how do we find the symbols available in a market?

In the next lesson, we will meet the second FDR tool introduced earlier: StockListing().

Next lesson: How to Get a U.S. Stock Market Listing with FinanceDataReader.



Official References