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 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, 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 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 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, account): today = datetime.date.today() self.coming.go() # unfortunately there doesn't seem to be a page indicating what's # left to be repaid on each project, so let's sum... valuations = {} commissions = {} for tr in self.page.iter_transactions(): if tr.date <= today: continue if tr.raw not in valuations: valuations[tr.raw] = tr.amount commissions[tr.raw] = tr.commission else: valuations[tr.raw] += tr.amount commissions[tr.raw] += tr.commission for label, value in valuations.items(): inv = Investment() inv.label = label inv.valuation = value inv.diff = commissions[label] yield inv yield create_french_liquidity(account._liquidities)
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 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_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): 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 get_investments(self): for line in self.document.xpath('//div[@class="row-fluid table-contrat-supports"]/table/tbody[(@class)]/tr'): cols = line.findall('td') inv = Investment() inv.label = self.parser.tocleanstring(cols[self.COL_LABEL]).replace('Cas sans risque ', '') inv.quantity = self.parse_decimal(cols[self.COL_QUANTITY]) inv.unitvalue = self.parse_decimal(cols[self.COL_UNITVALUE]) inv.valuation = self.parse_decimal(cols[self.COL_VALUATION]) yield inv
def obj_investments(self): investments = [] for elem in self.xpath( './following-sibling::div[1]//tbody/tr'): inv = Investment() inv.label = CleanText('./td[1]')(elem) inv.valuation = Coalesce( CleanDecimal.French('./td[2]/p', default=NotAvailable), CleanDecimal.French('./td[2]'))(elem) investments.append(inv) return investments
def iter_investments(self): for support in self.path(self.investments_path): inv = Investment() inv.code = inv.id = support['securityCode'] inv.quantity = support['quantityOwned'] inv.unitvalue = support['currentQuote'] inv.unitprice = support['averagePrice'] inv.label = support['securityName'] inv.valuation = support['valorizationValuation'] inv.diff = support['profitLossValorisation'] inv.set_empty_fields(NotAvailable) 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): 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_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 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 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_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_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): item = self.doc.xpath( u'//table[@summary="Liste des échéances"]/tfoot/tr/td[@class="tot _c1 d _c1"]' )[0] total = CleanDecimal(Regexp(CleanText('.'), '(.*) .*'), default=1, replace_dots=True)(item) item_xpath = u'((//table[@summary="Liste des échéances"])[1]/tbody/tr)[position() < last() and not(contains(./td[1]/@class, "tittot"))]' obj = None for tr in self.doc.xpath(item_xpath): tds = tr.xpath('./td') if len(tds) > 3: if obj is not None: obj.portfolio_share = (obj.valuation / total).quantize( Decimal('.0001')) yield obj obj = Investment() obj.label = CleanText('.')(tds[0]) obj.vdate = date.today( ) # * En réalité derniere date de valorisation connue obj.unitvalue = CleanDecimal('.', replace_dots=True)(tds[2]) obj.valuation = CleanDecimal('.', replace_dots=True)(tds[5]) obj.quantity = CleanDecimal('.', replace_dots=True)(tds[4]) elif obj is not None: obj.quantity += CleanDecimal('.', replace_dots=True)(tds[1]) obj.valuation += CleanDecimal('.', replace_dots=True)(tds[2]) if obj is not None: obj.portfolio_share = (obj.valuation / total).quantize( Decimal('.0001')) yield obj
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_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): 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, 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 get_operations(self): for tr in self.doc.xpath('//table[@id="tabHistoriqueOperations"]/tbody/tr'): tds = tr.findall('td') if len(CleanText(None).filter(tds[-1])) == 0: continue t = Transaction() t.type = Transaction.TYPE_BANK t.parse(date=CleanText(None).filter(tds[3]), raw=CleanText(None).filter(tds[1])) t.amount = CleanDecimal(None, replace_dots=True, default=0).filter(tds[-2]) t.commission = CleanDecimal(None, replace_dots=True, default=0).filter(tds[-3]) investment = Investment() investment.label = CleanText(None).filter(tds[0]) investment.quantity = CleanDecimal(None, replace_dots=True, default=0).filter(tds[4]) investment.unitvalue = CleanDecimal(None, replace_dots=True, default=0).filter(tds[5]) t.investments = [investment] yield t
def iter_investment(self): item = self.doc.xpath(u'//table[@summary="Liste des échéances"]/tfoot/tr/td[@class="tot _c1 d _c1"]')[0] total = CleanDecimal(Regexp(CleanText('.'), '(.*) .*'), default=1, replace_dots=True)(item) item_xpath = u'((//table[@summary="Liste des échéances"])[1]/tbody/tr)[position() < last() and not(contains(./td[1]/@class, "tittot"))]' obj = None for tr in self.doc.xpath(item_xpath): tds = tr.xpath('./td') if len(tds) > 3: if obj is not None: obj.portfolio_share = (obj.valuation / total).quantize(Decimal('.0001')) yield obj obj = Investment() obj.label = CleanText('.')(tds[0]) obj.vdate = date.today() # * En réalité derniere date de valorisation connue obj.unitvalue = CleanDecimal('.', replace_dots=True)(tds[2]) obj.valuation = CleanDecimal('.', replace_dots=True)(tds[5]) obj.quantity = CleanDecimal('.', replace_dots=True)(tds[4]) elif obj is not None: obj.quantity += CleanDecimal('.', replace_dots=True)(tds[1]) obj.valuation += CleanDecimal('.', replace_dots=True)(tds[2]) if obj is not None: obj.portfolio_share = (obj.valuation / total).quantize(Decimal('.0001')) yield obj
def get_transactions_from_detail(self, account): for label, page in account._history_pages: amounts = page.doc.xpath( '//span[contains(text(), "Montant")]/following-sibling::span') if len(amounts) == 3: amounts.pop(0) for table in page.doc.xpath('//table'): t = Transaction() t.date = Date(CleanText( page.doc.xpath( '//span[contains(text(), "Date d\'effet")]/following-sibling::span' )), dayfirst=True)(page) t.label = label t.amount = CleanDecimal(replace_dots=True).filter(amounts[0]) amounts.pop(0) t._is_coming = False t.investments = [] for tr in table.xpath('./tbody/tr'): i = Investment() i.label = CleanText().filter(tr.xpath('./td[1]')) i.vdate = Date(CleanText(tr.xpath('./td[2]')), dayfirst=True)(tr) i.unitvalue = CleanDecimal(replace_dots=True).filter( tr.xpath('./td[3]')) i.quantity = CleanDecimal(replace_dots=True).filter( tr.xpath('./td[4]')) i.valuation = CleanDecimal(replace_dots=True).filter( tr.xpath('./td[5]')) t.investments.append(i) yield t
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 get_investment(self): Decimal = CleanDecimal(replace_dots=True).filter for tr in self._tr_list(self.document): cells = [el_to_string(td) for td in self._td_list(tr)] link = unicode(self._link(tr)[0]) ''' Boursorama table cells ---------------------- 0. Fonds 1. Date de valeur 2. Valeur de part 3. Nombre de parts 4. Contre valeur 5. Prix revient 6. +/- value en €* 7. +/- value en %* Investment model ---------------- label = StringField('Label of stocks') code = StringField('Identifier of the stock (ISIN code)') description = StringField('Short description of the stock') quantity = IntField('Quantity of stocks') unitprice = DecimalField('Buy price of one stock') unitvalue = DecimalField('Current value of one stock') valuation = DecimalField('Total current valuation of the Investment') diff = DecimalField('Difference between the buy cost and the current valuation') ''' inv = Investment() isin = self.get_isin(link) if isin: inv.id = inv.code = isin inv.label = cells[0] inv.quantity = Decimal(cells[3]) inv.valuation = Decimal(cells[4]) inv.unitprice = Decimal(cells[5]) inv.unitvalue = Decimal(cells[2]) inv.diff = Decimal(cells[6]) inv._detail_url = link if '/cours.phtml' in link else None 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 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 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 iter_investment(self): el_list = self.doc.xpath('//table[@class="liste"]/tbody/tr') for index, el in enumerate(el_list): try: rowspan = int(Attr(el.xpath('./td[has-class("g")]'), 'rowspan')(self)) except: continue inv = Investment() inv.label = CleanText(el.xpath('./td[has-class("i g")]'))(self.doc) inv.valuation = MyDecimal(el.xpath('./td[last()]'))(self.doc) inv._pocket_url = None for i in range(1, rowspan): # valuation is not directly written on website, but it's separated by pocket, so we compute it here, # and is also written in footer so it's sum of all valuation, not just one inv.valuation += MyDecimal(el_list[index+i].xpath('./td[last()]'))(self.doc) yield 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_investments(self): for support in self.path(self.investments_path): inv = Investment() if 'codeIsin' in support: inv.code = inv.id = support['codeIsin'] inv.quantity = support['nbUC'] inv.unitvalue = support['valUC'] inv.label = support['libelle'] inv.valuation = support['montant'] inv.set_empty_fields(NotAvailable) yield inv
def iter_investment(self): table = self.document.xpath('//table[@align="center"]')[4] rows = table.xpath('.//tr[@class="hdoc1"]') for tr in rows: cells = clean_cells(tr.findall('td')) cells[2:] = clean_amounts(cells[2:]) inv = Investment() inv.label, _, inv.quantity, inv.unitvalue, inv.valuation = cells tr2 = tr.xpath('./following-sibling::tr')[0] tr2td = tr2.findall('td')[1] inv.id = inv.code = clean_text(tr2.xpath('.//a')[0]) inv.unitprice = clean_amount(tr2td.xpath('.//td[@class="hdotc1nb"]')[0].text) inv.description = u'' if inv.unitprice: inv.diff = inv.quantity * inv.unitprice - inv.valuation yield inv
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 get_transactions_from_detail(self, account): for label, page in account._history_pages: amounts = page.doc.xpath('//span[contains(text(), "Montant")]/following-sibling::span') if len(amounts) == 3: amounts.pop(0) for table in page.doc.xpath('//table'): t = Transaction() t.date = Date(CleanText(page.doc.xpath('//span[contains(text(), "Date d\'effet")]/following-sibling::span')), dayfirst=True)(page) t.label = label t.amount = CleanDecimal(replace_dots=True).filter(amounts[0]) amounts.pop(0) t._is_coming = False t.investments = [] sum_amount = 0 for tr in table.xpath('./tbody/tr'): i = Investment() i.label = CleanText().filter(tr.xpath('./td[1]')) i.vdate = Date(CleanText(tr.xpath('./td[2]')), dayfirst=True)(tr) i.unitvalue = CleanDecimal(replace_dots=True).filter(tr.xpath('./td[3]')) i.quantity = CleanDecimal(replace_dots=True).filter(tr.xpath('./td[4]')) i.valuation = CleanDecimal(replace_dots=True).filter(tr.xpath('./td[5]')) sum_amount += i.valuation t.investments.append(i) if t.label == 'prélèvement': t.amount = sum_amount yield t
def iter_investment(self): for tr in self.document.xpath(u'//table[@class="boursedetail"]/tr[@class and not(@class="total")]'): inv = Investment() libelle = self.parser.tocleanstring(tr.xpath('./td[1]')[0]).split(' ') inv.label, inv.code = self.split_label_code(libelle) diff = self.parse_decimal(tr.xpath('./td[6]')[0]) inv.quantity = self.parse_decimal(tr.xpath('./td[2]')[0]) inv.unitvalue = self.parse_decimal(tr.xpath('./td[3]')[0]) inv.unitprice = self.calc(inv.unitvalue, diff) inv.valuation = self.parse_decimal(tr.xpath('./td[5]')[0]) inv.diff = self.get_diff(inv.valuation, self.calc(inv.valuation, diff)) 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('#') _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) yield invest
def get_accounts_list(self): data = {'clang': self.LANG, 'ctcc': self.CTCC, 'login': self.username, 'session': self.sessionId} for dispositif in self.accountsp.open(data=data).get_list(): if dispositif['montantBrutDispositif'] == 0: continue a = Account() a.id = dispositif['codeDispositif'] a.type = Account.TYPE_MARKET a.balance = Decimal(dispositif["montantBrutDispositif"]).quantize(Decimal('.01')) a.label = dispositif['titreDispositif'] a.currency = u"EUR" # Don't find any possbility to get that from configuration. a._investments = [] for fund in dispositif['listeFonds']: if fund['montantValeurEuro'] == 0: continue i = Investment() i.id = i.code = dispositif['codeEntreprise'] + dispositif["codeDispositif"] + fund["codeSupport"] i.label = fund['libelleSupport'] i.unitvalue = Decimal(fund["montantValeur"]).quantize(Decimal('.01')) i.valuation = Decimal(fund["montantValeurEuro"]).quantize(Decimal('.01')) i.quantity = i.valuation / i.unitvalue i.vdate = parse_date(fund['dateValeur'], dayfirst=True) a._investments.append(i) yield a
def get_investment(self): Decimal = CleanDecimal(replace_dots=True).filter for tr in self._tr_list(self.document): cells = list(el_to_string(td) for td in self._td_list(tr)) link = unicode(self._link(tr)[0]) ''' Boursorama table cells ---------------------- 0. Fonds 1. Date de valeur 2. Valeur de part 3. Nombre de parts 4. Contre valeur 5. Prix revient 6. +/- value en €* 7. +/- value en %* Investment model ---------------- label = StringField('Label of stocks') code = StringField('Identifier of the stock (ISIN code)') description = StringField('Short description of the stock') quantity = IntField('Quantity of stocks') unitprice = DecimalField('Buy price of one stock') unitvalue = DecimalField('Current value of one stock') valuation = DecimalField('Total current valuation of the Investment') diff = DecimalField('Difference between the buy cost and the current valuation') ''' inv = Investment() isin = self.get_isin(link) if isin: inv.id = inv.code = isin inv.label = cells[0] inv.quantity = Decimal(cells[3]) inv.valuation = Decimal(cells[4]) inv.unitprice = Decimal(cells[5]) inv.unitvalue = Decimal(cells[2]) inv.diff = Decimal(cells[6]) inv._detail_url = link if '/cours.phtml' in link else None yield inv
def iter_investment(self, label): for tr in self.doc.xpath(u'//table[@summary="Liste des échéances"]/tbody/tr'): # list containing the numerical values # element 1 is the quantity # element 2 is the valuation tds = tr.findall('td[@class="i d"]') # var containing the label td_label = tr.find('td[@class="i g"]') inv = Investment() if len(tds) <= 2: continue inv.label = CleanText(td_label)(tr) inv.quantity = CleanDecimal(tds[1], replace_dots=True)(tr) inv.valuation = CleanDecimal(tds[2], replace_dots=True)(tr) if 'PEI' in label.split()[0]: label = 'PEE' if Regexp(CleanText(td_label), '\(([\w]+).*\)$')(tr) not in label.split()[0]: continue 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 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 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 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 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 not account.url or account.type not in (Account.TYPE_MARKET, Account.TYPE_PEA, Account.TYPE_LIFE_INSURANCE): return if account._perimeter != self.current_perimeter: self.go_perimeter(account._perimeter) if account.type == Account.TYPE_PEA and account._liquidity_url: liquidity_inv = Investment() liquidity_inv.label = account.label liquidity_inv.code = u'XX-liquidity' liquidity_inv.valuation = account.balance yield liquidity_inv if account.type in (Account.TYPE_MARKET, Account.TYPE_PEA): new_location = self.moveto_market_website(account) # Detail unavailable try: self.location(new_location) except BrowserHTTPError: return elif account.type == Account.TYPE_LIFE_INSURANCE: new_location = self.moveto_insurance_website(account) self.location(new_location, data={}) if self.bgpi.is_here(): if self.page.cgu_needed() or not self.page.go_detail(): return if self.lifeinsurance.is_here(): self.page.go_on_detail(account.id) for inv in self.page.iter_investment(): yield inv if account.type in (Account.TYPE_MARKET, Account.TYPE_PEA): self.quit_market_website() elif account.type == Account.TYPE_LIFE_INSURANCE: self.quit_insurance_website()
def iter_investment(self): for tr in self.doc.xpath( u'//table[@class="boursedetail"]/tr[@class and not(@class="total")]' ): inv = Investment() libelle = CleanText('.')(tr.xpath('./td[1]')[0]).split(' ') inv.label, inv.code = self.split_label_code(libelle) diff = self.parse_decimal(tr.xpath('./td[6]')[0]) inv.quantity = self.parse_decimal(tr.xpath('./td[2]')[0]) inv.unitvalue = self.parse_decimal(tr.xpath('./td[3]')[0]) date = CleanText('.')(tr.xpath('./td[4]')[0]) inv.vdate = Date(dayfirst=True).filter( date) if date and date != '-' else NotAvailable inv.unitprice = self.calc(inv.unitvalue, diff) inv.valuation = self.parse_decimal(tr.xpath('./td[5]')[0]) inv.diff = self.get_diff(inv.valuation, self.calc(inv.valuation, diff)) yield inv
def iter_investment(self, label): for tr in self.doc.xpath( u'//table[@summary="Liste des échéances"]/tbody/tr'): # list containing the numerical values # element 1 is the quantity # element 2 is the valuation tds = tr.findall('td[@class="i d"]') # var containing the label td_label = tr.find('td[@class="i g"]') inv = Investment() if len(tds) <= 2: continue inv.label = CleanText(td_label)(tr) inv.quantity = CleanDecimal(tds[1], replace_dots=True)(tr) inv.valuation = CleanDecimal(tds[2], replace_dots=True)(tr) if 'PEI' in label.split()[0]: label = 'PEE' if Regexp(CleanText(td_label), '\(([\w]+).*\)$')(tr) not in label.split()[0]: continue yield inv
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