Stage 2 of 4, lesson 7 of 31. Beginner
Read prices from a file and work out a moving average
Load a CSV file of daily prices, keep the closing prices in a list and work out a moving average. It introduces opening files, the csv module and turning a column into numbers.
Risk warning: CFDs and spread bets are complex instruments and come with a high risk of losing money rapidly due to leverage. You can lose money on these products, and each provider publishes its own loss figure under FCA rules. You should consider whether you understand how they work and whether you can afford to take the high risk of losing your money. Automated and API trading can amplify losses through bugs, connectivity failures and runaway orders.
You need: The lessons on lists and loops. No broker account.
Price history arrives as rows: a date, then open, high, low and close. A CSV file is the plainest form of that, and every broker export and most APIs can be turned into one.
Download the sample file, put it in the same folder as the script and run it. The prices in the file are invented, so nothing you see is a fact about any market.
A moving average is not a signal. It is the simplest example of turning a column of prices into one number you can reason about.
Files for this lesson
- sample-candles.csv, sample data with invented values
The code
# Read prices from a file and work out a moving average.
# Download sample-candles.csv from this lesson and keep it in the same folder as this script.
# The prices in it are invented. They are not from any market.
import csv
closes = []
with open("sample-candles.csv", newline="") as f:
for row in csv.DictReader(f):
closes.append(float(row["close"]))
print("Rows read:", len(closes))
print("First close:", closes[0])
print("Last close:", closes[-1])
window = 10
last_ten = closes[-window:]
average = sum(last_ten) / window
print("Average of the last", window, "closes:", round(average, 2))
if closes[-1] > average:
print("The last close is above its average.")
else:
print("The last close is at or below its average.")What you should see
Rows read: 120 First close: 99.54 Last close: 106.66 Average of the last 10 closes: 106.07 The last close is above its average.
Run with Python 3.12 on Windows against the sample files on this page. No network and no account.
Check yourself
Answer each question from the code above before you open it. The answers were written from the script on this page and what it printed.
Why does the script wrap row["close"] in float?
The csv module hands every value over as text. float turns the text into a number so that it can be added up and compared.
The file has a header line and the script reports 120 rows. Was the header counted?
No. DictReader uses the first line for the column names, which is why row["close"] works. The 120 rows are the days of prices.
What does closes[-window:] give when window is 10?
The last ten closes. A negative start counts back from the end of the list, and leaving out the end of the slice means carry on to the last value.
Exercise
Change the window from 10 to 20 and run the script again. Does the last line of output change?
What the changed script prints
Rows read: 120 First close: 99.54 Last close: 106.66 Average of the last 20 closes: 106.29 The last close is above its average.
Captured from a run of the solution on . Run with Python 3.12 on Windows against the sample files on this page. No network and no account.
One solution
# Exercise solution: the lesson script with the one change the exercise asks for.
# Read prices from a file and work out a moving average.
# Download sample-candles.csv from this lesson and keep it in the same folder as this script.
# The prices in it are invented. They are not from any market.
import csv
closes = []
with open("sample-candles.csv", newline="") as f:
for row in csv.DictReader(f):
closes.append(float(row["close"]))
print("Rows read:", len(closes))
print("First close:", closes[0])
print("Last close:", closes[-1])
window = 20
last_ten = closes[-window:]
average = sum(last_ten) / window
print("Average of the last", window, "closes:", round(average, 2))
if closes[-1] > average:
print("The last close is above its average.")
else:
print("The last close is at or below its average.")Your progress
Your marks are kept in this browser only, in its local storage. They are not sent anywhere, there is no account, and they will not follow you to another browser or device. To remove them, use Clear my progress on the learning track page, or clear this site's data in your browser's settings. Marking needs JavaScript. With scripts off the track reads the same, without the ticks.
This browser refused to store anything for this page, so marks cannot be kept here.
Where this sits in the path
Stage 2 of 4: Working with data. Read prices and trades from files, get dates and money right, and turn a list of trades into a journal.
- Prices from a fileDoneYou are here
- Dates and time zonesDone
- Read and write JSONDone
- Money with DecimalDone
- Build a trade journalDone
- Measure drawdownDone
Repositories to read next
- openbq-org/OpenBB73,862 stars, read . Open Data Platform for analysts, quants and AI agents.
- ranaroussi/yfinance25,435 stars, read . Download market data from Yahoo! Finance's API
- tradingview/lightweight-charts17,477 stars, read . Performant financial charts built with HTML5 canvas
- TA-Lib/ta-lib-python12,268 stars, read . Python wrapper for TA-Lib (http://ta-lib.org/).
- bukosabino/ta5,233 stars, read . Technical Analysis Library using Pandas and Numpy
- pydata/pandas-datareader3,271 stars, read . Extract data from a wide range of Internet sources into a pandas DataFrame.