itrade_datation.py :  » Business-Application » iTrade » itrade » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Business Application » iTrade 
iTrade » itrade » itrade_datation.py
#!/usr/bin/env python
# ============================================================================
# Project Name : iTrade
# Module Name  : itrade_datation.py
#
# Description: Datation
#
# The Original Code is iTrade code (http://itrade.sourceforge.net).
#
# The Initial Developer of the Original Code is  Gilles Dumortier.
#
# Portions created by the Initial Developer are Copyright (C) 2004-2008 the
# Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see http://www.gnu.org/licenses/gpl.html
#
# History       Rev   Description
# 2005-01-09    dgil  Wrote it from scratch
# 2005-08-15    dgil  Add indexation system (trade can be referenced by index
#                     or by date)
# ============================================================================

# ============================================================================
# Imports
# ============================================================================

# python system
from datetime import *
import time
import logging
import string
import re

# iTrade system
from itrade_logging import *
from itrade_local import getShortDateFmt
import itrade_csv

# ============================================================================
# some patterns for date
# ============================================================================

re_p3_1 = re.compile('\d\d\d\d-\d\d-\d\d')
re_p3_2 = re.compile('\d\d\d\d/\d\d/\d\d')
re_p4_1 = re.compile('\d\d-\d\d-\d\d')
re_p4_2 = re.compile('\d\d-\d\d-\d\d\d\d')
re_p4_3 = re.compile('\d\d/\d\d/\d\d')
re_p4_4 = re.compile('\d\d/\d\d/\d\d\d\d')

# ============================================================================
# some convertion
# ============================================================================

MONTH2NUM = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6,
  'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12}

Y2KCUTOFF = 60

def yy2yyyy(yy):
    yy = int(yy) % 100
    if yy<Y2KCUTOFF:
        return `yy+2000`
    else:
        return `yy+1900`

def dd_mmm_yy2yyyymmdd(d):
    d = string.split(d, '-')
    day = '%02d' % int(d[0])
    month = '%02d' % MONTH2NUM[d[1]]
    year = yy2yyyy(d[2])
    return year + month + day

def jjmmaa2yyyymmdd(d):
    d = string.split(d,'/')
    day = '%02d' % int(d[0])
    month = '%02d' % int(d[1])
    year = yy2yyyy(d[2])
    return year + month + day

# ============================================================================
# date2str
# ============================================================================

def date2str(dt,bDisplayShort):
    if dt:
        if bDisplayShort:
            return dt.strftime(getShortDateFmt())
        else:
            return dt.strftime('%x')
    return ''

# ============================================================================
# Calendar
#
# singleton object to manage market day closed
# ============================================================================

MONDAY = 0
TUESDAY = 1
WEDNESDAY = 2
THURSDAY = 3
FRIDAY = 4
SATURDAY = 5
SUNDAY = 6

