- 🥇 Победитель Tinkoff Invest Robot Contest #1 2022 (номинация java)
- 🥇 Победитель Tinkoff Invest Robot Contest #2 2024 (абсолютный результат)
tinkoff.token: токен для Tinkoff GRPC API
tinkoff.is-token-sandbox: true для токена песочницы, false для боевого
tinkoff.account-id: ID счета (опционально, по умолчанию будет выбран первый счет, список счетов выводится в лог)
tinkoff.emulator: true для эмуляции ордеров, false для вызова Tinkoff GRPC API
Опционально, используется для уведомлений об ордерах и ошибках
telegram.bot.token: токен телеграм бота
telegram.bot.chat-id: id чата, будет отправлен в чат, если написать боту любое сообщение
Прибыль за счет торговли при изменении стоимости торговых инструментов, относительно друг друга (арбитраж). В рамках одной стратегии должно быть не менее 2х инструментов.
Используется для перемещения средств между валютами на московской бирже вследствие периодически меняющейся стоимости валют относительно друг друга (предположительно на фоне наличия позиций покупки/продажи конкретной валюты крупными игроками, экспортерами, ЦБ и т.д.).
Продажа текущего инструмента и покупка другого из стратегии происходит при увеличении цены текущего относительно покупаемого на определенный процент (0.5% по умолчанию).
Стоимость USD, EUR, CNY на московской бирже за RUB. USD дорожает относительно RUB в течении дня, EUR при этом изменится на меньший процент или даже дешевеет, на следующий день ситуация изменится в обратную сторону и т.д.. Соответственно в первый день нужно переложить из USD в EUR, а во второй из EUR в USD, при пересчете по любой из этих валют будет прибыль.
2 инструмента EUR и CNY, при изменении стоимости одной из валюты на 0.5% относительно другой происходит перекладывание (есть в исходниках, запущено на продакшене)
public class EURByCNYStrategy extends AInstrumentByInstrumentStrategy {
private static final Map FIGIES = Map.of(
"BBG0013HRTL0", 6000, // CNY
"BBG0013HJJ31", 1000 // EUR
);
public Map<String, Integer> getFigies() {
return FIGIES;
}
@Override
public boolean isEnabled() {
return true;
}
}
AInstrumentByInstrumentStrategy.getFigies
- список FIGI (инструментов) и количество бумаг, которые используются в стратегии (минимум 2 инструмента)AInstrumentByInstrumentStrategy.getMinimalDropPercent
- процент падения стоимости одного из инструментов в стратегии относительно инструмента, которым владеем (по умолчанию 0.5%). Выполняется операция продажи/покупки при достижении данного значенияAInstrumentByInstrumentStrategy.getForceToSellDuration
- максимальное период, которое держим средства в одном из инструментов (по умолчанию 30 дней)
- live/sandbox: src/main/java/com/struchev/invest/strategy/instrument_by_instrument
- tests: src/test/java/com/struchev/invest/strategy/instrument_by_instrument
Прибыль за счет торговли при изменении стоимости торгового инструмента. В рамках одной стратегии может быть любое кол-во инструментов.
Классическая покупка/продажа инструмента на основе критериев, индикаторов, истории свечей.
Торговля акциями Tinkoff, покупаем при цене меньше 40% значения за последние 7 дней, продаем при достижении прибыли в 1%, либо убытка в 3% (есть в проекте, запущено на продакшене)
@Component
public class BuyP40AndTP1PercentAndSL3PercentStrategy extends AInstrumentByFiatStrategy {
private static final Map FIGIES = Map.of(
"TCS00A107UL4", 1 // Tinkoff
);
public Map<String, Integer> getFigies() {
return FIGIES;
}
@Override
public AInstrumentByFiatStrategy.BuyCriteria getBuyCriteria() {
return AInstrumentByFiatStrategy.BuyCriteria.builder().lessThenPercentile(40).build();
}
@Override
public AInstrumentByFiatStrategy.SellCriteria getSellCriteria() {
return AInstrumentByFiatStrategy.SellCriteria.builder().takeProfitPercent(1f).stopLossPercent(3f).build();
}
@Override
public boolean isEnabled() {
return true;
}
}
AInstrumentByFiatStrategy.getFigies
- список FIGI (инструментов) и количество бумаг, которые используются в стратегии (минимум 1 инструмент)AInstrumentByFiatStrategy.getHistoryDuration
- период истории свечей, для расчета процента (перцентиля) по текущей цене относительно истории (по умолчанию 7 дней)AInstrumentByFiatStrategy.getBuyCriteria().lessThenPercentile
- процент (перцентиль), если цена за указанный период падает ниже него, покупаемAInstrumentByFiatStrategy.getSellCriteria().takeProfitPercent
- процент (take profit), если цена покупки растет на него, продаемAInstrumentByFiatStrategy.getSellCriteria().takeProfitPercentile
- процент (take profit, перцентиль), если цена за указанный период растет выше него, продаемAInstrumentByFiatStrategy.getSellCriteria().stopLossPercent
- процент (stop loss), если цена покупки падает на него, продаемAInstrumentByFiatStrategy.getSellCriteria().stopLossPercentile
- процент (stop loss, перцентиль), если цена за указанный период падает ниже него, продаемAInstrumentByFiatStrategy.getDelayBySL
- период паузы в торговле, если продали по stop loss критерию
- live/sandbox: src/main/java/com/struchev/invest/strategy/instrument_by_fiat
- tests: src/test/java/com/struchev/invest/strategy/instrument_by_fiat
Приложение загружает историю, эмулирует поток свечей и ордеры в рамках прописанных стратегий. Работа возможна с live или sandbox токенами Tinkoff invest GRPC API.
candle.history.duration: период истории свечей от времени запуска теста, используется при эмуляции потока свечей. Пример P30D (формат java.time.Duration)
Требуется docker, jdk 21+
- Обновить конфигурацию (свойства) в src/test/resources/application-test.properties
- Проверить/изменить стратегии в src/test/java/com/struchev/invest/strategy
- Скомпилировать и запустить тесты
./gradlew clean test --info
- В консоле будет лог операций и результат.
Пример запуска теста за 30 дней и вывод результата по стратегиям типа
инструмент за инструмент
---------------------- Report instrument by instrument start ----------------------
EURByCNYStrategy | init amount 1000.00 Евро | last amount 1104.32 Евро | profit 10.43% | orders 34 | commission 1099.96 RUB
EURByCNYbyUSDStrategy | init amount 1000.00 Евро | last amount 1166.59 Евро | profit 16.66% | orders 58 | commission 1836.92 RUB
USDByCNYStrategy | init amount 6000.00 Юань | last amount 7279.10 Юань | profit 21.32% | orders 55 | commission 1715.71 RUB
EURByCNYByGBPStrategy | init amount 1000.00 Фунт стерлингов | last amount 1376.91 Фунт стерлингов | profit 37.69% | orders 131 | commission 4388.70 RUB
GBPByCNYStrategy | init amount 1000.00 Фунт стерлингов | last amount 1433.18 Фунт стерлингов | profit 43.32% | orders 72 | commission 2502.98 RUB
JPYByCNYStrategy | init amount 1000.00 Иена | last amount 1651.13 Иена | profit 65.11% | orders 81 | commission 2398.00 RUB
JPYbyCNYByEURByGBPStrategy | init amount 1000.00 Иена | last amount 2393.02 Иена | profit 139.30% | orders 210 | commission 7154.09 RUB
---------------------- Report instrument by instrument end ------------------------
Приложение слушает поток свечей и выполняет ордеры в рамках прописанных стратегий. Работа возможна с live или sandbox токенами Tinkoff invest API.
Требуется docker, docker-compose
- Обновить конфигурацию (свойства) в docker-compose-app-with-db-local.yml
- Проверить/изменить стратегии в src/main/java/com/struchev/invest/strategy
- Собрать docker образ локально (опционально, если меняли стратегии в проекте, иначе будет использоваться уже опубликованный из CI https://hub.docker.com/repository/docker/romanew/invest)
docker build -t romanew/invest:latest -f Dockerfile.App .
- Запустить контейнеры приложения и БД через docker-compose
docker-compose -f docker-compose-app-with-db-local.yml up
- В консоле будет лог операций, статистика доступна через UI http://localhost:10000
Требуется posgresql, jdk 21+
- Обновить конфигурацию (свойства) и подключение к posgresql в одном из профилей.
Профили
application-*.properties
в src/main/resources/. - Проверить/изменить стратегии в src/main/java/com/struchev/invest/strategy
- Скомпилировать и запустить приложение указав профиль
./gradlew bootRun -Dspring.profiles.active=sandbox
- В консоле будет лог операций, статистика по адресу http://localhost:10000
По коммиту, проект собирается с помощью github actions и docker образы публикуются в https://hub.docker.com/repository/docker/romanew/invest. Экземпляр приложения разворачивается на сервере c помощью GitHub Actions.
На данный момент торгуются несколько стратегий, которые обгоняют рынок. Актуальное состояние можно посмотреть:
- Sandbox 1: https://invest-sandbox.struchev.site (песочница, акции, ветка sandbox)
- Sandbox 2: https://invest-sandbox-2.struchev.site (песочница, арбитраж валюты, ветка sandbox-2)
- Live: https://invest.struchev.site (боевые стратегии, ветка master)
Подключен Spring Actuator. По умолчанию открыты:
/actuator/metrics
/actuator/prometheus
Для отображения детальной статистики по любому из брокерских счетов разработан отдельный сервис https://invest-stats.struchev.site