itrade_portfolio.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_portfolio.py
#!/usr/bin/env python
# ============================================================================
# Project Name : iTrade
# Module Name  : itrade_portfolio.py
#
# Description: Portfolio & Operations
#
# 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
# 2004-02-20    dgil  Wrote it from scratch
# ============================================================================

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

# python system
from datetime import *
import logging

# iTrade system
from itrade_logging import *
import itrade_datation
from itrade_quotes import quotes,QUOTE_CASH,QUOTE_CREDIT,QUOTE_BOTH
from itrade_matrix import *
from itrade_local import message,getLang
import itrade_csv
from itrade_currency import currency2symbol,currencies,convert
from itrade_vat import country2vat
from itrade_login import getLoginConnector
from itrade_market import getDefaultIndice

# ============================================================================
# Operation
#
#   TYPE:
#       A/B buy (trade)     i.e. accumulate (SRD/x)
#       R/S sell (trade)    i.e. reduce (SRD/x)
#       C   credit (cash)   i.e. deposit
#       D   debit (cash)    i.e. withdrawal
#       F   fee (cash)
#       I   interest (cash)
#       X   split (divisor)
#       Y   detachment of coupon (cash on trade) - non taxable
#       Z   dividend (cash on trade) - taxable
#       L   liquidation     i.e. SRD
#       Q   dividend with shares
#       W   register shares
#
# ============================================================================

OPERATION_BUY       = 'B'
OPERATION_BUY_SRD   = 'A'
OPERATION_SELL      = 'S'
OPERATION_SELL_SRD  = 'R'
OPERATION_CREDIT    = 'C'
OPERATION_DEBIT     = 'D'
OPERATION_FEE       = 'F'
OPERATION_INTEREST  = 'I'
OPERATION_SPLIT     = 'X'
OPERATION_DETACHMENT= 'Y'
OPERATION_DIVIDEND  = 'Z'
OPERATION_LIQUIDATION  = 'L'
OPERATION_QUOTE = 'Q'
OPERATION_REGISTER = 'W'

operation_desc = {
    OPERATION_BUY       : 'Portfolio_buy',
    OPERATION_BUY_SRD   : 'Portfolio_buy_srd',
    OPERATION_SELL      : 'Portfolio_sell',
    OPERATION_SELL_SRD  : 'Portfolio_sell_srd',
    OPERATION_CREDIT    : 'Portfolio_credit',
    OPERATION_DEBIT     : 'Portfolio_debit',
    OPERATION_FEE       : 'Portfolio_fee',
    OPERATION_INTEREST  : 'Portfolio_interest',
    OPERATION_SPLIT     : 'Portfolio_split',
    OPERATION_DETACHMENT: 'Portfolio_detachment',
    OPERATION_DIVIDEND  : 'Portfolio_dividend',
    OPERATION_LIQUIDATION : 'Portfolio_liquidation',
    OPERATION_QUOTE     : 'Portfolio_quote',
    OPERATION_REGISTER  : 'Portfolio_register'
}

operation_cash = {
    OPERATION_BUY       : False,
    OPERATION_BUY_SRD   : False,
    OPERATION_SELL      : False,
    OPERATION_SELL_SRD  : False,
    OPERATION_CREDIT    : True,
    OPERATION_DEBIT     : True,
    OPERATION_FEE       : False,
    OPERATION_INTEREST  : False,
    OPERATION_SPLIT     : False,
    OPERATION_DETACHMENT: False,
    OPERATION_DIVIDEND  : False,
    OPERATION_LIQUIDATION : False,
    OPERATION_REGISTER : False,
    OPERATION_QUOTE : False
}

operation_quote = {
    OPERATION_BUY       : True,
    OPERATION_BUY_SRD   : True,
    OPERATION_SELL      : True,
    OPERATION_SELL_SRD  : True,
    OPERATION_CREDIT    : False,
    OPERATION_DEBIT     : False,
    OPERATION_FEE       : False,
    OPERATION_INTEREST  : False,
    OPERATION_SPLIT     : True,
    OPERATION_DETACHMENT: True,
    OPERATION_DIVIDEND  : True,
    OPERATION_LIQUIDATION  : True,
    OPERATION_REGISTER  : True,
    OPERATION_QUOTE     : True
}

operation_number = {
    OPERATION_BUY       : True,
    OPERATION_BUY_SRD   : True,
    OPERATION_SELL      : True,
    OPERATION_SELL_SRD  : True,
    OPERATION_CREDIT    : False,
    OPERATION_DEBIT     : False,
    OPERATION_FEE       : False,
    OPERATION_INTEREST  : False,
    OPERATION_SPLIT     : False,
    OPERATION_DETACHMENT: False,
    OPERATION_DIVIDEND  : False,
    OPERATION_LIQUIDATION  : True,
    OPERATION_REGISTER  : True,
    OPERATION_QUOTE     : True,
}

operation_sign = {
    OPERATION_BUY       : '-',
    OPERATION_BUY_SRD   : '-',
    OPERATION_SELL      : '+',
    OPERATION_SELL_SRD  : '+',
    OPERATION_CREDIT    : '+',
    OPERATION_DEBIT     : '-',
    OPERATION_FEE       : '-',
    OPERATION_INTEREST  : '+',
    OPERATION_SPLIT     : ' ',
    OPERATION_DETACHMENT: '+',
    OPERATION_DIVIDEND  : '+',
    OPERATION_LIQUIDATION  : '+',
    OPERATION_REGISTER  : '~',
    OPERATION_QUOTE     : ' '
}

operation_apply = {
    OPERATION_BUY       : True,
    OPERATION_BUY_SRD   : True,
    OPERATION_SELL      : True,
    OPERATION_SELL_SRD  : True,
    OPERATION_CREDIT    : False,
    OPERATION_DEBIT     : False,
    OPERATION_FEE       : False,
    OPERATION_INTEREST  : False,
    OPERATION_SPLIT     : False,
    OPERATION_DETACHMENT: True,
    OPERATION_DIVIDEND  : False,
    OPERATION_LIQUIDATION  : True,
    OPERATION_REGISTER  : True,
    OPERATION_QUOTE     : True
}

