Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ ARGUS is a Python-based market analytics project evolving from a small FX conver

ARGUS is currently focused on building a clean local foundation:

- currency conversion using live ExchangeRate API data
- historical market-data retrieval using yfinance
- currency conversion using live exchange-rate data
- calculator and conversion logic
- input validation and error handling
- Tkinter GUI prototype
- legacy CLI/debug interface
- pandas/matplotlib-based analytics prototype
- first pandas/matplotlib-based analytics prototype
- tests and documentation

> [!IMPORTANT]
Expand Down Expand Up @@ -67,16 +66,19 @@ Each roadmap phase is treated as a separate development sprint. The roadmap desc
## Current Features

- Calculator
- Currency conversion using live ExchangeRate API data
- Historical market-data retrieval using yfinance
- Currency conversion using live exchange rates
- Input validation and error handling
- Tkinter GUI prototype
- Legacy CLI/debug interface
- Basic pandas-based trend metrics
- Matplotlib-based trend visualization
- Basic client, service and analytics pipeline
- Mock time-series data for early analytics development
- Basic test suite

> [!CAUTION]
> Historical market data support is still limited.
> The current live exchange-rate client is useful for simple conversion, but future analytics work will require additional data sources such as Frankfurter or yfinance.

---

## Project Structure
Expand Down Expand Up @@ -113,7 +115,6 @@ README.md

- requests
- python-dotenv
- yfinance
- pandas
- NumPy
- matplotlib
Expand All @@ -123,7 +124,6 @@ README.md
### Current data source

- ExchangeRate API for live currency conversion
- yfinance for historical market-data retrieval and analytics

---

Expand All @@ -136,6 +136,7 @@ Planned or likely future technologies include:
### Data sources

- Frankfurter API for historical FX data
- yfinance for broader market data
- possible additional market-data APIs later

### Data processing
Expand Down Expand Up @@ -192,7 +193,7 @@ Before running ARGUS locally, make sure you have:
- Python 3.11 or newer
- Git
- pip
- an ExchangeRate API key for live currency conversion. Historical analytics currently use yfinance and do not require an additional API key.
- an ExchangeRate API key for live currency conversion

Recommended for development:

Expand Down Expand Up @@ -341,9 +342,9 @@ The project now has a runnable local Python application, a Tkinter GUI prototype

Current focus:

- continue Sprint 2 — Market Analytics & Data Source Expansion
- extend historical market-data support beyond the first yfinance client
- start Sprint 2 — Market Analytics & Data Source Expansion
- improve historical exchange-rate data support
- add stronger market metrics
- expand pandas-based analytics workflows
- improve dashboard usefulness without adding unnecessary chart noise
- document metric definitions, assumptions and data-source behavior
- document metric definitions, assumptions and data-source behavior
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ dependencies = [
"pandas",
"numpy",
"matplotlib",
"yfinance",
]

[project.optional-dependencies]
Expand Down
9 changes: 4 additions & 5 deletions src/argus/analytics/charts/trend_chart.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import matplotlib.pyplot as plt
import pandas as pd
from argus.services.timeseries_service import prepare_trend_analysis


def create_trendchart(curr_symbol: str, start: str, end: str, interval: str):
def create_trendchart(curr: str, dates: pd.DataFrame):
"""
Create a trend chart for exchange-rate analysis.

Expand Down Expand Up @@ -30,10 +31,8 @@ def create_trendchart(curr_symbol: str, start: str, end: str, interval: str):
Minimum and maximum exchange-rate values are marked with scatter
points and annotations.
"""
result = prepare_trend_analysis(curr_symbol, start, end, interval)
if result is None:
return None
df, min_max_rates = result
df = pd.DataFrame()
df, min_max_rates = prepare_trend_analysis(curr, dates)
min_date = min_max_rates["min_date"][0]
min_rate = min_max_rates["min_rate"][0]
max_date = min_max_rates["max_date"][0]
Expand Down
File renamed without changes.
43 changes: 0 additions & 43 deletions src/argus/clients/yfinance_client.py

This file was deleted.

