forked from KapJI/capital-gains-calculator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
model.py
113 lines (99 loc) · 2.93 KB
/
model.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env python3
import datetime
from decimal import Decimal
from enum import Enum
from typing import Dict, List, Optional
from dates import DateIndex
class ActionType(Enum):
BUY = 1
SELL = 2
TRANSFER = 3
STOCK_ACTIVITY = 4
DIVIDEND = 5
TAX = 6
FEE = 7
ADJUSTMENT = 8
CAPITAL_GAIN = 9
SPIN_OFF = 10
INTEREST = 11
class BrokerTransaction:
def __init__(
self,
date: datetime.date,
action: ActionType,
symbol: str,
description: str,
quantity: Optional[Decimal],
price: Optional[Decimal],
fees: Decimal,
amount: Optional[Decimal],
currency: str,
broker: str,
):
self.date = date
self.action = action
self.symbol = symbol
self.description = description
self.quantity = quantity
self.price = price
self.fees = fees
self.amount = amount
self.currency = currency
self.broker = broker
def __str__(self) -> str:
result = f'date: {self.date}, action: "{self.action}"'
if self.symbol:
result += f", symbol: {self.symbol}"
if self.description:
result += f', description: "{self.description}"'
if self.quantity:
result += f", quantity: {self.quantity}"
if self.price:
result += f", price: {self.price}"
if self.fees:
result += f", fees: {self.fees}"
if self.amount:
result += f", amount: {self.amount}"
if self.currency:
result += f", currency: {self.currency}"
if self.broker:
result += f", broker: {self.broker}"
return result
class RuleType(Enum):
SECTION_104 = 1
SAME_DAY = 2
BED_AND_BREAKFAST = 3
class CalculationEntry:
def __init__(
self,
rule_type: RuleType,
quantity: Decimal,
amount: Decimal,
fees: Decimal,
new_quantity: Decimal,
new_pool_cost: Decimal,
gain: Decimal = Decimal(0),
allowable_cost: Decimal = Decimal(0),
bed_and_breakfast_date_index: int = 0,
):
self.rule_type = rule_type
self.quantity = quantity
self.amount = amount
self.allowable_cost = allowable_cost
self.fees = fees
self.gain = gain
self.new_quantity = new_quantity
self.new_pool_cost = new_pool_cost
self.bed_and_breakfast_date_index = bed_and_breakfast_date_index
if amount >= 0:
assert gain == amount - allowable_cost
def __str__(self) -> str:
return (
f"{self.rule_type.name.replace('_', ' ')}, "
f"quantity: {self.quantity}, "
f"disposal proceeds: {self.amount}, "
f"allowable cost: {self.allowable_cost}, "
f"fees: {self.fees}, "
f"gain: {self.gain}"
)
CalculationLog = Dict[DateIndex, Dict[str, List[CalculationEntry]]]