Skip to main content

Case study: PCA in financial analysis

Introduction: Suppose you have samples located in space, defined by several variables (usually more than three). If you could simultaneously envision all these variables, then there would be little need for additional data manipulation. However, with more than three dimensions, we usually need a little help. What Principal Component Analysis does (speaking loosely) is that it takes your cloud of data points, and rotates it such that the maximum variability is visible. Another way of saying this is that it identifies your most important gradients.

Case and data: The example follows the description avaiable here. Suppose today is June 30, 2000. We consider a random vector Z whose components represent the simple price returns that specific European currencies will realize versus the US dollar (USD) over the upcoming trading day:

Z=(Z1Z2Z3Z4Z5Z6Z7)∼(Swiss franc (CHF) price returnDanish krone (DKK) price returnEuro (EUR) price returnBritish pound (GBP) price returnGreek drachma (GRD) price returnNorwegian krone (NOK) price returnSwedish krona (SEK) price return)\mathbf{Z} = \begin{pmatrix} Z_1 \\ Z_2 \\ Z_3 \\ Z_4 \\ Z_5 \\ Z_6 \\ Z_7 \end{pmatrix} \sim \begin{pmatrix} \text{Swiss franc (CHF) price return} \\ \text{Danish krone (DKK) price return} \\ \text{Euro (EUR) price return} \\ \text{British pound (GBP) price return} \\ \text{Greek drachma (GRD) price return} \\ \text{Norwegian krone (NOK) price return} \\ \text{Swedish krona (SEK) price return} \end{pmatrix}

Based upon a time series analysis of the historical price data, a covariance and correlation matrices for Z can be constructed:

ΣZ=(0.000042560.000039120.000039000.000017370.000037760.000027260.000027350.000039120.000039940.000039290.000016020.000038650.000028290.000028480.000039000.000039290.000039350.000015990.000038290.000027930.000028100.000017370.000016020.000015990.000021050.000015240.000012560.000011750.000037760.000038650.000038290.000015240.000039610.000027820.000028050.000027260.000028290.000027930.000012560.000027820.000029590.000026030.000027350.000028480.000028100.000011750.000028050.000026030.00003220)\small \boldsymbol{\Sigma}_Z = \begin{pmatrix} 0.00004256 & 0.00003912 & 0.00003900 & 0.00001737 & 0.00003776 & 0.00002726 & 0.00002735 \\ 0.00003912 & 0.00003994 & 0.00003929 & 0.00001602 & 0.00003865 & 0.00002829 & 0.00002848 \\ 0.00003900 & 0.00003929 & 0.00003935 & 0.00001599 & 0.00003829 & 0.00002793 & 0.00002810 \\ 0.00001737 & 0.00001602 & 0.00001599 & 0.00002105 & 0.00001524 & 0.00001256 & 0.00001175 \\ 0.00003776 & 0.00003865 & 0.00003829 & 0.00001524 & 0.00003961 & 0.00002782 & 0.00002805 \\ 0.00002726 & 0.00002829 & 0.00002793 & 0.00001256 & 0.00002782 & 0.00002959 & 0.00002603 \\ 0.00002735 & 0.00002848 & 0.00002810 & 0.00001175 & 0.00002805 & 0.00002603 & 0.00003220 \end{pmatrix}

ρZ=(10.94880.95300.58040.91970.76820.73880.948810.99110.55230.97170.82290.79400.95300.991110.55540.96980.81840.78940.58040.55230.555410.52760.50310.45120.91970.97170.96980.527610.81240.78550.76820.82290.81840.50310.812410.84340.73880.79400.78940.45120.78550.84341)\boldsymbol{\rho}_Z = \begin{pmatrix} 1 & 0.9488 & 0.9530 & 0.5804 & 0.9197 & 0.7682 & 0.7388 \\ 0.9488 & 1 & 0.9911 & 0.5523 & 0.9717 & 0.8229 & 0.7940 \\ 0.9530 & 0.9911 & 1 & 0.5554 & 0.9698 & 0.8184 & 0.7894 \\ 0.5804 & 0.5523 & 0.5554 & 1 & 0.5276 & 0.5031 & 0.4512 \\ 0.9197 & 0.9717 & 0.9698 & 0.5276 & 1 & 0.8124 & 0.7855 \\ 0.7682 & 0.8229 & 0.8184 & 0.5031 & 0.8124 & 1 & 0.8434 \\ 0.7388 & 0.7940 & 0.7894 & 0.4512 & 0.7855 & 0.8434 & 1 \end{pmatrix}

Now we will use PCA to try to reduce the number of variables (currencies) describing time series stored in Z. All we must do is use tMtxPCA control, connect it to covariance/correlation matrix, run PCA and finally interpret results.

