Package: macrosynergy
Macrosynergy Quant ResearchThe Macrosynergy package supports financial market research and the development of trading strategies based on formats and conventions of the J.P. Morgan Macrosynergy  Quantamental System (JPMaQS). JPMaQS provides quantitative-fundamental (quantamental) and market data in simple daily formats in accordance with the information state of markets. The Macrosynergy package consists of five sub-packages:management: simulates, analyses and reshapes standard quantamental dataframes.panel: analyses and visualizes panels of quantamental data.signal: transforms quantamental indicators into trading signals and does naive analysis.pnl: constructs portfolios based on signals, applies risk management and analyses realistic PnLs.download: interface for downloading data from JP Morgan DataQuery, with main modulejpmaqs.py.InstallationThe easiest method for installing the package is to use thePyPIinstallation method:pipinstallmacrosynergyAlternatively for the cutting edge development version, install the package from thedevelopbranch aspipinstallgit+https://github.com/macrosynergy/macrosynergy@developUsageDataQuery InterfaceTo download data from JP Morgan DataQuery, you can use theJPMaQSDownload Objecttogether with your OAuth authentication credentials (default):importpandasaspdfrommacrosynergy.downloadimportJPMaQSDownloadwithJPMaQSDownload(client_id="<dq_client_id>",client_secret="<dq_client_secret>")asdownloader:data=downloader.download(tickers="EUR_FXXR_NSA",start_date="2022-01-01")assertisinstance(data,pd.DataFrame)andnotdata.emptyassertdata.shape[0]>0data.info()Alternatively, you can also the certificate and private key pair, to access DataQuery as:importpandasaspdfrommacrosynergy.downloadimportJPMaQSDownloadwithJPMaQSDownload(oauth=False,username="<dq_username>",password="<dq_password>",crt="<path_to_dq_certificate>",key="<path_to_dq_key>")asdownloader:data=downloader.download(tickers="EUR_FXXR_NSA",start_date="2022-01-01")assertisinstance(data,pd.DataFrame)andnotdata.emptyassertdata.shape[0]>0data.info()Both of the above example will download a snippet of example data from the premium JPMaQS dataset
of the daily timeseries of EUR FX excess returns.Using the API you can also access a panel of tickers from different countries like so.importpandasaspdfrommacrosynergy.downloadimportJPMaQSDownloadcids=['EUR','GBP','USD']xcats=['FXXR_NSA','EQXR_NSA']tickers=[cid+"_"+xcatforcidincidsforxcatinxcats]withJPMaQSDownload(client_id="<dq_client_id>",client_secret="<dq_client_secret>")asdownloader:data=downloader.download(tickers=tickers,start_date="2022-01-01")assertisinstance(data,pd.DataFrame)andnotdata.emptyassertdata.shape[0]>0data.info()Connecting via a proxy serverSince a lot of institutions use a proxy server to connect to the internet; theJPMaQSDownloadobject can be configured to use a proxy server.It is also possible to use a proxy server with the Dataquery interface. Here's an example:importpandasaspdfrommacrosynergy.downloadimportJPMaQSDownloadcids=['EUR','GBP','USD']xcats=['FXXR_NSA','EQXR_NSA']tickers=[cid+"_"+xcatforcidincidsforxcatinxcats]oauth_proxy="https://secureproxy.example.com:port"proxy={"https":oauth_proxy}# or proxy = {"http": "http://proxy.example.com:port"}withJPMaQSDownload(client_id="<dq_client_id>",client_secret="<dq_client_secret>",proxy=proxy)asdownloader:data=downloader.download(tickers=tickers,start_date="2022-01-01")assertisinstance(data,pd.DataFrame)andnotdf.emptyor,...proxies={"http":"http://proxy.example.com:port","https":"https://secucreproxy.example.com:port",}withJPMaQSDownload(client_id="<dq_client_id>",client_secret="<dq_client_secret>",proxy=proxies)asdownloader:data=downloader.download(tickers=tickers)...ManagementIn order to use the rest of the package without access to the API you cansimulatequantamental data using the management sub-package.frommacrosynergy.management.simulateimportmake_qdfcids=['AUD','GBP','NZD','USD']xcats=['FXXR_NSA','FXCRY_NSA','FXCRR_NSA','EQXR_NSA','EQCRY_NSA','EQCRR_NSA','FXWBASE_NSA','EQWBASE_NSA']df_cids=pd.DataFrame(index=cids,columns=['earliest','latest','mean_add','sd_mult'])df_cids.loc['AUD']=['2000-01-01','2022-03-14',0,1]df_cids.loc['GBP']=['2001-01-01','2022-03-14',0,2]df_cids.loc['NZD']=['2002-01-01','2022-03-14',0,3]df_cids.loc['USD']=['2000-01-01','2022-03-14',0,4]df_xcats=pd.DataFrame(index=xcats,columns=['earliest','latest','mean_add','sd_mult','ar_coef','back_coef'])df_xcats.loc['FXXR_NSA']=['2010-01-01','2022-03-14',0,1,0,0.2]df_xcats.loc['FXCRY_NSA']=['2010-01-01','2022-03-14',1,1,0.9,0.2]df_xcats.loc['FXCRR_NSA']=['2010-01-01','2022-03-14',0.5,0.8,0.9,0.2]df_xcats.loc['EQXR_NSA']=['2010-01-01','2022-03-14',0.5,2,0,0.2]df_xcats.loc['EQCRY_NSA']=['2010-01-01','2022-03-14',2,1.5,0.9,0.5]df_xcats.loc['EQCRR_NSA']=['2010-01-01','2022-03-14',1.5,1.5,0.9,0.5]df_xcats.loc['FXWBASE_NSA']=['2010-01-01','2022-02-01',1,1.5,0.8,0.5]df_xcats.loc['EQWBASE_NSA']=['2010-01-01','2022-02-01',1,1.5,0.9,0.5]data=make_qdf(df_cids,df_xcats,back_ar=0.75)The management sub-package can also be used tocheckwhich data is available
in the dataframe.frommacrosynergy.managementimportcheck_availabilityfilt_na=(data['cid']=='USD')&(data['real_date']<'2015-01-01')data_filt.loc[filt_na,'value']=np.nancheck_availability(df=data_filt,xcats=xcats,cids=cids)You can also use the built-in function toreshapethe data depending on
the dates or tickers of your choice.data_reduced=reduce_df(data,xcats=xcats[:-1],cids=cids[0],start='2012-01-01',end='2018-01-31')PanelBasketThe basket class is used to calculate the returns and carries of financial contracts using various methods,
abasketis created as so.frommacrosynergy.panel.basketimportBasketblack={'AUD':['2010-01-01','2013-12-31'],'GBP':['2010-01-01','2013-12-31']}contracts=['AUD_FX','AUD_EQ','NZD_FX','GBP_EQ','USD_EQ']gdp_figures=[17.0,17.0,41.0,9.0,250.0]basket_1=Basket(df=data,contracts=contracts_1,ret="XR_NSA",cry=["CRY_NSA","CRR_NSA"],blacklist=black)basket_1.make_basket(weight_meth="equal",max_weight=0.55,basket_name="GLB_EQUAL")Using the basket class you have access to the methods such as visulasing the weights associated with each contract,
or returning the weight or basket.basket_1.return_basket()basket_1.return_weights()basket_1.weight_visualiser(basket_name="GLB_EQUAL")You can also calculate and visualise the following and more with built-in functions.historic volatilityz-scoresbeta valuestimelinefrommacrosynergy.panel.historic_volimporthistoric_voldata_historic=historic_vol(data,cids=cids,xcat='FXXR_NSA',lback_periods=21,lback_meth='ma',half_life=11,remove_zeros=True)frommacrosynergy.panel.make_zn_scoresimportmake_zn_scoresz_mean=make_zn_scores(data,xcat='FXXR_NSA',sequential=True,cids=cids,blacklist=black,iis=False,neutral='mean',pan_weight=0.5,min_obs=261,est_freq="w")z_median=make_zn_scores(data,xcat='FXXR_NSA',sequential=True,cids=cids,blacklist=black,iis=False,neutral='median',pan_weight=0.5,min_obs=261,est_freq="d")frommacrosynergy.panel.return_betaimportreturn_betabenchmark_return="USD_FXXR_NSA"data_hedge=return_beta(df=data,xcat='FXXR_NSA',cids=cids,benchmark_return=benchmark_return,start='2010-01-01',end='2020-10-30',blacklist=black,meth='ols',oos=True,refreq='w',min_obs=24,hedged_returns=True)print(df_hedge)beta_display(df_hedge=df_hedge,subplots=False)view_timelines(data,xcats=['FXXR_NSA','FXCRY_NSA'],cids=cids[0],size=(10,5),title='AUD Return and Carry')SignalSignal Return RelationsTheSignalReturnRelationsclass analyses and visualises signal and
return series.frommacrosynergy.signal.signal_returnimportSignalReturnRelationssrn=SignalReturnRelations(data,ret="EQXR_NSA",sig="EQCRY_NSA",rival_sigs=None,sig_neg=True,cosp=True,freq="M",start="2002-01-01")srn.summary_table()In the creation of the class you can also indicate rival signals for basic relational statistics.r_sigs=["EQCRR_NSA"]srn=SignalReturnRelations(data,"EQXR_NSA",sig="EQCRY_NSA",rival_sigs=r_sigs,sig_neg=True,cosp=True,freq="M",start="2002-01-01")df_sigs=srn.signals_table(sigs=['EQCRY_NSA_NEG','EQCRR_NSA_NEG'])df_sigs_all=srn.signals_table()Using the class you can plot accuracy bars between returns and signals.srn.accuracy_bars(type="signals",title="Accuracy measure between target return, EQXR_NSA,"" and the respective signals, ['EQCRY_NSA_NEG', "" 'EQCRR_NSA_NEG'].")PnLNaive pnlTheNaivePnLclass computes Pnls with limited signal options and
disregarding transaction costs.frommacrosynergy.pnl.naive_pnlimportNaivePnLpnl=NaivePnL(data,ret="EQXR_NSA",sigs=["CRY","GROWTH"],cids=cids,start="2000-01-01",bms=["EUR_EQXR_NSA","USD_EQXR_NSA"])You can then make the pnl and see a list of key pnl statistics.pnl.make_pnl(sig="GROWTH",sig_op="zn_score_pan",sig_neg=True,rebal_freq="monthly",vol_scale=5,rebal_slip=1,min_obs=250,thresh=2)df_eval=pnl.evaluate_pnls(pnl_cats=["PNL_GROWTH_NEG"],start="2015-01-01",end="2020-12-31")DocumentationThe official documentation can be found at our documentation website:docs.macrosynergy.com.We use "code-as-documentation" to ensure that our documentation is always up-to-date.
If you find any issues with the documentation, pleaseraise an issueon our GitHub repository.FAQs and TroubleshootingI am having trouble connecting to DataQuery using the APIFor the most common issues, such as incorrect credentials, invalid certificates etc, the package will raise an exception with a helpful error message.If you find that the package raises anHTTPConnection/HTTPSConnectionPoolerror, please check your proxy settings. In scenarios where an error is raised while runningcheck_connection()(or another download), the error is raised with context to the OAuth token request (to "https://authe.jpmchase.com/as/token.oauth2").You would most likely need to pass your proxy settings to theJPMaQSDownloadobject, as shown in theConnecting via a proxy serversection.
If you are accessing DataQuery from an institutional/enterprise network, please contact your IT department to ensure that you have the correct proxy settings.For organizations using ZScaler - you may have to manually add the ZScaler certificates to thecertificertificate store (typically calledcacert.pem). You can find the location of thecertificertificate store by running the following in your Python environment:importcertifiprint(certifi.where())Here's a link toZScaler's official documentation and FAQson how to add certificates to application specific trust stores.https://help.zscaler.com/zia/adding-custom-certificate-application-specific-trust-storeA function is not working as expectedPlease check the documentation for the function on ourdocumentation website,
and ensure you are using the latest version of the package.
If you are still having issues, pleaseraise an issueon our GitHub repository.
Please include a minimal reproducible example, and the output ofpip freezein your issue.I have a feature requestPleaseraise an issue,
and title it "Feature Request: [your feature request]".Contributing or creating a pull requestCurrently, we do not allow a pull request to be created by users outside of the Macrosynergy team.
If you'd like to contribute, please create a fork of the repository, and create a pull request from your fork.