operation_srd = {
    OPERATION_BUY       : False,
    OPERATION_BUY_SRD   : True,
    OPERATION_SELL      : False,
    OPERATION_SELL_SRD  : True,
    OPERATION_CREDIT    : False,
    OPERATION_DEBIT     : False,
    OPERATION_FEE       : False,
    OPERATION_INTEREST  : False,
    OPERATION_SPLIT     : False,
    OPERATION_DETACHMENT: False,
    OPERATION_DIVIDEND  : False,
    OPERATION_LIQUIDATION  : True,
    OPERATION_REGISTER  : False,
    OPERATION_QUOTE     : False
}

operation_incl_taxes = {
    OPERATION_BUY       : True,
    OPERATION_BUY_SRD   : True,
    OPERATION_SELL      : True,
    OPERATION_SELL_SRD  : True,
    OPERATION_CREDIT    : True,
    OPERATION_DEBIT     : True,
    OPERATION_FEE       : True,
    OPERATION_INTEREST  : True,
    OPERATION_SPLIT     : True,
    OPERATION_DETACHMENT: True,
    OPERATION_DIVIDEND  : True,
    OPERATION_LIQUIDATION  : False,
    OPERATION_REGISTER  : False,
    OPERATION_QUOTE     : True
}

class Operation(object):
    def __init__(self,d,t,m,v,e,n,vat,ref):

        # decode the date (string) to convert to date
        if isinstance(d,date):
            self.m_date = d
        elif d[4]=='-':
            debug('Operation::__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('Operation::__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]))

        self.m_type = t
        self.m_value = float(v)
        self.m_number = long(n)
        self.m_expenses = float(e)
        self.m_vat = float(vat)
        self.m_ref = ref

        # support key or name or bad value
        if self.isQuote():
            # m : could be isin (old format) or key (new format)
            self.m_quote = quotes.lookupKey(m)
            if not self.m_quote:
                self.m_quote = quotes.lookupTicker(m)
                if self.m_quote:
                    self.m_name = self.m_quote.name()
                else:
                    lst = quotes.lookupISIN(m)
                    if len(lst)>0:
                        self.m_quote = lst[0]
                        self.m_name = self.m_quote.name()
                    else:
                        # bad name : keep it :-(
                        self.m_name = m
            else:
                self.m_name = self.m_quote.name()
        else:
            # not a quote : keep the label
            self.m_quote = None
            self.m_name = m

        #print 'Operation(): quote=%s name=%s' % (self.m_quote,self.m_name)

    def __repr__(self):
        if self.m_quote:
            return '%s;%s;%s;%f;%f;%d;%f' % (self.m_date, self.m_type, self.m_quote.key(), self.m_value, self.m_expenses, self.m_number, self.m_vat)
        else:
            return '%s;%s;%s;%f;%f;%d;%f' % (self.m_date, self.m_type, self.m_name, self.m_value, self.m_expenses, self.m_number, self.m_vat)

    def ref(self):
        return self.m_ref

    def nv_value(self):
        return self.m_value

    def sv_value(self):
        return '%.2f' % self.nv_value()

    def nv_expenses(self):
        return self.m_expenses

    def sv_expenses(self):
        return '%.2f' % self.nv_expenses()

    def nv_vat(self):
        return self.m_vat

    def sv_vat(self):
        return '%.2f' % self.nv_vat()

    def nv_number(self):
        if operation_number.has_key(self.m_type) and operation_number[self.m_type]:
            return self.m_number
        else:
            return 0

    def sv_number(self):
        return '%6d' % self.nv_number()

    def type(self):
        return self.m_type

    def isSRD(self):
        if operation_srd.has_key(self.m_type):
            return operation_srd[self.m_type]
        else:
            return False

    def setType(self,nt):
        self.m_type = nt
        return self.m_type

    def name(self):
        if self.m_name: return self.m_name
        return ""

    def date(self):
        return self.m_date

    def sv_date(self):
        return self.date().strftime('%x')

    def setDate(self,nd):
        self.m_date = nd
        return self.m_date

    def quote(self):
        if self.isQuote():
            return self.m_quote
        else:
            raise TypeError("quote(): operation::type() shall be S or B or Y or Z")

    def operation(self):
        if operation_desc.has_key(self.m_type):
            return message(operation_desc[self.m_type])
        else:
            return '? (%s)' % self.m_type

    def isCash(self):
        if operation_cash.has_key(self.m_type):
            return operation_cash[self.m_type]
        return self.isQuote()

    def isQuote(self):
        if operation_quote.has_key(self.m_type):
            return operation_quote[self.m_type]
        else:
            return False

    def sign(self):
        if operation_sign.has_key(self.m_type):
            return operation_sign[self.m_type]
        else:
            return '?'

    def description(self):
        if self.isQuote():
            if self.m_quote:
                return '%s (%s)' % (self.name(),self.m_quote.ticker())
            else:
                return '%s (?)' % self.name()
        else:
            return self.name()

    def apply(self,d=None):
        if self.m_type == OPERATION_SELL:
            if self.m_quote:
                debug('sell %s' % self.m_quote)
                max = self.m_quote.nv_number(QUOTE_CASH)
                if self.m_number>max:
                    self.m_number = max
                self.m_quote.sell(self.m_number,QUOTE_CASH)
        elif self.m_type == OPERATION_BUY:
            if self.m_quote:
                debug('buy %s' % self.m_quote)
                self.m_quote.buy(self.m_number,self.m_value,QUOTE_CASH)
        elif self.m_type == OPERATION_SELL_SRD:
            if self.m_quote:
                debug('sell SRD %s' % self.m_quote)
                max = self.m_quote.nv_number(QUOTE_CREDIT)
                if self.m_number>max:
                    self.m_number = max
                self.m_quote.sell(self.m_number,QUOTE_CREDIT)
        elif self.m_type == OPERATION_BUY_SRD:
            if self.m_quote:
                debug('buy SRD %s' % self.m_quote)
                self.m_quote.buy(self.m_number,self.m_value,QUOTE_CREDIT)
        elif self.m_type == OPERATION_QUOTE:
            if self.m_quote:
                debug('dividend/shares %s' % self.m_quote)
                self.m_quote.buy(self.m_number,0.0,QUOTE_CASH)
        elif self.m_type == OPERATION_REGISTER:
            if self.m_quote:
                debug('register/shares %s' % self.m_quote)
                self.m_quote.buy(self.m_number,self.m_value,QUOTE_CASH)
        elif self.m_type == OPERATION_DETACHMENT:
            if self.m_quote:
                debug('detachment %s / %d' % (self.m_quote,self.m_value))
                self.m_quote.buy(0,-self.m_value,QUOTE_CASH)
        elif self.m_type == OPERATION_LIQUIDATION:
            if self.m_quote:
                debug('liquidation %s / %d' % (self.m_quote,self.m_value))
                self.m_quote.transfertTo(self.m_number,self.m_expenses,QUOTE_CASH)

    def undo(self,d=None):
        if self.m_type == OPERATION_SELL:
            if self.m_quote:
                debug('undo-sell %s' % self.m_quote)
                self.m_quote.buy(self.m_number,self.m_value,QUOTE_CASH)
        elif self.m_type == OPERATION_BUY:
            if self.m_quote:
                debug('undo-buy %s' % self.m_quote)
                self.m_quote.sell(self.m_number,QUOTE_CASH)
        elif self.m_type == OPERATION_QUOTE:
            if self.m_quote:
                debug('undo-dividend/share %s' % self.m_quote)
                self.m_quote.sell(self.m_number,QUOTE_CASH)
        elif self.m_type == OPERATION_REGISTER:
            if self.m_quote:
                debug('undo-register %s' % self.m_quote)
                self.m_quote.sell(self.m_number,QUOTE_CASH)
        elif self.m_type == OPERATION_BUY_SRD:
            if self.m_quote:
                debug('undo-buy SRD %s' % self.m_quote)
                self.m_quote.sell(self.m_number,QUOTE_CREDIT)
        elif self.m_type == OPERATION_SELL_SRD:
            if self.m_quote:
                debug('undo-sell SRD %s' % self.m_quote)
                self.m_quote.buy(self.m_number,self.m_value,QUOTE_CREDIT)
        elif self.m_type == OPERATION_DETACHMENT:
            if self.m_quote:
                debug('undo-detachment %s' % self.m_quote)
                self.m_quote.buy(0,self.m_value,QUOTE_CASH)
        elif self.m_type == OPERATION_LIQUIDATION:
            if self.m_quote:
                debug('undo-liquidation %s / %d' % self.m_quote)
                self.m_quote.transfertTo(self.m_number,self.m_expenses,QUOTE_CREDIT)

    def nv_pvalue(self):
        if self.m_quote:
            if self.m_type == OPERATION_SELL:
                    return self.m_value - (self.m_quote.nv_pru(QUOTE_CASH) * self.m_number)
            if self.m_type == OPERATION_SELL_SRD:
                    return self.m_value - (self.m_quote.nv_pru(QUOTE_CREDIT) * self.m_number)
        return 0

    def sv_pvalue(self):
        return '%.2f' % self.nv_pvalue()