class Calendar(object):
    def __init__(self):
        self.m_closed = {}
        self.m_index = {}
        self.m_date = {}
        self.m_srd = {}
        self.m_maxidx = 0
        self.load()
        self.indexme()

    # --- [ properties ] --------------------------------------

    def isopen(self,d,market=None):
        if type(d)==type('') or isinstance(d,date):
            d = Datation(d)
        if not isinstance(d,Datation):
            raise TypeError("parameter shall be date, Datation or string object")

        debug('isopen %s ? %s ' % (d,self.m_closed))

        # is it saturday or sunday ?
        if d.weekday()>=SATURDAY:
            return False

        # key
        k = self.key(d,market)
        debug('isopen %s k=%s: ? ' % (d,k))

        # is it a special day ?
        if self.m_closed.has_key(k):
            return False

        # market should be opened !
        return True

    def issrd(self,d,market=None):
        if type(d)==type('') or isinstance(d,date):
            d = Datation(d)
        if not isinstance(d,Datation):
            raise TypeError("parameter shall be date, Datation or string object")

        debug('issrd %s ? %s ' % (d,self.m_srd))

        # is it saturday or sunday ?
        if d.weekday()>=SATURDAY:
            return False

        # key
        k = self.key(d,market)
        debug('issrd %s k=%s: ? ' % (d,k))

        # is it a SRD day ?
        if self.m_srd.has_key(k):
            return True

        # normal day
        return False

    def srd(self,d,market=None):
        if type(d)==type('') or isinstance(d,date):
            d = Datation(d)
        if not isinstance(d,Datation):
            raise TypeError("parameter shall be date, Datation or string object")

        # key
        k = self.key(d,market)

        # is it a SRD day ?
        if self.m_srd.has_key(k):
            return self.m_srd[k]
        return None

    # --- [ key management ] --------------------------------------

    def key(self,d,market=None):
        # default Market Entry Place
        if market==None:
            market = 'EURONEXT'

        # key : date + market
        return  '%s%s' % (market,d)

    # --- [ file management ] -------------------------------------

    def addClosed(self,d,market=None,title=None):
        # default Market Entry Place
        if market==None:
            market = 'EURONEXT'

        # normalize the date notation !
        d = Datation(d)

        # key
        k = self.key(d,market)

        if self.m_closed.has_key(k):
            debug('Calendar::addClosed(): %s k=%s: %s - already !' % (d,k,self.m_closed[k]));
            return False
        else:
            # add it in the closed list
            self.m_closed[k] = (market,title)
            debug('Calendar::addClosed(): %s k=%s: %s - added' % (d,k,self.m_closed[k]));
            return True

    def addSRD(self,d,market=None,title=None):
        # default Market Entry Place
        if market==None:
            market = 'EURONEXT'

        # normalize the date notation !
        d = Datation(d)

        # key
        k = self.key(d,market)

        if self.m_srd.has_key(k):
            debug('Calendar::addSRD(): %s k=%s: %s - already !' % (d,k,self.m_srd[k]));
            return False
        else:
            # add it in the srd list
            self.m_srd[k] = (market,title)
            debug('Calendar::addSRD(): %s k=%s: %s - added' % (d,k,self.m_srd[k]));
            return True

    def load(self,fn=None):
        # open and read the file to load these closure information
        infile = itrade_csv.read(fn,os.path.join(itrade_config.dirSysData,'closed.txt'))
        if infile:
            # scan each line to read each quote
            for eachLine in infile:
                item = itrade_csv.parse(eachLine,3)
                if item:
                    if len(item)>2:
                        self.addClosed(item[0],item[1],item[2])
                    else:
                        info("can't import item=%s" % item)

        # open and read the file to load these SRD information
        infile = itrade_csv.read(fn,os.path.join(itrade_config.dirSysData,'srd.txt'))
        if infile:
            # scan each line to read each quote
            for eachLine in infile:
                item = itrade_csv.parse(eachLine,3)
                if item:
                    if len(item)>2:
                        self.addSRD(item[0],item[1],item[2])
                    else:
                        info("can't import item=%s" % item)

    # --- [ index management ] ------------------------------------

    def indexme(self):
        self.m_maxidx = 0
        year = date.today().year - itrade_config.numTradeYears + 1
        num = (itrade_config.numTradeYears * (12*31)) + 5
        while num > 0:
            #print '--- index datation --%d--' % year
            month = 1
            while month <= 12 and num>0:
                #print '--- index datation --%d--' % month
                day = 1
                while day <= 31 and num>0:
                    #print '--- index datation --%d--' % day
                    try:
                        d = date(year,month,day)
                        #d = Datation(d)
                        if d.weekday()<SATURDAY:
                        #if self.isopen(d):
                            #print 'num=%d - index %s = %d' % (num,d,self.m_maxidx)
                            self.m_index[d] = self.m_maxidx
                            self.m_date[self.m_maxidx] = d
                            self.m_maxidx = self.m_maxidx + 1
                        else:
                            #print 'num=%d - index %s = closed' % (num,d)
                            pass
                    except ValueError:
                        pass
                    day = day + 1
                    num = num - 1
                month = month + 1
            year = year + 1

    def index(self,_date):
        if self.m_index.has_key(_date):
            return self.m_index[_date]
        else:
            return -1

    def date(self,_index):
        if self.m_date.has_key(_index):
            return self.m_date[_index]
        else:
            return None

    def lastindex(self):
        return self.m_maxidx - 1

    def lastdate(self):
        return self.date(self.lastindex())

# ============================================================================
# Datation
#
# this object encapsulate a date object with the following properties :
# - really read only object
# - constructed by a date object or a string
# - use calendar singleton object with prev / next
# ============================================================================

