def iter_investment(self): for line in self.document.xpath( '//table[@summary and count(descendant::td) > 1]/tbody/tr'): cells = line.findall('td') if len(cells) < 5: continue inv = Investment() inv.label = unicode(cells[self.COL_ID].text_content().strip()) a = cells[self.COL_ID].find('a') if a is not None: try: inv.code = a.attrib['id'] except KeyError: #For "Mandat d'arbitrage" which is a recapitulatif of more investement continue else: inv.code = NotAvailable inv.quantity = self.parse_decimal( cells[self.COL_QUANTITY].text_content()) inv.unitvalue = self.parse_decimal( cells[self.COL_UNITVALUE].text_content()) inv.valuation = self.parse_decimal( cells[self.COL_VALUATION].text_content()) inv.unitprice = NotAvailable inv.diff = NotAvailable yield inv
def iter_investment(self): for line in self.document.xpath('//table[@summary and count(descendant::td) > 1]/tbody/tr'): cells = line.findall('td') if len(cells) < 5: continue inv = Investment() inv.label = unicode(cells[self.COL_ID].text_content().strip()) a = cells[self.COL_ID].find('a') if a is not None: try: inv.code = a.attrib['id'] except KeyError: #For "Mandat d'arbitrage" which is a recapitulatif of more investement continue else: inv.code = NotAvailable inv.quantity = self.parse_decimal(cells[self.COL_QUANTITY].text_content()) inv.unitvalue = self.parse_decimal(cells[self.COL_UNITVALUE].text_content()) inv.valuation = self.parse_decimal(cells[self.COL_VALUATION].text_content()) inv.unitprice = NotAvailable inv.diff = NotAvailable yield inv
def iter_investment(self): not_rounded_valuations = self.get_not_rounded_valuations() doc = self.browser.open('/brs/fisc/fisca10a.html').page.doc num_page = None try: num_page = int(CleanText('.')(doc.xpath(u'.//tr[contains(td[1], "Relevé des plus ou moins values latentes")]/td[2]')[0]).split('/')[1]) except IndexError: pass docs = [doc] if num_page: for n in range(2, num_page + 1): docs.append(self.browser.open('%s%s' % ('/brs/fisc/fisca10a.html?action=12&numPage=', str(n))).page.doc) for doc in docs: # There are two different tables possible depending on the market account type. is_detailed = bool(doc.xpath(u'//span[contains(text(), "Années d\'acquisition")]')) tr_xpath = '//tr[@height and td[@colspan="6"]]' if is_detailed else '//tr[count(td)>5]' for tr in doc.xpath(tr_xpath): cells = tr.findall('td') inv = Investment() title_split = cells[self.COL_LABEL].xpath('.//span')[0].attrib['title'].split(' - ') inv.label = unicode(title_split[0]) for code in title_split[1:]: if is_isin_valid(code): inv.code = unicode(code) inv.code_type = Investment.CODE_TYPE_ISIN break else: inv.code = NotAvailable inv.code_type = NotAvailable if is_detailed: inv.quantity = MyDecimal('.')(tr.xpath('./following-sibling::tr/td[2]')[0]) inv.unitprice = MyDecimal('.', replace_dots=True)(tr.xpath('./following-sibling::tr/td[3]')[1]) inv.unitvalue = MyDecimal('.', replace_dots=True)(tr.xpath('./following-sibling::tr/td[3]')[0]) try: # try to get not rounded value inv.valuation = not_rounded_valuations[inv.label] except KeyError: # ok.. take it from the page inv.valuation = MyDecimal('.')(tr.xpath('./following-sibling::tr/td[4]')[0]) inv.diff = MyDecimal('.')(tr.xpath('./following-sibling::tr/td[5]')[0]) or \ MyDecimal('.')(tr.xpath('./following-sibling::tr/td[6]')[0]) else: inv.quantity = MyDecimal('.')(cells[self.COL_QUANTITY]) inv.diff = MyDecimal('.')(cells[self.COL_DIFF]) inv.unitprice = MyDecimal('.')(cells[self.COL_UNITPRICE].xpath('.//tr[1]/td[2]')[0]) inv.unitvalue = MyDecimal('.')(cells[self.COL_VALUATION].xpath('.//tr[1]/td[2]')[0]) inv.valuation = MyDecimal('.')(cells[self.COL_VALUATION].xpath('.//tr[2]/td[2]')[0]) yield inv
def iter_investments(self): # We did not get some html, but something like that (XX is a quantity, YY a price): # message='[...] # popup=2{6{E:ALO{PAR{{reel{695{380{ALSTOM REGROUPT#XX#YY,YY €#YY,YY €#1 YYY,YY €#-YYY,YY €#-42,42%#-0,98 %#42,42 %#|1|AXA#cotationValeur.php?val=E:CS&pl=6&nc=1& # popup=2{6{E:CS{PAR{{reel{695{380{AXA#XX#YY,YY €#YY,YYY €#YYY,YY €#YY,YY €#3,70%#42,42 %#42,42 %#|1|blablablab #cotationValeur.php?val=P:CODE&pl=6&nc=1& # [...] lines = self.doc.split("popup=2") lines.pop(0) invests = [] for line in lines: columns = line.split('#') _pl = columns[0].split('{')[1] _id = columns[0].split('{')[2] invest = Investment(_id) invest.label = unicode(columns[0].split('{')[-1]) invest.code = unicode(_id) if ':' in invest.code: invest.code = self.browser.titrevalue.open(val=invest.code,pl=_pl).get_isin() # The code we got is not a real ISIN code. if not re.match('^[A-Z]{2}[\d]{10}$|^[A-Z]{2}[\d]{5}[A-Z]{1}[\d]{4}$', invest.code): m = re.search('\{([A-Z]{2}[\d]{10})\{|\{([A-Z]{2}[\d]{5}[A-Z]{1}[\d]{4})\{', line) if m: invest.code = unicode(m.group(1) or m.group(2)) quantity = FrenchTransaction.clean_amount(columns[1]) invest.quantity = CleanDecimal(default=NotAvailable).filter(quantity) unitprice = FrenchTransaction.clean_amount(columns[2]) invest.unitprice = CleanDecimal(default=NotAvailable).filter(unitprice) unitvalue = FrenchTransaction.clean_amount(columns[3]) invest.unitvalue = CleanDecimal(default=NotAvailable).filter(unitvalue) valuation = FrenchTransaction.clean_amount(columns[4]) # valuation is not nullable, use 0 as default value invest.valuation = CleanDecimal(default=Decimal('0')).filter(valuation) diff = FrenchTransaction.clean_amount(columns[5]) invest.diff = CleanDecimal(default=NotAvailable).filter(diff) # On some case we have a multine investment with a total column # for now we have only see this on 2 lines, we will need to adapt it when o if columns[9] == u'|Total' and _id == 'fichevaleur': prev_inv = invest invest = invests.pop(-1) if prev_inv.quantity: invest.quantity = invest.quantity + prev_inv.quantity if prev_inv.valuation: invest.valuation = invest.valuation + prev_inv.valuation if prev_inv.diff: invest.diff = invest.diff + prev_inv.diff invests.append(invest) for invest in invests: yield invest
def iter_investments(self): # We did not get some html, but something like that (XX is a quantity, YY a price): # message='[...] # popup=2{6{E:ALO{PAR{{reel{695{380{ALSTOM REGROUPT#XX#YY,YY €#YY,YY €#1 YYY,YY €#-YYY,YY €#-42,42%#-0,98 %#42,42 %#|1|AXA#cotationValeur.php?val=E:CS&pl=6&nc=1& # popup=2{6{E:CS{PAR{{reel{695{380{AXA#XX#YY,YY €#YY,YYY €#YYY,YY €#YY,YY €#3,70%#42,42 %#42,42 %#|1|blablablab #cotationValeur.php?val=P:CODE&pl=6&nc=1& # [...] lines = self.doc.split("popup=2") lines.pop(0) for line in lines: columns = line.split('#') _pl = columns[0].split('{')[1] _id = columns[0].split('{')[2] invest = Investment(_id) invest.label = unicode(columns[0].split('{')[-1]) invest.code = unicode(_id) if ':' in invest.code: invest.code = self.browser.titrevalue.open(val=invest.code,pl=_pl).get_isin() # The code we got is not a real ISIN code. if not re.match('^[A-Z]{2}[\d]{10}$|^[A-Z]{2}[\d]{5}[A-Z]{1}[\d]{4}$', invest.code): m = re.search('\{([A-Z]{2}[\d]{10})\{|\{([A-Z]{2}[\d]{5}[A-Z]{1}[\d]{4})\{', line) if m: invest.code = unicode(m.group(1) or m.group(2)) quantity = FrenchTransaction.clean_amount(columns[1]) if quantity != '': invest.quantity = Decimal(quantity) else: invest.quantity = NotAvailable unitprice = FrenchTransaction.clean_amount(columns[2]) if unitprice != '': invest.unitprice = Decimal(unitprice) else: invest.unitprice = NotAvailable unitvalue = FrenchTransaction.clean_amount(columns[3]) if unitvalue != '': invest.unitvalue = Decimal(unitvalue) else: invest.unitvalue = NotAvailable valuation = FrenchTransaction.clean_amount(columns[4]) if valuation != '': invest.valuation = Decimal(valuation) else: # valuation is not nullable. invest.valuation = Decimal('0') diff = FrenchTransaction.clean_amount(columns[5]) if diff != '': invest.diff = Decimal(diff) else: invest.diff = NotAvailable yield invest
def create_investment(self, cells): inv = Investment() inv.quantity = MyDecimal('.')(cells[self.COL_QUANTITY]) inv.unitvalue = MyDecimal('.')(cells[self.COL_UNITVALUE]) inv.unitprice = NotAvailable inv.valuation = MyDecimal('.')(cells[self.COL_VALUATION]) inv.diff = NotAvailable link = cells[self.COL_LABEL].xpath('a[contains(@href, "CDCVAL=")]')[0] m = re.search('CDCVAL=([^&]+)', link.attrib['href']) if m: inv.code = m.group(1) else: inv.code = NotAvailable return inv
def create_investement(self, cells): inv = Investment() inv.quantity = self.parse_decimal(cells[self.COL_QUANTITY]) inv.unitvalue = self.parse_decimal(cells[self.COL_UNITVALUE]) inv.unitprice = NotAvailable inv.valuation = self.parse_decimal(cells[self.COL_VALUATION]) inv.diff = NotAvailable link = cells[self.COL_LABEL].xpath('a[contains(@href, "CDCVAL=")]')[0] m = re.search('CDCVAL=([^&]+)', link.attrib['href']) if m: inv.code = m.group(1) else: inv.code = NotAvailable return inv
def get_market_investment(self): COL_LABEL = 0 COL_QUANTITY = 1 COL_UNITPRICE = 2 COL_UNITVALUE = 3 COL_VALUATION = 4 COL_PERF = 5 for table in self.document.xpath('//table[@class="datas-large"]'): for tr in table.xpath('.//tr[not(@class="entete")]'): cols = tr.findall('td') if len(cols) < 7: continue delta = 0 if len(cols) == 9: delta = 1 inv = Investment() inv.code = self.parser.tocleanstring(cols[COL_LABEL + delta].xpath('.//span')[1]) inv.label = self.parser.tocleanstring(cols[COL_LABEL + delta].xpath('.//span')[0]) inv.quantity = self.parse_decimal(cols[COL_QUANTITY + delta]) inv.unitprice = self.parse_decimal(cols[COL_UNITPRICE + delta]) inv.unitvalue = self.parse_decimal(cols[COL_UNITVALUE + delta]) inv.valuation = self.parse_decimal(cols[COL_VALUATION + delta]) inv.diff = self.parse_decimal(cols[COL_PERF + delta]) yield inv
def iter_investments(self): # We did not get some html, but something like that (XX is a quantity, YY a price): # message='[...] # popup=2{6{E:ALO{PAR{{reel{695{380{ALSTOM REGROUPT#XX#YY,YY €#YY,YY €#1 YYY,YY €#-YYY,YY €#-42,42%#-0,98 %#42,42 %#|1|AXA#cotationValeur.php?val=E:CS&pl=6&nc=1& # popup=2{6{E:CS{PAR{{reel{695{380{AXA#XX#YY,YY €#YY,YYY €#YYY,YY €#YY,YY €#3,70%#42,42 %#42,42 %#|1|blablablab #cotationValeur.php?val=P:CODE&pl=6&nc=1& # [...] lines = self.doc.split("popup=2") lines.pop(0) for line in lines: columns = line.split('#') _id = columns[0].split('{')[2] invest = Investment(_id) invest.label = unicode(columns[0].split('{')[-1]) invest.code = NotAvailable if ':' in _id: invest.description = unicode(_id.split(':')[1]) invest.quantity = Decimal( FrenchTransaction.clean_amount(columns[1])) invest.unitprice = Decimal( FrenchTransaction.clean_amount(columns[2])) invest.unitvalue = Decimal( FrenchTransaction.clean_amount(columns[3])) invest.valuation = Decimal( FrenchTransaction.clean_amount(columns[4])) invest.diff = Decimal(FrenchTransaction.clean_amount(columns[5])) yield invest
def get_investments(self, account): if account is not None: # the balance is highly dynamic, fetch it along with the investments to grab a snapshot account.balance = CleanDecimal(None, replace_dots=True).filter(self.get_balance(account.type)) for line in self.doc.xpath('//table[@id="t_intraday"]/tbody/tr'): if line.find_class('categorie') or line.find_class('detail') or line.find_class('detail02'): continue cols = line.findall('td') inv = Investment() inv.label = CleanText(None).filter(cols[self.COL_LABEL]) link = cols[self.COL_LABEL].xpath('./a[contains(@href, "cdReferentiel")]')[0] inv.id = re.search('cdReferentiel=(.*)', link.attrib['href']).group(1) inv.code = re.match('^[A-Z]+[0-9]+(.*)$', inv.id).group(1) inv.quantity = self.parse_decimal(cols[self.COL_QUANTITY], True) inv.unitprice = self.parse_decimal(cols[self.COL_UNITPRICE], True) inv.unitvalue = self.parse_decimal(cols[self.COL_UNITVALUE], False) inv.valuation = self.parse_decimal(cols[self.COL_VALUATION], True) diff = cols[self.COL_PERF].text.strip() if diff == "-": inv.diff = NotAvailable else: inv.diff = CleanDecimal(None, replace_dots=True).filter(diff) if is_isin_valid(inv.code): inv.code_type = Investment.CODE_TYPE_ISIN yield inv if account.type != account.TYPE_MARKET: valuation = CleanDecimal(None, True).filter(self.doc.xpath('//*[@id="valorisation_compte"]/table/tr[3]/td[2]')) yield create_french_liquidity(valuation)
def get_investments(self, account): for line in self.doc.xpath('//table[@id="tableau_support"]/tbody/tr'): cols = line.findall('td') inv = Investment() inv.id = re.search( 'cdReferentiel=(.*)', cols[self.COL_LABEL].find('a').attrib['href']).group(1) inv.code = re.match('^[A-Z]+[0-9]+(.*)$', inv.id).group(1) inv.label = CleanText(None).filter(cols[self.COL_LABEL]) inv.quantity = self.parse_decimal(cols[self.COL_QUANTITY]) inv.unitprice = self.parse_decimal(cols[self.COL_UNITPRICE]) inv.unitvalue = self.parse_decimal(cols[self.COL_UNITVALUE]) inv.vdate = Date(CleanText(cols[self.COL_DATE], default=NotAvailable), dayfirst=True, default=NotAvailable)(self.doc) inv.valuation = self.parse_decimal(cols[self.COL_VALUATION]) inv.diff = self.parse_decimal(cols[self.COL_PERF]) diff_percent = self.parse_decimal(cols[self.COL_PERF_PERCENT]) inv.diff_percent = diff_percent / 100 if diff_percent else NotAvailable if is_isin_valid(inv.code): inv.code_type = Investment.CODE_TYPE_ISIN yield inv
def get_deposit_investment(self): COL_LABEL = 0 COL_QUANTITY = 3 COL_UNITVALUE = 4 COL_VALUATION = 5 for tr in self.doc.xpath( '//table[@class="datas"]/tr[not(@class="entete")]'): cols = tr.findall('td') inv = Investment() inv.label = CleanText('.')(cols[COL_LABEL].xpath('.//a')[0]) inv.code = CleanText('./text()')(cols[COL_LABEL]) inv.quantity = MyDecimal('.')(cols[COL_QUANTITY]) inv.unitvalue = MyDecimal().filter( CleanText('.')(cols[COL_UNITVALUE]).split()[0]) if inv.unitvalue is not NotAvailable: inv.vdate = Date(dayfirst=True, default=NotAvailable)\ .filter(Regexp(CleanText('.'), '(\d{2})/(\d{2})/(\d{4})', '\\3-\\2-\\1', default=NotAvailable)(cols[COL_UNITVALUE])) or \ Date(dayfirst=True, default=NotAvailable)\ .filter(Regexp(CleanText('//tr[td[span[b[contains(text(), "Estimation du contrat")]]]]/td[2]'), '(\d{2})/(\d{2})/(\d{4})', '\\3-\\2-\\1', default=NotAvailable)(cols[COL_UNITVALUE])) inv.valuation = MyDecimal('.')(cols[COL_VALUATION]) yield inv
def iter_investment(self): doc = self.browser.get_document(self.browser.openurl('/brs/fisc/fisca10a.html'), encoding='utf-8') num_page = None try: num_page = int(self.parser.tocleanstring(doc.xpath(u'.//tr[contains(td[1], "Relevé des plus ou moins values latentes")]/td[2]')[0]).split('/')[1]) except IndexError: pass docs = [doc] if num_page: for n in range(2, num_page + 1): docs.append(self.browser.get_document(self.browser.openurl('%s%s' % ('/brs/fisc/fisca10a.html?action=12&numPage=', str(n))), encoding='utf-8')) for doc in docs: for tr in doc.xpath('//tr[count(td)=6 and td[1]/strong]'): cells = tr.findall('td') inv = Investment() inv.label = unicode(cells[self.COL_LABEL].xpath('.//span')[0].attrib['title'].split(' - ')[0]) inv.code = unicode(cells[self.COL_LABEL].xpath('.//span')[0].attrib['title'].split(' - ')[1]) inv.quantity = self.parse_decimal(cells[self.COL_QUANTITY]) inv.unitprice = self.parse_decimal(tr.xpath('./following-sibling::tr/td[3]')[0]) inv.unitvalue = self.parse_decimal(cells[self.COL_UNITVALUE]) inv.valuation = self.parse_decimal(cells[self.COL_VALUATION]) inv.diff = self.parse_decimal(cells[self.COL_DIFF]) yield inv
def iter_investment(self, account): if account.type == Account.TYPE_LIFE_INSURANCE: if not self.goto_spirica(account): return iter([]) return self.spirica.iter_investment(account) elif account.type in (Account.TYPE_MARKET, Account.TYPE_PEA): bourse_account = self.get_bourse_account(account) if not bourse_account: return iter([]) self.location(bourse_account._market_link) assert self.bourse.is_here() invs = list(self.page.iter_investment()) # _especes is set during BoursePage accounts parsing. BoursePage # inherits from lcl module BoursePage if bourse_account._especes: i = Investment() i.valuation = bourse_account._especes i.code = u"XX-liquidity" i.label = u"Liquidités" invs.append(i) return invs raise NotImplementedError()
def get_market_investment(self): if CleanText('//div[contains(text(), "restreint aux fonctions de bourse")]')(self.doc): return COL_LABEL = 0 COL_QUANTITY = 1 COL_UNITPRICE = 2 COL_UNITVALUE = 3 COL_VALUATION = 4 COL_PERF = 5 for table in self.doc.xpath('//table[@class="datas-large"]'): for tr in table.xpath('.//tr[not(@class="entete")]'): cols = tr.findall('td') if len(cols) < 7: continue delta = 0 if len(cols) == 9: delta = 1 inv = Investment() inv.code = CleanText('.')(cols[COL_LABEL + delta].xpath('.//span')[1]).split(' ')[0].split(u'\xa0')[0] inv.label = CleanText('.')(cols[COL_LABEL + delta].xpath('.//span')[0]) inv.quantity = MyDecimal('.')(cols[COL_QUANTITY + delta]) inv.unitprice = MyDecimal('.')(cols[COL_UNITPRICE + delta]) inv.unitvalue = MyDecimal('.')(cols[COL_UNITVALUE + delta]) inv.valuation = MyDecimal('.')(cols[COL_VALUATION + delta]) inv.diff = MyDecimal('.')(cols[COL_PERF + delta]) yield inv
def iter_investment(self): cleaner = CleanText().filter for line in self.doc.xpath( '//div[@class="supportTable"]//table/tbody/tr'): tds = line.findall('td') if len(tds) < 4: continue inv = Investment() if self.doc.xpath( '//div[@id="table-evolution-contrat"]//table/tbody/tr[1]/td[1]' ): inv.vdate = Date(dayfirst=True).filter(CleanText().filter( self.doc.xpath( '//div[@id="table-evolution-contrat"]//table/tbody/tr[1]/td[1]' ))) else: inv.vdate = NotAvailable inv.label = cleaner(tds[self.COL_LABEL]) inv.code = cleaner(tds[self.COL_CODE]) inv.valuation = Decimal( FrenchTransaction.clean_amount(cleaner( tds[self.COL_VALUATION]))) inv.portfolio_share = Decimal( FrenchTransaction.clean_amount( cleaner(tds[self.COL_PORTFOLIO_SHARE]))) / 100 yield inv
def get_market_investment(self): COL_LABEL = 0 COL_QUANTITY = 1 COL_UNITPRICE = 2 COL_UNITVALUE = 3 COL_VALUATION = 4 COL_PERF = 5 for table in self.document.xpath('//table[@class="datas-large"]'): for tr in table.xpath('.//tr[not(@class="entete")]'): cols = tr.findall('td') if len(cols) < 7: continue delta = 0 if len(cols) == 9: delta = 1 inv = Investment() inv.code = self.parser.tocleanstring( cols[COL_LABEL + delta].xpath('.//span')[1]) inv.label = self.parser.tocleanstring( cols[COL_LABEL + delta].xpath('.//span')[0]) inv.quantity = self.parse_decimal(cols[COL_QUANTITY + delta]) inv.unitprice = self.parse_decimal(cols[COL_UNITPRICE + delta]) inv.unitvalue = self.parse_decimal(cols[COL_UNITVALUE + delta]) inv.valuation = self.parse_decimal(cols[COL_VALUATION + delta]) inv.diff = self.parse_decimal(cols[COL_PERF + delta]) yield inv
def get_investment(self, account): if account.type == Account.TYPE_LIFE_INSURANCE and account._form: self.assurancevie.stay_or_go() account._form.submit() if self.calie.is_here(): # come back to syntese self.assurancevie.go() return if self.page.is_restricted(): self.logger.warning('restricted access to account %s', account) else: for inv in self.page.iter_investment(): yield inv if self.avdetail.is_here(): self.page.come_back() elif hasattr(account, '_market_link') and account._market_link: self.connexion_bourse() for inv in self.location(account._market_link).page.iter_investment(): yield inv self.deconnexion_bourse() elif account.id in self.get_bourse_accounts_ids(): inv = Investment() inv.id = account.id inv.code = 'XX-Liquidity' inv.label = "Liquidités" inv.valuation = account.balance yield inv
def iter_investment(self): for line in self.document.xpath('//table[contains(@class, "ca-data-table")]/descendant::tr[count(td)>=7]'): for sub in line.xpath('./td[@class="info-produit"]'): sub.drop_tree() cells = line.findall('td') if cells[self.COL_ID].find('div/a') is None: continue inv = Investment() inv.label = unicode(cells[self.COL_ID].find('div/a').text.strip()) inv.code = cells[self.COL_ID].find('div/br').tail.strip().split(u'\xa0')[0] inv.quantity = self.parse_decimal(cells[self.COL_QUANTITY].find('span').text) inv.valuation = self.parse_decimal(cells[self.COL_VALUATION].text) inv.diff = self.parse_decimal(cells[self.COL_DIFF].text_content()) if "%" in cells[self.COL_UNITPRICE].text and "%" in cells[self.COL_UNITVALUE].text: inv.unitvalue = inv.valuation / inv.quantity inv.unitprice = (inv.valuation - inv.diff) / inv.quantity else: inv.unitprice = self.parse_decimal(cells[self.COL_UNITPRICE].text) inv.unitvalue = self.parse_decimal(cells[self.COL_UNITVALUE].text) date = cells[self.COL_UNITVALUE].find('span').text if ':' in date: inv.vdate = ddate.today() else: day, month = map(int, date.split('/', 1)) date_guesser = LinearDateGuesser() inv.vdate = date_guesser.guess_date(day, month) yield inv
def get_investments(self): for line in self.document.xpath('//table[@id="t_intraday"]/tbody/tr'): if line.find_class('categorie') or line.find_class( 'detail') or line.find_class('detail02'): continue cols = line.findall('td') inv = Investment() inv.label = self.parser.tocleanstring(cols[self.COL_LABEL]) link = cols[self.COL_LABEL].xpath( './a[contains(@href, "cdReferentiel")]')[0] inv.id = unicode( re.search('cdReferentiel=(.*)', link.attrib['href']).group(1)) inv.code = re.match('^[A-Z]+[0-9]+(.*)$', inv.id).group(1) inv.quantity = self.parse_decimal(cols[self.COL_QUANTITY]) inv.unitprice = self.parse_decimal(cols[self.COL_UNITPRICE]) inv.unitvalue = self.parse_decimal(cols[self.COL_UNITVALUE]) inv.valuation = self.parse_decimal(cols[self.COL_VALUATION]) diff = cols[self.COL_PERF].text.strip() if diff == "-": inv.diff = NotAvailable else: inv.diff = Decimal(Transaction.clean_amount(diff)) yield inv
def iter_investment(self, account): if account.type == Account.TYPE_LIFE_INSURANCE: if not self.goto_spirica(account): return iter([]) return self.spirica.iter_investment(account) elif account.type in (Account.TYPE_MARKET, Account.TYPE_PEA): bourse_account = self.get_bourse_account(account) if not bourse_account: return iter([]) self.location(bourse_account._market_link) assert self.bourse.is_here() invs = list(self.page.iter_investment()) # _especes is set during BoursePage accounts parsing. BoursePage # inherits from lcl module BoursePage if bourse_account._especes: i = Investment() i.valuation = bourse_account._especes i.code = u"XX-liquidity" i.label = u"Liquidités" invs.append(i) self.leave_espace_bourse() return invs raise NotImplementedError()
def parse(self, el): i = Investment() i.label = Field('label')(self) i.code = CleanText(TableCell('code'))(self) i.quantity = MyDecimal(TableCell('quantity'))(self) i.valuation = Field('amount')(self) i.vdate = Field('date')(self) self.env['investments'] = [i]
def iter_investments(self): # We did not get some html, but something like that (XX is a quantity, YY a price): # message='[...] # popup=2{6{E:ALO{PAR{{reel{695{380{ALSTOM REGROUPT#XX#YY,YY €#YY,YY €#1 YYY,YY €#-YYY,YY €#-42,42%#-0,98 %#42,42 %#|1|AXA#cotationValeur.php?val=E:CS&pl=6&nc=1& # popup=2{6{E:CS{PAR{{reel{695{380{AXA#XX#YY,YY €#YY,YYY €#YYY,YY €#YY,YY €#3,70%#42,42 %#42,42 %#|1|blablablab #cotationValeur.php?val=P:CODE&pl=6&nc=1& # [...] lines = self.doc.split("popup=2") lines.pop(0) for line in lines: columns = line.split('#') _id = columns[0].split('{')[2] invest = Investment(_id) invest.label = unicode(columns[0].split('{')[-1]) invest.code = unicode(_id) if ':' in invest.code: invest.code = self.browser.titrevalue.open( val=invest.code).get_isin() quantity = FrenchTransaction.clean_amount(columns[1]) if quantity != '': invest.quantity = Decimal(quantity) else: invest.quantity = NotAvailable unitprice = FrenchTransaction.clean_amount(columns[2]) if unitprice != '': invest.unitprice = Decimal(unitprice) else: invest.unitprice = NotAvailable unitvalue = FrenchTransaction.clean_amount(columns[3]) if unitvalue != '': invest.unitvalue = Decimal(unitvalue) else: invest.unitvalue = NotAvailable valuation = FrenchTransaction.clean_amount(columns[4]) if valuation != '': invest.valuation = Decimal(valuation) else: invest.valuation = NotAvailable diff = FrenchTransaction.clean_amount(columns[5]) if diff != '': invest.diff = Decimal(diff) else: invest.diff = NotAvailable yield invest
def iter_investments(self): # We did not get some html, but something like that (XX is a quantity, YY a price): # message='[...] # popup=2{6{E:ALO{PAR{{reel{695{380{ALSTOM REGROUPT#XX#YY,YY €#YY,YY €#1 YYY,YY €#-YYY,YY €#-42,42%#-0,98 %#42,42 %#|1|AXA#cotationValeur.php?val=E:CS&pl=6&nc=1& # popup=2{6{E:CS{PAR{{reel{695{380{AXA#XX#YY,YY €#YY,YYY €#YYY,YY €#YY,YY €#3,70%#42,42 %#42,42 %#|1|blablablab #cotationValeur.php?val=P:CODE&pl=6&nc=1& # [...] lines = self.doc.split("popup=2") lines.pop(0) for line in lines: columns = line.split("#") _id = columns[0].split("{")[2] invest = Investment(_id) invest.label = unicode(columns[0].split("{")[-1]) invest.code = unicode(_id) if ":" in invest.code: invest.code = self.browser.titrevalue.open(val=invest.code).get_isin() quantity = FrenchTransaction.clean_amount(columns[1]) if quantity != "": invest.quantity = Decimal(quantity) else: invest.quantity = NotAvailable unitprice = FrenchTransaction.clean_amount(columns[2]) if unitprice != "": invest.unitprice = Decimal(unitprice) else: invest.unitprice = NotAvailable unitvalue = FrenchTransaction.clean_amount(columns[3]) if unitvalue != "": invest.unitvalue = Decimal(unitvalue) else: invest.unitvalue = NotAvailable valuation = FrenchTransaction.clean_amount(columns[4]) if valuation != "": invest.valuation = Decimal(valuation) else: invest.valuation = NotAvailable diff = FrenchTransaction.clean_amount(columns[5]) if diff != "": invest.diff = Decimal(diff) else: invest.diff = NotAvailable yield invest
def create_french_liquidity(valuation): """ Automatically fills a liquidity investment with label, code and code_type. """ liquidity = Investment() liquidity.label = "Liquidités" liquidity.code = "XX-liquidity" liquidity.code_type = NotAvailable liquidity.valuation = valuation return liquidity
def parse(self, el): i = None if CleanText(TableCell('code'))(self): i = Investment() i.label = Field('label')(self) i.code = unicode(TableCell('code')(self)[0].xpath('./text()[last()]')[0]).strip() i.quantity = MyDecimal(TableCell('quantity'))(self) i.valuation = Field('amount')(self) i.vdate = Field('date')(self) self.env['investments'] = [i] if i else []
def iter_investment(self): valuation = MyDecimal('//td[@class="donneeNumerique borderbottom "]/text()')(self.doc) if valuation is not None: inv = Investment() inv.code = 'XX-liquidity' inv.code_type = NotAvailable inv.label = 'Liquidités' inv.valuation = valuation yield inv for inv in self.get_investment(): yield inv
def iter_investment(self, account, invs=None): if account.id not in self.investments and invs is not None: self.investments[account.id] = [] for inv in invs: i = Investment() # If nothing is given to make the label, we use the ISIN instead # We let it crash if the ISIN is not available either. if all([inv['classification'], inv['description']]): i.label = "%s - %s" % (inv['classification'], inv['description']) else: i.label = Coalesce().filter(( inv['classification'], inv['description'], inv['isin'], )) i.code = inv['isin'] if not is_isin_valid(i.code): i.code = NotAvailable i.code_type = NotAvailable if u'Solde Espèces' in i.label: i.code = 'XX-liquidity' else: i.code_type = Investment.CODE_TYPE_ISIN i.quantity = CleanDecimal(default=NotAvailable).filter( inv['nombreParts']) i.unitprice = CleanDecimal(default=NotAvailable).filter( inv['prixMoyenAchat']) i.unitvalue = CleanDecimal(default=NotAvailable).filter( inv['valeurCotation']) i.valuation = CleanDecimal().filter(inv['montantEuro']) # For some invests the vdate returned is None # Consequently we set the default value at NotAvailable i.vdate = Date(default=NotAvailable).filter( inv['datePosition']) i.diff = CleanDecimal(default=NotAvailable).filter( inv['performanceEuro']) self.investments[account.id].append(i) return self.investments[account.id]
def iter_investments(self): for tr in self.doc.xpath('//table[@id="support"]/tbody/tr'): tds = tr.findall('td') inv = Investment() inv.label = CleanText('.')(tds[0]) inv.code = NotAvailable inv.quantity = MyDecimal('.')(tds[1]) inv.unitvalue = MyDecimal('.')(tds[2]) inv.valuation = MyDecimal('.')(tds[3]) yield inv
def obj_investments(self): inv = Investment() inv.quantity = CleanDecimal(TableCell('quantity'), replace_dots=True)(self) inv.code_type = Investment.CODE_TYPE_ISIN txt = CleanText(TableCell('name'))(self) match = re.match('(?:(.*) )?- ([^-]+)$', txt) inv.label = match.group(1) or NotAvailable inv.code = match.group(1) return [inv]
def iter_investment(self): for tbody in self.doc.xpath(u'//table[@summary="Contenu du portefeuille valorisé"]/tbody'): inv = Investment() inv.label = CleanText('.')(tbody.xpath('./tr[1]/td[1]/a/span')[0]) inv.code = CleanText('.')(tbody.xpath('./tr[1]/td[1]/a')[0]).split(' - ')[1] inv.quantity = self.parse_decimal(tbody.xpath('./tr[2]/td[2]')[0]) inv.unitvalue = self.parse_decimal(tbody.xpath('./tr[2]/td[3]')[0]) inv.unitprice = self.parse_decimal(tbody.xpath('./tr[2]/td[5]')[0]) inv.valuation = self.parse_decimal(tbody.xpath('./tr[2]/td[4]')[0]) inv.diff = self.parse_decimal(tbody.xpath('./tr[2]/td[7]')[0]) yield inv
def iter_investment(self, account): self.account.go(id=account.id) key = self.page.get_invest_key() self.invests.go() data = self.page.get_invest(*key) for item in data: inv = Investment() inv.code = item['isin'] inv.label = item['name'] inv.portfolio_share = item['share'] inv.valuation = account.balance * inv.portfolio_share yield inv
def iter_investment(self): for tbody in self.document.xpath(u'//table[@summary="Contenu du portefeuille valorisé"]/tbody'): inv = Investment() inv.label = self.parser.tocleanstring(tbody.xpath('./tr[1]/td[1]/a/span')[0]) inv.code = self.parser.tocleanstring(tbody.xpath('./tr[1]/td[1]/a')[0]).split(' - ')[1] inv.quantity = self.parse_decimal(tbody.xpath('./tr[2]/td[2]')[0]) inv.unitvalue = self.parse_decimal(tbody.xpath('./tr[2]/td[3]')[0]) inv.unitprice = self.parse_decimal(tbody.xpath('./tr[2]/td[5]')[0]) inv.valuation = self.parse_decimal(tbody.xpath('./tr[2]/td[4]')[0]) inv.diff = self.parse_decimal(tbody.xpath('./tr[2]/td[7]')[0]) yield inv
def iter_investment(self): valuation = CleanDecimal( '//li[h4[contains(text(), "Solde Espèces")]]/h3', replace_dots=True, default=None)(self.doc) if valuation: inv = Investment() inv.code = u"XX-liquidity" inv.label = u"Liquidités" inv.valuation = valuation yield inv for inv in self.get_investment(): yield inv
def iter_investment(self): valuation = CleanDecimal( '//td[contains(text(), "Liquidités")]/following-sibling::td[1]', replace_dots=True, default=None)(self.doc) if valuation: inv = Investment() inv.code = u"XX-liquidity" inv.label = u"Liquidités" inv.valuation = valuation yield inv for inv in self.get_investment(): yield inv
def get_investments(self): for line in self.document.xpath('//table[@id="tableau_support"]/tbody/tr'): cols = line.findall('td') inv = Investment() inv.id = unicode(re.search('cdReferentiel=(.*)', cols[self.COL_LABEL].find('a').attrib['href']).group(1)) inv.code = re.match('^[A-Z]+[0-9]+(.*)$', inv.id).group(1) inv.label = self.parser.tocleanstring(cols[self.COL_LABEL]) inv.quantity = self.parse_decimal(cols[self.COL_QUANTITY]) inv.unitprice = self.parse_decimal(cols[self.COL_UNITPRICE]) inv.unitvalue = self.parse_decimal(cols[self.COL_UNITVALUE]) inv.valuation = self.parse_decimal(cols[self.COL_VALUATION]) inv.diff = self.parse_decimal(cols[self.COL_PERF]) yield inv
def iter_investments(self, data): acc = data['acc'] for disp in self.doc['positionsSalarieDispositifDto']: if disp['codeDispositif'] == acc.id: for ele in disp['positionsSalarieFondsDto']: if ele['mtBrut']: inv = Investment() inv.label = ele['libelleFonds'] inv.code = ele['codeIsin'] inv.description = inv.label inv.quantity = Decimal(ele['nbParts']) inv.unitvalue = Decimal(ele['vl']) inv.valuation = inv.unitvalue * inv.quantity inv.diff = Decimal(ele['mtPMV']) yield inv
def get_investments(self): for line in self.document.xpath('//table[contains(@summary, "Contenu")]/tbody/tr[@class="color4"]'): cols1 = line.findall('td') cols2 = line.xpath('./following-sibling::tr')[0].findall('td') inv = Investment() inv.label = self.parser.tocleanstring(cols1[self.COL_LABEL].xpath('.//span')[0]) inv.code = self.parser.tocleanstring(cols1[self.COL_LABEL].xpath('./a')[0]).split(' ')[-1] inv.quantity = self.parse_decimal(cols2[self.COL_QUANTITY]) inv.unitprice = self.parse_decimal(cols2[self.COL_UNITPRICE]) inv.unitvalue = self.parse_decimal(cols2[self.COL_UNITVALUE]) inv.valuation = self.parse_decimal(cols2[self.COL_VALUATION]) inv.diff = self.parse_decimal(cols2[self.COL_PERF]) yield inv
def get_deposit_investment(self): COL_LABEL = 0 COL_QUANTITY = 3 COL_UNITVALUE = 4 COL_VALUATION = 5 for tr in self.document.xpath('//table[@class="datas"]/tr[not(@class="entete")]'): cols = tr.findall('td') inv = Investment() inv.label = self.parser.tocleanstring(cols[COL_LABEL].xpath('.//a')[0]) inv.code = self.parser.tocleanstring(cols[COL_LABEL]).replace(inv.label, "").split(' ')[0].split(u'\xa0')[0] inv.quantity = self.parse_decimal(cols[COL_QUANTITY]) inv.unitvalue = self.parse_decimal(cols[COL_UNITVALUE]) inv.valuation = self.parse_decimal(cols[COL_VALUATION]) yield inv
def get_deposit_investment(self): COL_LABEL = 0 COL_QUANTITY = 3 COL_UNITVALUE = 4 COL_VALUATION = 5 for tr in self.document.xpath('//table[@class="datas"]/tr[not(@class="entete")]'): cols = tr.findall('td') inv = Investment() inv.label = self.parser.tocleanstring(cols[COL_LABEL].xpath('.//a')[0]) inv.code = self.parser.tocleanstring(cols[COL_LABEL]).replace(inv.label, "") inv.quantity = self.parse_decimal(cols[COL_QUANTITY]) inv.unitvalue = self.parse_decimal(cols[COL_UNITVALUE]) inv.valuation = self.parse_decimal(cols[COL_VALUATION]) yield inv
def iter_investment(self, account, invs=None): if account.id not in self.investments and invs is not None: self.investments[account.id] = [] for inv in invs: i = Investment() i.label = "%s - %s" % (inv['classification'], inv['description']) i.code = inv['isin'] i.quantity = CleanDecimal().filter(inv['nombreParts']) i.unitprice = CleanDecimal().filter(inv['prixMoyenAchat']) i.unitvalue = CleanDecimal().filter(inv['valeurCotation']) i.valuation = CleanDecimal().filter(inv['montantEuro']) i.vdate = Date().filter(inv['datePosition']) i.diff = CleanDecimal().filter(inv['performanceEuro']) self.investments[account.id].append(i) return self.investments[account.id]
def iter_investment(self, account, invs=None): if account.id not in self.investments and invs is not None: self.investments[account.id] = [] for inv in invs: i = Investment() i.label = "%s - %s" % (inv['classification'], inv['description']) i.code = inv['isin'] i.code_type = Investment.CODE_TYPE_ISIN i.quantity = CleanDecimal().filter(inv['nombreParts']) i.unitprice = CleanDecimal().filter(inv['prixMoyenAchat']) i.unitvalue = CleanDecimal().filter(inv['valeurCotation']) i.valuation = CleanDecimal().filter(inv['montantEuro']) i.vdate = Date().filter(inv['datePosition']) i.diff = CleanDecimal().filter(inv['performanceEuro']) self.investments[account.id].append(i) return self.investments[account.id]
def obj_investments(self): inv = Investment() inv.quantity = CleanDecimal(TableCell('quantity'), replace_dots=True)(self) inv.code_type = Investment.CODE_TYPE_ISIN txt = CleanText(TableCell('name'))(self) match = re.match('(?:(.*) )?- ([^-]+)$', txt) inv.label = match.group(1) or NotAvailable inv.code = match.group(2) if inv.code in self.parent.labels: inv.label = inv.label or self.parent.labels[inv.code] elif inv.label: self.parent.labels[inv.code] = inv.label else: inv.label = inv.code return [inv]
def iter_investment(self): rows = self.document.xpath('//table[@id="mefav_repartition_supports_BPF"]//tr') or \ self.document.xpath('//tbody[@id="mefav_repartition_supports"]//tr') for tr in rows: cells = clean_cells(tr.findall('td')) cells[3:] = clean_amounts(cells[3:]) inv = Investment() inv.label, _, inv.code, inv.quantity, inv.unitvalue, inv.valuation, _ = cells if inv.code: inv.id = inv.code if not inv.unitvalue: # XXX Fonds eu Euros inv.code = u'XX' + re.sub(ur'[^A-Za-z0-9]', u'', inv.label).upper() inv.description = u'' yield inv
def iter_investment(self): for line in self.document.xpath('//table[contains(@class, "ca-data-table")]/descendant::tr[count(td)=8]'): cells = line.findall('td') inv = Investment() inv.label = unicode(cells[self.COL_ID].find('div/a').text.strip()) inv.code = cells[self.COL_ID].find('div/br').tail.strip() inv.quantity = self.parse_decimal(cells[self.COL_QUANTITY].find('span').text) inv.valuation = self.parse_decimal(cells[self.COL_VALUATION].text) inv.diff = self.parse_decimal(cells[self.COL_DIFF].text_content()) if "%" in cells[self.COL_UNITPRICE].text and "%" in cells[self.COL_UNITVALUE].text: inv.unitvalue = inv.valuation / inv.quantity inv.unitprice = (inv.valuation - inv.diff) / inv.quantity else: inv.unitprice = self.parse_decimal(cells[self.COL_UNITPRICE].text) inv.unitvalue = self.parse_decimal(cells[self.COL_UNITVALUE].text) yield inv
def iter_history(self): for op in self.get('contentList') or []: tr = Transaction.from_dict({ 'type': Transaction.TYPE_BANK, 'amount': op.get('movementAmount'), 'date': datetime.fromtimestamp(op.get('movementDate') / 1000), 'label': op.get('operationName'), }) tr.investments = [] inv = Investment() inv.code = op.get('securityCode') inv.quantity = op.get('movementQuantity') inv.label = op.get('securityName') inv.set_empty_fields(NotAvailable) tr.investments.append(inv) yield tr
def get_investments(self): for line in self.document.xpath( '//table[contains(@summary, "Contenu")]/tbody/tr[@class="color4"]' ): cols1 = line.findall('td') cols2 = line.xpath('./following-sibling::tr')[0].findall('td') inv = Investment() inv.label = self.parser.tocleanstring( cols1[self.COL_LABEL].xpath('.//span')[0]) inv.code = self.parser.tocleanstring( cols1[self.COL_LABEL].xpath('./a')[0]).split(' ')[-1] inv.quantity = self.parse_decimal(cols2[self.COL_QUANTITY]) inv.unitprice = self.parse_decimal(cols2[self.COL_UNITPRICE]) inv.unitvalue = self.parse_decimal(cols2[self.COL_UNITVALUE]) inv.valuation = self.parse_decimal(cols2[self.COL_VALUATION]) inv.diff = self.parse_decimal(cols2[self.COL_PERF]) yield inv
def get_investments(self, account): for line in self.doc.xpath('//table[@id="tableau_support"]/tbody/tr'): cols = line.findall('td') inv = Investment() inv.id = re.search('cdReferentiel=(.*)', cols[self.COL_LABEL].find('a').attrib['href']).group(1) inv.code = re.match('^[A-Z]+[0-9]+(.*)$', inv.id).group(1) inv.label = CleanText(None).filter(cols[self.COL_LABEL]) inv.quantity = self.parse_decimal(cols[self.COL_QUANTITY]) inv.unitprice = self.parse_decimal(cols[self.COL_UNITPRICE]) inv.unitvalue = self.parse_decimal(cols[self.COL_UNITVALUE]) inv.vdate = Date(CleanText(cols[self.COL_DATE], default=NotAvailable), default=NotAvailable)(self.doc) inv.valuation = self.parse_decimal(cols[self.COL_VALUATION]) inv.diff = self.parse_decimal(cols[self.COL_PERF]) diff_percent = self.parse_decimal(cols[self.COL_PERF_PERCENT]) inv.diff_percent = diff_percent / 100 if diff_percent else NotAvailable if is_isin_valid(inv.code): inv.code_type = Investment.CODE_TYPE_ISIN yield inv
def iter_investment(self): cleaner = CleanText().filter for line in self.doc.xpath('//div[@class="supportTable"]//table/tbody/tr'): tds = line.findall('td') if len(tds) < 4: continue inv = Investment() if self.doc.xpath('//div[@id="table-evolution-contrat"]//table/tbody/tr[1]/td[1]'): inv.vdate = Date(dayfirst=True).filter(CleanText().filter( self.doc.xpath('//div[@id="table-evolution-contrat"]//table/tbody/tr[1]/td[1]'))) else: inv.vdate = NotAvailable inv.label = cleaner(tds[self.COL_LABEL]) inv.code = cleaner(tds[self.COL_CODE]) inv.valuation = Decimal(FrenchTransaction.clean_amount( cleaner(tds[self.COL_VALUATION]))) inv.portfolio_share = Decimal(FrenchTransaction.clean_amount( cleaner(tds[self.COL_PORTFOLIO_SHARE]))) / 100 yield inv
def iter_investments(self): # We did not get some html, but something like that (XX is a quantity, YY a price): # message='[...] #popup=2{6{E:ALO{PAR{{reel{695{380{ALSTOM REGROUPT#XX#YY,YY €#YY,YY €#1 YYY,YY €#-YYY,YY €#-42,42%#-0,98 %#42,42 %#|1|AXA#cotationValeur.php?val=E:CS&pl=6&nc=1& #popup=2{6{E:CS{PAR{{reel{695{380{AXA#XX#YY,YY €#YY,YYY €#YYY,YY €#YY,YY €#3,70%#42,42 %#42,42 %#|1|blablablab #cotationValeur.php?val=P:CODE&pl=6&nc=1& # [...] lines = self.document.split("popup=2") lines.pop(0) for line in lines: columns = line.split('#') code = columns[0].split('{')[2] invest = Investment(code) invest.code = code invest.label = columns[0].split('{')[-1] invest.quantity = int(columns[1]) invest.unitprice = Decimal(FrenchTransaction.clean_amount(columns[2])) invest.unitvalue = Decimal(FrenchTransaction.clean_amount(columns[3])) invest.valuation = Decimal(FrenchTransaction.clean_amount(columns[4])) invest.diff = Decimal(FrenchTransaction.clean_amount(columns[5])) yield invest
def get_investments(self): for line in self.document.xpath('//table[@id="t_intraday"]/tbody/tr'): if line.find_class('categorie') or line.find_class('detail') or line.find_class('detail02'): continue cols = line.findall('td') inv = Investment() inv.label = self.parser.tocleanstring(cols[self.COL_LABEL]) link = cols[self.COL_LABEL].xpath('./a[contains(@href, "cdReferentiel")]')[0] inv.id = unicode(re.search('cdReferentiel=(.*)', link.attrib['href']).group(1)) inv.code = re.match('^[A-Z]+[0-9]+(.*)$', inv.id).group(1) inv.quantity = self.parse_decimal(cols[self.COL_QUANTITY]) inv.unitprice = self.parse_decimal(cols[self.COL_UNITPRICE]) inv.unitvalue = self.parse_decimal(cols[self.COL_UNITVALUE]) inv.valuation = self.parse_decimal(cols[self.COL_VALUATION]) diff = cols[self.COL_PERF].text.strip() if diff == "-": inv.diff = NotAvailable else: inv.diff = Decimal(Transaction.clean_amount(diff)) yield inv