Gourav Kumar
2 years ago
5 changed files with 201 additions and 273 deletions
@ -0,0 +1,15 @@ |
|||
# Fincal |
|||
This module simplified handling of time-series data |
|||
|
|||
## The problem |
|||
Time series data often have missing data points. These missing points mess things up when you are trying to do a comparison between two sections of a time series. |
|||
|
|||
To make things worse, most libraries don't allow comparison based on dates. Month to Month and year to year comparisons become difficult as they cannot be translated into number of days. However, these are commonly used metrics while looking at financial data. |
|||
|
|||
## The Solution |
|||
Fincal aims to simplify things by allowing you to: |
|||
* Compare time-series data based on dates |
|||
* Easy way to work around missing dates by taking the closest data points |
|||
* Completing series with missing data points using forward fill and backward fill |
|||
|
|||
## Examples |
@ -0,0 +1,129 @@ |
|||
{ |
|||
"cells": [ |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 14, |
|||
"id": "3f7938c0-98e3-43b8-86e8-4f000cda7ce5", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"import datetime\n", |
|||
"import pandas as pd\n", |
|||
"\n", |
|||
"from fincal.fincal import TimeSeries\n", |
|||
"from fincal.core import Series" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 16, |
|||
"id": "757eafc2-f804-4e7e-a3b8-2d09cd62e646", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"dfd = pd.read_csv('test_files/nav_history_daily - copy.csv')" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 17, |
|||
"id": "59b3d4a9-8ef4-4652-9e20-1bac69ab4ff9", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"dfd = dfd[dfd['amfi_code'] == 118825].reset_index(drop=True)" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 19, |
|||
"id": "4bc95ae0-8c33-4eab-acf9-e765d22979b8", |
|||
"metadata": {}, |
|||
"outputs": [ |
|||
{ |
|||
"name": "stdout", |
|||
"output_type": "stream", |
|||
"text": [ |
|||
"Warning: The input data contains duplicate dates which have been ignored.\n" |
|||
] |
|||
} |
|||
], |
|||
"source": [ |
|||
"ts = TimeSeries([(i.date, i.nav) for i in dfd.itertuples()], frequency='D')" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 20, |
|||
"id": "f2c3218c-3984-43d6-8638-41a74a9d0b58", |
|||
"metadata": {}, |
|||
"outputs": [ |
|||
{ |
|||
"data": { |
|||
"text/plain": [ |
|||
"TimeSeries([(datetime.datetime(2013, 1, 2, 0, 0), 18.972),\n", |
|||
"\t (datetime.datetime(2013, 1, 3, 0, 0), 19.011),\n", |
|||
"\t (datetime.datetime(2013, 1, 4, 0, 0), 19.008)\n", |
|||
"\t ...\n", |
|||
"\t (datetime.datetime(2022, 2, 10, 0, 0), 86.5),\n", |
|||
"\t (datetime.datetime(2022, 2, 11, 0, 0), 85.226),\n", |
|||
"\t (datetime.datetime(2022, 2, 14, 0, 0), 82.53299999999999)], frequency='D')" |
|||
] |
|||
}, |
|||
"execution_count": 20, |
|||
"metadata": {}, |
|||
"output_type": "execute_result" |
|||
} |
|||
], |
|||
"source": [ |
|||
"ts" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 22, |
|||
"id": "dc469722-c816-4b57-8d91-7a3b865f86be", |
|||
"metadata": {}, |
|||
"outputs": [ |
|||
{ |
|||
"ename": "TypeError", |
|||
"evalue": "getattr(): attribute name must be string", |
|||
"output_type": "error", |
|||
"traceback": [ |
|||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", |
|||
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", |
|||
"File \u001b[1;32m<timed eval>:1\u001b[0m, in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n", |
|||
"File \u001b[1;32mD:\\Documents\\Projects\\fincal\\fincal\\fincal.py:203\u001b[0m, in \u001b[0;36mTimeSeries.calculate_rolling_returns\u001b[1;34m(self, from_date, to_date, frequency, as_on_match, prior_match, closest, compounding, years)\u001b[0m\n\u001b[0;32m 200\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mAttributeError\u001b[39;00m:\n\u001b[0;32m 201\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInvalid argument for frequency \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfrequency\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m--> 203\u001b[0m dates \u001b[38;5;241m=\u001b[39m \u001b[43mcreate_date_series\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfrom_date\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mto_date\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfrequency\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 204\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m frequency \u001b[38;5;241m==\u001b[39m AllFrequencies\u001b[38;5;241m.\u001b[39mD:\n\u001b[0;32m 205\u001b[0m dates \u001b[38;5;241m=\u001b[39m [i \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m dates \u001b[38;5;28;01mif\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtime_series]\n", |
|||
"File \u001b[1;32mD:\\Documents\\Projects\\fincal\\fincal\\fincal.py:16\u001b[0m, in \u001b[0;36mcreate_date_series\u001b[1;34m(start_date, end_date, frequency, eomonth)\u001b[0m\n\u001b[0;32m 11\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcreate_date_series\u001b[39m(\n\u001b[0;32m 12\u001b[0m start_date: datetime\u001b[38;5;241m.\u001b[39mdatetime, end_date: datetime\u001b[38;5;241m.\u001b[39mdatetime, frequency: \u001b[38;5;28mstr\u001b[39m, eomonth: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[0;32m 13\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m List[datetime\u001b[38;5;241m.\u001b[39mdatetime]:\n\u001b[0;32m 14\u001b[0m \u001b[38;5;124;03m\"\"\"Creates a date series using a frequency\"\"\"\u001b[39;00m\n\u001b[1;32m---> 16\u001b[0m frequency \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mAllFrequencies\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfrequency\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 17\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m eomonth \u001b[38;5;129;01mand\u001b[39;00m frequency\u001b[38;5;241m.\u001b[39mdays \u001b[38;5;241m<\u001b[39m AllFrequencies\u001b[38;5;241m.\u001b[39mM\u001b[38;5;241m.\u001b[39mdays:\n\u001b[0;32m 18\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124meomonth cannot be set to True if frequency is higher than \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mAllFrequencies\u001b[38;5;241m.\u001b[39mM\u001b[38;5;241m.\u001b[39mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n", |
|||
"\u001b[1;31mTypeError\u001b[0m: getattr(): attribute name must be string" |
|||
] |
|||
} |
|||
], |
|||
"source": [ |
|||
"%%time\n", |
|||
"ts.calculate_rolling_returns(from_date='2020-01-01', to_date='2021-01-01')" |
|||
] |
|||
} |
|||
], |
|||
"metadata": { |
|||
"kernelspec": { |
|||
"display_name": "Python 3 (ipykernel)", |
|||
"language": "python", |
|||
"name": "python3" |
|||
}, |
|||
"language_info": { |
|||
"codemirror_mode": { |
|||
"name": "ipython", |
|||
"version": 3 |
|||
}, |
|||
"file_extension": ".py", |
|||
"mimetype": "text/x-python", |
|||
"name": "python", |
|||
"nbconvert_exporter": "python", |
|||
"pygments_lexer": "ipython3", |
|||
"version": "3.8.3" |
|||
} |
|||
}, |
|||
"nbformat": 4, |
|||
"nbformat_minor": 5 |
|||
} |
@ -0,0 +1,15 @@ |
|||
{ |
|||
// Use IntelliSense to learn about possible attributes. |
|||
// Hover to view descriptions of existing attributes. |
|||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 |
|||
"version": "0.2.0", |
|||
"configurations": [ |
|||
{ |
|||
"name": "Python: Current File", |
|||
"type": "python", |
|||
"request": "launch", |
|||
"program": "${file}", |
|||
"console": "integratedTerminal" |
|||
} |
|||
] |
|||
} |
Loading…
Reference in new issue