Broker API HubMenu

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.

Independent and unofficialCode run

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

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

Next: Dates and time zones

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.

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.

  1. Prices from a fileYou are here
  2. Dates and time zones
  3. Read and write JSON
  4. Money with Decimal
  5. Build a trade journal
  6. Measure drawdown

The whole path, every stage

Repositories to read next

The full repository list

Back: Test your functionsNext: Dates and time zones