def isOperationTypeAQuote(type):
    if operation_quote.has_key(type):
        return operation_quote[type]
    else:
        return False

def isOperationTypeIncludeTaxes(type):
    if operation_incl_taxes.has_key(type):
        return operation_incl_taxes[type]
    else:
        return True

def isOperationTypeHasShareNumber(type):
    if operation_number.has_key(type):
        return operation_number[type]
    else:
        return False

def signOfOperationType(type):
    if operation_sign.has_key(type):
        return operation_sign[type]
    else:
        return ' '

# ============================================================================
# Operations : list of Operation
# ============================================================================
#
# CSV File format :
#
#   DATE;TYPE;NAME;VALUE;EXPENSES;NUMBER;VAT
#
#   TYPE: see OPERATION_xx
#
# ============================================================================

class Operations(object):
    def __init__(self,portfolio):
        debug('Operations:__init__(%s)' % portfolio)
        self.m_operations = {}
        self.m_portfolio = portfolio
        self.m_ref = 0

    def portfolio(self):
        return self.m_portfolio

    def list(self):
        items = self.m_operations.values()
        nlist = [(x.date(), x) for x in items]
        nlist.sort()
        nlist = [val for (key, val) in nlist]
        #print nlist
        return nlist

    def load(self,infile=None):
        infile = itrade_csv.read(infile,os.path.join(itrade_config.dirUserData,'default.operations.txt'))
        if infile:
            # scan each line to read each trade
            for eachLine in infile:
                item = itrade_csv.parse(eachLine,7)
                if item:
                    self.add(item,False)

    def save(self,outfile=None):
        itrade_csv.write(outfile,os.path.join(itrade_config.dirUserData,'default.operations.txt'),self.m_operations.values())

    def add(self,item,bApply):
        debug('Operations::add() before: 0:%s , 1:%s , 2:%s , 3:%s , 4:%s , 5:%s' % (item[0],item[1],item[2],item[3],item[4],item[5]))
        ll = len(item)
        if ll>=7:
            vat = item[6]
        else:
            vat = self.m_portfolio.vat()
        op = Operation(item[0],item[1],item[2],item[3],item[4],item[5],vat,self.m_ref)
        self.m_operations[self.m_ref] = op
        if bApply:
            op.apply()
        debug('Operations::add() after: %s' % self.m_operations)
        self.m_ref = self.m_ref + 1
        return op.ref()

    def remove(self,ref,bUndo):
        if bUndo:
            self.m_operations[ref].undo()
        del self.m_operations[ref]

    def get(self,ref):
        return self.m_operations[ref]