1) Setup tMtxPCA control: We begin with creating a tMtxPCA control. Since we will be analyzing the correlation matrix, we set the tMtxPCA.PCAMode property to PCACorrMat and tMtxPCA.DataFormat property to DataFormatCorrCov. Next we must populate the tMtxPCA.Data matrix with correlation matrix values.

Delphi

Uses MtxVec, StatTools, Statistics, Math387;

procedure PCAAnalysis;
var pca: TMtxPCA;
begin
    pca := TMtxPCA.Create(nil);
    try
        // we'll be doing PCA on correlation matrix
        pca.DataFormat := DataFormatCorrCov;
        pca.PCAMode := PCACorrMat;
        // setup correlation matrix
        pca.Data.SetIt(7,7,false,
        [1.0000, 0.9488, 0.9530, 0.5804, 0.9197, 0.7682, 0.7388,
        0.9488, 1.0000, 0.9911, 0.5523, 0.9717, 0.8229, 0.7940,
        0.9530, 0.9911, 1.0000, 0.5554, 0.9698, 0.8184, 0.7894,
        0.5804, 0.5523, 0.5554, 1.0000, 0.5276, 0.5031, 0.4512,
        0.9197, 0.9717, 0.9698, 0.5276, 1.0000, 0.8124, 0.7855,
        0.7682, 0.8229, 0.8184, 0.5031, 0.8124, 1.0000, 0.8434,
        0.7388, 0.7940, 0.7894, 0.4512, 0.7855, 0.8434, 1.0000]);

BCB

#include "MtxExpr.hpp"
#include "Statistics.hpp"
#include "Math387.hpp"
#include "MtxVec.hpp"
#include "StatTools.hpp"

void PCAAnalysis(void);
{
   TMtxPCA* pca = new TMtxPCA(NULL);
    try
    {
       pca->DataFormat = DataFormatCorrCov;
       pca->PCAMode = PCACorrMat;
       // setup correlation matrix
       pca->Data->SetIt(7,7,false,OPENARRAY(TSample,
         (1.0000, 0.9488, 0.9530, 0.5804, 0.9197, 0.7682, 0.7388,
          0.9488, 1.0000, 0.9911, 0.5523, 0.9717, 0.8229, 0.7940,
          0.9530, 0.9911, 1.0000, 0.5554, 0.9698, 0.8184, 0.7894,
          0.5804, 0.5523, 0.5554, 1.0000, 0.5276, 0.5031, 0.4512,
          0.9197, 0.9717, 0.9698, 0.5276, 1.0000, 0.8124, 0.7855,
          0.7682, 0.8229, 0.8184, 0.5031, 0.8124, 1.0000, 0.8434,
          0.7388, 0.7940, 0.7894, 0.4512, 0.7855, 0.8434, 1.0000)));;

C#

using Dew.Math;
using Dew.Math.Units;
using Dew.Stats.Units;
using Dew.Stats;

namespace Dew.Tests
{
   private void PCAAnalysis()
   {
      TMtxPCA pca = new TMtxPCA();
       try
       {
          // we'll be doing PCA on correlation matrix
          pca.DataFormat = DataFormatCorrCov;
          pca.PCAMode = PCACorrMat;
          // setup correlation matrix (7 variables)
          pca.Data.SetIt(7,7,false, new double[]
           {1.0000, 0.9488, 0.9530, 0.5804, 0.9197, 0.7682, 0.7388,
             0.9488, 1.0000, 0.9911, 0.5523, 0.9717, 0.8229, 0.7940,
             0.9530, 0.9911, 1.0000, 0.5554, 0.9698, 0.8184, 0.7894,
             0.5804, 0.5523, 0.5554, 1.0000, 0.5276, 0.5031, 0.4512,
             0.9197, 0.9717, 0.9698, 0.5276, 1.0000, 0.8124, 0.7855,
             0.7682, 0.8229, 0.8184, 0.5031, 0.8124, 1.0000, 0.8434,
             0.7388, 0.7940, 0.7894, 0.4512, 0.7855, 0.8434, 1.0000});

2) Run PCA: A simple call to tMtxPCA.Recalc() method triggers PCA calculation. The results of PCA are:

  • Principal Components, stored in tMtxPCA.PC matrix,
  • Eigenvalues, stored in tMtxPCA.EigValues vector,
  • Percentage (total) of variation for individual eigenvalues (eigenvectors, stored in tMtxPCA.TotalVarPct vector.

Using these results we can decide which and how many variables (currencies) are needed to describe currencies time series.

Additional things to try:

  • Visualize ZScores by using MtxVecTee.DrawValues routine,
  • Visualize percentage of variation by using MtxVecTee.DrawValues method,
  • Try using Varimax rotation on ZScores by using Statistics.OrthogonalRotation routine. Visualize rotated ZScores and compare it with unrotated values.