Bonjour à tous,
Je refais du Python après quelques années (et même un peu plus que ça ) et je galère un peu.
J'ai un ensemble de portefeuilles (books) contenant des instruments financiers.
Pour chaque jour et chaque book, je connais le résultat (PnL) en euros depuis le début de l'année (YtD = Year to Date). Le tout est ventilé par source.
Mon objectif : calculer le gain journalier, autrement dit, le PnL Daily. PnLDaily(J) = PnLYtD(J) - PnLYtD(J-1)
En m'aidant du net, j'ai identifié 2 méthodes pour faire ce calcul et fait fonctionné le tout avec des données bricolées.
Cela donne ça :
Méthode de calcul 1 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 ''' Préparation des données ''' import pandas as pd import numpy as np import random from itertools import product random.seed(1) np.random.seed(2) dates = pd.date_range(start='2013-10-01', periods=10).to_native_types() Books = ['Book%d' % i for i in range(3)] # make a list of all the possible (date, ticker) tuples pairs = list(product(dates, Books)) random.shuffle(pairs) PnL = np.random.rand(len(pairs)) * 10000 mydates, myBooks = zip(*pairs) data = pd.DataFrame({'date': mydates, 'book': myBooks, 'PnL':PnL})
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 data2 = data.pivot_table(index=['date'], columns=['book'],values='PnL', aggfunc=[np.sum]) print(data2.diff())
Méthode de calcul 2 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 data3 = data.copy() data3.sort_values(by=['book','date'],inplace=True) data3['PnLDaily'] = data3.groupby('book')['PnL'].transform(pd.Series.diff) print(data3)
Ne sachant pas quelle méthode choisir, je souhaite refaire l'exercice avec de vraies données pour comparer les performances.
C'est là que les choses se gâtent...
Je récupère mes données en base
Mes données étant dans 2 tables, je fais l'union et je somme
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 sql = '''SELECT date, book, Filiere, PnL_Eur bla bla bla'' % (lDates, lBooks)''' dfRescum = psql.read_sql(sql, con) sql = '''SELECT date, book, Filiere, PnL_Eur bla bla bla'' % (lDates, lBooks)''' dfCorrect = psql.read_sql(sql, con)
Problème : maintenant en appliquant mes 2 méthodes présentées ci-dessous, ça plante dans les 2 cas.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 dfPnL = pd.concat([dfRescum,dfCorrect],ignore_index=True) dfPnLAgg = dfPnL.groupby(['AsofDate','Book']).agg({'PnL_Eur' : np.sum})
Il y a quelque chose dans la structure de données obtenue que je ne comprends pas et qui fait tout coincer.
Désolé pour la log...
methode1.diff()
Traceback (most recent call last):
File "<ipython-input-214-694d35795766>", line 1, in <module>
methode1.diff()
File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\frame.py", line 4059, in diff
new_data = self._data.diff(n=periods, axis=bm_axis)
File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\internals.py", line 3174, in diff
return self.apply('diff', **kwargs)
File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\internals.py", line 3056, in apply
applied = getattr(b, f)(**kwargs)
File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\internals.py", line 1041, in diff
new_values = algos.diff(self.values, n, axis=axis)
File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\algorithms.py", line 1251, in diff
out_arr[res_indexer] = arr[res_indexer] - arr[lag_indexer]
TypeError: unsupported operand type(s) for -: 'str' and 'str'
Quand je tente la méthode 2, même genre de soucis.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 methode2 = dfPnLAgg.copy() methode2['PnLDaily'] = dfPnLAgg.groupby('Book')['PnL_Eur'].transform(pd.Series.diff)methode2['PnLDaily'] = dfPnLAgg.groupby('Book')['PnL_Eur'].transform(pd.Series.diff)
Traceback (most recent call last):
File "<ipython-input-216-2c608f326c29>", line 1, in <module>
methode2['PnLDaily'] = dfPnLAgg.groupby('Book')['PnL_Eur'].transform(pd.Series.diff)
File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\groupby.py", line 2831, in transform
res = wrapper(group)
File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\groupby.py", line 2828, in <lambda>
wrapper = lambda x: func(x, *args, **kwargs)
File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\series.py", line 1459, in diff
result = algos.diff(_values_from_object(self), periods)
File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\algorithms.py", line 1251, in diff
out_arr[res_indexer] = arr[res_indexer] - arr[lag_indexer]
TypeError: unsupported operand type(s) for -: 'str' and 'str'
Voila voila, je suis un peu gêné de vous coller mes logs d'erreurs, mais je ne sais pas où chercher.
Bien amicalement.
Mathu
Partager