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 :

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})
Méthode de calcul 1 :
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())
Nom : 20170616 150939 Spyder (Python 3.5).png
Affichages : 915
Taille : 13,8 Ko

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)
Nom : 20170616 151136 Spyder (Python 3.5).png
Affichages : 919
Taille : 31,3 Ko


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
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)
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
dfPnL = pd.concat([dfRescum,dfCorrect],ignore_index=True)
dfPnLAgg = dfPnL.groupby(['AsofDate','Book']).agg({'PnL_Eur' : np.sum})
Problème : maintenant en appliquant mes 2 méthodes présentées ci-dessous, ça plante dans les 2 cas.
Il y a quelque chose dans la structure de données obtenue que je ne comprends pas et qui fait tout coincer.

Nom : 20170616 151941 Spyder (Python 3.5).png
Affichages : 908
Taille : 21,7 Ko

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