# ============================================================================
# Portfolio
# ============================================================================
#
#   filename
#   name            name displayed for the user
#   accountref      account reference number
#   market          principal market traded by this portfolio
# ============================================================================

class Portfolio(object):

    def __init__(self,filename='default',name='<Portfolio>',accountref='000000000',market='EURONEXT',currency='EUR',vat=1.0,term=3,risk=5,indice='FR0003500008'):
        debug('Portfolio::__init__ fn=%s name=%s account=%s' % (filename,name,accountref))

        self.m_filename = filename
        self.m_name = name
        self.m_accountref = accountref
        self.m_market = market
        self.m_currency = currency
        self.m_vat = vat
        self.m_term = term
        self.m_risk = risk
        self.m_indice = indice
        self._init_()

    # portfolio name
    def name(self):
        return self.m_name

    # market name ('EURONEXT')
    def market(self):
        return self.m_market

    # currency code (i.e. EUR)
    def currency(self):
        return self.m_currency

    # main indice (CAC40 : FR0003500008)
    def indice(self):
        return self.m_indice

    # vat (i.e. 1.196 for France)
    def vat(self):
        return self.m_vat

    # investment term period (in month)
    def term(self):
        return self.m_term

    # risk level (integer xx%) per line of investment
    def risk(self):
        return self.m_risk

    # symbol for the currency in use
    def currency_symbol(self):
        return currency2symbol(self.m_currency)

    def __repr__(self):
        return '%s;%s;%s;%s;%s;%f;%d;%d;%s' % (self.m_filename,self.m_name,self.m_accountref,self.m_market,self.m_currency,self.m_vat,self.m_term,self.m_risk,self.m_indice)

    def filenamepath(self,portfn,fn):
        return os.path.join(itrade_config.dirUserData,'%s.%s.txt' % (portfn,fn))

    def filepath(self,fn):
        return os.path.join(itrade_config.dirUserData,'%s.%s.txt' % (self.filename(),fn))

    def filename(self):
        return self.m_filename

    def key(self):
        return self.m_filename.lower()

    def accountref(self):
        return self.m_accountref

    def operations(self):
        return self.m_operations

    def date(self):
        return self.m_date

    # ---[ initialise internal structure ]-------------------------------------

    def _init_(self):
        self.m_operations = Operations(self)
        # __fee self.m_fees = Fees(self)

        # indexed by gCal index
        self.m_inDate = {}          # date
        self.m_inCash = {}          # cash available
        self.m_inCredit = {}        # credit available (SRD)
        self.m_inBuy = {}           # buy
        self.m_inValue = {}         # value available (not including cash)
        self.m_inInvest = {}        # cash investment cumulation
        self.m_inExpenses = {}      # expenses cumulation
        self.m_inTransfer = {}      # transfer cumulation

        # first cell
        self.m_inDate[0] = itrade_datation.gCal.date(0)
        self.m_inCash[0] = 0.0
        self.m_inCredit[0] = 0.0
        self.m_inBuy[0] = 0.0
        self.m_inValue[0] = 0.0
        self.m_inInvest[0] = 0.0
        self.m_inExpenses[0] = 0.0
        self.m_inTransfer[0] = 0.0

        # cumulated value
        self.reset()

    # ---[ reset some fields before calculation ]------------------------------

    def reset(self):
        self.m_cCash = 0.0
        self.m_cCredit = 0.0
        self.m_cDIRBuy = 0.0
        self.m_cSRDBuy = 0.0
        self.m_cDIRValue = 0.0
        self.m_cSRDValue = 0.0
        self.m_cInvest = 0.0

        # year dependent
        self.m_cExpenses = 0.0
        self.m_cTransfer = 0.0
        self.m_cTaxable = 0.0
        self.m_cAppreciation = 0.0

    # ---[ reinit the porfolio, associated services and quotes ]---------------

    def reinit(self):
        debug('Portfolio::%s::reinit' %(self.name()))
        self.logoutFromServices()
        quotes.reinit()
        self._init_()

    # ---[ File management for the porfolio ]----------------------------------

    def remove(self):
        # remove all files used by the portfolio

        fn = self.filepath('operations')
        try:
            os.remove(fn)
        except OSError:
            pass
        fn = self.filepath('matrix')
        try:
            os.remove(fn)
        except OSError:
            pass
        fn = self.filepath('fees')
        try:
            os.remove(fn)
        except OSError:
            pass
        fn = self.filepath('stops')
        try:
            os.remove(fn)
        except OSError:
            pass

    def rename(self,nname):
        # rename all files used by the portfolio

        fn = self.filepath('operations')
        nfn = self.filenamepath(nname,'operations')
        try:
            os.rename(fn,nfn)
        except OSError:
            pass
        fn = self.filepath('matrix')
        nfn = self.filenamepath(nname,'matrix')
        try:
            os.rename(fn,nfn)
        except OSError:
            pass
        fn = self.filepath('fees')
        nfn = self.filenamepath(nname,'fees')
        try:
            os.rename(fn,nfn)
        except OSError:
            pass
        fn = self.filepath('stops')
        nfn = self.filenamepath(nname,'stops')
        try:
            os.rename(fn,nfn)
        except OSError:
            pass
        self.m_filename = nname

    # ---[ load, save and apply Rules ] ---------------------------------------
    """# __fee
    def loadFeesRules(self):
        fn = self.filepath('fees')
        self.m_fees.load(fn)

    def saveFeesRules(self):
        fn = self.filepath('fees')
        self.m_fees.save(fn)

    def applyFeeRules(self,v,all=True):
        fee = 0.0
        for eachFee in self.m_fees.list():
            fee = fee + eachFee.nv_fee(v)
            if fee and all:
                # first rule apply -> return fee
                return fee
        # no rule apply -> no fee
        return fee
     """
    # ---[ load, save stops ] -------------------------------------------------

    def loadStops(self):
        fn = self.filepath('stops')
        quotes.loadStops(fn)

    def saveStops(self):
        fn = self.filepath('stops')
        quotes.saveStops(fn)

    # ---[ load, save global properties ] -------------------------------------

    def loadProperties(self):
        quotes.loadProperties()

    def saveProperties(self):
        quotes.saveProperties()

    # ---[ load, save and apply Operations ] ----------------------------------

    def loadOperations(self):
        fn = self.filepath('operations')
        self.m_operations.load(fn)

    def saveOperations(self):
        fn = self.filepath('operations')
        self.m_operations.save(fn)

    def applyOperations(self,d=None):
        debug('applyOperations date<=%s' % d)
        for eachOp in self.m_operations.list():
            debug('applyOperations: %s' % eachOp)
            if d==None or d>=eachOp.date():
                typ = eachOp.type()
                if operation_apply.has_key(typ) and operation_apply[typ]:
                    eachOp.apply(d)
            else:
                info('ignore %s' % (eachOp.name()))

    # --- [ manage login to services ] ----------------------------------------

    def loginToServices(self,quote=None):

        def login(quote):
            name = quote.liveconnector(bForceLive=True).name()
            #print 'loginToServices:',quote.ticker(),name
            if not maperr.has_key(name):
                con = getLoginConnector(name)
                if con:
                    if not con.logged():
                        print 'login to service :',name
                        maperr[name] = con.login()

        if itrade_config.isConnected():
            # temp map
            maperr = {}

            # log to service
            if quote:
                login(quote)
            else:
                for eachQuote in quotes.list():
                    if eachQuote.isMatrix():
                        login(eachQuote)

    def logoutFromServices(self):
        if itrade_config.isConnected():
            # temp map
            maperr = {}

            # log to service
            for eachQuote in quotes.list():
                if eachQuote.isMatrix():
                    name = eachQuote.liveconnector().name()
                    if not maperr.has_key(name):
                        con = getLoginConnector(name)
                        if con:
                            if con.logged():
                                print 'logout from service :',name
                                maperr[name] = con.logout()

    # --- [ manage multi-currency on the portfolio ] --------------------------

    def setupCurrencies(self):
        currencies.reset()
        for eachQuote in quotes.list():
            if eachQuote.isMatrix():
                currencies.inuse(self.m_currency,eachQuote.currency(),bInUse=True)

    def is_multicurrencies(self):
        for eachQuote in quotes.list():
            if eachQuote.isMatrix():
                if eachQuote.currency()!=self.m_currency:
                    return True
        return False

    # --- [ compute the operations ] ------------------------------------------

    def sameyear(self,op,cd=None):
        if cd==None:
            cd = date.today().year
        if cd == op.date().year:
            return True
        else:
            return False

    def computeOperations(self,cd=None):
        self.reset()
        for eachOp in self.m_operations.list():
            if eachOp.type() == OPERATION_CREDIT:
                debug('credit %s : + %f' % (eachOp.name(),eachOp.nv_value()))
                self.m_cCash = self.m_cCash + eachOp.nv_value()
                self.m_cInvest = self.m_cInvest + eachOp.nv_value()
                if self.sameyear(eachOp,cd):
                    self.m_cExpenses = self.m_cExpenses + eachOp.nv_expenses()
            elif eachOp.type() == OPERATION_DEBIT:
                debug('debit %s : - %f' % (eachOp.name(),eachOp.nv_value()))
                self.m_cCash = self.m_cCash - eachOp.nv_value()
                # __x self.m_cInvest = self.m_cInvest - eachOp.nv_value()
                if self.sameyear(eachOp,cd):
                    self.m_cExpenses = self.m_cExpenses + eachOp.nv_expenses()
            elif eachOp.type() == OPERATION_BUY:
                debug('buy %s/%s : %d for %f' % (eachOp.name(),eachOp.quote(),eachOp.nv_number(),eachOp.nv_value()))
                self.m_cCash = self.m_cCash - eachOp.nv_value()
                if self.sameyear(eachOp,cd):
                    self.m_cExpenses = self.m_cExpenses + eachOp.nv_expenses()
            elif eachOp.type() == OPERATION_BUY_SRD:
                debug('buy SRD %s/%s : %d for %f' % (eachOp.name(),eachOp.quote(),eachOp.nv_number(),eachOp.nv_value()))
                self.m_cCredit = self.m_cCredit + eachOp.nv_value()
                if self.sameyear(eachOp,cd):
                    self.m_cExpenses = self.m_cExpenses + eachOp.nv_expenses()
            elif eachOp.type() == OPERATION_SELL:
                debug('sell %s/%s : %d for %f' % (eachOp.name(),eachOp.quote(),eachOp.nv_number(),eachOp.nv_value()))
                self.m_cCash = self.m_cCash + eachOp.nv_value()
                if self.sameyear(eachOp,cd):
                    self.m_cExpenses = self.m_cExpenses + eachOp.nv_expenses()
                    self.m_cTransfer = self.m_cTransfer + eachOp.nv_value() + eachOp.nv_expenses()
                    self.m_cTaxable = self.m_cTaxable + eachOp.nv_pvalue()
                    self.m_cAppreciation = self.m_cAppreciation + eachOp.nv_pvalue()
            elif eachOp.type() == OPERATION_SELL_SRD:
                debug('sell SRD %s/%s : %d for %f' % (eachOp.name(),eachOp.quote(),eachOp.nv_number(),eachOp.nv_value()))
                self.m_cCredit = self.m_cCredit - eachOp.nv_value()
                if self.sameyear(eachOp,cd):
                    self.m_cExpenses = self.m_cExpenses + eachOp.nv_expenses()
                    self.m_cTransfer = self.m_cTransfer + eachOp.nv_value() + eachOp.nv_expenses()
            elif eachOp.type() == OPERATION_FEE:
                debug('fee %s: %f' % (eachOp.name(),eachOp.nv_value()))
                self.m_cCash = self.m_cCash - eachOp.nv_value()
                if self.sameyear(eachOp,cd):
                    self.m_cExpenses = self.m_cExpenses + eachOp.nv_expenses()
            elif eachOp.type() == OPERATION_LIQUIDATION:
                debug('liquidation %s: %f' % (eachOp.name(),eachOp.nv_value()))
                self.m_cCash = self.m_cCash + eachOp.nv_value()
                self.m_cCredit = self.m_cCredit + (eachOp.nv_value() + eachOp.nv_expenses())
                if self.sameyear(eachOp,cd):
                    self.m_cExpenses = self.m_cExpenses + eachOp.nv_expenses()
                    self.m_cTaxable = self.m_cTaxable + eachOp.nv_value()
                    self.m_cAppreciation = self.m_cAppreciation + eachOp.nv_value()
                    quote = eachOp.quote()
                    if quote:
                        pv = eachOp.nv_number() * quote.nv_pru(QUOTE_CREDIT)
                        self.m_cTaxable = self.m_cTaxable + pv
                        self.m_cAppreciation = self.m_cAppreciation + pv
            elif eachOp.type() == OPERATION_INTEREST:
                debug('interest %s : %f' % (eachOp.name(),eachOp.nv_value()))
                self.m_cCash = self.m_cCash + eachOp.nv_value()
                if self.sameyear(eachOp,cd):
                    self.m_cExpenses = self.m_cExpenses + eachOp.nv_expenses()
                    #self.m_cTaxable = self.m_cTaxable + eachOp.nv_value()
                    self.m_cAppreciation = self.m_cAppreciation + eachOp.nv_value()
            elif eachOp.type() == OPERATION_DETACHMENT:
                debug('detach %s/%s : %f' % (eachOp.name(),eachOp.quote(),eachOp.nv_value()))
                self.m_cCash = self.m_cCash + eachOp.nv_value()
                if self.sameyear(eachOp,cd):
                    self.m_cExpenses = self.m_cExpenses + eachOp.nv_expenses()
                    #self.m_cTaxable = self.m_cTaxable + eachOp.nv_value()
                    self.m_cAppreciation = self.m_cAppreciation + eachOp.nv_value()
            elif eachOp.type() == OPERATION_DIVIDEND:
                debug('dividend %s/%s : %f' % (eachOp.name(),eachOp.quote(),eachOp.nv_value()))
                self.m_cCash = self.m_cCash + eachOp.nv_value()
                if self.sameyear(eachOp,cd):
                    self.m_cExpenses = self.m_cExpenses + eachOp.nv_expenses()
                    self.m_cTaxable = self.m_cTaxable + eachOp.nv_value()
                    self.m_cAppreciation = self.m_cAppreciation + eachOp.nv_value()
            elif eachOp.type() == OPERATION_QUOTE:
                debug('dividend/share %s/%s : %f' % (eachOp.name(),eachOp.quote(),eachOp.nv_value()))
                pass
            elif eachOp.type() == OPERATION_REGISTER:
                debug('register/share %s/%s : %f' % (eachOp.name(),eachOp.quote(),eachOp.nv_value()))
                self.m_cInvest = self.m_cInvest + eachOp.nv_value()
            else:
                raise TypeError("computeOperations(): operation::type() unknown %s",eachOp.type())

    # --- [ compute the value ] -----------------------------------------------

    def computeValue(self):
        self.m_cDIRValue = 0.0
        self.m_cSRDValue = 0.0
        for eachQuote in quotes.list():
            if eachQuote.isTraded():
                self.m_cDIRValue = self.m_cDIRValue + eachQuote.nv_pv(self.m_currency,QUOTE_CASH)
                self.m_cSRDValue = self.m_cSRDValue + eachQuote.nv_pv(self.m_currency,QUOTE_CREDIT)

    def computeBuy(self):
        self.m_cDIRBuy = 0.0
        self.m_cSRDBuy = 0.0
        for eachQuote in quotes.list():
            if eachQuote.isTraded():
                self.m_cDIRBuy = self.m_cDIRBuy + eachQuote.nv_pr(QUOTE_CASH)
                self.m_cSRDBuy = self.m_cSRDBuy + eachQuote.nv_pr(QUOTE_CREDIT)

    # --- [ operations API ] --------------------------------------------------

    def addOperation(self,item):
        self.m_operations.add(item,True)

    def delOperation(self,ref):
        self.m_operations.remove(ref,True)

    def getOperation(self,ref):
        return self.m_operations.get(ref)

    # --- [ value API ] -------------------------------------------------------

    def nv_cash(self,currency=None):
        retval = self.m_cCash
        if currency:
            retval = convert(currency,self.m_currency,retval)
        return retval

    def nv_credit(self,currency=None):
        retval = self.m_cCredit
        if currency:
            retval = convert(currency,self.m_currency,retval)
        return retval

    def nv_invest(self):
        return self.m_cInvest

    def nv_value(self,box=QUOTE_BOTH):
        # __x compute it !
        self.computeValue()
        if box==QUOTE_CASH:
            return self.m_cDIRValue
        if box==QUOTE_CREDIT:
            return self.m_cSRDValue
        else:
            return self.m_cDIRValue + self.m_cSRDValue

    def nv_buy(self,box=QUOTE_BOTH):
        # __x compute it !
        self.computeBuy()
        if box==QUOTE_CASH:
            return self.m_cDIRBuy
        if box==QUOTE_CREDIT:
            return self.m_cSRDBuy
        else:
            return self.m_cDIRBuy + self.m_cSRDBuy

    def nv_expenses(self):
        return self.m_cExpenses

    def nv_transfer(self):
        return self.m_cTransfer

    def nv_taxable(self):
        if self.m_cTaxable < 0.0:
            return 0.0
        return self.m_cTaxable

    def nv_appreciation(self):
        return self.m_cAppreciation

    def nv_taxes(self):
        if self.nv_transfer() < itrade_config.taxesThreshold:
            return 0.0
        else:
            return self.nv_taxable() * itrade_config.taxesPercent

    def nv_perf(self,box=QUOTE_BOTH):
        #info('nv_perf=%f'% (self.nv_value(box) - self.nv_buy(box)))
        return self.nv_value(box) - self.nv_buy(box)

    def nv_perfPercent(self,box=QUOTE_BOTH):
        n = self.nv_value(box)
        b = self.nv_buy(box)
        if n==0.0 or b==0.0:
            return 0.0
        return ((n*100.0) / b) - 100

    def nv_totalValue(self):
        return self.nv_value(QUOTE_BOTH) + self.nv_cash() - self.m_cCredit

    def nv_perfTotal(self):
        return self.nv_totalValue() - self.nv_invest()

    def nv_perfTotalPercent(self):
        n = self.nv_totalValue()
        i = self.nv_invest()
        if n==0.0 or i==0.0:
            return 0.0
        return ((n*100.0) / i) - 100

    def nv_percentCash(self,box=QUOTE_BOTH):
        total = self.nv_value(box) + self.nv_cash()
        if total==0.0:
            return 0.0
        else:
            return (total-self.nv_value(box))/total*100.0

    def nv_percentQuotes(self,box=QUOTE_BOTH):
        total = self.nv_value(box) + self.nv_cash()
        if total==0.0:
            return 0.0
        else:
            return (total-self.nv_cash())/total*100.0

    # --- [ string API ] ------------------------------------------------------

    def sv_cash(self,currency=None,fmt="%.2f",bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.currency_symbol()+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_cash(),sc)

    def sv_credit(self,currency=None,fmt="%.2f",bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.currency_symbol()+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_credit(),sc)

    def sv_taxes(self,fmt="%.2f",bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.currency_symbol()+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_taxes(),sc)

    def sv_expenses(self,fmt="%.2f",bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.currency_symbol()+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_expenses(),sc)

    def sv_transfer(self,fmt="%.2f",bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.currency_symbol()+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_transfer(),sc)

    def sv_taxable(self,fmt="%.2f",bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.currency_symbol()+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_taxable(),sc)

    def sv_appreciation(self,fmt="%.2f",bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.currency_symbol()+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_appreciation(),sc)

    def sv_invest(self,fmt="%.2f",bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.currency_symbol()+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_invest(),sc)

    def sv_value(self,box=QUOTE_BOTH,fmt="%.2f",bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.currency_symbol()+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_value(box),sc)

    def sv_buy(self,box=QUOTE_BOTH,fmt="%.2f",bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.currency_symbol()+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_buy(box),sc)

    def sv_perf(self,box=QUOTE_BOTH,fmt="%.2f",bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.currency_symbol()+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_perf(box),sc)

    def sv_perfPercent(self,box=QUOTE_BOTH,fmt="%3.2f %%"):
        return fmt % self.nv_perfPercent(box)

    def sv_percentCash(self,box=QUOTE_BOTH,fmt="%3.2f %%"):
        return fmt % self.nv_percentCash(box)

    def sv_percentQuotes(self,box=QUOTE_BOTH,fmt="%3.2f %%"):
        return fmt % self.nv_percentQuotes(box)

    def sv_totalValue(self,fmt="%.2f",bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.currency_symbol()+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_totalValue(),sc)

    def sv_perfTotal(self,fmt="%.2f",bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.currency_symbol()+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_perfTotal(),sc)

    def sv_perfTotalPercent(self,fmt="%3.2f %%"):
        return fmt % self.nv_perfTotalPercent()

