tariochbctools 0.35__py2.py3-none-any.whl → 0.37__py2.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.
- tariochbctools/importers/general/priceLookup.py +12 -3
- tariochbctools/importers/netbenefits/__init__.py +0 -0
- tariochbctools/importers/netbenefits/importer.py +173 -0
- tariochbctools/importers/swisscard/importer.py +2 -1
- tariochbctools/plugins/check_portfolio_sum.py +1 -0
- tariochbctools/plugins/generate_base_ccy_prices.py +1 -0
- {tariochbctools-0.35.dist-info → tariochbctools-0.37.dist-info}/METADATA +2 -2
- {tariochbctools-0.35.dist-info → tariochbctools-0.37.dist-info}/RECORD +12 -10
- {tariochbctools-0.35.dist-info → tariochbctools-0.37.dist-info}/WHEEL +1 -1
- {tariochbctools-0.35.dist-info → tariochbctools-0.37.dist-info}/LICENSE.txt +0 -0
- {tariochbctools-0.35.dist-info → tariochbctools-0.37.dist-info}/entry_points.txt +0 -0
- {tariochbctools-0.35.dist-info → tariochbctools-0.37.dist-info}/top_level.txt +0 -0
@@ -1,16 +1,25 @@
|
|
1
1
|
from datetime import date
|
2
2
|
|
3
3
|
from beancount.core import amount, prices
|
4
|
+
from beancount.core.number import D
|
4
5
|
|
5
6
|
|
6
7
|
class PriceLookup:
|
7
8
|
def __init__(self, existing_entries, baseCcy: str):
|
8
|
-
|
9
|
+
if existing_entries:
|
10
|
+
self.priceMap = prices.build_price_map(existing_entries)
|
11
|
+
else:
|
12
|
+
self.priceMap = None
|
9
13
|
self.baseCcy = baseCcy
|
10
14
|
|
11
15
|
def fetchPriceAmount(self, instrument: str, date: date):
|
12
|
-
|
13
|
-
|
16
|
+
if self.priceMap:
|
17
|
+
price = prices.get_price(
|
18
|
+
self.priceMap, tuple([instrument, self.baseCcy]), date
|
19
|
+
)
|
20
|
+
return price[1]
|
21
|
+
else:
|
22
|
+
return D(1)
|
14
23
|
|
15
24
|
def fetchPrice(self, instrument: str, date: date):
|
16
25
|
if instrument == self.baseCcy:
|
File without changes
|
@@ -0,0 +1,173 @@
|
|
1
|
+
import csv
|
2
|
+
from collections.abc import Iterable
|
3
|
+
from datetime import date
|
4
|
+
from io import StringIO
|
5
|
+
|
6
|
+
from beancount.core import amount, data
|
7
|
+
from beancount.core.number import D
|
8
|
+
from beancount.core.position import CostSpec
|
9
|
+
from beancount.ingest import importer
|
10
|
+
from beancount.ingest.importers.mixins import identifier
|
11
|
+
from dateutil.parser import parse
|
12
|
+
|
13
|
+
from tariochbctools.importers.general.priceLookup import PriceLookup
|
14
|
+
|
15
|
+
|
16
|
+
class Importer(identifier.IdentifyMixin, importer.ImporterProtocol):
|
17
|
+
"""An importer for Fidelity Netbenefits Activity CSV files."""
|
18
|
+
|
19
|
+
def __init__(
|
20
|
+
self,
|
21
|
+
regexps: str | Iterable[str],
|
22
|
+
cashAccount: str,
|
23
|
+
investmentAccount: str,
|
24
|
+
dividendAccount: str,
|
25
|
+
taxAccount: str,
|
26
|
+
capGainAccount: str,
|
27
|
+
symbol: str,
|
28
|
+
ignoreTypes: Iterable[str],
|
29
|
+
baseCcy: str,
|
30
|
+
):
|
31
|
+
identifier.IdentifyMixin.__init__(self, matchers=[("filename", regexps)])
|
32
|
+
self.cashAccount = cashAccount
|
33
|
+
self.investmentAccount = investmentAccount
|
34
|
+
self.dividendAccount = dividendAccount
|
35
|
+
self.taxAccount = taxAccount
|
36
|
+
self.capGainAccount = capGainAccount
|
37
|
+
self.symbol = symbol
|
38
|
+
self.ignoreTypes = ignoreTypes
|
39
|
+
self.baseCcy = baseCcy
|
40
|
+
|
41
|
+
def name(self):
|
42
|
+
return super().name() + self.cashAccount
|
43
|
+
|
44
|
+
def file_account(self, file):
|
45
|
+
return self.cashAccount
|
46
|
+
|
47
|
+
def extract(self, file, existing_entries):
|
48
|
+
entries = []
|
49
|
+
|
50
|
+
self.priceLookup = PriceLookup(existing_entries, self.baseCcy)
|
51
|
+
|
52
|
+
with StringIO(file.contents()) as csvfile:
|
53
|
+
reader = csv.DictReader(
|
54
|
+
csvfile,
|
55
|
+
[
|
56
|
+
"Transaction date",
|
57
|
+
"Transaction type",
|
58
|
+
"Investment name",
|
59
|
+
"Shares",
|
60
|
+
"Amount",
|
61
|
+
],
|
62
|
+
delimiter=",",
|
63
|
+
skipinitialspace=True,
|
64
|
+
)
|
65
|
+
next(reader)
|
66
|
+
for row in reader:
|
67
|
+
if not row["Transaction type"]:
|
68
|
+
break
|
69
|
+
|
70
|
+
if row["Transaction type"] in self.ignoreTypes:
|
71
|
+
continue
|
72
|
+
|
73
|
+
book_date = parse(row["Transaction date"].strip()).date()
|
74
|
+
amt = amount.Amount(D(row["Amount"].replace("$", "")), "USD")
|
75
|
+
shares = None
|
76
|
+
if row["Shares"] != "-":
|
77
|
+
shares = amount.Amount(D(row["Shares"]), self.symbol)
|
78
|
+
|
79
|
+
metakv = {}
|
80
|
+
|
81
|
+
if not amt and not shares:
|
82
|
+
continue
|
83
|
+
|
84
|
+
meta = data.new_metadata(file.name, 0, metakv)
|
85
|
+
description = row["Transaction type"].strip()
|
86
|
+
|
87
|
+
if "TAX" in description:
|
88
|
+
postings = self.__createDividend(amt, book_date, self.taxAccount)
|
89
|
+
elif "DIVIDEND" in description:
|
90
|
+
postings = self.__createDividend(
|
91
|
+
amt, book_date, self.dividendAccount
|
92
|
+
)
|
93
|
+
elif "YOU BOUGHT" in description:
|
94
|
+
postings = self.__createBuy(amt, shares, book_date)
|
95
|
+
elif "YOU SOLD" in description:
|
96
|
+
postings = self.__createSell(amt, shares, book_date)
|
97
|
+
else:
|
98
|
+
postings = [
|
99
|
+
data.Posting(self.cashAccount, amt, None, None, None, None),
|
100
|
+
]
|
101
|
+
|
102
|
+
if shares is not None:
|
103
|
+
postings.append(
|
104
|
+
data.Posting(
|
105
|
+
self.investmentAccount, shares, None, None, None, None
|
106
|
+
),
|
107
|
+
)
|
108
|
+
|
109
|
+
entry = data.Transaction(
|
110
|
+
meta,
|
111
|
+
book_date,
|
112
|
+
"*",
|
113
|
+
"",
|
114
|
+
description,
|
115
|
+
data.EMPTY_SET,
|
116
|
+
data.EMPTY_SET,
|
117
|
+
postings,
|
118
|
+
)
|
119
|
+
entries.append(entry)
|
120
|
+
|
121
|
+
return entries
|
122
|
+
|
123
|
+
def __createBuy(self, amt: amount, shares: amount, book_date: date):
|
124
|
+
price = self.priceLookup.fetchPrice("USD", book_date)
|
125
|
+
cost = CostSpec(
|
126
|
+
number_per=None,
|
127
|
+
number_total=round(-amt.number * price.number, 2),
|
128
|
+
currency=self.baseCcy,
|
129
|
+
date=None,
|
130
|
+
label=None,
|
131
|
+
merge=None,
|
132
|
+
)
|
133
|
+
postings = [
|
134
|
+
data.Posting(self.investmentAccount, shares, cost, None, None, None),
|
135
|
+
data.Posting(self.cashAccount, amt, None, price, None, None),
|
136
|
+
]
|
137
|
+
|
138
|
+
return postings
|
139
|
+
|
140
|
+
def __createSell(self, amt: amount, shares: amount, book_date: date):
|
141
|
+
price = self.priceLookup.fetchPrice("USD", book_date)
|
142
|
+
cost = CostSpec(
|
143
|
+
number_per=None,
|
144
|
+
number_total=None,
|
145
|
+
currency=None,
|
146
|
+
date=None,
|
147
|
+
label=None,
|
148
|
+
merge=None,
|
149
|
+
)
|
150
|
+
postings = [
|
151
|
+
data.Posting(self.investmentAccount, shares, cost, None, None, None),
|
152
|
+
data.Posting(self.cashAccount, amt, None, price, None, None),
|
153
|
+
data.Posting(self.capGainAccount, None, None, None, None, None),
|
154
|
+
]
|
155
|
+
|
156
|
+
return postings
|
157
|
+
|
158
|
+
def __createDividend(self, amt: amount, book_date: date, incomeAccount: str):
|
159
|
+
price = self.priceLookup.fetchPrice("USD", book_date)
|
160
|
+
postings = [
|
161
|
+
data.Posting(
|
162
|
+
self.investmentAccount,
|
163
|
+
amount.Amount(D(0), self.symbol),
|
164
|
+
None,
|
165
|
+
None,
|
166
|
+
None,
|
167
|
+
None,
|
168
|
+
),
|
169
|
+
data.Posting(self.cashAccount, amt, None, price, None, None),
|
170
|
+
data.Posting(incomeAccount, None, None, None, None, None),
|
171
|
+
]
|
172
|
+
|
173
|
+
return postings
|
@@ -33,7 +33,8 @@ class SwisscardImporter(identifier.IdentifyMixin, importer.ImporterProtocol):
|
|
33
33
|
book_date = parse(row["Transaction date"].strip(), dayfirst=True).date()
|
34
34
|
amt = amount.Amount(-D(row["Amount"]), row["Currency"])
|
35
35
|
metakv = {
|
36
|
-
"
|
36
|
+
"merchant": row["Merchant Category"],
|
37
|
+
"category": row["Registered Category"],
|
37
38
|
}
|
38
39
|
meta = data.new_metadata(file.name, 0, metakv)
|
39
40
|
description = row["Description"].strip()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: tariochbctools
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.37
|
4
4
|
Summary: Importers, plugins and price fetchers for Beancount
|
5
5
|
Home-page: https://github.com/tarioch/beancounttools/
|
6
6
|
Author: Patrick Ruckstuhl
|
@@ -19,7 +19,7 @@ Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
19
19
|
Classifier: License :: OSI Approved :: MIT License
|
20
20
|
Description-Content-Type: text/x-rst; charset=UTF-8
|
21
21
|
License-File: LICENSE.txt
|
22
|
-
Requires-Dist: beancount
|
22
|
+
Requires-Dist: beancount <3,>=2
|
23
23
|
Requires-Dist: bitstampclient
|
24
24
|
Requires-Dist: mt-940
|
25
25
|
Requires-Dist: pyyaml
|
@@ -11,11 +11,13 @@ tariochbctools/importers/cembrastatement/importer.py,sha256=fqfJxcU1SDiyyV3iDvfv
|
|
11
11
|
tariochbctools/importers/general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
12
|
tariochbctools/importers/general/mailAdapterImporter.py,sha256=B6r9ycPY1ZiWFPNnl2-h73OgMZAMaq_QSdURW6gxR3c,1805
|
13
13
|
tariochbctools/importers/general/mt940importer.py,sha256=gLE77YhMaQdHE3nDg344eLh-hSofGKHTW5O_h6kmUdM,2102
|
14
|
-
tariochbctools/importers/general/priceLookup.py,sha256=
|
14
|
+
tariochbctools/importers/general/priceLookup.py,sha256=2nqDcSHC2BMmfSaJtgdmZKNejvTglmAj4oMqOf-SLXg,839
|
15
15
|
tariochbctools/importers/ibkr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
16
16
|
tariochbctools/importers/ibkr/importer.py,sha256=ie8LjnIpok8bWGGItxfin_aBSyqe5DXpGSdg3kcNID0,8616
|
17
17
|
tariochbctools/importers/neon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
18
|
tariochbctools/importers/neon/importer.py,sha256=SNG6podG1PI3gABy6eYfv1-mRnPwRjK-j5_GoNz2-Wc,2547
|
19
|
+
tariochbctools/importers/netbenefits/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
|
+
tariochbctools/importers/netbenefits/importer.py,sha256=V1C9t9LU09osxBDOz-V8DL4LxhtnuhLRj6WV_idxrTM,5816
|
19
21
|
tariochbctools/importers/nordigen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
22
|
tariochbctools/importers/nordigen/importer.py,sha256=pHRs1WyvNmb_zIUsq1O6tcUq2xMDt7AFpIbok4R1B9A,3633
|
21
23
|
tariochbctools/importers/nordigen/nordigen_config.py,sha256=jT4vgEKc35qgXqF8_bRbXLHUrkgsSDKHfhDbEw5OXD4,4903
|
@@ -29,7 +31,7 @@ tariochbctools/importers/revolut/importer.py,sha256=TUjTnvvnYgc0j4z86KIohoMmw13U
|
|
29
31
|
tariochbctools/importers/schedule/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
30
32
|
tariochbctools/importers/schedule/importer.py,sha256=g1q7NwGzwkj25LknOguf3b7iJ0v4JXET01a8N3cWu2U,1526
|
31
33
|
tariochbctools/importers/swisscard/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
32
|
-
tariochbctools/importers/swisscard/importer.py,sha256=
|
34
|
+
tariochbctools/importers/swisscard/importer.py,sha256=CTJOJMe_QRPzGPPvkhHe4S0aqzBXbPCrkpcFGqOTrz8,1864
|
33
35
|
tariochbctools/importers/transferwise/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
34
36
|
tariochbctools/importers/transferwise/importer.py,sha256=czCUtcfOA9XlsP3HKN8DZ7wTDMTllitJXKdr019GJoI,6089
|
35
37
|
tariochbctools/importers/truelayer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -41,13 +43,13 @@ tariochbctools/importers/zak/importer.py,sha256=9HyFhsavUHLAlO1Pi3eJ7qlNmPsmKzC0
|
|
41
43
|
tariochbctools/importers/zkb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
42
44
|
tariochbctools/importers/zkb/importer.py,sha256=yrUck3DL2uyuliw0OTBGqBLYl8WBHxgTNnmaG_vA68o,1421
|
43
45
|
tariochbctools/plugins/__init__.py,sha256=DSZtoTVosmExbFmMlHVrZAxKewEILDZlGh_7-uWcc_w,26
|
44
|
-
tariochbctools/plugins/check_portfolio_sum.py,sha256=
|
45
|
-
tariochbctools/plugins/generate_base_ccy_prices.py,sha256=
|
46
|
+
tariochbctools/plugins/check_portfolio_sum.py,sha256=naJ2j6BFpQhJhT2c-gfjyIdcYe0l_ZzpdlqgwrsIv2g,2340
|
47
|
+
tariochbctools/plugins/generate_base_ccy_prices.py,sha256=Phw314qox3jpNgC5-GcnmyYcLkMkrd8xsWS-wYwdj6o,1236
|
46
48
|
tariochbctools/plugins/prices/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
47
49
|
tariochbctools/plugins/prices/ibkr.py,sha256=9OwaZvI55bCj7H80K2iLZVsGLpuCyaoCnyuTS9e1_-c,1294
|
48
|
-
tariochbctools-0.
|
49
|
-
tariochbctools-0.
|
50
|
-
tariochbctools-0.
|
51
|
-
tariochbctools-0.
|
52
|
-
tariochbctools-0.
|
53
|
-
tariochbctools-0.
|
50
|
+
tariochbctools-0.37.dist-info/LICENSE.txt,sha256=VR2hkz3p9Sw4hSXc7S5iZTOXGeV4h-i8AO_q0zEmtkE,1074
|
51
|
+
tariochbctools-0.37.dist-info/METADATA,sha256=m2PiA0wx0xM-qtsTiJVZVtvk4G8fQCcc2l2eqaTeKUE,2110
|
52
|
+
tariochbctools-0.37.dist-info/WHEEL,sha256=0XQbNV6JE5ziJsWjIU8TRRv0N6SohNonLWgP86g5fiI,109
|
53
|
+
tariochbctools-0.37.dist-info/entry_points.txt,sha256=9xrCCY1wx2zCIsQUOWZelLHDmHw9Oc-ZBAKUIY9lKTA,88
|
54
|
+
tariochbctools-0.37.dist-info/top_level.txt,sha256=CiA_NepCI6zDNsaORA55zmpuJFSnTvLESraIL13xiOQ,15
|
55
|
+
tariochbctools-0.37.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|