class Datation(object):
    def __init__(self,d):
        #debug('Datation::__init__():%s: instance=%s' %(d,type(d)))
        if isinstance(d,date):
            self.m_date = d
        else:
            if d[4]=='-':
                debug('Datation::__init__():%s: %d %d %d' % (d,long(d[0:4]),long(d[5:7]),long(d[8:10])));
                self.m_date = date(long(d[0:4]),long(d[5:7]),long(d[8:10]))
            else:
                debug('Datation::__init__():%s: %d %d %d' % (d,long(d[0:4]),long(d[4:6]),long(d[6:8])));
                self.m_date = date(long(d[0:4]),long(d[4:6]),long(d[6:8]))

    def __str__(self):
        return '%4.4d%2.2d%2.2d' % (self.m_date.year,self.m_date.month,self.m_date.day)

    def __repr__(self):
        return '%4.4d-%2.2d-%2.2d' % (self.m_date.year,self.m_date.month,self.m_date.day)

    def __hash__(self):
        return self.m_date.toordinal()

    def year(self):
        return self.m_date.year

    def month(self):
        return self.m_date.month

    def day(self):
        return self.m_date.day

    def weekday(self):
        return self.m_date.weekday()

    def date(self):
        return self.m_date

    def nextopen(self,market=None):
        ndate = self.m_date + timedelta(1)
        while not gCal.isopen(ndate,market):
            ndate = ndate + timedelta(1)
        return Datation(ndate)

    def prevopen(self,market=None):
        ndate = self.m_date - timedelta(1)
        while not gCal.isopen(ndate,market):
            ndate = ndate - timedelta(1)
        return Datation(ndate)

    def nearopen(self,market=None):
        ndate = self.m_date
        while not gCal.isopen(ndate,market):
            ndate = ndate - timedelta(1)
        return Datation(ndate)

    def index(self):
        return gCal.index(self.m_date)

# ============================================================================
# Install the Calendar system
# ============================================================================

if __name__=='__main__':
    setLevel(logging.INFO)

try:
    ignore(gCal)
except NameError:
    gCal = Calendar()

# ============================================================================
# Test
# ============================================================================

if __name__=='__main__':
    setLevel(logging.INFO)

    info('test0 1==%s' % gCal.add('2004-12-31'));
    info('test0 0==%s' % gCal.add('20041231'));

    info('test1 0==%s' % gCal.isopen('2005-01-01'));
    info('test2 0==%s' % gCal.isopen('20050101'));
    info('test3 1==%s' % gCal.isopen('20050104'));

    info('test4 0==%s' % gCal.isopen('20041231'));      # closed in default market (PAR)
    info('test4 1==%s' % gCal.isopen('20041231','TOK'));# but open in other market

    info('test5 20050104==%s' % Datation('20050104'));
    info('test6 20050105==%s' % Datation('20050104').nextopen());
    info('test7 20050103==%s' % Datation('20050104').prevopen());
    info('test8 20041230==%s' % Datation('20050103').prevopen());
    info('test9 20041230==%s' % Datation('20041231').prevopen());

    info('test10 20040130>20040101 == %s' % (Datation('20040130')>Datation('20040101')))
    info('test10 20040101>20040130 == %s' % (Datation('20040101')>Datation('20040130')))
    info('test10 20040227>20040101 == %s' % (Datation('20040227')>Datation('20040101')))
    info('test10 20040101>20040227 == %s' % (Datation('20040101')>Datation('20040227')))

    info('test11 20050814 index is %d == -1' % (Datation('20050814').index()))
    info('test11 20050815 index is %d != -1' % (Datation('20050815').index()))
    info('test11 20050816 index is %d != -1' % (Datation('20050816').index()))
    info('test11 20051231 index is %d == -1' % (Datation('20051231').index()))
    info('test11 20060101 index is %d == -1' % (Datation('20060101').index()))
    info('test11 20060102 index is %d != -1' % (Datation('20060102').index()))

    print 'lastindex = %d' % gCal.lastindex()

    ts = '20050816'
    dt = datetime(*time.strptime(ts.strip('"'), '%Y%m%d')[:6])
    print '%s = %s' % (ts,dt)

    ts = '2005-08-16'
    dt = datetime(*time.strptime(ts.strip('"'), '%Y-%m-%d')[:6])
    print '%s = %s' % (ts,dt)

# ============================================================================
# That's all folks !
# ============================================================================
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.