# ============================================================================
# Portfolios
# ============================================================================
#
# usrdata/portfolio.txt CSV File format :
#   filename;username;accountref
# ============================================================================

class Portfolios(object):
    def __init__(self):
        debug('Portfolios:__init__')
        self._init_()

    def _init_(self):
        self.m_portfolios = {}

    def reinit(self):
        debug('Portfolios::reinit')
        for eachPortfolio in self.list():
            eachPortfolio.reinit()

    def list(self):
        #items = self.m_portfolios.values()
        #nlist = [(x.filename(), x) for x in items]
        #nlist.sort()
        #nlist = [val for (key, val) in nlist]
        ##print nlist
        #return nlist
        items = self.m_portfolios.values()
        items.sort(key=Portfolio.key)
        return items

    def existPortfolio(self,fn):
        return self.m_portfolios.has_key(fn)

    def delPortfolio(self,filename):
        if not self.m_portfolios.has_key(filename):
            return False
        else:
            debug('Portfolios::delPortfolio(): %s' % self.m_portfolios[filename])
            self.m_portfolios[filename].remove()
            del self.m_portfolios[filename]
            return True

    def addPortfolio(self,filename,name,accountref,market,currency,vat,term,risk,indice):
        if self.m_portfolios.has_key(filename):
            return None
        else:
            self.m_portfolios[filename] = Portfolio(filename,name,accountref,market,currency,vat,term,risk,indice)
            debug('Portfolios::addPortfolio(): %s' % self.m_portfolios[filename])
            return self.m_portfolios[filename]

    def editPortfolio(self,filename,name,accountref,market,currency,vat,term,risk,indice):
        if not self.m_portfolios.has_key(filename):
            return None
        else:
            del self.m_portfolios[filename]
            self.m_portfolios[filename] = Portfolio(filename,name,accountref,market,currency,vat,term,risk,indice)
            debug('Portfolios::editPortfolio(): %s' % self.m_portfolios[filename])
            return self.m_portfolios[filename]

    def renamePortfolio(self,filename,newfilename):
        if not self.m_portfolios.has_key(filename):
            return None
        else:
            self.m_portfolios[filename].rename(newfilename)
            self.m_portfolios[newfilename] = self.m_portfolios[filename]
            del self.m_portfolios[filename]
            debug('Portfolios::renamePortfolio(): %s -> %s' % (filename,newfilename))
            return self.m_portfolios[newfilename]

    def portfolio(self,fn):
        if self.m_portfolios.has_key(fn):
            return self.m_portfolios[fn]
        else:
            return None

    def load(self,fn=None):
        debug('Portfolios:load()')

        # open and read the file to load these quotes information
        infile = itrade_csv.read(fn,os.path.join(itrade_config.dirUserData,'portfolio.txt'))
        if infile:
            # scan each line to read each portfolio
            for eachLine in infile:
                item = itrade_csv.parse(eachLine,6)
                if item:
                    #info('%s :: %s' % (eachLine,item))
                    vat = country2vat(getLang())
                    if len(item)>=5:
                        currency = item[4]
                        if len(item)>=6:
                            vat = float(item[5])
                        else:
                            vat = 1.0
                        if len(item)>=8:
                            term = int(item[6])
                            risk = int(item[7])
                        else:
                            term = 3
                            risk = 5
                        if len(item)>=9:
                            indice = item[8]
                        else:
                            indice = getDefaultIndice(item[3])
                    else:
                        currency = 'EUR'
                    self.addPortfolio(item[0],item[1],item[2],item[3],currency,vat,term,risk,indice)

    def save(self,fn=None):
        debug('Portfolios:save()')

        # open and write the file with these quotes information
        itrade_csv.write(fn,os.path.join(itrade_config.dirUserData,'portfolio.txt'),self.m_portfolios.values())

