fixed histo_edit
This commit is contained in:
BIN
cao_blogr.sqlite
BIN
cao_blogr.sqlite
Binary file not shown.
BIN
cao_blogr.sqlite.copie
Normal file
BIN
cao_blogr.sqlite.copie
Normal file
Binary file not shown.
@@ -4,7 +4,6 @@ from ..models.portfolio import Actifs, Allocation, Histo
|
|||||||
|
|
||||||
class PFService(object):
|
class PFService(object):
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_actifs(cls, request, no_id):
|
def get_actifs(cls, request, no_id):
|
||||||
if no_id == '0':
|
if no_id == '0':
|
||||||
@@ -41,9 +40,15 @@ class PFService(object):
|
|||||||
items = request.dbsession.query(Histo).filter(Histo.no_id == no_id).first()
|
items = request.dbsession.query(Histo).filter(Histo.no_id == no_id).first()
|
||||||
return items
|
return items
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_last_histo(cls, request):
|
||||||
|
# lire le dernier histo créé
|
||||||
|
items = request.dbsession.query(Histo).order_by(sa.desc(Histo.date)).first()
|
||||||
|
return items
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def delete_allocation(cls, request, no_id):
|
def delete_allocation(cls, request, no_id):
|
||||||
request.dbsession.query(Allocation).filter(Histo.no_ == no_id).delete(synchronize_session=False)
|
request.dbsession.query(Allocation).filter(Allocation.no_ == no_id).delete(synchronize_session=False)
|
||||||
return
|
return
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -52,37 +57,49 @@ class PFService(object):
|
|||||||
return
|
return
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_actif_devise(request, devise, taux):
|
def update_actif_devise(cls, request, devise, taux):
|
||||||
request.dbsession.query(Actifs).filter(Actifs.devise == devise).update({'parite': taux})
|
request.dbsession.query(Actifs).filter(Actifs.devise == devise).update({'parite': taux})
|
||||||
request.dbsession.commit()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def update_actif_valeur(request, symbole, cours, dividends):
|
def update_actif_valeur(request, symbole, cours, dividends):
|
||||||
request.dbsession.query(Actifs).filter(Actifs.symbole == symbole).update({'symbole': symbole, 'cours': cours, 'dividends': dividends})
|
request.dbsession.query(Actifs).filter(Actifs.symbole == symbole).update({'cours': cours, 'rendement': dividends})
|
||||||
request.dbsession.commit()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def update_portefeuille(request):
|
def update_portefeuille(request):
|
||||||
TotalValue = request.dbsession.query(Actifs, func.sum(Actifs.valeur).label("TotalValue")).first()
|
# cumuler la valeur totale des actifs
|
||||||
|
result = request.dbsession.query(Actifs, func.sum(Actifs.valeur).label("TotalValue")).first()
|
||||||
|
TotalValue = result.TotalValue
|
||||||
# maj du pourcentage d'allocation des lignes du portefeuille
|
# maj du pourcentage d'allocation des lignes du portefeuille
|
||||||
request.dbsession.query(Actifs).update({'pc_allocation': Actifs.valeur / TotalValue * 100})
|
request.dbsession.query(Actifs).update({'pc_allocation': Actifs.valeur / TotalValue * 100})
|
||||||
request.dbsession.commit()
|
|
||||||
|
|
||||||
# maj des allocations
|
# maj des allocations
|
||||||
items = PFService.get_allocation(request, '0')
|
items = PFService.get_allocation(request, '0')
|
||||||
for item in items:
|
for item in items:
|
||||||
TotalClasse = request.dbsession.query(Actifs, func.sum(Actifs.valeur).label("TotalValue")
|
# cumuler la valeur totale des actifs de cette classe
|
||||||
|
result = request.dbsession.query(Actifs, func.sum(Actifs.valeur).label("TotalClasse")
|
||||||
).filter(Actifs.classe == item.classe).first()
|
).filter(Actifs.classe == item.classe).first()
|
||||||
item.valeur = TotalClasse,
|
TotalClasse = result.TotalClasse
|
||||||
item.pc_atteint = item.valeur / TotalValue * 100;
|
# maj du pourcentage d'allocation de cette classe
|
||||||
request.dbsession.commit()
|
request.dbsession.query(Allocation).filter(Allocation.classe == item.classe
|
||||||
|
).update({'valeur': TotalClasse, 'pc_atteint': TotalClasse / TotalValue * 100})
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def delete_actif(request, no_id):
|
def delete_actif(cls, request, no_id):
|
||||||
request.dbsession.query(Actifs).filter(Actifs.no_id == no_id).delete(synchronize_session=False)
|
request.dbsession.query(Actifs).filter(Actifs.no_id == no_id).delete(synchronize_session=False)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def get_dividends(ticker):
|
||||||
|
d = 0
|
||||||
|
# le ticker a des dividendes ?
|
||||||
|
if len(ticker.dividends) > 0:
|
||||||
|
# oui, cumuler les dividendes sur un an
|
||||||
|
h = ticker.history(period="1y")
|
||||||
|
nb = len(ticker.dividends)
|
||||||
|
for i in range(nb):
|
||||||
|
d += ticker.dividends[nb - 1 - i]
|
||||||
|
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,11 +20,12 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<a class="btn btn-default" href="{{ request.route_url('histo_list') }}">
|
<a class="btn btn-default" href="{{ request.route_url('histo_list') }}">
|
||||||
<span class="glyphicon glyphicon-chevron-left"></span> Retour</a>
|
<span class="glyphicon glyphicon-chevron-left"></span> Retour</a>
|
||||||
<button class="btn btn-primary" type="submit" name="form.submitted">
|
|
||||||
<span class="glyphicon glyphicon-ok"></span> Enregistrer</button>
|
|
||||||
{% if form.no_id.data %}
|
{% if form.no_id.data %}
|
||||||
<button class="btn btn-danger" type="button" data-toggle="modal" data-target="#confirmDelete">
|
<button class="btn btn-danger" type="button" data-toggle="modal" data-target="#confirmDelete">
|
||||||
<span class="glyphicon glyphicon-remove"></span> Supprimer</button>
|
<span class="glyphicon glyphicon-remove"></span> Supprimer</button>
|
||||||
|
{% else %}
|
||||||
|
<button class="btn btn-primary" type="submit" name="form.submitted">
|
||||||
|
<span class="glyphicon glyphicon-ok"></span> Enregistrer</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<p><a href="{{ request.route_url('histo_edit', no_id='0') }}" class="btn btn-success" role="button">
|
<p>
|
||||||
<span class="glyphicon glyphicon-plus"></span> Entrée / Sortie cash</a>
|
<a class="btn btn-default" href="{{ request.route_url('portfolio') }}">
|
||||||
|
<span class="glyphicon glyphicon-chevron-left"></span> Retour</a>
|
||||||
|
<a href="{{ request.route_url('histo_edit', no_id='0') }}" class="btn btn-success" role="button">
|
||||||
|
<span class="glyphicon glyphicon-plus"></span> Entrée / Sortie cash</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<table id="histo_list" class="table table-striped table-bordered table-condensed">
|
<table id="histo_list" class="table table-striped table-bordered table-condensed">
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="{{ item.bg_color }}"><a href="allocation_edit/{{ item.no_cat }}">{{ item.classe }}</a></td>
|
<td class="{{ item.bg_color }}"><a href="allocation_edit/{{ item.no_cat }}">{{ item.classe }}</a></td>
|
||||||
<td class="text-right">{{ item.pc_cible }} %</td>
|
<td class="text-right">{{ item.pc_cible }} %</td>
|
||||||
<td class="text-right">{{ item.pc_atteint }}</td>
|
<td class="text-right">{{ '{0:0.1f}'.format(item.pc_atteint) }}</td>
|
||||||
{% if (item.pc_atteint - item.pc_cible) >= 0 %}
|
{% if (item.pc_atteint - item.pc_cible) >= 0 %}
|
||||||
<td class="text-right" style="color: green;">{{ '{0:0.1f}'.format(item.pc_ecart) }}</td>
|
<td class="text-right" style="color: green;">{{ '{0:0.1f}'.format(item.pc_ecart) }}</td>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@@ -47,26 +47,28 @@ def portfolio(request):
|
|||||||
if 'form.submitted' in request.params:
|
if 'form.submitted' in request.params:
|
||||||
# lire le cours de EURUSD
|
# lire le cours de EURUSD
|
||||||
ticker = yf.Ticker('EUR=X')
|
ticker = yf.Ticker('EUR=X')
|
||||||
|
|
||||||
# maj des parités des devises
|
# maj des parités des devises
|
||||||
PFService.update_actif_devise(request, 'USD', ticker.info.get('regularMarketPrice'))
|
taux = ticker.fast_info.get('lastPrice')
|
||||||
|
PFService.update_actif_devise(request, 'USD', taux)
|
||||||
|
|
||||||
for item in actifs:
|
for item in actifs:
|
||||||
if item.Allocation.type == 'ACTION':
|
if item.Allocation.type == 'ACTION':
|
||||||
# lire le cours de l'action
|
# lire le cours de l'action
|
||||||
ticker = yf.Ticker(item.Actifs.symbole)
|
ticker = yf.Ticker(item.Actifs.symbole)
|
||||||
# ticker delisted ?
|
# ticker delisted ?
|
||||||
if ticker.info == None:
|
if item.Actifs.symbole == 'SHLDQ':
|
||||||
price = 0
|
price = 0
|
||||||
|
dividends = 0
|
||||||
else:
|
else:
|
||||||
price = ticker.info.get('regularMarketPrice')
|
price = ticker.fast_info.get('lastPrice')
|
||||||
# caluler son rendement
|
# caluler son rendement
|
||||||
dividends = PFService.get_dividends(ticker)
|
dividends = PFService.get_dividends(ticker)
|
||||||
|
|
||||||
PFService.update_actif_valeur(request, item.Actifs.symbole, price, dividends)
|
PFService.update_actif_valeur(request, item.Actifs.symbole, price, dividends)
|
||||||
# time.sleep(1) # attendre 2 secondes
|
# time.sleep(1) # attendre 2 secondes
|
||||||
|
|
||||||
# update du portefeuille
|
# update du portefeuille
|
||||||
PFService.update_portefeuille(request, logged_in)
|
PFService.update_portefeuille(request)
|
||||||
# relire les actifs
|
# relire les actifs
|
||||||
actifs = PFService.get_actifs(request, '0')
|
actifs = PFService.get_actifs(request, '0')
|
||||||
request.session.flash('Le portefeuille est mis à jour avec succès.', 'success')
|
request.session.flash('Le portefeuille est mis à jour avec succès.', 'success')
|
||||||
@@ -190,16 +192,28 @@ def histo_edit(request):
|
|||||||
page_title = "Modifier histo no " + str(entry.no_id)
|
page_title = "Modifier histo no " + str(entry.no_id)
|
||||||
|
|
||||||
if 'form.submitted' in request.params and form.validate():
|
if 'form.submitted' in request.params and form.validate():
|
||||||
if no_id == '0':
|
form.populate_obj(entry)
|
||||||
form.populate_obj(entry)
|
|
||||||
request.dbsession.add(entry)
|
# lire le cours de l'indice de réfence : Carmignac Investissement A EUR Acc
|
||||||
return HTTPFound(location=request.route_url('histo_list'))
|
ticker = yf.Ticker('0P00000FB2.F')
|
||||||
else:
|
entry.cours_ref = ticker.fast_info.last_price
|
||||||
del form.no_id # SECURITY: prevent overwriting of primary key
|
|
||||||
form.populate_obj(entry)
|
# lire le dernier histo
|
||||||
# lire le cours de l'indice de réfence : Carmignac Investissement A EUR Acc
|
last = PFService.get_last_histo(request)
|
||||||
ticker = yf.Ticker('0P00000FB2.F')
|
|
||||||
entry.cours_ref = ticker.info.get('regularMarketPrice')
|
# lire les actifs et cumuler leurs valeurs
|
||||||
|
actifs = PFService.get_actifs(request, '0')
|
||||||
|
valeur_pf = 0
|
||||||
|
for item in actifs:
|
||||||
|
valeur_pf += item.Actifs.valeur
|
||||||
|
|
||||||
|
entry.valeur_pf = valeur_pf
|
||||||
|
# nlle valeur part = ancienne + nouvelle ratio
|
||||||
|
entry.nb_part = last.nb_part + (float(entry.mvt_cash) / (valeur_pf - float(entry.mvt_cash))/last.nb_part)
|
||||||
|
entry.val_part = entry.valeur_pf / entry.nb_part
|
||||||
|
entry.val_part_ref = float(entry.cours_ref) * last.val_part_ref / last.cours_ref
|
||||||
|
|
||||||
|
request.dbsession.add(entry)
|
||||||
|
|
||||||
return HTTPFound(location=request.route_url('histo_list'))
|
return HTTPFound(location=request.route_url('histo_list'))
|
||||||
|
|
||||||
@@ -249,8 +263,8 @@ def actif_edit(request):
|
|||||||
form.populate_obj(entry)
|
form.populate_obj(entry)
|
||||||
# récupérer le cours du symbole de Yahoo finance
|
# récupérer le cours du symbole de Yahoo finance
|
||||||
ticker = yf.Ticker(entry.symbole)
|
ticker = yf.Ticker(entry.symbole)
|
||||||
entry.cours = ticker.fast_info.last_price
|
entry.cours = ticker.fast_info.get('lastPrice')
|
||||||
entry.devise = ticker.info.get('currency')
|
entry.devise = ticker.fast_info.get('currency')
|
||||||
entry.libelle = html.unescape(ticker.info.get('shortName'))
|
entry.libelle = html.unescape(ticker.info.get('shortName'))
|
||||||
# raccourcir le libelle
|
# raccourcir le libelle
|
||||||
entry.libelle = entry.libelle.replace('UCITS ','')
|
entry.libelle = entry.libelle.replace('UCITS ','')
|
||||||
@@ -267,8 +281,8 @@ def actif_edit(request):
|
|||||||
form.populate_obj(entry)
|
form.populate_obj(entry)
|
||||||
# récupérer le cours du symbole de Yahoo finance
|
# récupérer le cours du symbole de Yahoo finance
|
||||||
ticker = yf.Ticker(entry.symbole)
|
ticker = yf.Ticker(entry.symbole)
|
||||||
entry.cours = ticker.fast_info.last_price
|
entry.cours = ticker.fast_info.get('lastPrice')
|
||||||
entry.devise = ticker.info.get('currency')
|
entry.devise = ticker.fast_info.get('currency')
|
||||||
entry.libelle = html.unescape(ticker.info.get('shortName'))
|
entry.libelle = html.unescape(ticker.info.get('shortName'))
|
||||||
# raccourcir le libelle
|
# raccourcir le libelle
|
||||||
entry.libelle = entry.libelle.replace('UCITS ','')
|
entry.libelle = entry.libelle.replace('UCITS ','')
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s
|
|||||||
|
|
||||||
[server:main]
|
[server:main]
|
||||||
use = egg:waitress#main
|
use = egg:waitress#main
|
||||||
listen = localhost:6543
|
listen = localhost:9280
|
||||||
|
|
||||||
###
|
###
|
||||||
# logging configuration
|
# logging configuration
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s
|
|||||||
|
|
||||||
[server:main]
|
[server:main]
|
||||||
use = egg:waitress#main
|
use = egg:waitress#main
|
||||||
listen = *:6543
|
listen = *:9280
|
||||||
|
|
||||||
###
|
###
|
||||||
# logging configuration
|
# logging configuration
|
||||||
|
|||||||
Reference in New Issue
Block a user