05/31 Phase 1: initial codes
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
from app.extensions import db
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class Investment(db.Model):
|
||||
__tablename__ = 'investments'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
asset_name = db.Column(db.String(100), nullable=False)
|
||||
ticker = db.Column(db.String(20), nullable=True)
|
||||
asset_type = db.Column(
|
||||
db.Enum('stock', 'etf', 'crypto', 'real_estate', 'bond', 'cash', 'other'),
|
||||
nullable=False,
|
||||
default='stock'
|
||||
)
|
||||
shares = db.Column(db.Numeric(18, 8), nullable=False, default=0)
|
||||
avg_cost_basis = db.Column(db.Numeric(15, 4), nullable=False, default=0)
|
||||
current_price = db.Column(db.Numeric(15, 4), nullable=True)
|
||||
last_price_update = db.Column(db.DateTime, nullable=True)
|
||||
notes = db.Column(db.Text, nullable=True)
|
||||
is_active = db.Column(db.Boolean, default=True)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
inv_transactions = db.relationship('InvestmentTransaction', back_populates='investment',
|
||||
lazy='dynamic', cascade='all, delete-orphan')
|
||||
|
||||
@property
|
||||
def total_cost(self):
|
||||
return float(self.shares) * float(self.avg_cost_basis)
|
||||
|
||||
@property
|
||||
def current_value(self):
|
||||
if self.current_price:
|
||||
return float(self.shares) * float(self.current_price)
|
||||
return self.total_cost
|
||||
|
||||
@property
|
||||
def unrealized_gain(self):
|
||||
return self.current_value - self.total_cost
|
||||
|
||||
@property
|
||||
def unrealized_gain_pct(self):
|
||||
if self.total_cost == 0:
|
||||
return 0
|
||||
return round((self.unrealized_gain / self.total_cost) * 100, 2)
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Investment {self.asset_name}>'
|
||||
|
||||
|
||||
class InvestmentTransaction(db.Model):
|
||||
__tablename__ = 'investment_transactions'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
investment_id = db.Column(db.Integer, db.ForeignKey('investments.id'), nullable=False)
|
||||
transaction_type = db.Column(db.Enum('buy', 'sell', 'dividend', 'split'), nullable=False)
|
||||
shares = db.Column(db.Numeric(18, 8), nullable=False)
|
||||
price_per_share = db.Column(db.Numeric(15, 4), nullable=False)
|
||||
total_amount = db.Column(db.Numeric(15, 2), nullable=False)
|
||||
fees = db.Column(db.Numeric(10, 2), default=0.00)
|
||||
date = db.Column(db.Date, nullable=False, index=True)
|
||||
notes = db.Column(db.String(255), nullable=True)
|
||||
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
||||
|
||||
investment = db.relationship('Investment', back_populates='inv_transactions')
|
||||
|
||||
def __repr__(self):
|
||||
return f'<InvTransaction {self.transaction_type} {self.shares}@{self.price_per_share}>'
|
||||
Reference in New Issue
Block a user