Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package co.nilin.opex.api.core.spi

interface SymbolMapper {
suspend fun map(symbol: String?): String?
suspend fun unmap(value: String?): String?
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import co.nilin.opex.port.api.binance.util.BalanceParser
import co.nilin.opex.port.api.binance.util.asMatchConstraint
import co.nilin.opex.port.api.binance.util.asMatchingOrderType
import co.nilin.opex.port.api.binance.util.asOrderDirection
import co.nilin.opex.api.core.inout.*
import co.nilin.opex.utility.error.data.OpexError
import co.nilin.opex.utility.error.data.OpexException
import co.nilin.opex.api.core.spi.SymbolMapper
import com.fasterxml.jackson.annotation.JsonInclude
import io.swagger.annotations.*
import kotlinx.coroutines.flow.Flow
Expand All @@ -30,7 +30,8 @@ import java.util.*
class AccountController(
val queryHandler: UserQueryHandler,
val matchingGatewayProxy: MEGatewayProxy,
val walletProxy: WalletProxy
val walletProxy: WalletProxy,
val symbolMapper: SymbolMapper
) {

data class FillsData(
Expand Down Expand Up @@ -158,16 +159,16 @@ class AccountController(
timestamp: Long,
@AuthenticationPrincipal auth: CustomAuthToken
): NewOrderResponse {
val internalSymbol = symbolMapper.unmap(symbol)!!
val request = MEGatewayProxy.CreateOrderRequest(
auth.uuid,
symbol,
internalSymbol,
price ?: BigDecimal.ZERO, // Maybe make this nullable as well?
quantity ?: BigDecimal.ZERO,
side.asOrderDirection(),
timeInForce?.asMatchConstraint(),
type.asMatchingOrderType()
)

matchingGatewayProxy.createNewOrder(request, auth.tokenValue)
return NewOrderResponse(
symbol,
Expand Down Expand Up @@ -222,11 +223,11 @@ class AccountController(
@RequestParam(name = "timestamp")
timestamp: Long
): QueryOrderResponse {
val response = queryHandler.queryOrder(principal, QueryOrderRequest(symbol, orderId, origClientOrderId))
val internalSymbol = symbolMapper.unmap(symbol)!!
val response = queryHandler.queryOrder(principal, QueryOrderRequest(internalSymbol, orderId, origClientOrderId))
?: throw OpexException(OpexError.OrderNotFound)

return QueryOrderResponse(
response.symbol,
symbolMapper.map(response.symbol)!!,
response.orderId,
response.orderListId,
response.clientOrderId,
Expand Down Expand Up @@ -280,10 +281,11 @@ class AccountController(
@RequestParam(name = "timestamp")
timestamp: Long
): Flow<QueryOrderResponse> {
return queryHandler.openOrders(principal, symbol)
val internalSymbol = symbolMapper.unmap(symbol)
return queryHandler.openOrders(principal, internalSymbol)
.map { response ->
QueryOrderResponse(
response.symbol,
symbolMapper.map(response.symbol)!!,
response.orderId,
response.orderListId,
response.clientOrderId,
Expand Down Expand Up @@ -342,10 +344,11 @@ class AccountController(
@RequestParam(name = "timestamp")
timestamp: Long
): Flow<QueryOrderResponse> {
return queryHandler.allOrders(principal, AllOrderRequest(symbol, startTime, endTime, limit))
val internalSymbol = symbolMapper.unmap(symbol)
return queryHandler.allOrders(principal, AllOrderRequest(internalSymbol, startTime, endTime, limit))
.map { response ->
QueryOrderResponse(
response.symbol,
symbolMapper.map(response.symbol)!!,
response.orderId,
response.orderListId,
response.clientOrderId,
Expand Down Expand Up @@ -408,10 +411,11 @@ class AccountController(
@RequestParam(name = "timestamp")
timestamp: Long
): Flow<TradeResponse> {
return queryHandler.allTrades(principal, TradeRequest(symbol, fromId, startTime, endTime, limit))
val internalSymbol = symbolMapper.unmap(symbol)
return queryHandler.allTrades(principal, TradeRequest(internalSymbol, fromId, startTime, endTime, limit))
.map { response ->
TradeResponse(
response.symbol, response.id,
symbolMapper.map(response.symbol)!!, response.id,
response.orderId, -1, response.price, response.qty, response.quoteQty,
response.commission, response.commissionAsset, response.time, response.isBuyer,
response.isMaker, response.isBestMatch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,17 @@ class PostgresConfig(db: DatabaseClient) {
taker_uuid VARCHAR(72) NOT NULL,
create_date TIMESTAMP
);
CREATE TABLE IF NOT EXISTS symbol_maps (
symbol VARCHAR(72) PRIMARY KEY,
value VARCHAR(72) UNIQUE NOT NULL
);
INSERT INTO symbol_maps(symbol, value) VALUES('btc_usdt', 'BTCUSDT') ON CONFLICT DO NOTHING;
INSERT INTO symbol_maps(symbol, value) VALUES('eth_usdt', 'ETHUSDT') ON CONFLICT DO NOTHING;
INSERT INTO symbol_maps(symbol, value) VALUES('eth_btc', 'ETHBTC') ON CONFLICT DO NOTHING;
"""
val initDb = db.sql { sql }
initDb // initialize the database
.then()
.subscribe() // execute
.then()
.subscribe() // execute
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package co.nilin.opex.port.api.postgres.dao

import co.nilin.opex.port.api.postgres.model.SymbolMapModel
import org.springframework.data.r2dbc.repository.Query
import org.springframework.data.repository.query.Param
import org.springframework.data.repository.reactive.ReactiveCrudRepository
import org.springframework.stereotype.Repository
import reactor.core.publisher.Mono

@Repository
interface SymbolMapRepository : ReactiveCrudRepository<SymbolMapModel, Long> {

@Query("select * from symbol_maps where symbol = :symbol")
fun findBySymbol(@Param("symbol") symbol: String): Mono<SymbolMapModel>

@Query("select * from symbol_maps where value = :value")
fun findByValue(@Param("value") value: String): Mono<SymbolMapModel>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package co.nilin.opex.port.api.postgres.impl

import co.nilin.opex.api.core.spi.SymbolMapper
import co.nilin.opex.port.api.postgres.dao.SymbolMapRepository
import kotlinx.coroutines.reactive.awaitFirstOrNull
import org.springframework.stereotype.Component

@Component
class SymbolMapperImpl(val symbolMapRepository: SymbolMapRepository) : SymbolMapper {
override suspend fun map(symbol: String?): String? {
if (symbol == null) return null
return symbolMapRepository.findBySymbol(symbol).awaitFirstOrNull()?.value
}

override suspend fun unmap(value: String?): String? {
if (value == null) return null
return symbolMapRepository.findByValue(value).awaitFirstOrNull()?.symbol
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package co.nilin.opex.port.api.postgres.model


import org.springframework.data.annotation.Id
import org.springframework.data.relational.core.mapping.Column
import org.springframework.data.relational.core.mapping.Table

@Table("symbol_maps")
class SymbolMapModel(
@Id val symbol: String,
@Column("value") val value: String,
)