From b4cc94a4445b755ab180d3280c38a860e6309713 Mon Sep 17 00:00:00 2001 From: Giulio De Pasquale Date: Thu, 16 Oct 2025 12:59:39 +0100 Subject: [PATCH] asodijasoidjasoidj --- paperone/client.py | 6 +-- paperone/{data.py => entities.py} | 47 +---------------- paperone/models.py | 86 +++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 48 deletions(-) rename paperone/{data.py => entities.py} (92%) create mode 100644 paperone/models.py diff --git a/paperone/client.py b/paperone/client.py index 18cf084..02d7308 100644 --- a/paperone/client.py +++ b/paperone/client.py @@ -1,6 +1,6 @@ from datetime import datetime, timedelta from .taapi import TaapiClient -from .data import TickerData +from .data import TickerOHLCV import yfinance as yf import pandas as pd @@ -10,7 +10,7 @@ class Client: self._taapi = TaapiClient(taapi_key) @staticmethod - def ticker_data_for(ticker: str, date: datetime) -> TickerData | None: + def ticker_data_for(ticker: str, date: datetime) -> TickerOHLCV | None: # Set end date to next day to ensure we get the target date start_date = date.strftime("%Y-%m-%d") end_date = (date + timedelta(days=1)).strftime("%Y-%m-%d") @@ -60,7 +60,7 @@ class Client: # Calculate average price avg = (high + low) / 2.0 - return TickerData( + return TickerOHLCV( date=date, open=round(open_price, 2), high=round(high, 2), diff --git a/paperone/data.py b/paperone/entities.py similarity index 92% rename from paperone/data.py rename to paperone/entities.py index 8fa132f..ea5977c 100644 --- a/paperone/data.py +++ b/paperone/entities.py @@ -1,56 +1,13 @@ from dataclasses import dataclass, field from datetime import datetime from typing import List - - -@dataclass -class TickerData: - date: datetime - open: float - close: float - low: float - high: float - avg: float - volume: int +from .models import TickerOHLCV @dataclass class TimeSeriesTickerData: ticker: str - series: List[TickerData] = field(default_factory=list) - - @staticmethod - def build_time_series_ticker_data( - ticker: str, all_data: List[TickerData] - ): - ordered = sorted({d.date: d for d in all_data}.values(), key=lambda d: d.date) - - return TimeSeriesTickerData( - ticker=ticker, - series=ordered, - ) - - def get_by_date(self, dt: datetime) -> TickerData | None: - for d in self.series: - if d.date == dt: - return d - - return None - - def get_latest(self) -> TickerData | None: - if not self.series: - return None - - return self.series[-1] - - def get_range(self, start_date: datetime, end_date: datetime) -> List[TickerData]: - return [d for d in self.series if start_date <= d.date <= end_date] - - @property - def target_date_data(self) -> TickerData | None: - """Return the most recent TickerData (by convention, the target date tick).""" - return self.get_latest() - + series: List[TickerOHLCV] = field(default_factory=list) @dataclass diff --git a/paperone/models.py b/paperone/models.py new file mode 100644 index 0000000..aa19aae --- /dev/null +++ b/paperone/models.py @@ -0,0 +1,86 @@ +from sqlmodel import SQLModel, Field, Relationship +from datetime import datetime +from typing import Optional + + +class TickerOHLCV(SQLModel, table=True): + __tablename__ = "ohlcv" + + ticker: str = Field(primary_key=True) + date: datetime = Field(primary_key=True, index=True) + open: float + close: float + low: float + high: float + avg: float + volume: int + + indicators: Optional["IndicatorsData"] = Relationship( + back_populates="ohlcv", + sa_relationship_kwargs={ + "foreign_keys": "[IndicatorsData.ticker, IndicatorsData.date]", + "uselist": False, + }, + ) + + +class IndicatorsData(SQLModel, table=True): + __tablename__ = "indicators" + + ticker: str = Field(foreign_key="ohlcv.ticker", primary_key=True) + date: datetime = Field(foreign_key="ohlcv.date", primary_key=True, index=True) + + # ======================================================================== + # MOMENTUM INDICATORS (Trend Direction & Strength) + # ======================================================================== + rsi_14: float # Standard 14-period RSI + rsi_20: float # Longer 20-period RSI for smoother signal + macd_line: float # MACD line (12 EMA - 26 EMA) + macd_signal: float # Signal line (9-period EMA of MACD) + macd_histogram: float # Histogram (MACD - Signal), shows momentum strength + stoch_k: float # Fast stochastic %K (14-period) + stoch_d: float # Slow stochastic %D (3-period SMA of %K) + + # ======================================================================== + # VOLATILITY INDICATORS (Price Dispersion & Risk) + # ======================================================================== + bb_upper: float # Upper Bollinger Band (SMA + 2*std) + bb_middle: float # Middle band (20-period SMA) + bb_lower: float # Lower Bollinger Band (SMA - 2*std) + bb_width: float # Band width (upper - lower), measures volatility magnitude + bb_percent: float # %B indicator: (close - lower) / (upper - lower) + atr_14: float # 14-period Average True Range + + # ======================================================================== + # TREND INDICATORS (Trend Presence & Sustainability) + # ======================================================================== + adx_14: float # 14-period ADX (trend strength) + di_plus: float # +DI (bullish directional indicator) + di_minus: float # -DI (bearish directional indicator) + sar: float # Current Parabolic SAR level + + # ======================================================================== + # VOLUME INDICATORS (Institutional Participation) + # ======================================================================== + obv: float # On-Balance Volume cumulative total + obv_sma_20: float # 20-day SMA of OBV (trend confirmation) + volume_roc_5: float # 5-day volume rate of change (%) + + # ======================================================================== + # SUPPORT/RESISTANCE INDICATORS (Key Price Levels) + # ======================================================================== + fib_236: float # 23.6% Fibonacci retracement level + fib_382: float # 38.2% Fibonacci retracement level + fib_618: float # 61.8% Fibonacci retracement level (golden ratio) + pivot_point: float # Standard pivot point (High + Low + Close) / 3 + resistance_1: float # First resistance level (R1) + support_1: float # First support level (S1) + + # ======================================================================== + # MARKET REGIME INDICATORS (Market Condition Classification) + # ======================================================================== + cci_20: float # 20-period Commodity Channel Index + williams_r_14: float # 14-period Williams %R + + # One-to-one relationship back to TickerOHLCV + ohlcv: TickerOHLCV = Relationship(back_populates="indicators")