Skip to content

Commit

Permalink
Merge branch 'master' into fix_duplicate_settlement_dates
Browse files Browse the repository at this point in the history
  • Loading branch information
cdump authored Jan 29, 2022
2 parents 5e30291 + 00adab4 commit ab0dfbe
Show file tree
Hide file tree
Showing 17 changed files with 819 additions and 634 deletions.
7 changes: 3 additions & 4 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
[isort]
line_length = 79

[flake8]
max-line-length = 200

max-imports = 16

min-name-length = 1

max-line-complexity = 24
max-line-complexity = 25

max-string-usages = 16

Expand Down Expand Up @@ -44,6 +41,7 @@ ignore =
WPS202, # too many module members
WPS218, # too many asserts, useful for tests/
WPS226, # Found string constant over-use
WPS237, # too complex `f` string
WPS301, # dotted raw import
WPS305, # f-strings
WPS306, # class without a base class
Expand All @@ -52,5 +50,6 @@ ignore =
WPS323, # '%' strings, too many false-positives (strptime, ...)
WPS420, # allow 'pass' (but also 'global','local' & 'del')
WPS421, # allow 'print()' function
WPS454, # wrong `raise` exception type: Exception
WPS602, # @staticmethod
S314, S405, # allow xml.etree.ElementTree
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ jobs:
with:
fetch-depth: 0 # need tags to generate release notes

- name: Set up Python 3.8
- name: Set up Python 3.9
uses: actions/setup-python@v1
with:
python-version: 3.8
python-version: '3.9'

- name: Install poetry
run: |
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
curl -sSL https://install.python-poetry.org | python
echo "$HOME/.poetry/bin" >> $GITHUB_PATH
- name: Install package
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8]
python-version: ['3.8', '3.9', '3.10']
steps:
- uses: actions/checkout@v2

Expand All @@ -18,7 +18,7 @@ jobs:

- name: Install poetry
run: |
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
curl -sSL https://install.python-poetry.org | python
echo "$HOME/.poetry/bin" >> $GITHUB_PATH
- name: Install package
Expand Down
2 changes: 2 additions & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[settings]
line_length = 128
5 changes: 2 additions & 3 deletions investments/data_providers/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,5 @@ def get(self) -> Optional[pandas.DataFrame]:
return pandas.read_pickle(self._cache_file)

def put(self, df: pandas.DataFrame):
if self._cache_file is None:
return None
df.to_pickle(self._cache_file)
if self._cache_file is not None:
df.to_pickle(self._cache_file)
2 changes: 1 addition & 1 deletion investments/data_providers/cbr.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import datetime
import logging
import xml.etree.ElementTree as ET # type: ignore
import xml.etree.ElementTree as ET # noqa:N817
from typing import Dict, List, Optional, Tuple

import pandas # type: ignore
Expand Down
7 changes: 4 additions & 3 deletions investments/data_providers/moex.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import datetime
from typing import Optional

import aiohttp
import aiomoex # type: ignore
import pandas # type: ignore

