itrade_quotes.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_quotes.py
#!/usr/bin/env python
# ============================================================================
# Project Name : iTrade
# Module Name  : itrade_quotes.py
#
# Description: Quotes
#
# 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-01-08    dgil  Wrote it from scratch
# 2006-09-2x    dgil  New quote referencing
# ============================================================================

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

# python system
from datetime import *
import logging

# iTrade system
from itrade_logging import *
from itrade_local import message,getGroupChar
import itrade_csv
import itrade_trades
from itrade_import import *
from itrade_defs import *
from itrade_ext import *
from itrade_datation import *
from itrade_market import market2currency,compute_country,isin2market,market2place,list_of_markets,set_market_loaded,is_market_loaded
import itrade_currency

# ============================================================================
# color
# ============================================================================

QUOTE_RED = 0
QUOTE_GREEN = 1
QUOTE_NOCHANGE = 2
QUOTE_INVALID = 3

# ============================================================================
# type of quote : cash, SRD(credit) or both
# ============================================================================

QUOTE_NOTYPE    = 0
QUOTE_CASH      = 1
QUOTE_CREDIT    = 2
QUOTE_BOTH      = 3

# ============================================================================
# volume formatter
# ============================================================================

def fmtVolume(x):
    sep = getGroupChar()
    val = '%d' % x
    ret = ''
    i   = len(val)
    n   = 0
    while i>0:
        n = n + 1
        i = i - 1
        ret = val[i] + ret
        if (n%3 == 0) and (i>0):
            ret = sep+ret
    return ret

# ============================================================================
# Quote referencing
# ============================================================================

def quote_reference(isin,ticker,market,place):
    #print 'quote_reference: isin=%s ticker=%s market=%s place=%s' % (isin,ticker,market,place)
    if isin and isin!='':
        if market==None or market=='':
            lst = quotes.lookupISIN(isin)
            if len(lst)>0:
                quote = lst[0]
                market = quote.market()
                place = quote.place()
                return '%s.%s.%s' % (isin,market,place)
        else:
            if place==None or place=='':
                lst = quotes.lookupISIN(isin,market)
                if len(lst)>0:
                    quote = lst[0]
                    place = quote.place()

            return '%s.%s.%s' % (isin,market,place)

    if market==None or market=='':
        quote = quotes.lookupTicker(ticker)
        if quote:
            market = quote.market()
            place = quote.place()
        else:
            market = '?'
            place = '?'

    return '%s.%s.%s' % (ticker,market,place)

# ============================================================================
# Quote
# ============================================================================

