"""
Version 1.2
Date 2017-01-30, 2018-02-10, 2018-07-05
Christopher Ting
"""

from __future__ import division, print_function

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime

# List of Factors from Bloomberg
tickers = ['PDIVYUS', 'PEARNVUS', 'PGRWTHUS', 'PLEVERUS', 'PMOMENUS', 
           'PPROFTUS', 'PSIZEUS', 'PTRADEUS', 'PVALUEUS', 'PVOLAUS']
  
ticker = tickers[3]

fn = ticker + '--' + 'Index' + '.csv' 
data = pd.read_csv(fn)

dates = pd.to_datetime(data['Date'], format='%Y-%m-%d')
pc = data['PX_LAST']

n = len(pc)
lastp = np.zeros(n, dtype=float)   # Create an array of last traded prices 
tdate = ["" for i in range(n)]     # Create an empty array of length n

# Filtering out nan prices
c = 0
for i in range (n):
   if np.isnan(pc[i]):
      continue
   else:
      lastp[c] = pc[i]
      tdate[c] = dates[i]
      c += 1

# Get the first c values filtered
lastp, tdate = lastp[0:c], tdate[0:c]

s = pd.Series(lastp, tdate)
plt.plot(s)
plt.grid()
plt.title(ticker)
plt.show()
plt.close()

###############################################################################
# Select only daily data from weekly data in the earlier years before July 2008

s1 = s['2008-07-02':]
lastp = s1.values
log_price = np.log(lastp)
r1 = np.diff(log_price)
c = len(lastp)

u = pd.Series(100*r1, s1.index[1:c])
plt.plot(u, 'r')
plt.grid()
plt.title('Log Return of ' + ticker)
plt.show()
plt.close()

###############################################################################
# Variance ratio test

mr1 = np.mean(r1)
sr1 = np.var(r1, ddof=0)
VR = np.ones(11, dtype=float)
Z = np.zeros(11, dtype=float)
nq = 11
nobs = [len(r1)]
T = nobs[0]
for q in range(2, nq):
   idx = range(0, c, q)
   p_q = log_price[idx]
   r_q = np.diff(p_q)
   print('q = %d, length of p_q = %d, length of r_q = %d' % \
         (q, len(p_q), len(r_q)))

   M = len(r_q)
   s = 0
   mrq = q*mr1
   for i in range(M):
      s += (r_q[i] - mrq)**2
   srq = s/M 
   VR[q] = srq/(q*sr1)
   Z[q] = np.sqrt(T)*(VR[q]-1)/np.sqrt(2*(q-1))
   nobs.append(M)
      
VR = VR[1:q+1]
Z = Z[1:q+1]
q = range(1,11)
plt.plot(q, VR, '-^r')
plt.show()

print('\n')
for i in q[1:]:
   i1 = i-1
   print('%02d %d\t %0.4f\t %0.2f' %  (i, nobs[i1], VR[i1], Z[i1]))

