Package: degiro_analytics
IntroThis is a DeGiro analytics platform. DeGiro is a low-fee Dutch investment broker that, sadly, offers limited account analytics functionality. This project leverages DeGiro's private API and provides some investment performance analytics tools.Requirmentspandas>=1.4.2requests>=2.27.1Installationpip install degiro_analyticsDockerIf you prefer to run the project in Docker, I made an image available in Docker hub. It contains a Jupyter Notebook with getting-started example.docker pull degiro-analytics-notebook
docker run -p 8888:8888 degiro-analytics-notebookJust copy the link with an automatically generated token and plug it to your browser to run Jupyter.Hint: Make sure you don't have any existing notebooks running on port 8888.Descriptiondegiro_analytics/DegiroWrapper.pycontains API to retrieve current portfolio information and product search. It does not include trading API. There are open-source projects implementing trading API.degiro_analytics/utils.pycontains various methods for portfolio analytics.Examples.ipynbRefer to this Jupyter Notebook for examples.Examplesimportpandasaspdfromdegiro_analyticsimportDeGiroWrapperfromdegiro_analytics.utilsimportirr,analyticsDGW=DeGiroWrapper(True,True,base_curr='EUR')# you will have to provide your credentials (and possibly multi-factor auth code)Insights into your portfoliopf=DGW.get_current_portfolio()# retrieves your current portfolioGet price history of your portfolio constituentsP=DGW.get_prices(pf.index)P=P.pivot(index='date',columns='name',values='price')P=P.apply(lambdax:x/x.dropna().iloc[0])# normalize by starting priceP.plot(title='Portfolio constituents perfomance',figsize=(15,7))Perfomance of your accountstart_date='01/01/2020'# use any dateT=DGW.get_transactions(start_date)# trasactions historyP=DGW.get_prices(T.productId.unique())# get price history of all products from TP=P[P.date>=T.date.min()]P=pd.pivot_table(P,index='date',columns='productId',values='price',aggfunc='mean')# product per columnsP.fillna(method='ffill',inplace=True)Q=pd.pivot_table(T,index='date',columns='productId',values='quantity',aggfunc='sum')# number of shares purchased, product per columnQ=Q.reindex(P.index.append(Q.index)).sort_index().fillna(0).cumsum()# portfolio quantities per dayidx=P.index.get_indexer(Q.index,method='nearest')matched_P=P.iloc[idx].valuesThe following cell computes portfolio returns as $R_t = \frac{Q_{t-1}'P_t}{Q_{t-1}'P_{t-1}}$.numerator=Q.shift().multiply(matched_P).sum(axis=1)denominator=Q.multiply(matched_P).sum(axis=1).shift()R=numerator/denominatorIDX=R.fillna(1).cumprod()# index (or normalized price) of the portfolioIDX.plot(title='Account Portfolio Perfomance',figsize=(15,7))Some analyticsanalytics(IDX){'Mean return': 0.00027660251717962994,
 'Std': 0.010483131903391498,
 'Risk Adjusted Return': 0.02638548477007559,
 'Number of drawdowns': 28,
 'Maximum Drawdown': 0.25730401117784857,
 'Max drawdown duration (days)': 320,
 'Mean drawdown duration (days)': 26.035714285714285,
 'T': 570}Cash Flows analysis and money weighted return (IRR)cf_df=DGW.get_account_cash_flows('01/01/2000',fees=True,dividends=True)cf=cf_df.set_index('date').CFcf.loc[pd.to_datetime(DGW.today,dayfirst=True,utc=True)]=pf.Q.multiply(pf.price_base_curr).sum()# current portfolio valuemwr=irr(cf)print('Money weighted return is',mwr)Money weighted return is 0.008600000000000003Search productssearch_text='Microsoft'product=DGW.lookup(search_text,limit=1)[0]print('The current price of',product.name,'is',product.closePrice,product.currency)p=product.get_price_hist(convert=False).set_index('date').pricep.plot(title=product.name,figsize=(15,7))The current price of Microsoft Corp is 229.25 USDsearch_text='Apple'product=DGW.lookup(search_text,limit=1)[0]print('The current price of',product.name,'is',product.closePrice,product.currency)p=product.get_price_hist(history='1D',resolution='T1M',convert=False).set_index('date').pricep.plot(title=product.name+' (intraday pricing)',figsize=(15,7))The current price of Apple Inc is 140.42 USDSearch and analyze ETFs from core selectionetfs=DGW.search_etfs(only_free=True,limit=200)# returns all ETFs from DeGiro core selectionLoop through the ETFs and analyze the pricesout=[]foretfinetfs:p=etf.get_price_hist(resolution='1M')a=analytics(p.set_index('date').price)a['name']=etf.nameout.append(a)pd.DataFrame(out).sort_values('Risk Adjusted Return')<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}</style>Mean returnStdRisk Adjusted ReturnNumber of drawdownsMaximum DrawdownMax drawdown duration (days)Mean drawdown duration (days)Tname185-0.0035990.024421-0.14739360.3150741278375.33333380Xtrackers USD Corporate Bond UCITS ETF 2D HEUR100-0.0017150.012107-0.14166550.163109852329.00000059iShares Core Gl Aggregate Bd UCITS ETF EUR Hgd...190-0.0125690.095570-0.13151320.624981699380.00000027The Medical Cannabis and Wellness UCITS ETF Acc178-0.0120050.106949-0.11224820.649046699380.00000027Rize Medical Cannabis and Life Sciences UCITS ETF106-0.0015730.015111-0.10411340.2076321064578.25000080Vanguard EUR Eurozone Government Bd UCITS ETF EUR..............................720.0158370.0524220.302098140.243017396139.35714378SPDR MSCI World Technology UCITS ETF630.0120740.0382800.315414230.176644518166.782609149Amundi S&P 500 UCITS ETF- EUR (C)140.0151720.0462380.328118210.239507365175.523810142iShares NASDAQ 100 UCITS ETF USD (Acc)1720.0231670.0702300.32987630.271599365284.33333331Lyx Msci Future Etf1490.0259880.0659000.39436030.238976365294.33333332WisdomTree Battery Solutions UCITS ETF USD Acc198 rows × 9 columns