I am creating an application which generates statistical information for a pupil’s performance over their school career. To achieve this, I need to store every grade ever attained by a pupil.
But I have no idea how to optimally store this information. This is a preliminary design, but don’t know how it will hold up in practice.

So each pupil after a full 16 year education will have 288 pieces of grade data, 18 per year. In addition to that there is their personal information, which holds their name, DOB etc.
So, how could I optimally hold this data?
Your design is far too specific. You will need to change the schema every time the grading scheme changes or a new course is added!
Instead, you could have an abstracted design with
Course,Grade, andSubGradetables. Courses will have Names, and Grades and SubGrades will have types. That will give you lots of flexibility.