Система будет реализована на акторной модели, так как есть требования к масштабируемости, отказоустойчивости, а состояния система практически не имеет, поэтому акторная модель здесь отлично подойдет.
trait ExchangeFacade {
def balance(): Map[Currency, Balance]
def placeOrder(symbol: Symbol, placement: Placement): Order
def cancelOrder(symbol: Symbol, orderId: String)
def getOpenOrders(symbol: Symbol) : Seq[Order]
def checkOrderStatus(symbol: Symbol, orderId : String)
def getTradesByOrder(orderId : String) : TradeHistory
def getExchangeType : ExchangeType
}
trait ExchangeRouter {
def selectExchange(exchangeType: ExchangeType) : ExchangeFacade
}
sealed trait Currency
type Symbol = (Currency, Currency)
case class Balance()
case class Placement(orderType: OrderType, price: BigDecimal, quantity: BigDecimal)
case class Order()
sealed trait OrderType
case object LimitOrder extends OrderType
case object MarketOrder extends OrderType
case class TradeHistory()
sealed trait ExchangeType
case object Binance
case object Bitfinex
Для выбора конкретного типа биржи будет использоваться паттерн Стратегия (ExchangeRouter
).
Для авторизации можно использовать протокол oauth2 (или подобный, главное чтобы был внешний) auth provider.
- Клиент посылает команду вызова одной из функций (например, запрашивает баланс)
- Биржа редиректит его на один из auth provider (какой именно тип можно передавать в header'e запроса)
- Клиент авторизуется и получает токен, запрос с токеном возвращается на биржу
- Биржа запрашивает у выбранного auth provider'a про валидность токена. Если все ок, дергается функция.
Подобный алгоритм позволит иметь несколько внешних систем авторизаций, выбор из которых будет производиться по данным из запроса.
Например, у нас есть заказчики Х и Y. Они хотят иметь собственную систему авторизации. Они разворчивают AuthProviderX и AuthProviderY. В запросе от клиента в header'e передается источник запроса - X и Y. В зависимости от типа, клиент биржи редиректит на соответствующий AuthProvider и далее работает с ним во время выполнения запроса (проверяет валидность токена, к примеру)
-
Проксирование
-
Для реализации будет использованы акторы, которые развернуты в нужной стране (на облаках, либо на отдельном сервере). Для доступа к ним можно применить механизм
remote actor
, например,akka-remote
. Либо другой механизм связи, но обязательно бизнес-логика должна быть реализована такой же кодовой базой.
В каждой реализации ExchangeFacade
для конкретной биржы должно быть заинкапсулировано местонахождение (remote или
local) актора. То есть при передаче команды актору клиента конкретной биржи мы не должны знать, где выполнится актор,
на локальной машине или удаленной.
Секреты хранить в Vault By HashiCorp, для доступа обернуть в актор
- Набор внешних auth provider'ов как сервисов
- модуль обработки web запросов
- модуль роутинга по доступным биржам
- набор модулей-реализаций для каждой из бирж
- модуль гео роутинга
- модуль хранения конфигураций (секретных или не очень)
Все модули представлены в виде акторов. Масштабируемость и расширения списка из-за свойств акторных моделей происходит довольно легко (при расширение усложняется только роутер между биржами и то, можно сделать через конфигурацию, тип биржки = адрес актора реализации).