remplacer le site FT par YAHOO finance

This commit is contained in:
2019-09-29 11:25:48 +02:00
parent b00a7674d3
commit 63a73b6e81
8 changed files with 56 additions and 64 deletions

View File

@@ -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'}

View File

@@ -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)

View File

@@ -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

View File

@@ -31,39 +31,21 @@
data-fv-stringlength-max="15"
data-fv-stringlength-message="15 caractères maximum" />
</div>
</div>
<div class="form-group">
<label class="col-xs-2 control-label">Libellé</label>
<div class="col-xs-4">
<input class="form-control" type="text" name="libelle"
value="${actif.libelle}" placeholder="45 caractères maximum"
data-fv-notempty="true"
data-fv-notempty-message="Le libellé est obligatoire"
data-fv-stringlength="true"
data-fv-stringlength-max="45"
data-fv-stringlength-message="45 caractères maximum" />
<div class="col-xs-6">
<p class="form-control-static">${actif.libelle}</p>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-2" for="nombre">Nombre</label>
<div class="col-xs-2">
<div class="col-xs-4">
<input class="form-control" type="text" id="nombre" name="nombre" value="${actif.nombre}"
data-fv-digits="true"
data-fv-digits-message="Le nombre doit être composé que de chiffres" />
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-2">Devise</label>
<div class="col-xs-4">
<select class="form-control" name="devise">
<option value="EUR" tal:attributes="selected actif.devise == 'EUR' and 'selected' or None">EUR</option>
<option value="USD" tal:attributes="selected actif.devise == 'USD' and 'selected' or None">USD</option>
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-2" for="pru">PRU</label>
<div class="col-xs-2">
<div class="col-xs-4">
<div class="input-group">
<div class="input-group-addon">€</div>
<input class="form-control" type="text" id="pru" name="pru" value="${actif.pru}"
@@ -74,7 +56,7 @@
</div>
<div class="form-group">
<label class="control-label col-xs-2" for="ter">TER</label>
<div class="col-xs-2">
<div class="col-xs-4">
<div class="input-group">
<div class="input-group-addon">%</div>
<input class="form-control" type="text" id="ter" name="ter" value="${actif.ter}"
@@ -85,7 +67,7 @@
</div>
<div class="form-group">
<label class="control-label col-xs-2" for="pc_rdt">% Rendement</label>
<div class="col-xs-2">
<div class="col-xs-4">
<div class="input-group">
<div class="input-group-addon">%</div>
<input class="form-control" type="text" id="pc_rdt" name="pc_rdt" value="${actif.pc_rdt}"
@@ -94,6 +76,12 @@
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-2">Devise</label>
<div class="col-xs-7">
<p class="form-control-static">${actif.devise}</p>
</div>
</div>
<div class="form-group">
<label class="col-xs-2 control-label">Web site</label>
<div class="col-xs-8">

View File

@@ -115,7 +115,8 @@
<td class="${ligne.bg_color}">${ligne.classe}</td>
<td tal:condition="ligne.type=='ACTION'"><a href="actif_edit/${ligne.no_id}">${ligne.libelle}</a></td>
<td tal:condition="ligne.type!='ACTION'"><a href="actif2_edit/${ligne.no_id}">${ligne.libelle}</a></td>
<td class="text-right">${layout.to_euro(ligne.cours)}</td>
<td tal:condition="ligne.devise=='EUR'" class="text-right">${layout.to_euro(ligne.cours)}</td>
<td tal:condition="ligne.devise=='USD'" class="text-right">${layout.to_usd(ligne.cours)}</td>
<td class="text-right">${ligne.nombre}</td>
<td class="text-right">${layout.to_euro(ligne.valeur)}</td>
<td tal:condition="ligne.plus_value>=0" class="text-right" style="color: green;">${layout.to_euro(ligne.plus_value)}</td>

View File

@@ -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')

View File

@@ -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

View File

@@ -20,7 +20,7 @@ requires = [
'zope.sqlalchemy',
'waitress',
'mysqlclient',
'beautifulsoup4',
'yfinance',
'docutils',
]