Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
157 commits
Select commit Hold shift + click to select a range
220ba6f
examm base run subprocess implmented
rahulkfernandes Oct 25, 2025
986989c
getting CPI data test
rahulkfernandes Oct 25, 2025
f314a83
required series error fixed
rahulkfernandes Oct 25, 2025
2761ed8
requirements added, TODOs added
rahulkfernandes Oct 25, 2025
fde6021
loads dataset files
rahulkfernandes Oct 25, 2025
0a54c24
Added version with all params
Oct 25, 2025
83c54a6
added other indicators
rahulkfernandes Oct 25, 2025
0234172
saves data to csv
rahulkfernandes Oct 25, 2025
823b5c4
Code to aquire macro data implemented. Not tested for all available s…
rahulkfernandes Oct 25, 2025
fdd12ec
rate limit guard implemented
rahulkfernandes Oct 26, 2025
6e13114
loads all three datasets
rahulkfernandes Oct 26, 2025
165aa2f
Incorrect series ids, needs verification
rahulkfernandes Oct 26, 2025
d2dcb73
code to skip error codes, added
rahulkfernandes Oct 28, 2025
58a662a
notebook for exploration purposes created
rahulkfernandes Oct 28, 2025
c4db4ba
HRP implemented
rahulkfernandes Oct 29, 2025
e11848f
Naive MVP and Global MVP implmented
rahulkfernandes Oct 29, 2025
fcf386e
basic test for hrp added
rahulkfernandes Oct 29, 2025
6c5aaae
Redundant forceful symmetry removed
rahulkfernandes Oct 29, 2025
32e66c6
setter function for ridge added
rahulkfernandes Oct 29, 2025
a1e030f
function for auto calculation of ridge added
rahulkfernandes Oct 29, 2025
cc82db5
Mean-Variance Portfolio with Arithmetic and Geometric mean expected ret
rahulkfernandes Oct 30, 2025
7812824
Stabilized mean calc and inversion
rahulkfernandes Oct 30, 2025
fba476a
Removed untracked variables
Oct 30, 2025
f39fcf5
conflict fix
rahulkfernandes Oct 31, 2025
7f22f15
Merge branch 'financial-loss-functions' of https://github.com/rahulkf…
rahulkfernandes Oct 31, 2025
701a9fe
conflict_fixed
rahulkfernandes Oct 31, 2025
e8a3ec6
const file updated
rahulkfernandes Oct 31, 2025
92e9edd
pytest added
rahulkfernandes Oct 31, 2025
20097da
unit tests added for macro_api.py
rahulkfernandes Oct 31, 2025
d676073
integration test for api pipeline added
rahulkfernandes Oct 31, 2025
d84c1bd
main api orchestration moved back to macro_api.py
rahulkfernandes Oct 31, 2025
af86cca
checks number of tickers present
rahulkfernandes Oct 31, 2025
5702008
First and last dates checked, no missing values
rahulkfernandes Oct 31, 2025
fae767a
basic plots added
rahulkfernandes Oct 31, 2025
cca9131
cleaning and preprocessing for cov based models added
rahulkfernandes Oct 31, 2025
1688d49
info added
rahulkfernandes Nov 1, 2025
301d1e1
tests for hrp added
rahulkfernandes Nov 1, 2025
12ec994
unit tests for HRP added
rahulkfernandes Nov 2, 2025
072fa54
tests for naive MVP added
rahulkfernandes Nov 2, 2025
e3f0246
Setting ridge bug fixed, test added
rahulkfernandes Nov 2, 2025
6314cbd
ridge in constructor bug fixed, tests for Base added
rahulkfernandes Nov 2, 2025
547cda6
Tests added for GMVP
rahulkfernandes Nov 2, 2025
76b7e1d
Tests added for Mean Variance Portfolio
rahulkfernandes Nov 2, 2025
6049089
dulicate dates found, cross-sec mean & vol plot added
rahulkfernandes Nov 4, 2025
e9a72cb
Global View explored more
rahulkfernandes Nov 5, 2025
22c3ecb
data found to be not normal, follows student-t
rahulkfernandes Nov 5, 2025
9525e5e
Distruibutions Tested for all features
rahulkfernandes Nov 6, 2025
f2afd09
exploration
rahulkfernandes Nov 7, 2025
e8b9ae6
Merge branch 'financial-loss-functions' into loss-functions
rahulkfernandes Nov 7, 2025
ed6cd32
sensitive file removed
rahulkfernandes Nov 7, 2025
bd5b675
explorartion moved to directory
rahulkfernandes Nov 8, 2025
61d5f7e
bugs fixed
rahulkfernandes Nov 8, 2025
6feb565
Checked features for dist drift
rahulkfernandes Nov 8, 2025
2b35f2b
vol clustering & ARCH effect
rahulkfernandes Nov 8, 2025
f6d4ca7
exploration code implemented
rahulkfernandes Nov 12, 2025
ad232f2
cleaning function added
rahulkfernandes Nov 13, 2025
8e18d58
Yeo Johnson Transformation implemeted for vol_change
rahulkfernandes Nov 13, 2025
9e8eb40
tests updated, box-cox added
rahulkfernandes Nov 13, 2025
3b949d1
Added macro-analysis exploration
Nov 15, 2025
470cb37
readme file added
rahulkfernandes Nov 19, 2025
c59cf2d
directory structure changed
rahulkfernandes Nov 19, 2025
bd098dd
env updated
rahulkfernandes Nov 19, 2025
36bb61c
cleaning function added
rahulkfernandes Nov 13, 2025
99432b8
Yeo Johnson Transformation implemeted for vol_change
rahulkfernandes Nov 13, 2025
88582ee
tests updated, box-cox added
rahulkfernandes Nov 13, 2025
1f0a029
Merge branch 'rahul/loss-functions/preprocessing' of https://github.c…
rahulkfernandes Nov 19, 2025
96d6df7
rebase done
rahulkfernandes Nov 19, 2025
06d447a
raw folder bugs fixed
rahulkfernandes Nov 20, 2025
58bc3fa
scripts added
rahulkfernandes Nov 20, 2025
1cfd196
cleaning function added
rahulkfernandes Nov 13, 2025
fe455d5
Yeo Johnson Transformation implemeted for vol_change
rahulkfernandes Nov 13, 2025
a0de3cf
tests updated, box-cox added
rahulkfernandes Nov 13, 2025
553dd7a
cleaning function added
rahulkfernandes Nov 13, 2025
a46c8db
Yeo Johnson Transformation implemeted for vol_change
rahulkfernandes Nov 13, 2025
beea6bd
tests updated, box-cox added
rahulkfernandes Nov 13, 2025
90d3643
rebase done
rahulkfernandes Nov 19, 2025
2df9b6e
Merge branch 'rahul/loss-functions/preprocessing' of https://github.c…
rahulkfernandes Nov 20, 2025
8f5f3a1
conflicts fixed
rahulkfernandes Nov 20, 2025
640abf2
run_preprocessing file added
rahulkfernandes Nov 20, 2025
227251b
requirements updated
rahulkfernandes Nov 20, 2025
a259d4e
script files refactored
rahulkfernandes Nov 20, 2025
faad2e8
env variables handled outside src
rahulkfernandes Nov 20, 2025
868f297
saving csv file moved to pipeline for macro
rahulkfernandes Nov 20, 2025
82d0828
readme updated
rahulkfernandes Nov 21, 2025
395225b
contact info added
rahulkfernandes Nov 21, 2025
32d3644
directory handling refactored
rahulkfernandes Nov 21, 2025
f385e22
Normalizes data
rahulkfernandes Nov 21, 2025
b73a8cd
usage notes for CRSP equivalent datasets added
rahulkfernandes Nov 21, 2025
d65e1ff
cov preprocessing refactored
rahulkfernandes Nov 21, 2025
59261f5
preprocessing saves files, run_training file added
rahulkfernandes Nov 21, 2025
2a8c0ab
bug fixed, synthetic data added
rahulkfernandes Nov 21, 2025
4c4bf81
saves nn processed dataframes to csv
rahulkfernandes Nov 21, 2025
7dfba47
Code refactored to use config file, instead of extra env variables
rahulkfernandes Nov 22, 2025
ecee0ca
readme updated
rahulkfernandes Nov 22, 2025
e2c7dcc
paths in crsp_exp are loaded from config
rahulkfernandes Nov 22, 2025
0e5ba30
line breaks added to readme
rahulkfernandes Nov 22, 2025
a72f2a3
loading processed files updated
rahulkfernandes Nov 22, 2025
3c52e5a
code refactored, test refactored
rahulkfernandes Nov 22, 2025
af29f82
csv file saving bug fixed
rahulkfernandes Nov 23, 2025
8e5cca7
broadcasts common features to all tickers
rahulkfernandes Nov 24, 2025
689fc28
sprtrn_spr_trn bug fixed
rahulkfernandes Nov 24, 2025
954bc4b
reshaper class implemented
rahulkfernandes Nov 24, 2025
0f63f4e
loaded macro data. TODO's added
rahulkfernandes Nov 24, 2025
e9200bd
reshaping implmented
rahulkfernandes Nov 25, 2025
69eb334
Tests added for loading.py
rahulkfernandes Nov 26, 2025
91628c2
reshaper functions updated
rahulkfernandes Nov 26, 2025
f23961f
tests for Preprocessor added
rahulkfernandes Nov 26, 2025
96da4d0
tests for utils added
rahulkfernandes Nov 26, 2025
d4fb09c
basic lstm model implemented
rahulkfernandes Nov 26, 2025
c5703c2
tuned better
rahulkfernandes Nov 26, 2025
e3e13cb
Trainer implemented
rahulkfernandes Nov 27, 2025
1611ae0
dropout added, transformation removed
rahulkfernandes Nov 27, 2025
6ea0646
Attention+LSTM added
rahulkfernandes Nov 27, 2025
144d41d
diff-able sharpe added, equal-weight prior added
rahulkfernandes Nov 27, 2025
7f107be
sample data fixed
rahulkfernandes Nov 28, 2025
652efbb
synthetic data: more years added
rahulkfernandes Nov 28, 2025
8c1d758
attendtion layer improved
rahulkfernandes Nov 28, 2025
e9380df
relu added to attn model
rahulkfernandes Nov 28, 2025
74f250e
plots loss curves
rahulkfernandes Nov 28, 2025
979a169
Added splits for macro and modified paths
Nov 28, 2025
2a4aac7
gets validation alloc weights, calculates equal weight
rahulkfernandes Nov 29, 2025
4c1ac44
plots validation daily returns for each portfolio weight and window
rahulkfernandes Nov 29, 2025
1836341
calculates total return over each window
rahulkfernandes Nov 29, 2025
4485b78
Added macro-aware preprocessing, optimized feature broadcasting
Nov 29, 2025
3e62838
Added path resolutions for data directories
Nov 29, 2025
9763178
Dropping NaN
Nov 30, 2025
b30f058
Removing NaN
Nov 30, 2025
f6011dc
calculates overall perfomance of portfolios on validation windows
rahulkfernandes Nov 30, 2025
3815d28
hparams updated
rahulkfernandes Nov 30, 2025
6cb41d7
attendtion layer improved
rahulkfernandes Nov 28, 2025
4bdef7b
relu added to attn model
rahulkfernandes Nov 28, 2025
f35e4ed
plots loss curves
rahulkfernandes Nov 28, 2025
5de6c3b
gets validation alloc weights, calculates equal weight
rahulkfernandes Nov 29, 2025
5e9a6fd
plots validation daily returns for each portfolio weight and window
rahulkfernandes Nov 29, 2025
d14b37b
calculates total return over each window
rahulkfernandes Nov 29, 2025
774c787
calculates overall perfomance of portfolios on validation windows
rahulkfernandes Nov 30, 2025
1802228
hparams updated
rahulkfernandes Nov 30, 2025
5110b1c
Merge branch 'rahul/loss-functions/models' of https://github.com/trav…
rahulkfernandes Nov 30, 2025
cb63eee
Macro addition commented out for testing
rahulkfernandes Nov 30, 2025
bada56b
Layer norm added to Attention LSTM
rahulkfernandes Dec 1, 2025
e2d0eed
model stability improved
rahulkfernandes Dec 1, 2025
25f4da5
trainer class refactored to be more modular
rahulkfernandes Dec 4, 2025
0bf0bde
some tests added for MacroCombiner
rahulkfernandes Dec 11, 2025
ec259bd
doxygen docs created
rahulkfernandes Dec 12, 2025
414717d
documentation HTML created using Doxygen
rahulkfernandes Dec 12, 2025
5fc7303
readme updated
rahulkfernandes Dec 13, 2025
12d9305
tests added for preprocess
rahulkfernandes Dec 13, 2025
a72272d
tests added for dataset.py
rahulkfernandes Dec 13, 2025
01907e3
unneccessart data file removed
rahulkfernandes Dec 13, 2025
f9ae64c
Improved type hints
rahulkfernandes Dec 21, 2025
9205d80
type hints added
rahulkfernandes Dec 22, 2025
368e5c2
Add CRSP-macro feature selection pipeline and reports
Feb 9, 2026
2a465d4
Delete financial_loss_functions/data/raw/sample directory
v-atharva Feb 9, 2026
39a8c8f
Delete financial_loss_functions/data/feature_selection directory
v-atharva Feb 9, 2026
43591e1
Add sector-aware macro feature selection pipeline
Feb 18, 2026
7f73fbd
Added exploration for feature selection
Feb 18, 2026
64ae9e9
Chore: gitignore fixed before merge
rahulkfernandes Feb 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,28 @@ copy_binary_osx.sh
run.sh
*/__pycache__/*
__pycache__/*
__pycache__
*.pyc
visualization/plots/*
test_output/*
test_output/*

# Cache
*/.pytest_cache