class Quote(object):
    def __init__(self,key,isin,name,ticker,market,currency,place,country,list=QLIST_SYSTEM):
        self.m_key = key
        self.m_isin = isin
        self.m_defaultname = name
        self.m_defaultticker = ticker
        self.m_list = list

        if not place:
            self.m_place = market2place(market)
        else:
            self.m_place = place

        if not country:
            self.m_country = compute_country(isin,market,place)
        else:
            self.m_country = country

        self.m_market = market

        self.m_userliveconnector = None

        self.m_defaultimportconnector = getImportConnector(self.m_market,self.m_list,QTAG_IMPORT,self.m_place)
        if self.m_defaultimportconnector == None:
            if itrade_config.verbose:
                print 'no default import connector for %s (list:%d)' % (self,self.m_list)

        if self.m_list != QLIST_INDICES:
            if not currency:
                self.m_currency = market2currency(self.m_market)
            else:
                self.m_currency = currency
        else:
            self.m_currency = "N/A"

        # data for the connector plugin
        self.m_pluginId = None

        self._init_()

    # ---[ initialisation ]--------------------------------

    def _init_(self):
        # can be overloaded later ...
        # NB: PRU currency *is* portfolio currency
        self.m_DIR_number = 0
        self.m_DIR_pru = 0.0
        self.m_SRD_number = 0
        self.m_SRD_pru = 0.0
        self.m_SRD_accnum = 0
        self.m_SRD_prevacc = 0

        self.m_isTraded = False
        self.m_wasTraded = False
        self.m_isMonitored = False

        self.m_stoploss = 0.0
        self.m_stopwin = 0.0
        self.m_hasStops = False
        self.m_liveconnector = None
        self.m_importconnector = self.m_defaultimportconnector
        self.m_name = self.m_defaultname
        self.m_ticker = self.m_defaultticker
        self.m_symbcurr = itrade_currency.currency2symbol(self.m_currency)

        self.m_daytrades = None
        self.m_weektrades = None
        self.m_monthtrades = None

        self.m_percent = None

    def reinit(self):
        #info('%s::reinit' %(self.name()))
        self._init_()

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

    def key(self):
        return self.m_key

    def type(self):
        n = QUOTE_NOTYPE
        if self.m_DIR_number > 0:
            n = n + QUOTE_CASH
        if self.m_SRD_number > 0:
            n = n + QUOTE_BOTH
        return n

    def __str__(self):
        return self.m_key

    def __repr__(self):
        return '%s;%s;%s;%s;%s;%s;%s' % (self.m_isin, self.m_name, self.m_ticker, self.m_market, self.m_currency, self.m_place, self.m_country)

    def __hash__(self):
        return self.m_key

    def country(self):
        return self.m_country

    def currency(self):
        return self.m_currency

    def currency_symbol(self):
        return self.m_symbcurr

    def isin(self):
        return self.m_isin

    def place(self):
        return self.m_place

    def list(self):
        return self.m_list

    def name(self):
        return self.m_name

    def default_name(self):
        return self.m_defaultname

    def set_name(self,name):
        self.m_name = name

    def ticker(self):
        return self.m_ticker

    def default_ticker(self):
        return self.m_defaultticker

    def set_ticker(self,ticker):
        self.m_ticker = ticker

    def nv_number(self,box=QUOTE_BOTH):
        if box==QUOTE_CASH:
            return self.m_DIR_number
        if box==QUOTE_CREDIT:
            return self.m_SRD_number
        else:
            return self.m_DIR_number + self.m_SRD_number

    def sv_number(self,box=QUOTE_BOTH):
        return fmtVolume(self.nv_number(box))

    def nv_pru(self,box=QUOTE_BOTH):
        # return PRU in the default currency (i.e. portfolio currency)
        if box==QUOTE_CASH:
            return self.m_DIR_pru
        elif box==QUOTE_CREDIT:
            return self.m_SRD_pru
        else:
            n = self.nv_number(QUOTE_BOTH)
            if n > 0:
                return (self.nv_pr(QUOTE_CASH) + self.nv_pr(QUOTE_CREDIT)) / n
            return 0.0

    def nv_pr(self,box=QUOTE_BOTH):
        # return PR in the default currency (i.e. portfolio currency)
        return self.nv_pru(box) * self.nv_number(box)

    def sv_pru(self,box=QUOTE_BOTH,fmt="%.3f",bDispCurrency=False):
        # return PRU in the default currency (i.e. portfolio currency)
        if bDispCurrency:
            sc = ' '+self.m_symbcurr+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_pru(box),sc)

    def sv_pr(self,box=QUOTE_BOTH,fmt="%.2f",bDispCurrency=False):
        # return PR in the default currency (i.e. portfolio currency)
        if bDispCurrency:
            sc = ' '+self.m_symbcurr+' '
        else:
            sc = ''
        fmt = fmt + "%s"
        return fmt % (self.nv_pr(box),sc)

    def nv_pv(self,currency,box=QUOTE_BOTH):
        # return PV in the requested currency
        # nv_close() returns value in market currency
        cl = self.nv_close()
        if cl:
            if box==QUOTE_CASH:
                retval = cl * self.m_DIR_number
            elif box==QUOTE_CREDIT:
                retval = cl * self.m_SRD_number
            else:
                retval = cl * (self.m_DIR_number + self.m_SRD_number)
        else:
            retval = 0.0
        if currency:
            retval = itrade_currency.convert(currency,self.m_currency,retval)
        return retval

    def sv_pv(self,currency,box=QUOTE_BOTH,fmt="%.2f"):
        # return PV in the requested currency
        return fmt % self.nv_pv(currency,box)

    def nv_profit(self,currency,box=QUOTE_BOTH):
        return self.nv_pv(currency,box)-self.nv_pr(box)

    def sv_profit(self,currency,box=QUOTE_BOTH,fmt="%.2f"):
        return fmt % self.nv_profit(currency,box)

    def nv_profitPercent(self,currency,box=QUOTE_BOTH):
        # profit performance should be calculated after conversion to the portfolio currency !
        pr = self.nv_pr(box)
        if pr>0:
            return self.nv_profit(currency,box)/self.nv_pr(box)*100
        else:
            return 0.0

    def sv_profitPercent(self,currency,box=QUOTE_BOTH):
        # profit performance should be calculated after conversion to the portfolio currency !
        if self.nv_pr(box)>0:
            return "%3.2f %%" % self.nv_profitPercent(currency,box)
        else:
            return "---.-- %"

    def isTraded(self):
        return self.m_isTraded

    def wasTraded(self):
        return self.m_wasTraded

    def isMonitored(self):
        return self.m_isMonitored

    def isMatrix(self):
        return self.m_isMonitored or self.m_isTraded
        #was: return self.m_isMonitored or self.m_isTraded or self.m_wasTraded

    def descr(self):
        return '%s (%s-%s)' % (self.m_name, self.m_isin, self.m_ticker)

    def trades(self):
        return self.m_daytrades

    # ---[ market & connectors ] -------------------------------------

    def market(self):
        return self.m_market

    def delay(self):
        lc = self.liveconnector()
        if lc:
            return lc.delay()
        else:
            return 15

    def liveconnector(self,bForceLive=False,bDebug=False):
        if bForceLive:
            ret = getLiveConnector(self.m_market,self.m_list,QTAG_LIVE,self.m_place)
            if bDebug: print 'liveconnector: for live connector %s' % ret
            if ret: return ret

        if self.m_userliveconnector:
            # priority to connector selected by the user
            if bDebug: print 'liveconnector: retuns userliveconnector %s' % self.m_userliveconnector
            return self.m_userliveconnector

        if not self.m_liveconnector:
            self.m_liveconnector = getDefaultLiveConnector(self.m_market,self.m_list,self.m_place)
            if bDebug: print 'liveconnector: get liveconnector %s' % self.m_liveconnector
        if bDebug: print 'liveconnector: retuns liveconnector %s' % self.m_liveconnector
        return self.m_liveconnector

    def importconnector(self):
        return self.m_importconnector

    def user_liveconnector(self):
        if self.m_userliveconnector:
            return self.m_userliveconnector
        return self.m_liveconnector

    def default_importconnector(self):
        return self.m_defaultimportconnector

    def restore_defaultconnectors(self):
        self.m_userliveconnector = None
        #self.m_liveconnector = getDefaultLiveConnector(self.m_market,self.m_list,self.m_place)
        self.m_importconnector = getImportConnector(self.m_market,self.m_list,QTAG_IMPORT,self.m_place)
        self.m_pluginId = None

    def set_liveconnector(self,name):
        if itrade_config.verbose:
            print 'set_liveconnector %s/%s for ' % (self.key(),self.name()),self.m_market,self.m_list,QTAG_ANY,self.m_place,name
        conn = getLiveConnector(self.m_market,self.m_list,QTAG_ANY,self.m_place,name)
        if itrade_config.verbose:
            print ' returns',conn
        if conn:
            self.m_userliveconnector = conn
            self.m_pluginId = None

    def set_importconnector(self,name):
        conn = getImportConnector(self.m_market,self.m_list,QTAG_IMPORT,self.m_place,name)
        if conn:
            self.m_importconnector = conn
            self.m_pluginId = None

    def get_pluginID(self):
        return self.m_pluginId

    def set_pluginID(self,id):
        self.m_pluginId = id
        return self.m_pluginId

    # ---[ notebook of order ] ----------------------------

    def hasNotebook(self):
        lc = self.liveconnector()
        if lc:
            return lc.hasNotebook()
        else:
            return False

    def currentNotebook(self):
        if self.hasNotebook():
            return self.liveconnector().currentNotebook(self)
        else:
            return None

    # ---[ status ] ---------------------------------------

    def hasStatus(self):
        lc = self.liveconnector()
        if lc:
            return lc.hasStatus()
        else:
            return False

    def currentStatus(self):
        # current status (status,reopen,RB,RH,clock) could be :
        #   status = OK, CLOSED, SUSPEND, SUSPEND+, SUSPEND-, UNKNOWN
        #   clock = time string of status in local market time
        if self.hasStatus():
            # get the real status
            cs,r,rb,rh,cl = self.liveconnector().currentStatus(self)
            if cs=="OK" and not self.hasOpened():
                cs = "CLOSED"
            if cs=="UNKNOWN" and not self.isOpen():
                cs = "CLOSED"
            #print '>>> get real status : ',cs
            return (cs,r,rb,rh,cl)
        else:
            # generate a status
            if self.hasOpened():
                cs = "OK"
            else:
                cs = "CLOSED"
            #print '>>> generate a status : ', cs
            return (cs,"::","-","-","::")

    def sv_status(self):
        cs,r,rb,rh,cl = self.currentStatus()
        return cs

    def sv_clock(self):
        cs,r,rb,rh,cl = self.currentStatus()
        if cs=='CLOSED' or cl=="::":
            return ""
        return cl

    def sv_type_of_clock(self,bDisplayTime=False):
        if self.delay()==0:
            if bDisplayTime:
                return message('prop_islive')
            else:
                return message('prop_isslive')
        else:
            if bDisplayTime:
                return message('prop_isnotlive')%self.delay()
            else:
                return message('prop_isdiffered')

    def sv_reopen(self):
        cs,r,rb,rh,cl = self.currentStatus()
        if r=="::":
            return "-"
        return r

    def low_threshold(self):
        cs,r,rb,rh,cl = self.currentStatus()
        if rb<>"-":
            return float(rb)
        else:
            prev = self.nv_prevclose()
            if prev:
                # __x parameters given the market rules ...
                return prev - (0.1*prev)
            else:
                return 0.0

    def high_threshold(self):
        cs,r,rb,rh,cl = self.currentStatus()
        if rh<>"-":
            return float(rh)
        else:
            prev = self.nv_prevclose()
            if prev:
                # __x parameters given the market rules ...
                return prev + (0.1*prev)
            else:
                return 0.0

    def currentMeans(self):
        # means: sell,buy,last
        if self.hasStatus():
            return self.liveconnector().currentMeans(self)
        else:
            return "-","-","-"

    def sv_waq(self):
        # weighted average quotation
        s,b,l = self.currentMeans()
        return l

    # ---[ stops ] ----------------------------------------

    def setStops(self,loss,win):
        # set the stops
        self.m_stoploss = float(loss)
        self.m_stopwin = float(win)
        if itrade_config.verbose:
            info('%s::setStops %f %f' %(self.name(),self.m_stoploss,self.m_stopwin))
        self.m_hasStops = True

    def getStops(self):
        return '%s;%s;%s' % (self.key(),self.sv_stoploss(),self.sv_stopwin())

    def clrStops(self):
        # clear (remove) the stops
        self.m_stoploss = 0.0
        self.m_stopwin = 0.0
        if itrade_config.verbose:
            info('%s::clrStops' % self.name())
        self.m_hasStops = False

    def nv_stoploss(self):
        # return threshold low
        return self.m_stoploss

    def nv_stopwin(self):
        # return threshold high
        return self.m_stopwin

    def sv_stoploss(self,bDispCurrency=False):
        # return a string with optional currency
        if bDispCurrency:
            sc = ' '+self.m_symbcurr+' '
        else:
            sc = ''
        return "%.2f%s" % (self.nv_stoploss(),sc)

    def sv_stopwin(self,bDispCurrency=False):
        # return a string with optional currency
        if bDispCurrency:
            sc = ' '+self.m_symbcurr+' '
        else:
            sc = ''
        return "%.2f%s" % (self.nv_stopwin(),sc)

    def nv_riskmoney(self,currency):
        # calculate the money at risk
        sl = itrade_currency.convert(currency,self.m_currency,self.nv_stoploss())
        x = (self.nv_pru()-sl)*self.nv_number()
        if x>0:
            return x
        else:
            return 0.0

    def sv_riskmoney(self,currency,CurrencySymbolToDisplay=None):
        # return a string with optional currency
        if CurrencySymbolToDisplay:
            sc = ' '+CurrencySymbolToDisplay+' '
        else:
            sc = ''
        return "%.2f%s" % (self.nv_riskmoney(currency),sc)

    def hasStops(self):
        # return True if the quote has threshold, False otherwise
        # getting API on stops can be called only if the quote has threshold
        return self.m_hasStops

    # ---[ load or import trades / date is unique key ] ---

    def loadTrades(self,fn=None):
        #debug('Quote:loadTrades %s' % self.ticker)
        if self.m_daytrades==None:
            self.m_daytrades = itrade_trades.Trades(self)
        self.m_daytrades.load(fn)

    def importTrades(self,data,bLive):
        #debug('Quote:importTrades %s %s bLive=%s' % (self.ticker,data,bLive))
        if self.m_daytrades==None:
            self.m_daytrades = itrade_trades.Trades(self)

        data = data.split('\r\n')
        self.m_daytrades.imp(data,bLive)

        # only one line
        if bLive and len(data)>=1 and self.list()==QLIST_INDICES:
            item = itrade_csv.parse(data[0],8)
            if len(item)>7:
                # percent is included !
                self.m_percent = string.atof (item[7])

    # ---[ save or export trades / date is unique key ] ---

    def saveTrades(self,fn=None):
        if self.m_daytrades==None:
            info('Quote:saveTrades %s - no daytrades !' % self.ticker())
            return
        debug('Quote:saveTrades %s - save now !' % self.ticker())
        self.m_daytrades.save(fn)

    # ---[ update the quote from the network ] ---

    def update(self,fromdate=None,todate=None):
        #debug('update %s from:%s to:%s' % (self.ticker(),fromdate,todate))
        if self.m_daytrades==None:
            self.m_daytrades = itrade_trades.Trades(self)
            self.loadTrades()
        if fromdate==date.today() or fromdate==None:
            # import until 'yesterday' (be sure the day is or will open !)
            ajd = date.today()
            # if market is or will open:
            ajd = Datation(ajd).prevopen(self.m_market).date()
            #else:
            #   ajd = Datation(ajd).nearopen(self.m_market).date()

            # full importation ?
            tr = self.m_daytrades.lastimport()
            if tr==None:
                if itrade_config.verbose:
                    print '%s *** no trade at all ! : need to import ...' % self.key()
                if not cmdline_importQuoteFromInternet(self):
                    print 'error importing full data ...'
                    return False
            elif tr.date() != ajd:
                if itrade_config.verbose:
                    print '%s *** from = %s today = %s : need to import ...' % (self.key(),tr.date(),ajd)
                if not import_from_internet(self,tr.date(),ajd):
                    print 'error importing partial data ...'
                    return False
                self.saveTrades()

            # live update today
            if self.isOpen():
                if itrade_config.verbose:
                    print '%s / %s *** liveupdate today = %s ...' % (self.key(),self.market(),date.today())
                return liveupdate_from_internet(self)
            else:
                return True
        else:
            # history importation
            if itrade_config.verbose:
                print 'history importation for %s ' %self.key()
            if import_from_internet(self,fromdate,todate):
                #self.saveTrades()
                return True
            else:
                return False

    # ---[ operations on the quote ] ---

    def buy(self,n,m,box):
        #info('buy: %s %d %f' % (self.ticker(),n,m))
        if box==QUOTE_CASH:
            if (self.m_DIR_number + n) > 0:
                self.m_DIR_pru = ((self.m_DIR_pru * self.m_DIR_number) + m) / (self.m_DIR_number + n)
            if self.m_DIR_pru < 0.0:
                self.m_DIR_pru = 0.0
            self.m_DIR_number = self.m_DIR_number + n
        elif box==QUOTE_CREDIT:
            if (self.m_SRD_number + n) > 0:
                self.m_SRD_pru = ((self.m_SRD_pru * self.m_SRD_number) + m) / (self.m_SRD_number + n)
            if self.m_SRD_pru < 0.0:
                self.m_SRD_pru = 0.0
            self.m_SRD_number = self.m_SRD_number + n
            self.m_SRD_accnum = max(self.m_SRD_accnum,self.m_SRD_number)
            #print 'set accnum = ',self.m_SRD_accnum
        self.m_isTraded = (self.m_DIR_number>0) or (self.m_SRD_number>0)

    def sell(self,n,box):
        #info('sell: %s %d' % (self.ticker(),n))
        if box==QUOTE_CASH:
            if self.m_DIR_number < n:
                raise("negative number of shares is not possible ...")
            self.m_DIR_number = self.m_DIR_number - n
            if self.m_DIR_number <=0 :
                self.m_wasTraded = True
        elif box==QUOTE_CREDIT:
            if self.m_SRD_number < n:
                raise("short unsupported yet ...")
            self.m_SRD_number = self.m_SRD_number - n
            if self.m_SRD_number <=0 :
                self.m_wasTraded = True
        self.m_isTraded = (self.m_DIR_number>0) or (self.m_SRD_number>0)

    def transfertTo(self,n,expenses,box):
        #info('transfert: %s %d' % (self.ticker(),n))
        if box==QUOTE_CASH:
            if self.m_SRD_number < n:
                raise("negative number of shares is not possible ...")
            price = (n * self.m_SRD_pru)
            if self.m_SRD_accnum > 0:
                #print 'n=',n,'get accnum = ',self.m_SRD_accnum
                price = price + (expenses*n/self.m_SRD_accnum)
            #print 'n=',n,'price = ',price
            self.sell(n,QUOTE_CREDIT)
            self.buy(n,price,QUOTE_CASH)
            self.m_SRD_prevacc = self.m_SRD_accnum
            self.m_SRD_accnum = self.m_SRD_number
            #print 'n=',n,'reinit accnum = ',self.m_SRD_accnum
        elif box==QUOTE_CREDIT:
            if self.m_DIR_number < n:
                raise("negative number of shares is not possible ...")
            price = (n * self.m_DIR_pru)
            if self.m_SRD_prevacc > 0:
                price = price - (expenses*n/self.m_SRD_prevacc)
            self.sell(n,QUOTE_CASH)
            self.buy(n,price,QUOTE_CREDIT)
            self.m_SRD_accnum = self.m_SRD_prevacc

    # ---[ current / live values on the quote ] ---

    def index(self,d=None):
        if self.m_daytrades:
            if d==None:
                tr = self.m_daytrades.lasttrade()
            else:
                tr = self.m_daytrades.trade(d)
            if tr:
                return tr.index()
        return -1

    def lastindex(self):
        if self.m_daytrades:
            tr = self.m_daytrades.lasttrade()
            if tr:
                return tr.index()
        return -1

    def firstindex(self):
        if self.m_daytrades:
            tr = self.m_daytrades.firsttrade()
            if tr:
                return tr.index()
        return -1

    def nv_close(self,d=None):
        if self.m_daytrades:
            if d==None:
                tr = self.m_daytrades.lasttrade()
            else:
                tr = self.m_daytrades.trade(d)
            if tr:
                return tr.nv_close()
        return None

    def nv_open(self,d=None):
        if self.m_daytrades:
            if d==None:
                tr = self.m_daytrades.lasttrade()
            else:
                tr = self.m_daytrades.trade(d)
            if tr:
                return tr.nv_open()
        return None

    def nv_low(self,d=None):
        if self.m_daytrades:
            if d==None:
                tr = self.m_daytrades.lasttrade()
            else:
                tr = self.m_daytrades.trade(d)
            if tr:
                return tr.nv_low()
        return None

    def nv_high(self,d=None):
        if self.m_daytrades:
            if d==None:
                tr = self.m_daytrades.lasttrade()
            else:
                tr = self.m_daytrades.trade(d)
            if tr:
                return tr.nv_high()
        return None

    def nv_volume(self,d=None):
        if self.m_daytrades:
            if d==None:
                tr = self.m_daytrades.lasttrade()
            else:
                tr = self.m_daytrades.trade(d)
            if tr:
                return tr.nv_volume()
        return None

    def nv_prevclose(self,d=None):
        if self.m_daytrades:
            tc = self.m_daytrades.prevtrade(d)
            if tc:
                return tc.nv_close()
        return None

    def nv_unitvar(self,d=None):
        if self.m_daytrades:
            tc = self.nv_close(d)
            tp = self.nv_prevclose(d)
            if tc and tp:
                return tc - tp
        return None

    def nv_percent(self,d=None):
        if self.m_percent:
            return self.m_percent
        if self.m_daytrades:
            tc = self.nv_close(d)
            tp = self.nv_prevclose(d)
            if tc and tp:
                return ((tc/tp)*100)-100
        return None

    # ---[ same current / live data on quote but string ] ------------------

    def sv_close(self,d=None,bDispCurrency=False):
        if bDispCurrency:
            sc = ' '+self.m_symbcurr+' '
        else:
            sc = ''
        x = self.nv_close(d)
        if x!=None:
            st,re,rb,rh,cl = self.currentStatus()
            if st=='OK':
                return "%3.2f%s" % (x,sc)
            elif st=='SUSPEND+':
                return "%3.2f%s(+)" % (x,sc)
            elif st=='SUSPEND-':
                return "%3.2f%s(-)" % (x,sc)
            elif st=='SUSPEND':
                return "%3.2f%s(s)" % (x,sc)
            elif st=='CLOSED':
                return "%3.2f%s(c)" % (x,sc)
            else:
                return "%3.2f%s(%s)" % (x,sc,st)
        return " ---.--%s" % sc

    def sv_open(self,d=None):
        x = self.nv_open(d)
        if x!=None:
            return "%3.2f" % x
        return " ---.-- "

    def sv_low(self,d=None):
        x = self.nv_low(d)
        if x!=None:
            return "%3.2f" % x
        return " ---.-- "

    def sv_high(self,d=None):
        x = self.nv_high(d)
        if x!=None:
            return "%3.2f" % x
        return " ---.-- "

    def sv_volume(self,d=None):
        x = self.nv_volume(d)
        if x!=None:
            return fmtVolume(x)
        return " ---------- "

    def sv_prevclose(self,d=None):
        x = self.nv_prevclose(d)
        if x!=None:
            return "%3.2f" % x
        return " ---.-- "

    def sv_percent(self,d=None):
        try:
            x = self.nv_percent(d)
        except:
            return " ---.-- %"

        if x!=None:
            if x>0:
                return "+%3.2f %%" % x
            else:
                return "%3.2f %%" % x
        return " ---.-- %"

    def sv_unitvar(self,d=None):
        x = self.nv_unitvar(d)
        if x!=None:
            return "%3.2f" % x
        return " ---.-- "

    # ---[ object value ] ---

    def ov_candle(self,d=None):
        if self.m_daytrades:
            if d==None:
                tr = self.m_daytrades.lasttrade()
            else:
                tr = self.m_daytrades.trade(d)
            if tr==None:
                return None
            d = Datation(tr.date()).date()
            tc = self.m_daytrades.candle(d)
        return tc

    def ov_pivots(self):
        if self.m_daytrades:
            tc = self.m_daytrades.lasttrade()
            if tc:
                #debug('ov_pivots(): tc=%s tc_date=%s ... need to get prev ...' % (tc,tc.date()))
                tc = self.m_daytrades.prevtrade()
            if tc:
                H = tc.nv_high()
                B = tc.nv_low()
                C = tc.nv_close()
                pivot = (H + B + C) / 3
                s1 = (2 * pivot) - H
                s2 = pivot - (H - B)
                r1 = (2 * pivot) - B
                r2 = pivot + (H - B)
                return (s2,s1,pivot,r1,r2)
        return (-1.0,-1.0,-1.0,-1.0,-1.0)

    def sv_pivots(self):
        if self.sv_status()=='OK':
            s2,s1,pivot,r1,r2 = self.ov_pivots()
            if pivot != -1.0:
                cl = self.nv_close()
                if cl>r2:
                    return "R2+ (%.2f)" % r2
                elif cl==r2:
                    return "R2= (%.2f)" % r2
                elif cl>r1:
                    return "R1+ (%.2f)" % r1
                elif cl==r1:
                    return "R1= (%.2f)" % r1
                elif cl>pivot:
                    return "PI+ (%.2f)" % pivot
                elif cl==pivot:
                    return "PI= (%.2f)" % pivot
                elif cl>s1:
                    return "PI- (%.2f)" % pivot
                elif cl==s1:
                    return "S1= (%.2f)" % s1
                elif cl>s2:
                    return "S1- (%.2f)" % s1
                elif cl==s2:
                    return "S2= (%.2f)" % s2
                else:
                    return "S2- (%.2f)" % s2
        return " --- (-.--) "

    # ---[ market open/close ] ---

    def date(self,d=None):
        if self.m_daytrades:
            if d==None:
                tr = self.m_daytrades.lasttrade()
            else:
                tr = self.m_daytrades.trade(d)
            if tr:
                return tr.date()
        return None

    def sv_date(self,bDisplayShort=False):
        return date2str(self.date(),bDisplayShort)

    def hasOpened(self):
        if self.date() == date.today():
            #print '>>> hasOpened : True'
            return True
        else:
            #print '>>> hasOpened : False'
            return False

    def hasTraded(self):
        if self.isOpen():
            # today is open : check we have a known trade
            if self.date() == date.today():
                #print '>>> hasTraded : True'
                return True
            else:
                #print '>>> hasTraded : False'
                return False
        else:
            # today is closed : check previous open
            if self.m_daytrades and self.m_daytrades.prevtrade():
                # a trade exists !
                return True
            else:
                # no trade
                return False

    def isOpen(self):
        return gCal.isopen(date.today(),self.m_market)

    # ---[ compute all the data ] ---

    def compute(self,todate=None):
        debug('%s: compute [%s]' % (self.ticker(),todate))
        if self.m_daytrades:
            self.m_daytrades.compute(todate)

    # ---[ Trends ] ---

    def colorTrend(self,d=None):
        if self.m_daytrades:
            if d==None:
                tc = self.m_daytrades.lasttrade()
                #print 'colorTrend: lastrade close : %.2f date : %s ' % (tc.nv_close(),tc.date())
            else:
                tc = self.m_daytrades.trade(d)
                #print 'colorTrend: specific close : %.2f date : %s ' % (tc.nv_close(),tc.date())
            tp = self.m_daytrades.prevtrade(d)
            if not tp:
                return QUOTE_INVALID
            #print 'colorTrend: previous close : %.2f date : %s ' % (tp.nv_close(),tp.date())
            if tc.nv_close()==tp.nv_close():
                #print 'colorTrend: no change '
                return QUOTE_NOCHANGE
            elif tc.nv_close()<tp.nv_close():
                #print 'colorTrend: RED '
                return QUOTE_RED
            else:
                #print 'colorTrend: GREEN '
                return QUOTE_GREEN
        return QUOTE_INVALID

    def colorStop(self):
        cl = self.nv_close()
        if self.nv_number()==0:
            # no share on this quote : inside the target : BUY
            if (cl>=self.nv_stoploss()) and (cl<=self.nv_stopwin()):
                # must buy
                return QUOTE_GREEN
            else:
                # do nothing
                return QUOTE_NOCHANGE
        else:
            # some shares : outside the target : SELL
            if (cl<=self.nv_stoploss()) or (cl>=self.nv_stopwin()):
                # must sell
                return QUOTE_RED
            else:
                # do nothing
                return QUOTE_NOCHANGE

    # ---[ Indicators ] ---

    def nv_ma(self,period=20,d=None):
        if d==None:
            d = self.m_daytrades.lasttrade()
            if d:
                d = d.date()
            else:
                return None
        mm = self.m_daytrades.ma(period,d)
        return mm

    def sv_ma(self,period=20,d=None):
        x = self.nv_ma(period,d)
        if x!=None:
            return "%3.3f" % x
        return " ---.--- "

    def nv_rsi(self,period=14,d=None):
        if d==None:
            d = self.m_daytrades.lasttrade()
            if d:
                d = d.date()
            else:
                return None
        rsi = self.m_daytrades.rsi(period,d)
        return rsi

    def sv_rsi(self,period=14,d=None):
        x = self.nv_rsi(period,d)
        if x!=None:
            return "%3.3f" % x
        return " ---.--- "

    def nv_stoK(self,d=None):
        if d==None:
            d = self.m_daytrades.lasttrade()
            if d:
                d = d.date()
            else:
                return None
        sto = self.m_daytrades.stoK(d)
        return sto

    def sv_stoK(self,d=None):
        x = self.nv_stoK(d)
        if x!=None:
            return "%3.2f" % x
        return " ---.-- "

    def nv_stoD(self,d=None):
        if d==None:
            d = self.m_daytrades.lasttrade()
            if d:
                d = d.date()
            else:
                return None
        sto = self.m_daytrades.stoD(d)
        return sto

    def sv_stoD(self,d=None):
        x = self.nv_stoD(d)
        if x!=None:
            return "%3.2f" % x
        return " ---.-- "

    def nv_vma(self,period=15,d=None):
        if d==None:
            if d:
                d = d.date()
            else:
                return None
        mm = self.m_daytrades.vma(period,d)
        return mm

    def sv_vma(self,period=15,d=None):
        x = self.nv_vma(period,d)
        if x!=None:
            return "%d" % x
        return " ---------- "

    def nv_ovb(self,d=None):
        if d==None:
            if d:
                d = d.date()
            else:
                return None
        mm = self.m_daytrades.ovb(d)
        return mm

    def sv_ovb(self,d=None):
        x = self.nv_ovb(d)
        if x!=None:
            return "%d" % x
        return " ---------- "

    # ---[ monitor a quote ] ---

    def monitorIt(self,t):
        self.m_isMonitored = t
        return self.m_isMonitored

    # ---[ Command line ] ---

    def printInfo(self):
        print '%s - %s - %s (market=%s)' % (self.key(),self.ticker(),self.name(),self.market())
        print 'PRU DIR/SRD = %f / %f' % (self.m_DIR_pru,self.m_SRD_pru)
        print 'Cours = %f' % self.nv_close()
        print 'Nbre DIR/SRD/total = %d/%d/%d' % (self.nv_number(QUOTE_CASH),self.nv_number(QUOTE_CREDIT),self.nv_number(QUOTE_BOTH))
        print 'Gain DIR = %f' % ((self.nv_close()-self.m_DIR_pru)*self.nv_number(QUOTE_CASH))
        print 'Gain SRD = %f' % ((self.nv_close()-self.m_SRD_pru)*self.nv_number(QUOTE_CREDIT))
        print 'Candle = %s' % self.ov_candle()
        print 'StopLoss = %s' % self.sv_stoploss()
        print 'StopWin = %s' % self.sv_stopwin()

    # ---[ flush and reload ] ---

    def flushAndReload(self,dlg):
        self.flushTrades()
        cmdline_importQuoteFromInternet(self,dlg)
        self.compute()

    def flushTrades(self):
        if self.m_daytrades:
            self.m_daytrades.reset()
            self.m_daytrades = None
        self.m_pluginId = None

    def flushNews(self):
        newsfile = os.path.join(itrade_config.dirCacheData,'%s.htm' % self.key())
        try:
            os.remove(newsfile)
        except OSError:
            pass

    # ---[ Persistent Properties ] ------------------------

    def setProperty(self,prop,val):
        if prop=='name':
            self.set_name(val)
        elif prop=='ticker':
            self.set_ticker(val)
        elif prop=='live':
            self.set_liveconnector(val)
        elif prop=='import':
            self.set_importconnector(val)
        else:
            info('Quote::setProperty(%s): unknown property: %s' % (self.key(),prop))

    def listProperties(self):
        prop = []
        if self.name()!=self.default_name():
            prop.append('%s;%s;%s' % (self.key(),'name',self.name()))
        if self.ticker()!=self.default_ticker():
            prop.append('%s;%s;%s' % (self.key(),'ticker',self.ticker()))
        if self.m_userliveconnector and (self.m_userliveconnector != self.m_liveconnector):
            prop.append('%s;%s;%s' % (self.key(),'live',self.user_liveconnector().name()))
        if self.importconnector()!=self.default_importconnector():
            prop.append('%s;%s;%s' % (self.key(),'import',self.importconnector().name()))
        return prop

