Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Релиз 2023.3 #569

Merged
merged 20 commits into from
Dec 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
7ed7b93
update user doc
vananiev Sep 5, 2023
312d4eb
Check for null value with the appropriate assertion method
valery1707 Oct 3, 2023
bff0ac4
Merge pull request #562 from valery1707/patch-1
vananiev Oct 26, 2023
9eebd57
convert run configuration to idea community format
vananiev Oct 26, 2023
0cd1c6c
Merge pull request #563 from spacious-team/task-idea-community-run-co…
vananiev Oct 26, 2023
3985f7a
update java to 21
vananiev Oct 26, 2023
cfba3cd
Merge pull request #565 from spacious-team/task-java-21
vananiev Oct 26, 2023
8bbe0e9
fix forms fee column display
vananiev Nov 28, 2023
49bfa57
Merge pull request #566 from spacious-team/bugfix-fee-display
vananiev Nov 28, 2023
dd70b4e
support option for stock
vananiev Dec 2, 2023
6117450
refactor MoexDerivativeCodeService tests
vananiev Dec 2, 2023
7a45267
fix MoexDerivativeCodeService.isOptionShortname() for "GAZPP220722CE …
vananiev Dec 2, 2023
3d108ac
isOption() and isFutures() shouldn't know about derivative code (new …
vananiev Dec 2, 2023
446a29f
Merge pull request #568 from spacious-team/improvement-stock-option
vananiev Dec 2, 2023
81a0643
speedup big tinkoff report parse
vananiev Nov 28, 2023
9236f64
add 11.2023 tinkoff report support
vananiev Nov 28, 2023
3889a74
check option code and don't halt tinkoff report parser if assets not …
vananiev Dec 2, 2023
498031d
refactor TinkoffSecurityTransactionTableHelper after #568
vananiev Dec 2, 2023
f06a60b
Merge pull request #567 from spacious-team/bugfix-tinkoff
vananiev Dec 2, 2023
3daf70f
version 2023.3
vananiev Dec 2, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/publish-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Set up JDK
uses: actions/setup-java@v3
with:
java-version: '20'
java-version: '21'
distribution: 'liberica'
cache: maven
- name: Publish
Expand Down
9 changes: 3 additions & 6 deletions .idea/runConfigurations/InvestbookApplication.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[![java-version](https://img.shields.io/badge/java-20-brightgreen?style=flat-square)](https://openjdk.org/)
[![java-version](https://img.shields.io/badge/java-21-brightgreen?style=flat-square)](https://openjdk.org/)
[![spring-boot-version](https://img.shields.io/badge/spring--boot-3.0.7-brightgreen?style=flat-square)](https://github.com/spring-projects/spring-boot/releases)
[![hits-of-code](https://img.shields.io/badge/dynamic/json?style=flat-square&color=lightblue&label=hits-of-code&url=https://hitsofcode.com/github/spacious-team/investbook/json?branch=develop&query=$.count)](https://hitsofcode.com/github/spacious-team/investbook/view?branch=develop)
[![github-closed-pull-requests](https://img.shields.io/github/issues-pr-closed/spacious-team/investbook?style=flat-square&color=brightgreen)](https://github.com/spacious-team/investbook/pulls?q=is%3Apr+is%3Aclosed)
Expand Down
11 changes: 6 additions & 5 deletions docs/install-on-linux.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
```shell script
$ java -version
```
Если версия 20 или выше, пропустите следующий пункт.
Если версия 21 или выше, пропустите следующий пункт.
2. Воспользуйтесь менеджером пакетов вашей ОС для установки java, например на Ubuntu
```shell
$ sudo apt install openjdk-20-jre-headless
$ sudo apt install openjdk-21-jre-headless
```
Или можно скачать [Java 20](https://jdk.java.net/20/) и распаковать папку `jdk-20` в директорию `/opt`.
Для 32 разрядных ОС можно скачать [Java 20 x86 JRE](https://bell-sw.com/pages/downloads/). Если java распакована из
Или можно скачать [Java 21](https://jdk.java.net/21/) и распаковать папку `jdk-21` в директорию `/opt`.
Для 32 разрядных ОС можно скачать [Java 21 x86 JRE](https://bell-sw.com/pages/downloads/). Если java распакована из
архива, то в директории приложения нужно найти файл `start.sh`, раскомментировать и актуализировать `JAVA_HOME`
```shell
$ export JAVA_HOME=/opt/jdk-20
$ export JAVA_HOME=/opt/jdk-21
```
3. Скачать со страницы [проекта](https://github.com/spacious-team/investbook/releases/latest) архив `.zip` и
распаковать в директорию `/opt`.
Expand Down Expand Up @@ -49,6 +49,7 @@
| с 2021.9 | java 17 и выше |
| с 2022.7 | java 18 и выше |
| с 2023.1 | java 20 и выше |
| с 2023.3 | java 21 и выше |

#### Установка расширений

Expand Down
6 changes: 3 additions & 3 deletions docs/install-on-windows-by-zip.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

Данная инструкция поддерживает все версии Windows. Если у вас 64 битная Windows, рекомендуем устанавливать по
[инструкции](install-on-windows.md).
1. Создать папку `C:\Program Files\Java\`, скачать Java 20 под вашу версию операционной системы.
1. Создать папку `C:\Program Files\Java\`, скачать Java 21 под вашу версию операционной системы.
Если у вас 32 битная Windows можете использовать скачать по [ссылке](https://libericajdk.ru/pages/downloads/)
(достаточно JRE сборки), если 64 битная - рекомендуется скачивать сборку [OpenJdk](https://jdk.java.net/20/).
(достаточно JRE сборки), если 64 битная - рекомендуется скачивать сборку [OpenJdk](https://jdk.java.net/21/).
1. Скачать со страницы [проекта](https://github.com/vananiev/portfolio/releases/latest) архив `investbook.zip`
и распаковать в любую удобную папку. В ней открыть файл `start.bat` и изменить строчку
```
#set JAVA_HOME=C:\Program Files\Java\jdk-20
#set JAVA_HOME=C:\Program Files\Java\jdk-21
```
следующим образом:
+ Убрать первый символ `#`.
Expand Down
10 changes: 5 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
</parent>
<groupId>ru.investbook</groupId>
<artifactId>investbook</artifactId>
<version>2023.2</version>
<version>2023.3</version>

<name>investbook</name>
<description>Investor Accounting Book</description>
Expand Down Expand Up @@ -62,8 +62,8 @@

<properties>
<!-- Valid version is (0-255).(0-255).(0-65535) -->
<win.msi.version>23.2</win.msi.version>
<java.version>20</java.version>
<win.msi.version>23.3</win.msi.version>
<java.version>21</java.version>
</properties>

<repositories>
Expand Down Expand Up @@ -209,7 +209,7 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
<version>1.18.30</version>
<optional>true</optional>
</dependency>
<dependency>
Expand Down Expand Up @@ -427,7 +427,7 @@
<!-- Defines available bellsoft-liberica java versions from
https://github.com/paketo-buildpacks/java/releases
JRE with ${java.version} will be selected automatically when available -->
<buildpack>gcr.io/paketo-buildpacks/java:9.20.0</buildpack>
<buildpack>gcr.io/paketo-buildpacks/java:10.2.1</buildpack>
</buildpacks>
</image>
<docker>
Expand Down
2 changes: 1 addition & 1 deletion src/main/asciidoc/dbms-changing.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
директории пользователя. Вы не должны переходить на другую СУБД, если у вас нет четкой мотивации сделать это.

Если Вы по каким-то причинам решили сменить СУБД, возможен переход на https://downloads.mariadb.org/[MariaDB].
Рекомендуется версия 10.4.х, которая может быть установлена, в том числе на Windows 7 MSI установщиком.
Поддерживаются версии, указанные в документации [Flyway](https://documentation.red-gate.com/fd/mariadb-184127600.html).
После установки в файле `application-conf.properties` необходимо прописать
[source,properties]
----
Expand Down
4 changes: 2 additions & 2 deletions src/main/assembly/zip/start.bat
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# InvestBook
# Copyright (C) 2020 Vitalii Ananev (spacious-team@ya.ru)
# Copyright (C) 2023 Spacious Team <spacious-team@ya.ru>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
Expand All @@ -17,7 +17,7 @@
#

# Задать путь к распакованному архиву с Java
#set JAVA_HOME=C:\Program Files\Java\jdk-20
#set JAVA_HOME=C:\Program Files\Java\jdk-21

# Запуск приложения
chcp 65001
Expand Down
4 changes: 2 additions & 2 deletions src/main/assembly/zip/start.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# InvestBook
# Copyright (C) 2020 Vitalii Ananev <spacious-team@ya.ru>
# Copyright (C) 2023 Spacious Team <spacious-team@ya.ru>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
Expand All @@ -17,7 +17,7 @@
#

# Задать путь к распакованному архиву с Java
#export JAVA_HOME=/opt/jdk-20
#export JAVA_HOME=/opt/jdk-21

[ -n "$JAVA_HOME" ] && export PATH=$JAVA_HOME/bin:$PATH
cd $(dirname $0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import static java.util.Objects.requireNonNull;
import static org.springframework.util.StringUtils.hasLength;
import static ru.investbook.parser.tinkoff.SecurityCodeAndIsinTable.SecurityAndCodeTableHeader.*;
import static ru.investbook.parser.tinkoff.TinkoffBrokerReport.tablesLastRowPattern;
Expand Down Expand Up @@ -86,27 +86,42 @@ protected Void parseRow(TableRow row) {
}

@NotNull
public String getIsin(String code) {
public String getIsin(String code, String shortName) {
initializeIfNeed();
return Objects.requireNonNull(codeToIsin.get(code), "Не найден ISIN");
String isin = codeToIsin.get(code);
if (isin == null) {
code = shortNameToCode.get(shortName);
isin = codeToIsin.get(code);
}
return requireNonNull(isin, "Не найден ISIN");
}

@NotNull
public SecurityType getSecurityType(String code) {
public SecurityType getSecurityType(String code, String shortName) {
initializeIfNeed();
return Objects.requireNonNull(codeToType.get(code), "Не найден тип ценной бумаги");
SecurityType type = codeToType.get(code);
if (type == null) {
code = shortNameToCode.get(shortName);
type = codeToType.get(code);
}
return requireNonNull(type, "Не найден тип ценной бумаги");
}

@NotNull
public BigDecimal getFaceValue(String code) {
public BigDecimal getFaceValue(String code, String shortName) {
initializeIfNeed();
return Objects.requireNonNull(codeToFaceValue.get(code), "Не найдена номинальная стоимость облигации");
BigDecimal faceValue = codeToFaceValue.get(code);
if (faceValue == null) {
code = shortNameToCode.get(shortName);
faceValue = codeToFaceValue.get(code);
}
return requireNonNull(faceValue, "Не найдена номинальная стоимость облигации");
}

@NotNull
public String getCode(String shortName) {
initializeIfNeed();
return Objects.requireNonNull(shortNameToCode.get(shortName), "Не найден код бумаги");
return requireNonNull(shortNameToCode.get(shortName), "Не найден код бумаги");
}

@RequiredArgsConstructor
Expand All @@ -115,7 +130,7 @@ protected enum SecurityAndCodeTableHeader implements TableHeaderColumn {
CODE("код", "актива"), // код (SBERP) или ISIN
ISIN(optional("isin")), // может отсутствовать, если колонка CODE заполняется ISIN
TYPE("^Тип$"),
FACE_VALUE("Номинал");
FACE_VALUE(optional("Номинал"));

@Getter
private final TableColumn column;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

import static java.util.regex.Pattern.UNICODE_CHARACTER_CLASS;
import static org.spacious_team.table_wrapper.api.TableCellAddress.NOT_FOUND;
import static org.springframework.util.CollectionUtils.isEmpty;

class TinkoffBrokerReportHelper {
private static final Pattern tableNamePattern = Pattern.compile("^[0-9]+\\.[0-9]+\\s+\\b", UNICODE_CHARACTER_CLASS);
Expand Down Expand Up @@ -61,9 +62,14 @@ static void removePageNumRows(ExcelSheet excelSheet) {
}

private static boolean isTableHeader(ReportPage reportPage, int rowNum) {
return reportPage.find(rowNum, rowNum + 1, 0, 2, cell -> (cell instanceof String) &&
return reportPage.find(rowNum, rowNum + 1, 0, 2,
TinkoffBrokerReportHelper::isCellContainsTableName) != NOT_FOUND;
}

private static boolean isCellContainsTableName(Object cell) {
return (cell instanceof String) &&
!cell.toString().isEmpty() &&
tableNamePattern.matcher(cell.toString()).lookingAt()) != NOT_FOUND;
tableNamePattern.matcher(cell.toString()).lookingAt();
}

private static boolean isPageRowNum(ReportPage excelSheet, int rowNum) {
Expand All @@ -84,12 +90,15 @@ private static void cutRows(Sheet sheet, List<Integer> rowsForCut) {
}

private static void removeRowMergedRegions(Sheet sheet, Collection<Integer> rowsForCut) {
for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
CellRangeAddress range = sheet.getMergedRegion(i);
if (isEmpty(rowsForCut)) {
return;
}
List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
for (int n = mergedRegions.size(), i = n - 1; i >= 0; i--) {
CellRangeAddress range = mergedRegions.get(i);
int firstRow = range.getFirstRow();
if (firstRow == range.getLastRow() && rowsForCut.contains(firstRow)) {
sheet.removeMergedRegion(i);
i--;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,16 @@ protected PortfolioCash parseRow(TableRow row) {
if (value == null) {
return null;
}
String currency = row.getStringCellValue(CashTableHeader.CURRENCY);
if (currency == null || currency.length() != 3) {
return null; // неизвестный контракт GLD_MOEX указывается в качестве валюты
}
return PortfolioCash.builder()
.portfolio(getReport().getPortfolio())
.timestamp(getReport().getReportEndDateTime())
.market("all")
.value(value)
.currency(row.getStringCellValue(CashTableHeader.CURRENCY))
.currency(currency)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.spacious_team.broker.pojo.Security;
import org.spacious_team.broker.pojo.SecurityType;
import org.spacious_team.broker.report_parser.api.AbstractTransaction;
import org.spacious_team.broker.report_parser.api.ReportTable;
import org.spacious_team.broker.report_parser.api.SecurityTransaction;
Expand All @@ -38,8 +39,8 @@
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toMap;
import static ru.investbook.parser.tinkoff.TinkoffDepositAndWithdrawalTable.SecurityDepositAndWithdrawalTableHeader.*;
import static ru.investbook.parser.tinkoff.TinkoffSecurityTransactionTableHelper.declareSecurity;

Expand Down Expand Up @@ -69,7 +70,7 @@ private static Map<Integer, Integer> getCounter(ReportTable<AbstractTransaction>
return transactions.getData()
.stream()
.filter(filter)
.collect(Collectors.toMap(
.collect(toMap(
AbstractTransaction::getSecurity,
t -> Math.abs(t.getCount()),
Integer::sum));
Expand Down Expand Up @@ -110,11 +111,13 @@ protected Collection<SecurityTransaction> parseRowToCollection(TableRow row) {

private int getSecurityId(TableRow row) {
String code = row.getStringCellValue(CODE);
String shortName = row.getStringCellValue(SHORT_NAME);
SecurityType securityType = codeAndIsin.getSecurityType(code, shortName);
Security security = TinkoffSecurityTransactionTableHelper.getSecurity(
code,
codeAndIsin,
row.getStringCellValue(SHORT_NAME),
codeAndIsin.getSecurityType(code));
shortName,
securityType);
return declareSecurity(security, getReport().getSecurityRegistrar());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

package ru.investbook.parser.tinkoff;

import lombok.extern.slf4j.Slf4j;
import org.spacious_team.broker.pojo.PortfolioCash;
import org.spacious_team.broker.pojo.PortfolioProperty;
import org.spacious_team.broker.pojo.PortfolioPropertyType;
Expand All @@ -34,9 +35,11 @@
import java.util.function.Function;
import java.util.stream.Stream;

import static java.util.Collections.emptyList;
import static org.spacious_team.broker.pojo.PortfolioPropertyType.TOTAL_ASSETS_RUB;
import static org.spacious_team.broker.pojo.PortfolioPropertyType.TOTAL_ASSETS_USD;

@Slf4j
public class TinkoffPortfolioPropertyTable extends InitializableReportTable<PortfolioProperty> {

private final SingleBrokerReport report;
Expand All @@ -59,17 +62,22 @@ public TinkoffPortfolioPropertyTable(SingleBrokerReport report,

@Override
protected Collection<PortfolioProperty> parseTable() {
Collection<PortfolioProperty> result = new ArrayList<>(2);
try {
Collection<PortfolioProperty> result = new ArrayList<>(2);

getTotalAssets("RUB", TinkoffSecurityQuoteTable::getRubSecuritiesTotalValue)
.map(value -> value.add(getNonRubAndNonUsdCashInRub()))
.map(value -> toPortfolioProperty(TOTAL_ASSETS_RUB, value))
.ifPresent(result::add);
getTotalAssets("USD", TinkoffSecurityQuoteTable::getUsdSecuritiesTotalValue)
.map(value -> toPortfolioProperty(TOTAL_ASSETS_USD, value))
.ifPresent(result::add);
getTotalAssets("RUB", TinkoffSecurityQuoteTable::getRubSecuritiesTotalValue)
.map(value -> value.add(getNonRubAndNonUsdCashInRub()))
.map(value -> toPortfolioProperty(TOTAL_ASSETS_RUB, value))
.ifPresent(result::add);
getTotalAssets("USD", TinkoffSecurityQuoteTable::getUsdSecuritiesTotalValue)
.map(value -> toPortfolioProperty(TOTAL_ASSETS_USD, value))
.ifPresent(result::add);

return result;
return result;
} catch (Exception e) {
log.warn("Не смог получить оценку стоимости портфеля из отчета: " + getReport(), e);
return emptyList();
}
}

private BigDecimal getNonRubAndNonUsdCashInRub() {
Expand All @@ -79,7 +87,7 @@ private BigDecimal getNonRubAndNonUsdCashInRub() {
!cash.getCurrency().equalsIgnoreCase("USD") &&
Math.abs(cash.getValue().floatValue()) > 1e-3)
.map(cash -> cash.getValue().multiply(foreignExchangeRateService
.getExchangeRateOrDefault(cash.getCurrency(), "RUB", date)))
.getExchangeRateOrDefault(cash.getCurrency(), "RUB", date)))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}

Expand Down