# Environment files
.env
financial_loss_functions/exploration/.ipynb_checkpoints

# Dataset directories
financial_loss_functions/data/raw/2023_sp_500_select_50/
financial_loss_functions/data/raw/macro/
financial_loss_functions/data/processed/
# financial_loss_functions/scripts/generate_synthetic_data.py

# Artifacts & Results
financial_loss_functions/artifacts
financial_loss_functions/docs/docs_out/latex

# Local secrets
financial_loss_functions/data_collectors/fred_config.py
financial_loss_functions/project_structure.txt
4 changes: 4 additions & 0 deletions financial_loss_functions/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FRED_KEY = "<API-KEY>" # API key from Fred API

# Name of raw CRSP dataset directory
CRSP_DIR = "sample" # change to specific name if using equivalent dataset
167 changes: 167 additions & 0 deletions financial_loss_functions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# Financially Guided Neural Networks for Robust Portfolio Optimization

## Description
This repository contains the implementation for the capstone project "Financially Guided Neural Networks for Robust Portfolio Optimization," developed by Rahul Kenneth Fernandes and Atharva Atul Vaidya under the guidance of Dr. Travis Desell at Rochester Institute of Technology. The project introduces an end-to-end deep learning framework that embeds financial principles of portfolio construction theory directly into neural network training objectives to create stable, diversified portfolios. Our models output normalized allocation weights and optimize differentiable surrogates for key metrics like Sharpe/Sortino ratios, Conditional Value-at-Risk (CVaR), Maximum Drawdown (MDD), risk parity, and concentration penalties—enabling gradient-based optimization without intermediate forecasting. The goal is to develop a custom loss function to train neural networks to generate robust, diversified portfolios that generalize across market regimes.

