-
Notifications
You must be signed in to change notification settings - Fork 4
feat(portfolio): Read data and calculate mean-variance for returns #81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat(portfolio): Read data and calculate mean-variance for returns #81
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #81 +/- ##
==========================================
- Coverage 92.64% 89.70% -2.95%
==========================================
Files 29 30 +1
Lines 2775 2866 +91
==========================================
Hits 2571 2571
- Misses 204 295 +91 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
In the changes following this, I would also like to separate out the functions that calculate returns as they aren't really struct functions. Could move them to a more general utilities module or something that the whole package can make use of. |
|
Thanks for putting this together @SaurabhJamadagni; already looks really solid! Two quick notes:
Appreciate all the work so far! P.S. Just merged #65 🚀 |
|
No worries on the delay @carlobortolan. Hope you have a stress free move!
Noted. I'll give it a look.
Thanks on this one! Appreciate you pushing the final few commits to get it merged. Do we wanna keep this PR open till the whole optimization is implemented or are you looking to merge it after some of the above changes? No rush of course, I just wanted to clarify where you stand on this. |
|
Sorry for the long delay - finally finished moving (and all the bureaucracy that comes with it 🙄), so I'll have some time to review it over the weekend.
This PR is already quite well-sized with ~300 added LOC, so it's fine to leave it as is. (However, I'd say that it would be better to have the whole optimization merged as one PR, so that |
No worries @carlobortolan! I know the headache that comes with moving. I hope everything went well.
I agree with this and hence was curious. I also wanted to check if you would consider having dev and release branch instead of merging with main. Incomplete features could stay on dev and after a certain amount of features are added or after a certain period of time you could merge dev into main as a release which could be documented through the current CHANGELOG or something. Do you think there's a benefit to such a separation? |
@SaurabhJamadagni: Yes, having a dev branch could make things more organized, especially for tracking unreleased features. That said, I think that setup usually benefits larger projects more. If we had However, what we could do is keep master as the release branch and handle ongoing work through feature branches. For example, in this case we could have This way, features that are less modular / need multiple PRs can be split into smaller branches& PRs, while others can still be merged in a single PR. Does this approach sound good? (P.S.: I took the liberty of fixing the merge conflicts here, since I just updated some dependencies in another PR which might cause some issues with our |
…o portfolio_optimization
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR and again sorry for the long review-time: The PR looks mostly good to me; just added a few very small comments 👍
edit: another thing I noticed: The weights field is Option<Vec<f64>> but currently never populated. Is this intended? It might be a good idea to add a method stub/placeholder for computing optimal weights, so we don't forget to implement this later.
|
|
||
| #[warn(unused_variables)] | ||
| fn main() { | ||
| let data_path = "/Users/moneymaker/Downloads/ETFprices.csv"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use std::env::args() or a relative path to an example file (e.g., examples/data/ETFprices.csv) to avoid hard coded paths.
| fn calculate_simple_returns(prices: &Array2<f64>) -> Array2<f64> { | ||
| let simple_returns = | ||
| (&prices.slice(s![1.., ..]) - &prices.slice(s![..-1, ..])) / prices.slice(s![..-1, ..]); | ||
| simple_returns.to_owned() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
calculate_simple_returns and calculate_log_returns currently create new arrays using .to_owned(). Consider in-place operations or preallocating arrays for large datasets.
| rand_distr = "0.5.1" | ||
| rayon = "1.10.0" | ||
| statrs = "0.18.0" | ||
| ndarray = "0.16.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the latest version is 0.17.0 - is there any reason for using 0.16.x? If not, we should probably upgrade to the newer version
| fn calculate_log_returns(prices: &Array2<f64>) -> Array2<f64> { | ||
| let log_prices = prices.mapv(|x| x.ln()); | ||
| let log_returns = &log_prices.slice(s![1.., ..]) - &log_prices.slice(s![..-1, ..]); | ||
| log_returns.to_owned() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see comment above
The PR is in reference to issue:
PR makes the following changes:
Portfoliostruct which holds:.csvfile which contains price data.fn new()will read from the data file and perform return calculations and produce a covariance matrix.ndarrayand 'ndarray_stats` are used to store records from the csv and perform operations.Example output:

Next steps:
@carlobortolan please let me know your feedback on this. I haven't written tests for this yet. Was planning to include them when I add the optimization part. Can add something before as well if you would like that before merging. Let me know :)