Skip to content
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

Feature/create common ids #12

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
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
7 changes: 7 additions & 0 deletions investing_pal/app/bond_calculator/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
from rich.highlighter import NullHighlighter
from rich.logging import RichHandler

from data.capabilities import stock_name
from instruments.securities.debt.bond import Bond, BondId
from instruments.securities.equity.stock import StockId

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -45,6 +47,11 @@ def run() -> None:
bond = Bond(BondId("security.bond.test.wse.stooq"))
print(bond)

stock_id = StockId("AAPL.US", "NYSE")
print(stock_id)

print(stock_name)


if __name__ == "__main__":
run()
17 changes: 17 additions & 0 deletions investing_pal/data/capabilities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from dataclasses import dataclass

from data.value import DataType
from instruments.securities.equity.stock import StockId


@dataclass
class Capability:
data_id: str
data_type: DataType


# Stocks.
stock_name = Capability(f"{StockId.uid_format()}.name", DataType.TEXT)
stock_isin = Capability(f"{StockId.uid_format()}.isin", DataType.TEXT)
stock_currency = Capability(f"{StockId.uid_format()}.currency", DataType.TEXT)
stock_price = Capability(f"{StockId.uid_format()}.price", DataType.PRICE)
30 changes: 28 additions & 2 deletions investing_pal/data/source.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,44 @@
import datetime
import random
from abc import ABC, abstractmethod

from data.value import DataId, Number, Price, Text
from money.currency import PLN


class IDataSource(ABC):
def __init__(self, name: str) -> None:
self.name: str = name

@abstractmethod
def get_number(self, data_id: DataId, date: datetime.date, time: datetime.time | None = None) -> Number:
def get_number(
self, data_id: DataId, date: datetime.date | None = None, time: datetime.time | None = None
) -> Number:
pass

@abstractmethod
def get_text(self, data_id: DataId, date: datetime.date, time: datetime.time | None = None) -> Text:
def get_text(self, data_id: DataId, date: datetime.date | None = None, time: datetime.time | None = None) -> Text:
pass

@abstractmethod
def get_price(self, data_id: DataId, date: datetime.date, time: datetime.time | None = None) -> Price:
pass


class StooqDataSource(IDataSource):
def __init__(self) -> None:
super().__init__("stooq")

def get_number(
self, data_id: DataId, date: datetime.date | None = None, time: datetime.time | None = None
) -> Number:
assert data_id.source() == self.name
return Number(data_id=data_id, value=random.randint(1, 100))

def get_price(self, data_id: DataId, date: datetime.date, time: datetime.time | None = None) -> Price:
assert data_id.source() == self.name
return Price(data_id=data_id, value=random.randint(1, 100), currency=PLN)

def get_text(self, data_id: DataId, date: datetime.date | None = None, time: datetime.time | None = None) -> Text:
assert data_id.source() == self.name
return Text(data_id=data_id, value=f"some text {random.randint(1, 100)}")
51 changes: 42 additions & 9 deletions investing_pal/data/value.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,62 @@
import datetime
from dataclasses import dataclass
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from enum import Enum, auto
from typing import Optional

from money.currency import Currency

DataId = str

class DataId(ABC):
@staticmethod
@abstractmethod
def uid_format() -> str:
pass

@dataclass
@abstractmethod
def uid(self) -> str:
pass

def source(self) -> str:
return self.uid().split("@")[0]

def __str__(self) -> str:
return self.uid()


class DataType(Enum):
NUMBER = auto()
PRICE = auto()
TEXT = auto()


@dataclass(kw_only=True)
class MarketData:
type: DataType = field(init=False)
data_id: DataId
date: Optional[datetime.date]
time: Optional[datetime.time]
date: datetime.date | None = None
time: datetime.time | None = None


@dataclass
class Number(MarketData):
value: float


@dataclass
class Text(MarketData):
value: str
def __post_init__(self):
self.type = DataType.NUMBER


@dataclass
class Price(Number):
currency: Currency

def __post_init__(self):
self.type = DataType.PRICE


@dataclass
class Text(MarketData):
value: str

def __post_init__(self):
self.type = DataType.TEXT
14 changes: 11 additions & 3 deletions investing_pal/instruments/securities/equity/stock.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
import datetime
from dataclasses import dataclass

from data.value import DataId
from instruments.common import IFinancialInstrument
from money.cash import Cash
from money.currency import PLN, Currency


@dataclass
class StockId:
isin: str
class StockId(DataId):
ticker: str
exchange_id: str

@staticmethod
def uid_format() -> str:
return "instrument.stock.{ticker}.{exchange_id}"

def uid(self) -> str:
return self.uid_format().format(ticker=self.ticker.replace(".", ":::"), exchange_id=self.exchange_id)


@dataclass
class StockInfo:
id: StockId
name: str
exchange: str
isin: str
currency: Currency


Expand Down
2 changes: 1 addition & 1 deletion investing_pal/market/broker.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def __init__(self) -> None:
self._transactions: list[Transaction] = []


class BrokerAccount(Account, ABC):
class BrokerAccount(Account):
def __init__(self, name: str, info: AccountInfo) -> None:
super().__init__(name, info)
self._positions: list[Position] = []
Expand Down