32 changes: 24 additions & 8 deletions src/argus/gui/app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import tkinter as tk
import pandas as pd
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from argus.analytics.charts.trend_chart import create_trendchart
from argus.services.calculator_service import calc, check_op
Expand Down Expand Up @@ -76,10 +77,27 @@ def show_trend() -> None:
global trend_canvas
global trend_chart_widget

curr_symbol = "EURUSD=X"
start = "2024-01-01"
end = "2025-01-01"
interval = "1d"
mock_dates = {
"date": [
"2026-06-01",
"2026-06-02",
"2026-06-03",
"2026-06-04",
"2026-06-05",
"2026-06-06",
"2026-06-07",
"2026-06-08",
"2026-06-09",
"2026-06-10",
"2026-06-11",
"2026-06-12",
"2026-06-13",
"2026-06-14",
"2026-06-15",
]
}
mock_dates = pd.DataFrame(mock_dates)
mock_curr = "USD"

calc_frame.pack_forget()
conv_frame.pack_forget()
Expand All @@ -90,16 +108,14 @@ def show_trend() -> None:
content.pack(side="top", fill=tk.BOTH, expand=True)

if trend_canvas is None:
fig = create_trendchart(curr_symbol, start, end, interval)
if fig is None:
return None
fig = create_trendchart(mock_curr, mock_dates)
fig.set_size_inches(7, 4)

trend_canvas = FigureCanvasTkAgg(fig, master=content)
trend_chart_widget = trend_canvas.get_tk_widget()

if trend_chart_widget is None:
return None
return
trend_canvas.draw()
trend_chart_widget.pack(fill=tk.BOTH, expand=True)

Expand Down
39 changes: 15 additions & 24 deletions src/argus/services/timeseries_service.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pandas as pd
from argus.clients.yfinance_client import get_timeseries
from argus.clients.mock_client import get_mock_timeseries
from argus.analytics.metrics.trend_metrics import (
add_rolling_average,
add_daily_percentage_change,
Expand All @@ -8,33 +8,24 @@


def prepare_trend_analysis(
curr_symbol: str, start: str, end: str, intervall: str
) -> tuple[pd.DataFrame, dict] | None:
mock_curr: str, df: pd.DataFrame
) -> tuple[pd.DataFrame, dict]:
"""
Prepare time-series data for trend analysis.
Prepares the data for trend analysis by adding conversion rates, daily percentage change, and rolling average.

Fetches historical exchange-rate data for the given currency symbol and
enriches it with daily percentage changes and a rolling average. It also
calculates the minimum and maximum exchange rates for the resulting time
series.
Arg1: mock_curr: str - the currency code for which the trend analysis is to
be performed
Arg2: df: pd.DataFrame - the DataFrame containing the dates for which the
conversion rates are to be added

Args:
curr_symbol (str): Currency symbol used by Yahoo Finance, for example
"EURUSD=X".
start (str): Start date of the requested time range in YYYY-MM-DD format.
end (str): End date of the requested time range in YYYY-MM-DD format.
intervall (str): Data interval supported by Yahoo Finance, for example
"1d", "1h", or "15m".

Returns:
tuple[pd.DataFrame, dict] | None: A tuple containing the prepared
DataFrame and a dictionary with minimum and maximum rates. Returns
``None`` if no time-series data could be fetched.
Return: tuple[pd.DataFrame, dict] - a tuple containing the updated DataFrame with conversion rates,
daily percentage change, and rolling average, and a dictionary with the minimum and maximum rates
"""

df = get_timeseries(curr_symbol, start, end, intervall)
if df is None:
return None
df["rate"] = 0.0
# For each date one API call to get the rate
for i in range(len(df)):
date = str(df.loc[i, "date"])
df.loc[i, "rate"] = get_mock_timeseries(mock_curr, date)
df = add_daily_percentage_change(df)
df = add_rolling_average(df)
min_max_rates = get_min_max_rates(df)
Expand Down
Empty file removed src/legacy/analytics/__init__.py
Empty file.
Empty file.
72 changes: 0 additions & 72 deletions src/legacy/analytics/charts/trend_chart.py

This file was deleted.

Empty file.
Loading
Loading