remplacer le site FT par YAHOO finance
This commit is contained in:
20
CHANGES.txt
20
CHANGES.txt
@@ -2,3 +2,23 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
- Initial version
|
- 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'}
|
||||||
@@ -3,6 +3,7 @@ from pyramid_layout.layout import layout_config
|
|||||||
from .security import groupfinder
|
from .security import groupfinder
|
||||||
from .views.default import (
|
from .views.default import (
|
||||||
to_euro,
|
to_euro,
|
||||||
|
to_usd,
|
||||||
to_percent,
|
to_percent,
|
||||||
to_decimal,
|
to_decimal,
|
||||||
)
|
)
|
||||||
@@ -22,6 +23,9 @@ class GlobalLayout(object):
|
|||||||
def to_euro(self, x):
|
def to_euro(self, x):
|
||||||
return to_euro(x)
|
return to_euro(x)
|
||||||
|
|
||||||
|
def to_usd(self, x):
|
||||||
|
return to_usd(x)
|
||||||
|
|
||||||
def to_percent(self, x, d):
|
def to_percent(self, x, d):
|
||||||
return to_percent(x, d)
|
return to_percent(x, d)
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ from zope.sqlalchemy import ZopeTransactionExtension, mark_changed
|
|||||||
|
|
||||||
from datetime import *
|
from datetime import *
|
||||||
import transaction
|
import transaction
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
|
|
||||||
from .default import (
|
from .default import (
|
||||||
@@ -141,33 +140,5 @@ def delete_histo(request, no_id):
|
|||||||
query = "DELETE FROM histo WHERE no_id = :no_id ;"
|
query = "DELETE FROM histo WHERE no_id = :no_id ;"
|
||||||
execute_query(request, query, {'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
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,39 +31,21 @@
|
|||||||
data-fv-stringlength-max="15"
|
data-fv-stringlength-max="15"
|
||||||
data-fv-stringlength-message="15 caractères maximum" />
|
data-fv-stringlength-message="15 caractères maximum" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col-xs-6">
|
||||||
<div class="form-group">
|
<p class="form-control-static">${actif.libelle}</p>
|
||||||
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-2" for="nombre">Nombre</label>
|
<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}"
|
<input class="form-control" type="text" id="nombre" name="nombre" value="${actif.nombre}"
|
||||||
data-fv-digits="true"
|
data-fv-digits="true"
|
||||||
data-fv-digits-message="Le nombre doit être composé que de chiffres" />
|
data-fv-digits-message="Le nombre doit être composé que de chiffres" />
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-2" for="pru">PRU</label>
|
<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">
|
||||||
<div class="input-group-addon">€</div>
|
<div class="input-group-addon">€</div>
|
||||||
<input class="form-control" type="text" id="pru" name="pru" value="${actif.pru}"
|
<input class="form-control" type="text" id="pru" name="pru" value="${actif.pru}"
|
||||||
@@ -74,7 +56,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-2" for="ter">TER</label>
|
<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">
|
||||||
<div class="input-group-addon">%</div>
|
<div class="input-group-addon">%</div>
|
||||||
<input class="form-control" type="text" id="ter" name="ter" value="${actif.ter}"
|
<input class="form-control" type="text" id="ter" name="ter" value="${actif.ter}"
|
||||||
@@ -85,7 +67,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-xs-2" for="pc_rdt">% Rendement</label>
|
<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">
|
||||||
<div class="input-group-addon">%</div>
|
<div class="input-group-addon">%</div>
|
||||||
<input class="form-control" type="text" id="pc_rdt" name="pc_rdt" value="${actif.pc_rdt}"
|
<input class="form-control" type="text" id="pc_rdt" name="pc_rdt" value="${actif.pc_rdt}"
|
||||||
@@ -94,6 +76,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</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">
|
<div class="form-group">
|
||||||
<label class="col-xs-2 control-label">Web site</label>
|
<label class="col-xs-2 control-label">Web site</label>
|
||||||
<div class="col-xs-8">
|
<div class="col-xs-8">
|
||||||
|
|||||||
@@ -115,7 +115,8 @@
|
|||||||
<td class="${ligne.bg_color}">${ligne.classe}</td>
|
<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="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 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">${ligne.nombre}</td>
|
||||||
<td class="text-right">${layout.to_euro(ligne.valeur)}</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>
|
<td tal:condition="ligne.plus_value>=0" class="text-right" style="color: green;">${layout.to_euro(ligne.plus_value)}</td>
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ from ..views.default import (
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
|
import yfinance as yf
|
||||||
|
|
||||||
|
|
||||||
@view_config(route_name='actif_edit', renderer='../templates/actifs/actif_edit.pt', permission='view')
|
@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]
|
new_values[param] = request.params[param]
|
||||||
|
|
||||||
if new_values:
|
if new_values:
|
||||||
# récupérer les infos du symbole de FT finance
|
|
||||||
if 'symbole' in request.params:
|
if 'symbole' in request.params:
|
||||||
symbole = request.params['symbole']
|
symbole = request.params['symbole']
|
||||||
else:
|
else:
|
||||||
symbole = actif.symbole
|
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)
|
update_actif(request, no_id, new_values)
|
||||||
request.session.flash(u"La fiche a été mise à jour avec succès.", 'success')
|
request.session.flash(u"La fiche a été mise à jour avec succès.", 'success')
|
||||||
return HTTPFound(location=request.route_url('home'))
|
return HTTPFound(location=request.route_url('home'))
|
||||||
@@ -244,7 +247,8 @@ def histo_edit(request):
|
|||||||
|
|
||||||
if new_values:
|
if new_values:
|
||||||
# lire le cours de l'indice de réfence : Carmignac Investissement A EUR Acc
|
# 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)
|
update_histo(request, no_id, new_values)
|
||||||
request.session.flash(u"La fiche a été mise à jour avec succès.", 'success')
|
request.session.flash(u"La fiche a été mise à jour avec succès.", 'success')
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ from ..models.members import (
|
|||||||
import time
|
import time
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
|
import yfinance as yf
|
||||||
|
|
||||||
def to_decimal(x):
|
def to_decimal(x):
|
||||||
import decimal
|
import decimal
|
||||||
@@ -98,27 +99,30 @@ def home(request):
|
|||||||
total += item.pc_cible
|
total += item.pc_cible
|
||||||
|
|
||||||
if total != 100:
|
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
|
# lire les actifs
|
||||||
actifs = get_actifs(request, '0')
|
actifs = get_actifs(request, '0')
|
||||||
|
|
||||||
# MAJ du prtefeuille
|
# MAJ du prtefeuille
|
||||||
if 'form.submitted' in request.params:
|
if 'form.submitted' in request.params:
|
||||||
|
# lire le cours de EURUSD
|
||||||
|
ticker = yf.Ticker('EUR=X')
|
||||||
# maj des parités des devises
|
# 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:
|
for item in actifs:
|
||||||
if item.type == 'ACTION':
|
if item.type == 'ACTION':
|
||||||
# get FT price
|
# lire le cours de l'action
|
||||||
update_actif_valeur(request, item.symbole, getFTQuote(item.symbole))
|
ticker = yf.Ticker(item.symbole)
|
||||||
|
update_actif_valeur(request, item.symbole, ticker.info.get('regularMarketPrice'))
|
||||||
time.sleep(1) # attendre 2 secondes
|
time.sleep(1) # attendre 2 secondes
|
||||||
|
|
||||||
# update du portefeuille
|
# update du portefeuille
|
||||||
update_portefeuille(request, logged_in)
|
update_portefeuille(request, logged_in)
|
||||||
# relire les actifs
|
# relire les actifs
|
||||||
actifs = get_actifs(request, '0')
|
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_valeur = 0
|
||||||
total_pv = 0
|
total_pv = 0
|
||||||
|
|||||||
Reference in New Issue
Block a user