# ============================================================================
# loadPortfolio
#
#   fn    filename reference
# ============================================================================

class currentCell(object):
    def __init__(self,f):
        self.f = f

    def __repr__(self):
        return '%s' % (self.f)

def loadPortfolio(fn=None):
    # default portfolio reference
    if fn==None:
        defref = itrade_csv.read(None,os.path.join(itrade_config.dirUserData,'default.txt'))
        if defref:
            item = itrade_csv.parse(defref[0],1)
            fn = item[0]
        else:
            fn = 'default'
    debug('loadPortfolio %s',fn)

    # create the porfolio
    portfolios.reinit()
    p = portfolios.portfolio(fn)
    if p==None:
        # portfolio does not exist !
        print "Portfolio '%s' does not exist ... create it" % fn
        p = portfolios.addPortfolio(fn,fn,'noref','EURONEXT','EUR',country2vat('fr'), 3, 5,getDefaultIndice('EURONEXT'))
        portfolios.save()

    # load properties
    p.loadProperties()

    # load stops
    p.loadStops()

    # load transactions then apply them
    p.loadOperations()
    p.applyOperations()

    # load fees rules
    # __fee p.loadFeesRules()

    # save current file
    scf = {}
    scf[0] = currentCell(fn)
    itrade_csv.write(None,os.path.join(itrade_config.dirUserData,'default.txt'),scf.values())

    # return the portfolio
    return p

