fd86190e9a
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
45 lines
1.2 KiB
Python
45 lines
1.2 KiB
Python
from dataclasses import dataclass, field
|
|
from datetime import date
|
|
from typing import Optional
|
|
import pandas as pd
|
|
|
|
|
|
@dataclass
|
|
class DailyBar:
|
|
"""Single daily bar for one stock."""
|
|
symbol: str
|
|
date: date
|
|
open: float
|
|
high: float
|
|
low: float
|
|
close: float
|
|
volume: float
|
|
amount: float # turnover in yuan
|
|
|
|
@classmethod
|
|
def from_dataframe(cls, df: pd.DataFrame, symbol_col: str = "symbol") -> list["DailyBar"]:
|
|
"""Convert akshare/baostock DataFrame to list of DailyBar."""
|
|
bars = []
|
|
for _, row in df.iterrows():
|
|
bars.append(cls(
|
|
symbol=row.get(symbol_col, ""),
|
|
date=pd.Timestamp(row["date"]).date(),
|
|
open=float(row["open"]),
|
|
high=float(row["high"]),
|
|
low=float(row["low"]),
|
|
close=float(row["close"]),
|
|
volume=float(row["volume"]),
|
|
amount=float(row.get("amount", 0)),
|
|
))
|
|
return bars
|
|
|
|
def to_series(self) -> dict:
|
|
return {
|
|
"date": self.date,
|
|
"open": self.open,
|
|
"high": self.high,
|
|
"low": self.low,
|
|
"close": self.close,
|
|
"volume": self.volume,
|
|
}
|