Expand All @@ -18,10 +19,10 @@ async def async_get_board_candles(ticker: Ticker, cache_dir: Optional[str], star
if df is not None:
return df

async with aiomoex.ISSClientSession():
async with aiohttp.ClientSession() as session:
engine, market, board = '', '', ''

resp = await aiomoex.find_securities(ticker.symbol, columns=('secid', 'name', 'group', 'primary_boardid'))
resp = await aiomoex.find_securities(session, ticker.symbol, columns=('secid', 'name', 'group', 'primary_boardid'))
for x in resp:
if x['secid'] != ticker.symbol:
continue
Expand All @@ -31,7 +32,7 @@ async def async_get_board_candles(ticker: Ticker, cache_dir: Optional[str], star
if engine == '':
raise Exception(f'unknown ticker {ticker}')

rdata = await aiomoex.get_board_candles(ticker.symbol, start=start, end=end, interval=interval, engine=engine, market=market, board=board)
rdata = await aiomoex.get_board_candles(session, ticker.symbol, start=start, end=end, interval=interval, engine=engine, market=market, board=board)
df = pandas.DataFrame(rdata)
df.set_index('begin', inplace=True)
df.drop(['value'], axis=1, inplace=True)
Expand Down
Empty file added investments/ibdds/__init__.py
Empty file.
30 changes: 18 additions & 12 deletions investments/ibdds/ibdds.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
import argparse
import csv
import logging
from pathlib import Path
from typing import List
from typing import Any, List

from tabulate import tabulate

Expand All @@ -22,8 +21,9 @@


class InteractiveBrokersCashReportParser(InteractiveBrokersReportParser):
def parse_csv(self, *, activity_report_filepath: Path, **kwargs):
with open(activity_report_filepath, newline='') as activity_fh:
def parse_csv(self, *, activity_csvs: List[str], trade_confirmation_csvs: List[str]):
assert len(activity_csvs) == 1
with open(activity_csvs[0], newline='') as activity_fh:
self._real_parse_activity_csv(csv.reader(activity_fh, delimiter=','), {
'Cash Report': self._parse_cash_report,
})
Expand All @@ -32,11 +32,10 @@ def parse_csv(self, *, activity_report_filepath: Path, **kwargs):
def parse_reports(activity_report_filepath: str) -> InteractiveBrokersCashReportParser:
parser_object = InteractiveBrokersCashReportParser()

activity_report = Path(activity_report_filepath)
logging.info(f'Activity report {activity_report}')
logging.info(f'Activity report {activity_report_filepath}')

logging.info('start reports parse')
parser_object.parse_csv(activity_report_filepath=activity_report)
parser_object.parse_csv(activity_csvs=[activity_report_filepath], trade_confirmation_csvs=[])
logging.info(f'end reports parse {parser_object}')

return parser_object
Expand All @@ -55,13 +54,20 @@ def show_report(cash: List[Cash]):
begin_amount = dds_specific_round([op.amount for op in operations if op.description == 'Starting Cash'][0])
end_amount = dds_specific_round([op.amount for op in operations if op.description == 'Ending Cash'][0])

deposits = [op.amount for op in operations if 'Cash' not in op.description and op.amount > Money(0, op.amount.currency)]
deposits_amount = dds_specific_round(sum(deposits) if deposits else Money(0, currency))
deposits_amount = Money(0, currency)
withdrawals_amount = Money(0, currency)

withdrawals = [op.amount for op in operations if 'Cash' not in op.description and op.amount < Money(0, op.amount.currency)]
withdrawals_amount = dds_specific_round(sum(withdrawals) if withdrawals else Money(0, currency))
for op in operations:
if 'Cash' not in op.description:
if op.amount > Money(0, op.amount.currency):
deposits_amount += op.amount
else:
withdrawals_amount += op.amount

report = [
deposits_amount = dds_specific_round(deposits_amount)
withdrawals_amount = dds_specific_round(withdrawals_amount)

report: List[List[Any]] = [
[f'{currency.name} {currency.iso_numeric_code}', 'Сумма в тысячах единиц'],
['Остаток денежных средств на счете на начало отчетного периода', begin_amount],
['Зачислено денежных средств за отчетный период', deposits_amount],
Expand Down
Empty file added investments/ibtax/__init__.py
Empty file.
2 changes: 1 addition & 1 deletion investments/ibtax/ibtax.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from investments.interests import Interest
from investments.money import Money
from investments.report_parsers.ib import InteractiveBrokersReportParser
from investments.trades_fifo import TradesAnalyzer, FinishedTrade, PortfolioElement # noqa: I001
from investments.trades_fifo import FinishedTrade, PortfolioElement, TradesAnalyzer


def apply_round_for_dataframe(source: pandas.DataFrame, columns: Iterable, digits: int = 2) -> pandas.DataFrame:
Expand Down
6 changes: 5 additions & 1 deletion investments/report_parsers/ib.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ def _parse_date(strval: str) -> datetime.date:
return datetime.datetime.strptime(strval, '%Y-%m-%d').date()


def _parse_trade_quantity(strval: str) -> int:
return int(strval.replace(',', ''))


def _parse_dividend_description(description: str) -> Tuple[str, str]:
m = re.match(r'^(\w+)\s*\(\w+\) (Cash Dividend|Payment in Lieu of Dividend|Choice Dividend)', description)
if m is None:
Expand Down Expand Up @@ -284,7 +288,7 @@ def _parse_trades(self, f: Dict[str, str]):
ticker=ticker,
trade_date=dt,
settle_date=settle_date_item.settle_date,
quantity=int(f['Quantity']) * quantity_multiplier,
quantity=_parse_trade_quantity(f['Quantity']) * quantity_multiplier,
price=Money(f['T. Price'], currency),
fee=Money(f['Comm/Fee'], currency),
))
Expand Down
2 changes: 1 addition & 1 deletion investments/report_parsers/open_fr.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import datetime
import re
import xml.etree.ElementTree as ET # type: ignore
import xml.etree.ElementTree as ET # noqa:N817
from typing import List, Optional

from investments.currency import Currency
Expand Down
Loading

0 comments on commit ab0dfbe

Please sign in to comment.