# ============================================================================
# newPortfolio
#
#   fn    filename reference (shall be unique)
# ============================================================================

def newPortfolio(fn=None):
    debug('newPortfolio %s',fn)

    # create the porfolio
    portfolios.reinit()
    p = portfolios.portfolio(fn)
    if p==None:
        # portfolio does not exist !
        pass

    # save current file
    scf = {}
    scf[0] = currentCell(fn)
    itrade_csv.write(None,os.path.join(itrade_config.dirUserData,'default.txt'),scf.values())

    # return the portfolio
    return p

# ============================================================================
# CommandLine : -e / evaluate portfolio
# ============================================================================

def cmdline_evaluatePortfolio(year=2006):

    print '--- load current portfolio ---'
    p = loadPortfolio()
    print '... %s:%s:%s ' % (p.filename(),p.name(),p.accountref())

    print '--- build a matrix -----------'
    m = createMatrix(p.filename(),p)

    print '--- liveupdate this matrix ---'
    m.update()
    m.saveTrades()

    print '--- evaluation ---------------'
    p.computeOperations(year)
    print ' cumul. investment  : %.2f' % p.nv_invest()
    print
    print ' total buy          : %.2f' % p.nv_buy(QUOTE_CASH)
    print ' evaluation quotes  : %.2f (%2.2f%% of portfolio)' % (p.nv_value(QUOTE_CASH),p.nv_percentQuotes(QUOTE_CASH))
    print ' evaluation cash    : %.2f (%2.2f%% of portfolio)' % (p.nv_cash(),p.nv_percentCash(QUOTE_CASH))
    print ' performance        : %.2f (%2.2f%%)' % (p.nv_perf(QUOTE_CASH),p.nv_perfPercent(QUOTE_CASH))
    print
    print ' total credit (SRD) : %.2f (==%.2f)' % (p.nv_credit(),p.nv_buy(QUOTE_CREDIT))
    print ' evaluation quotes  : %.2f (%2.2f%% of portfolio)' % (p.nv_value(QUOTE_CREDIT),p.nv_percentQuotes(QUOTE_CREDIT))
    print ' evaluation cash    : %.2f (%2.2f%% of portfolio)' % (p.nv_cash(),p.nv_percentCash(QUOTE_CREDIT))
    print ' performance        : %.2f (%2.2f%%)' % (p.nv_perf(QUOTE_CREDIT),p.nv_perfPercent(QUOTE_CREDIT))
    print
    print ' expenses (VAT, ...): %.2f' % p.nv_expenses()
    print ' total of transfers : %.2f' % p.nv_transfer()
    print ' appreciation       : %.2f' % p.nv_appreciation()
    print ' taxable amount     : %.2f' % p.nv_taxable()
    print ' amount of taxes    : %.2f' % p.nv_taxes()
    print
    print ' evaluation total   : %.2f ' % p.nv_totalValue()
    print ' global performance : %.2f (%2.2f%%)' % (p.nv_perfTotal(),p.nv_perfTotalPercent())

    return (p,m)

# ============================================================================
# Export
# ============================================================================

try:
    ignore(portfolios)
except NameError:
    portfolios = Portfolios()

# ============================================================================
# initPortfolioModule()
# ============================================================================

def initPortfolioModule():
    portfolios.load()

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

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

    initPortfolioModule()

    cmdline_evaluatePortfolio(2006)

# ============================================================================
# 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.