Skip to content

Instantly share code, notes, and snippets.

@pathikrit
Last active February 18, 2025 18:48
Show Gist options
  • Select an option

  • Save pathikrit/35030c3253e4a1a5b7f163ed7f668242 to your computer and use it in GitHub Desktop.

Select an option

Save pathikrit/35030c3253e4a1a5b7f163ed7f668242 to your computer and use it in GitHub Desktop.
Export Fidelity Positions to www.portfoliovisualizer.com
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import polars as pl\n",
"\n",
"fidelity_export = '~/Downloads/Portfolio_Positions_Sep-29-2024.csv'\n",
"pv_export = '~/Downloads/pv_export.csv'\n",
"account_name = 'Personal'\n",
"cash = '^CASHUS'\n",
"\n",
"def money_col(name): return pl.col(name).str.replace_all(r'[\\$,]', '').cast(pl.Float32)\n",
"\n",
"portfolio = (pl\n",
" .read_csv(fidelity_export)\n",
" .filter(pl.col('Account Name') == account_name)\n",
" .filter(~pl.col('Symbol').str.starts_with(' -')) # remove options\n",
" .with_columns([\n",
" pl.col('Symbol').str.replace_all(r'^(SPAXX|Pending).*', cash), # Cash positions\n",
" money_col('Last Price').alias('Price'),\n",
" pl.col('Quantity'),\n",
" money_col('Current Value'),\n",
" ])\n",
" # Sometimes current value is empty (e.g when security is in margin)\n",
" .with_columns(pl.coalesce(pl.col('Current Value'), pl.col('Quantity') * pl.col('Price')).alias('Value'))\n",
")\n",
"\n",
"total = portfolio['Value'].sum()\n",
"portfolio = (portfolio\n",
" .with_columns((100 * pl.col('Value')/total).alias('Weight'))\n",
" # sometimes the same security is listed multiple times e.g. when it is loaned out\n",
" .group_by(pl.col('Symbol'))\n",
" .agg(pl.sum('Weight'))\n",
" .sort(pl.col('Weight'), descending=True)\n",
")\n",
"portfolio.write_csv(pv_export)\n",
"print(f'Wrote {len(portfolio)} securities to {pv_export}')\n",
"total, portfolio"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Sometimes a security is too new to be properly backtested;\n",
"# we override with a similar ticker that has a longer history\n",
"\n",
"pv_export_long_history = '~/Downloads/pv_export_long_history.csv'\n",
"overrides = {\n",
" 'RSBY': 'LCSIX',\n",
" 'LCDS': 'DFSVX',\n",
" 'MCDS': 'VOE',\n",
" 'SCDS': 'SPYV',\n",
" 'NIXT': 'SPY',\n",
" 'EZBC': cash,\n",
" 'SPYU': 'UPRO',\n",
" 'MFUT': 'ASFYX',\n",
" 'AHLT': 'ASFYX',\n",
" 'TFPN': 'ASFYX',\n",
" 'QIS': 'LCSIX',\n",
" 'VFLO': 'LEXCX',\n",
" 'ASMF': 'ASFYX',\n",
" 'CAOS': cash,\n",
" 'RSBT': 'ASFYX',\n",
" 'HYGI': 'HYG',\n",
" 'CTA': 'LCSIX',\n",
" 'CRIT': 'XME',\n",
" 'DISV': 'DISVX',\n",
" 'HGER': 'LCSIX',\n",
" 'UPAR': 'DBC',\n",
" 'FLSP': 'QSPIX',\n",
" 'PFIX': 'TIPZ',\n",
" 'KMLM': 'ASFYX',\n",
" 'GOVZ': 'ZROZ',\n",
" 'CCRV': 'LCSIX',\n",
" 'KRBN': cash,\n",
" 'FCPI': 'BTAL',\n",
" 'AVUV': 'DFSVX',\n",
" 'DBMF': 'ASFYX',\n",
" 'IVOL': 'TIPZ',\n",
" 'DYNF': 'USMV',\n",
" 'IETC': 'PPA',\n",
" 'DFEN': 'PPA',\n",
" 'COWZ': 'LEXCX',\n",
" 'NANR': 'IEO',\n",
" 'CIBR': cash,\n",
" 'AIRR': 'PKB',\n",
" 'FMF': 'ASFYX',\n",
" 'WTMF': 'ASFYX',\n",
" 'USDU': 'UUP',\n",
"}\n",
"overrides_df = pl.DataFrame({'Symbol': list(overrides.keys()), 'Symbol Override': list(overrides.values())})\n",
"portfolio = (portfolio\n",
" .join(overrides_df, on='Symbol', how='left')\n",
" .group_by(pl.coalesce(pl.col('Symbol Override'), pl.col('Symbol')).alias('Symbol'))\n",
" .agg(pl.sum('Weight'))\n",
" .sort(pl.col('Weight'), descending=True)\n",
")\n",
"\n",
"portfolio.write_csv(pv_export_long_history)\n",
"print(f'Wrote {len(portfolio)} securities to {pv_export_long_history}')\n",
"portfolio"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment