diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 05fcce7..0000000 --- a/LICENSE.txt +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (C) 2010-2013 Jev Kuznetsov -All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - The name of Jev Kuznetsov may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - diff --git a/ProjectHome.md b/ProjectHome.md new file mode 100644 index 0000000..c125f0c --- /dev/null +++ b/ProjectHome.md @@ -0,0 +1 @@ +Collection of tools/example code for quantitative finance research and trading \ No newline at end of file diff --git a/__init__.py b/__init__.py deleted file mode 100644 index 89dbd48..0000000 --- a/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__docformat__ = 'restructuredtext' __version__ = '0.0.13.2' from datetime import datetime import numpy as np import pandas as pd pd.options.display.mpl_style = 'default' # make nicer plots from lib.functions import * from lib.csvDatabase import HistDataCsv from lib.backtest import Backtest \ No newline at end of file diff --git a/cookbook/calculatePnl.py b/cookbook/calculatePnl.py deleted file mode 100644 index 71a6def..0000000 --- a/cookbook/calculatePnl.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Nov 21 19:03:09 2011 - -@author: jev -""" -import numpy as np -from pandas import * - -dataFile = 'D:\\Development\\tradingWithPython\\cookbook\\tritonDaily.csv' - -spy = DataFrame.from_csv(dataFile)['SPY'] - -pos = Series(np.zeros(spy.shape[0]),index=spy.index) -pos[10:20] = 10 - -#pos.plot() - - -d = {'price':spy, 'pos':pos} -df = DataFrame(d) -df['port'] = df['price']*df['pos'] - -df.to_csv('pnl.csv',index_label='dates') -# = DataFrame(d) - -# test data frame -#idx = spy.index[:10] -idx = DateRange('1/1/2000', periods=10) -data = np.random.rand(10,2) -df = DataFrame(data=data,index=idx,columns =['a','b']) -df.to_csv('foo.csv') - - -df = read_csv('foo.csv',index_col=0, parse_dates=True) -df.to_csv('bar.csv') \ No newline at end of file diff --git a/cookbook/calculateSpread.py b/cookbook/calculateSpread.py deleted file mode 100644 index 6b1d33a..0000000 --- a/cookbook/calculateSpread.py +++ /dev/null @@ -1,30 +0,0 @@ -''' -Created on 28 okt 2011 - -@author: jev -''' - -from tradingWithPython import Symbol, estimateBeta, Spread -from tradingWithPython.lib import yahooFinance -from pandas import DataFrame -import numpy as np - - -startDate = (2010,1,1) -# create two timeseries. data for SPY goes much further back -# than data of VXX - - - -symbolX = Symbol('SPY') -symbolY = Symbol('IWM') - - -symbolX.downloadHistData(startDate) -symbolY.downloadHistData(startDate) - - - -s = Spread(symbolX,symbolY) - - diff --git a/cookbook/connectToTWS.py b/cookbook/connectToTWS.py deleted file mode 100644 index 230b9a7..0000000 --- a/cookbook/connectToTWS.py +++ /dev/null @@ -1,114 +0,0 @@ -#! /usr/bin/env python -# -*- coding: utf-8 -*- - -from ib.ext.Contract import Contract -from ib.ext.ExecutionFilter import ExecutionFilter -from ib.opt import ibConnection, message -from time import sleep - -# print all messages from TWS -def watcher(msg): - print '[watcher]',msg - -def dummyHandler(msg): - pass - -# show Bid and Ask quotes -def my_BidAsk(msg): - print 'bid_ask' - print msg - - if msg.field == 1: - print '%s: bid: %s' % (contractTuple[0], msg.price) - elif msg.field == 2: - print '%s: ask: %s' % (contractTuple[0], msg.price) - -def my_BidAsk2(msg): - print 'Handler 2' - print msg - - -def portfolioHandler(msg): - print msg - print msg.contract.m_symbol - -def makeStkContract(contractTuple): - newContract = Contract() - newContract.m_symbol = contractTuple[0] - newContract.m_secType = contractTuple[1] - newContract.m_exchange = contractTuple[2] - newContract.m_currency = contractTuple[3] - - print 'Contract Values:%s,%s,%s,%s:' % contractTuple - return newContract - -def testMarketData(): - tickId = 1 - - # Note: Option quotes will give an error if they aren't shown in TWS - contractTuple = ('SPY', 'STK', 'SMART', 'USD') - - stkContract = makeStkContract(contractTuple) - print '* * * * REQUESTING MARKET DATA * * * *' - con.reqMktData(tickId, stkContract, '', False) - sleep(3) - print '* * * * CANCELING MARKET DATA * * * *' - con.cancelMktData(tickId) - -def testExecutions(): - print 'testing executions' - f = ExecutionFilter() - #f.m_clientId = 101 - f.m_time = '20110901-00:00:00' - f.m_symbol = 'SPY' - f.m_secType = 'STK' - f.m_exchange = 'SMART' - #f.m_side = 'BUY' - - con.reqExecutions(f) - - - sleep(2) - -def testAccountUpdates(): - con.reqAccountUpdates(True,'') - -def testHistoricData(con): - print 'Testing historic data' - - contractTuple = ('SPY', 'STK', 'SMART', 'USD') - contract = makeStkContract(contractTuple) - - con.reqHistoricalData(1,contract,'20120803 22:00:00','1800 S','1 secs','TRADES',1,2) - sleep(2) - - -def showMessageTypes(): - # show available messages - m = message.registry.keys() - m.sort() - print 'Available message types\n-------------------------' - for msgType in m: - print msgType - -if __name__ == '__main__': - - - showMessageTypes() - - con = ibConnection() - con.registerAll(watcher) # show all messages - con.register(portfolioHandler,message.UpdatePortfolio) - #con.register(watcher,(message.tickPrice,)) - con.connect() - - testHistoricData(con) - - sleep(1) - #testMarketData() - #testExecutions() - #testAccountUpdates() - - con.disconnect() - sleep(2) - print 'All done!' diff --git a/cookbook/cython/mean_c.pyx b/cookbook/cython/mean_c.pyx deleted file mode 100644 index 4937c94..0000000 --- a/cookbook/cython/mean_c.pyx +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -""" -test file for mean calculation -""" - -#cython: boundscheck=False -#cython: wraparound=False - -from __future__ import division -import numpy as np - -cimport numpy as np -ctypedef np.float32_t dtype_t - -def mean(np.ndarray[dtype_t, ndim=2] data): - - - cdef unsigned int row, col, i - cdef dtype_t val - - cdef np.ndarray[dtype_t,ndim=1] s = np.zeros(data.shape[1], dtype=np.float32) - - for row in range(data.shape[0]): - for col in range(data.shape[1]): - s[col]+=data[row,col] - - for row in xrange(s.shape[0]): - s[row] = s[row]/data.shape[0] - - return s - - - diff --git a/cookbook/cython/mean_py.py b/cookbook/cython/mean_py.py deleted file mode 100644 index 6d7b587..0000000 --- a/cookbook/cython/mean_py.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- -""" -test file for mean calculation -""" - -from __future__ import division -import numpy as np - -def mean(data): - - s = np.zeros(data.shape[1]) - - for row in range(data.shape[0]): - for col in range(data.shape[1]): - s[col]+=data[row,col] - - for i in range(s.shape[0]): - s[i] = s[i]/data.shape[0] - - - return s - - diff --git a/cookbook/cython/setup.py b/cookbook/cython/setup.py deleted file mode 100644 index 0c945ee..0000000 --- a/cookbook/cython/setup.py +++ /dev/null @@ -1,11 +0,0 @@ -from distutils.core import setup -from distutils.extension import Extension -from Cython.Distutils import build_ext - -import numpy - -ext = Extension("mean_c", ["mean_c.pyx"], - include_dirs = [numpy.get_include()]) - -setup(ext_modules=[ext], - cmdclass = {'build_ext': build_ext}) \ No newline at end of file diff --git a/cookbook/cython/testSpeed.py b/cookbook/cython/testSpeed.py deleted file mode 100644 index 464a488..0000000 --- a/cookbook/cython/testSpeed.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Wed Jan 25 20:43:49 2012 - -@author: jev -""" - - -import numpy as np -import mean_py -import mean_c -import time - -a = np.random.rand(128,100000).astype(np.float32) - -start = time.clock() -#m1 = a.sum(axis=1) -#m1 = m1/a.shape[0] -m1 = a.mean(axis=0) -print 'Done in %.3f s' % (time.clock()-start) -print m1.shape - -start = time.clock() -m2 = mean_c.mean(a) -print 'Done in %.3f s' % (time.clock()-start) -print m2.shape -#clf() -#plot(m1,'b-x') -#plot(m2,'r-o') -#plot(a.mean(axis=0),'g') \ No newline at end of file diff --git a/cookbook/downloadVixFutures.py b/cookbook/downloadVixFutures.py deleted file mode 100644 index 5333d76..0000000 --- a/cookbook/downloadVixFutures.py +++ /dev/null @@ -1,42 +0,0 @@ -#------------------------------------------------------------------------------- -# Name: download CBOE futures -# Purpose: get VIX futures data from CBOE and save to user directory -# -# -# Created: 15-10-2011 -# Copyright: (c) Jev Kuznetsov 2011 -# Licence: GPL v2 -#------------------------------------------------------------------------------- -#!/usr/bin/env python - - - -from urllib import urlretrieve -import os - -m_codes = ['F','G','H','J','K','M','N','Q','U','V','X','Z'] #month codes of the futures -dataDir = os.getenv("USERPROFILE")+'\\twpData\\vixFutures' # data directory - -def saveVixFutureData(year,month, path): - ''' Get future from CBOE and save to file ''' - fName = "CFE_{0}{1}_VX.csv".format(m_codes[month],str(year)[-2:]) - urlStr = "http://cfe.cboe.com/Publish/ScheduledTask/MktData/datahouse/{0}".format(fName) - - try: - urlretrieve(urlStr,path+'\\'+fName) - except Exception as e: - print e - - - -if __name__ == '__main__': - - if not os.path.exists(dataDir): - os.makedirs(dataDir) - - for year in range(2004,2012): - for month in range(12): - print 'Getting data for {0}/{1}'.format(year,month) - saveVixFutureData(year,month,dataDir) - - print 'Data was saved to {0}'.format(dataDir) \ No newline at end of file diff --git a/cookbook/getDataFromYahooFinance.py b/cookbook/getDataFromYahooFinance.py deleted file mode 100644 index 9901292..0000000 --- a/cookbook/getDataFromYahooFinance.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Sun Oct 16 18:37:23 2011 - -@author: jev -""" - - -from urllib import urlretrieve -from urllib2 import urlopen -from pandas import Index, DataFrame -from datetime import datetime -import matplotlib.pyplot as plt - -sDate = (2005,1,1) -eDate = (2011,10,1) - -symbol = 'SPY' - -fName = symbol+'.csv' - -try: # try to load saved csv file, otherwise get from the net - fid = open(fName) - lines = fid.readlines() - fid.close() - print 'Loaded from ' , fName -except Exception as e: - print e - urlStr = 'http://ichart.finance.yahoo.com/table.csv?s={0}&a={1}&b={2}&c={3}&d={4}&e={5}&f={6}'.\ - format(symbol.upper(),sDate[1]-1,sDate[2],sDate[0],eDate[1]-1,eDate[2],eDate[0]) - print 'Downloading from ', urlStr - urlretrieve(urlStr,symbol+'.csv') - lines = urlopen(urlStr).readlines() - - -dates = [] -data = [[] for i in range(6)] -#high - -# header : Date,Open,High,Low,Close,Volume,Adj Close -for line in lines[1:]: - fields = line.rstrip().split(',') - dates.append(datetime.strptime( fields[0],'%Y-%m-%d')) - for i,field in enumerate(fields[1:]): - data[i].append(float(field)) - -idx = Index(dates) -data = dict(zip(['open','high','low','close','volume','adj_close'],data)) - -# create a pandas dataframe structure -df = DataFrame(data,index=idx).sort() - -df.plot(secondary_y=['volume']) - - diff --git a/cookbook/guiqwt_CurveDialog.py b/cookbook/guiqwt_CurveDialog.py deleted file mode 100644 index 693dc74..0000000 --- a/cookbook/guiqwt_CurveDialog.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Wed Dec 14 19:47:02 2011 - -@author: jev -""" - - -from PyQt4.QtGui import * -from PyQt4.QtCore import * - -from guiqwt.plot import CurveDialog -from guiqwt.builder import make -import sys - -import numpy as np - -class MainForm(QDialog): - def __init__(self,parent=None): - super(MainForm,self).__init__(parent) - self.resize(200,200) - - but = QPushButton() - but.setText('Create plot') - self.connect(but,SIGNAL('clicked()'),self.testFcn) - - lay = QVBoxLayout() - lay.addWidget(but) - self.setLayout(lay) - - def testFcn(self): - x = np.linspace(0, 100, 1000) - - y = (np.random.rand(len(x))-0.5).cumsum() - - curve = make.curve(x, y, "ab", "b") - range = make.range(0, 5) - - disp2 = make.computations(range, "TL", - [(curve, "min=%.5f", lambda x,y: y.min()), - (curve, "max=%.5f", lambda x,y: y.max()), - (curve, "avg=%.5f", lambda x,y: y.mean())]) - legend = make.legend("TR") - items = [ curve, range, disp2, legend] - - win = CurveDialog(edit=False, toolbar=True, parent=self) - plot = win.get_plot() - for item in items: - plot.add_item(item) - win.show() - - - - -if __name__ == "__main__": - app = QApplication(sys.argv) - form = MainForm() - form.show() - app.exec_() diff --git a/cookbook/ib_histData.py b/cookbook/ib_histData.py deleted file mode 100644 index 4f82f93..0000000 --- a/cookbook/ib_histData.py +++ /dev/null @@ -1,17 +0,0 @@ -import tradingWithPython as twp - -#---check for correct version -print 'twp version', twp.__version__ -assert twp.__version__ >= '0.0.6', 'Your twp distribution is too old, please update' - -from tradingWithPython.lib.interactiveBrokers import histData, createContract - - -dl = histData.Downloader(debug=True) # historic data downloader class - -contract = createContract('SPY') # create contract using defaults (STK,SMART,USD) -data = dl.requestData(contract,"20130508 16:00:00 EST") # request 30-second data bars up till now - -data.to_csv('SPY.csv') # write data to csv - -print 'Done' \ No newline at end of file diff --git a/cookbook/ib_logQuotes.py b/cookbook/ib_logQuotes.py deleted file mode 100644 index 5b456fa..0000000 --- a/cookbook/ib_logQuotes.py +++ /dev/null @@ -1,154 +0,0 @@ -''' -Created on May 5, 2013 -Copyright: Jev Kuznetsov -License: BSD - -Program to log tick events to a file - -example usage: - > python ib_logQuotes.py SPY,VXX,XLE - - start with -v option to show all incoming events - - -''' - -import argparse # command line argument parser -import datetime as dt # date and time functions -import time # time module for timestamping -import os # used to create directories -import sys # used to print a dot to a terminal without new line - -#--------ibpy imports ---------------------- -from ib.ext.Contract import Contract -from ib.opt import ibConnection, message - - -# tick type definitions, see IB api manual -priceTicks = {1:'bid',2:'ask',4:'last',6:'high',7:'low',9:'close', 14:'open'} -sizeTicks = {0:'bid',3:'ask',5:'last',8:'volume'} - -class TickLogger(object): - ''' class for handling incoming ticks and saving them to file - will create a subdirectory 'tickLogs' if needed and start logging - to a file with current timestamp in its name. - All timestamps in the file are in seconds relative to start of logging - - ''' - def __init__(self,tws, subscriptions): - ''' init class, register handlers ''' - - tws.register(self._priceHandler,message.TickPrice) - tws.register(self._sizeHandler,message.TickSize) - - self.subscriptions = subscriptions - - # save starting time of logging. All times will be in seconds relative - # to this moment - self._startTime = time.time() - - # create data directory if it does not exist - if not os.path.exists('tickLogs'): os.mkdir('tickLogs') - - # open data file for writing - fileName = 'tickLogs\\tickLog_%s.csv' % dt.datetime.now().strftime('%H_%M_%S') - print 'Logging ticks to ' , fileName - self.dataFile = open(fileName,'w') - - - def _priceHandler(self,msg): - ''' price tick handler ''' - data = [self.subscriptions[msg.tickerId].m_symbol,'price',priceTicks[msg.field],msg.price] # data, second field is price tick type - self._writeData(data) - - def _sizeHandler(self,msg): - ''' size tick handler ''' - data = [self.subscriptions[msg.tickerId].m_symbol,'size',sizeTicks[msg.field],msg.size] - self._writeData(data) - - def _writeData(self,data): - ''' write data to log file while adding a timestamp ''' - timestamp = '%.3f' % (time.time()-self._startTime) # 1 ms resolution - dataLine = ','.join(str(bit) for bit in [timestamp]+data) + '\n' - self.dataFile.write(dataLine) - - def flush(self): - ''' commits data to file''' - self.dataFile.flush() - - def close(self): - '''close file in a neat manner ''' - print 'Closing data file' - self.dataFile.close() - - -def printMessage(msg): - ''' function to print all incoming messages from TWS ''' - print '[msg]:', msg - - -def createContract(symbol): - ''' create contract object ''' - c = Contract() - c.m_symbol = symbol - c.m_secType= "STK" - c.m_exchange = "SMART" - c.m_currency = "USD" - - return c - -#--------------main script------------------ - -if __name__ == '__main__': - - #-----------parse command line arguments - parser = argparse.ArgumentParser(description='Log ticks for a set of stocks') - - - parser.add_argument("symbols",help = 'symbols separated by coma: SPY,VXX') - parser.add_argument("-v", "--verbose", help="show all incoming messages", - action="store_true") - - args = parser.parse_args() - - symbols = args.symbols.strip().split(',') - print 'Logging ticks for:',symbols - - - #---create subscriptions dictionary. Keys are subscription ids - subscriptions = {} - for idx, symbol in enumerate(symbols): - subscriptions[idx+1] = createContract(symbol) - - tws = ibConnection() - logger = TickLogger(tws,subscriptions) - - # print all messages to the screen if verbose option is chosen - if args.verbose: - print 'Starting in verbose mode' - tws.registerAll(printMessage) - - - tws.connect() - - #-------subscribe to data - for subId, c in subscriptions.iteritems(): - tws.reqMktData(subId,c,"",False) - - #------start a loop that must be interrupted with Ctrl-C - print 'Press Ctr-C to stop loop' - - try: - while True: - time.sleep(2) # wait a little - logger.flush() # commit data to file - sys.stdout.write('.') # print a dot to the screen - - - except KeyboardInterrupt: - print 'Interrupted with Ctrl-c' - - logger.close() - tws.disconnect() - print 'All done' - \ No newline at end of file diff --git a/cookbook/ib_placeOrder.py b/cookbook/ib_placeOrder.py deleted file mode 100644 index bae57b9..0000000 --- a/cookbook/ib_placeOrder.py +++ /dev/null @@ -1,100 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Demonstrate order submission with ibpy -""" - -from time import sleep - -from ib.ext.Contract import Contract -from ib.opt import ibConnection -from ib.ext.Order import Order - -def createContract(symbol): - ''' create contract object ''' - c = Contract() - c.m_symbol = symbol - c.m_secType= "STK" - c.m_exchange = "SMART" - c.m_currency = "USD" - - return c - -def createOrder(orderId,shares,limit = None, transmit=0): - ''' - create order object - - Parameters - ----------- - orderId : The order Id. You must specify a unique value. - When the order status returns, it will be identified by this tag. - This tag is also used when canceling the order. - - shares: number of shares to buy or sell. Negative for sell order. - limit : price limit, None for MKT order - transmit: transmit immideatelly from tws - ''' - - action = {-1:'SELL',1:'BUY'} - - o = Order() - - o.m_orderId = orderId - o.m_action = action[cmp(shares,0)] - o.m_totalQuantity = abs(shares) - o.m_transmit = transmit - - if limit is not None: - o.m_orderType = 'LMT' - o.m_lmtPrice = limit - else: - o.m_orderType = 'MKT' - - return o - -class MessageHandler(object): - ''' class for handling incoming messages ''' - - def __init__(self,tws): - ''' create class, provide ibConnection object as parameter ''' - self.nextValidOrderId = None - - tws.registerAll(self.debugHandler) - tws.register(self.nextValidIdHandler,'NextValidId') - - - def nextValidIdHandler(self,msg): - ''' handles NextValidId messages ''' - self.nextValidOrderId = msg.orderId - - def debugHandler(self,msg): - """ function to print messages """ - print msg - - - -#-----------Main script----------------- - -tws = ibConnection() # create connection object -handler = MessageHandler(tws) # message handling class - -tws.connect() # connect to API - -sleep(1) # wait for nextOrderId to come in - -orderId = handler.nextValidOrderId # numeric order id, must be unique. -print 'Placing order with id ', orderId - -contract = createContract('SPY') -order = createOrder(orderId,shares=5, transmit=0) # create order - - -tws.placeOrder(orderId, contract, order) # place order - -sleep(5) - -print 'Cancelling order ' -tws.cancelOrder(orderId) # cancel it. - -print 'All done' - -tws.disconnect() \ No newline at end of file diff --git a/cookbook/ib_streamQuotes.py b/cookbook/ib_streamQuotes.py deleted file mode 100644 index 86771a3..0000000 --- a/cookbook/ib_streamQuotes.py +++ /dev/null @@ -1,42 +0,0 @@ -''' - -Copyright: Jev Kuznetsov -License: BSD - -Demonstration of how to stream quotes from IB. -This script will subscribe to SPY and stream quotes to the sreen for 10 seconds. - -''' - -from time import sleep -from ib.ext.Contract import Contract -from ib.opt import ibConnection, message - - - -def price_tick_handler(msg): - """ function to handle price ticks """ - print msg - - -#--------------main script------------------ - -tws = ibConnection() # create connection object -tws.register(price_tick_handler, message.TickPrice) # register handler -tws.connect() # connect to API - -#-------create contract and subscribe to data -c = Contract() -c.m_symbol = "SPY" -c.m_secType= "STK" -c.m_exchange = "SMART" -c.m_currency = "USD" - -tws.reqMktData(1,c,"",False) # request market data - -#-------print data for a couple of seconds, then close -sleep(10) - -print 'All done' - -tws.disconnect() \ No newline at end of file diff --git a/cookbook/reconstructVXX/downloadVixFutures.py b/cookbook/reconstructVXX/downloadVixFutures.py deleted file mode 100644 index 800b2d8..0000000 --- a/cookbook/reconstructVXX/downloadVixFutures.py +++ /dev/null @@ -1,103 +0,0 @@ -#------------------------------------------------------------------------------- -# Name: download CBOE futures -# Purpose: get VIX futures data from CBOE, process data to a single file -# -# -# Created: 15-10-2011 -# Copyright: (c) Jev Kuznetsov 2011 -# Licence: BSD -#------------------------------------------------------------------------------- -#!/usr/bin/env python - - - -from urllib import urlretrieve -import os -from pandas import * -import datetime -import numpy as np - -m_codes = ['F','G','H','J','K','M','N','Q','U','V','X','Z'] #month codes of the futures -codes = dict(zip(m_codes,range(1,len(m_codes)+1))) - -#dataDir = os.path.dirname(__file__)+'/data' - - -dataDir = os.path.expanduser('~')+'/twpData/vixFutures' -print 'Data directory: ', dataDir - - - -def saveVixFutureData(year,month, path, forceDownload=False): - ''' Get future from CBOE and save to file ''' - fName = "CFE_{0}{1}_VX.csv".format(m_codes[month],str(year)[-2:]) - if os.path.exists(path+'\\'+fName) or forceDownload: - print 'File already downloaded, skipping' - return - - urlStr = "http://cfe.cboe.com/Publish/ScheduledTask/MktData/datahouse/{0}".format(fName) - print 'Getting: %s' % urlStr - try: - urlretrieve(urlStr,path+'\\'+fName) - except Exception as e: - print e - -def buildDataTable(dataDir): - """ create single data sheet """ - files = os.listdir(dataDir) - - data = {} - for fName in files: - print 'Processing: ', fName - try: - df = DataFrame.from_csv(dataDir+'/'+fName) - - - code = fName.split('.')[0].split('_')[1] - month = '%02d' % codes[code[0]] - year = '20'+code[1:] - newCode = year+'_'+month - data[newCode] = df - except Exception as e: - print 'Could not process:', e - - - full = DataFrame() - for k,df in data.iteritems(): - s = df['Settle'] - s.name = k - s[s<5] = np.nan - if len(s.dropna())>0: - full = full.join(s,how='outer') - else: - print s.name, ': Empty dataset.' - - full[full<5]=np.nan - full = full[sorted(full.columns)] - - # use only data after this date - startDate = datetime.datetime(2008,1,1) - - idx = full.index >= startDate - full = full.ix[idx,:] - - #full.plot(ax=gca()) - fName = os.path.expanduser('~')+'/twpData/vix_futures.csv' - print 'Saving to ', fName - full.to_csv(fName) - - -if __name__ == '__main__': - - if not os.path.exists(dataDir): - print 'creating data directory %s' % dataDir - os.makedirs(dataDir) - - for year in range(2008,2013): - for month in range(12): - print 'Getting data for {0}/{1}'.format(year,month+1) - saveVixFutureData(year,month,dataDir) - - print 'Raw wata was saved to {0}'.format(dataDir) - - buildDataTable(dataDir) \ No newline at end of file diff --git a/cookbook/reconstructVXX/reconstructVXX.py b/cookbook/reconstructVXX/reconstructVXX.py deleted file mode 100644 index bb89152..0000000 --- a/cookbook/reconstructVXX/reconstructVXX.py +++ /dev/null @@ -1,119 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Reconstructing VXX from futures data - -author: Jev Kuznetsov - -License : BSD -""" -from __future__ import division -from pandas import * -import numpy as np -import os - -class Future(object): - """ vix future class, used to keep data structures simple """ - def __init__(self,series,code=None): - """ code is optional, example '2010_01' """ - self.series = series.dropna() # price data - self.settleDate = self.series.index[-1] - self.dt = len(self.series) # roll period (this is default, should be recalculated) - self.code = code # string code 'YYYY_MM' - - def monthNr(self): - """ get month nr from the future code """ - return int(self.code.split('_')[1]) - - def dr(self,date): - """ days remaining before settlement, on a given date """ - return(sum(self.series.index>date)) - - - def price(self,date): - """ price on a date """ - return self.series.get_value(date) - - -def returns(df): - """ daily return """ - return (df/df.shift(1)-1) - - -def recounstructVXX(): - """ - calculate VXX returns - needs a previously preprocessed file vix_futures.csv - """ - dataDir = os.path.expanduser('~')+'/twpData' - X = DataFrame.from_csv(dataDir+'/vix_futures.csv') # raw data table - - # build end dates list & futures classes - futures = [] - codes = X.columns - endDates = [] - for code in codes: - f = Future(X[code],code=code) - print code,':', f.settleDate - endDates.append(f.settleDate) - futures.append(f) - - endDates = np.array(endDates) - - # set roll period of each future - for i in range(1,len(futures)): - futures[i].dt = futures[i].dr(futures[i-1].settleDate) - - - # Y is the result table - idx = X.index - Y = DataFrame(index=idx, columns=['first','second','days_left','w1','w2', - 'ret','30days_avg']) - - # W is the weight matrix - W = DataFrame(data = np.zeros(X.values.shape),index=idx,columns = X.columns) - - # for VXX calculation see http://www.ipathetn.com/static/pdf/vix-prospectus.pdf - # page PS-20 - for date in idx: - i =np.nonzero(endDates>=date)[0][0] # find first not exprired future - first = futures[i] # first month futures class - second = futures[i+1] # second month futures class - - dr = first.dr(date) # number of remaining dates in the first futures contract - dt = first.dt #number of business days in roll period - - W.set_value(date,codes[i],100*dr/dt) - W.set_value(date,codes[i+1],100*(dt-dr)/dt) - - # this is all just debug info - p1 = first.price(date) - p2 = second.price(date) - w1 = 100*dr/dt - w2 = 100*(dt-dr)/dt - - Y.set_value(date,'first',p1) - Y.set_value(date,'second',p2) - Y.set_value(date,'days_left',first.dr(date)) - Y.set_value(date,'w1',w1) - Y.set_value(date,'w2',w2) - - - Y.set_value(date,'30days_avg',(p1*w1+p2*w2)/100) - - valCurr = (X*W.shift(1)).sum(axis=1) # value on day N - valYest = (X.shift(1)*W.shift(1)).sum(axis=1) # value on day N-1 - Y['ret'] = valCurr/valYest-1 # index return on day N - - return Y - - - - - -##-------------------Main script--------------------------- -if __name__=="__main__": - Y = recounstructVXX() - - print Y.head(30)# - Y.to_csv('reconstructedVXX.csv') - diff --git a/cookbook/reconstructVXX/vix_futures.csv b/cookbook/reconstructVXX/vix_futures.csv deleted file mode 100644 index 0140ee8..0000000 --- a/cookbook/reconstructVXX/vix_futures.csv +++ /dev/null @@ -1,1017 +0,0 @@ -index,2008_01,2008_02,2008_03,2008_04,2008_05,2008_06,2008_07,2008_08,2008_09,2008_10,2008_11,2008_12,2009_01,2009_02,2009_03,2009_04,2009_05,2009_06,2009_07,2009_08,2009_09,2009_10,2009_11,2009_12,2010_01,2010_02,2010_03,2010_04,2010_05,2010_06,2010_07,2010_08,2010_09,2010_10,2010_11,2010_12,2011_01,2011_02,2011_03,2011_04,2011_05,2011_06,2011_07,2011_08,2011_09,2011_10,2011_11,2011_12,2012_01,2012_02,2012_03,2012_04,2012_05,2012_06,2012_07,2012_08,2012_09 -2008-01-02 00:00:00,23.86,24.49,24.34,24.32,24.23,23.97,23.9,23.91,,,23.9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-03 00:00:00,23.42,24.52,24.31,24.26,24.21,24.04,23.83,23.77,,,23.92,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-04 00:00:00,24.68,25.3,25.01,24.83,24.65,24.57,24.53,24.42,,,24.35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-07 00:00:00,24.12,24.81,24.54,24.45,24.37,24.28,24.13,24.03,,,23.96,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-08 00:00:00,25.54,25.9,25.52,25.35,25.17,25.07,24.86,24.88,,,24.47,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-09 00:00:00,24.89,25.78,25.28,24.76,24.66,24.49,24.39,24.4,,,24.13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-10 00:00:00,24.07,24.95,24.51,24.36,24.27,24.15,23.88,24.05,,,23.91,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-11 00:00:00,24.96,26.15,26.05,25.92,25.5,25.5,25.25,25.01,,,25.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-14 00:00:00,23.36,25.1,25.07,25.07,24.89,24.9,24.77,24.52,,,24.36,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-15 00:00:00,24.04,25.24,25.03,25.1,24.91,24.5,24.71,24.61,,,24.65,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-16 00:00:00,24.18,24.99,25.03,25.1,24.94,24.5,24.42,24.4,,,24.16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-17 00:00:00,,26.97,26.62,26.73,26.36,26.25,26.2,25.99,,,25.87,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-18 00:00:00,,27.24,26.71,26.62,26.19,26.01,25.88,25.61,,,25.55,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-22 00:00:00,,27.73,26.38,26.45,25.77,25.7,25.71,25.51,,,25.35,22.7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-23 00:00:00,,26.4,25.3,25.43,24.98,25.0,24.85,24.63,,,24.25,25.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-24 00:00:00,,26.43,25.34,25.42,25.2,24.98,25.0,24.71,,,24.41,25.02,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-25 00:00:00,,26.75,25.8,25.74,25.63,25.38,25.2,24.98,,,24.73,24.97,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-28 00:00:00,,26.16,25.37,25.23,25.13,25.02,24.95,24.77,,,24.65,24.79,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-29 00:00:00,,26.25,25.25,25.39,25.11,24.79,24.82,24.67,,,24.3,24.55,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-30 00:00:00,,26.14,25.56,25.55,25.27,25.08,25.09,24.7,,,23.94,24.37,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-01-31 00:00:00,,25.64,25.31,25.15,24.78,24.52,24.56,24.11,,,23.72,23.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-01 00:00:00,,24.95,24.66,24.7,24.24,23.91,22.6,23.97,,,23.69,23.61,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-04 00:00:00,,25.81,25.56,25.17,24.51,24.2,23.96,24.01,,,23.97,23.88,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-05 00:00:00,,27.39,26.92,26.63,25.92,25.33,25.05,25.07,,,24.36,24.48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-06 00:00:00,,28.19,27.6,27.37,26.53,25.85,25.69,25.35,,,25.29,25.23,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-07 00:00:00,,27.62,27.25,26.7,26.01,25.75,25.46,25.15,,,25.03,24.7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-08 00:00:00,,28.39,27.63,27.56,26.88,26.25,25.96,25.6,,,25.41,25.17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-11 00:00:00,,27.88,26.97,26.81,26.22,26.07,25.87,25.3,,,24.85,24.74,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-12 00:00:00,,27.06,26.72,26.5,25.9,25.47,25.6,25.2,,,24.63,24.82,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-13 00:00:00,,26.0,25.81,25.78,25.33,25.18,25.06,24.85,,,24.52,24.14,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-14 00:00:00,,26.28,26.18,26.13,25.75,25.44,25.21,24.98,,,24.56,24.38,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-15 00:00:00,,26.07,25.93,25.91,25.5,25.36,25.17,24.68,,,24.45,24.41,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-19 00:00:00,,25.51,25.61,25.7,25.31,24.96,24.78,24.57,,,24.26,24.18,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-20 00:00:00,,,25.45,25.41,25.18,24.88,24.84,24.7,,,24.46,24.64,,24.2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-21 00:00:00,,,25.42,25.45,24.93,24.88,24.69,24.7,,,24.39,24.13,,23.88,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-22 00:00:00,,,24.87,24.83,24.66,24.62,24.77,24.7,,,24.33,24.14,,24.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-25 00:00:00,,,24.17,24.34,24.24,24.15,24.14,24.03,,,23.95,23.9,,23.21,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-26 00:00:00,,,23.71,24.18,24.15,24.07,24.0,23.83,,,23.78,23.5,,24.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-27 00:00:00,,,23.88,24.45,24.46,24.15,23.93,23.77,,,23.68,23.54,,24.15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-28 00:00:00,,,24.58,25.1,24.91,24.75,24.69,24.43,,,24.27,24.16,,24.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-02-29 00:00:00,,,26.1,26.36,26.31,25.85,25.57,25.42,,,24.93,24.63,,25.64,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-03 00:00:00,,,26.16,26.25,26.11,25.69,25.64,25.4,,,25.15,24.24,,25.18,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-04 00:00:00,,,25.72,25.79,25.71,25.5,25.65,25.5,,,24.64,24.4,,24.57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-05 00:00:00,,,24.83,25.38,25.1,24.85,24.86,24.76,,,24.15,23.88,,23.91,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-06 00:00:00,,,26.76,26.99,26.5,26.23,25.85,25.55,,,25.05,25.3,,24.83,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-07 00:00:00,,,26.91,26.87,26.41,25.94,25.91,25.39,,,25.2,24.71,,25.17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-10 00:00:00,,,27.75,27.6,26.99,26.56,26.42,25.9,,,25.45,25.38,,25.33,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-11 00:00:00,,,26.11,26.09,25.48,25.28,25.21,25.08,,,24.72,24.0,,24.21,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-12 00:00:00,,,26.68,26.92,26.51,26.01,25.71,25.56,,,25.31,24.82,,24.92,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-13 00:00:00,,,26.75,27.02,26.44,26.17,26.13,25.68,,,25.55,24.93,,25.35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-14 00:00:00,,,29.03,28.52,27.45,27.24,26.96,26.48,,,26.26,25.96,,25.84,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-17 00:00:00,,,30.57,28.54,27.37,27.1,27.12,26.44,,,25.85,25.05,,25.52,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-18 00:00:00,,,25.95,26.2,25.33,25.13,25.33,25.13,,,24.92,24.65,,24.78,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-19 00:00:00,,,25.67,27.41,26.53,26.21,26.2,25.68,,,25.46,25.38,,25.38,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-20 00:00:00,,,,27.0,26.08,25.86,25.8,25.52,,,25.27,24.98,,24.83,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-24 00:00:00,,,,26.35,25.71,25.41,25.6,25.3,24.71,,25.15,24.44,,23.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-25 00:00:00,,,,26.32,25.87,25.62,25.56,25.2,25.12,,24.91,24.38,,24.12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-26 00:00:00,,,,26.95,26.32,26.15,26.14,25.83,25.39,,25.24,24.9,,24.46,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-27 00:00:00,,,,26.64,26.46,26.22,26.05,25.81,25.35,,25.16,24.58,,24.51,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-28 00:00:00,,,,26.6,26.59,26.16,26.24,25.76,25.53,,25.43,24.65,,24.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-03-31 00:00:00,,,,26.01,26.3,25.92,25.78,25.62,25.53,,25.32,24.92,,24.77,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-01 00:00:00,,,,24.0,24.85,24.59,24.58,24.5,24.55,,24.32,23.94,,24.09,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-02 00:00:00,,,,24.64,25.03,24.55,24.74,24.47,24.57,,23.86,23.72,,24.03,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-03 00:00:00,,,,24.27,24.94,24.65,24.54,24.57,24.45,,24.2,24.03,,24.15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-04 00:00:00,,,,23.96,24.95,24.72,24.68,24.68,24.0,,24.38,23.92,,23.88,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-07 00:00:00,,,,23.01,24.26,24.12,24.2,23.96,24.14,,23.89,23.74,,23.95,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-08 00:00:00,,,,23.02,24.07,23.91,24.01,24.13,24.19,,24.1,24.1,,24.02,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-09 00:00:00,,,,23.63,24.66,24.48,24.59,24.48,24.71,,24.38,24.32,,24.27,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-10 00:00:00,,,,22.85,24.33,24.15,24.15,24.05,24.23,,24.1,23.85,,24.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-11 00:00:00,,,,23.91,24.98,25.1,25.14,24.72,25.06,,24.73,24.58,,24.81,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-14 00:00:00,,,,23.84,24.88,24.83,24.99,24.8,24.74,,24.57,24.48,,24.41,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-15 00:00:00,,,,22.87,24.41,24.54,24.59,24.54,24.57,,24.27,24.14,,24.43,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-16 00:00:00,,,,21.78,22.96,23.23,23.5,23.46,23.72,,23.45,23.2,,23.57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-17 00:00:00,,,,,23.03,23.55,23.61,23.44,23.75,,23.58,23.39,,23.71,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-18 00:00:00,,,,,22.2,22.84,23.14,23.18,23.36,,23.22,23.0,,23.55,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-21 00:00:00,,,,,21.92,22.43,22.81,22.92,23.29,24.21,23.07,22.94,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-22 00:00:00,,,,,22.1,22.62,23.15,23.21,23.56,23.51,23.5,23.1,23.7,23.48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-23 00:00:00,,,,,21.86,22.41,23.16,23.11,23.63,23.71,23.47,23.38,23.67,23.73,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-24 00:00:00,,,,,21.23,22.05,22.85,22.87,23.26,23.33,23.28,23.15,23.56,23.63,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-25 00:00:00,,,,,20.69,21.52,22.33,22.4,22.59,22.53,22.71,22.4,23.22,22.49,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-28 00:00:00,,,,,20.54,21.33,22.05,22.05,22.6,22.65,22.45,22.21,22.64,23.05,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-29 00:00:00,,,,,20.81,21.59,22.3,22.38,22.67,22.85,22.78,22.53,22.94,23.55,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-04-30 00:00:00,,,,,21.24,22.14,22.49,22.45,22.79,22.72,22.84,22.4,22.67,22.69,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-01 00:00:00,,,,,19.86,20.95,21.6,21.51,22.01,21.14,21.68,21.63,22.11,22.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-02 00:00:00,,,,,19.66,20.63,21.42,21.47,21.59,21.69,21.35,21.3,21.54,21.8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-05 00:00:00,,,,,19.69,20.99,21.69,21.6,21.91,21.89,21.67,21.46,21.74,21.74,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-06 00:00:00,,,,,18.82,20.26,21.16,21.34,21.67,21.55,21.55,21.44,21.5,21.66,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-07 00:00:00,,,,,19.7,21.21,22.07,22.08,22.29,22.28,22.24,21.89,22.06,22.86,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-08 00:00:00,,,,,19.67,21.25,22.18,22.17,22.34,22.34,22.15,21.88,22.49,22.13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-09 00:00:00,,,,,19.84,21.45,22.27,22.29,22.51,22.63,22.68,22.27,22.42,22.3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-12 00:00:00,,,,,18.94,20.82,21.87,21.87,21.95,22.01,21.96,21.7,21.9,22.01,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-13 00:00:00,,,,,18.7,20.78,21.88,21.88,22.08,22.08,22.04,21.91,22.18,22.23,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-14 00:00:00,,,,,18.3,20.32,21.53,21.68,22.09,22.11,21.92,21.74,22.17,22.59,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-15 00:00:00,,,,,17.43,19.88,21.25,21.37,21.56,21.53,21.37,21.36,21.51,21.71,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-16 00:00:00,,,,,17.15,20.14,21.5,21.69,21.95,22.02,21.87,21.81,21.88,22.03,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-19 00:00:00,,,,,16.64,19.76,21.58,21.73,22.0,22.04,21.98,21.94,22.2,22.13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-20 00:00:00,,,,,17.37,20.82,22.35,22.68,22.57,22.58,22.69,22.46,22.79,22.72,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-21 00:00:00,,,,,17.16,22.14,23.58,23.84,23.76,23.96,23.76,23.16,23.64,23.86,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-22 00:00:00,,,,,,21.72,23.56,23.72,23.7,23.6,23.5,23.16,23.19,23.6,24.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-23 00:00:00,,,,,,22.23,24.04,24.18,24.22,24.21,23.97,23.48,23.49,23.83,23.69,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-27 00:00:00,,,,,,21.49,23.7,23.83,23.78,23.68,23.53,23.14,23.45,23.83,23.97,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-28 00:00:00,,,,,,21.33,23.25,23.55,23.59,23.55,23.38,23.08,23.44,23.6,23.92,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-29 00:00:00,,,,,,19.97,22.07,22.66,23.11,23.1,22.76,22.62,22.96,23.16,23.03,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-05-30 00:00:00,,,,,,19.38,21.77,22.63,22.99,22.97,22.76,22.72,23.07,23.01,22.98,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-02 00:00:00,,,,,,20.64,22.8,23.25,23.48,23.62,23.35,22.96,23.4,23.61,23.11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-03 00:00:00,,,,,,21.07,23.18,23.6,23.84,23.86,23.69,23.51,24.02,23.94,23.68,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-04 00:00:00,,,,,,21.3,23.09,23.44,24.02,23.98,23.84,23.66,24.05,24.1,23.95,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-05 00:00:00,,,,,,19.91,22.13,23.01,23.46,23.37,23.07,22.98,23.4,23.44,23.39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-06 00:00:00,,,,,,22.98,23.94,24.18,24.66,24.48,24.28,23.93,24.46,24.45,24.16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-09 00:00:00,,,,,,22.7,23.43,24.03,24.59,24.55,24.21,24.04,24.45,24.58,24.39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-10 00:00:00,,,,,,22.72,23.47,23.81,24.36,24.42,24.24,23.96,24.46,24.5,24.22,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-11 00:00:00,,,,,,23.75,24.05,24.27,24.74,24.69,24.36,24.15,24.44,24.45,24.61,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-12 00:00:00,,,,,,22.85,23.88,23.97,24.78,24.52,24.33,24.1,24.48,24.48,24.31,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-13 00:00:00,,,,,,21.62,23.0,23.2,23.89,23.78,23.75,23.56,23.92,24.18,24.09,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-16 00:00:00,,,,,,20.86,22.74,22.89,23.44,23.4,23.34,23.36,23.56,23.57,23.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-17 00:00:00,,,,,,21.05,22.68,22.86,23.43,23.47,23.38,23.26,23.53,23.64,23.63,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-18 00:00:00,,,,,,21.54,23.35,23.37,23.69,23.85,23.55,23.44,23.61,23.75,23.79,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-19 00:00:00,,,,,,,22.93,23.17,23.57,23.45,23.38,23.17,23.36,23.58,23.52,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-20 00:00:00,,,,,,,23.51,23.43,23.7,23.72,23.54,23.43,23.38,23.87,23.72,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-23 00:00:00,,,,,,,23.51,23.49,23.59,23.61,23.47,23.22,23.26,23.53,23.47,23.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-24 00:00:00,,,,,,,23.63,23.7,23.65,23.54,23.52,23.15,23.43,23.5,23.59,24.3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-25 00:00:00,,,,,,,22.61,22.75,23.03,23.01,22.88,22.47,22.8,23.02,22.99,22.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-26 00:00:00,,,,,,,24.72,24.25,24.41,24.21,24.06,23.94,24.36,24.26,24.74,24.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-27 00:00:00,,,,,,,24.55,24.18,24.36,24.18,23.73,23.5,23.97,24.11,23.97,23.96,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-06-30 00:00:00,,,,,,,24.19,23.93,24.11,24.02,23.68,23.41,23.78,23.85,23.58,23.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-01 00:00:00,,,,,,,24.19,23.8,24.06,23.85,23.57,23.32,23.76,23.64,23.6,23.69,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-02 00:00:00,,,,,,,25.53,24.95,24.78,24.55,24.21,23.87,24.35,24.2,24.22,24.47,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-03 00:00:00,,,,,,,25.39,24.69,24.6,24.33,23.94,23.44,23.93,24.1,23.99,24.82,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-07 00:00:00,,,,,,,25.85,24.78,24.72,24.69,24.16,23.87,24.06,24.15,24.11,25.11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-08 00:00:00,,,,,,,23.96,23.54,23.52,23.44,23.14,22.99,23.42,23.19,23.42,23.49,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-09 00:00:00,,,,,,,25.47,24.69,24.56,24.51,24.11,23.88,24.18,24.15,24.06,24.06,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-10 00:00:00,,,,,,,25.61,24.86,24.7,24.52,24.1,23.79,24.29,24.25,24.14,24.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-11 00:00:00,,,,,,,27.15,25.25,24.99,24.78,24.44,24.04,24.42,24.55,24.22,24.27,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-14 00:00:00,,,,,,,28.03,25.89,25.49,24.93,24.47,24.23,24.72,24.62,24.47,24.77,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-15 00:00:00,,,,,,,28.43,26.12,26.04,25.3,24.84,24.42,24.62,24.26,24.34,24.34,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-16 00:00:00,,,,,,,28.4,24.72,24.48,23.94,23.57,23.0,23.47,23.5,23.01,23.41,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-17 00:00:00,,,,,,,,24.25,23.99,23.7,23.14,22.71,23.2,23.26,22.87,22.92,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-18 00:00:00,,,,,,,,24.05,23.8,23.57,23.03,22.58,23.03,23.12,23.03,22.87,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-21 00:00:00,,,,,,,,23.4,23.44,23.28,22.77,22.43,22.69,22.95,22.76,22.83,,,23.87,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-22 00:00:00,,,,,,,,22.47,22.74,22.74,22.36,21.95,22.31,22.49,22.4,22.42,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-23 00:00:00,,,,,,,,22.43,22.78,22.86,22.71,22.07,22.53,22.7,22.39,22.36,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-24 00:00:00,,,,,,,,23.55,23.72,23.91,23.66,23.17,23.49,23.45,23.28,23.3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-25 00:00:00,,,,,,,,23.45,23.63,23.77,23.6,22.95,23.26,23.31,23.06,23.11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-28 00:00:00,,,,,,,,24.25,24.24,24.3,24.11,23.54,23.69,23.65,23.51,23.76,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-29 00:00:00,,,,,,,,22.68,22.99,23.21,23.17,22.54,22.78,23.06,22.98,22.98,23.03,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-30 00:00:00,,,,,,,,21.57,22.1,22.46,22.52,21.96,22.34,22.6,22.59,22.61,22.89,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-07-31 00:00:00,,,,,,,,22.77,22.94,23.02,23.01,22.62,22.87,22.9,22.75,22.83,22.85,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-01 00:00:00,,,,,,,,22.95,23.04,23.16,23.09,22.68,22.96,23.13,22.89,22.97,23.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-04 00:00:00,,,,,,,,22.78,23.01,23.16,23.06,22.7,22.89,23.03,22.97,23.1,23.14,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-05 00:00:00,,,,,,,,21.44,22.12,22.47,22.42,22.0,22.37,22.57,22.35,22.38,22.67,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-06 00:00:00,,,,,,,,20.7,21.58,22.24,22.38,21.93,22.34,22.41,22.28,22.29,22.45,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-07 00:00:00,,,,,,,,21.51,22.52,22.94,22.88,22.44,22.58,22.85,22.32,22.41,22.34,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-08 00:00:00,,,,,,,,20.91,21.87,22.62,22.69,22.31,22.52,22.68,22.18,22.31,22.27,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-11 00:00:00,,,,,,,,20.29,21.68,22.59,22.65,22.23,22.53,22.83,22.38,22.44,22.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-12 00:00:00,,,,,,,,21.28,22.46,22.91,23.02,22.6,23.04,23.3,22.62,22.62,22.45,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-13 00:00:00,,,,,,,,21.5,22.93,23.26,23.24,22.85,23.15,22.97,22.9,22.97,22.9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-14 00:00:00,,,,,,,,20.8,22.15,22.67,22.68,22.45,22.84,22.95,22.65,22.74,22.64,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-15 00:00:00,,,,,,,,20.18,21.92,22.66,22.71,22.47,22.72,22.76,22.65,22.67,22.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-18 00:00:00,,,,,,,,20.66,22.21,22.98,23.01,22.65,22.99,23.08,22.88,23.03,22.8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-19 00:00:00,,,,,,,,21.0,22.93,23.56,23.53,22.9,23.42,23.64,23.31,23.34,23.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-20 00:00:00,,,,,,,,20.83,22.45,23.16,23.17,22.73,23.21,23.32,23.1,23.21,23.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-21 00:00:00,,,,,,,,,22.19,23.25,23.23,22.73,23.15,23.45,23.17,23.18,23.09,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-22 00:00:00,,,,,,,,,21.59,22.92,23.08,22.74,23.18,23.44,23.29,23.13,22.88,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-25 00:00:00,,,,,,,,,22.64,23.45,23.64,23.3,23.62,23.84,23.46,23.44,23.36,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-26 00:00:00,,,,,,,,,22.4,23.24,23.41,23.15,23.53,23.74,23.37,23.37,23.22,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-27 00:00:00,,,,,,,,,21.8,22.94,23.1,22.88,23.25,23.43,23.16,23.17,22.97,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-28 00:00:00,,,,,,,,,21.12,22.68,22.91,22.61,23.04,23.23,23.07,23.1,22.98,23.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-08-29 00:00:00,,,,,,,,,21.7,22.99,23.31,22.95,23.5,23.59,23.46,23.39,23.05,23.05,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-02 00:00:00,,,,,,,,,22.08,23.19,23.42,23.16,23.62,23.73,23.56,23.43,23.17,23.22,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-03 00:00:00,,,,,,,,,21.64,23.1,23.42,23.2,23.66,23.83,23.64,23.35,23.3,23.3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-04 00:00:00,,,,,,,,,23.78,24.31,24.46,24.03,24.47,24.48,24.27,24.3,23.9,24.04,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-05 00:00:00,,,,,,,,,23.08,23.98,24.1,23.56,24.19,24.17,24.1,24.15,23.76,24.06,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-08 00:00:00,,,,,,,,,21.99,23.39,23.63,23.18,23.63,23.68,23.48,23.56,23.16,23.02,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-09 00:00:00,,,,,,,,,24.22,24.71,24.56,24.09,24.55,24.7,24.53,24.42,24.26,24.44,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-10 00:00:00,,,,,,,,,23.59,24.31,24.24,23.79,24.23,24.29,24.28,24.2,24.05,24.26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-11 00:00:00,,,,,,,,,23.83,24.49,24.22,23.68,24.21,24.38,24.39,24.36,24.08,24.2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-12 00:00:00,,,,,,,,,24.68,24.57,24.42,23.97,24.37,24.42,24.37,24.34,24.16,24.21,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-15 00:00:00,,,,,,,,,28.84,25.73,25.13,24.73,25.21,25.13,25.1,24.46,24.71,24.82,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-16 00:00:00,,,,,,,,,29.68,25.17,24.96,24.49,24.76,24.64,24.73,24.57,24.31,24.03,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-17 00:00:00,,,,,,,,,31.54,26.61,25.93,25.44,25.58,25.32,25.6,25.41,25.1,26.57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-18 00:00:00,,,,,,,,,,25.31,25.01,24.65,24.78,24.47,24.7,24.34,23.86,24.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-19 00:00:00,,,,,,,,,,24.74,24.38,24.2,24.37,24.18,24.41,24.07,23.57,24.12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-22 00:00:00,,,,,,,,,,26.56,25.41,25.11,25.39,25.01,25.13,24.91,24.65,24.65,25.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-23 00:00:00,,,,,,,,,,29.02,26.85,25.94,26.1,25.74,26.0,25.67,25.48,25.18,24.95,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-24 00:00:00,,,,,,,,,,28.65,26.68,25.61,25.68,25.65,25.78,25.49,25.44,25.39,24.88,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-25 00:00:00,,,,,,,,,,27.74,25.99,25.12,25.32,25.4,25.54,25.2,24.98,24.84,24.72,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-26 00:00:00,,,,,,,,,,28.64,26.25,25.17,25.43,25.46,25.52,25.27,25.1,25.03,24.93,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-29 00:00:00,,,,,,,,,,32.69,29.84,28.03,27.87,27.4,27.45,27.82,26.55,28.12,27.22,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-09-30 00:00:00,,,,,,,,,,30.66,28.22,26.68,26.77,26.6,26.54,26.03,25.75,25.46,26.18,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-01 00:00:00,,,,,,,,,,31.87,28.85,27.04,27.0,26.94,26.75,26.23,26.05,26.1,26.36,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-02 00:00:00,,,,,,,,,,34.1,30.64,28.24,27.8,27.58,27.39,27.16,27.06,27.12,26.87,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-03 00:00:00,,,,,,,,,,35.67,31.2,28.56,28.05,27.84,27.56,27.6,27.39,27.39,27.18,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-06 00:00:00,,,,,,,,,,37.37,31.94,29.32,28.66,28.27,28.3,27.86,27.48,27.5,27.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-07 00:00:00,,,,,,,,,,41.83,34.32,30.43,29.73,28.85,27.96,27.72,27.42,25.75,23.46,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-08 00:00:00,,,,,,,,,,45.56,35.39,31.21,30.2,28.96,28.02,27.73,27.6,26.45,26.85,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-09 00:00:00,,,,,,,,,,52.3,37.68,33.38,31.6,30.96,28.98,29.06,28.98,28.07,28.81,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-10 00:00:00,,,,,,,,,,56.71,38.31,33.79,32.42,31.35,29.3,28.91,28.58,28.11,28.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-13 00:00:00,,,,,,,,,,50.64,36.07,31.78,30.52,29.83,28.17,27.58,26.98,26.78,27.07,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-14 00:00:00,,,,,,,,,,49.05,37.94,32.24,31.38,30.58,28.85,28.03,27.43,27.01,27.09,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-15 00:00:00,,,,,,,,,,58.18,42.7,35.55,34.49,33.85,31.13,29.56,28.16,26.82,28.05,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-16 00:00:00,,,,,,,,,,63.88,42.78,35.47,34.71,34.32,32.65,31.17,29.26,27.82,28.13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-17 00:00:00,,,,,,,,,,63.25,47.04,37.28,36.08,34.75,33.1,31.65,30.68,28.62,29.61,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-20 00:00:00,,,,,,,,,,52.31,45.05,34.8,34.22,33.79,32.12,30.91,29.4,27.85,28.53,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-21 00:00:00,,,,,,,,,,52.8,43.8,36.93,34.95,33.82,32.51,31.97,30.37,29.12,29.18,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-22 00:00:00,,,,,,,,,,63.04,48.33,39.71,37.85,36.03,34.87,33.9,32.83,32.17,32.24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-23 00:00:00,,,,,,,,,,,50.02,40.14,38.11,36.48,35.12,34.59,33.74,32.08,32.69,27.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-24 00:00:00,,,,,,,,,,,55.82,43.56,40.69,39.23,37.75,37.39,35.99,36.25,37.21,26.94,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-27 00:00:00,,,,,,,,,,,59.29,44.88,41.78,39.98,38.75,38.41,37.51,36.45,36.51,34.55,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-28 00:00:00,,,,,,,,,,,53.7,42.77,39.2,37.16,35.79,35.47,34.99,34.3,34.41,37.04,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-29 00:00:00,,,,,,,,,,,56.41,44.16,41.28,38.47,36.74,34.96,35.6,34.29,34.51,32.16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-30 00:00:00,,,,,,,,,,,55.37,44.2,41.4,38.84,37.41,35.77,36.5,34.46,34.22,18.14,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-10-31 00:00:00,,,,,,,,,,,54.57,44.93,41.97,39.34,37.75,35.95,35.46,35.2,34.7,35.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-03 00:00:00,,,,,,,,,,,51.96,44.71,41.78,39.0,37.2,35.69,34.81,35.09,35.4,35.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-04 00:00:00,,,,,,,,,,,46.43,41.86,39.85,37.84,35.6,34.39,34.44,33.76,33.83,30.04,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-05 00:00:00,,,,,,,,,,,50.2,43.85,42.21,40.11,37.95,36.59,35.58,35.44,34.73,30.68,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-06 00:00:00,,,,,,,,,,,57.58,47.8,45.65,42.51,39.81,38.75,35.95,38.28,37.78,35.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-07 00:00:00,,,,,,,,,,,54.65,47.48,45.1,42.02,39.42,38.29,37.81,37.13,36.23,36.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-10 00:00:00,,,,,,,,,,,56.19,48.2,45.48,42.73,39.72,38.26,37.79,37.03,36.28,36.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-11 00:00:00,,,,,,,,,,,58.38,49.38,46.62,43.54,40.51,38.86,38.24,37.53,36.58,37.01,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-12 00:00:00,,,,,,,,,,,63.71,52.92,47.8,45.13,41.83,39.87,39.12,37.61,36.39,34.82,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-13 00:00:00,,,,,,,,,,,56.87,50.03,47.32,44.28,40.53,39.15,38.01,37.59,37.22,34.82,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-14 00:00:00,,,,,,,,,,,62.9,53.51,49.66,46.09,42.35,40.13,39.28,38.82,37.34,34.82,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-17 00:00:00,,,,,,,,,,,67.95,56.25,51.71,47.43,43.41,41.29,40.15,40.02,38.97,34.82,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-18 00:00:00,,,,,,,,,,,67.04,57.29,52.59,48.59,44.27,42.18,40.65,39.68,38.72,34.82,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-19 00:00:00,,,,,,,,,,,67.22,62.9,56.87,52.26,47.34,44.74,43.32,41.53,41.15,38.18,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-20 00:00:00,,,,,,,,,,,,66.23,59.77,54.67,50.58,47.02,44.57,42.64,41.95,38.18,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-21 00:00:00,,,,,,,,,,,,62.78,56.9,53.11,49.06,45.83,43.12,42.89,42.34,34.81,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-24 00:00:00,,,,,,,,,,,,58.64,54.15,50.33,46.78,43.82,41.19,41.14,40.64,41.91,36.15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-25 00:00:00,,,,,,,,,,,,57.18,52.61,49.1,45.43,42.94,40.69,39.59,39.52,36.36,38.23,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-26 00:00:00,,,,,,,,,,,,53.18,50.85,47.23,43.61,41.34,39.5,39.24,39.42,35.61,38.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-11-28 00:00:00,,,,,,,,,,,,53.21,50.6,47.17,43.52,40.98,39.79,39.28,39.6,42.77,40.34,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-01 00:00:00,,,,,,,,,,,,60.45,56.29,51.91,48.13,45.47,43.67,43.76,42.83,38.25,42.36,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-02 00:00:00,,,,,,,,,,,,57.93,55.3,51.78,47.57,45.16,43.14,42.94,42.18,44.94,42.28,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-03 00:00:00,,,,,,,,,,,,57.73,55.21,51.21,47.12,44.95,42.95,42.66,41.49,41.25,40.35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-04 00:00:00,,,,,,,,,,,,60.49,57.62,53.94,49.35,46.68,44.28,43.37,42.61,44.13,40.89,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-05 00:00:00,,,,,,,,,,,,58.32,56.75,53.58,48.7,46.03,44.06,43.86,42.92,38.75,42.53,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-08 00:00:00,,,,,,,,,,,,55.26,54.67,52.72,48.23,45.38,43.93,44.06,43.74,42.25,42.45,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-09 00:00:00,,,,,,,,,,,,56.4,55.38,53.33,48.82,46.79,45.26,44.84,44.43,43.88,42.9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-10 00:00:00,,,,,,,,,,,,55.26,54.44,52.76,48.48,46.35,44.44,44.58,44.45,38.75,42.46,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-11 00:00:00,,,,,,,,,,,,55.06,55.32,53.38,49.09,47.07,45.0,45.0,43.88,43.88,42.91,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-12 00:00:00,,,,,,,,,,,,54.58,54.46,52.8,48.58,46.63,44.67,43.95,43.77,43.88,43.7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-15 00:00:00,,,,,,,,,,,,55.7,54.84,52.63,48.63,46.44,44.49,43.44,43.7,43.88,41.16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-16 00:00:00,,,,,,,,,,,,52.44,52.25,50.28,46.75,44.8,43.33,42.5,41.91,43.88,37.69,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-17 00:00:00,,,,,,,,,,,,51.29,52.07,49.94,46.18,43.91,42.23,40.82,40.48,40.18,38.68,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-18 00:00:00,,,,,,,,,,,,,50.31,48.93,45.61,43.22,41.4,40.26,40.0,40.43,39.38,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-19 00:00:00,,,,,,,,,,,,,47.35,46.53,43.57,41.76,40.52,39.07,39.17,39.14,38.27,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-22 00:00:00,,,,,,,,,,,,,45.51,45.63,42.67,41.43,40.28,39.91,39.45,39.66,36.73,36.15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-23 00:00:00,,,,,,,,,,,,,46.15,46.54,43.39,42.14,40.95,39.74,40.51,39.75,39.38,35.53,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-24 00:00:00,,,,,,,,,,,,,45.73,45.96,42.93,41.75,41.2,40.0,39.95,39.12,37.96,36.15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-26 00:00:00,,,,,,,,,,,,,45.15,45.65,42.81,41.61,41.04,40.42,40.02,39.71,37.67,37.62,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-29 00:00:00,,,,,,,,,,,,,46.34,46.76,43.49,42.51,41.27,41.03,40.18,39.5,38.53,37.86,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-30 00:00:00,,,,,,,,,,,,,44.18,45.08,42.1,40.97,40.25,39.81,39.36,38.45,37.66,37.35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2008-12-31 00:00:00,,,,,,,,,,,,,41.94,42.93,40.41,38.55,37.71,38.28,38.29,38.47,37.42,36.08,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-02 00:00:00,,,,,,,,,,,,,38.7,39.91,37.69,36.22,36.05,35.9,36.36,36.5,35.35,35.33,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-05 00:00:00,,,,,,,,,,,,,39.96,40.16,37.83,36.47,36.06,35.64,35.93,36.02,35.06,35.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-06 00:00:00,,,,,,,,,,,,,39.53,39.55,37.5,36.74,36.06,36.05,35.72,35.53,34.87,34.63,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-07 00:00:00,,,,,,,,,,,,,43.52,42.5,40.09,38.63,37.9,37.45,36.86,36.37,35.57,35.48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-08 00:00:00,,,,,,,,,,,,,42.97,42.72,39.72,38.4,37.1,37.22,37.2,36.49,36.64,36.44,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-09 00:00:00,,,,,,,,,,,,,44.55,44.15,40.95,38.66,37.63,37.15,37.09,36.17,36.17,35.19,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-12 00:00:00,,,,,,,,,,,,,48.04,47.74,43.41,40.84,39.03,38.56,37.91,37.61,35.89,36.52,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-13 00:00:00,,,,,,,,,,,,,46.67,46.81,43.43,40.93,38.95,38.56,38.27,37.79,37.43,35.98,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-14 00:00:00,,,,,,,,,,,,,51.79,50.56,45.74,42.88,40.98,39.67,39.38,38.6,38.11,37.24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-15 00:00:00,,,,,,,,,,,,,53.26,49.93,46.36,43.25,40.87,39.74,39.2,38.68,38.42,38.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-16 00:00:00,,,,,,,,,,,,,49.65,48.53,46.36,43.44,41.2,40.27,39.45,38.99,38.29,36.97,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-20 00:00:00,,,,,,,,,,,,,57.9,54.66,51.08,47.54,44.42,42.38,41.33,41.36,40.45,38.45,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-21 00:00:00,,,,,,,,,,,,,49.88,51.13,47.36,44.4,41.62,39.98,39.47,38.97,39.47,37.95,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-22 00:00:00,,,,,,,,,,,,,,50.54,47.37,45.25,42.25,40.42,39.75,39.85,39.2,38.75,35.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-23 00:00:00,,,,,,,,,,,,,,50.16,47.2,45.13,42.31,40.29,39.46,38.95,38.28,37.85,37.67,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-26 00:00:00,,,,,,,,,,,,,,47.55,45.63,44.33,41.59,39.86,39.01,38.61,37.64,36.57,35.9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-27 00:00:00,,,,,,,,,,,,,,45.16,43.51,42.4,40.1,38.46,37.67,37.03,37.08,35.95,35.05,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-28 00:00:00,,,,,,,,,,,,,,42.31,40.75,40.29,38.36,37.63,37.19,36.64,36.52,36.09,35.59,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-29 00:00:00,,,,,,,,,,,,,,43.38,40.88,39.96,37.89,37.0,36.6,35.61,35.71,35.45,34.98,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-01-30 00:00:00,,,,,,,,,,,,,,44.99,42.18,41.1,38.99,38.17,37.88,37.07,36.92,36.46,35.59,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-02 00:00:00,,,,,,,,,,,,,,45.35,42.3,41.4,39.55,38.65,38.35,37.7,37.4,36.8,36.05,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-03 00:00:00,,,,,,,,,,,,,,43.15,40.95,40.3,38.65,38.45,38.05,37.75,37.05,36.55,35.8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-04 00:00:00,,,,,,,,,,,,,,43.75,41.1,40.1,38.3,37.95,37.65,37.2,36.75,36.4,35.65,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-05 00:00:00,,,,,,,,,,,,,,43.25,40.5,39.55,38.05,37.55,37.35,37.1,37.0,36.85,36.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-06 00:00:00,,,,,,,,,,,,,,42.6,40.1,39.15,37.9,37.55,36.85,36.45,36.25,36.15,35.55,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-09 00:00:00,,,,,,,,,,,,,,42.5,40.5,39.65,38.05,37.65,37.1,36.65,36.55,36.3,35.45,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-10 00:00:00,,,,,,,,,,,,,,45.6,42.9,41.45,39.15,38.45,37.9,37.3,37.05,36.7,35.8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-11 00:00:00,,,,,,,,,,,,,,44.6,42.2,40.65,38.7,38.25,37.75,37.2,36.8,36.5,35.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-12 00:00:00,,,,,,,,,,,,,,42.55,41.6,40.7,38.65,37.85,37.45,36.85,36.95,36.7,35.65,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-13 00:00:00,,,,,,,,,,,,,,43.6,42.35,41.4,39.25,38.25,37.65,36.85,36.45,36.15,35.4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-17 00:00:00,,,,,,,,,,,,,,48.0,44.05,42.3,40.25,39.25,38.65,37.75,37.35,36.8,36.2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-18 00:00:00,,,,,,,,,,,,,,48.4,44.85,42.65,40.6,39.5,38.65,37.75,37.2,36.75,36.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-19 00:00:00,,,,,,,,,,,,,,,44.55,43.2,41.1,39.95,39.15,37.9,37.8,36.75,35.75,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-20 00:00:00,,,,,,,,,,,,,,,46.7,44.75,41.95,40.95,40.25,38.7,38.15,37.35,36.3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-23 00:00:00,,,,,,,,,,,,,,,49.05,46.9,43.45,41.9,40.9,39.55,38.6,37.8,36.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-24 00:00:00,,,,,,,,,,,,,,,44.5,43.9,41.2,40.15,39.2,38.2,37.9,37.1,36.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-25 00:00:00,,,,,,,,,,,,,,,43.45,43.25,40.95,40.1,39.5,38.3,37.95,37.55,36.45,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-26 00:00:00,,,,,,,,,,,,,,,44.0,43.75,41.35,40.65,40.05,39.05,38.75,38.2,37.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-02-27 00:00:00,,,,,,,,,,,,,,,44.45,43.9,41.7,40.95,40.35,39.4,38.8,38.25,37.2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-02 00:00:00,,,,,,,,,,,,,,,47.85,46.05,43.15,42.15,41.35,39.9,39.55,38.95,37.75,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-03 00:00:00,,,,,,,,,,,,,,,48.45,46.35,43.7,42.05,41.55,39.85,39.65,38.6,37.4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-04 00:00:00,,,,,,,,,,,,,,,44.75,42.9,40.55,39.8,39.25,38.05,37.65,37.2,36.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-05 00:00:00,,,,,,,,,,,,,,,47.35,44.45,41.75,40.2,39.55,38.55,37.95,37.8,36.9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-06 00:00:00,,,,,,,,,,,,,,,46.65,44.15,41.4,40.1,39.6,38.65,38.25,37.95,36.9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-09 00:00:00,,,,,,,,,,,,,,,47.05,44.9,41.8,40.35,39.75,38.6,38.1,37.8,36.65,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-10 00:00:00,,,,,,,,,,,,,,,43.15,41.6,38.95,37.9,37.25,36.35,36.55,36.05,35.15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-11 00:00:00,,,,,,,,,,,,,,,42.65,41.6,39.05,37.85,37.25,36.15,35.8,35.55,34.7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-12 00:00:00,,,,,,,,,,,,,,,41.1,41.1,38.6,37.45,37.05,35.85,35.5,35.25,34.3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-13 00:00:00,,,,,,,,,,,,,,,42.1,41.6,39.15,38.2,37.3,36.25,35.85,35.65,34.75,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-16 00:00:00,,,,,,,,,,,,,,,43.0,43.1,40.1,38.7,37.8,36.75,36.15,35.75,34.8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-17 00:00:00,,,,,,,,,,,,,,,40.05,41.3,39.1,38.2,37.45,36.25,36.05,35.35,34.4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-18 00:00:00,,,,,,,,,,,,,,,40.62,40.95,39.15,38.45,37.9,36.75,36.15,35.75,34.9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-19 00:00:00,,,,,,,,,,,,,,,,43.7,41.55,40.2,39.5,38.15,37.5,36.9,36.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-20 00:00:00,,,,,,,,,,,,,,,,47.05,44.45,42.5,41.55,39.85,39.05,38.1,37.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-23 00:00:00,,,,,,,,,,,,,,,,43.35,41.75,40.55,39.55,38.5,37.7,37.1,36.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-24 00:00:00,,,,,,,,,,,,,,,,44.0,42.25,40.95,40.05,39.0,38.0,37.3,36.35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-25 00:00:00,,,,,,,,,,,,,,,,42.75,41.45,40.5,39.9,38.65,37.95,37.25,36.35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-26 00:00:00,,,,,,,,,,,,,,,,41.45,40.45,39.8,39.25,38.05,37.55,37.0,36.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-27 00:00:00,,,,,,,,,,,,,,,,42.95,41.6,40.8,40.2,39.3,38.55,37.9,36.65,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-30 00:00:00,,,,,,,,,,,,,,,,46.35,44.05,42.7,41.8,40.5,39.8,39.1,38.15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-03-31 00:00:00,,,,,,,,,,,,,,,,45.05,43.95,42.75,41.75,40.35,39.55,38.8,37.9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-01 00:00:00,,,,,,,,,,,,,,,,43.65,43.25,42.0,41.2,39.95,39.1,38.25,37.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-02 00:00:00,,,,,,,,,,,,,,,,42.95,42.5,41.85,41.25,40.0,39.45,38.3,37.35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-03 00:00:00,,,,,,,,,,,,,,,,41.7,41.8,41.25,40.85,39.65,39.15,38.35,37.4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-06 00:00:00,,,,,,,,,,,,,,,,41.95,42.15,41.65,41.3,40.05,39.55,38.5,37.8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-07 00:00:00,,,,,,,,,,,,,,,,41.65,42.45,42.0,41.55,40.4,39.75,38.95,38.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-08 00:00:00,,,,,,,,,,,,,,,,40.6,41.55,41.15,40.95,40.05,39.7,38.85,38.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-09 00:00:00,,,,,,,,,,,,,,,,38.3,39.9,39.7,39.75,39.15,38.75,37.8,37.35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-13 00:00:00,,,,,,,,,,,,,,,,37.05,39.7,39.5,39.65,39.15,38.75,37.9,37.35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-14 00:00:00,,,,,,,,,,,,,,,,37.85,39.6,39.6,39.6,39.1,38.85,38.2,37.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-15 00:00:00,,,,,,,,,,,,,,,,38.2,38.8,38.8,38.9,38.55,38.5,38.15,37.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-16 00:00:00,,,,,,,,,,,,,,,,,37.35,37.5,37.65,37.5,37.5,37.25,36.8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-17 00:00:00,,,,,,,,,,,,,,,,,36.6,36.65,36.85,36.7,36.8,36.55,36.4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-20 00:00:00,,,,,,,,,,,,,,,,,39.5,38.95,38.75,38.15,38.05,37.65,37.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-21 00:00:00,,,,,,,,,,,,,,,,,37.9,37.65,37.7,37.3,37.3,37.1,36.75,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-22 00:00:00,,,,,,,,,,,,,,,,,38.45,38.05,38.05,37.8,37.7,37.4,37.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-23 00:00:00,,,,,,,,,,,,,,,,,37.8,37.4,37.45,37.15,37.15,36.85,36.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-24 00:00:00,,,,,,,,,,,,,,,,,37.8,37.65,37.65,37.4,37.45,37.1,36.75,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-27 00:00:00,,,,,,,,,,,,,,,,,38.75,38.45,38.4,38.1,38.2,37.8,37.35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-28 00:00:00,,,,,,,,,,,,,,,,,38.2,38.15,38.05,37.65,37.8,37.45,37.05,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-29 00:00:00,,,,,,,,,,,,,,,,,36.45,36.7,36.7,36.55,36.85,36.7,36.35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-04-30 00:00:00,,,,,,,,,,,,,,,,,36.95,37.0,37.0,36.65,36.9,36.7,36.4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-01 00:00:00,,,,,,,,,,,,,,,,,36.35,36.55,36.45,36.15,36.25,36.05,35.85,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-04 00:00:00,,,,,,,,,,,,,,,,,34.8,34.75,34.75,34.6,34.9,34.8,34.55,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-05 00:00:00,,,,,,,,,,,,,,,,,34.6,34.8,34.95,34.75,35.05,35.05,34.75,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-06 00:00:00,,,,,,,,,,,,,,,,,33.05,33.8,33.8,33.75,34.05,33.95,33.7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-07 00:00:00,,,,,,,,,,,,,,,,,33.7,34.15,34.05,34.0,34.35,34.2,33.9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-08 00:00:00,,,,,,,,,,,,,,,,,32.2,32.8,32.75,32.95,33.4,33.35,33.2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-11 00:00:00,,,,,,,,,,,,,,,,,32.45,33.0,33.2,33.15,33.4,33.6,33.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-12 00:00:00,,,,,,,,,,,,,,,,,31.95,32.85,33.0,33.05,33.4,33.6,33.3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-13 00:00:00,,,,,,,,,,,,,,,,,33.4,33.85,33.95,33.9,34.0,34.05,33.7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-14 00:00:00,,,,,,,,,,,,,,,,,31.6,32.5,32.55,32.65,32.85,33.1,32.75,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-15 00:00:00,,,,,,,,,,,,,,,,,33.15,33.2,33.2,33.2,33.4,33.3,33.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-18 00:00:00,,,,,,,,,,,,,,,,,29.85,30.85,31.0,30.85,31.15,31.15,30.7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-19 00:00:00,,,,,,,,,,,,,,,,,28.5,30.4,30.9,30.9,31.2,31.25,30.8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-20 00:00:00,,,,,,,,,,,,,,,,,27.04,30.5,31.4,31.3,31.55,31.55,31.1,29.2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-21 00:00:00,,,,,,,,,,,,,,,,,,32.2,32.85,32.35,32.3,32.25,31.85,31.2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-22 00:00:00,,,,,,,,,,,,,,,,,,32.75,33.05,32.4,32.4,32.25,32.05,31.2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-26 00:00:00,,,,,,,,,,,,,,,,,,31.15,32.0,31.4,31.55,31.35,30.9,30.15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-27 00:00:00,,,,,,,,,,,,,,,,,,32.1,32.9,32.1,32.05,31.7,30.85,29.85,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-28 00:00:00,,,,,,,,,,,,,,,,,,31.55,32.4,31.5,31.9,31.9,31.1,30.05,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-05-29 00:00:00,,,,,,,,,,,,,,,,,,30.35,31.5,31.1,31.55,31.6,30.85,29.9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-01 00:00:00,,,,,,,,,,,,,,,,,,29.6,30.75,30.4,30.75,30.8,30.4,29.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-02 00:00:00,,,,,,,,,,,,,,,,,,29.6,31.0,30.5,30.95,30.8,30.35,29.55,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-03 00:00:00,,,,,,,,,,,,,,,,,,31.15,32.65,31.95,32.1,31.85,31.05,30.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-04 00:00:00,,,,,,,,,,,,,,,,,,30.8,32.25,31.75,31.85,31.7,30.8,29.75,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-05 00:00:00,,,,,,,,,,,,,,,,,,30.55,32.2,31.7,31.85,31.7,30.9,29.85,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-08 00:00:00,,,,,,,,,,,,,,,,,,30.25,32.0,31.7,31.75,31.65,30.85,29.95,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-09 00:00:00,,,,,,,,,,,,,,,,,,29.1,30.95,30.95,31.15,31.1,30.4,29.45,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-10 00:00:00,,,,,,,,,,,,,,,,,,29.1,31.2,31.3,31.45,31.5,30.75,29.95,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-11 00:00:00,,,,,,,,,,,,,,,,,,28.1,30.6,30.75,30.9,31.0,30.2,29.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-12 00:00:00,,,,,,,,,,,,,,,,,,28.35,29.95,30.1,30.45,30.5,29.9,29.05,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-15 00:00:00,,,,,,,,,,,,,,,,,,30.2,31.35,31.1,31.25,31.3,30.7,29.8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-16 00:00:00,,,,,,,,,,,,,,,,,,31.85,32.4,31.95,32.05,31.95,31.25,30.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-17 00:00:00,,,,,,,,,,,,,,,,,,31.03,32.65,32.1,32.0,31.95,31.25,30.2,30.7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-18 00:00:00,,,,,,,,,,,,,,,,,,,32.4,31.85,31.9,31.85,31.15,30.2,30.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-19 00:00:00,,,,,,,,,,,,,,,,,,,31.35,31.55,31.7,31.75,31.05,30.15,30.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-22 00:00:00,,,,,,,,,,,,,,,,,,,32.75,32.55,32.6,32.55,31.7,30.8,30.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-23 00:00:00,,,,,,,,,,,,,,,,,,,32.05,32.15,32.3,32.3,31.6,30.65,30.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-24 00:00:00,,,,,,,,,,,,,,,,,,,30.6,31.35,31.6,31.5,30.85,30.0,30.05,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-25 00:00:00,,,,,,,,,,,,,,,,,,,29.1,30.25,30.85,30.8,30.4,29.65,29.7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-26 00:00:00,,,,,,,,,,,,,,,,,,,28.55,29.85,30.5,30.55,30.3,29.65,29.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-29 00:00:00,,,,,,,,,,,,,,,,,,,27.45,28.95,29.7,29.95,29.65,29.2,29.15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-06-30 00:00:00,,,,,,,,,,,,,,,,,,,28.05,29.25,30.0,30.05,29.7,29.15,29.2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-01 00:00:00,,,,,,,,,,,,,,,,,,,27.65,29.2,29.8,29.9,29.45,28.85,28.75,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-02 00:00:00,,,,,,,,,,,,,,,,,,,29.3,30.65,31.1,31.0,30.3,29.6,29.55,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-06 00:00:00,,,,,,,,,,,,,,,,,,,29.0,30.4,31.05,30.95,30.35,29.7,29.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-07 00:00:00,,,,,,,,,,,,,,,,,,,30.25,31.45,31.9,31.8,31.05,30.4,30.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-08 00:00:00,,,,,,,,,,,,,,,,,,,30.8,31.8,32.3,32.0,31.35,30.7,30.55,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-09 00:00:00,,,,,,,,,,,,,,,,,,,29.75,31.75,32.25,32.0,31.25,30.65,30.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-10 00:00:00,,,,,,,,,,,,,,,,,,,29.8,31.95,32.5,32.35,31.4,30.8,30.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-13 00:00:00,,,,,,,,,,,,,,,,,,,27.55,30.8,31.7,31.75,31.1,30.4,30.35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-14 00:00:00,,,,,,,,,,,,,,,,,,,27.0,30.25,31.2,31.35,30.95,30.25,30.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-15 00:00:00,,,,,,,,,,,,,,,,,,,26.45,29.25,30.65,30.65,30.2,29.65,29.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-16 00:00:00,,,,,,,,,,,,,,,,,,,25.9,28.95,30.15,30.35,29.9,29.35,29.3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-17 00:00:00,,,,,,,,,,,,,,,,,,,25.6,29.0,30.25,30.4,30.15,29.55,29.4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-20 00:00:00,,,,,,,,,,,,,,,,,,,24.55,28.4,29.45,29.6,29.35,28.75,28.65,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-21 00:00:00,,,,,,,,,,,,,,,,,,,24.05,27.85,29.35,29.45,29.15,28.5,28.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-22 00:00:00,,,,,,,,,,,,,,,,,,,23.48,27.2,29.2,29.3,28.9,28.35,28.3,28.7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-23 00:00:00,,,,,,,,,,,,,,,,,,,,26.25,28.45,28.9,28.75,28.1,28.05,28.15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-24 00:00:00,,,,,,,,,,,,,,,,,,,,26.0,28.55,29.0,28.65,28.05,28.1,28.1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-27 00:00:00,,,,,,,,,,,,,,,,,,,,26.35,28.95,29.3,29.0,28.35,28.5,28.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-28 00:00:00,,,,,,,,,,,,,,,,,,,,27.3,29.85,30.0,29.7,29.0,29.05,29.05,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-29 00:00:00,,,,,,,,,,,,,,,,,,,,27.65,30.05,30.35,29.8,28.95,29.15,29.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-30 00:00:00,,,,,,,,,,,,,,,,,,,,27.05,29.3,29.9,29.4,28.55,28.75,28.8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-07-31 00:00:00,,,,,,,,,,,,,,,,,,,,27.25,29.7,30.0,29.7,28.9,29.2,29.2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-03 00:00:00,,,,,,,,,,,,,,,,,,,,26.45,29.1,29.6,29.3,28.55,28.75,28.9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-04 00:00:00,,,,,,,,,,,,,,,,,,,,26.3,28.85,29.5,29.15,28.45,28.7,28.85,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-05 00:00:00,,,,,,,,,,,,,,,,,,,,26.05,28.85,29.4,29.05,28.4,28.8,28.9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-06 00:00:00,,,,,,,,,,,,,,,,,,,,26.6,28.95,29.7,29.35,28.75,28.95,28.95,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-07 00:00:00,,,,,,,,,,,,,,,,,,,,25.65,28.05,29.05,28.75,28.15,28.35,28.3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-10 00:00:00,,,,,,,,,,,,,,,,,,,,25.6,28.1,29.1,28.8,28.2,28.45,28.45,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-11 00:00:00,,,,,,,,,,,,,,,,,,,,26.2,28.6,29.5,29.2,28.6,28.85,28.8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-12 00:00:00,,,,,,,,,,,,,,,,,,,,25.55,28.35,29.35,29.05,28.35,28.6,28.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-13 00:00:00,,,,,,,,,,,,,,,,,,,,25.05,27.8,29.2,28.8,28.25,28.65,28.6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-14 00:00:00,,,,,,,,,,,,,,,,,,,,25.2,28.3,29.35,28.7,28.25,28.5,28.5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-17 00:00:00,,,,,,,,,,,,,,,,,,,,27.6,29.9,30.95,30.4,29.7,30.0,29.95,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-18 00:00:00,,,,,,,,,,,,,,,,,,,,26.35,29.25,30.55,30.1,29.4,29.7,29.7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-19 00:00:00,,,,,,,,,,,,,,,,,,,,28.76,28.35,30.55,30.05,29.35,29.65,29.5,29.8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-20 00:00:00,,,,,,,,,,,,,,,,,,,,,27.8,30.1,29.75,29.2,29.35,29.35,29.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-21 00:00:00,,,,,,,,,,,,,,,,,,,,,27.35,30.0,29.65,29.05,29.15,28.95,28.85,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-24 00:00:00,,,,,,,,,,,,,,,,,,,,,27.4,29.9,29.55,28.9,29.15,29.1,28.85,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-25 00:00:00,,,,,,,,,,,,,,,,,,,,,27.75,30.05,29.8,29.1,29.35,29.35,29.0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-26 00:00:00,,,,,,,,,,,,,,,,,,,,,28.3,30.4,30.05,29.3,29.6,29.65,29.2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-27 00:00:00,,,,,,,,,,,,,,,,,,,,,27.8,30.25,29.95,29.2,29.45,29.55,29.2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-28 00:00:00,,,,,,,,,,,,,,,,,,,,,28.1,30.5,30.1,29.3,29.5,29.6,29.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-08-31 00:00:00,,,,,,,,,,,,,,,,,,,,,28.5,30.95,30.25,29.55,29.9,29.9,29.55,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-01 00:00:00,,,,,,,,,,,,,,,,,,,,,30.05,32.25,31.2,30.3,30.55,30.6,30.15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-02 00:00:00,,,,,,,,,,,,,,,,,,,,,30.5,32.65,31.7,30.7,30.9,30.9,30.4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-03 00:00:00,,,,,,,,,,,,,,,,,,,,,28.95,31.25,30.5,29.75,30.0,30.0,29.65,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-04 00:00:00,,,,,,,,,,,,,,,,,,,,,27.6,30.45,29.9,29.15,29.55,29.6,29.3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-08 00:00:00,,,,,,,,,,,,,,,,,,,,,26.7,29.45,29.25,28.75,29.3,29.35,29.05,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-09 00:00:00,,,,,,,,,,,,,,,,,,,,,25.95,28.6,28.8,28.35,29.0,29.1,28.9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-10 00:00:00,,,,,,,,,,,,,,,,,,,,,24.45,27.35,28.05,27.75,28.4,28.65,28.65,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-11 00:00:00,,,,,,,,,,,,,,,,,,,,,24.75,27.7,28.35,27.95,28.7,28.95,28.85,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-14 00:00:00,,,,,,,,,,,,,,,,,,,,,23.85,27.05,27.9,27.8,28.4,28.75,28.75,28.75,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-15 00:00:00,,,,,,,,,,,,,,,,,,,,,23.5,27.15,27.9,27.8,28.4,28.7,28.5,28.35,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-16 00:00:00,,,,,,,,,,,,,,,,,,,,,23.64,25.95,27.65,27.35,28.05,28.45,28.15,28.4,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,26.1,27.75,27.5,28.3,28.45,28.2,28.25,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,26.75,28.35,27.95,28.55,28.65,28.45,28.45,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,26.7,28.4,28.05,28.65,28.7,28.6,28.7,28.7,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,26.1,28.05,27.8,28.55,28.75,28.6,28.9,28.5,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,26.35,28.15,27.85,28.3,28.6,28.45,28.65,28.6,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,26.9,28.5,28.35,28.8,29.15,29.1,29.35,28.65,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,27.0,28.55,28.35,28.85,29.25,29.2,29.5,29.4,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,25.85,27.95,27.8,28.45,28.7,28.65,28.95,28.7,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,25.9,27.85,27.85,28.5,28.85,28.7,28.95,28.45,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-09-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,26.3,27.95,28.1,28.65,29.0,28.8,29.05,28.95,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,27.8,28.75,28.85,29.35,29.7,29.5,29.7,29.6,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,27.85,28.8,29.0,29.35,29.7,29.35,29.55,29.2,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,26.8,27.95,28.35,28.8,29.15,28.95,29.25,28.8,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,26.0,27.45,27.75,28.25,28.55,28.45,28.75,28.4,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,25.4,27.35,27.65,28.05,28.45,28.35,28.8,28.55,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,25.05,27.05,27.3,27.8,28.2,28.1,28.35,28.4,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,24.55,26.5,27.05,27.55,27.9,27.85,28.15,28.1,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,24.05,25.75,26.55,27.15,27.65,27.55,27.85,27.65,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,23.55,25.6,26.4,27.1,27.5,27.55,27.85,27.8,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,23.25,25.4,26.2,27.1,27.45,27.55,27.9,27.55,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,22.35,24.9,25.75,26.55,27.1,27.05,27.55,27.2,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,22.35,25.3,26.05,26.8,27.35,27.35,27.65,27.35,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,21.4,24.65,25.55,26.4,27.05,27.05,27.45,27.25,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,21.1,24.55,25.55,26.4,27.0,26.95,27.3,27.25,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,20.82,24.55,25.65,26.35,27.05,26.95,27.2,27.05,,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,23.65,25.1,25.95,26.6,26.6,26.7,26.55,27.0,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,24.05,25.45,26.15,26.9,26.9,27.1,26.85,27.05,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,24.55,25.95,26.7,27.3,27.3,27.55,27.25,27.3,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,24.65,25.85,26.6,27.2,27.25,27.55,27.35,27.3,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,26.65,26.9,27.6,27.95,27.9,27.95,27.75,27.8,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,25.05,25.8,26.6,27.15,27.15,27.35,27.1,27.1,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-10-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,27.85,27.7,27.95,28.25,28.25,28.4,28.15,28.2,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,28.0,28.1,28.2,28.4,28.25,28.25,27.95,28.0,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,28.1,28.3,28.45,28.65,28.55,28.45,28.1,28.15,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,27.6,28.05,28.05,28.25,28.1,28.15,27.8,27.95,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,25.9,27.25,27.6,27.95,27.65,27.8,27.5,27.55,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,25.1,26.4,27.0,27.65,27.5,27.65,27.45,27.4,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,23.5,24.9,26.15,26.95,27.0,27.1,26.95,26.95,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,23.5,25.1,26.5,27.2,27.15,27.4,27.15,27.05,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,23.65,25.15,26.8,27.5,27.45,27.75,27.45,27.4,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,24.8,26.25,27.7,28.0,27.95,28.2,27.9,27.9,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,24.25,25.85,27.45,27.8,27.75,28.1,27.85,27.8,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,23.4,25.45,27.0,27.6,27.55,27.9,27.6,27.65,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,22.55,25.35,27.05,27.7,27.7,27.95,27.75,27.7,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,22.54,24.4,26.85,27.65,27.7,27.95,27.85,27.7,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,24.7,27.25,28.0,28.05,28.25,28.0,28.0,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,24.2,27.0,27.8,27.95,28.25,28.05,27.95,,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,22.85,26.4,27.2,27.5,27.8,27.7,27.65,27.85,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,22.7,26.05,27.15,27.45,27.7,27.6,27.6,27.75,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,22.35,25.8,27.0,27.35,27.65,27.5,27.45,27.55,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,24.05,27.15,28.2,28.35,28.65,28.35,28.15,28.2,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-11-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,24.1,27.15,28.15,28.35,28.7,28.5,28.25,28.2,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,23.05,26.3,27.6,27.75,28.05,27.95,27.7,27.75,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,22.65,26.2,27.7,27.85,28.2,28.0,27.8,27.8,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,23.25,26.65,27.7,27.85,28.15,27.95,27.9,28.1,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,22.6,26.15,27.7,27.8,28.1,27.9,27.9,28.15,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,22.5,26.05,27.65,27.8,28.05,27.9,27.85,28.05,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,23.5,26.55,28.15,28.35,28.55,28.5,28.45,28.5,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,23.05,26.45,28.0,28.3,28.5,28.45,28.35,28.5,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,22.5,26.1,27.9,28.25,28.5,28.35,28.25,28.45,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,22.1,26.0,27.6,28.05,28.4,28.25,28.2,28.4,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,21.1,25.55,27.5,28.0,28.25,28.15,28.15,28.3,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,21.35,25.25,27.0,27.65,27.9,27.85,27.95,28.1,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,20.84,24.1,26.5,27.2,27.5,27.55,27.7,27.9,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,24.45,26.75,27.35,27.8,27.85,27.9,28.05,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,24.1,26.4,27.0,27.4,27.5,27.55,27.7,,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,23.25,25.65,26.2,26.6,26.65,26.75,26.95,27.15,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,22.65,25.1,25.6,26.1,26.2,26.25,26.6,26.7,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,22.45,24.9,25.45,26.0,26.0,26.1,26.3,26.5,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,22.1,24.75,25.25,25.8,25.85,25.95,25.95,26.0,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,21.85,24.65,25.15,25.65,25.75,25.8,25.85,25.75,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,22.0,24.75,25.2,25.6,25.6,25.7,25.7,25.75,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,22.4,25.05,25.6,25.9,25.9,25.9,25.95,25.9,,,,,,,,,,,,,,,,,,,,,,,,, -2009-12-31 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,22.95,25.8,26.0,26.3,26.35,26.3,26.4,26.35,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,22.1,24.85,25.25,25.75,25.75,25.75,25.85,25.95,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,21.55,24.45,24.85,25.45,25.5,25.5,25.55,25.7,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,20.8,23.55,24.2,24.95,25.05,25.05,25.1,25.3,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,20.45,23.15,23.85,24.75,24.85,24.85,24.9,25.1,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,19.9,22.55,23.4,24.4,24.65,24.6,24.75,24.9,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,19.5,22.25,23.25,24.15,24.3,24.4,24.5,24.65,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,20.25,22.8,23.65,24.25,24.45,24.45,24.6,24.75,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,19.4,22.5,23.45,24.15,24.4,24.4,24.55,24.55,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,18.95,22.0,23.0,23.65,23.95,24.0,24.15,24.25,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,19.65,22.55,23.55,24.05,24.3,24.35,24.45,24.45,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,17.85,21.55,22.75,23.55,23.8,23.8,23.9,24.1,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,18.87,21.4,22.85,23.6,23.8,23.9,23.85,24.05,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,22.65,24.1,24.55,24.5,24.45,24.55,24.55,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,24.75,25.15,25.35,25.4,25.35,25.5,25.35,,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,24.35,24.95,25.05,25.05,25.1,25.15,25.15,25.15,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,24.55,25.3,25.45,25.4,25.3,25.25,25.25,25.3,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,23.75,24.7,25.05,25.1,25.1,25.1,25.0,25.2,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,24.0,24.9,25.15,25.15,25.15,25.15,25.05,25.2,,,,,,,,,,,,,,,,,,,,,,,, -2010-01-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,24.65,25.35,25.5,25.5,25.45,25.45,25.3,25.4,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,23.05,24.25,24.95,25.05,25.0,25.05,24.95,25.15,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,22.1,23.45,24.4,24.65,24.75,24.9,24.85,25.05,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,22.15,23.55,24.45,24.8,24.85,24.95,24.9,25.1,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,25.6,25.65,26.0,26.05,25.95,25.9,25.85,25.95,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,26.1,25.85,26.15,26.2,26.15,26.2,26.0,26.1,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,26.4,26.2,26.3,26.2,26.3,26.35,26.25,26.35,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,25.55,25.65,26.05,26.05,26.15,26.15,26.05,26.15,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,25.5,25.55,26.0,26.15,26.1,26.2,26.05,26.2,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,24.45,24.95,25.65,25.8,25.85,25.95,25.85,26.05,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,24.45,24.9,25.85,26.0,25.95,26.05,25.95,26.1,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,22.6,23.6,24.8,25.15,25.2,25.45,25.35,25.5,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,22.5,22.75,24.7,24.85,24.95,25.2,25.05,25.2,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,21.8,24.1,24.5,24.7,24.9,24.9,25.05,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,21.35,23.7,24.1,24.35,24.5,24.55,24.6,,,,,,,,,,,,,,,,,,,,,,,, -2010-02-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,20.95,23.25,23.75,24.0,24.25,24.25,24.4,23.95,,,,,,,,,,,,,,,,,,,,,,, -2010-02-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,21.65,23.9,24.25,24.3,24.45,24.35,24.5,24.55,,,,,,,,,,,,,,,,,,,,,,, -2010-02-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,21.1,23.65,23.9,24.05,24.25,24.25,24.35,24.45,,,,,,,,,,,,,,,,,,,,,,, -2010-02-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,20.95,23.75,23.95,24.1,24.3,24.2,24.45,24.45,,,,,,,,,,,,,,,,,,,,,,, -2010-02-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,20.4,23.5,23.8,23.95,24.2,24.2,24.3,24.35,,,,,,,,,,,,,,,,,,,,,,, -2010-03-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,20.0,23.05,23.65,23.85,24.05,24.1,24.25,24.2,,,,,,,,,,,,,,,,,,,,,,, -2010-03-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,19.8,22.8,23.45,23.75,23.9,24.05,24.1,24.15,,,,,,,,,,,,,,,,,,,,,,, -2010-03-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,19.6,22.6,23.25,23.45,23.7,23.8,23.9,24.0,,,,,,,,,,,,,,,,,,,,,,, -2010-03-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,19.6,22.5,23.25,23.6,23.7,23.8,23.9,24.05,,,,,,,,,,,,,,,,,,,,,,, -2010-03-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,18.55,21.6,22.6,23.05,23.25,23.5,23.65,23.7,,,,,,,,,,,,,,,,,,,,,,, -2010-03-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,18.35,21.25,22.45,22.95,23.25,23.45,23.5,23.6,,,,,,,,,,,,,,,,,,,,,,, -2010-03-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,18.5,21.25,22.45,23.0,23.2,23.4,23.45,23.6,,,,,,,,,,,,,,,,,,,,,,, -2010-03-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,18.6,21.4,22.65,23.3,23.45,23.65,24.1,23.75,,,,,,,,,,,,,,,,,,,,,,, -2010-03-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,18.6,21.6,22.8,23.4,23.65,23.85,24.0,24.0,,,,,,,,,,,,,,,,,,,,,,, -2010-03-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,18.35,21.45,22.7,23.25,23.55,23.65,23.75,23.85,,,,,,,,,,,,,,,,,,,,,,, -2010-03-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,18.1,21.5,22.85,23.35,23.65,23.8,23.95,24.0,,,,,,,,,,,,,,,,,,,,,,, -2010-03-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,17.45,20.9,22.3,23.0,23.3,23.55,23.65,23.85,,,,,,,,,,,,,,,,,,,,,,, -2010-03-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,16.68,20.1,21.75,22.65,23.05,23.4,23.5,23.6,,,,,,,,,,,,,,,,,,,,,,, -2010-03-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.8,21.45,22.45,23.0,23.25,23.35,23.5,,,,,,,,,,,,,,,,,,,,,,, -2010-03-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.2,21.7,22.7,23.25,23.45,23.6,23.7,,,,,,,,,,,,,,,,,,,,,,, -2010-03-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.9,21.65,22.55,23.15,23.35,23.5,23.65,23.85,,,,,,,,,,,,,,,,,,,,,, -2010-03-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.45,21.35,22.35,23.0,23.2,23.4,23.5,23.65,,,,,,,,,,,,,,,,,,,,,, -2010-03-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.9,21.65,22.6,23.25,23.4,23.65,23.8,23.85,,,,,,,,,,,,,,,,,,,,,, -2010-03-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.1,21.95,22.9,23.4,23.6,23.7,23.8,23.8,,,,,,,,,,,,,,,,,,,,,, -2010-03-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.9,21.7,22.7,23.35,23.5,23.7,23.75,23.9,,,,,,,,,,,,,,,,,,,,,, -2010-03-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.5,21.25,22.35,23.1,23.35,23.55,23.7,23.75,,,,,,,,,,,,,,,,,,,,,, -2010-03-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.1,21.0,22.15,23.05,23.3,23.55,23.7,23.75,,,,,,,,,,,,,,,,,,,,,, -2010-03-31 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.95,21.0,22.2,23.0,23.3,23.6,23.75,23.8,,,,,,,,,,,,,,,,,,,,,, -2010-04-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.8,21.05,22.25,23.05,23.35,23.65,23.8,23.85,,,,,,,,,,,,,,,,,,,,,, -2010-04-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.0,20.35,21.6,22.5,22.75,23.25,23.4,23.5,,,,,,,,,,,,,,,,,,,,,, -2010-04-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.45,19.85,21.2,22.2,22.6,23.0,23.25,23.35,,,,,,,,,,,,,,,,,,,,,, -2010-04-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.9,20.1,21.4,22.4,22.8,23.2,23.45,23.55,,,,,,,,,,,,,,,,,,,,,, -2010-04-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.45,19.85,21.2,22.3,22.75,23.2,23.45,23.55,,,,,,,,,,,,,,,,,,,,,, -2010-04-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.2,19.65,21.15,22.2,22.65,23.2,23.5,23.55,,,,,,,,,,,,,,,,,,,,,, -2010-04-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.1,19.65,21.2,22.2,22.6,23.1,23.45,23.5,,,,,,,,,,,,,,,,,,,,,, -2010-04-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.15,19.75,21.25,22.25,22.65,23.25,23.5,23.55,,,,,,,,,,,,,,,,,,,,,, -2010-04-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.7,19.3,20.95,22.05,22.45,23.1,23.4,23.5,,,,,,,,,,,,,,,,,,,,,, -2010-04-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.7,19.3,20.95,22.0,22.5,23.15,23.4,23.55,,,,,,,,,,,,,,,,,,,,,, -2010-04-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.2,19.95,21.45,22.55,23.0,23.6,23.85,24.0,,,,,,,,,,,,,,,,,,,,,, -2010-04-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.4,19.5,21.0,22.4,22.9,23.5,23.85,23.95,,,,,,,,,,,,,,,,,,,,,, -2010-04-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.0,18.6,20.45,21.9,22.65,23.4,23.65,23.75,,,,,,,,,,,,,,,,,,,,,, -2010-04-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,15.8,18.7,20.75,22.15,22.95,23.7,23.95,24.05,,,,,,,,,,,,,,,,,,,,,, -2010-04-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.65,20.75,22.25,23.1,23.9,24.2,24.25,,,,,,,,,,,,,,,,,,,,,, -2010-04-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.5,20.75,22.25,23.05,23.85,24.15,24.25,,,,,,,,,,,,,,,,,,,,,, -2010-04-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.75,20.95,22.45,23.25,23.9,24.15,24.25,24.35,,,,,,,,,,,,,,,,,,,,, -2010-04-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.05,22.4,23.65,24.35,25.05,25.2,25.3,25.25,,,,,,,,,,,,,,,,,,,,, -2010-04-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.8,22.2,23.5,24.2,24.9,25.15,25.2,25.3,,,,,,,,,,,,,,,,,,,,, -2010-04-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.65,21.65,23.05,23.85,24.65,24.95,25.0,25.15,,,,,,,,,,,,,,,,,,,,, -2010-04-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.6,23.0,24.1,24.8,25.45,25.7,25.8,25.9,,,,,,,,,,,,,,,,,,,,, -2010-05-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.55,22.6,23.9,24.6,25.25,25.5,25.55,25.65,,,,,,,,,,,,,,,,,,,,, -2010-05-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.0,24.45,25.6,26.1,26.55,26.65,26.8,26.85,,,,,,,,,,,,,,,,,,,,, -2010-05-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.15,25.45,26.4,26.85,27.4,27.6,27.65,27.65,,,,,,,,,,,,,,,,,,,,, -2010-05-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.2,29.1,29.3,29.3,29.95,29.65,29.7,29.65,,,,,,,,,,,,,,,,,,,,, -2010-05-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.95,30.95,30.9,30.75,31.1,31.0,30.85,30.8,,,,,,,,,,,,,,,,,,,,, -2010-05-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.45,27.05,27.85,27.9,28.4,28.55,28.4,28.5,,,,,,,,,,,,,,,,,,,,, -2010-05-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.1,27.05,27.6,27.8,28.45,28.6,28.6,28.6,,,,,,,,,,,,,,,,,,,,, -2010-05-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.05,25.8,26.4,26.7,27.5,27.7,27.8,27.75,,,,,,,,,,,,,,,,,,,,, -2010-05-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.85,26.4,26.75,26.8,27.6,27.75,27.75,27.7,,,,,,,,,,,,,,,,,,,,, -2010-05-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30.1,28.75,28.75,28.4,29.15,29.2,29.1,29.0,,,,,,,,,,,,,,,,,,,,, -2010-05-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30.3,29.0,29.2,28.9,29.6,29.7,29.65,29.5,,,,,,,,,,,,,,,,,,,,, -2010-05-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.7,30.95,30.9,30.45,30.9,30.55,30.35,30.2,,,,,,,,,,,,,,,,,,,,, -2010-05-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34.53,31.65,32.05,31.15,31.75,31.45,31.15,30.9,,,,,,,,,,,,,,,,,,,,, -2010-05-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35.95,35.7,34.0,34.3,33.8,33.3,32.9,,,,,,,,,,,,,,,,,,,,, -2010-05-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35.75,35.7,34.1,34.35,33.8,33.4,32.9,,,,,,,,,,,,,,,,,,,,, -2010-05-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35.1,35.1,33.65,34.05,33.7,33.35,32.95,33.15,,,,,,,,,,,,,,,,,,,, -2010-05-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.75,34.1,32.7,33.35,33.3,33.0,32.75,32.85,,,,,,,,,,,,,,,,,,,, -2010-05-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.8,33.3,32.15,33.05,33.0,32.8,32.45,32.4,,,,,,,,,,,,,,,,,,,, -2010-05-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.65,30.95,30.35,31.35,31.4,31.35,31.3,31.45,,,,,,,,,,,,,,,,,,,, -2010-05-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30.4,31.3,30.55,31.6,31.6,31.5,31.45,31.55,,,,,,,,,,,,,,,,,,,, -2010-06-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.55,32.65,31.8,32.5,32.15,32.0,31.9,31.85,,,,,,,,,,,,,,,,,,,, -2010-06-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.85,31.0,30.6,31.5,31.5,31.45,31.25,31.35,,,,,,,,,,,,,,,,,,,, -2010-06-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.6,30.7,30.35,31.3,31.2,31.15,30.75,31.1,,,,,,,,,,,,,,,,,,,, -2010-06-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.55,32.8,32.25,32.85,32.55,32.4,31.7,32.05,,,,,,,,,,,,,,,,,,,, -2010-06-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35.45,34.1,33.15,33.45,33.05,32.75,31.95,32.4,,,,,,,,,,,,,,,,,,,, -2010-06-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.45,32.95,32.2,32.8,32.75,32.55,31.6,32.2,,,,,,,,,,,,,,,,,,,, -2010-06-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.4,33.35,32.65,33.0,33.05,32.7,31.75,32.35,,,,,,,,,,,,,,,,,,,, -2010-06-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30.65,31.55,31.3,32.0,32.1,32.1,31.1,31.8,,,,,,,,,,,,,,,,,,,, -2010-06-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.3,30.9,30.8,31.7,31.8,31.8,30.9,31.6,,,,,,,,,,,,,,,,,,,, -2010-06-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,28.55,30.3,30.55,31.4,31.6,31.45,30.4,30.8,,,,,,,,,,,,,,,,,,,, -2010-06-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.85,28.55,29.2,30.25,30.45,30.35,29.5,30.0,,,,,,,,,,,,,,,,,,,, -2010-06-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.11,27.8,28.95,30.0,30.2,30.2,29.45,29.85,,,,,,,,,,,,,,,,,,,, -2010-06-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.3,28.6,29.7,29.95,29.9,29.25,29.55,,,,,,,,,,,,,,,,,,,, -2010-06-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.85,28.0,29.3,29.55,29.5,28.85,29.1,,,,,,,,,,,,,,,,,,,, -2010-06-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.1,28.15,29.5,29.65,29.6,28.9,29.25,29.25,,,,,,,,,,,,,,,,,,, -2010-06-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,28.4,29.0,30.3,30.4,30.3,29.55,29.8,29.85,,,,,,,,,,,,,,,,,,, -2010-06-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,28.75,29.55,30.7,30.85,30.7,30.15,30.25,30.05,,,,,,,,,,,,,,,,,,, -2010-06-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30.65,30.8,31.85,31.9,31.45,30.7,31.0,30.85,,,,,,,,,,,,,,,,,,, -2010-06-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.75,30.35,31.75,31.95,31.5,30.75,31.15,30.95,,,,,,,,,,,,,,,,,,, -2010-06-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30.15,31.05,32.45,32.5,32.0,31.35,31.8,31.6,,,,,,,,,,,,,,,,,,, -2010-06-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.5,33.45,34.75,34.75,34.25,33.5,34.2,33.8,,,,,,,,,,,,,,,,,,, -2010-06-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.9,34.15,35.15,35.3,34.8,33.9,34.6,34.35,,,,,,,,,,,,,,,,,,, -2010-07-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.35,34.15,35.3,35.35,34.95,34.1,34.9,34.85,,,,,,,,,,,,,,,,,,, -2010-07-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.05,33.4,34.95,35.15,34.85,34.0,34.85,34.8,,,,,,,,,,,,,,,,,,, -2010-07-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.8,31.9,34.05,34.55,34.4,33.5,34.5,34.45,,,,,,,,,,,,,,,,,,, -2010-07-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.6,30.05,32.35,33.1,32.85,32.05,32.95,33.0,,,,,,,,,,,,,,,,,,, -2010-07-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.05,29.5,31.8,32.6,32.35,31.55,32.6,32.6,,,,,,,,,,,,,,,,,,, -2010-07-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.55,29.05,31.2,32.15,32.15,31.3,32.35,32.2,,,,,,,,,,,,,,,,,,, -2010-07-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.85,28.35,30.9,31.95,31.9,31.0,32.2,32.05,,,,,,,,,,,,,,,,,,, -2010-07-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.8,28.15,30.45,31.45,31.45,30.55,31.8,31.75,,,,,,,,,,,,,,,,,,, -2010-07-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.75,28.95,31.1,32.1,32.0,31.2,32.3,32.2,,,,,,,,,,,,,,,,,,, -2010-07-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.5,29.3,31.45,32.4,32.45,31.7,32.8,32.65,,,,,,,,,,,,,,,,,,, -2010-07-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,28.1,30.6,32.8,33.75,33.7,33.05,34.2,33.9,,,,,,,,,,,,,,,,,,, -2010-07-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.8,30.3,32.5,33.5,33.45,32.9,34.15,33.8,,,,,,,,,,,,,,,,,,, -2010-07-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.4,28.5,31.2,32.4,32.45,32.0,33.35,33.2,,,,,,,,,,,,,,,,,,, -2010-07-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.79,28.85,31.45,32.55,32.55,32.1,33.55,33.5,,,,,,,,,,,,,,,,,,, -2010-07-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.3,30.2,31.4,31.45,31.3,32.7,32.75,,,,,,,,,,,,,,,,,,, -2010-07-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.6,29.6,31.0,31.2,31.05,32.45,32.5,,,,,,,,,,,,,,,,,,, -2010-07-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.55,28.75,30.2,30.3,29.95,31.45,31.4,32.4,,,,,,,,,,,,,,,,,, -2010-07-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.45,28.45,29.9,30.2,29.75,31.2,31.25,31.55,,,,,,,,,,,,,,,,,, -2010-07-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.75,28.8,29.8,29.9,29.5,30.95,31.0,31.4,,,,,,,,,,,,,,,,,, -2010-07-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.75,28.75,29.9,30.05,29.5,30.95,31.05,31.5,,,,,,,,,,,,,,,,,, -2010-07-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.45,28.6,29.75,29.8,29.35,30.8,30.9,31.45,,,,,,,,,,,,,,,,,, -2010-08-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.85,27.15,28.45,28.8,28.4,29.9,30.05,30.55,,,,,,,,,,,,,,,,,, -2010-08-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.1,27.5,28.75,29.0,28.65,30.15,30.3,30.7,,,,,,,,,,,,,,,,,, -2010-08-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.75,27.35,28.75,28.95,28.55,30.1,30.15,30.65,,,,,,,,,,,,,,,,,, -2010-08-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.8,27.65,29.1,29.2,28.75,30.25,30.4,30.8,,,,,,,,,,,,,,,,,, -2010-08-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.7,27.75,29.2,29.35,28.85,30.35,30.55,31.05,,,,,,,,,,,,,,,,,, -2010-08-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.1,27.4,29.0,29.1,28.65,30.2,30.45,30.95,,,,,,,,,,,,,,,,,, -2010-08-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.25,27.55,29.3,29.45,29.05,30.4,30.55,31.1,,,,,,,,,,,,,,,,,, -2010-08-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.7,29.6,30.85,30.85,30.45,31.75,31.8,32.15,,,,,,,,,,,,,,,,,, -2010-08-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.15,30.05,31.25,31.15,30.7,31.95,31.9,32.25,,,,,,,,,,,,,,,,,, -2010-08-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.75,30.7,31.9,31.8,31.25,32.45,32.25,32.55,,,,,,,,,,,,,,,,,, -2010-08-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.0,30.35,31.6,31.55,31.05,32.15,32.05,32.3,,,,,,,,,,,,,,,,,, -2010-08-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.35,29.45,30.95,31.1,30.8,32.05,31.9,32.0,,,,,,,,,,,,,,,,,, -2010-08-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.82,29.0,31.1,31.35,31.1,32.25,32.05,32.15,,,,,,,,,,,,,,,,,, -2010-08-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.9,32.15,32.2,31.7,32.95,32.65,32.85,,,,,,,,,,,,,,,,,, -2010-08-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.6,32.25,32.25,31.75,32.75,32.55,32.8,,,,,,,,,,,,,,,,,, -2010-08-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.0,32.15,32.15,31.95,33.05,32.95,33.15,32.95,,,,,,,,,,,,,,,,, -2010-08-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.8,32.85,32.95,32.6,33.75,33.7,33.95,33.7,,,,,,,,,,,,,,,,, -2010-08-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.15,32.3,32.35,32.05,33.05,33.05,33.3,33.25,,,,,,,,,,,,,,,,, -2010-08-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.55,32.5,32.75,32.4,33.55,33.4,33.6,33.55,,,,,,,,,,,,,,,,, -2010-08-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.55,30.9,31.3,31.05,32.45,32.4,32.65,32.6,,,,,,,,,,,,,,,,, -2010-08-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,28.45,31.75,32.15,31.75,33.2,33.15,33.25,33.1,,,,,,,,,,,,,,,,, -2010-08-31 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.9,31.25,32.05,31.7,33.2,33.2,33.45,33.3,,,,,,,,,,,,,,,,, -2010-09-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.8,29.75,30.75,30.65,32.5,32.55,32.9,32.8,,,,,,,,,,,,,,,,, -2010-09-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.0,29.15,30.05,30.25,32.3,32.4,32.7,32.5,,,,,,,,,,,,,,,,, -2010-09-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.6,27.85,29.05,29.4,31.7,31.85,32.15,32.05,,,,,,,,,,,,,,,,, -2010-09-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.45,28.6,29.6,29.9,32.1,32.2,32.55,32.25,,,,,,,,,,,,,,,,, -2010-09-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.85,27.85,29.1,29.45,31.7,31.8,32.3,32.15,,,,,,,,,,,,,,,,, -2010-09-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.75,27.55,28.85,29.1,31.4,31.55,32.05,31.9,,,,,,,,,,,,,,,,, -2010-09-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.05,27.0,28.55,28.9,31.2,31.4,32.05,31.85,,,,,,,,,,,,,,,,, -2010-09-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.7,25.7,27.45,28.25,30.65,30.85,31.45,31.45,,,,,,,,,,,,,,,,, -2010-09-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.7,25.7,27.6,28.4,30.45,30.7,31.35,31.45,,,,,,,,,,,,,,,,, -2010-09-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,22.97,25.2,27.45,28.3,30.2,30.55,31.3,31.45,,,,,,,,,,,,,,,,, -2010-09-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.1,27.6,28.45,30.3,30.55,31.4,31.5,,,,,,,,,,,,,,,,, -2010-09-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.05,27.8,28.7,30.45,30.7,31.55,31.65,,,,,,,,,,,,,,,,, -2010-09-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.35,27.35,28.4,30.1,30.3,31.35,31.5,31.5,,,,,,,,,,,,,,,, -2010-09-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.45,27.4,28.4,30.05,30.3,31.4,31.5,31.5,,,,,,,,,,,,,,,, -2010-09-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.95,27.65,28.7,30.35,30.55,31.65,31.7,31.7,,,,,,,,,,,,,,,, -2010-09-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.8,28.25,29.3,31.0,31.15,32.1,32.1,32.15,,,,,,,,,,,,,,,, -2010-09-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.2,27.2,28.35,30.25,30.6,31.55,31.6,31.65,,,,,,,,,,,,,,,, -2010-09-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.35,27.25,28.3,30.15,30.65,31.55,31.65,31.75,,,,,,,,,,,,,,,, -2010-09-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.3,27.25,28.3,30.1,30.65,31.45,31.65,31.75,,,,,,,,,,,,,,,, -2010-09-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.7,27.65,28.7,30.4,30.95,31.75,32.05,32.15,,,,,,,,,,,,,,,, -2010-09-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.45,28.2,29.3,30.85,31.35,32.25,32.5,32.6,,,,,,,,,,,,,,,, -2010-10-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.75,27.85,29.0,30.5,31.05,32.0,32.25,32.5,,,,,,,,,,,,,,,, -2010-10-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.15,28.2,29.4,30.8,31.4,32.25,32.4,32.55,,,,,,,,,,,,,,,, -2010-10-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.65,27.05,28.5,30.05,30.7,31.65,31.8,32.15,,,,,,,,,,,,,,,, -2010-10-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.25,26.8,28.4,30.1,30.75,31.7,31.75,32.05,,,,,,,,,,,,,,,, -2010-10-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,22.95,26.7,28.35,30.05,30.75,31.65,31.7,31.95,,,,,,,,,,,,,,,, -2010-10-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.95,25.7,27.55,29.55,30.5,31.4,31.45,31.6,,,,,,,,,,,,,,,, -2010-10-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.3,25.1,27.05,29.1,29.95,30.85,30.9,31.0,,,,,,,,,,,,,,,, -2010-10-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.65,24.25,26.3,28.65,29.5,30.4,30.45,30.5,,,,,,,,,,,,,,,, -2010-10-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.65,23.55,25.6,27.9,28.8,29.65,29.65,29.8,,,,,,,,,,,,,,,, -2010-10-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.55,24.2,26.1,28.35,29.2,30.05,30.2,30.15,,,,,,,,,,,,,,,, -2010-10-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.95,24.05,25.8,28.15,28.95,29.8,29.9,29.95,,,,,,,,,,,,,,,, -2010-10-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.85,23.3,25.45,27.8,28.65,29.55,29.75,29.75,,,,,,,,,,,,,,,, -2010-10-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.95,23.85,25.85,28.25,29.05,29.95,30.1,30.15,,,,,,,,,,,,,,,, -2010-10-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.41,22.6,25.05,27.4,28.4,29.35,29.5,29.7,,,,,,,,,,,,,,,, -2010-10-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,22.0,24.65,27.0,27.95,28.9,29.1,29.25,,,,,,,,,,,,,,,, -2010-10-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.1,23.95,26.25,27.35,28.35,28.55,28.75,,,,,,,,,,,,,,,, -2010-10-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.95,23.7,25.9,27.0,28.0,28.2,28.35,28.4,,,,,,,,,,,,,,, -2010-10-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.4,23.9,26.1,27.05,28.1,28.3,28.35,28.5,,,,,,,,,,,,,,, -2010-10-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.85,24.2,26.3,27.15,28.1,28.3,28.4,28.45,,,,,,,,,,,,,,, -2010-10-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.75,24.3,26.45,27.1,28.0,28.1,28.2,28.3,,,,,,,,,,,,,,, -2010-10-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.75,24.25,26.4,26.9,27.9,28.0,28.05,28.2,,,,,,,,,,,,,,, -2010-11-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.55,24.2,26.6,26.9,27.85,28.0,28.05,28.15,,,,,,,,,,,,,,, -2010-11-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.0,23.75,26.35,26.65,27.45,27.55,27.7,27.95,,,,,,,,,,,,,,, -2010-11-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.8,22.35,25.35,25.75,26.45,26.7,26.9,26.95,,,,,,,,,,,,,,, -2010-11-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.5,21.0,23.95,24.55,25.5,25.8,25.9,26.1,,,,,,,,,,,,,,, -2010-11-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.55,20.95,23.75,24.65,25.5,25.8,26.0,26.15,,,,,,,,,,,,,,, -2010-11-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.7,21.05,23.9,24.8,25.7,26.05,26.25,26.4,,,,,,,,,,,,,,, -2010-11-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.9,21.1,24.1,25.0,25.95,26.3,26.5,26.65,,,,,,,,,,,,,,, -2010-11-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.65,20.9,24.0,24.95,25.9,26.3,26.6,26.85,,,,,,,,,,,,,,, -2010-11-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.95,21.05,24.3,25.4,26.25,26.6,26.95,27.2,,,,,,,,,,,,,,, -2010-11-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.35,22.25,25.25,26.3,27.1,27.4,27.7,28.0,,,,,,,,,,,,,,, -2010-11-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.75,21.95,25.05,26.0,26.75,27.05,27.35,27.65,,,,,,,,,,,,,,, -2010-11-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,22.25,22.8,25.85,26.7,27.45,27.75,28.05,28.2,,,,,,,,,,,,,,, -2010-11-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,22.21,22.3,25.4,26.3,27.1,27.4,27.7,27.85,,,,,,,,,,,,,,, -2010-11-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.75,24.2,25.5,26.35,26.65,26.85,27.1,,,,,,,,,,,,,,, -2010-11-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.5,23.9,25.35,26.2,26.5,26.7,26.95,,,,,,,,,,,,,,, -2010-11-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.8,23.25,24.75,25.9,26.25,26.5,26.8,27.3,,,,,,,,,,,,,, -2010-11-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.75,24.1,25.55,26.5,26.85,27.05,27.4,27.8,,,,,,,,,,,,,, -2010-11-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.8,23.3,25.05,26.05,26.4,26.75,27.05,27.45,,,,,,,,,,,,,, -2010-11-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.25,24.25,25.95,26.85,27.2,27.4,27.7,28.05,,,,,,,,,,,,,, -2010-11-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.45,24.5,26.1,26.95,27.15,27.35,27.7,28.05,,,,,,,,,,,,,, -2010-11-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.2,25.8,27.05,27.8,28.05,28.05,28.35,28.75,,,,,,,,,,,,,, -2010-12-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.9,24.75,26.35,27.2,27.55,27.6,27.85,28.25,,,,,,,,,,,,,, -2010-12-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.85,23.0,24.8,25.95,26.4,26.65,27.05,27.5,,,,,,,,,,,,,, -2010-12-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.05,22.15,24.1,25.25,25.85,26.1,26.55,27.0,,,,,,,,,,,,,, -2010-12-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.6,21.6,23.7,25.0,25.6,25.95,26.4,26.85,,,,,,,,,,,,,, -2010-12-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.6,21.45,23.55,24.9,25.5,25.95,26.5,26.95,,,,,,,,,,,,,, -2010-12-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.2,20.7,22.9,24.3,25.05,25.55,25.9,26.3,,,,,,,,,,,,,, -2010-12-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.0,20.2,22.25,23.9,24.7,25.2,25.7,26.05,,,,,,,,,,,,,, -2010-12-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.05,20.05,21.75,23.4,24.25,24.75,25.25,25.7,,,,,,,,,,,,,, -2010-12-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.3,20.3,21.9,23.5,24.25,24.8,25.25,25.7,,,,,,,,,,,,,, -2010-12-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.7,20.45,22.15,23.55,24.3,24.85,25.2,25.65,,,,,,,,,,,,,, -2010-12-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.05,20.8,22.4,23.75,24.45,24.95,25.35,25.8,,,,,,,,,,,,,, -2010-12-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.4,20.5,22.15,23.5,24.25,24.8,25.15,25.65,,,,,,,,,,,,,, -2010-12-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.6,20.25,22.2,23.45,24.2,24.7,25.0,25.5,,,,,,,,,,,,,, -2010-12-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.75,19.65,21.75,23.15,24.05,24.6,24.9,25.4,,,,,,,,,,,,,, -2010-12-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.75,19.25,21.4,22.95,23.9,24.45,24.85,25.3,,,,,,,,,,,,,, -2010-12-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.01,19.25,21.3,22.95,23.8,24.5,24.8,25.3,,,,,,,,,,,,,, -2010-12-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.85,21.55,23.25,24.1,24.75,25.05,25.5,,,,,,,,,,,,,, -2010-12-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.45,21.75,23.8,24.55,25.1,25.45,25.9,26.4,,,,,,,,,,,,, -2010-12-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.55,21.9,23.9,24.75,25.15,25.45,25.8,26.0,,,,,,,,,,,,, -2010-12-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.25,21.85,23.8,24.6,25.1,25.55,25.85,26.0,,,,,,,,,,,,, -2010-12-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.1,21.7,23.9,24.7,25.2,25.6,26.0,26.15,,,,,,,,,,,,, -2010-12-31 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.7,21.6,23.75,24.8,25.35,25.75,26.3,26.35,,,,,,,,,,,,, -2011-01-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.3,21.35,23.45,24.3,24.95,25.5,25.95,26.1,,,,,,,,,,,,, -2011-01-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.1,21.3,23.3,24.15,24.8,25.35,25.75,25.95,,,,,,,,,,,,, -2011-01-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.7,20.95,22.85,23.75,24.5,25.0,25.45,25.65,,,,,,,,,,,,, -2011-01-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.65,20.9,22.8,23.75,24.5,24.95,25.45,25.6,,,,,,,,,,,,, -2011-01-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.7,21.0,22.85,23.8,24.6,25.1,25.6,25.7,,,,,,,,,,,,, -2011-01-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.65,21.0,22.8,23.7,24.55,25.1,25.75,25.85,,,,,,,,,,,,, -2011-01-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.95,20.4,22.4,23.4,24.3,24.85,25.5,25.75,,,,,,,,,,,,, -2011-01-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.0,19.45,21.7,22.7,23.65,24.4,25.15,25.4,,,,,,,,,,,,, -2011-01-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.95,19.3,21.65,22.65,23.55,24.2,24.9,25.2,,,,,,,,,,,,, -2011-01-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.25,18.4,20.75,22.0,22.95,23.7,24.4,24.7,,,,,,,,,,,,, -2011-01-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,15.9,17.85,20.15,21.55,22.5,23.2,24.0,24.35,,,,,,,,,,,,, -2011-01-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.38,18.75,20.9,22.2,23.05,23.8,24.6,24.95,,,,,,,,,,,,, -2011-01-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.65,20.85,22.1,22.95,23.75,24.4,24.75,,,,,,,,,,,,, -2011-01-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.85,21.0,22.2,23.0,23.7,24.35,24.75,,,,,,,,,,,,, -2011-01-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.4,20.55,21.85,22.65,23.4,24.15,24.55,25.15,,,,,,,,,,,, -2011-01-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.2,20.35,21.6,22.45,23.25,23.95,24.4,24.85,,,,,,,,,,,, -2011-01-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.55,19.75,21.0,21.85,22.6,23.4,23.8,24.3,,,,,,,,,,,, -2011-01-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.25,19.4,20.7,21.55,22.3,23.15,23.5,24.0,,,,,,,,,,,, -2011-01-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.4,20.65,21.75,22.6,23.2,23.9,24.3,24.8,,,,,,,,,,,, -2011-01-31 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.1,20.45,21.5,22.2,22.75,23.5,23.95,24.45,,,,,,,,,,,, -2011-02-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.95,19.6,20.6,21.35,21.95,22.75,23.1,23.6,,,,,,,,,,,, -2011-02-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.05,19.55,20.55,21.3,21.95,22.7,23.05,23.6,,,,,,,,,,,, -2011-02-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.7,19.35,20.45,21.2,21.8,22.6,23.0,23.5,,,,,,,,,,,, -2011-02-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.25,18.85,20.05,20.8,21.45,22.3,22.75,23.3,,,,,,,,,,,, -2011-02-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.95,18.45,19.6,20.4,21.15,21.95,22.5,23.05,,,,,,,,,,,, -2011-02-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.85,18.2,19.35,20.05,20.85,21.65,22.15,22.75,,,,,,,,,,,, -2011-02-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.85,18.25,19.3,20.05,20.8,21.6,22.1,22.7,,,,,,,,,,,, -2011-02-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.9,18.3,19.3,19.95,20.6,21.3,21.75,22.3,,,,,,,,,,,, -2011-02-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.6,18.05,19.15,19.85,20.45,21.15,21.55,22.1,,,,,,,,,,,, -2011-02-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.45,17.85,18.95,19.75,20.4,21.1,21.5,22.05,,,,,,,,,,,, -2011-02-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.7,18.05,19.0,19.9,20.55,21.25,21.6,22.15,,,,,,,,,,,, -2011-02-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.49,18.3,19.35,20.15,20.7,21.4,21.65,22.2,,,,,,,,,,,, -2011-02-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.45,19.65,20.5,21.1,21.7,21.95,22.45,,,,,,,,,,,, -2011-02-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.6,19.8,20.8,21.45,21.95,22.2,22.7,,,,,,,,,,,, -2011-02-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.15,21.6,22.3,22.75,23.2,23.35,23.75,24.0,,,,,,,,,,, -2011-02-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,22.25,22.55,23.1,23.4,23.8,23.95,24.35,24.55,,,,,,,,,,, -2011-02-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.85,22.35,23.0,23.3,23.75,23.95,24.35,24.55,,,,,,,,,,, -2011-02-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.15,21.15,22.05,22.55,23.1,23.35,23.75,24.0,,,,,,,,,,, -2011-02-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.2,20.3,21.45,22.0,22.6,23.0,23.45,23.75,,,,,,,,,,, -2011-03-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.2,21.7,22.5,22.9,23.45,23.8,24.25,24.45,,,,,,,,,,, -2011-03-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.1,21.6,22.4,22.85,23.45,23.75,24.2,24.45,,,,,,,,,,, -2011-03-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.7,20.7,21.65,22.1,22.85,23.15,23.65,23.85,,,,,,,,,,, -2011-03-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.05,21.15,22.05,22.5,23.15,23.45,24.0,24.2,,,,,,,,,,, -2011-03-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.05,21.8,22.6,23.0,23.65,23.95,24.5,24.65,,,,,,,,,,, -2011-03-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.45,21.4,22.4,22.85,23.55,23.8,24.45,24.6,,,,,,,,,,, -2011-03-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.05,21.8,22.65,23.1,23.75,24.0,24.65,24.8,,,,,,,,,,, -2011-03-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,22.25,22.7,23.35,23.8,24.4,24.6,25.25,25.35,,,,,,,,,,, -2011-03-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.3,22.05,22.9,23.3,24.05,24.2,24.85,24.95,,,,,,,,,,, -2011-03-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.7,22.3,23.1,23.55,24.25,24.45,25.15,25.25,,,,,,,,,,, -2011-03-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.6,23.45,23.75,24.15,24.75,24.9,25.6,25.65,,,,,,,,,,, -2011-03-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.14,24.9,25.15,25.2,25.8,25.9,26.5,26.7,,,,,,,,,,, -2011-03-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.15,24.4,24.6,25.0,25.05,25.6,25.85,,,,,,,,,,, -2011-03-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.35,23.65,23.9,24.2,24.25,24.75,25.0,,,,,,,,,,, -2011-03-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.6,22.3,22.75,23.05,23.2,23.8,24.1,23.95,,,,,,,,,, -2011-03-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.5,22.25,22.8,23.1,23.3,23.9,24.2,24.3,,,,,,,,,, -2011-03-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.5,21.6,22.35,22.8,23.05,23.7,24.05,24.1,,,,,,,,,, -2011-03-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.95,21.05,21.9,22.45,22.8,23.45,23.95,24.0,,,,,,,,,, -2011-03-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.75,21.05,21.9,22.55,22.9,23.65,24.15,24.35,,,,,,,,,, -2011-03-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.3,21.55,22.2,22.75,23.0,23.75,24.3,24.45,,,,,,,,,, -2011-03-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.6,20.95,21.75,22.25,22.65,23.4,24.0,24.15,,,,,,,,,, -2011-03-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.25,20.7,21.45,21.95,22.35,23.1,23.7,23.85,,,,,,,,,, -2011-03-31 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.3,20.8,21.5,22.0,22.4,23.2,23.8,24.0,,,,,,,,,, -2011-04-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.05,20.55,21.4,21.95,22.4,23.15,23.85,23.95,,,,,,,,,, -2011-04-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.7,20.25,21.15,21.7,22.15,23.0,23.7,23.9,,,,,,,,,, -2011-04-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.55,20.15,21.1,21.75,22.2,23.0,23.65,23.9,,,,,,,,,, -2011-04-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.35,20.15,21.1,21.75,22.25,23.05,23.7,23.95,,,,,,,,,, -2011-04-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.4,20.35,21.3,21.95,22.45,23.25,23.9,24.1,,,,,,,,,, -2011-04-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.65,20.65,21.6,22.3,22.8,23.6,24.25,24.45,,,,,,,,,, -2011-04-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.4,20.45,21.55,22.3,22.9,23.7,24.35,24.55,,,,,,,,,, -2011-04-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.7,20.7,21.7,22.5,23.05,23.75,24.35,24.55,,,,,,,,,, -2011-04-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.3,20.35,21.45,22.3,22.85,23.6,24.3,24.55,,,,,,,,,, -2011-04-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.9,20.15,21.4,22.25,22.85,23.6,24.3,24.5,,,,,,,,,, -2011-04-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.75,19.65,21.15,22.05,22.7,23.5,24.2,24.5,,,,,,,,,, -2011-04-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.3,20.2,21.7,22.45,23.1,23.8,24.5,24.75,,,,,,,,,, -2011-04-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.0,19.1,21.05,21.9,22.75,23.5,24.2,24.5,,,,,,,,,, -2011-04-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,14.86,18.15,20.35,21.55,22.25,23.05,23.8,24.3,,,,,,,,,, -2011-04-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.9,20.0,21.4,22.0,22.9,23.65,24.15,,,,,,,,,, -2011-04-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.45,19.6,21.0,21.65,22.65,23.5,24.05,24.6,,,,,,,,, -2011-04-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.3,19.2,20.65,21.35,22.5,23.25,23.5,23.35,,,,,,,,, -2011-04-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.0,18.75,20.25,20.95,22.3,23.0,23.2,23.15,,,,,,,,, -2011-04-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.75,18.4,19.9,20.65,22.0,22.75,23.05,23.05,,,,,,,,, -2011-04-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.7,18.35,19.65,20.4,21.65,22.55,22.9,22.9,,,,,,,,, -2011-05-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.25,18.8,20.15,20.85,22.15,23.05,23.25,23.2,,,,,,,,, -2011-05-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.7,19.35,20.6,21.25,22.45,23.2,23.45,23.35,,,,,,,,, -2011-05-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.95,19.55,20.8,21.35,22.55,23.3,23.55,23.4,,,,,,,,, -2011-05-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.3,19.8,20.95,21.5,22.7,23.5,23.65,23.55,,,,,,,,, -2011-05-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.15,19.55,20.75,21.35,22.55,23.3,23.55,23.45,,,,,,,,, -2011-05-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.45,18.85,20.3,20.95,22.15,22.85,23.1,23.05,,,,,,,,, -2011-05-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.65,18.2,19.75,20.55,21.75,22.45,22.6,22.6,,,,,,,,, -2011-05-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.2,18.65,20.2,20.9,22.05,22.7,22.9,22.85,,,,,,,,, -2011-05-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.65,18.35,20.0,20.7,21.9,22.55,22.75,22.65,,,,,,,,, -2011-05-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.35,18.65,20.25,20.95,22.15,22.8,22.95,22.85,,,,,,,,, -2011-05-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.0,19.05,20.5,21.2,22.3,22.9,23.1,23.0,,,,,,,,, -2011-05-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.75,18.7,20.2,20.9,22.1,22.8,23.05,22.95,,,,,,,,, -2011-05-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.02,18.05,19.75,20.65,21.85,22.55,22.75,22.75,,,,,,,,, -2011-05-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.65,19.6,20.6,21.85,22.65,22.85,22.9,,,,,,,,, -2011-05-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.05,20.0,21.1,22.45,23.3,23.5,23.45,,,,,,,,, -2011-05-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.55,20.3,21.3,22.6,23.55,23.75,23.75,24.0,,,,,,,, -2011-05-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.3,20.15,21.2,22.4,23.45,23.65,23.7,24.25,,,,,,,, -2011-05-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.95,19.9,21.0,22.15,23.2,23.5,23.6,24.25,,,,,,,, -2011-05-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.45,19.35,20.45,21.65,22.75,23.05,23.2,23.9,,,,,,,, -2011-05-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.1,19.05,20.1,21.2,22.3,22.7,22.85,23.6,,,,,,,, -2011-05-31 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.55,18.55,19.6,20.75,21.9,22.3,22.45,23.3,,,,,,,, -2011-06-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.95,19.55,20.4,21.4,22.5,22.9,23.1,23.8,,,,,,,, -2011-06-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.8,19.35,20.3,21.3,22.4,22.8,23.05,23.85,,,,,,,, -2011-06-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.95,19.45,20.4,21.45,22.55,22.95,23.2,24.05,,,,,,,, -2011-06-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.2,19.65,20.6,21.65,22.7,23.2,23.45,24.25,,,,,,,, -2011-06-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.1,19.35,20.3,21.45,22.5,23.05,23.3,24.2,,,,,,,, -2011-06-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.5,19.55,20.5,21.65,22.65,23.15,23.4,24.25,,,,,,,, -2011-06-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.75,19.0,19.95,21.25,22.2,22.7,23.0,23.9,,,,,,,, -2011-06-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.9,19.6,20.5,21.75,22.7,23.15,23.4,24.3,,,,,,,, -2011-06-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.55,20.0,20.65,21.75,22.75,23.25,23.5,24.45,,,,,,,, -2011-06-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.2,19.2,19.95,21.05,22.05,22.55,22.9,23.9,,,,,,,, -2011-06-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.73,20.95,21.25,22.25,23.05,23.45,23.75,24.75,,,,,,,, -2011-06-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.95,22.3,23.35,24.0,24.25,24.45,25.5,,,,,,,, -2011-06-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.45,22.0,23.2,23.75,24.05,24.25,25.25,,,,,,,, -2011-06-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.45,21.15,22.55,23.2,23.55,23.85,24.85,24.95,,,,,,, -2011-06-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.95,20.8,22.25,23.0,23.3,23.55,24.65,24.95,,,,,,, -2011-06-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.3,21.1,22.6,23.35,23.65,23.8,24.95,25.15,,,,,,, -2011-06-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.85,20.8,22.5,23.25,23.55,23.8,24.95,25.25,,,,,,, -2011-06-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.05,21.55,23.1,23.75,24.0,24.2,25.4,25.65,,,,,,, -2011-06-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.6,21.0,22.65,23.4,23.75,23.85,25.2,25.45,,,,,,, -2011-06-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.5,20.2,22.1,23.1,23.4,23.6,25.05,25.35,,,,,,, -2011-06-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.5,19.35,21.5,22.6,23.05,23.2,24.75,25.05,,,,,,, -2011-06-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.7,18.75,20.75,22.0,22.55,22.7,24.3,24.6,,,,,,, -2011-07-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.95,17.95,19.9,21.0,21.55,21.75,23.2,23.7,,,,,,, -2011-07-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.95,18.1,20.0,21.0,21.6,21.85,23.35,23.8,,,,,,, -2011-07-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.25,18.35,20.1,20.95,21.45,21.65,23.3,23.7,,,,,,, -2011-07-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,16.75,17.85,19.5,20.4,20.9,21.1,22.75,23.15,,,,,,, -2011-07-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17.1,18.25,19.85,20.65,21.2,21.4,22.9,23.35,,,,,,, -2011-07-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.85,19.6,20.8,21.5,22.05,22.15,23.55,24.05,,,,,,, -2011-07-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.6,20.0,21.35,22.1,22.55,22.65,24.1,24.45,,,,,,, -2011-07-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.9,20.05,21.45,22.1,22.55,22.65,24.05,24.5,,,,,,, -2011-07-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.65,20.65,21.9,22.6,22.9,22.95,24.35,24.75,,,,,,, -2011-07-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.15,20.2,21.6,22.25,22.55,22.65,24.0,24.4,,,,,,, -2011-07-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.15,21.0,22.15,22.75,23.0,23.05,24.35,24.65,,,,,,, -2011-07-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.25,19.75,21.3,21.95,22.3,22.45,23.7,24.15,,,,,,, -2011-07-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.1,19.35,21.0,21.8,22.05,22.25,23.55,24.0,,,,,,, -2011-07-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.35,20.05,21.25,21.5,21.7,23.0,23.45,,,,,,, -2011-07-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18.25,19.9,21.05,21.4,21.65,22.95,23.45,,,,,,, -2011-07-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.35,20.3,21.5,21.8,21.95,23.25,23.8,24.05,,,,,, -2011-07-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19.65,20.7,21.8,22.0,22.1,23.35,23.9,24.05,,,,,, -2011-07-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.3,21.75,22.55,22.6,22.7,24.0,24.45,24.65,,,,,, -2011-07-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.35,21.7,22.55,22.55,22.6,23.85,24.4,24.65,,,,,, -2011-07-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.1,21.1,21.9,21.95,22.05,23.2,23.8,24.05,,,,,, -2011-08-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20.7,20.6,21.3,21.5,21.5,22.75,23.35,23.8,,,,,, -2011-08-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,22.3,22.0,22.25,22.35,22.35,23.6,24.1,24.4,,,,,, -2011-08-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,22.0,21.85,22.05,22.15,22.15,23.45,23.95,24.3,,,,,, -2011-08-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.45,25.9,25.1,24.55,24.05,25.35,25.7,25.6,,,,,, -2011-08-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.15,26.2,25.75,25.15,24.25,25.65,25.9,26.1,,,,,, -2011-08-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,36.55,30.2,29.1,27.65,26.05,27.35,27.55,27.5,,,,,, -2011-08-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30.5,25.4,25.3,24.8,24.05,25.4,25.75,26.0,,,,,, -2011-08-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,36.0,28.75,28.3,27.4,26.3,27.55,27.8,27.8,,,,,, -2011-08-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35.15,27.65,27.1,26.6,25.55,26.8,27.2,27.35,,,,,, -2011-08-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35.0,27.85,26.9,26.4,25.4,26.65,26.85,27.0,,,,,, -2011-08-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.1,26.7,25.95,25.45,24.5,25.7,25.8,25.95,,,,,, -2011-08-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.65,26.9,26.25,25.65,24.75,25.85,26.0,26.15,,,,,, -2011-08-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.73,27.95,26.8,26.0,24.9,26.1,26.2,26.3,,,,,, -2011-08-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.4,30.2,29.2,27.8,28.85,28.85,29.05,,,,,, -2011-08-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35.35,31.6,30.35,28.7,29.7,29.65,29.65,,,,,, -2011-08-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,36.45,32.65,31.0,29.1,30.05,29.9,29.85,30.15,30.0,,,, -2011-08-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34.3,31.75,30.6,28.9,29.9,29.85,29.8,30.05,30.0,,,, -2011-08-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.55,31.45,30.6,29.25,30.3,30.25,30.35,30.2,29.15,,,, -2011-08-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34.75,31.75,30.75,29.8,30.85,30.9,30.95,30.95,30.65,,,, -2011-08-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34.0,31.0,30.2,29.4,30.45,30.5,30.7,30.65,30.7,,,, -2011-08-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,31.65,29.7,29.3,28.4,29.55,29.7,29.95,29.9,29.85,,,, -2011-08-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.5,30.55,30.05,29.15,30.35,30.5,30.65,30.55,30.3,,,, -2011-08-31 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,31.65,30.2,29.65,28.4,29.7,29.85,30.05,30.2,30.1,,,, -2011-09-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.15,30.7,29.95,28.65,29.95,30.05,30.3,30.3,30.25,,,, -2011-09-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34.5,32.05,30.75,29.25,30.4,30.5,30.7,30.55,30.55,,,, -2011-09-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35.75,32.85,31.45,29.85,31.0,31.0,31.2,31.25,31.1,,,, -2011-09-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.55,31.4,30.45,29.1,30.25,30.3,30.4,30.4,30.35,,,, -2011-09-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34.6,32.15,30.9,29.4,30.7,30.75,30.8,30.8,30.65,,,, -2011-09-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,38.55,34.55,32.85,30.8,31.85,31.75,31.9,31.95,31.6,,,, -2011-09-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,38.3,35.05,33.25,31.15,32.25,32.15,32.15,32.1,31.8,,,, -2011-09-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,37.85,35.15,33.35,31.25,32.2,32.1,32.15,32.25,31.95,,,, -2011-09-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35.75,34.1,32.75,30.7,31.75,31.65,31.7,31.9,31.65,,,, -2011-09-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.2,32.55,31.7,29.9,31.0,31.05,31.15,31.3,31.15,,,, -2011-09-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.05,31.85,31.25,29.7,30.8,30.9,31.05,31.1,31.0,,,, -2011-09-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.7,33.1,32.15,30.4,31.45,31.5,31.6,31.7,31.55,,,, -2011-09-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.5,32.95,31.85,30.2,31.3,31.3,31.35,31.6,31.4,,,, -2011-09-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.72,35.75,33.75,31.55,32.3,32.2,32.0,32.3,32.05,,,, -2011-09-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,38.55,35.75,33.15,33.8,33.4,33.2,33.3,32.9,,,, -2011-09-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,39.1,35.9,33.25,33.95,33.6,33.3,33.35,33.1,,,, -2011-09-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,37.5,34.7,32.35,33.3,32.95,32.7,32.8,32.5,32.5,,, -2011-09-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,36.75,34.3,32.0,33.05,32.65,32.45,32.55,32.15,32.05,,, -2011-09-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,39.45,36.05,33.5,34.3,33.65,33.35,33.4,32.85,32.5,,, -2011-09-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,38.6,35.3,32.95,33.8,33.25,33.0,33.05,32.55,33.45,,, -2011-09-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,42.15,37.75,34.8,35.5,34.7,34.25,34.35,33.7,32.85,,, -2011-10-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45.05,40.55,36.7,37.05,35.6,35.15,35.3,34.65,34.05,,, -2011-10-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,40.8,38.1,35.2,35.85,34.65,33.95,33.9,33.5,34.35,,, -2011-10-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,38.45,36.3,34.1,35.1,34.35,33.9,33.95,33.35,32.95,,, -2011-10-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,37.85,35.9,33.75,34.75,34.0,33.5,33.6,33.25,33.0,,, -2011-10-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,37.95,35.95,33.85,34.9,34.2,33.85,33.85,33.4,33.25,,, -2011-10-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34.7,33.65,32.1,33.05,32.65,32.45,32.6,32.25,32.65,,, -2011-10-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34.5,33.5,32.05,33.0,32.55,32.35,32.6,32.2,32.55,,, -2011-10-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.25,31.45,30.55,31.65,31.35,31.3,31.55,31.2,31.75,,, -2011-10-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.1,31.2,30.3,31.5,31.3,31.25,31.6,31.1,31.25,,, -2011-10-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.75,29.35,28.9,30.35,30.15,30.2,30.45,30.3,30.45,,, -2011-10-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34.2,32.95,31.0,32.2,31.7,31.55,31.85,31.55,30.75,,, -2011-10-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.15,31.0,29.95,31.2,30.8,30.9,31.2,31.0,31.05,,, -2011-10-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.15,33.85,31.55,32.6,31.9,31.8,32.05,32.0,31.7,,, -2011-10-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34.1,31.55,32.6,31.9,31.85,32.05,32.0,31.65,,, -2011-10-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,31.6,30.0,31.2,30.65,30.6,30.85,30.85,30.7,,, -2011-10-24 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.75,28.85,30.25,29.85,29.85,30.1,30.1,30.2,30.0,, -2011-10-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.4,30.25,31.4,30.85,30.8,31.0,30.8,30.75,31.8,, -2011-10-26 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30.5,29.2,30.4,29.9,29.9,30.2,30.05,29.9,30.25,, -2011-10-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.2,25.8,27.5,27.1,27.3,27.7,27.65,27.65,28.05,, -2011-10-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.25,25.55,27.35,26.95,27.2,27.55,27.5,27.55,27.95,, -2011-10-31 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,29.95,28.2,29.8,29.0,28.9,29.2,29.1,28.8,28.6,, -2011-11-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.95,31.25,32.15,31.3,31.05,31.2,30.9,30.55,30.7,, -2011-11-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.7,30.4,31.55,30.75,30.55,30.8,30.65,30.4,30.6,, -2011-11-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30.95,29.25,30.6,29.95,29.9,30.15,30.1,29.95,29.95,, -2011-11-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,31.4,29.85,30.95,30.25,30.1,30.3,30.2,30.25,30.2,, -2011-11-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,31.1,29.75,30.95,30.2,30.15,30.4,30.3,30.25,30.35,, -2011-11-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,28.9,28.35,30.0,29.5,29.65,29.9,29.85,29.75,29.85,, -2011-11-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,36.45,33.45,34.35,32.95,32.65,32.65,32.25,31.75,31.2,, -2011-11-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.45,31.5,32.9,32.05,31.85,32.05,31.6,31.15,31.25,, -2011-11-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,31.4,30.2,31.75,31.25,31.1,31.25,30.9,30.5,30.5,, -2011-11-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.1,30.75,32.1,31.6,31.4,31.55,31.2,30.9,31.0,, -2011-11-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.05,30.7,32.2,31.7,31.45,31.65,31.35,31.05,31.05,, -2011-11-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.36,32.65,33.6,32.8,32.25,32.35,32.0,32.0,31.65,, -2011-11-17 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.75,34.65,33.8,33.3,33.35,32.8,32.6,32.75,, -2011-11-18 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.35,33.75,33.3,33.1,33.2,32.65,32.6,32.6,, -2011-11-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.95,34.35,33.8,33.5,33.5,33.1,33.25,33.1,33.5, -2011-11-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.3,33.85,33.4,33.15,33.3,32.85,33.05,33.2,33.15, -2011-11-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33.6,35.05,34.45,34.0,34.1,33.65,33.7,33.8,33.55, -2011-11-25 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34.5,35.6,35.05,34.55,34.7,34.1,34.15,34.2,33.9, -2011-11-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32.0,33.7,33.3,32.95,33.15,32.85,33.0,33.05,33.25, -2011-11-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,31.35,33.2,33.0,32.7,32.9,32.55,32.7,32.9,33.0, -2011-11-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,28.35,30.9,31.3,31.2,31.35,31.05,31.0,31.0,31.2, -2011-12-01 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.9,30.15,30.6,30.7,31.05,30.85,30.85,30.95,30.7, -2011-12-02 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.8,29.9,30.45,30.6,30.95,30.65,30.8,30.85,30.55, -2011-12-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.8,29.7,30.1,30.15,30.55,30.35,30.45,30.5,30.25, -2011-12-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,28.1,29.95,30.2,30.2,30.5,30.35,30.45,30.5,30.25, -2011-12-07 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,28.6,30.6,30.6,30.55,30.85,30.7,30.8,30.8,30.4, -2011-12-08 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30.15,32.1,31.75,31.5,31.7,31.55,31.6,31.65,31.2, -2011-12-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.2,29.55,30.25,30.4,30.8,30.8,31.0,31.05,30.55, -2011-12-12 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.6,30.1,30.8,30.9,31.35,31.3,31.45,31.5,31.1, -2011-12-13 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.1,29.9,30.75,31.1,31.6,31.55,31.7,31.8,31.2, -2011-12-14 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,27.1,30.1,31.1,31.25,31.7,31.7,31.85,32.05,31.55, -2011-12-15 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.35,28.9,30.2,30.55,31.05,31.15,31.35,31.5,31.0, -2011-12-16 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.1,28.85,29.85,30.35,30.95,31.1,31.3,31.45,31.25, -2011-12-19 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.6,28.35,29.3,30.05,30.7,30.85,31.1,31.35,31.25, -2011-12-20 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.85,26.55,27.65,28.65,29.45,29.85,30.2,30.5,30.4, -2011-12-21 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21.36,24.5,25.85,27.05,27.9,28.45,28.75,29.35,29.45, -2011-12-22 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.1,26.0,27.2,28.1,28.5,28.85,29.45,29.45, -2011-12-23 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.7,26.4,27.45,28.15,28.55,28.95,29.6,29.5, -2011-12-27 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.45,26.2,27.2,27.9,28.3,28.7,29.35,29.3,30.0 -2011-12-28 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.7,27.1,27.8,28.4,28.9,29.25,29.85,29.85,30.15 -2011-12-29 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,25.95,26.55,27.35,28.05,28.45,28.9,29.5,29.5,29.9 -2011-12-30 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,26.7,27.15,27.75,28.4,28.7,29.1,29.75,29.75,29.95 -2012-01-03 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.8,25.8,26.8,27.5,27.85,28.2,29.0,29.0,29.3 -2012-01-04 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,24.2,25.3,26.35,27.05,27.6,28.0,28.65,28.65,29.05 -2012-01-05 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.75,24.9,26.0,26.8,27.4,27.95,28.55,28.55,29.55 -2012-01-06 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23.05,24.4,25.55,26.45,27.0,27.55,28.15,28.1,28.35 -2012-01-09 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,22.85,24.15,25.4,26.3,26.9,27.4,28.0,27.95,28.05 -2012-01-10 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,22.35,23.65,25.1,26.05,26.6,27.15,27.8,27.75,28.2 -2012-01-11 00:00:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,22.95,24.15,25.4,26.3,26.9,27.4,28.05,28.05,28.25 diff --git a/cookbook/runConsoleUntilInterrupt.py b/cookbook/runConsoleUntilInterrupt.py deleted file mode 100644 index 695e352..0000000 --- a/cookbook/runConsoleUntilInterrupt.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -""" -example on how to run a console script until interrupted by keyboard - -@author: jev -""" - - -from time import sleep -counter = 0 - -print 'Press Ctr-C to stop loop' - -try: - while True: - print counter - counter += 1 - sleep(1) - -except KeyboardInterrupt: - print 'All done' - diff --git a/cookbook/scales.py b/cookbook/scales.py deleted file mode 100644 index a6041ba..0000000 --- a/cookbook/scales.py +++ /dev/null @@ -1,488 +0,0 @@ -#!/usr/bin/env python - -############################################################################# -## -## This file was adapted from Taurus, a Tango User Interface Library -## -## http://www.tango-controls.org/static/taurus/latest/doc/html/index.html -## -## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain -## -## Taurus is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## Taurus is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with Taurus. If not, see . -## -############################################################################# - -""" -scales.py: Custom scales -""" -__all__=["DateTimeScaleEngine", "DeltaTimeScaleEngine", "FixedLabelsScaleEngine", - "FancyScaleDraw", "TaurusTimeScaleDraw", "DeltaTimeScaleDraw", - "FixedLabelsScaleDraw"] - -import numpy -from datetime import datetime, timedelta -from time import mktime -from PyQt4 import Qt, Qwt5 - - -def _getDefaultAxisLabelsAlignment(axis, rotation): - '''return a "smart" alignment for the axis labels depending on the axis - and the label rotation - - :param axis: (Qwt5.QwtPlot.Axis) the axis - :param rotation: (float) The rotation (in degrees, clockwise-positive) - - :return: (Qt.Alignment) an alignment - ''' - if axis == Qwt5.QwtPlot.xBottom: - if rotation == 0 : return Qt.Qt.AlignHCenter|Qt.Qt.AlignBottom - elif rotation < 0: return Qt.Qt.AlignLeft|Qt.Qt.AlignBottom - else: return Qt.Qt.AlignRight|Qt.Qt.AlignBottom - elif axis == Qwt5.QwtPlot.yLeft: - if rotation == 0 : return Qt.Qt.AlignLeft|Qt.Qt.AlignVCenter - elif rotation < 0: return Qt.Qt.AlignLeft|Qt.Qt.AlignBottom - else: return Qt.Qt.AlignLeft|Qt.Qt.AlignTop - elif axis == Qwt5.QwtPlot.yRight: - if rotation == 0 : return Qt.Qt.AlignRight|Qt.Qt.AlignVCenter - elif rotation < 0: return Qt.Qt.AlignRight|Qt.Qt.AlignTop - else: return Qt.Qt.AlignRight|Qt.Qt.AlignBottom - elif axis == Qwt5.QwtPlot.xTop: - if rotation == 0 : return Qt.Qt.AlignHCenter|Qt.Qt.AlignTop - elif rotation < 0: return Qt.Qt.AlignLeft|Qt.Qt.AlignTop - else: return Qt.Qt.AlignRight|Qt.Qt.AlignTop - -class FancyScaleDraw(Qwt5.QwtScaleDraw): - - '''This is a scaleDraw with a tuneable palette and label formats''' - def __init__(self, format = None, palette = None): - Qwt5.QwtScaleDraw.__init__(self) - self._labelFormat = format - self._palette = palette - - def setPalette(self, palette): - '''pass a QPalette or None to use default''' - self._palette = palette - - def getPalette(self): - return self._palette - - def setLabelFormat(self, format): - '''pass a format string (e.g. "%g") or None to use default (it uses the locale)''' - self._labelFormat = format - self.invalidateCache() #to force repainting of the labels - - def getLabelFormat(self): - '''pass a format string (e.g. "%g") or None to use default (it uses the locale)''' - return self._labelFormat - - def label(self, val): - if str(self._labelFormat) == "": return Qwt5.QwtText() - if self._labelFormat is None: - return Qwt5.QwtScaleDraw.label(self, val) - else: - return Qwt5.QwtText(self._labelFormat%val) - - def draw(self, painter, palette): - if self._palette is None: - Qwt5.QwtScaleDraw.draw(self, painter, palette) - else: - Qwt5.QwtScaleDraw.draw(self, painter, self._palette) - - -class DateTimeScaleEngine(Qwt5.QwtLinearScaleEngine): - def __init__(self, scaleDraw=None): - Qwt5.QwtLinearScaleEngine.__init__(self) - self.setScaleDraw(scaleDraw) - - def setScaleDraw(self, scaleDraw): - self._scaleDraw = scaleDraw - - def scaleDraw(self): - return self._scaleDraw - - def divideScale(self, x1, x2, maxMajSteps, maxMinSteps, stepSize): - ''' Reimplements Qwt5.QwtLinearScaleEngine.divideScale - - **Important**: The stepSize parameter is **ignored**. - - :return: (Qwt5.QwtScaleDiv) a scale division whose ticks are aligned with - the natural time units ''' - - #if stepSize != 0: - # scaleDiv = Qwt5.QwtLinearScaleEngine.divideScale(self, x1, x2, maxMajSteps, maxMinSteps, stepSize) - # scaleDiv.datetimeLabelFormat = "%Y/%m/%d %H:%M%S.%f" - # return scaleDiv - - interval = Qwt5.QwtDoubleInterval(x1, x2).normalized() - if interval.width() <= 0: - return Qwt5.QwtScaleDiv() - - dt1=datetime.fromtimestamp(interval.minValue()) - dt2=datetime.fromtimestamp(interval.maxValue()) - - if dt1.year<1900 or dt2.year>9999 : #limits in time.mktime and datetime - return Qwt5.QwtScaleDiv() - - majticks = [] - medticks = [] - minticks = [] - - dx=interval.width() - - if dx > 63072001: # = 3600s*24*(365+366) = 2 years (counting a leap year) - format = "%Y" - for y in range(dt1.year+1,dt2.year): - dt = datetime(year=y, month=1, day=1) - majticks.append(mktime(dt.timetuple())) - - elif dx > 5270400: # = 3600s*24*61 = 61 days - format = "%Y %b" - d = timedelta(days=31) - dt = dt1.replace(day=1, hour=0, minute=0, second=0, microsecond=0)+d - while(dt 172800: # 3600s24*2 = 2 days - format = "%b/%d" - d = timedelta(days=1) - dt = dt1.replace(hour=0, minute=0, second=0, microsecond=0) + d - while(dt 7200: # 3600s*2 = 2hours - format = "%b/%d-%Hh" - d = timedelta(hours=1) - dt = dt1.replace(minute=0, second=0, microsecond=0) + d - while(dt 1200: # 60s*20 =20 minutes - format = "%H:%M" - d = timedelta(minutes=10) - dt = dt1.replace(minute=(dt1.minute//10)*10, second=0, microsecond=0) + d - while(dt 120: # =60s*2 = 2 minutes - format = "%H:%M" - d = timedelta(minutes=1) - dt = dt1.replace(second=0, microsecond=0) + d - while(dt 20: # 20 s - format = "%H:%M:%S" - d = timedelta(seconds=10) - dt = dt1.replace(second=(dt1.second//10)*10, microsecond=0) + d - while(dt 2: # 2s - format = "%H:%M:%S" - majticks=range(int(x1)+1, int(x2)) - - else: #less than 2s (show microseconds) - scaleDiv = Qwt5.QwtLinearScaleEngine.divideScale(self, x1, x2, maxMajSteps, maxMinSteps, stepSize) - self.scaleDraw().setDatetimeLabelFormat("%S.%f") - return scaleDiv - - #make sure to comply with maxMajTicks - L= len(majticks) - if L > maxMajSteps: - majticks = majticks[::int(numpy.ceil(float(L)/maxMajSteps))] - - scaleDiv = Qwt5.QwtScaleDiv(interval, minticks, medticks, majticks) - self.scaleDraw().setDatetimeLabelFormat(format) - if x1>x2: - scaleDiv.invert() - - ##START DEBUG - #print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - #for tk in scaleDiv.ticks(scaleDiv.MajorTick): - # print datetime.fromtimestamp(tk).isoformat() - #print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" - ##END DEBUG - - return scaleDiv - - @staticmethod - def getDefaultAxisLabelsAlignment(axis, rotation): - '''return a "smart" alignment for the axis labels depending on the axis - and the label rotation - - :param axis: (Qwt5.QwtPlot.Axis) the axis - :param rotation: (float) The rotation (in degrees, clockwise-positive) - - :return: (Qt.Alignment) an alignment - ''' - return _getDefaultAxisLabelsAlignment(axis, rotation) - - @staticmethod - def enableInAxis(plot, axis, scaleDraw =None, rotation=None): - '''convenience method that will enable this engine in the given - axis. Note that it changes the ScaleDraw as well. - - :param plot: (Qwt5.QwtPlot) the plot to change - :param axis: (Qwt5.QwtPlot.Axis) the id of the axis - :param scaleDraw: (Qwt5.QwtScaleDraw) Scale draw to use. If None given, - the current ScaleDraw for the plot will be used if - possible, and a :class:`TaurusTimeScaleDraw` will be set if not - :param rotation: (float or None) The rotation of the labels (in degrees, clockwise-positive) - ''' - if scaleDraw is None: - scaleDraw = plot.axisScaleDraw(axis) - if not isinstance(scaleDraw, TaurusTimeScaleDraw): - scaleDraw = TaurusTimeScaleDraw() - plot.setAxisScaleDraw(axis, scaleDraw) - plot.setAxisScaleEngine(axis, DateTimeScaleEngine(scaleDraw)) - if rotation is not None: - alignment = DateTimeScaleEngine.getDefaultAxisLabelsAlignment(axis, rotation) - plot.setAxisLabelRotation(axis, rotation) - plot.setAxisLabelAlignment(axis, alignment) - - @staticmethod - def disableInAxis(plot, axis, scaleDraw=None, scaleEngine=None): - '''convenience method that will disable this engine in the given - axis. Note that it changes the ScaleDraw as well. - - :param plot: (Qwt5.QwtPlot) the plot to change - :param axis: (Qwt5.QwtPlot.Axis) the id of the axis - :param scaleDraw: (Qwt5.QwtScaleDraw) Scale draw to use. If None given, - a :class:`FancyScaleDraw` will be set - :param scaleEngine: (Qwt5.QwtScaleEngine) Scale draw to use. If None given, - a :class:`Qwt5.QwtLinearScaleEngine` will be set - ''' - if scaleDraw is None: - scaleDraw=FancyScaleDraw() - if scaleEngine is None: - scaleEngine = Qwt5.QwtLinearScaleEngine() - plot.setAxisScaleEngine(axis, scaleEngine) - plot.setAxisScaleDraw(axis, scaleDraw) - - -class TaurusTimeScaleDraw(FancyScaleDraw): - - def __init__(self, *args): - FancyScaleDraw.__init__(self, *args) - - def setDatetimeLabelFormat(self, format): - self._datetimeLabelFormat = format - - def datetimeLabelFormat(self): - return self._datetimeLabelFormat - - def label(self, val): - if str(self._labelFormat) == "": return Qwt5.QwtText() - # From val to a string with time - t = datetime.fromtimestamp(val) - try: #If the scaleDiv was created by a DateTimeScaleEngine it has a _datetimeLabelFormat - s = t.strftime(self._datetimeLabelFormat) - except AttributeError, e: - print "Warning: cannot get the datetime label format (Are you using a DateTimeScaleEngine?)" - s = t.isoformat(' ') - return Qwt5.QwtText(s) - - -class DeltaTimeScaleEngine(Qwt5.QwtLinearScaleEngine): - def __init__(self, scaleDraw=None): - Qwt5.QwtLinearScaleEngine.__init__(self) - self.setScaleDraw(scaleDraw) - - def setScaleDraw(self, scaleDraw): - self._scaleDraw = scaleDraw - - def scaleDraw(self): - return self._scaleDraw - - def divideScale(self, x1, x2, maxMajSteps, maxMinSteps, stepSize): - ''' Reimplements Qwt5.QwtLinearScaleEngine.divideScale - - :return: (Qwt5.QwtScaleDiv) a scale division whose ticks are aligned with - the natural delta time units ''' - interval = Qwt5.QwtDoubleInterval(x1, x2).normalized() - if interval.width() <= 0: - return Qwt5.QwtScaleDiv() - d_range = interval.width() - if d_range < 2: # 2s - return Qwt5.QwtLinearScaleEngine.divideScale(self, x1, x2, maxMajSteps, maxMinSteps, stepSize) - elif d_range < 20: # 20 s - s = 1 - elif d_range < 120: # =60s*2 = 2 minutes - s = 10 - elif d_range < 1200: # 60s*20 =20 minutes - s = 60 - elif d_range < 7200: # 3600s*2 = 2 hours - s = 600 - elif d_range < 172800: # 3600s24*2 = 2 days - s = 3600 - else: - s = 86400 #1 day - #calculate a step size that respects the base step (s) and also enforces the maxMajSteps - stepSize = s * int(numpy.ceil(float(d_range//s)/maxMajSteps)) - return Qwt5.QwtLinearScaleEngine.divideScale(self, x1, x2, maxMajSteps, maxMinSteps, stepSize) - - @staticmethod - def getDefaultAxisLabelsAlignment(axis, rotation): - '''return a "smart" alignment for the axis labels depending on the axis - and the label rotation - - :param axis: (Qwt5.QwtPlot.Axis) the axis - :param rotation: (float) The rotation (in degrees, clockwise-positive) - - :return: (Qt.Alignment) an alignment - ''' - return _getDefaultAxisLabelsAlignment(axis, rotation) - - @staticmethod - def enableInAxis(plot, axis, scaleDraw =None, rotation=None): - '''convenience method that will enable this engine in the given - axis. Note that it changes the ScaleDraw as well. - - :param plot: (Qwt5.QwtPlot) the plot to change - :param axis: (Qwt5.QwtPlot.Axis) the id of the axis - :param scaleDraw: (Qwt5.QwtScaleDraw) Scale draw to use. If None given, - the current ScaleDraw for the plot will be used if - possible, and a :class:`TaurusTimeScaleDraw` will be set if not - :param rotation: (float or None) The rotation of the labels (in degrees, clockwise-positive) - ''' - if scaleDraw is None: - scaleDraw = plot.axisScaleDraw(axis) - if not isinstance(scaleDraw, DeltaTimeScaleDraw): - scaleDraw = DeltaTimeScaleDraw() - plot.setAxisScaleDraw(axis, scaleDraw) - plot.setAxisScaleEngine(axis, DeltaTimeScaleEngine(scaleDraw)) - if rotation is not None: - alignment = DeltaTimeScaleEngine.getDefaultAxisLabelsAlignment(axis, rotation) - plot.setAxisLabelRotation(axis, rotation) - plot.setAxisLabelAlignment(axis, alignment) - - @staticmethod - def disableInAxis(plot, axis, scaleDraw=None, scaleEngine=None): - '''convenience method that will disable this engine in the given - axis. Note that it changes the ScaleDraw as well. - - :param plot: (Qwt5.QwtPlot) the plot to change - :param axis: (Qwt5.QwtPlot.Axis) the id of the axis - :param scaleDraw: (Qwt5.QwtScaleDraw) Scale draw to use. If None given, - a :class:`FancyScaleDraw` will be set - :param scaleEngine: (Qwt5.QwtScaleEngine) Scale draw to use. If None given, - a :class:`Qwt5.QwtLinearScaleEngine` will be set - ''' - if scaleDraw is None: - scaleDraw=FancyScaleDraw() - if scaleEngine is None: - scaleEngine = Qwt5.QwtLinearScaleEngine() - plot.setAxisScaleEngine(axis, scaleEngine) - plot.setAxisScaleDraw(axis, scaleDraw) - - -class DeltaTimeScaleDraw(FancyScaleDraw): - - def __init__(self, *args): - FancyScaleDraw.__init__(self, *args) - - def label(self, val): - if val >= 0: - s = "+%s"%str(timedelta(seconds=val)) - else: - s = "-%s"%str(timedelta(seconds=-val)) - return Qwt5.QwtText(s) - - - -class FixedLabelsScaleEngine(Qwt5.QwtLinearScaleEngine): - def __init__(self, positions): - '''labels is a sequence of (pos,label) tuples where pos is the point - at wich to draw the label and label is given as a python string (or QwtText)''' - Qwt5.QwtScaleEngine.__init__(self) - self._positions = positions - #self.setAttribute(self.Floating,True) - - def divideScale(self, x1, x2, maxMajSteps, maxMinSteps, stepSize=0.0): - div = Qwt5.QwtScaleDiv(x1, x2, self._positions, [], []) - div.setTicks(Qwt5.QwtScaleDiv.MajorTick, self._positions) - return div - - @staticmethod - def enableInAxis(plot, axis, scaleDraw =None): - '''convenience method that will enable this engine in the given - axis. Note that it changes the ScaleDraw as well. - - :param plot: (Qwt5.QwtPlot) the plot to change - :param axis: (Qwt5.QwtPlot.Axis) the id of the axis - :param scaleDraw: (Qwt5.QwtScaleDraw) Scale draw to use. If None given, - the current ScaleDraw for the plot will be used if - possible, and a :class:`FixedLabelsScaleDraw` will be set if not - ''' - if scaleDraw is None: - scaleDraw = plot.axisScaleDraw(axis) - if not isinstance(scaleDraw, FixedLabelsScaleDraw): - scaleDraw = FixedLabelsScaleDraw() - plot.setAxisScaleDraw(axis, scaleDraw) - plot.setAxisScaleEngine(axis, FixedLabelsScaleEngine(scaleDraw)) - - @staticmethod - def disableInAxis(plot, axis, scaleDraw=None, scaleEngine=None): - '''convenience method that will disable this engine in the given - axis. Note that it changes the ScaleDraw as well. - - :param plot: (Qwt5.QwtPlot) the plot to change - :param axis: (Qwt5.QwtPlot.Axis) the id of the axis - :param scaleDraw: (Qwt5.QwtScaleDraw) Scale draw to use. If None given, - a :class:`FancyScaleDraw` will be set - :param scaleEngine: (Qwt5.QwtScaleEngine) Scale draw to use. If None given, - a :class:`Qwt5.QwtLinearScaleEngine` will be set - ''' - if scaleDraw is None: - scaleDraw=FancyScaleDraw() - if scaleEngine is None: - scaleEngine = Qwt5.QwtLinearScaleEngine() - plot.setAxisScaleEngine(axis, scaleEngine) - plot.setAxisScaleDraw(axis, scaleDraw) - - -class FixedLabelsScaleDraw(FancyScaleDraw): - def __init__(self, positions, labels): - '''This is a custom ScaleDraw that shows labels at given positions (and nowhere else) - positions is a sequence of points for which labels are defined. - labels is a sequence strings (or QwtText) - Note that the lengths of positions and labels must match''' - - if len(positions) != len(labels): - raise ValueError('lengths of positions and labels do not match') - - FancyScaleDraw.__init__(self) - self._positions = positions - self._labels = labels - #self._positionsarray = numpy.array(self._positions) #this is stored just in case - - def label(self, val): - try: - index = self._positions.index(val) #try to find an exact match - except: - index = None #It won't show any label - #use the index of the closest position - #index = (numpy.abs(self._positionsarray - val)).argmin() - if index is not None: - return Qwt5.QwtText(self._labels[index]) - else: Qwt5.QwtText() - - diff --git a/cookbook/workingWithDatesAndTime.py b/cookbook/workingWithDatesAndTime.py deleted file mode 100644 index 064ae6a..0000000 --- a/cookbook/workingWithDatesAndTime.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Sun Oct 16 17:45:02 2011 - -@author: jev -""" - -import time -import datetime as dt -from pandas import * -from pandas.core import datetools - - - - - -# basic functions -print 'Epoch start: %s' % time.asctime(time.gmtime(0)) -print 'Seconds from epoch: %.2f' % time.time() - -today = dt.date.today() -print type(today) -print 'Today is %s' % today.strftime('%Y.%m.%d') - -# parse datetime -d = dt.datetime.strptime('20120803 21:59:59',"%Y%m%d %H:%M:%S") - - - - -# time deltas -someDate = dt.date(2011,8,1) -delta = today - someDate -print 'Delta :', delta - -# calculate difference in dates -delta = dt.timedelta(days=20) -print 'Today-delta=', today-delta - - -t = dt.datetime(*time.strptime('3/30/2004',"%m/%d/%Y")[0:5]) -# the '*' operator unpacks the tuple, producing the argument list. -print t - - -# print every 3d wednesday of the month -for month in xrange(1,13): - t = dt.date(2013,month,1)+datetools.relativedelta(months=1) - - - offset = datetools.Week(weekday=4) - if t.weekday()<>4: - t_new = t+3*offset - else: - t_new = t+2*offset - - t_new = t_new-datetools.relativedelta(days=30) - print t_new.strftime("%B, %d %Y (%A)") - -#rng = DateRange(t, t+datetools.YearEnd()) -#print rng - -# create a range of times -start = dt.datetime(2012,8,1)+datetools.relativedelta(hours=9,minutes=30) -end = dt.datetime(2012,8,1)+datetools.relativedelta(hours=22) - -rng = date_range(start,end,freq='30min') -for r in rng: print r.strftime("%Y%m%d %H:%M:%S") \ No newline at end of file diff --git a/createDistribution.py b/createDistribution.py deleted file mode 100644 index c6776bc..0000000 --- a/createDistribution.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- - - -import os, shutil - -def copyFiles(sourceDir,targetDir,includes=None): - - if not os.path.exists(targetDir): os.makedirs(targetDir) - - - for f in os.listdir(sourceDir): - - base,ext = os.path.splitext(f) - - if (ext =='.py') and (True if not includes else (base in includes)): - s = os.path.join(sourceDir, f) - d = os.path.join(targetDir, f) - print s, '->', d - shutil.copyfile(s,d) - - -sourceDir = 'lib' -targetDir = 'dist\\tradingWithPython\\lib' - - - -includes = ['__init__','cboe','csvDatabase','functions','yahooFinance','extra','bats','backtest'] - -print '-----------init file---------' -shutil.copyfile('__init__.py','dist\\tradingWithPython\\__init__.py') -print '-----------lib files---------' -copyFiles(sourceDir,targetDir,includes) -print '-----------IB files----------' -copyFiles(sourceDir+'\\interactiveBrokers',targetDir+'\\interactiveBrokers') - diff --git a/dist/make.bat b/dist/make.bat deleted file mode 100644 index 00c835c..0000000 --- a/dist/make.bat +++ /dev/null @@ -1,3 +0,0 @@ -rd /s /q build -python setup.py bdist_wininst -python setup.py sdist \ No newline at end of file diff --git a/dist/setup.py b/dist/setup.py deleted file mode 100644 index b738f38..0000000 --- a/dist/setup.py +++ /dev/null @@ -1,14 +0,0 @@ -from distutils.core import setup - -import tradingWithPython as twp - - -setup(name = "tradingWithPython", - version = twp.__version__, - description = "A collection of functions and classes for Quantitative trading", - author = "Jev Kuznetsov", - author_email = "jev.kuznetsov@gmail.com", - url = "http://www.tradingwithpython.com/", - license = "BSD", - packages=["tradingWithPython","tradingWithPython/lib","tradingWithPython/lib/interactiveBrokers"] - ) \ No newline at end of file diff --git a/historicDataDownloader/historicDataDownloader.py b/historicDataDownloader/historicDataDownloader.py deleted file mode 100644 index 8ba6d83..0000000 --- a/historicDataDownloader/historicDataDownloader.py +++ /dev/null @@ -1,146 +0,0 @@ -''' -Created on 4 aug. 2012 -Copyright: Jev Kuznetsov -License: BSD - -a module for downloading historic data from IB - -''' -import ib -import pandas -from ib.ext.Contract import Contract -from ib.opt import ibConnection, message -from time import sleep -import tradingWithPython.lib.logger as logger -from pandas import DataFrame, Index -import datetime as dt -from timeKeeper import TimeKeeper -import time - -timeFormat = "%Y%m%d %H:%M:%S" - -class DataHandler(object): - ''' handles incoming messages ''' - def __init__(self,tws): - self._log = logger.getLogger('DH') - tws.register(self.msgHandler,message.HistoricalData) - self.reset() - - def reset(self): - self._log.debug('Resetting data') - self.dataReady = False - self._timestamp = [] - self._data = {'open':[],'high':[],'low':[],'close':[],'volume':[],'count':[],'WAP':[]} - - def msgHandler(self,msg): - #print '[msg]', msg - - if msg.date[:8] == 'finished': - self._log.debug('Data recieved') - self.dataReady = True - return - - self._timestamp.append(dt.datetime.strptime(msg.date,timeFormat)) - for k in self._data.keys(): - self._data[k].append(getattr(msg, k)) - - @property - def data(self): - ''' return downloaded data as a DataFrame ''' - df = DataFrame(data=self._data,index=Index(self._timestamp)) - return df - - -class Downloader(object): - def __init__(self,debug=False): - self._log = logger.getLogger('DLD') - self._log.debug('Initializing data dwonloader. Pandas version={0}, ibpy version:{1}'.format(pandas.__version__,ib.version)) - - self.tws = ibConnection() - self._dataHandler = DataHandler(self.tws) - - if debug: - self.tws.registerAll(self._debugHandler) - self.tws.unregister(self._debugHandler,message.HistoricalData) - - self._log.debug('Connecting to tws') - self.tws.connect() - - self._timeKeeper = TimeKeeper() # keep track of past requests - self._reqId = 1 # current request id - - - def _debugHandler(self,msg): - print '[debug]', msg - - - def requestData(self,contract,endDateTime,durationStr='1800 S',barSizeSetting='1 secs',whatToShow='TRADES',useRTH=1,formatDate=1): - self._log.debug('Requesting data for %s end time %s.' % (contract.m_symbol,endDateTime)) - - - while self._timeKeeper.nrRequests(timeSpan=600) > 59: - print 'Too many requests done. Waiting... ' - time.sleep(1) - - self._timeKeeper.addRequest() - self._dataHandler.reset() - self.tws.reqHistoricalData(self._reqId,contract,endDateTime,durationStr,barSizeSetting,whatToShow,useRTH,formatDate) - self._reqId+=1 - - #wait for data - startTime = time.time() - timeout = 3 - while not self._dataHandler.dataReady and (time.time()-startTime < timeout): - sleep(2) - - if not self._dataHandler.dataReady: - self._log.error('Data timeout') - - print self._dataHandler.data - - return self._dataHandler.data - - def getIntradayData(self,contract, dateTuple ): - ''' get full day data on 1-s interval - date: a tuple of (yyyy,mm,dd) - ''' - - openTime = dt.datetime(*dateTuple)+dt.timedelta(hours=16) - closeTime = dt.datetime(*dateTuple)+dt.timedelta(hours=22) - - timeRange = pandas.date_range(openTime,closeTime,freq='30min') - - datasets = [] - - for t in timeRange: - datasets.append(self.requestData(contract,t.strftime(timeFormat))) - - return pandas.concat(datasets) - - - def disconnect(self): - self.tws.disconnect() - - -if __name__=='__main__': - - dl = Downloader(debug=True) - - c = Contract() - c.m_symbol = 'SPY' - c.m_secType = 'STK' - c.m_exchange = 'SMART' - c.m_currency = 'USD' - df = dl.getIntradayData(c, (2012,8,6)) - df.to_csv('test.csv') - -# df = dl.requestData(c, '20120803 22:00:00') -# df.to_csv('test1.csv') -# df = dl.requestData(c, '20120803 21:30:00') -# df.to_csv('test2.csv') - - dl.disconnect() - - - - print 'Done.' \ No newline at end of file diff --git a/historicDataDownloader/testData.py b/historicDataDownloader/testData.py deleted file mode 100644 index 7db4a08..0000000 --- a/historicDataDownloader/testData.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Sun Aug 05 22:06:13 2012 - -@author: jev -""" -import numpy as np -from pandas import * -from matplotlib.pyplot import * - - - -#df1 = DataFrame.from_csv('test1.csv').astype(np.dtype('f4')) -#df2 = DataFrame.from_csv('test2.csv').astype(np.dtype('f4')) -#df = DataFrame([df1,df2]) -df = DataFrame.from_csv('test.csv').astype(np.dtype('f4')) - -close('all') -clf() -ax1=subplot(2,1,1) -df[['high','low','WAP']].plot(grid=True,ax=gca()) - - -subplot(2,1,2,sharex=ax1) -df[['count','volume']].plot(ax=gca()) \ No newline at end of file diff --git a/historicDataDownloader/timeKeeper.py b/historicDataDownloader/timeKeeper.py deleted file mode 100644 index 557014a..0000000 --- a/historicDataDownloader/timeKeeper.py +++ /dev/null @@ -1,55 +0,0 @@ -# -*- coding: utf-8 -*- -""" -used to check timing constraints - -@author: jev -""" - - -import os -import datetime as dt -import tradingWithPython.lib.logger as logger - -class TimeKeeper(object): - def __init__(self): - self._log = logger.getLogger('TK') - dataDir = os.path.expanduser('~')+'/twpData' - - if not os.path.exists(dataDir): - os.mkdir(dataDir) - - self._timeFormat = "%Y%m%d %H:%M:%S" - self.dataFile = os.path.normpath(os.path.join(dataDir,'requests.txt')) - self._log.debug('Data file: {0}'.format(self.dataFile)) - - def addRequest(self): - ''' adds a timestamp of current request''' - with open(self.dataFile,'a') as f: - f.write(dt.datetime.now().strftime(self._timeFormat)+'\n') - - - def nrRequests(self,timeSpan=600): - ''' return number of requests in past timespan (s) ''' - delta = dt.timedelta(seconds=timeSpan) - now = dt.datetime.now() - requests = 0 - - with open(self.dataFile,'r') as f: - lines = f.readlines() - - for line in lines: - if now-dt.datetime.strptime(line.strip(),self._timeFormat) < delta: - requests+=1 - - if requests==0: # erase all contents if no requests are relevant - open(self.dataFile,'w').close() - - self._log.debug('past requests: {0}'.format(requests)) - return requests - -if __name__=='__main__': - print 'testing timeKeeper' - - tk = TimeKeeper() - tk.addRequest() - print tk.nrRequests() \ No newline at end of file diff --git a/lib/__init__.py b/lib/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/lib/backtest.py b/lib/backtest.py deleted file mode 100644 index f1a41f4..0000000 --- a/lib/backtest.py +++ /dev/null @@ -1,202 +0,0 @@ -#------------------------------------------------------------------------------- -# Name: backtest -# Purpose: perform routine backtesting tasks. -# This module should be useable as a stand-alone library outide of the TWP package. -# -# Author: Jev Kuznetsov -# -# Created: 03/07/2014 -# Copyright: (c) Jev Kuznetsov 2013 -# Licence: BSD -#------------------------------------------------------------------------------- - -import pandas as pd -import matplotlib.pyplot as plt -import sys -import numpy as np - - - - -def tradeBracket(price,entryBar,upper=None, lower=None, timeout=None): - ''' - trade a bracket on price series, return price delta and exit bar # - Input - ------ - price : numpy array of price values - entryBar: entry bar number, *determines entry price* - upper : high stop - lower : low stop - timeout : max number of periods to hold - - Returns exit price and number of bars held - - ''' - assert isinstance(price, np.ndarray) , 'price must be a numpy array' - - - # create list of exit indices and add max trade duration. Exits are relative to entry bar - if timeout: # set trade length to timeout or series length - exits = [min(timeout,len(price)-entryBar-1)] - else: - exits = [len(price)-entryBar-1] - - p = price[entryBar:entryBar+exits[0]+1] # subseries of price - - # extend exits list with conditional exits - # check upper bracket - if upper: - assert upper>p[0] , 'Upper bracket must be higher than entry price ' - idx = np.where(p>upper)[0] # find where price is higher than the upper bracket - if idx.any(): - exits.append(idx[0]) # append first occurence - # same for lower bracket - if lower: - assert lower 0].index , -# 'ko':self.trades[self.trades == 0].index, -# 'rv':self.trades[self.trades < 0].index} -# -# -# for style, idx in indices.iteritems(): -# if len(idx) > 0: -# p[idx].plot(style=style) - - # --- plot trades - #colored line for long positions - idx = (self.data['shares'] > 0) | (self.data['shares'] > 0).shift(1) - if idx.any(): - p[idx].plot(style='go') - l.append('long') - - #colored line for short positions - idx = (self.data['shares'] < 0) | (self.data['shares'] < 0).shift(1) - if idx.any(): - p[idx].plot(style='ro') - l.append('short') - - plt.xlim([p.index[0],p.index[-1]]) # show full axis - - plt.legend(l,loc='best') - plt.title('trades') - - -class ProgressBar: - def __init__(self, iterations): - self.iterations = iterations - self.prog_bar = '[]' - self.fill_char = '*' - self.width = 50 - self.__update_amount(0) - - def animate(self, iteration): - print '\r',self, - sys.stdout.flush() - self.update_iteration(iteration + 1) - - def update_iteration(self, elapsed_iter): - self.__update_amount((elapsed_iter / float(self.iterations)) * 100.0) - self.prog_bar += ' %d of %s complete' % (elapsed_iter, self.iterations) - - def __update_amount(self, new_amount): - percent_done = int(round((new_amount / 100.0) * 100.0)) - all_full = self.width - 2 - num_hashes = int(round((percent_done / 100.0) * all_full)) - self.prog_bar = '[' + self.fill_char * num_hashes + ' ' * (all_full - num_hashes) + ']' - pct_place = (len(self.prog_bar) // 2) - len(str(percent_done)) - pct_string = '%d%%' % percent_done - self.prog_bar = self.prog_bar[0:pct_place] + \ - (pct_string + self.prog_bar[pct_place + len(pct_string):]) - def __str__(self): - return str(self.prog_bar) - -def sharpe(pnl): - return np.sqrt(250)*pnl.mean()/pnl.std() - diff --git a/lib/bats.py b/lib/bats.py deleted file mode 100644 index 9e0be10..0000000 --- a/lib/bats.py +++ /dev/null @@ -1,107 +0,0 @@ -#------------------------------------------------------------------------------- -# Name: BATS -# Purpose: get data from BATS exchange -# -# Author: jev -# -# Created: 17/08/2013 -# Copyright: (c) Jev Kuznetsov 2013 -# Licence: BSD -#------------------------------------------------------------------------------- - -import urllib -import re -import pandas as pd -import datetime as dt -import zipfile -import StringIO -from extra import ProgressBar -import os -import yahooFinance as yf -from string import Template -import numpy as np - -def fileName2date( fName): - '''convert filename to date''' - name = os.path.splitext(fName)[0] - m = re.findall('\d+',name)[0] - return dt.datetime.strptime(m,'%Y%m%d').date() - -def date2fileName(date): - return 'BATSshvol%s.txt.zip' % date.strftime('%Y%m%d') - -def downloadUrl(date): - s = Template('http://www.batstrading.com/market_data/shortsales/$year/$month/$fName-dl?mkt=bzx') - url = s.substitute(fName=date2fileName(date), year=date.year, month='%02d' % date.month) - return url - -class BATS_Data(object): - def __init__(self, dataDir): - ''' create class. dataDir: directory to which files are downloaded ''' - self.dataDir = dataDir - - self.shortRatio = None - self._checkDates() - - - def _checkDates(self): - ''' update list of available dataset dates''' - self.dates = [] - for fName in os.listdir(self.dataDir): - self.dates.append(fileName2date(fName)) - - def _missingDates(self): - ''' check for missing dates based on spy data''' - print 'Getting yahoo data to determine business dates... ', - spy = yf.getHistoricData('SPY',sDate = (2010,1,1)) - busDates = [d.date() for d in spy.index ] - - print 'Date range: ', busDates[0] ,'-', busDates[-1] - missing = [] - for d in busDates: - if d not in self.dates: - missing.append(d) - - return missing - - def updateDb(self): - - print 'Updating database' - missing = self._missingDates() - - for i, date in enumerate(missing): - source = downloadUrl(date) - - dest = os.path.join(self.dataDir,date2fileName(date)) - if not os.path.exists(dest): - print 'Downloading [%i/%i]' %(i,len(missing)), source - urllib.urlretrieve(source, dest) - else: - print 'x', - print 'Update done.' - self._checkDates() - - def loadDate(self,date): - fName = os.path.join(self.dataDir, date2fileName(date)) - zipped = zipfile.ZipFile(fName) # open zip file - lines = zipped.read(zipped.namelist()[0]) # read first file from to lines - buf = StringIO.StringIO(lines) # create buffer - df = pd.read_csv(buf,sep='|',index_col=1,parse_dates=False,dtype={'Date':object,'Short Volume':np.float32,'Total Volume':np.float32}) - s = df['Short Volume']/df['Total Volume'] - s.name = dt.datetime.strptime(df['Date'][-1],'%Y%m%d') - - return s - - def loadData(self): - ''' load data from zip files ''' - data = [] - - pb = ProgressBar(len(self.dates)-1) - - for idx, date in enumerate(self.dates): - data.append(self.loadDate(date)) - pb.animate(idx) - - self.shortRatio = pd.DataFrame(data) - return self.shortRatio - diff --git a/lib/cboe.py b/lib/cboe.py deleted file mode 100644 index af9d0a6..0000000 --- a/lib/cboe.py +++ /dev/null @@ -1,154 +0,0 @@ -# -*- coding: utf-8 -*- -""" -toolset working with cboe data - -@author: Jev Kuznetsov -Licence: BSD -""" -from datetime import datetime, date -import urllib2 -from pandas import DataFrame, Index -from pandas.core import datetools -import numpy as np -import pandas as pd - - -def monthCode(month): - """ - perform month->code and back conversion - - Input: either month nr (int) or month code (str) - Returns: code or month nr - - """ - codes = ('F','G','H','J','K','M','N','Q','U','V','X','Z') - - if isinstance(month,int): - return codes[month-1] - elif isinstance(month,str): - return codes.index(month)+1 - else: - raise ValueError('Function accepts int or str') - - -def vixExpiration(year,month): - """ - expriration date of a VX future - """ - t = datetime(year,month,1)+datetools.relativedelta(months=1) - - - offset = datetools.Week(weekday=4) - if t.weekday()<>4: - t_new = t+3*offset - else: - t_new = t+2*offset - - t_exp = t_new-datetools.relativedelta(days=30) - return t_exp - -def getPutCallRatio(): - """ download current Put/Call ratio""" - urlStr = 'http://www.cboe.com/publish/ScheduledTask/MktData/datahouse/totalpc.csv' - - try: - lines = urllib2.urlopen(urlStr).readlines() - except Exception, e: - s = "Failed to download:\n{0}".format(e); - print s - - headerLine = 2 - - header = lines[headerLine].strip().split(',') - - data = [[] for i in range(len(header))] - - for line in lines[(headerLine+1):]: - fields = line.rstrip().split(',') - data[0].append(datetime.strptime(fields[0],'%m/%d/%Y')) - for i,field in enumerate(fields[1:]): - data[i+1].append(float(field)) - - - return DataFrame(dict(zip(header[1:],data[1:])), index = Index(data[0])) - - - - -def getHistoricData(symbols = ['VIX','VXV','VXMT','VVIX']): - ''' get historic data from CBOE - - return dataframe - ''' - if not isinstance(symbols,list): - symbols = [symbols] - - urls = {'VIX':'http://www.cboe.com/publish/ScheduledTask/MktData/datahouse/vixcurrent.csv', - 'VXV':'http://www.cboe.com/publish/scheduledtask/mktdata/datahouse/vxvdailyprices.csv', - 'VXMT':'http://www.cboe.com/publish/ScheduledTask/MktData/datahouse/vxmtdailyprices.csv', - 'VVIX':'http://www.cboe.com/publish/scheduledtask/mktdata/datahouse/VVIXtimeseries.csv'} - - startLines = {'VIX':1,'VXV':2,'VXMT':2,'VVIX':1} - cols = {'VIX':'VIX Close','VXV':'CLOSE','VXMT':'Close','VVIX':'VVIX'} - - data = {} - - for symbol in symbols: - urlStr = urls[symbol] - print 'Downloading %s from %s' % (symbol,urlStr) - - data[symbol] = pd.read_csv(urllib2.urlopen(urlStr), header=startLines[symbol],index_col=0,parse_dates=True)[cols[symbol]] - - - return pd.DataFrame(data) - - - -#---------------------classes-------------------------------------------- -class VixFuture(object): - """ - Class for easy handling of futures data. - """ - - - - def __init__(self,year,month): - self.year = year - self.month = month - - def expirationDate(self): - return vixExpiration(self.year,self.month) - - def daysLeft(self,date): - """ business days to expiration date """ - from pandas import DateRange # this will cause a problem with pandas 0.14 and higher... Method is depreciated and replaced by DatetimeIndex - - r = DateRange(date,self.expirationDate()) - return len(r) - - def __repr__(self): - return 'VX future [%i-%i %s] Exprires: %s' % (self.year,self.month,monthCode(self.month), - self.expirationDate()) -#-------------------test functions--------------------------------------- -def testDownload(): - vix = getHistoricData('VIX') - vxv = getHistoricData('VXV') - vix.plot() - vxv.plot() - -def testExpiration(): - for month in xrange(1,13): - d = vixExpiration(2011,month) - print d.strftime("%B, %d %Y (%A)") - - - -if __name__ == '__main__': - - #testExpiration() - v = VixFuture(2011,11) - print v - - print v.daysLeft(datetime(2011,11,10)) - - \ No newline at end of file diff --git a/lib/classes.py b/lib/classes.py deleted file mode 100644 index a79de44..0000000 --- a/lib/classes.py +++ /dev/null @@ -1,248 +0,0 @@ -""" -worker classes - -@author: Jev Kuznetsov -Licence: GPL v2 -""" - -__docformat__ = 'restructuredtext' - -import os -import logger as logger -import yahooFinance as yahoo -from functions import returns, rank -from datetime import date -from pandas import DataFrame, Series -import numpy as np -import pandas as pd -import matplotlib.pyplot as plt - -class Symbol(object): - ''' - Symbol class, the foundation of Trading With Python library, - This class acts as an interface to Yahoo data, Interactive Brokers etc - ''' - def __init__(self,name): - self.name = name - self.log = logger.getLogger(self.name) - self.log.debug('class created.') - - self.dataDir = os.getenv("USERPROFILE")+'\\twpData\\symbols\\'+self.name - self.log.debug('Data dir:'+self.dataDir) - self.ohlc = None # historic OHLC data - - def downloadHistData(self, startDate=(2010,1,1),endDate=date.today().timetuple()[:3],\ - source = 'yahoo'): - ''' - get historical OHLC data from a data source (yahoo is default) - startDate and endDate are tuples in form (d,m,y) - ''' - self.log.debug('Getting OHLC data') - self.ohlc = yahoo.getHistoricData(self.name,startDate,endDate) - - - def histData(self,column='adj_close'): - ''' - Return a column of historic data. - - Returns - ------------- - df : DataFrame - ''' - s = self.ohlc[column] - return DataFrame(s.values,s.index,[self.name]) - - @property - def dayReturns(self): - ''' close-close returns ''' - return (self.ohlc['adj_close']/self.ohlc['adj_close'].shift(1)-1) - #return DataFrame(s.values,s.index,[self.name]) - -class Portfolio(object): - def __init__(self,histPrice,name=''): - """ - Constructor - - Parameters - ---------- - histPrice : historic price - - """ - self.histPrice = histPrice - self.params = DataFrame(index=self.symbols) - self.params['capital'] = 100*np.ones(self.histPrice.shape[1],dtype=np.float) - self.params['last'] = self.histPrice.tail(1).T.ix[:,0] - self.params['shares'] = self.params['capital']/self.params['last'] - self.name= name - - - def setHistPrice(self,histPrice): - self.histPrice = histPrice - - def setShares(self,shares): - """ set number of shares, adjust capital - shares: list, np array or Series - """ - - if len(shares) != self.histPrice.shape[1]: - raise AttributeError('Wrong size of shares vector.') - self.params['shares'] = shares - self.params['capital'] = self.params['shares']*self.params['last'] - - def setCapital(self,capital): - """ Set target captial, adjust number of shares """ - if len(capital) != self.histPrice.shape[1]: - raise AttributeError('Wrong size of shares vector.') - self.params['capital'] = capital - self.params['shares'] = self.params['capital']/self.params['last'] - - - def calculateStatistics(self,other=None): - ''' calculate spread statistics, save internally ''' - res = {} - res['micro'] = rank(self.returns[-1],self.returns) - res['macro'] = rank(self.value[-1], self.value) - - res['last'] = self.value[-1] - - if other is not None: - res['corr'] = self.returns.corr(returns(other)) - - return Series(res,name=self.name) - - @property - def symbols(self): - return self.histPrice.columns.tolist() - - @property - def returns(self): - return (returns(self.histPrice)*self.params['capital']).sum(axis=1) - - @property - def value(self): - return (self.histPrice*self.params['shares']).sum(axis=1) - - def __repr__(self): - return ("Portfolio %s \n" % self.name ) + str(self.params) - #return ('Spread %s :' % self.name ) + str.join(',', - # ['%s*%.2f' % t for t in zip(self.symbols,self.capital)]) - - - -class Spread(object): - ''' - Spread class, used to build a spread out of two symbols. - ''' - - def __init__(self,stock,hedge,beta=None): - ''' init with symbols or price series ''' - - if isinstance(stock,str) and isinstance(hedge,str): - self.symbols = [stock,hedge] - self._getYahooData() - elif isinstance(stock,pd.Series) and isinstance(hedge,pd.Series): - self.symbols = [stock.name,hedge.name] - self.price = pd.DataFrame(dict(zip(self.symbols,[stock,hedge]))).dropna() - else: - raise ValueError('Both stock and hedge should be of the same type, symbol string or Series') - - # calculate returns - self.returns = self.price.pct_change() - - if beta is not None: - self.beta = beta - else: - self.estimateBeta() - - - # set data - self.data = pd.DataFrame(index = self.symbols) - self.data['beta'] = pd.Series({self.symbols[0]:1., self.symbols[1]:-self.beta}) - - def calculateShares(self,bet): - ''' set number of shares based on last quote ''' - if 'price' not in self.data.columns: - print 'Getting quote...' - self.getQuote() - self.data['shares'] = bet*self.data['beta']/self.data['price'] - - - def estimateBeta(self,plotOn=False): - """ linear estimation of beta """ - x = self.returns[self.symbols[1]] # hedge - y = self.returns[self.symbols[0]] # stock - - #avoid extremes - low = np.percentile(x,20) - high = np.percentile(x,80) - iValid = (x>low) & (x 0 : - - (a,b) = np.polyfit(x,y,1) - yf = np.polyval([a,b],x) - - err = yf-y - idxOutlier = abs(err) > 3*np.std(err) - nrOutliers =sum(idxOutlier) - beta = a - #print 'Iteration: %i beta: %.2f outliers: %i' % (iteration,beta, nrOutliers) - x = x[~idxOutlier] - y = y[~idxOutlier] - iteration += 1 - - - if plotOn: - yf = x*beta - plt.plot(x,yf,'-',color='red') - plt.xlabel(self.symbols[1]) - plt.ylabel(self.symbols[0]) - - self.beta = beta - return beta - - @property - def spread(self): - ''' return daily returns of the pair ''' - return (self.returns*self.data['beta']).sum(1) - - - def getQuote(self): - ''' get current quote from yahoo ''' - q = yahoo.getQuote(self.symbols) - self.data['price'] = q['last'] - - def _getYahooData(self, startDate=(2007,1,1)): - """ fetch historic data """ - data = {} - for symbol in self.symbols: - print 'Downloading %s' % symbol - data[symbol]=(yahoo.getHistoricData(symbol,sDate=startDate)['adj_close'] ) - - self.price = pd.DataFrame(data).dropna() - - - def __repr__(self): - return 'Spread 1*%s & %.2f*%s ' % (self.symbols[0],-self.beta,self.symbols[1]) - - @property - def name(self): - return str.join('_',self.symbols) - - - -if __name__=='__main__': - - - s = Spread(['SPY','IWM']) - - \ No newline at end of file diff --git a/lib/csvDatabase.py b/lib/csvDatabase.py deleted file mode 100644 index f61ff64..0000000 --- a/lib/csvDatabase.py +++ /dev/null @@ -1,195 +0,0 @@ -# -*- coding: utf-8 -*- -""" -intraday data handlers in csv format. - -@author: jev -""" - -from __future__ import division - -import pandas as pd -import datetime as dt -import os -from extra import ProgressBar - -dateFormat = "%Y%m%d" # date format for converting filenames to dates -dateTimeFormat = "%Y%m%d %H:%M:%S" - -def fileName2date(fName): - '''convert filename to date''' - name = os.path.splitext(fName)[0] - return dt.datetime.strptime(name.split('_')[1],dateFormat).date() - -def parseDateTime(dateTimeStr): - return dt.datetime.strptime(dateTimeStr,dateTimeFormat) - -def loadCsv(fName): - ''' load DataFrame from csv file ''' - with open(fName,'r') as f: - lines = f.readlines() - - dates= [] - header = [h.strip() for h in lines[0].strip().split(',')[1:]] - data = [[] for i in range(len(header))] - - - for line in lines[1:]: - fields = line.rstrip().split(',') - dates.append(parseDateTime(fields[0])) - for i,field in enumerate(fields[1:]): - data[i].append(float(field)) - - return pd.DataFrame(data=dict(zip(header,data)),index=pd.Index(dates)) - - -class HistDataCsv(object): - '''class for working with historic database in .csv format''' - def __init__(self,symbol,dbDir,autoCreateDir=False): - self.symbol = symbol - self.dbDir = os.path.normpath(os.path.join(dbDir,symbol)) - - if not os.path.exists(self.dbDir) and autoCreateDir: - print 'Creating data directory ', self.dbDir - os.mkdir(self.dbDir) - - self.dates = [] - - for fName in os.listdir(self.dbDir): - self.dates.append(fileName2date(fName)) - - - def saveData(self,date, df,lowerCaseColumns=True): - ''' add data to database''' - - if lowerCaseColumns: # this should provide consistency to column names. All lowercase - df.columns = [ c.lower() for c in df.columns] - - s = self.symbol+'_'+date.strftime(dateFormat)+'.csv' # file name - dest = os.path.join(self.dbDir,s) # full path destination - print 'Saving data to: ', dest - df.to_csv(dest) - - def loadDate(self,date): - ''' load data ''' - s = self.symbol+'_'+date.strftime(dateFormat)+'.csv' # file name - - df = pd.DataFrame.from_csv(os.path.join(self.dbDir,s)) - cols = [col.strip() for col in df.columns.tolist()] - df.columns = cols - #df = loadCsv(os.path.join(self.dbDir,s)) - - return df - - def loadDates(self,dates): - ''' load multiple dates, concantenating to one DataFrame ''' - tmp =[] - print 'Loading multiple dates for ' , self.symbol - p = ProgressBar(len(dates)) - - for i,date in enumerate(dates): - tmp.append(self.loadDate(date)) - p.animate(i+1) - - print '' - return pd.concat(tmp) - - - def createOHLC(self): - ''' create ohlc from intraday data''' - ohlc = pd.DataFrame(index=self.dates, columns=['open','high','low','close']) - - for date in self.dates: - - print 'Processing', date - try: - df = self.loadDate(date) - - ohlc.set_value(date,'open',df['open'][0]) - ohlc.set_value(date,'high',df['wap'].max()) - ohlc.set_value(date,'low', df['wap'].min()) - ohlc.set_value(date,'close',df['close'][-1]) - - except Exception as e: - print 'Could not convert:', e - - return ohlc - - def __repr__(self): - return '{symbol} dataset with {nrDates} days of data'.format(symbol=self.symbol, nrDates=len(self.dates)) - -class HistDatabase(object): - ''' class working with multiple symbols at once ''' - def __init__(self, dataDir): - - # get symbols from directory names - symbols = [] - for l in os.listdir(dataDir): - if os.path.isdir(os.path.join(dataDir,l)): - symbols.append(l) - - #build dataset - self.csv = {} # dict of HistDataCsv halndlers - - for symbol in symbols: - self.csv[symbol] = HistDataCsv(symbol,dataDir) - - - def loadDates(self,dates=None): - ''' - get data for all symbols as wide panel - provide a dates list. If no dates list is provided, common dates are used. - ''' - if dates is None: dates=self.commonDates - - tmp = {} - - - for k,v in self.csv.iteritems(): - tmp[k] = v.loadDates(dates) - - return pd.WidePanel(tmp) - - def toHDF(self,dataFile,dates=None): - ''' write wide panel data to a hdfstore file ''' - - if dates is None: dates=self.commonDates - store = pd.HDFStore(dataFile) - wp = self.loadDates(dates) - - store['data'] = wp - store.close() - - - - - - @property - def commonDates(self): - ''' return dates common for all symbols ''' - t = [v.dates for v in self.csv.itervalues()] # get all dates in a list - - d = list(set(t[0]).intersection(*t[1:])) - return sorted(d) - - - def __repr__(self): - s = '-----Hist CSV Database-----\n' - for k,v in self.csv.iteritems(): - s+= (str(v)+'\n') - return s - - -#-------------------- - -if __name__=='__main__': - - dbDir =os.path.normpath('D:/data/30sec') - vxx = HistDataCsv('VXX',dbDir) - spy = HistDataCsv('SPY',dbDir) -# - date = dt.date(2012,8,31) - print date -# - pair = pd.DataFrame({'SPY':spy.loadDate(date)['close'],'VXX':vxx.loadDate(date)['close']}) - - print pair.tail() \ No newline at end of file diff --git a/lib/eventSystem.py b/lib/eventSystem.py deleted file mode 100644 index f05a93b..0000000 --- a/lib/eventSystem.py +++ /dev/null @@ -1,84 +0,0 @@ -''' -Created on 26 dec. 2011 -Copyright: Jev Kuznetsov -License: BSD - -sender-reciever pattern. - -''' - -import logger as logger -import types - -class Sender(object): - """ - Sender -> dispatches messages to interested callables - """ - def __init__(self): - self.listeners = {} - self.logger = logger.getLogger() - - - def register(self,listener,events=None): - """ - register a listener function - - Parameters - ----------- - listener : external listener function - events : tuple or list of relevant events (default=None) - """ - if events is not None and type(events) not in (types.TupleType,types.ListType): - events = (events,) - - self.listeners[listener] = events - - def dispatch(self,event=None, msg=None): - """notify listeners """ - for listener,events in self.listeners.items(): - if events is None or event is None or event in events: - try: - listener(self,event,msg) - except (Exception,): - self.unregister(listener) - errmsg = "Exception in message dispatch: Handler '{0}' unregistered for event '{1}' ".format(listener.func_name,event) - self.logger.exception(errmsg) - - def unregister(self,listener): - """ unregister listener function """ - del self.listeners[listener] - -#---------------test functions-------------- - -class ExampleListener(object): - def __init__(self,name=None): - self.name = name - - def method(self,sender,event,msg=None): - print "[{0}] got event {1} with message {2}".format(self.name,event,msg) - - -if __name__=="__main__": - print 'demonstrating event system' - - - alice = Sender() - bob = ExampleListener('bob') - charlie = ExampleListener('charlie') - dave = ExampleListener('dave') - - - # add subscribers to messages from alice - alice.register(bob.method,events='event1') # listen to 'event1' - alice.register(charlie.method,events ='event2') # listen to 'event2' - alice.register(dave.method) # listen to all events - - # dispatch some events - alice.dispatch(event='event1') - alice.dispatch(event='event2',msg=[1,2,3]) - alice.dispatch(msg='attention to all') - - print 'Done.' - - - \ No newline at end of file diff --git a/lib/extra.py b/lib/extra.py deleted file mode 100644 index cea2623..0000000 --- a/lib/extra.py +++ /dev/null @@ -1,69 +0,0 @@ -''' -Created on Apr 28, 2013 -Copyright: Jev Kuznetsov -License: BSD -''' -from __future__ import print_function -import sys -import urllib -import os -import xlrd # module for excel file reading -import pandas as pd - -class ProgressBar: - def __init__(self, iterations): - self.iterations = iterations - self.prog_bar = '[]' - self.fill_char = '*' - self.width = 50 - self.__update_amount(0) - - def animate(self, iteration): - print('\r', self, end='') - sys.stdout.flush() - self.update_iteration(iteration + 1) - - def update_iteration(self, elapsed_iter): - self.__update_amount((elapsed_iter / float(self.iterations)) * 100.0) - self.prog_bar += ' %d of %s complete' % (elapsed_iter, self.iterations) - - def __update_amount(self, new_amount): - percent_done = int(round((new_amount / 100.0) * 100.0)) - all_full = self.width - 2 - num_hashes = int(round((percent_done / 100.0) * all_full)) - self.prog_bar = '[' + self.fill_char * num_hashes + ' ' * (all_full - num_hashes) + ']' - pct_place = (len(self.prog_bar) // 2) - len(str(percent_done)) - pct_string = '%d%%' % percent_done - self.prog_bar = self.prog_bar[0:pct_place] + \ - (pct_string + self.prog_bar[pct_place + len(pct_string):]) - - def __str__(self): - return str(self.prog_bar) - -def getSpyHoldings(dataDir): - ''' get SPY holdings from the net, uses temp data storage to save xls file ''' - - dest = os.path.join(dataDir,"spy_holdings.xls") - - if os.path.exists(dest): - print('File found, skipping download') - else: - print('saving to', dest) - urllib.urlretrieve ("https://www.spdrs.com/site-content/xls/SPY_All_Holdings.xls?fund=SPY&docname=All+Holdings&onyx_code1=1286&onyx_code2=1700", - dest) # download xls file and save it to data directory - - # parse - wb = xlrd.open_workbook(dest) # open xls file, create a workbook - sh = wb.sheet_by_index(0) # select first sheet - - - data = {'name':[], 'symbol':[], 'weight':[],'sector':[]} - for rowNr in range(5,505): # cycle through the rows - v = sh.row_values(rowNr) # get all row values - data['name'].append(v[0]) - data['symbol'].append(v[1]) # symbol is in the second column, append it to the list - data['weight'].append(float(v[2])) - data['sector'].append(v[3]) - - return pd.DataFrame(data) - diff --git a/lib/functions.py b/lib/functions.py deleted file mode 100644 index 32dd5da..0000000 --- a/lib/functions.py +++ /dev/null @@ -1,434 +0,0 @@ -# -*- coding: utf-8 -*- -""" -twp support functions - -@author: Jev Kuznetsov -Licence: GPL v2 -""" - -from scipy import polyfit, polyval -import datetime as dt -#from datetime import datetime, date -from pandas import DataFrame, Index, Series -import csv -import matplotlib.pyplot as plt -import numpy as np -import pandas as pd - -def nans(shape, dtype=float): - ''' create a nan numpy array ''' - a = np.empty(shape, dtype) - a.fill(np.nan) - return a - - -def plotCorrelationMatrix(price, thresh = None): - ''' plot a correlation matrix as a heatmap image - inputs: - price: prices DataFrame - thresh: correlation threshold to use for checking, default None - - ''' - symbols = price.columns.tolist() - R = price.pct_change() - - - correlationMatrix = R.corr() - - if thresh is not None: - correlationMatrix = correlationMatrix > thresh - - plt.imshow(abs(correlationMatrix.values),interpolation='none') - plt.xticks(range(len(symbols)),symbols) - plt.yticks(range(len(symbols)),symbols) - plt.colorbar() - plt.title('Correlation matrix') - - return correlationMatrix - - -def pca(A): - """ performs principal components analysis - (PCA) on the n-by-p DataFrame A - Rows of A correspond to observations, columns to variables. - - Returns : - coeff : principal components, column-wise - transform: A in principal component space - latent : eigenvalues - - """ - # computing eigenvalues and eigenvectors of covariance matrix - M = (A - A.mean()).T # subtract the mean (along columns) - [latent,coeff] = np.linalg.eig(np.cov(M)) # attention:not always sorted - - idx = np.argsort(latent) # sort eigenvalues - idx = idx[::-1] # in ascending order - - coeff = coeff[:,idx] - latent = latent[idx] - - score = np.dot(coeff.T,A.T) # projection of the data in the new space - - transform = DataFrame(index = A.index, data = score.T) - - return coeff,transform,latent - - - -def pos2pnl(price,position , ibTransactionCost=False ): - """ - calculate pnl based on price and position - Inputs: - --------- - price: series or dataframe of price - position: number of shares at each time. Column names must be same as in price - ibTransactionCost: use bundled Interactive Brokers transaction cost of 0.005$/share - - Returns a portfolio DataFrame - """ - - delta=position.diff() - port = DataFrame(index=price.index) - - if isinstance(price,Series): # no need to sum along 1 for series - port['cash'] = (-delta*price).cumsum() - port['stock'] = (position*price) - - else: # dealing with DataFrame here - port['cash'] = (-delta*price).sum(axis=1).cumsum() - port['stock'] = (position*price).sum(axis=1) - - - - if ibTransactionCost: - tc = -0.005*position.diff().abs() # basic transaction cost - tc[(tc>-1) & (tc<0)] = -1 # everything under 1$ will be ceil'd to 1$ - if isinstance(price,DataFrame): - tc = tc.sum(axis=1) - port['tc'] = tc.cumsum() - else: - port['tc'] = 0. - - port['total'] = port['stock']+port['cash']+port['tc'] - - - - return port - -def tradeBracket(price,entryBar,maxTradeLength,bracket): - ''' - trade a symmetrical bracket on price series, return price delta and exit bar # - Input - ------ - price : series of price values - entryBar: entry bar number - maxTradeLength : max trade duration in bars - bracket : allowed price deviation - - - ''' - - lastBar = min(entryBar+maxTradeLength,len(price)-1) - p = price[entryBar:lastBar]-price[entryBar] - - idxOutOfBound = np.nonzero(abs(p)>bracket) # find indices where price comes out of bracket - if idxOutOfBound[0].any(): # found match - priceDelta = p[idxOutOfBound[0][0]] - exitBar = idxOutOfBound[0][0]+entryBar - else: # all in bracket, exiting based on time - priceDelta = p[-1] - exitBar = lastBar - - return priceDelta, exitBar - - -def estimateBeta(priceY,priceX,algo = 'standard'): - ''' - estimate stock Y vs stock X beta using iterative linear - regression. Outliers outside 3 sigma boundary are filtered out - - Parameters - -------- - priceX : price series of x (usually market) - priceY : price series of y (estimate beta of this price) - - Returns - -------- - beta : stockY beta relative to stock X - ''' - - X = DataFrame({'x':priceX,'y':priceY}) - - if algo=='returns': - ret = (X/X.shift(1)-1).dropna().values - - #print len(ret) - - x = ret[:,0] - y = ret[:,1] - - # filter high values - low = np.percentile(x,20) - high = np.percentile(x,80) - iValid = (x>low) & (x 0 : - (a,b) = polyfit(x,y,1) - yf = polyval([a,b],x) - #plot(x,y,'x',x,yf,'r-') - err = yf-y - idxOutlier = abs(err) > 3*np.std(err) - nrOutliers =sum(idxOutlier) - beta = a - #print 'Iteration: %i beta: %.2f outliers: %i' % (iteration,beta, nrOutliers) - x = x[~idxOutlier] - y = y[~idxOutlier] - iteration += 1 - - elif algo=='log': - x = np.log(X['x']) - y = np.log(X['y']) - (a,b) = polyfit(x,y,1) - beta = a - - elif algo=='standard': - ret =np.log(X).diff().dropna() - beta = ret['x'].cov(ret['y'])/ret['x'].var() - - - - else: - raise TypeError("unknown algorithm type, use 'standard', 'log' or 'returns'") - - return beta - -def estimateVolatility(ohlc, N=10, algo='YangZhang'): - """ - Volatility estimation - Possible algorithms: ['YangZhang', 'CC'] - - """ - - - cc = np.log(ohlc.close/ohlc.close.shift(1)) - - if algo == 'YangZhang': # Yang-zhang volatility - ho = np.log(ohlc.high/ohlc.open) - lo = np.log(ohlc.low/ohlc.open) - co = np.log(ohlc.close/ohlc.open) - - oc = np.log(ohlc.open/ohlc.close.shift(1)) - oc_sq = oc**2 - - - cc_sq = cc**2 - - rs = ho*(ho-co)+lo*(lo-co) - - close_vol = pd.rolling_sum(cc_sq, window=N) * (1.0 / (N - 1.0)) - open_vol = pd.rolling_sum(oc_sq, window=N) * (1.0 / (N - 1.0)) - window_rs = pd.rolling_sum(rs, window=N) * (1.0 / (N - 1.0)) - - result = (open_vol + 0.164333 * close_vol + 0.835667 * window_rs).apply(np.sqrt) * np.sqrt(252) - - result[:N-1] = np.nan - - elif algo == 'CC': # standard close-close estimator - result = np.sqrt(252)*np.sqrt(((pd.rolling_sum(cc**2,N))/N)) - - else: - raise ValueError('Unknown algo type.') - - return result*100 - - -def rank(current,past): - ''' calculate a relative rank 0..1 for a value against series ''' - return (current>past).sum()/float(past.count()) - - -def returns(df): - return (df/df.shift(1)-1) - -def logReturns(df): - t = np.log(df) - return t-t.shift(1) - -def dateTimeToDate(idx): - ''' convert datetime index to date ''' - dates = [] - for dtm in idx: - dates.append(dtm.date()) - return dates - - - -def readBiggerScreener(fName): - ''' import data from Bigger Capital screener ''' - with open(fName,'rb') as f: - reader = csv.reader(f) - rows = [row for row in reader] - - header = rows[0] - data = [[] for i in range(len(header))] - - for row in rows[1:]: - for i,elm in enumerate(row): - try: - data[i].append(float(elm)) - except Exception: - data[i].append(str(elm)) - - - - return DataFrame(dict(zip(header,data)),index=Index(range(len(data[0]))))[header] - -def sharpe(pnl): - return np.sqrt(250)*pnl.mean()/pnl.std() - - -def drawdown(s): - """ - calculate max drawdown and duration - - Input: - s, price or cumulative pnl curve $ - Returns: - drawdown : vector of drawdwon values - duration : vector of drawdown duration - - - """ - # convert to array if got pandas series, 10x speedup - if isinstance(s,pd.Series): - idx = s.index - s = s.values - returnSeries = True - else: - returnSeries = False - - if s.min() < 0: # offset if signal minimum is less than zero - s = s-s.min() - - highwatermark = np.zeros(len(s)) - drawdown = np.zeros(len(s)) - drawdowndur = np.zeros(len(s)) - - - for t in range(1,len(s)): - highwatermark[t] = max(highwatermark[t-1], s[t]) - drawdown[t] = (highwatermark[t]-s[t]) - drawdowndur[t]= (0 if drawdown[t] == 0 else drawdowndur[t-1]+1) - - if returnSeries: - return pd.Series(index=idx,data=drawdown), pd.Series(index=idx,data=drawdowndur) - else: - return drawdown , drawdowndur - - -def profitRatio(pnl): - ''' - calculate profit ratio as sum(pnl)/drawdown - Input: pnl - daily pnl, Series or DataFrame - ''' - def processVector(pnl): # process a single column - s = pnl.fillna(0) - dd = drawdown(s)[0] - p = s.sum()/dd.max() - return p - - if isinstance(pnl,Series): - return processVector(pnl) - - elif isinstance(pnl,DataFrame): - - p = Series(index = pnl.columns) - - for col in pnl.columns: - p[col] = processVector(pnl[col]) - - return p - else: - raise TypeError("Input must be DataFrame or Series, not "+str(type(pnl))) - - - - -def candlestick(df,width=0.5, colorup='b', colordown='r'): - ''' plot a candlestick chart of a dataframe ''' - - O = df['open'].values - H = df['high'].values - L = df['low'].values - C = df['close'].values - - fig = plt.gcf() - ax = plt.axes() - #ax.hold(True) - - X = df.index - - - #plot high and low - ax.bar(X,height=H-L,bottom=L,width=0.1,color='k') - - idxUp = C>O - ax.bar(X[idxUp],height=(C-O)[idxUp],bottom=O[idxUp],width=width,color=colorup) - - idxDown = C<=O - ax.bar(X[idxDown],height=(O-C)[idxDown],bottom=C[idxDown],width=width,color=colordown) - - try: - fig.autofmt_xdate() - except Exception: # pragma: no cover - pass - - - ax.grid(True) - - #ax.bar(x,height=H-L,bottom=L,width=0.01,color='k') - -def datetime2matlab(t): - ''' convert datetime timestamp to matlab numeric timestamp ''' - mdn = t + dt.timedelta(days = 366) - frac = (t-dt.datetime(t.year,t.month,t.day,0,0,0)).seconds / (24.0 * 60.0 * 60.0) - return mdn.toordinal() + frac - - -def getDataSources(fName = None): - ''' return data sources directories for this machine. - directories are defined in datasources.ini or provided filepath''' - import socket - from ConfigParser import ConfigParser - - pcName = socket.gethostname() - - p = ConfigParser() - p.optionxform = str - - - if fName is None: - fName = 'datasources.ini' - - p.read(fName) - - if pcName not in p.sections(): - raise NameError('Host name section %s not found in file %s' %(pcName,fName)) - - dataSources = {} - for option in p.options(pcName): - dataSources[option] = p.get(pcName,option) - - return dataSources - -if __name__ == '__main__': - df = DataFrame({'open':[1,2,3],'high':[5,6,7],'low':[-2,-1,0],'close':[2,1,4]}) - plt.clf() - candlestick(df) \ No newline at end of file diff --git a/lib/indicators.py b/lib/indicators.py deleted file mode 100644 index 88ffba0..0000000 --- a/lib/indicators.py +++ /dev/null @@ -1,25 +0,0 @@ -''' -Created on Jul 3, 2014 - -author: Jev Kuznetsov - -License: BSD - -Description: Module containing some (technical) indicators -''' - -import pandas as pd - -def rsi(price, n=14): - ''' rsi indicator ''' - gain = price.diff().fillna(0) # fifference between day n and n-1, replace nan (first value) with 0 - - def rsiCalc(p): - # subfunction for calculating rsi for one lookback period - avgGain = p[p>0].sum()/n - avgLoss = -p[p<0].sum()/n - rs = avgGain/avgLoss - return 100 - 100/(1+rs) - - # run for all periods with rolling_apply - return pd.rolling_apply(gain,n,rsiCalc) diff --git a/lib/interactiveBrokers/__init__.py b/lib/interactiveBrokers/__init__.py deleted file mode 100644 index e9a9bc0..0000000 --- a/lib/interactiveBrokers/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from extra import createContract -from tickLogger import logTicks -from histData import Downloader -from extra import * \ No newline at end of file diff --git a/lib/interactiveBrokers/extra.py b/lib/interactiveBrokers/extra.py deleted file mode 100644 index eca22d2..0000000 --- a/lib/interactiveBrokers/extra.py +++ /dev/null @@ -1,55 +0,0 @@ -''' -Created on May 8, 2013 -Copyright: Jev Kuznetsov -License: BSD - -convenience functions for interactiveBrokers module - -''' -from ib.ext.Contract import Contract -from ib.ext.Order import Order - -priceTicks = {1:'bid',2:'ask',4:'last',6:'high',7:'low',9:'close', 14:'open'} -timeFormat = "%Y%m%d %H:%M:%S" -dateFormat = "%Y%m%d" - - -def createContract(symbol,secType='STK',exchange='SMART',currency='USD'): - ''' create contract object ''' - c = Contract() - c.m_symbol = symbol - c.m_secType= secType - c.m_exchange = exchange - c.m_currency = currency - - return c - -def createOrder(orderId,shares,orderType='MKT', limit = None, transmit=0): - ''' - create order object - - Parameters - ----------- - orderId : The order Id. You must specify a unique value. - When the order status returns, it will be identified by this tag. - This tag is also used when canceling the order. - - shares: number of shares to buy or sell. Negative for sell order. - limit : price limit, None for MKT order - transmit: transmit immideatelly from tws - ''' - - action = {-1:'SELL',1:'BUY'} - - o = Order() - - o.m_orderId = orderId - o.m_action = action[cmp(shares,0)] - o.m_totalQuantity = abs(shares) - o.m_transmit = transmit - o.m_orderType = orderType - - if limit is not None: - o.m_lmtPrice = limit - - return o \ No newline at end of file diff --git a/lib/interactiveBrokers/histData.py b/lib/interactiveBrokers/histData.py deleted file mode 100644 index ab5c9d7..0000000 --- a/lib/interactiveBrokers/histData.py +++ /dev/null @@ -1,200 +0,0 @@ -''' -Created on May 8, 2013 -Copyright: Jev Kuznetsov -License: BSD - -Module for downloading historic data from IB - -''' - -import ib -import pandas as pd -from ib.ext.Contract import Contract -from ib.opt import ibConnection, message - -import logger as logger - -from pandas import DataFrame, Index - -import os -import datetime as dt -import time -from time import sleep -from extra import timeFormat, dateFormat - -class Downloader(object): - def __init__(self,debug=False): - self._log = logger.getLogger('DLD') - self._log.debug('Initializing data dwonloader. Pandas version={0}, ibpy version:{1}'.format(pd.__version__,ib.version)) - - self.tws = ibConnection() - self._dataHandler = _HistDataHandler(self.tws) - - if debug: - self.tws.registerAll(self._debugHandler) - self.tws.unregister(self._debugHandler,message.HistoricalData) - - self._log.debug('Connecting to tws') - self.tws.connect() - - self._timeKeeper = TimeKeeper() # keep track of past requests - self._reqId = 1 # current request id - - - def _debugHandler(self,msg): - print '[debug]', msg - - - def requestData(self,contract,endDateTime,durationStr='1 D',barSizeSetting='30 secs',whatToShow='TRADES',useRTH=1,formatDate=1): - - if isinstance(endDateTime,dt.datetime): # convert to string - endDateTime = endDateTime.strftime(timeFormat) - - - self._log.debug('Requesting data for %s end time %s.' % (contract.m_symbol,endDateTime)) - - - while self._timeKeeper.nrRequests(timeSpan=600) > 59: - print 'Too many requests done. Waiting... ' - time.sleep(10) - - self._timeKeeper.addRequest() - self._dataHandler.reset() - self.tws.reqHistoricalData(self._reqId,contract,endDateTime,durationStr,barSizeSetting,whatToShow,useRTH,formatDate) - self._reqId+=1 - - #wait for data - startTime = time.time() - timeout = 3 - while not self._dataHandler.dataReady and (time.time()-startTime < timeout): - sleep(2) - - if not self._dataHandler.dataReady: - self._log.error('Data timeout') - - print self._dataHandler.data - - return self._dataHandler.data - -# def getIntradayData(self,contract, dateTuple ): -# ''' get full day data on 1-s interval -# date: a tuple of (yyyy,mm,dd) -# ''' -# -# openTime = dt.datetime(*dateTuple)+dt.timedelta(hours=16) -# closeTime = dt.datetime(*dateTuple)+dt.timedelta(hours=22) -# -# timeRange = pd.date_range(openTime,closeTime,freq='30min') -# -# datasets = [] -# -# for t in timeRange: -# datasets.append(self.requestData(contract,t.strftime(timeFormat))) -# -# return pd.concat(datasets) - - - def disconnect(self): - self.tws.disconnect() - -class _HistDataHandler(object): - ''' handles incoming messages ''' - def __init__(self,tws): - self._log = logger.getLogger('DH') - tws.register(self.msgHandler,message.HistoricalData) - self.reset() - - def reset(self): - self._log.debug('Resetting data') - self.dataReady = False - self._timestamp = [] - self._data = {'open':[],'high':[],'low':[],'close':[],'volume':[],'count':[],'WAP':[]} - - def msgHandler(self,msg): - #print '[msg]', msg - - if msg.date[:8] == 'finished': - self._log.debug('Data recieved') - self.dataReady = True - return - - if len(msg.date) > 8: - self._timestamp.append(dt.datetime.strptime(msg.date,timeFormat)) - else: - self._timestamp.append(dt.datetime.strptime(msg.date,dateFormat)) - - - for k in self._data.keys(): - self._data[k].append(getattr(msg, k)) - - @property - def data(self): - ''' return downloaded data as a DataFrame ''' - df = DataFrame(data=self._data,index=Index(self._timestamp)) - return df - - - -class TimeKeeper(object): - ''' - class for keeping track of previous requests, to satify the IB requirements - (max 60 requests / 10 min) - - each time a requiest is made, a timestamp is added to a txt file in the user dir. - - ''' - - def __init__(self): - self._log = logger.getLogger('TK') - dataDir = os.path.expanduser('~')+'/twpData' - - if not os.path.exists(dataDir): - os.mkdir(dataDir) - - self._timeFormat = "%Y%m%d %H:%M:%S" - self.dataFile = os.path.normpath(os.path.join(dataDir,'requests.txt')) - - # Create file if it's missing - if not os.path.exists(self.dataFile): - open(self.dataFile,'w').close() - - self._log.debug('Data file: {0}'.format(self.dataFile)) - - def addRequest(self): - ''' adds a timestamp of current request''' - with open(self.dataFile,'a') as f: - f.write(dt.datetime.now().strftime(self._timeFormat)+'\n') - - - def nrRequests(self,timeSpan=600): - ''' return number of requests in past timespan (s) ''' - delta = dt.timedelta(seconds=timeSpan) - now = dt.datetime.now() - requests = 0 - - with open(self.dataFile,'r') as f: - lines = f.readlines() - - for line in lines: - if now-dt.datetime.strptime(line.strip(),self._timeFormat) < delta: - requests+=1 - - if requests==0: # erase all contents if no requests are relevant - open(self.dataFile,'w').close() - - self._log.debug('past requests: {0}'.format(requests)) - return requests - - -if __name__ == '__main__': - - from extra import createContract - - dl = Downloader(debug=True) # historic data downloader class - - contract = createContract('SPY') # create contract using defaults (STK,SMART,USD) - data = dl.requestData(contract,"20141208 16:00:00 EST") # request 30-second data bars up till now - - data.to_csv('SPY.csv') # write data to csv - - print 'Done' \ No newline at end of file diff --git a/lib/interactiveBrokers/logger.py b/lib/interactiveBrokers/logger.py deleted file mode 100644 index 3a36cb4..0000000 --- a/lib/interactiveBrokers/logger.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -## -# Defines logging formats and logger instance -## - -import logging -import os - -## -# Default log message formatting string. -format = '%(asctime)s %(levelname)s [%(name)s] %(message)s' - -## -# Default log date formatting string. -datefmt = '%d-%b-%y %H:%M:%S' - -## -# Default log level. Set TWP_LOGLEVEL environment variable to -# change this default. -level = int(os.environ.get('TWP_LOGLEVEL', logging.DEBUG)) - - -def getLogger(name='twp', level=level, format=format, - datefmt=datefmt): - """ Configures and returns a logging instance. - - @param name ignored - @param level logging level - @param format format string for log messages - @param datefmt format string for log dates - @return logging instance (the module) - """ - #print 'Loglevel:' , level - logging.basicConfig(level=level, format=format, datefmt=datefmt) - return logging.getLogger(name) diff --git a/lib/interactiveBrokers/tickLogger.py b/lib/interactiveBrokers/tickLogger.py deleted file mode 100644 index 9c3a8c6..0000000 --- a/lib/interactiveBrokers/tickLogger.py +++ /dev/null @@ -1,166 +0,0 @@ -''' -Created on May 5, 2013 -Copyright: Jev Kuznetsov -License: BSD - -Program to log tick events to a file - -example usage: - > python ib_logQuotes.py SPY,VXX,XLE - - start with -v option to show all incoming events - - -''' - -import argparse # command line argument parser -import datetime as dt # date and time functions -import time # time module for timestamping -import os # used to create directories -import sys # used to print a dot to a terminal without new line - -#--------ibpy imports ---------------------- -from extra import createContract -from ib.opt import ibConnection, message -from ib.ext.Contract import Contract - - -# tick type definitions, see IB api manual -priceTicks = {1:'bid',2:'ask',4:'last',6:'high',7:'low',9:'close', 14:'open'} -sizeTicks = {0:'bid',3:'ask',5:'last',8:'volume'} - -class TickLogger(object): - ''' class for handling incoming ticks and saving them to file - will create a subdirectory 'tickLogs' if needed and start logging - to a file with current timestamp in its name. - All timestamps in the file are in seconds relative to start of logging - - ''' - def __init__(self,tws, subscriptions): - ''' init class, register handlers ''' - - tws.register(self._priceHandler,message.TickPrice) - tws.register(self._sizeHandler,message.TickSize) - - self.subscriptions = subscriptions - - # save starting time of logging. All times will be in seconds relative - # to this moment - self._startTime = time.time() - - # create data directory if it does not exist - if not os.path.exists('tickLogs'): os.mkdir('tickLogs') - - # open data file for writing - fileName = 'tickLogs\\tickLog_%s.csv' % dt.datetime.now().strftime('%H_%M_%S') - print 'Logging ticks to ' , fileName - self.dataFile = open(fileName,'w') - - - def _priceHandler(self,msg): - ''' price tick handler ''' - data = [self.subscriptions[msg.tickerId].m_symbol,'price',priceTicks[msg.field],msg.price] # data, second field is price tick type - self._writeData(data) - - def _sizeHandler(self,msg): - ''' size tick handler ''' - data = [self.subscriptions[msg.tickerId].m_symbol,'size',sizeTicks[msg.field],msg.size] - self._writeData(data) - - def _writeData(self,data): - ''' write data to log file while adding a timestamp ''' - timestamp = '%.3f' % (time.time()-self._startTime) # 1 ms resolution - dataLine = ','.join(str(bit) for bit in [timestamp]+data) + '\n' - self.dataFile.write(dataLine) - - def flush(self): - ''' commits data to file''' - self.dataFile.flush() - - def close(self): - '''close file in a neat manner ''' - print 'Closing data file' - self.dataFile.close() - - -def printMessage(msg): - ''' function to print all incoming messages from TWS ''' - print '[msg]:', msg - - - - -def logTicks(contracts,verbose=False): - ''' - log ticks from IB to a csv file - - Parameters - ---------- - contracts : ib.ext.Contract objects - verbose : print out all tick events - ''' - # check for correct input - assert isinstance(contracts,(list,Contract)) ,'Wrong input, should be a Contract or list of contracts' - - #---create subscriptions dictionary. Keys are subscription ids - subscriptions = {} - try: - for idx, c in enumerate(contracts): - subscriptions[idx+1] = c - except TypeError: # not iterable, one contract provided - subscriptions[1] = contracts - - tws = ibConnection() - logger = TickLogger(tws,subscriptions) - - if verbose: tws.registerAll(printMessage) - - tws.connect() - - #-------subscribe to data - for subId, c in subscriptions.iteritems(): - assert isinstance(c,Contract) , 'Need a Contract object to subscribe' - tws.reqMktData(subId,c,"",False) - - #------start a loop that must be interrupted with Ctrl-C - print 'Press Ctr-C to stop loop' - - try: - while True: - time.sleep(2) # wait a little - logger.flush() # commit data to file - sys.stdout.write('.') # print a dot to the screen - - - except KeyboardInterrupt: - print 'Interrupted with Ctrl-c' - - logger.close() - tws.disconnect() - print 'All done' - -#--------------main script------------------ - -if __name__ == '__main__': - - #-----------parse command line arguments - parser = argparse.ArgumentParser(description='Log ticks for a set of stocks') - - - parser.add_argument("symbols",help = 'symbols separated by coma: SPY,VXX') - parser.add_argument("-v", "--verbose", help="show all incoming messages", - action="store_true") - - args = parser.parse_args() - - symbols = args.symbols.strip().split(',') - print 'Logging ticks for:',symbols - - contracts = [createContract(symbol) for symbol in symbols] - - logTicks(contracts, verbose=args.verbose) - - - - - \ No newline at end of file diff --git a/lib/interactivebrokers.py b/lib/interactivebrokers.py deleted file mode 100644 index 95c876c..0000000 --- a/lib/interactivebrokers.py +++ /dev/null @@ -1,592 +0,0 @@ -""" -Copyright: Jev Kuznetsov -Licence: BSD - -Interface to interactive brokers together with gui widgets - -""" -import sys -# import os -from time import sleep -from PyQt4.QtCore import (SIGNAL, SLOT) -from PyQt4.QtGui import (QApplication, QFileDialog, QDialog, QVBoxLayout, QHBoxLayout, QDialogButtonBox, - QTableView, QPushButton, QWidget, QLabel, QLineEdit, QGridLayout, QHeaderView) - -import ib -from ib.ext.Contract import Contract -from ib.opt import ibConnection, message -from ib.ext.Order import Order - -import logger as logger -from qtpandas import DataFrameModel, TableView -from eventSystem import Sender -import numpy as np - -import pandas -from pandas import DataFrame, Index -from datetime import datetime -import os -import datetime as dt -import time - -priceTicks = {1: 'bid', 2: 'ask', 4: 'last', 6: 'high', 7: 'low', 9: 'close', 14: 'open'} -timeFormat = "%Y%m%d %H:%M:%S" -dateFormat = "%Y%m%d" - - -def createContract(symbol, secType='STK', exchange='SMART', currency='USD'): - """ contract factory function """ - contract = Contract() - contract.m_symbol = symbol - contract.m_secType = secType - contract.m_exchange = exchange - contract.m_currency = currency - - return contract - - -def _str2datetime(s): - """ convert string to datetime """ - return datetime.strptime(s, '%Y%m%d') - - -def readActivityFlex(fName): - """ - parse trade log in a csv file produced by IB 'Activity Flex Query' - the file should contain these columns: - ['Symbol','TradeDate','Quantity','TradePrice','IBCommission'] - - Returns: - A DataFrame with parsed trade data - - """ - import csv - - rows = [] - - with open(fName, 'rb') as f: - reader = csv.reader(f) - for row in reader: - rows.append(row) - - header = ['TradeDate', 'Symbol', 'Quantity', 'TradePrice', 'IBCommission'] - - types = dict(zip(header, [_str2datetime, str, int, float, float])) - idx = dict(zip(header, [rows[0].index(h) for h in header])) - data = dict(zip(header, [[] for h in header])) - - for row in rows[1:]: - print row - for col in header: - val = types[col](row[idx[col]]) - data[col].append(val) - - return DataFrame(data)[header].sort(column='TradeDate') - - -class Subscriptions(DataFrameModel, Sender): - """ a data table containing price & subscription data """ - - def __init__(self, tws=None): - - super(Subscriptions, self).__init__() - self.df = DataFrame() # this property holds the data in a table format - - self._nextId = 1 - self._id2symbol = {} # id-> symbol lookup dict - self._header = ['id', 'position', 'bid', 'ask', 'last'] # columns of the _data table - - # register callbacks - if tws is not None: - tws.register(self.priceHandler, message.TickPrice) - tws.register(self.accountHandler, message.UpdatePortfolio) - - - def add(self, symbol, subId=None): - """ - Add a subscription to data table - return : subscription id - - """ - if subId is None: - subId = self._nextId - - data = dict(zip(self._header, [subId, 0, np.nan, np.nan, np.nan])) - row = DataFrame(data, index=Index([symbol])) - - self.df = self.df.append(row[self._header]) # append data and set correct column order - - self._nextId = subId + 1 - self._rebuildIndex() - - self.emit(SIGNAL("layoutChanged()")) - - return subId - - def priceHandler(self, msg): - """ handler function for price updates. register this with ibConnection class """ - - if priceTicks[msg.field] not in self._header: # do nothing for ticks that are not in _data table - return - - self.df[priceTicks[msg.field]][self._id2symbol[msg.tickerId]] = msg.price - - #notify viewer - col = self._header.index(priceTicks[msg.field]) - row = self.df.index.tolist().index(self._id2symbol[msg.tickerId]) - - idx = self.createIndex(row, col) - self.emit(SIGNAL("dataChanged(QModelIndex,QModelIndex)"), idx, idx) - - def accountHandler(self, msg): - if msg.contract.m_symbol in self.df.index.tolist(): - self.df['position'][msg.contract.m_symbol] = msg.position - - def _rebuildIndex(self): - """ udate lookup dictionary id-> symbol """ - symbols = self.df.index.tolist() - ids = self.df['id'].values.tolist() - self._id2symbol = dict(zip(ids, symbols)) - - - def __repr__(self): - return str(self.df) - - -class Broker(object): - """ - Broker class acts as a wrapper around ibConnection - from ibPy. It tracks current subscriptions and provides - data models to viewiers . - """ - - def __init__(self, name='broker'): - """ initialize broker class - - """ - self.name = name - self.log = logger.getLogger(self.name) - - self.log.debug('Initializing broker. Pandas version={0}'.format(pandas.__version__)) - self.contracts = {} # a dict to keep track of subscribed contracts - - self.tws = ibConnection() # tws interface - self.nextValidOrderId = None - - self.dataModel = Subscriptions(self.tws) # data container - - self.tws.registerAll(self.defaultHandler) - #self.tws.register(self.debugHandler,message.TickPrice) - self.tws.register(self.nextValidIdHandler, 'NextValidId') - self.log.debug('Connecting to tws') - self.tws.connect() - - self.tws.reqAccountUpdates(True, '') - - def subscribeStk(self, symbol, secType='STK', exchange='SMART', currency='USD'): - """ subscribe to stock data """ - self.log.debug('Subscribing to ' + symbol) - # if symbol in self.data.symbols: - # print 'Already subscribed to {0}'.format(symbol) - # return - - c = Contract() - c.m_symbol = symbol - c.m_secType = secType - c.m_exchange = exchange - c.m_currency = currency - - subId = self.dataModel.add(symbol) - self.tws.reqMktData(subId, c, '', False) - - self.contracts[symbol] = c - - return subId - - @property - def data(self): - return self.dataModel.df - - - def placeOrder(self, symbol, shares, limit=None, exchange='SMART', transmit=0): - """ place an order on already subscribed contract """ - - if symbol not in self.contracts.keys(): - self.log.error("Can't place order, not subscribed to %s" % symbol) - return - - action = {-1: 'SELL', 1: 'BUY'} - - o = Order() - o.m_orderId = self.getOrderId() - o.m_action = action[cmp(shares, 0)] - o.m_totalQuantity = abs(shares) - o.m_transmit = transmit - - if limit is not None: - o.m_orderType = 'LMT' - o.m_lmtPrice = limit - - self.log.debug('Placing %s order for %i %s (id=%i)' % (o.m_action, o.m_totalQuantity, symbol, o.m_orderId)) - - self.tws.placeOrder(o.m_orderId, self.contracts[symbol], o) - - - def getOrderId(self): - self.nextValidOrderId += 1 - return self.nextValidOrderId - 1 - - def unsubscribeStk(self, symbol): - self.log.debug('Function not implemented') - - def disconnect(self): - self.tws.disconnect() - - def __del__(self): - """destructor, clean up """ - print 'Broker is cleaning up after itself.' - self.tws.disconnect() - - def debugHandler(self, msg): - print msg - - def defaultHandler(self, msg): - """ default message handler """ - #print msg.typeName - if msg.typeName == 'Error': - self.log.error(msg) - - - def nextValidIdHandler(self, msg): - self.nextValidOrderId = msg.orderId - self.log.debug('Next valid order id:{0}'.format(self.nextValidOrderId)) - - def saveData(self, fname): - """ save current dataframe to csv """ - self.log.debug("Saving data to {0}".format(fname)) - self.dataModel.df.to_csv(fname) - - -# def __getattr__(self, name): -# """ x.__getattr__('name') <==> x.name -# an easy way to call ibConnection methods -# @return named attribute from instance tws -# """ -# return getattr(self.tws, name) - - - -class _HistDataHandler(object): - """ handles incoming messages """ - - def __init__(self, tws): - self._log = logger.getLogger('DH') - tws.register(self.msgHandler, message.HistoricalData) - self.reset() - - def reset(self): - self._log.debug('Resetting data') - self.dataReady = False - self._timestamp = [] - self._data = {'open': [], 'high': [], 'low': [], 'close': [], 'volume': [], 'count': [], 'WAP': []} - - def msgHandler(self, msg): - #print '[msg]', msg - - if msg.date[:8] == 'finished': - self._log.debug('Data recieved') - self.dataReady = True - return - - if len(msg.date) > 8: - self._timestamp.append(dt.datetime.strptime(msg.date, timeFormat)) - else: - self._timestamp.append(dt.datetime.strptime(msg.date, dateFormat)) - - for k in self._data.keys(): - self._data[k].append(getattr(msg, k)) - - @property - def data(self): - """ return downloaded data as a DataFrame """ - df = DataFrame(data=self._data, index=Index(self._timestamp)) - return df - - -class Downloader(object): - def __init__(self, debug=False): - self._log = logger.getLogger('DLD') - self._log.debug( - 'Initializing data dwonloader. Pandas version={0}, ibpy version:{1}'.format(pandas.__version__, ib.version)) - - self.tws = ibConnection() - self._dataHandler = _HistDataHandler(self.tws) - - if debug: - self.tws.registerAll(self._debugHandler) - self.tws.unregister(self._debugHandler, message.HistoricalData) - - self._log.debug('Connecting to tws') - self.tws.connect() - - self._timeKeeper = TimeKeeper() # keep track of past requests - self._reqId = 1 # current request id - - - def _debugHandler(self, msg): - print '[debug]', msg - - - def requestData(self, contract, endDateTime, durationStr='1 D', barSizeSetting='30 secs', whatToShow='TRADES', - useRTH=1, formatDate=1): - self._log.debug('Requesting data for %s end time %s.' % (contract.m_symbol, endDateTime)) - - while self._timeKeeper.nrRequests(timeSpan=600) > 59: - print 'Too many requests done. Waiting... ' - time.sleep(10) - - self._timeKeeper.addRequest() - self._dataHandler.reset() - self.tws.reqHistoricalData(self._reqId, contract, endDateTime, durationStr, barSizeSetting, whatToShow, useRTH, - formatDate) - self._reqId += 1 - - #wait for data - startTime = time.time() - timeout = 3 - while not self._dataHandler.dataReady and (time.time() - startTime < timeout): - sleep(2) - - if not self._dataHandler.dataReady: - self._log.error('Data timeout') - - print self._dataHandler.data - - return self._dataHandler.data - - def getIntradayData(self, contract, dateTuple): - """ get full day data on 1-s interval - date: a tuple of (yyyy,mm,dd) - """ - - openTime = dt.datetime(*dateTuple) + dt.timedelta(hours=16) - closeTime = dt.datetime(*dateTuple) + dt.timedelta(hours=22) - - timeRange = pandas.date_range(openTime, closeTime, freq='30min') - - datasets = [] - - for t in timeRange: - datasets.append(self.requestData(contract, t.strftime(timeFormat))) - - return pandas.concat(datasets) - - - def disconnect(self): - self.tws.disconnect() - - -class TimeKeeper(object): - def __init__(self): - self._log = logger.getLogger('TK') - dataDir = os.path.expanduser('~') + '/twpData' - - if not os.path.exists(dataDir): - os.mkdir(dataDir) - - self._timeFormat = "%Y%m%d %H:%M:%S" - self.dataFile = os.path.normpath(os.path.join(dataDir, 'requests.txt')) - self._log.debug('Data file: {0}'.format(self.dataFile)) - - def addRequest(self): - """ adds a timestamp of current request""" - with open(self.dataFile, 'a') as f: - f.write(dt.datetime.now().strftime(self._timeFormat) + '\n') - - - def nrRequests(self, timeSpan=600): - """ return number of requests in past timespan (s) """ - delta = dt.timedelta(seconds=timeSpan) - now = dt.datetime.now() - requests = 0 - - with open(self.dataFile, 'r') as f: - lines = f.readlines() - - for line in lines: - if now - dt.datetime.strptime(line.strip(), self._timeFormat) < delta: - requests += 1 - - if requests == 0: # erase all contents if no requests are relevant - open(self.dataFile, 'w').close() - - self._log.debug('past requests: {0}'.format(requests)) - return requests - - -#---------------test functions----------------- - -def dummyHandler(msg): - print msg - - -def testConnection(): - """ a simple test to check working of streaming prices etc """ - tws = ibConnection() - tws.registerAll(dummyHandler) - - tws.connect() - - c = createContract('SPY') - tws.reqMktData(1, c, '', False) - sleep(3) - - print 'testConnection done.' - - -def testSubscriptions(): - s = Subscriptions() - s.add('SPY') - #s.add('XLE') - - print s - - -def testBroker(): - b = Broker() - sleep(2) - b.subscribeStk('SPY') - b.subscribeStk('XLE') - b.subscribeStk('GOOG') - - b.placeOrder('ABC', 125, 55.1) - sleep(3) - return b - - -#---------------------GUI stuff-------------------------------------------- -class AddSubscriptionDlg(QDialog): - def __init__(self, parent=None): - super(AddSubscriptionDlg, self).__init__(parent) - symbolLabel = QLabel('Symbol') - self.symbolEdit = QLineEdit() - secTypeLabel = QLabel('secType') - self.secTypeEdit = QLineEdit('STK') - exchangeLabel = QLabel('exchange') - self.exchangeEdit = QLineEdit('SMART') - currencyLabel = QLabel('currency') - self.currencyEdit = QLineEdit('USD') - - buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | - QDialogButtonBox.Cancel) - - lay = QGridLayout() - lay.addWidget(symbolLabel, 0, 0) - lay.addWidget(self.symbolEdit, 0, 1) - lay.addWidget(secTypeLabel, 1, 0) - lay.addWidget(self.secTypeEdit, 1, 1) - lay.addWidget(exchangeLabel, 2, 0) - lay.addWidget(self.exchangeEdit, 2, 1) - lay.addWidget(currencyLabel, 3, 0) - lay.addWidget(self.currencyEdit, 3, 1) - - lay.addWidget(buttonBox, 4, 0, 1, 2) - self.setLayout(lay) - - self.connect(buttonBox, SIGNAL("accepted()"), - self, SLOT("accept()")) - self.connect(buttonBox, SIGNAL("rejected()"), - self, SLOT("reject()")) - self.setWindowTitle("Add subscription") - - -class BrokerWidget(QWidget): - def __init__(self, broker, parent=None): - super(BrokerWidget, self).__init__(parent) - - self.broker = broker - - self.dataTable = TableView() - self.dataTable.setModel(self.broker.dataModel) - self.dataTable.horizontalHeader().setResizeMode(QHeaderView.Stretch) - #self.dataTable.resizeColumnsToContents() - dataLabel = QLabel('Price Data') - dataLabel.setBuddy(self.dataTable) - - dataLayout = QVBoxLayout() - - dataLayout.addWidget(dataLabel) - dataLayout.addWidget(self.dataTable) - - addButton = QPushButton("&Add Symbol") - saveDataButton = QPushButton("&Save Data") - #deleteButton = QPushButton("&Delete") - - buttonLayout = QVBoxLayout() - buttonLayout.addWidget(addButton) - buttonLayout.addWidget(saveDataButton) - buttonLayout.addStretch() - - layout = QHBoxLayout() - layout.addLayout(dataLayout) - layout.addLayout(buttonLayout) - self.setLayout(layout) - - self.connect(addButton, SIGNAL('clicked()'), self.addSubscription) - self.connect(saveDataButton, SIGNAL('clicked()'), self.saveData) - #self.connect(deleteButton,SIGNAL('clicked()'),self.deleteSubscription) - - def addSubscription(self): - dialog = AddSubscriptionDlg(self) - if dialog.exec_(): - self.broker.subscribeStk(str(dialog.symbolEdit.text()), str(dialog.secTypeEdit.text()), - str(dialog.exchangeEdit.text()), str(dialog.currencyEdit.text())) - - def saveData(self): - """ save data to a .csv file """ - fname = unicode(QFileDialog.getSaveFileName(self, caption="Save data to csv", filter='*.csv')) - if fname: - self.broker.saveData(fname) - - -# def deleteSubscription(self): -# pass - - -class Form(QDialog): - def __init__(self, parent=None): - super(Form, self).__init__(parent) - self.resize(640, 480) - self.setWindowTitle('Broker test') - - self.broker = Broker() - - self.broker.subscribeStk('SPY') - self.broker.subscribeStk('XLE') - self.broker.subscribeStk('GOOG') - - brokerWidget = BrokerWidget(self.broker, self) - lay = QVBoxLayout() - lay.addWidget(brokerWidget) - self.setLayout(lay) - - -def startGui(): - app = QApplication(sys.argv) - form = Form() - form.show() - app.exec_() - - -if __name__ == "__main__": - import ib - - print 'iby version:', ib.version - #testConnection() - #testBroker() - #testSubscriptions() - print message.messageTypeNames() - startGui() - print 'All done' - - \ No newline at end of file diff --git a/lib/logger.py b/lib/logger.py deleted file mode 100644 index 3a36cb4..0000000 --- a/lib/logger.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -## -# Defines logging formats and logger instance -## - -import logging -import os - -## -# Default log message formatting string. -format = '%(asctime)s %(levelname)s [%(name)s] %(message)s' - -## -# Default log date formatting string. -datefmt = '%d-%b-%y %H:%M:%S' - -## -# Default log level. Set TWP_LOGLEVEL environment variable to -# change this default. -level = int(os.environ.get('TWP_LOGLEVEL', logging.DEBUG)) - - -def getLogger(name='twp', level=level, format=format, - datefmt=datefmt): - """ Configures and returns a logging instance. - - @param name ignored - @param level logging level - @param format format string for log messages - @param datefmt format string for log dates - @return logging instance (the module) - """ - #print 'Loglevel:' , level - logging.basicConfig(level=level, format=format, datefmt=datefmt) - return logging.getLogger(name) diff --git a/lib/qtpandas.py b/lib/qtpandas.py deleted file mode 100644 index cdbc098..0000000 --- a/lib/qtpandas.py +++ /dev/null @@ -1,253 +0,0 @@ -''' -Easy integration of DataFrame into pyqt framework - -Copyright: Jev Kuznetsov -Licence: BSD - -''' -from PyQt4.QtCore import (QAbstractTableModel,Qt,QVariant,QModelIndex,SIGNAL) -from PyQt4.QtGui import (QApplication,QDialog,QVBoxLayout, QHBoxLayout, QTableView, QPushButton, - QWidget,QTableWidget, QHeaderView, QFont,QMenu,QAbstractItemView) - - -from pandas import DataFrame, Index - - - - -class DataFrameModel(QAbstractTableModel): - ''' data model for a DataFrame class ''' - def __init__(self,parent=None): - super(DataFrameModel,self).__init__(parent) - self.df = DataFrame() - self.columnFormat = {} # format columns - - def setFormat(self,fmt): - """ - set string formatting for the output - example : format = {'close':"%.2f"} - """ - - self.columnFormat = fmt - - def setDataFrame(self,dataFrame): - self.df = dataFrame - - self.signalUpdate() - - def signalUpdate(self): - ''' tell viewers to update their data (this is full update, not efficient)''' - self.layoutChanged.emit() - - def __repr__(self): - return str(self.df) - - def setData(self,index,value, role=Qt.EditRole): - - if index.isValid(): - row,column = index.row(), index.column() - dtype = self.df.dtypes.tolist()[column] # get column dtype - - if np.issubdtype(dtype,np.float): - val,ok = value.toFloat() - elif np.issubdtype(dtype,np.int): - val,ok = value.toInt() - else: - val = value.toString() - ok = True - - if ok: - self.df.iloc[row,column] = val - return True - - return False - - def flags(self, index): - if not index.isValid(): - return Qt.ItemIsEnabled - return Qt.ItemFlags( - QAbstractTableModel.flags(self, index)| - Qt.ItemIsEditable) - - def appendRow(self, index, data=0): - self.df.loc[index,:] = data - self.signalUpdate() - - def deleteRow(self, index): - idx = self.df.index[index] - #self.beginRemoveRows(QModelIndex(), index,index) - #self.df = self.df.drop(idx,axis=0) - #self.endRemoveRows() - #self.signalUpdate() - - #------------- table display functions ----------------- - def headerData(self,section,orientation,role=Qt.DisplayRole): - if role != Qt.DisplayRole: - return QVariant() - - if orientation == Qt.Horizontal: - try: - return self.df.columns.tolist()[section] - except (IndexError, ): - return QVariant() - elif orientation == Qt.Vertical: - try: - #return self.df.index.tolist() - return str(self.df.index.tolist()[section]) - except (IndexError, ): - return QVariant() - - def data(self, index, role=Qt.DisplayRole): - if role != Qt.DisplayRole: - return QVariant() - - if not index.isValid(): - return QVariant() - - col = self.df.ix[:,index.column()] # get a column slice first to get the right data type - elm = col[index.row()] - #elm = self.df.ix[index.row(),index.column()] - - if self.df.columns[index.column()] in self.columnFormat.keys(): - return QVariant(self.columnFormat[self.df.columns[index.column()]] % elm ) - else: - return QVariant(str(elm)) - - def sort(self,nCol,order): - - self.layoutAboutToBeChanged.emit() - if order == Qt.AscendingOrder: - self.df = self.df.sort(columns=self.df.columns[nCol], ascending=True) - elif order == Qt.DescendingOrder: - self.df = self.df.sort(columns=self.df.columns[nCol], ascending=False) - - self.layoutChanged.emit() - - - - def rowCount(self, index=QModelIndex()): - return self.df.shape[0] - - def columnCount(self, index=QModelIndex()): - return self.df.shape[1] - - -class TableView(QTableView): - """ extended table view """ - def __init__(self,name='TableView1', parent=None): - super(TableView,self).__init__(parent) - self.name = name - self.setSelectionBehavior(QAbstractItemView.SelectRows) - - def contextMenuEvent(self, event): - menu = QMenu(self) - - Action = menu.addAction("delete row") - Action.triggered.connect(self.deleteRow) - - menu.exec_(event.globalPos()) - - def deleteRow(self): - print "Action triggered from " + self.name - - print 'Selected rows:' - for idx in self.selectionModel().selectedRows(): - print idx.row() - # self.model.deleteRow(idx.row()) - - - -class DataFrameWidget(QWidget): - ''' a simple widget for using DataFrames in a gui ''' - def __init__(self,name='DataFrameTable1', parent=None): - super(DataFrameWidget,self).__init__(parent) - self.name = name - - self.dataModel = DataFrameModel() - self.dataModel.setDataFrame(DataFrame()) - - self.dataTable = QTableView() - #self.dataTable.setSelectionBehavior(QAbstractItemView.SelectRows) - self.dataTable.setSortingEnabled(True) - - self.dataTable.setModel(self.dataModel) - self.dataModel.signalUpdate() - - #self.dataTable.setFont(QFont("Courier New", 8)) - - layout = QVBoxLayout() - layout.addWidget(self.dataTable) - self.setLayout(layout) - - - - def setFormat(self,fmt): - """ set non-default string formatting for a column """ - for colName, f in fmt.iteritems(): - self.dataModel.columnFormat[colName]=f - - def fitColumns(self): - self.dataTable.horizontalHeader().setResizeMode(QHeaderView.Stretch) - - def setDataFrame(self,df): - self.dataModel.setDataFrame(df) - - - def resizeColumnsToContents(self): - self.dataTable.resizeColumnsToContents() - - def insertRow(self,index, data=None): - self.dataModel.appendRow(index,data) - -#-----------------stand alone test code - -def testDf(): - ''' creates test dataframe ''' - data = {'int':[1,2,3],'float':[1./3,2.5,3.5],'string':['a','b','c'],'nan':[np.nan,np.nan,np.nan]} - return DataFrame(data, index=Index(['AAA','BBB','CCC']))[['int','float','string','nan']] - - -class Form(QDialog): - def __init__(self,parent=None): - super(Form,self).__init__(parent) - - df = testDf() # make up some data - self.table = DataFrameWidget(parent=self) - self.table.setDataFrame(df) - #self.table.resizeColumnsToContents() - self.table.fitColumns() - self.table.setFormat({'float': '%.2f'}) - - - #buttons - #but_add = QPushButton('Add') - but_test = QPushButton('Test') - but_test.clicked.connect(self.testFcn) - hbox = QHBoxLayout() - #hbox.addself.table(but_add) - hbox.addWidget(but_test) - - layout = QVBoxLayout() - layout.addWidget(self.table) - layout.addLayout(hbox) - - self.setLayout(layout) - - def testFcn(self): - print 'test function' - self.table.insertRow('foo') - -if __name__=='__main__': - import sys - import numpy as np - - app = QApplication(sys.argv) - form = Form() - form.show() - app.exec_() - - - - - - \ No newline at end of file diff --git a/lib/vixFutures.py b/lib/vixFutures.py deleted file mode 100644 index 347eca9..0000000 --- a/lib/vixFutures.py +++ /dev/null @@ -1,136 +0,0 @@ -# -*- coding: utf-8 -*- -""" -set of tools for working with VIX futures - -@author: Jev Kuznetsov -Licence: GPL v2 -""" - -import datetime as dt -from pandas import * -import os -import urllib2 -#from csvDatabase import HistDataCsv - -m_codes = dict(zip(range(1,13),['F','G','H','J','K','M','N','Q','U','V','X','Z'])) #month codes of the futures -monthToCode = dict(zip(range(1,len(m_codes)+1),m_codes)) - - -def getCboeData(year,month): - ''' download data from cboe ''' - fName = "CFE_{0}{1}_VX.csv".format(m_codes[month],str(year)[-2:]) - urlStr = "http://cfe.cboe.com/Publish/ScheduledTask/MktData/datahouse/{0}".format(fName) - - try: - lines = urllib2.urlopen(urlStr).readlines() - except Exception, e: - s = "Failed to download:\n{0}".format(e); - print s - - # first column is date, second is future , skip these - header = lines[0].strip().split(',')[2:] - - dates = [] - data = [[] for i in range(len(header))] - - - - for line in lines[1:]: - fields = line.strip().split(',') - dates.append(datetime.strptime( fields[0],'%m/%d/%Y')) - for i,field in enumerate(fields[2:]): - data[i].append(float(field)) - - data = dict(zip(header,data)) - - df = DataFrame(data=data, index=Index(dates)) - - return df - -class Future(object): - ''' vix future class ''' - def __init__(self,year,month): - self.year = year - self.month = month - self.expiration = self._calculateExpirationDate() - self.cboeData = None # daily cboe data - self.intradayDb = None # intraday database (csv) - - def _calculateExpirationDate(self): - ''' calculate expiration date of the future, (not 100% reliable) ''' - t = dt.date(self.year,self.month,1)+datetools.relativedelta(months=1) - offset = datetools.Week(weekday=4) - if t.weekday()<>4: - t_new = t+3*offset - else: - t_new = t+2*offset - - t_new = t_new-datetools.relativedelta(days=30) - return t_new - - - def getCboeData(self, dataDir=None, forceUpdate=False): - ''' download interday CBOE data - specify dataDir to save data to csv. - data will not be downloaded if csv file is already present. - This can be overridden with setting forceUpdate to True - ''' - - - if dataDir is not None: - fileFound = os.path.exists(self._csvFilename(dataDir)) - - if forceUpdate or not fileFound: - self.cboeData = getCboeData(self.year, self.month) - self.to_csv(dataDir) - else: - self.cboeData = DataFrame.from_csv(self._csvFilename(dataDir)) - - else: - self.cboeData = getCboeData(self.year, self.month) - - - return self.cboeData - - def updateIntradayDb(self,dbDir): - #self.intradayDb = - pass - - def to_csv(self,dataDir): - ''' save to csv in given dir. Filename is automatically generated ''' - self.cboeData.to_csv(self._csvFilename(dataDir)) - - - @property - def dates(self): - ''' trading days derived from cboe data ''' - if self.cboeData is not None: - dates = [d.date() for d in self.cboeData.index] - else: - dates = None - - return dates - - def _csvFilename(self,dataDir): - fName = "VIX_future_%i_%i.csv" % (self.year, self.month) - return os.path.join(dataDir,fName) - - def __repr__(self): - s = 'Vix future [%i-%i (%s)] exp: %s\n' % (self.year, self.month,monthToCode[self.month], self.expiration.strftime("%B, %d %Y (%A)")) - s+= 'Cboe data: %i days'% len(self.cboeData) if self.cboeData is not None else 'No data downloaded yet' - return s - - - -if __name__ == '__main__': - print 'testing vix futures' - - year = 2012 - month = 12 - - - f = Future(year,month) - f.getCboeData() - print f - - \ No newline at end of file diff --git a/lib/widgets.py b/lib/widgets.py deleted file mode 100644 index bb69181..0000000 --- a/lib/widgets.py +++ /dev/null @@ -1,110 +0,0 @@ -# -*- coding: utf-8 -*- -""" -A collection of widgets for gui building - -Copyright: Jev Kuznetsov -License: BSD -""" - -from __future__ import division - -import sys -from PyQt4.QtCore import * -from PyQt4.QtGui import * - - -import numpy as np -from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas -from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar -from matplotlib.figure import Figure -import matplotlib.pyplot as plt - - -class MatplotlibWidget(QWidget): - def __init__(self,parent=None,grid=True): - QWidget.__init__(self,parent) - - self.grid = grid - - - self.fig = Figure() - self.canvas =FigureCanvas(self.fig) - self.canvas.setParent(self) - self.canvas.mpl_connect('button_press_event', self.onPick) # bind pick event - - - #self.axes = self.fig.add_subplot(111) - margins = [0.05,0.1,0.9,0.8] - self.axes = self.fig.add_axes(margins) - self.toolbar = NavigationToolbar(self.canvas,self) - - - #self.initFigure() - - layout = QVBoxLayout() - layout.addWidget(self.toolbar) - layout.addWidget(self.canvas) - - self.setLayout(layout) - - def onPick(self,event): - print 'Pick event' - print 'you pressed', event.button, event.xdata, event.ydata - - def update(self): - self.canvas.draw() - - def plot(self,*args,**kwargs): - self.axes.plot(*args,**kwargs) - self.axes.grid(self.grid) - self.update() - - def clear(self): - self.axes.clear() - - def initFigure(self): - self.axes.grid(True) - x = np.linspace(-1,1) - y = x**2 - self.axes.plot(x,y,'o-') - - -class PlotWindow(QMainWindow): - ''' a stand-alone window with embedded matplotlib widget ''' - def __init__(self,parent=None): - super(PlotWindow,self).__init__(parent) - self.setAttribute(Qt.WA_DeleteOnClose) - self.mplWidget = MatplotlibWidget() - self.setCentralWidget(self.mplWidget) - - def plot(self,dataFrame): - ''' plot dataframe ''' - dataFrame.plot(ax=self.mplWidget.axes) - - def getAxes(self): - return self.mplWidget.axes - - def getFigure(self): - return self.mplWidget.fig - - def update(self): - self.mplWidget.update() - -class MainForm(QMainWindow): - def __init__(self, parent=None): - QMainWindow.__init__(self, parent) - self.setWindowTitle('Demo: PyQt with matplotlib') - - self.plot = MatplotlibWidget() - self.setCentralWidget(self.plot) - - self.plot.clear() - self.plot.plot(np.random.rand(10),'x-') - - -#--------------------- -if __name__=='__main__': - app = QApplication(sys.argv) - form = MainForm() - form.show() - app.exec_() \ No newline at end of file diff --git a/lib/yahooFinance.py b/lib/yahooFinance.py deleted file mode 100644 index 4d6aaac..0000000 --- a/lib/yahooFinance.py +++ /dev/null @@ -1,278 +0,0 @@ -# -*- coding: utf-8 -*- - -# Author: Jev Kuznetsov -# License: BSD - - -""" -Toolset working with yahoo finance data - -This module includes functions for easy access to YahooFinance data - -Functions ----------- -- `getHistoricData` get historic data for a single symbol -- `getQuote` get current quote for a symbol -- `getScreenerSymbols` load symbols from a yahoo stock screener file - -Classes ---------- -- `HistData` a class for working with multiple symbols - - - -""" - - -from datetime import datetime, date -import urllib2 -from pandas import DataFrame, Index, HDFStore, WidePanel -import numpy as np -import os -from extra import ProgressBar - - - -def parseStr(s): - ''' convert string to a float or string ''' - f = s.strip() - if f[0] == '"': - return f.strip('"') - elif f=='N/A': - return np.nan - - else: - try: # try float conversion - prefixes = {'M':1e6, 'B': 1e9} - prefix = f[-1] - - if prefix in prefixes: # do we have a Billion/Million character? - return float(f[:-1])*prefixes[prefix] - else: # no, convert to float directly - return float(f) - except ValueError: # failed, return original string - return s - -class HistData(object): - ''' a class for working with yahoo finance data ''' - def __init__(self, autoAdjust=True): - - self.startDate = (2008,1,1) - self.autoAdjust=autoAdjust - self.wp = WidePanel() - - - def load(self,dataFile): - """load data from HDF""" - if os.path.exists(dataFile): - store = HDFStore(dataFile) - symbols = [str(s).strip('/') for s in store.keys() ] - data = dict(zip(symbols,[store[symbol] for symbol in symbols])) - self.wp = WidePanel(data) - store.close() - else: - raise IOError('Data file does not exist') - - - def save(self,dataFile): - """ save data to HDF""" - print 'Saving data to', dataFile - store = HDFStore(dataFile) - for symbol in self.wp.items: - store[symbol] = self.wp[symbol] - - store.close() - - - - def downloadData(self,symbols='all'): - ''' get data from yahoo ''' - - if symbols == 'all': - symbols = self.symbols - - #store = HDFStore(self.dataFile) - p = ProgressBar(len(symbols)) - - for idx,symbol in enumerate(symbols): - - try: - df = getSymbolData(symbol,sDate=self.startDate,verbose=False) - if self.autoAdjust: - df = _adjust(df,removeOrig=True) - - if len(self.symbols)==0: - self.wp = WidePanel({symbol:df}) - else: - self.wp[symbol] = df - - except Exception,e: - print e - p.animate(idx+1) - - def getDataFrame(self,field='close'): - ''' return a slice on wide panel for a given field ''' - return self.wp.minor_xs(field) - - - @property - def symbols(self): - return self.wp.items.tolist() - - - def __repr__(self): - return str(self.wp) - - -def getQuote(symbols): - ''' get current yahoo quote, return a DataFrame ''' - # for codes see: http://www.gummy-stuff.org/Yahoo-data.htm - if not isinstance(symbols,list): - symbols = [symbols] - - - header = ['symbol','last','change_pct','PE','time','short_ratio','prev_close','eps','market_cap'] - request = str.join('', ['s', 'l1', 'p2' , 'r', 't1', 's7', 'p', 'e' , 'j1']) - - - data = dict(zip(header,[[] for i in range(len(header))])) - - urlStr = 'http://finance.yahoo.com/d/quotes.csv?s=%s&f=%s' % (str.join('+',symbols), request) - - try: - lines = urllib2.urlopen(urlStr).readlines() - except Exception, e: - s = "Failed to download:\n{0}".format(e); - print s - - for line in lines: - fields = line.strip().split(',') - #print fields, len(fields) - for i,field in enumerate(fields): - data[header[i]].append( parseStr(field)) - - idx = data.pop('symbol') - - - return DataFrame(data,index=idx) - -def _historicDataUrll(symbol, sDate=(1990,1,1),eDate=date.today().timetuple()[0:3]): - """ - generate url - - symbol: Yahoo finanance symbol - sDate: start date (y,m,d) - eDate: end date (y,m,d) - """ - - urlStr = 'http://ichart.finance.yahoo.com/table.csv?s={0}&a={1}&b={2}&c={3}&d={4}&e={5}&f={6}'.\ - format(symbol.upper(),sDate[1]-1,sDate[2],sDate[0],eDate[1]-1,eDate[2],eDate[0]) - - return urlStr - -def getHistoricData(symbols, **options): - ''' - get data from Yahoo finance and return pandas dataframe - Will get OHLCV data frame if sinle symbol is provided. - If many symbols are provided, it will return a wide panel - - Parameters - ------------ - symbols: Yahoo finanance symbol or a list of symbols - sDate: start date (y,m,d) - eDate: end date (y,m,d) - adjust : T/[F] adjust data based on adj_close - - ''' - - assert isinstance(symbols,(list,str)), 'Input must be a string symbol or a list of symbols' - - if isinstance(symbols,str): - return getSymbolData(symbols,**options) - else: - data = {} - print 'Downloading data:' - p = ProgressBar(len(symbols)) - for idx,symbol in enumerate(symbols): - p.animate(idx+1) - data[symbol] = getSymbolData(symbol,verbose=False,**options) - - return WidePanel(data) - -def getSymbolData(symbol, sDate=(1990,1,1),eDate=date.today().timetuple()[0:3], adjust=False, verbose=True): - """ - get data from Yahoo finance and return pandas dataframe - - symbol: Yahoo finanance symbol - sDate: start date (y,m,d) - eDate: end date (y,m,d) - """ - - urlStr = 'http://ichart.finance.yahoo.com/table.csv?s={0}&a={1}&b={2}&c={3}&d={4}&e={5}&f={6}'.\ - format(symbol.upper(),sDate[1]-1,sDate[2],sDate[0],eDate[1]-1,eDate[2],eDate[0]) - - - try: - lines = urllib2.urlopen(urlStr).readlines() - except Exception, e: - s = "Failed to download:\n{0}".format(e); - print s - return None - - dates = [] - data = [[] for i in range(6)] - #high - - # header : Date,Open,High,Low,Close,Volume,Adj Close - for line in lines[1:]: - #print line - fields = line.rstrip().split(',') - dates.append(datetime.strptime( fields[0],'%Y-%m-%d')) - for i,field in enumerate(fields[1:]): - data[i].append(float(field)) - - idx = Index(dates) - data = dict(zip(['open','high','low','close','volume','adj_close'],data)) - - # create a pandas dataframe structure - df = DataFrame(data,index=idx).sort() - - if verbose: - print 'Got %i days of data' % len(df) - - if adjust: - return _adjust(df,removeOrig=True) - else: - return df - -def _adjust(df, removeOrig=False): - ''' - _adjustust hist data based on adj_close field - ''' - c = df['close']/df['adj_close'] - - df['adj_open'] = df['open']/c - df['adj_high'] = df['high']/c - df['adj_low'] = df['low']/c - - if removeOrig: - df=df.drop(['open','close','high','low'],axis=1) - renames = dict(zip(['adj_open','adj_close','adj_high','adj_low'],['open','close','high','low'])) - df=df.rename(columns=renames) - - return df - -def getScreenerSymbols(fileName): - ''' read symbols from a .csv saved by yahoo stock screener ''' - - with open(fileName,'r') as fid: - lines = fid.readlines() - - symbols = [] - for line in lines[3:]: - fields = line.strip().split(',') - field = fields[0].strip() - if len(field) > 0: - symbols.append(field) - return symbols - diff --git a/nautilus/nautilus.py b/nautilus/nautilus.py deleted file mode 100644 index 4755cc5..0000000 --- a/nautilus/nautilus.py +++ /dev/null @@ -1,179 +0,0 @@ -''' -Created on 26 dec. 2011 -Copyright: Jev Kuznetsov -License: BSD -''' - - - -from PyQt4.QtCore import * -from PyQt4.QtGui import * - -from ib.ext.Contract import Contract -from ib.opt import ibConnection -from ib.ext.Order import Order - -import tradingWithPython.lib.logger as logger -from tradingWithPython.lib.eventSystem import Sender, ExampleListener -import tradingWithPython.lib.qtpandas as qtpandas -import numpy as np - -import pandas - - -priceTicks = {1:'bid',2:'ask',4:'last',6:'high',7:'low',9:'close', 14:'open'} - - -class PriceListener(qtpandas.DataFrameModel): - def __init__(self): - super(PriceListener,self).__init__() - self._header = ['position','bid','ask','last'] - - def addSymbol(self,symbol): - data = dict(zip(self._header,[0,np.nan,np.nan,np.nan])) - row = pandas.DataFrame(data, index = pandas.Index([symbol])) - self.df = self.df.append(row[self._header]) # append data and set correct column order - - - def priceHandler(self,sender,event,msg=None): - - if msg['symbol'] not in self.df.index: - self.addSymbol(msg['symbol']) - - if msg['type'] in self._header: - self.df.ix[msg['symbol'],msg['type']] = msg['price'] - self.signalUpdate() - #print self.df - - - -class Broker(Sender): - def __init__(self, name = "broker"): - super(Broker,self).__init__() - - self.name = name - self.log = logger.getLogger(self.name) - - self.log.debug('Initializing broker. Pandas version={0}'.format(pandas.__version__)) - self.contracts = {} # a dict to keep track of subscribed contracts - self._id2symbol = {} # id-> symbol dict - self.tws = None - self._nextId = 1 # tws subscription id - self.nextValidOrderId = None - - - - def connect(self): - """ connect to tws """ - self.tws = ibConnection() # tws interface - self.tws.registerAll(self._defaultHandler) - self.tws.register(self._nextValidIdHandler,'NextValidId') - self.log.debug('Connecting to tws') - self.tws.connect() - - self.tws.reqAccountUpdates(True,'') - self.tws.register(self._priceHandler,'TickPrice') - - def subscribeStk(self,symbol, secType='STK', exchange='SMART',currency='USD'): - ''' subscribe to stock data ''' - self.log.debug('Subscribing to '+symbol) - c = Contract() - c.m_symbol = symbol - c.m_secType = secType - c.m_exchange = exchange - c.m_currency = currency - - subId = self._nextId - self._nextId += 1 - - self.tws.reqMktData(subId,c,'',False) - self._id2symbol[subId] = c.m_symbol - self.contracts[symbol]=c - - - def disconnect(self): - self.tws.disconnect() - #------event handlers-------------------- - - def _defaultHandler(self,msg): - ''' default message handler ''' - #print msg.typeName - if msg.typeName == 'Error': - self.log.error(msg) - - - def _nextValidIdHandler(self,msg): - self.nextValidOrderId = msg.orderId - self.log.debug( 'Next valid order id:{0}'.format(self.nextValidOrderId)) - - def _priceHandler(self,msg): - #translate to meaningful messages - message = {'symbol':self._id2symbol[msg.tickerId], - 'price':msg.price, - 'type':priceTicks[msg.field]} - self.dispatch('price',message) - - -#-----------------GUI elements------------------------- - -class TableView(QTableView): - """ extended table view """ - def __init__(self,name='TableView1', parent=None): - super(TableView,self).__init__(parent) - self.name = name - self.setSelectionBehavior(QAbstractItemView.SelectRows) - - def contextMenuEvent(self, event): - menu = QMenu(self) - - Action = menu.addAction("print selected rows") - Action.triggered.connect(self.printName) - - menu.exec_(event.globalPos()) - - def printName(self): - print "Action triggered from " + self.name - - print 'Selected :' - for idx in self.selectionModel().selectedRows(): - print self.model().df.ix[idx.row(),:] - - - -class Form(QDialog): - def __init__(self,parent=None): - super(Form,self).__init__(parent) - - self.broker = Broker() - self.price = PriceListener() - - self.broker.connect() - - symbols = ['SPY','XLE','QQQ','VXX','XIV'] - for symbol in symbols: - self.broker.subscribeStk(symbol) - - self.broker.register(self.price.priceHandler, 'price') - - - widget = TableView(parent=self) - widget.setModel(self.price) - widget.horizontalHeader().setResizeMode(QHeaderView.Stretch) - - layout = QVBoxLayout() - layout.addWidget(widget) - self.setLayout(layout) - - def __del__(self): - print 'Disconnecting.' - self.broker.disconnect() - -if __name__=="__main__": - print "Running nautilus" - - import sys - app = QApplication(sys.argv) - form = Form() - form.show() - app.exec_() - print "All done." \ No newline at end of file diff --git a/sandbox/dataModels.py b/sandbox/dataModels.py deleted file mode 100644 index a2e49d4..0000000 --- a/sandbox/dataModels.py +++ /dev/null @@ -1,185 +0,0 @@ -# -*- coding: utf-8 -*- -""" - -""" - - - -import sqlite3 as lite -import sys -from PyQt4.QtCore import (QAbstractTableModel,Qt,QVariant,QModelIndex, SIGNAL) -from PyQt4.QtGui import (QApplication,QDialog,QVBoxLayout, QTableView, QWidget, QHeaderView) - - -#import sys, os - -def initDb(dbName): - '''reset database ''' - print 'Resetting ' , dbName - con = lite.connect(dbName) - cur = con.cursor() - - cur.execute("DROP TABLE IF EXISTS tbl_symbols") - cur.execute("""CREATE TABLE tbl_symbols ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - symbol TEXT, - secType TEXT DEFAULT 'STK', - currency TEXT DEFAULT 'USD', - exchange TEXT DEFAULT 'SMART', - active BOOLEAN DEFAULT 1)""") - - - symbols = ('AAA','BBB','CCC') - for symbol in symbols: - cur.execute("INSERT INTO tbl_symbols (symbol) VALUES(?) ",(symbol,)) - - con.commit() - - - -class SqliteTableModel(QAbstractTableModel): - ''' base class for interfacing to sqlite db''' - def __init__(self,dbConnection,tableName,parent=None): - super(SqliteTableModel,self).__init__(parent) - self._con = dbConnection - self._table = tableName - self._data = [] - self._header = [] - self._reload() - - - - def _reload(self): - ' reload all data' - q = "SELECT * FROM %s " % self._table - cur = self._con.cursor() - cur.execute(q) - - self._data = [] - for row in cur: - self._data.append([]) - curr = self._data[-1] - for elm in row: - curr.append(elm) - - cur.execute("PRAGMA table_info(%s)" % self._table) - for c in cur: - self._header.append(c[1]) - - def __repr__(self): - return str(self._header)+'\n'+str.join('\n',[ str(row) for row in self._data]) - - - - -class Symbols(QAbstractTableModel): - ''' class for managing a group of spreads through sqlite ''' - def __init__(self,dbConnection,tableName): - - self.tblName = tableName # name of the database table - self.con = dbConnection - - self.cur = self.con.cursor() - self.data = [] - - def sql(self,query): - cur = self.con.cursor() - cur.execute(query) - return cur.fetchall() - - - def initDb(self): - self.cur.execute("DROP TABLE IF EXISTS tbl_symbols") - self.cur.execute("""CREATE TABLE tbl_symbols ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - symbol TEXT, - secType TEXT DEFAULT 'STK', - currency TEXT DEFAULT 'USD', - exchange TEXT DEFAULT 'SMART', - active BOOLEAN DEFAULT 1)""") - - - self.con.commit() - - - def addSymbol(self, symbol): - t = (symbol,) - self.cur.execute("INSERT INTO tbl_symbols (symbol) VALUES(?) ",t) - - - def load(self): - ''' reload full table from db ''' - q = "SELECT * FROM tbl_symbols " - self.cur.execute(q) - - self.data = [] - for row in self.cur: - self.data.append([]) - curr = self.data[-1] - for elm in row: - curr.append(elm) - - - - def printTable(self): - self.load() - print '-'*10 - print self.data - - def _testFcn(self): - self.sql("insert into tbl_symbols ") - - def showTables(self): - self.cur.execute("select name from sqlite_master where type='table' ") - res = self.cur.fetchall() - for row in res: - print row[0] - - def __del__(self): - self.con.close() - - -#----------------test code -class Form(QDialog): - def __init__(self, parent=None): - super(Form, self).__init__(parent) - self.resize(640,480) - self.setWindowTitle('Model test') - - model = SqliteTableModel(con,'tbl_symbols') - table = QTableView() - table.setModel(model) - - lay = QVBoxLayout() - lay.addWidget(table) - self.setLayout(lay) - -def startGui(): - app = QApplication(sys.argv) - form = Form() - form.show() - app.exec_() - -def testModel(): - ' simple model test, without gui' - m = SqliteTableModel(con,'tbl_symbols') - print m - -if __name__=='__main__': - - dbName = 'testDb' - - #initDb(dbName) - con = lite.connect(dbName) - cur = con.cursor() - cur.execute("select name from sqlite_master where type='table' ") - - for row in cur: - print row[0] - - - testModel() - #startGui() - - - \ No newline at end of file diff --git a/sandbox/guiWithDatabase.py b/sandbox/guiWithDatabase.py deleted file mode 100644 index d62cb8d..0000000 --- a/sandbox/guiWithDatabase.py +++ /dev/null @@ -1,105 +0,0 @@ - -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals -from future_builtins import * - -import os -import sys -from PyQt4.QtCore import * -from PyQt4.QtGui import * -from PyQt4.QtSql import (QSqlDatabase, QSqlQuery, QSqlRelation, - QSqlRelationalDelegate, QSqlRelationalTableModel, QSqlTableModel) - - - -import sqlite3 as db - -dbName = 'test.db' - - -def initDb(): - '''reset database ''' - con = db.connect(dbName) - cur = con.cursor() - - cur.execute("DROP TABLE IF EXISTS tbl_symbols") - cur.execute("""CREATE TABLE tbl_symbols ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - symbol TEXT, - secType TEXT DEFAULT 'STK', - currency TEXT DEFAULT 'USD', - exchange TEXT DEFAULT 'SMART', - active BOOLEAN DEFAULT 1)""") - - - symbols = ('AAA','BBB','CCC') - for symbol in symbols: - cur.execute("INSERT INTO tbl_symbols (symbol) VALUES(?) ",(symbol,)) - - con.commit() - - -#----------------- -class MainForm(QDialog): - def __init__(self): - super(MainForm, self).__init__() - - self.model = QSqlTableModel(self) - self.model.setTable('tbl_symbols') - self.model.select() - - self.view = QTableView() - self.view.setModel(self.model) - self.view.horizontalHeader().setResizeMode(QHeaderView.Stretch) - - addButton = QPushButton("&Add") - deleteButton = QPushButton("&Delete") - - buttonLayout = QVBoxLayout() - buttonLayout.addWidget(addButton) - buttonLayout.addWidget(deleteButton) - buttonLayout.addStretch() - - lay = QHBoxLayout() - lay.addWidget(self.view) - lay.addLayout(buttonLayout) - self.setLayout(lay) - - self.connect(addButton, SIGNAL("clicked()"), self.addRecord) - self.connect(deleteButton, SIGNAL("clicked()"), self.deleteRecord) - - - def addRecord(self): - row = self.model.rowCount() - self.model.insertRow(row) - index = self.model.index(row, 1) - self.view.setCurrentIndex(index) - self.view.edit(index) - - def deleteRecord(self): - index = self.view.currentIndex() - if not index.isValid(): - return - #QSqlDatabase.database().transaction() - record = self.model.record(index.row()) - self.model.removeRow(index.row()) - self.model.submitAll() - -def main(): - app = QApplication(sys.argv) - db = QSqlDatabase.addDatabase("QSQLITE") - db.setDatabaseName(dbName) - if not db.open(): - QMessageBox.warning(None, "Asset Manager", - QString("Database Error: %1") - .arg(db.lastError().text())) - sys.exit(1) - - form = MainForm() - form.show() - app.exec_() - del form - del db -#initDb() -main() \ No newline at end of file diff --git a/sandbox/spreadCalculations.py b/sandbox/spreadCalculations.py deleted file mode 100644 index 3a93829..0000000 --- a/sandbox/spreadCalculations.py +++ /dev/null @@ -1,64 +0,0 @@ -''' -Created on 28 okt 2011 - -@author: jev -''' - -from tradingWithPython import estimateBeta, Spread, returns, Portfolio, readBiggerScreener -from tradingWithPython.lib import yahooFinance -from pandas import DataFrame, Series -import numpy as np -import matplotlib.pyplot as plt -import os - - - -symbols = ['SPY','IWM'] -y = yahooFinance.HistData('temp.csv') -y.startDate = (2007,1,1) - -df = y.loadSymbols(symbols,forceDownload=False) -#df = y.downloadData(symbols) - -res = readBiggerScreener('CointPairs.csv') - -#---check with spread scanner -#sp = DataFrame(index=symbols) -# -#sp['last'] = df.ix[-1,:] -#sp['targetCapital'] = Series({'SPY':100,'IWM':-100}) -#sp['targetShares'] = sp['targetCapital']/sp['last'] -#print sp - -#The dollar-neutral ratio is about 1 * IWM - 1.7 * IWM. You will get the spread = zero (or probably very near zero) - - -#s = Spread(symbols, histClose = df) -#print s - -#s.value.plot() - -#print 'beta (returns)', estimateBeta(df[symbols[0]],df[symbols[1]],algo='returns') -#print 'beta (log)', estimateBeta(df[symbols[0]],df[symbols[1]],algo='log') -#print 'beta (standard)', estimateBeta(df[symbols[0]],df[symbols[1]],algo='standard') - -#p = Portfolio(df) -#p.setShares([1, -1.7]) -#p.value.plot() - - -quote = yahooFinance.getQuote(symbols) -print quote - - -s = Spread(symbols,histClose=df, estimateBeta = False) -s.setLast(quote['last']) - -s.setShares(Series({'SPY':1,'IWM':-1.7})) -print s -#s.value.plot() -#s.plot() -fig = figure(2) -s.plot() - - diff --git a/sandbox/spreadGroup.py b/sandbox/spreadGroup.py deleted file mode 100644 index e8735b6..0000000 --- a/sandbox/spreadGroup.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Dec 09 18:41:08 2011 - -@author: jev -""" - - - -import sqlite3 as db -#import sys, os - - -class Symbols(object): - ''' class for managing a group of spreads through sqlite ''' - def __init__(self,fName='spreads.db'): - self.con = db.connect(fName) - self.cur = self.con.cursor() - - def sql(self,query): - cur = self.con.cursor() - cur.execute(query) - return cur.fetchall() - - - def initDb(self): - self.cur.execute("DROP TABLE IF EXISTS tbl_symbols") - self.cur.execute("""CREATE TABLE tbl_symbols ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - symbol TEXT, - secType TEXT DEFAULT 'STK', - currency TEXT DEFAULT 'USD', - exchange TEXT DEFAULT 'SMART', - active BOOLEAN DEFAULT 1)""") - - - self.con.commit() - - - def addSymbol(self, symbol): - t = (symbol,) - self.cur.execute("INSERT INTO tbl_symbols (symbol) VALUES(?) ",t) - - def printTable(self,table): - - q = "SELECT * FROM "+table # insecure, but ? does not work here - self.cur.execute(q) - print '-'*10+table+"-"*10 - for row in self.cur: - print row - - def _testFcn(self): - self.sql("insert into tbl_symbols ") - - def showTables(self): - self.cur.execute("select name from sqlite_master where type='table' ") - res = self.cur.fetchall() - for row in res: - print row[0] - - def __del__(self): - self.con.close() - - - - - -if __name__=='__main__': - g = Symbols() - g.initDb() - g.showTables() - g.addSymbol('SPY') - g.addSymbol('XYZ') - g.printTable('tbl_symbols') - \ No newline at end of file diff --git a/spreadApp/gold_stocks.csv b/spreadApp/gold_stocks.csv deleted file mode 100644 index 35750bd..0000000 --- a/spreadApp/gold_stocks.csv +++ /dev/null @@ -1,20 +0,0 @@ -Screener Results: - -Ticker,Company Name,Last Trade,Trade Time,Mkt Cap,Return On Equity,Return On Assets,Forward PE -AU , AngloGold Ashanti , 44,25 , 1:30pm , 85,484B , 26,85 , 10,694 , 7,68 -ABX , Barrick Gold Corp , 47,66 , 1:30pm , 47,650B , 19,136 , 9,884 , 8,29 -GG , Goldcorp Incorpor , 47,82 , 1:30pm , 38,721B , 9,357 , 5,266 , 15,92 -NEM , Newmont Mining Co , 64,77 , 1:30pm , 32,049B , 19,569 , 9,911 , 10,96 -KGC , Kinross Gold Corp , 12,62 , 1:30pm , 14,356B , 5,149 , 4,694 , 10,44 -AUY , Yamana Gold, Inc. , 15,43 , 1:30pm , 11,506B , 7,85 , 5,275 , 12,55 -GFI , Gold Fields Ltd. , 15,67 , 1:30pm , 11,332B , 0 , 0 , 0 -BVN , Compania Mina Bue , 37,39 , 1:30pm , 9,514B , 32,741 , 13,33 , 9,11 -EGO , Eldorado Gold Cor , 15,73 , 1:30pm , 8,671B , 9,3 , 7,446 , 15,21 -AEM , Agnico-Eagle Mine , 41,33 , 1:30pm , 7,000B , 3,283 , 2,603 , 13,05 -IAG , Iamgold Corporati , 18,23 , 1:30pm , 6,852B , 15,331 , 10,41 , 12,73 -HMY , Harmony Gold Mini , 12,85 , 1:30pm , 5,527B , 0 , 0 , 11,57 -AUQ , AuRico Gold Inc. , 8,92 , 1:30pm , 2,511B , 13,228 , 9,076 , 7,44 -JAG , Jaguar Mining Inc , 6,26 , 1:30pm , 528,4M , -28,931 , 0,948 , 0 -UXG , U.S. Gold Corpora , 3,45 , 1:30pm , 482,1M , -25,537 , -10,547 , 0 - - diff --git a/spreadApp/makeDist.py b/spreadApp/makeDist.py deleted file mode 100644 index 7d51331..0000000 --- a/spreadApp/makeDist.py +++ /dev/null @@ -1,60 +0,0 @@ -from distutils.core import setup -import py2exe - -manifest_template = ''' - - - -%(prog)s Program - - - - - - -''' - -RT_MANIFEST = 24 -import matplotlib - - -opts = { - 'py2exe': { - "compressed": 1, - "bundle_files" : 3, - "includes" : ["sip", - "matplotlib.backends", - "matplotlib.backends.backend_qt4agg", - "pylab", "numpy", - "matplotlib.backends.backend_tkagg"], - 'excludes': ['_gtkagg', '_tkagg', '_agg2', - '_cairo', '_cocoaagg', - '_fltkagg', '_gtk', '_gtkcairo', ], - 'dll_excludes': ['libgdk-win32-2.0-0.dll', - 'libgobject-2.0-0.dll'] - - } - } - - - -setup(name="triton", - version = "0.1", - scripts=["spreadScanner.pyw"], - windows=[{"script": "spreadScanner.pyw"}], - options=opts, - data_files=matplotlib.get_py2exe_datafiles(), - other_resources = [(RT_MANIFEST, 1, manifest_template % dict(prog="spreadDetective"))], - zipfile = None) \ No newline at end of file diff --git a/spreadApp/spreadScanner.pyw b/spreadApp/spreadScanner.pyw deleted file mode 100644 index a2679fa..0000000 --- a/spreadApp/spreadScanner.pyw +++ /dev/null @@ -1,275 +0,0 @@ -''' -Created on 12 dec. 2011 -Copyright: Jev Kuznetsov -License: BSD -''' - -import sys, os - -__version__ = "0.1.0" - -from PyQt4.QtCore import (Qt, SIGNAL) -from PyQt4.QtGui import * -import platform - -import widgets.ui_symbolChooser -from tradingWithPython.lib.yahooFinance import getScreenerSymbols -import qrc_resources -from tradingWithPython import readBiggerScreener -from tradingWithPython.lib.qtpandas import DataFrameWidget, DataFrameModel -from tradingWithPython.lib.widgets import PlotWindow -from tradingWithPython.lib.classes import Spread -from tradingWithPython.lib.functions import returns - -from widgets.spread import SpreadWidget - -import numpy as np -import matplotlib.pyplot as plt -from pandas import DataFrame,Index,Series - -#---------globals -dataFile = 'yahooData.csv' -dataStartDate = (2010,1,1) -#--------classes - -class SymbolChooser(QWidget,widgets.ui_symbolChooser.Ui_Form): - ''' symbol chooser widget ''' - def __init__(self,parent=None): - super(SymbolChooser,self).__init__(parent) - self.setupUi(self) - - def symbols(self): - symbols = [] - for i in range(self.listSymbols.count()): - symbols.append(str(self.listSymbols.item(i).text())) - return symbols - - - - -class SpreadViewModel(DataFrameModel): - """ modified version of the model to hack around sorting issue""" - def __init__(self,parent=None): - super(SpreadViewModel,self).__init__(parent=None) - - def sort(self,nCol,order): - - self.layoutAboutToBeChanged.emit() - - col = self.df[self.df.columns[nCol]].values.tolist() - - #create indexed list, sort, rebuild complete data frame 8( - di = [(d,i) for i,d in enumerate(col)] - - if order == Qt.AscendingOrder: - idx = [i for d,i in sorted(di)] - elif order == Qt.DescendingOrder: - idx = [i for d,i in sorted(di,reverse=True)] - - data = self.df.values[idx,:] - cols = self.df.columns - # rebuild the whole thing - self.df = DataFrame(data=data, columns=cols, index = Index(range(len(idx)))) - - self.layoutChanged.emit() - - - - -class SpreadView(QTableView): - """ extended table view """ - def __init__(self,name='TableView1', parent=None): - super(SpreadView,self).__init__(parent) - self.name = name - self.setSelectionBehavior(QAbstractItemView.SelectRows) - - - def contextMenuEvent(self, event): - menu = QMenu(self) - - Action = menu.addAction("Show spread") - Action.triggered.connect(self.showSpread) - - menu.exec_(event.globalPos()) - - def showSpread(self): - """ open a spread window """ - for idx in self.selectionModel().selectedRows(): - row = self.selectionModel().model().df.ix[idx.row(),:] - symbols = [row['StockA'],row['StockB']] - spread = Spread(symbols) - spread.setShares(Series({row['StockA']:1,row['StockB']:-row['Price Ratio']})) - spreadWindow = SpreadWindow(self) - spreadWindow.setSpread(spread) - - spreadWindow.show() - - -class SpreadWindow(QMainWindow): - def __init__(self,parent=None): - super(SpreadWindow,self).__init__(parent) - self.resize(640,600) - self.setWindowTitle('Spread test') - - self.widget = SpreadWidget(self) - self.setCentralWidget(self.widget) - - self.spread = None - - def setSpread(self,spread): - - self.spread = spread - self.setWindowTitle(spread.name) - self.widget.setSpread(self.spread) - -class BiggerSpreads(QWidget): - """ class for working with spreads from screener """ - def __init__(self, parent=None): - super(QWidget,self).__init__(parent) - self.name = 'bigger spreads' - - self.df = DataFrame() # main data container - self.dataModel = SpreadViewModel() - self.dataModel.setDataFrame(self.df) - - self.dataTable = SpreadView() - self.dataTable.setSortingEnabled(True) - - self.dataTable.setModel(self.dataModel) - self.dataModel.signalUpdate() - - - layout = QVBoxLayout() - layout.addWidget(self.dataTable) - self.setLayout(layout) - - def loadSpreads(self,fName): - self.df = readBiggerScreener(fName) - self.dataModel.setDataFrame(self.df) - #self.dataTable.resizeColumnsToContents() - self.dataTable.horizontalHeader().setResizeMode(QHeaderView.Stretch) - - -class MainWindow(QMainWindow): - def __init__(self, parent=None): - super(MainWindow, self).__init__(parent) - - self.setWindowTitle('Spread Detective [alpha]') - - # general vars - self.filename = None - self.actions = {} # actions list - - #fill central area - self.dataTable = BiggerSpreads() - self.setCentralWidget(self.dataTable) - - #create actions - self.actions['loadScreener'] = self.createAction("Load symbols",self.loadScreenerSymbols,icon="fileopen") - self.actions['helpAbout'] = self.createAction("About",self.helpAbout) - #self.actions['test'] = self.createAction("Test",self._testFcn) - - #set app menu - self.createMenu() - self.createToolbars() - - #quick init - self._quickInit() - self.resize(800,600) - - def _quickInit(self): - testFile = 'CointPairs_test.csv' - if os.path.exists(testFile): - self.dataTable.loadSpreads(testFile) - - def createMenu(self): - menu = self.menuBar() - menu.addMenu("File").addAction(self.actions['loadScreener']) - menu.addMenu("Help").addAction(self.actions['helpAbout']) - - def createToolbars(self): - t = self.addToolBar("File") - t.setObjectName("FileToolBar") - t.addAction(self.actions['loadScreener']) - - def loadScreenerSymbols(self, fName = None): - ' load symbols from yahoo screener csv' - - if fName is None: - formats = ['*.csv'] - path = (os.path.dirname(self.filename) - if self.filename is not None else ".") - - fName = unicode(QFileDialog.getOpenFileName(self,"Open screener results",path, - "CSV files ({0})".format(" ".join(formats)))) - - if fName: - self.dataTable.loadSpreads(fName) - - def plotHistData(self): - ''' plot internal historic data ''' - plt = PlotWindow(self) - plt.plot(self.dataTable.histData.df) - plt.show() - - def createAction(self, text, slot=None, shortcut=None, icon=None, - tip=None, checkable=False, signal="triggered()"): - action = QAction(text, self) - if icon is not None: - action.setIcon(QIcon(":/{0}.png".format(icon))) - if shortcut is not None: - action.setShortcut(shortcut) - if tip is not None: - action.setToolTip(tip) - action.setStatusTip(tip) - if slot is not None: - self.connect(action, SIGNAL(signal), slot) - if checkable: - action.setCheckable(True) - return action - - - def helpAbout(self): - QMessageBox.about(self, "Spread Detective - About", - """Spread Detective v {0} -

Copyright © 2011 Jev Kuznetsov. - All rights reserved. -

- Copyright © 2008-2011 AQR Capital Management, LLC All rights reserved. -

- Copyright © 2011 Wes McKinney and pandas developers All rights reserved. - -

- - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -

Python {1} """.format(__version__, platform.python_version())) - - - - def _testFcn(self): - print 'test function' - self.dataTable.dataModel.signalUpdate() - - - -def main(): - app = QApplication(sys.argv) - form = MainWindow() - form.show() - app.exec_() - - -main() - \ No newline at end of file