# ============================================================================
# Quotes
# ============================================================================
#
# CSV File format :
#   ISIN;NAME;SICOVAM;TICKER
# ============================================================================

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

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

    def reinit(self):
        debug('Quotes::reinit')
        for eachQuote in self.list():
            eachQuote.reinit()

    def list(self):
        items = self.m_quotes.values()
        items.sort(key=Quote.name)
        return items

    # ---[ Properties ] ---

    def addProperty(self,key,prop,val):
        quote = self.lookupKey(key)
        if quote:
            quote.setProperty(prop,val)

    def loadProperties(self):
        # open and read the file to load properties information
        infile = itrade_csv.read(None,os.path.join(itrade_config.dirUserData,'properties.txt'))
        if infile:
            # scan each line to read each quote
            for eachLine in infile:
                item = itrade_csv.parse(eachLine,3)
                if item:
                    # debug('%s ::: %s' % (eachLine,item))
                    self.addProperty(item[0],item[1],item[2])

    def saveProperties(self):
        props = []
        for eachQuote in self.list():
            for eachProp in eachQuote.listProperties():
                #print eachProp
                props.append(eachProp)
        itrade_csv.write(None,os.path.join(itrade_config.dirUserData,'properties.txt'),props)

    # ---[ Stops ] ---

    def addStops(self,key,loss,win):
        quote = self.lookupKey(key)
        if quote:
            quote.setStops(loss,win)

    def removeStops(self,key):
        quote = self.lookupKey(key)
        if quote:
            quote.clrStops()

    def loadStops(self,fs=None):
        # open and read the file to load stops information
        infile = itrade_csv.read(fs,os.path.join(itrade_config.dirUserData,'default.stops.txt'))
        if infile:
            # scan each line to read each quote
            for eachLine in infile:
                item = itrade_csv.parse(eachLine,3)
                if item:
                    # debug('%s ::: %s' % (eachLine,item))
                    self.addStops(item[0],item[1],item[2])

    def saveStops(self,fp=None):
        stops = []
        for eachQuote in self.list():
            if eachQuote.hasStops():
                stops.append(eachQuote.getStops())
        itrade_csv.write(fp,os.path.join(itrade_config.dirUserData,'default.stops.txt'),stops)

    # ---[ Quotes ] ---

    def addQuote(self,isin,name,ticker,market,currency,place,country=None,list=QLIST_SYSTEM,debug=False):

        # right case
        if country:
            country = country.upper()
        if place:
            place = place.upper()

        # get a key and check strict duplicate (i.e. same key)
        key = quote_reference(isin,ticker,market,place)
        if self.m_quotes.has_key(key):
            if debug:
                print '%r/%s already exists - keep it (ignore %s)' % (self.m_quotes[key],self.m_quotes[key].ticker(),ticker)
            return True

        # depending on isin
        if isin==None or isin=='':
            # no isin : check if we have already this quote
            quote = None # __perf: self.lookupTicker(ticker,market)
            if quote:
                if debug:
                    print '%r already exists - ignore' % self.m_quotes[key]
                return True
        else:
            # isin : check if we can replace the same quote without isin
            key2 = quote_reference(None,ticker,market,place)
            if self.m_quotes.has_key(key2):
                if debug:
                    print '%r already exists but without ISIN - replace' % self.m_quotes[key2]
                del self.m_quotes[key2]

        # new quote
        self.m_quotes[key] = Quote(key,isin,name.upper(),ticker.upper(),market,currency.upper(),place,country,list)

        if debug:
            print 'Add %s in quotes list' % self.m_quotes[key]

        return True

    def _addLines(self,infile,list,debug):
        # scan each line to read each quote
        for eachLine in infile:
            item = itrade_csv.parse(eachLine,7)
            if item and len(item)>=7:
                self.addQuote(item[0],item[1],item[2],item[3],item[4],item[5],item[6],list,debug)

    # ---[ load list of quotes / indices / trackers / ... ] ---------------------------------------------------

    def loadMarket(self,market):
        # open and read the file to load these quotes information
        if not is_market_loaded(market):
            infile = itrade_csv.read(None,os.path.join(itrade_config.dirSymbData,'quotes.%s.txt' % market))
            if infile:
                self._addLines(infile,list=QLIST_SYSTEM,debug=False)
            set_market_loaded(market)

    def loadListOfQuotes(self):
        infile = itrade_csv.read(None,os.path.join(itrade_config.dirSymbData,'indices.txt'))
        if infile:
            self._addLines(infile,list=QLIST_INDICES,debug=False)

        infile = itrade_csv.read(None,os.path.join(itrade_config.dirSymbData,'trackers.txt'))
        if infile:
            self._addLines(infile,list=QLIST_TRACKERS,debug=False)

        # them open and read user file
        infile = itrade_csv.read(None,os.path.join(itrade_config.dirUserData,'usrquotes.txt'))
        if infile:
            self._addLines(infile,list=QLIST_USER,debug=False)

    # ---[ save list of quotes / indices / trackers / ... ] ---------------------------------------------------

    def saveMarkets(self):
        for eachMarket in list_of_markets(ifLoaded=True):
            props = []
            for eachQuote in self.list():
                if eachQuote.list()==QLIST_SYSTEM and eachQuote.market()==eachMarket:
                    props.append(eachQuote.__repr__())
            #
            # open and write the file with these quotes information
            itrade_csv.write(None,os.path.join(itrade_config.dirSymbData,'quotes.%s.txt' % eachMarket),props)
            print 'System List of symbols %s saved.' % eachMarket

    def saveListOfQuotes(self):
        # System list
        self.saveMarkets()

        # User list
        props = []
        for eachQuote in self.list():
            if eachQuote.list()==QLIST_USER:
                props.append(eachQuote.__repr__())
        #
        # open and write the file with these quotes information
        itrade_csv.write(None,os.path.join(itrade_config.dirUserData,'usrquotes.txt'),props)
        print 'User List of symbols saved.'

    # ---[ removeQuotes from the list ] ---

    def removeQuote(self,key):
        if self.m_quotes.has_key(key):
            del self.m_quotes[key]
            return True
        return False

    def removeQuotes(self,market,list):
        for eachQuote in self.list():
            if list==eachQuote.list():
                if market==None or eachQuote.market()==market:
                    del self.m_quotes[eachQuote.key()]

    # ---[ Lookup (optionaly, filter by market) ] ---

    def lookupKey(self,key):
        if key==None:
            return None

        if self.m_quotes.has_key(key):
            return self.m_quotes[key]

        # key not found
        skey = key.split('.')
        if len(skey)==3:
            # check the list of quotes for this market has been loaded
            market = skey[1]
            if not is_market_loaded(market):
                self.loadMarket(market)
                if self.m_quotes.has_key(key):
                    return self.m_quotes[key]

        # key really not found
        return None

    def lookupISIN(self,isin,market=None,place=None):
        # return list of
        ret = []
        for eachVal in self.m_quotes.values():
            if eachVal.isin() == isin:
                if (market==None or (market==eachVal.market())) and (place==None or (place==eachVal.place())):
                    ret.append(eachVal)
        return ret

    def lookupTicker(self,ticker,market=None,place=None):
        # return first one
        for eachVal in self.m_quotes.values():
            if (eachVal.ticker() == ticker) and (market==None or (market==eachVal.market())) and (place==None or (place==eachVal.place())):
                    return eachVal
        return None

    def lookupPartialTicker(self,ticker,market=None,place=None):
        # return list of
        ret = []
        for eachVal in self.m_quotes.values():
            if (eachVal.ticker().find(ticker,0)==0) and (market==None or (market==eachVal.market())) and (place==None or (place==eachVal.place())):
                    ret.append(eachVal)
        return ret

    def lookupName(self,name,market,place=None):
        for eachVal in self.m_quotes.values():
            if (eachVal.name() == name) and (market==None or (market==eachVal.market())) and (place==None or (place==eachVal.place())):
                return eachVal
        return None

    # ---[ Trades ] ---

    def loadTrades(self,fi=None):
        # read quotes data
        for eachKey in self.m_quotes.keys():
            self.m_quotes[eachKey].loadTrades(fi)

    def saveTrades(self,fe=None):
        # read quotes data
        for eachKey in self.m_quotes.keys():
            self.m_quotes[eachKey].saveTrades(fe)

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