**Authors:** Rahul Kenneth fernandes, Atharva Atul Vaidya
**Advisors:** Dr. Travis Desell
**Institution:** Rochester Institute of Technology

## Prerequisites
- Python 3.13.5
- Free [Fred API Key](https://fred.stlouisfed.org)

## Hardware Recommendations
- RAM: 16GB
- GPU: CUDA compatible NVIDIA GPU or MPS MacOS GPU

## Installation

### Clone Git Repository
```bash
git clone -b loss-functions https://github.com/travisdesell/exact.git
cd exact/financial_loss_functions
```

### Install Dependencies
1. Create and activate a virtual environment (optional but recommended) You can use either venv or conda.

venv:
```bash
# Create and activate a virtual environment (optional but recommended)
python -m venv <env_name>
source <env_name>/bin/activate # On Windows, use: <env_name>\Scripts\activate
```
OR

conda
```bash
conda create -n <env_name> python=3.13.5
conda activate <env_name>
```

2. Install python dependecies
```bash
# Install the required packages
pip install -r requirements.txt
```

### Setting Up Environment Variables
1. Create your local environment file:
```bash
cp .env.example .env
```
2. Update the .env file in root directory with your Fred API key

## Usage
### 1. Run macro-economic data collection
```bash
python -m scripts.run_macro_collection
```

### 2. Run data processing
```bash
python -m scripts.run_processing
```

### 3. Run prelimnary training
```bash
python -m scripts.run_training
```

### 4. Run feature selection analysis
```bash
python -m scripts.run_feature_selection --crsp-dir 2023_sp_500_select_50
```

### Run tests
```bash
pytest tests
```

## Directory Structure
```text
financial_loss_functions # Root directory for this project
├── config
│   └── paths.json
├── data
│   ├── processed
│   └── raw
│   ├── macro # gitignored since, data can be acquired
│   │   ├── Consumption_Orders_Inventories.csv
│   │   ├── Housing.csv
│   │   ├── Labor_Market.csv
│   │   ├── Money_Credit.csv
│   │   ├── Output_Income.csv
│   │   ├── Prices.csv
│   │   ├── Rates_FX.csv
│   │   └── Stock_Market.csv
│   └── sample # Contains synthetic CRSP-like sample data
│   ├── combined_predictors_test.csv
│   ├── combined_predictors_train.csv
│   └── combined_predictors_validation.csv
├── exploration
│   ├── crsp_exp.ipynb # Exploration of the CRSP dataset
│   └── fred_series_analysis.ipynb # Exploration of the macro-economic data
├── pytest.ini
├── README.md # This file
├── requirements.txt # Python dependecies
├── scripts
│   ├── run_macro_collection.py # Data collection
│   ├── run_processing.py # Data cleaning and processing
│   ├── run_training.py # All model training
│   └── utils.py
├── src
│   ├── __init__.py
│   ├── data_collection
│   │   ├── const.py # Contains fixed series IDs for FRED API
│   │   └── macro_api.py # Collects data from FRED API
│   ├── data_processing
│   │   ├── loading.py
│   │   ├── pipeline.py # Runs processing pipeline
│   │   └── preprocess.py
│   ├── models
│   │   ├── cov_models.py # Covariance-based classicial models
│   │   ├── examm.py # Python wrapper to run EXAMM model
│   │   └── pipeline.py # Runs training pipeline for all models
│   └── utils.py
├── tests
│ ├── cov_models_tests.py
│ ├── integration
│ │   └── test_macro_data_coll.py
│ └── unit
│ ├── test_cov_models.py
│ ├── test_loading.py
│ ├── test_macro_api.py
│ ├── test_preprocess.py
│ └── test_utils.py
├── .env # Environment variables
└── .env.example # Template for storing environment variables
```

## Using CRSP Equivalent Datasets
Currently, a sythetic CRSP-like dataset is stored in `data/raw/sample`. If any other CRSP equivalent dataset is being used, place the directory in `data/raw/` and update the CRSP_DIR environment variable in the .env file with the name of the equivalent data directory.

.env
```bash
CRSP_DIR = "<equivalent-data-directory>" # Add directory name here if using CRSP like dataset
```

Since we use pre-split data (train, val, test), the new files must follow the structure shown below and the config/paths.json must be updated to reflect the correct file names.

- data/
- raw/
- `<equivalent-data-directory>/`
- `<train_name>.csv`
- `<validation_name>.csv`
- `<test_name>.csv`

## Contact

**Rahul Keneth Fernandes**
Email: rf4074@rit.edu
Github: [@rahulkfernandes](https://github.com/rahulkfernandes)

**Atharva Atul Vaidya**
Email: aav6986@rit.edu
Github: [@v-atharva](https://github.com/v-atharva)
3 changes: 3 additions & 0 deletions financial_loss_functions/config/features.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"common_features": ["sprtrn"]
}
41 changes: 41 additions & 0 deletions financial_loss_functions/config/hparams.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"rolling_windows": {
"in_size": 200,
"out_size": 50,
"stride": 1
},
"BaseLSTM": {
"model": {
"hidden_size": 256,
"num_layers": 2,
"dropout": 0.2
},
"optimizer": {
"lr": 1e-4,
"weight_decay": 3e-4
},
"train" : {
"train_batch_size": 256,
"val_batch_size": 1,
"clip_grad_norm": 0.5,
"epochs": 100
}
},
"AttentionLSTM": {
"model": {
"hidden_size": 128,
"num_layers": 3,
"dropout": 0.2
},
"optimizer": {
"lr": 1e-3,
"weight_decay": 3e-4
},
"train": {
"train_batch_size": 256,
"val_batch_size": 1,
"clip_grad_norm": 0.5,
"epochs": 100
}
}
}
29 changes: 29 additions & 0 deletions financial_loss_functions/config/paths.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"data": {
"data_dir": "data/",
"raw_dir": "data/raw/",
"processed_dir": "data/processed/",
"raw_macro_dir": "data/raw/macro/",
"crsp_dir": ""
},
"raw_files": {
"train": "combined_predictors_train.csv",
"val": "combined_predictors_validation.csv",
"test": "combined_predictors_test.csv"
},
"processed_paths": {
"returns_train": "data/processed/ret_train.csv",
"returns_val": "data/processed/ret_val.csv",
"returns_test": "data/processed/ret_test.csv",
"cov_train": "data/processed/cov_train.csv",
"corr_train": "data/processed/corr_train.csv",
"processed_train": "data/processed/processed_train.csv",
"processed_val": "data/processed/processed_val.csv",
"processed_test": "data/processed/processed_test.csv"
},
"artifacts": {
"artifact_dir": "artifacts/",
"results": "artifacts/results/",
"plots": "artifacts/results/plots/"
}
}
Loading