Пишем биржу :)
Биржа состоит из 3-х компонентов:
- Клиент
- Брокер
- Биржа
Биржа - центральная точка всей системы. Она сводит между собой различных продавцов и покупателей из разных брокеров, результатом сделок которых является изменение цены.
В нашем хакатоне будут использоваться исторические данные реальных торгов по фьючерсным контрактам на бирже РТС за 2017-12-08 - https://cloud.mail.ru/public/6g7X/6tbbcaiaL
Если на биржу ставится заявка на покупку или продажу, то она ставится в очередь и когда цена доходит до неё и хватает объёма - заявка исполняется, брокеру уходит соответствующее уведомление. Если не хватает объёма, то заявка исполняется частичсно, брокеру так же уходит уведомление. Если несколько участников поставилос заявку на одинаковый уровеньт цены, то исполняются в порядке добавления.
Внутри биржи цена образует книгу заявок, то что называется стаканом - https://s.mail.ru/ESbV/M5iGMvkQR - это на каком уровне стоят заявки на покупку или продажу
В связи с тем что наши данные исторические - предполагем, что мы не можем выступить инициатором сделки (т.е. сдвинуть цену, купив по рынку), можем приобрести только если другая сторона выступила инциатором. Это значит что мы встаём в стакан и когда цена доходит до нас - происходит сделка.
Заявки могут быть 2 видов:
- на прокупку - "я хочу купить по цене Х" - когда цена сверху вниз доходит до нашей заявки - она исполняется
- на продажу - "я хочу продать по цене Х" - когда цена снизу вверх доходит до нашей заявки - она исполняется
Помимо исполнения сделок брокер транслирует цену инструментов всем подключенным брокерам. Список транслируемых инструментов берётся из конфига, сами цены - из файла. В связи с тем что цены исторические - мы не смотрим на дату, а просто начинаем таранслировать ту цену что есть. Инфомрация о изменении цены отправляется каждую секунду. Если в секунду ( под конфигом) произошло больше чем 1 сделка - они аггрегируются. Брокеру отправляется OHLCV ( open, high, low, close, volume ), где:
- open - цена открытия интервала (первая сделка)
- high - максимальная цена в интервале
- low - минимальная цена в интервале
- close - цена закрытия интервала ( последняя сделка )
- volume - количество проторгованных контрактов
Формат обмена данными с брокером - protobuf через GRPC
syntax = "proto3";
message OHLCV {
int64 ID = 1;
int32 Time = 2;
int32 Interval = 3;
float Open = 4;
float High = 5;
float Low = 6;
float Close = 7;
int32 Time = 8;
string Ticker = 9;
}
message Deal {
int32 BrokerID = 1;
int32 ClientID = 2;
string Ticker = 3;
int32 Amount = 4;
bool Partial = 5;
int32 Time = 6;
float Price = 7;
}
Брокер - это организация, которая предсотавляет своим клиентам доступ на биржу. У неё есть список клиентов, которые могут взаимодействовать посредством неё с биржей, так же она хранит количество их позиицй и историю сделок.
Брокер аггрегирует внутри себя информацию от биржи по ценовым данным, позволяя клиенту посмотреть историю. По-умолчанию, хранится история за последнеи 5 минут (300 секунд).
Брокер предоставляет клиентам JSON-апи (REST или JSON-RPC), через который им доступныы следующие возможности:
- посмотреть свои позиции и баланс
- посмотрить историю своих сделок
- отправить на биржу заявку на покупку или продажу тикера
- отменить ранее отправленную заявку
- посмотреть последнюю истории торгов
CREATE TABLE `clients` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`login_id` int NOT NULL,
-- `password` varchar(300) NOT NULL,
`balance` int NOT NULL
);
-- INSERT INTO `clients` (`id`, `login`, `password`, `balance`)
-- VALUES (1, 'Vasily', '123456', 200000),
-- VALUES (2, 'Ivan', 'qwerty', 200000),
-- VALUES (3, 'Olga', '1qaz2wsx', 200000);
CREATE TABLE `positions` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`user_id` int NOT NULL,
`ticker` varchar(300) NOT NULL,
`vol` int NOT NULL,
KEY user_id(user_id)
);
-- INSERT INTO `clients` (`user_id`, `ticker`, `amount`)
-- VALUES (1, 'SiM7', '123456', 200000),
-- VALUES (1, 'RIM7', '123456', 200000),
-- VALUES (2, 'RIM7', 'qwerty', 200000);
CREATE TABLE `orders_history` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`time` int NOT NULL,
`user_id` int,
`ticker` varchar(300) NOT NULL,
`vol` int NOT NULL,
`price` float not null,
`is_buy` int not null,
KEY user_id(user_id)
);
CREATE TABLE `request` ( -- запросы
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`user_id` int,
`ticker` varchar(300) NOT NULL,
`vol` int NOT NULL,
`price` float NOT NULL,
`is_buy` int not null, -- 1 - покупаем, 0 - продаем
KEY user_id(user_id)
);
CREATE TABLE `stat` ( -- запросы
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`time` int,
`interval` int,
`open` float,
`high` float,
`low` float,
`close` float,
`volume` int,
`ticker` varchar(300),
KEY id(id)
);
Клиент - это телеграмм бот, который нам позволяет покупать-продавать и смотреть свою историю.