try:
    ignore(quotes)
except NameError:
    quotes = Quotes()

# ============================================================================
# initQuotesModule()
# ============================================================================

def initQuotesModule():
    quotes.loadListOfQuotes()

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

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

    initQuotesModule()

    info('test1 %s' % quotes.lookupISIN('FR0000072621'));
    quote = quotes.lookupTicker('OSI','EURONEXT')
    info('test2 %s' % quote.ticker());
    info('test3a %s' % quote.isin());
    info('test3b %s' % quote.key());
    info('test4 %s' % quote.name());
    info('test5 %s' % quote.descr());

    quote = quotes.lookupTicker('OSI','EURONEXT')
    quote.loadTrades('import/Cortal-2005-01-07.txt')
    info('test6 %s' % quote.trades().trade('20050104'));

    quotes.loadTrades('import/Cortal-2005-01-07.txt')
    quotes.loadTrades('import/Cortal-2005-01-14.txt')
    quotes.loadTrades('import/Cortal-2005-01-21.txt')
    quote = quotes.lookupTicker('EADT','EURONEXT')
    info('test7 %s' % quote.trades().trade('20050104'));

#    quotes.saveTrades()
#    quotes.saveListOfQuotes(os.path.join(itrade_config.dirSymbData,'test.txt'))

    print fmtVolume(1)
    print fmtVolume(12)
    print fmtVolume(130)
    print fmtVolume(1400)
    print fmtVolume(15000)
    print fmtVolume(160000)
    print fmtVolume(1700000)
    print fmtVolume(18000000)

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