mc-postgres-db 1.0.7__py3-none-any.whl → 1.0.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,205 @@
1
+ Metadata-Version: 2.4
2
+ Name: mc-postgres-db
3
+ Version: 1.0.9
4
+ Summary: Add your description here
5
+ Requires-Python: >=3.12
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: alembic>=1.16.2
8
+ Requires-Dist: psycopg2-binary>=2.9.10
9
+ Requires-Dist: ruff>=0.12.0
10
+ Requires-Dist: sqlalchemy>=2.0.41
11
+
12
+ # MC Postgres DB
13
+
14
+ A Python package containing ORM models for a PostgreSQL database that powers a personal quantitative trading and investment analysis platform.
15
+
16
+ ## Overview
17
+
18
+ This package provides SQLAlchemy ORM models and database utilities for managing financial data, trading strategies, portfolio analytics, and market research. The database serves as the backbone for a personal "quant hedge fund" project, storing everything from market data and content data.
19
+
20
+ ## Features
21
+
22
+ - **Asset Models**: `AssetType` and `Asset` tables for categorizing and managing financial instruments and various fiat and digital currencies
23
+ - **Provider Models**: `ProviderType` and `Provider` tables for handling data sources and exchanges
24
+ - **Market Data Models**: `ProviderAssetMarket` table for storing OHLCV and bid/ask price data
25
+ - **Order Models**: `ProviderAssetOrder` table for tracking trading orders between assets
26
+ - **Content Models**: `ContentType`, `ProviderContent`, and `AssetContent` tables for managing news articles and social content
27
+ - **Relation Models**: `ProviderAsset` table for mapping relationships between providers and assets
28
+
29
+ ## Installation
30
+
31
+ ### From PyPI
32
+
33
+ ```bash
34
+ pip install mc-postgres-db
35
+ ```
36
+
37
+ ### From Source
38
+
39
+ ```bash
40
+ # Clone the repository
41
+ git clone <repository-url>
42
+ cd mc-postgres-db
43
+
44
+ # Install using uv (recommended)
45
+ uv sync
46
+ ```
47
+
48
+ ## Database Setup
49
+
50
+ 1. **PostgreSQL Setup**: Ensure PostgreSQL is installed and running
51
+ 2. **Environment Variables**: Set up your database connection string
52
+ ```bash
53
+ export SQLALCHEMY_DATABASE_URL="postgresql://username:password@localhost:5432/mc_trading_db"
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ ```python
59
+ from sqlalchemy import create_engine, select
60
+ from sqlalchemy.orm import Session
61
+ from mcpdb.tables import Asset, Provider, ProviderAssetMarket
62
+
63
+ # Create database connection
64
+ url = "postgresql://username:password@localhost:5432/mc_trading_db"
65
+ engine = create_engine(url)
66
+
67
+ # Query assets
68
+ with Session(engine) as session:
69
+ stmt = select(Asset).where(Asset.is_active)
70
+ assets = session.scalars(stmt).all()
71
+ asset_pairs = {asset.id: asset.name for asset in assets}
72
+ print("Available assets:")
73
+ for asset_id, asset_name in asset_pairs.items():
74
+ print(f"{asset_id}: {asset_name}")
75
+
76
+ # Query market data
77
+ with Session(engine) as session:
78
+ stmt = (
79
+ select(ProviderAssetMarket)
80
+ .where(
81
+ ProviderAssetMarket.asset_id == 1, # Bitcoin for example
82
+ ProviderAssetMarket.provider_id == 2, # Binance for example
83
+ )
84
+ .order_by(ProviderAssetMarket.timestamp.desc())
85
+ .limit(10)
86
+ )
87
+ market_data = session.scalars(stmt).all()
88
+ for data in market_data:
89
+ print(f"Timestamp: {data.timestamp}, Close: {data.close}, Volume: {data.volume}")
90
+
91
+ # Get assets from a provider
92
+ with Session(engine) as session:
93
+ stmt = select(Provider).where(Provider.id == 1)
94
+ provider = session.scalars(stmt).one()
95
+ provider_assets = provider.get_all_assets(engine)
96
+ print(f"Assets available from {provider.name}:")
97
+ for provider_asset in provider_assets:
98
+ print(f"Asset code: {provider_asset.asset_code}")
99
+ ```
100
+
101
+ ## Models Overview
102
+
103
+ ### Core Models
104
+
105
+ - **AssetType**: Categorizes assets (e.g., stocks, bonds, cryptocurrencies) with names and descriptions
106
+ - **Asset**: Represents financial instruments with references to asset types, symbols, and optional underlying assets
107
+ - **ProviderType**: Categorizes data providers (e.g., exchanges, news services) with names and descriptions
108
+ - **Provider**: Represents data sources with references to provider types and optional underlying providers
109
+ - **ProviderAsset**: Maps the relationship between providers and assets with asset codes and active status
110
+ - **ProviderAssetOrder**: Tracks orders for assets from providers including timestamp, price, and volume
111
+ - **ProviderAssetMarket**: Stores OHLCV (Open, High, Low, Close, Volume) market data and bid/ask prices
112
+ - **ContentType**: Categorizes content (e.g., news articles, social media posts) with names and descriptions
113
+ - **ProviderContent**: Stores content from providers with timestamps, titles, descriptions, and full content
114
+ - **AssetContent**: Maps the relationship between content and assets
115
+
116
+ ### Database Schema Features
117
+
118
+ - **Inheritance Support**: Assets and providers can reference underlying entities for hierarchical relationships
119
+ - **Timestamped Records**: All tables include creation and update timestamps
120
+ - **Soft Delete Pattern**: Uses is_active flags to mark records as inactive without deletion
121
+ - **Time Series Data**: Market data is organized by timestamp for efficient time-series operations
122
+ - **Cross-Reference Tables**: Enables many-to-many relationships between assets, providers, and content
123
+
124
+ ## Development
125
+
126
+ ### Setting up Development Environment
127
+
128
+ ```bash
129
+ # Install development dependencies using uv
130
+ uv sync --dev
131
+
132
+ # Run tests
133
+ uv run pytest
134
+
135
+ # Run linting
136
+ uv run ruff check src/mcpdb/
137
+ uv run ruff format src/mcpdb/
138
+ ```
139
+
140
+ ### Database Migrations
141
+
142
+ ```bash
143
+ # Generate new migration
144
+ uv run alembic revision --autogenerate -m "Description of changes"
145
+
146
+ # Apply migrations
147
+ uv run alembic upgrade head
148
+
149
+ # Rollback migration
150
+ uv run alembic downgrade -1
151
+ ```
152
+
153
+ ## Project Structure
154
+
155
+ ```
156
+ mc-postgres-db/
157
+ ├── src/ # Source code directory
158
+ │ └── mcpdb/ # Package directory
159
+ │ └── tables.py # SQLAlchemy ORM models
160
+ ├── tests/ # Unit and integration tests
161
+ ├── scripts/ # Database maintenance scripts
162
+ ├── pyproject.toml # Project configuration and dependencies
163
+ ├── uv.lock # Locked dependency versions
164
+ └── README.md # Project documentation
165
+ ```
166
+
167
+ ## Data Sources
168
+
169
+ This database integrates with various financial data providers:
170
+
171
+ - Market data APIs (Alpha Vantage, IEX Cloud, etc.)
172
+ - Fundamental data providers
173
+ - Alternative data sources
174
+ - Custom scraped data
175
+
176
+ ## Security & Compliance
177
+
178
+ - Database connections use SSL encryption
179
+ - Sensitive data is encrypted at rest
180
+ - Access controls and audit logging implemented
181
+ - Regular backups and disaster recovery procedures
182
+
183
+ ## Performance Considerations
184
+
185
+ - Optimized indexes for common query patterns
186
+ - Partitioned tables for large time-series data
187
+ - Connection pooling for high-throughput operations
188
+ - Caching layer for frequently accessed data
189
+
190
+ ## Contributing
191
+
192
+ This is a personal project, but suggestions and improvements are welcome:
193
+
194
+ 1. Fork the repository
195
+ 2. Create a feature branch
196
+ 3. Make your changes with tests
197
+ 4. Submit a pull request
198
+
199
+ ## License
200
+
201
+ This project is for personal use and learning purposes.
202
+
203
+ ## Disclaimer
204
+
205
+ This software is for educational and personal use only. It is not intended for production trading or investment advice. Use at your own risk.
@@ -0,0 +1,5 @@
1
+ mcpdb/tables.py,sha256=6RWuE8eJzShSWG_wg_qgjwZ5UuhLu81JZiuTvRomOiM,11008
2
+ mc_postgres_db-1.0.9.dist-info/METADATA,sha256=vYbruza1zMgKJQsb_uwaFYAqJMh_HgqGUKXThhrMpxY,7052
3
+ mc_postgres_db-1.0.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
4
+ mc_postgres_db-1.0.9.dist-info/top_level.txt,sha256=xiCw1E_-H0o0I8j5PbuWddHW1iwrGwntb2enCqa4FQA,6
5
+ mc_postgres_db-1.0.9.dist-info/RECORD,,
mcpdb/tables.py CHANGED
@@ -20,8 +20,8 @@ class AssetType(Base):
20
20
  __tablename__ = "asset_type"
21
21
 
22
22
  id: Mapped[int] = mapped_column(primary_key=True)
23
- name: Mapped[str] = mapped_column(String(30), nullable=False)
24
- description: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
23
+ name: Mapped[str] = mapped_column(String(100), nullable=False)
24
+ description: Mapped[Optional[str]] = mapped_column(String(1000), nullable=True)
25
25
  is_active: Mapped[bool] = mapped_column(default=True)
26
26
  created_at: Mapped[datetime.datetime] = mapped_column(
27
27
  nullable=False, server_default=func.now()
@@ -41,8 +41,12 @@ class Asset(Base):
41
41
  asset_type_id: Mapped[int] = mapped_column(
42
42
  ForeignKey("asset_type.id"), nullable=False
43
43
  )
44
- name: Mapped[str] = mapped_column(String(30), nullable=False)
44
+ name: Mapped[str] = mapped_column(String(100), nullable=False)
45
45
  description: Mapped[Optional[str]]
46
+ symbol: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
47
+ underlying_asset_id: Mapped[Optional[int]] = mapped_column(
48
+ ForeignKey("asset.id"), nullable=True
49
+ )
46
50
  is_active: Mapped[bool] = mapped_column(default=True)
47
51
  created_at: Mapped[datetime.datetime] = mapped_column(
48
52
  nullable=False, server_default=func.now()
@@ -59,7 +63,7 @@ class ProviderType(Base):
59
63
  __tablename__ = "provider_type"
60
64
 
61
65
  id: Mapped[int] = mapped_column(primary_key=True)
62
- name: Mapped[str] = mapped_column(String(30), nullable=False)
66
+ name: Mapped[str] = mapped_column(String(100), nullable=False)
63
67
  description: Mapped[Optional[str]] = mapped_column(String(1000), nullable=True)
64
68
  is_active: Mapped[bool] = mapped_column(default=True)
65
69
  created_at: Mapped[datetime.datetime] = mapped_column(
@@ -80,8 +84,12 @@ class Provider(Base):
80
84
  provider_type_id: Mapped[int] = mapped_column(
81
85
  ForeignKey("provider_type.id"), nullable=False
82
86
  )
83
- name: Mapped[str] = mapped_column(String(30), nullable=False)
87
+ name: Mapped[str] = mapped_column(String(100), nullable=False)
84
88
  description: Mapped[Optional[str]] = mapped_column(String(1000), nullable=True)
89
+ symbol: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
90
+ underlying_provider_id: Mapped[Optional[int]] = mapped_column(
91
+ ForeignKey("provider.id"), nullable=True
92
+ )
85
93
  is_active: Mapped[bool] = mapped_column(default=True)
86
94
  created_at: Mapped[datetime.datetime] = mapped_column(
87
95
  nullable=False, server_default=func.now()
@@ -147,7 +155,7 @@ class ProviderAsset(Base):
147
155
  asset_id: Mapped[int] = mapped_column(
148
156
  ForeignKey("asset.id"), nullable=False, primary_key=True
149
157
  )
150
- asset_code: Mapped[str] = mapped_column(String(30), nullable=False)
158
+ asset_code: Mapped[str] = mapped_column(String(100), nullable=False)
151
159
  is_active: Mapped[bool] = mapped_column(default=True)
152
160
  created_at: Mapped[datetime.datetime] = mapped_column(
153
161
  nullable=False, server_default=func.now()
@@ -203,7 +211,7 @@ class ContentType(Base):
203
211
  __tablename__ = "content_type"
204
212
 
205
213
  id: Mapped[int] = mapped_column(primary_key=True)
206
- name: Mapped[str] = mapped_column(String(30), nullable=False)
214
+ name: Mapped[str] = mapped_column(String(100), nullable=False)
207
215
  description: Mapped[Optional[str]] = mapped_column(String(1000), nullable=True)
208
216
  is_active: Mapped[bool] = mapped_column(default=True)
209
217
  created_at: Mapped[datetime.datetime] = mapped_column(
@@ -223,14 +231,19 @@ class ProviderContent(Base):
223
231
  id: Mapped[int] = mapped_column(primary_key=True)
224
232
  timestamp: Mapped[datetime.datetime] = mapped_column(nullable=False)
225
233
  provider_id: Mapped[int] = mapped_column(ForeignKey("provider.id"), nullable=False)
226
- provider_unique_identifier: Mapped[str] = mapped_column(
227
- String(1000), nullable=False
234
+ provider_external_code: Mapped[str] = mapped_column(
235
+ String(1000),
236
+ nullable=False,
237
+ comment="This is the external identifier for the content and will depend on the content provider and the type of content. For example, for a news article, it could be the URL of the article and for a social media post, it could be the post ID.",
228
238
  )
229
239
  content_type_id: Mapped[int] = mapped_column(
230
240
  ForeignKey("content_type.id"), nullable=False
231
241
  )
232
- author: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
233
- title: Mapped[Optional[str]] = mapped_column(String(200), nullable=True)
242
+ authors: Mapped[Optional[str]] = mapped_column(String(1000), nullable=True)
243
+ title: Mapped[Optional[str]] = mapped_column(String(1000), nullable=True)
244
+ description: Mapped[Optional[str]] = mapped_column(
245
+ String(5000), nullable=True, comment="A short description of the content"
246
+ )
234
247
  content: Mapped[str] = mapped_column(String(), nullable=False)
235
248
  created_at: Mapped[datetime.datetime] = mapped_column(
236
249
  nullable=False, server_default=func.now()
@@ -1,10 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: mc-postgres-db
3
- Version: 1.0.7
4
- Summary: Add your description here
5
- Requires-Python: >=3.12
6
- Description-Content-Type: text/markdown
7
- Requires-Dist: alembic>=1.16.2
8
- Requires-Dist: psycopg2-binary>=2.9.10
9
- Requires-Dist: ruff>=0.12.0
10
- Requires-Dist: sqlalchemy>=2.0.41
@@ -1,5 +0,0 @@
1
- mcpdb/tables.py,sha256=jeyQH3u7DvOxLpIM6u5AaSLrBaL5UxvXTFK29ytJ_A8,10201
2
- mc_postgres_db-1.0.7.dist-info/METADATA,sha256=Lwnx5ZHsUvxPpJRGVqH8JQBijeEtQFUHPmEwCj3bIfE,289
3
- mc_postgres_db-1.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
4
- mc_postgres_db-1.0.7.dist-info/top_level.txt,sha256=xiCw1E_-H0o0I8j5PbuWddHW1iwrGwntb2enCqa4FQA,6
5
- mc_postgres_db-1.0.7.dist-info/RECORD,,