diff --git a/CHANGES.txt b/CHANGES.txt index 35a34f3..c13b2da 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,3 +2,23 @@ --- - Initial version + + + +>>> quote.info +{'language': 'en-US', 'region': 'US', 'quoteType': 'ETF', 'quoteSourceName': 'Delayed Quote', 'currency': 'USD', 'regularMarketChange': -0.5200043, +'regularMarketOpen': 93.81, 'regularMarketDayHigh': 93.91, 'regularMarketDayLow': 92.44, 'regularMarketVolume': 4040066, 'askSize': 14, +'messageBoardId': 'finmb_22939711', 'fullExchangeName': 'NYSEArca', 'longName': 'Vanguard Real Estate Index Fund ETF Shares', +'financialCurrency': 'USD', 'averageDailyVolume3Month': 4826021, 'averageDailyVolume10Day': 4604087, 'fiftyTwoWeekLowChange': 22.009995, +'fiftyTwoWeekLowChangePercent': 0.30965102, 'fiftyTwoWeekRange': '71.08 - 94.07', 'fiftyTwoWeekHighChange': -0.98000336, +'fiftyTwoWeekHighChangePercent': -0.01041781, 'fiftyTwoWeekLow': 71.08, 'fiftyTwoWeekHigh': 94.07, 'esgPopulated': False, 'tradeable': True, +'trailingAnnualDividendRate': 3.533, 'trailingPE': 8.381201, 'trailingAnnualDividendYield': 0.037741695, 'ytdReturn': 25.76, +'trailingThreeMonthReturns': 7.14, 'trailingThreeMonthNavReturns': 7.21, 'epsTrailingTwelveMonths': 11.107, 'marketState': 'CLOSED', +'postMarketChangePercent': 0.042970154, 'postMarketTime': 1569618175, 'postMarketPrice': 93.13, 'postMarketChange': 0.040000916, +'regularMarketChangePercent': -0.55550075, 'regularMarketDayRange': '92.44 - 93.91', 'regularMarketPreviousClose': 93.61, 'bid': 93.03, +'ask': 93.13, 'bidSize': 11, 'exchange': 'PCX', 'shortName': 'Vanguard Real Estate ETF', 'exchangeDataDelayedBy': 0, 'priceHint': 2, +'sharesOutstanding': 370180992, 'bookValue': 63.751, 'fiftyDayAverage': 92.157425, 'fiftyDayAverageChange': 0.9325714, +'fiftyDayAverageChangePercent': 0.01011933, 'twoHundredDayAverage': 88.83857, 'twoHundredDayAverageChange': 4.2514267, +'twoHundredDayAverageChangePercent': 0.04785564, 'marketCap': 34460147712, 'priceToBook': 1.4602123, 'sourceInterval': 15, +'exchangeTimezoneName': 'America/New_York', 'exchangeTimezoneShortName': 'EDT', 'gmtOffSetMilliseconds': -14400000, 'triggerable': False, +'market': 'us_market', 'regularMarketPrice': 93.09, 'regularMarketTime': 1569614400, 'symbol': 'VNQ'} \ No newline at end of file diff --git a/caotek_mesavoirs/layout.py b/caotek_mesavoirs/layout.py index b120662..d0db947 100644 --- a/caotek_mesavoirs/layout.py +++ b/caotek_mesavoirs/layout.py @@ -3,6 +3,7 @@ from pyramid_layout.layout import layout_config from .security import groupfinder from .views.default import ( to_euro, + to_usd, to_percent, to_decimal, ) @@ -22,6 +23,9 @@ class GlobalLayout(object): def to_euro(self, x): return to_euro(x) + def to_usd(self, x): + return to_usd(x) + def to_percent(self, x, d): return to_percent(x, d) diff --git a/caotek_mesavoirs/models/actifs.py b/caotek_mesavoirs/models/actifs.py index ee079c4..e6763c2 100644 --- a/caotek_mesavoirs/models/actifs.py +++ b/caotek_mesavoirs/models/actifs.py @@ -10,7 +10,6 @@ from zope.sqlalchemy import ZopeTransactionExtension, mark_changed from datetime import * import transaction -from bs4 import BeautifulSoup from urllib.request import urlopen from .default import ( @@ -141,33 +140,5 @@ def delete_histo(request, no_id): query = "DELETE FROM histo WHERE no_id = :no_id ;" execute_query(request, query, {'no_id': no_id}) -def getCurrencyRate(currency): - # specify the url - quote_page = 'https://markets.ft.com/data/currencies/tearsheet/summary?s=%seur' % currency - # query & parse the html using beautiful soap and store in variable `soup` - soup = BeautifulSoup(urlopen(quote_page), 'html.parser') - data_list = soup.find_all("span", class_="mod-ui-data-list__value") - if data_list: - # get the rate price in EUR - rate_price = float(data_list[0].text.replace(',','')) - else: - rate_price = 0.0 - - return rate_price - -def getFTQuote(ticker): - # specify the url of The Financial Times - quote_page = 'https://markets.ft.com/data/funds/tearsheet/historical?s=%s' % ticker - - # query & parse the html using beautiful soap and store in variable `soup` - soup = BeautifulSoup(urlopen(quote_page), 'html.parser') - data_list = soup.find_all("span", class_="mod-ui-data-list__value") - if data_list: - # get the quote price - quote_price = float(data_list[0].text.replace(',','')) - else: - quote_price = 0.0 - - return quote_price diff --git a/caotek_mesavoirs/templates/actifs/actif_edit.pt b/caotek_mesavoirs/templates/actifs/actif_edit.pt index 70ae4ed..1e20a40 100644 --- a/caotek_mesavoirs/templates/actifs/actif_edit.pt +++ b/caotek_mesavoirs/templates/actifs/actif_edit.pt @@ -31,39 +31,21 @@ data-fv-stringlength-max="15" data-fv-stringlength-message="15 caractères maximum" /> - -
- -
- +
+

${actif.libelle}

-
+
-
- -
- -
-
-
+
-
+
%
-
+
%
+
+ +
+

${actif.devise}

+
+
diff --git a/caotek_mesavoirs/templates/home.pt b/caotek_mesavoirs/templates/home.pt index fb481e2..43f62c7 100644 --- a/caotek_mesavoirs/templates/home.pt +++ b/caotek_mesavoirs/templates/home.pt @@ -115,7 +115,8 @@ ${ligne.classe} ${ligne.libelle} ${ligne.libelle} - ${layout.to_euro(ligne.cours)} + ${layout.to_euro(ligne.cours)} + ${layout.to_usd(ligne.cours)} ${ligne.nombre} ${layout.to_euro(ligne.valeur)} ${layout.to_euro(ligne.plus_value)} diff --git a/caotek_mesavoirs/views/actifs.py b/caotek_mesavoirs/views/actifs.py index 379abda..5421d7e 100644 --- a/caotek_mesavoirs/views/actifs.py +++ b/caotek_mesavoirs/views/actifs.py @@ -31,6 +31,7 @@ from ..views.default import ( import json import time +import yfinance as yf @view_config(route_name='actif_edit', renderer='../templates/actifs/actif_edit.pt', permission='view') @@ -70,14 +71,16 @@ def actif_edit(request): new_values[param] = request.params[param] if new_values: - # récupérer les infos du symbole de FT finance if 'symbole' in request.params: symbole = request.params['symbole'] else: symbole = actif.symbole - new_values['cours'] = getFTQuote(symbole) - + # récupérer le cours du symbole de Yahoo finance + ticker = yf.Ticker(symbole) + new_values['cours'] = ticker.info.get('regularMarketPrice') + new_values['devise'] = ticker.info.get('currency') + new_values['libelle'] = ticker.info.get('longName').replace('Distributing','').replace('Amundi Index Solutions - ','') update_actif(request, no_id, new_values) request.session.flash(u"La fiche a été mise à jour avec succès.", 'success') return HTTPFound(location=request.route_url('home')) @@ -244,7 +247,8 @@ def histo_edit(request): if new_values: # lire le cours de l'indice de réfence : Carmignac Investissement A EUR Acc - new_values['cours_ref'] = getFTQuote('FR0010148981:EUR') + ticker = yf.Ticker('0P00000FB2.F') + new_values['cours_ref'] = ticker.info.get('regularMarketPrice') update_histo(request, no_id, new_values) request.session.flash(u"La fiche a été mise à jour avec succès.", 'success') diff --git a/caotek_mesavoirs/views/default.py b/caotek_mesavoirs/views/default.py index a29f9fc..3648540 100644 --- a/caotek_mesavoirs/views/default.py +++ b/caotek_mesavoirs/views/default.py @@ -27,6 +27,7 @@ from ..models.members import ( import time import hashlib import json +import yfinance as yf def to_decimal(x): import decimal @@ -98,27 +99,30 @@ def home(request): total += item.pc_cible if total != 100: - message = u'Attention, le total de votre répartition cible est incorrect : %s.' % total + message = 'Attention, le total de votre répartition cible est incorrect : %s.' % total # lire les actifs actifs = get_actifs(request, '0') # MAJ du prtefeuille if 'form.submitted' in request.params: + # lire le cours de EURUSD + ticker = yf.Ticker('EUR=X') # maj des parités des devises - update_actif_devise(request, 'USD', getCurrencyRate('usd')) + update_actif_devise(request, 'USD', ticker.info.get('regularMarketPrice')) for item in actifs: if item.type == 'ACTION': - # get FT price - update_actif_valeur(request, item.symbole, getFTQuote(item.symbole)) + # lire le cours de l'action + ticker = yf.Ticker(item.symbole) + update_actif_valeur(request, item.symbole, ticker.info.get('regularMarketPrice')) time.sleep(1) # attendre 2 secondes # update du portefeuille update_portefeuille(request, logged_in) # relire les actifs actifs = get_actifs(request, '0') - message = u'Le portefeuille est mis à jour avec succès.' + message = 'Le portefeuille est mis à jour avec succès.' total_valeur = 0 total_pv = 0 diff --git a/setup.py b/setup.py index 7b29d28..53353bc 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ requires = [ 'zope.sqlalchemy', 'waitress', 'mysqlclient', - 'beautifulsoup4', + 'yfinance', 'docutils', ]