Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,17 @@ class AppConfig {
@Bean
fun orderManager(
pairConfigLoader: PairConfigLoader,
userLevelLoader: UserLevelLoader,
financialActionPersister: FinancialActionPersister,
financeActionLoader: FinancialActionLoader,
orderPersister: OrderPersister,
tempEventPersister: TempEventPersister,
tempEventRepublisher: TempEventRepublisher,
richOrderPublisher: RichOrderPublisher
richOrderPublisher: RichOrderPublisher,
): OrderManager {
return OrderManagerImpl(
pairConfigLoader,
userLevelLoader,
financialActionPersister,
financeActionLoader,
orderPersister,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package co.nilin.opex.accountant.app.config

import co.nilin.opex.accountant.ports.postgres.dao.PairConfigRepository
import co.nilin.opex.accountant.ports.postgres.dao.PairFeeConfigRepository
import co.nilin.opex.accountant.ports.postgres.dao.UserLevelRepository
import co.nilin.opex.accountant.ports.postgres.model.PairFeeConfigModel
import co.nilin.opex.utility.preferences.Preferences
import kotlinx.coroutines.reactor.awaitSingleOrNull
Expand All @@ -15,13 +16,19 @@ import javax.annotation.PostConstruct
@DependsOn("postgresConfig")
class InitializeService(
private val pairConfigRepository: PairConfigRepository,
private val pairFeeConfigRepository: PairFeeConfigRepository
private val pairFeeConfigRepository: PairFeeConfigRepository,
private val userLevelRepository: UserLevelRepository,
) {

@Autowired
private lateinit var preferences: Preferences

@PostConstruct
fun init() = runBlocking {
preferences.userLevels.forEach {
userLevelRepository.insert(it).awaitSingleOrNull()
}

preferences.markets.map {
val pair = it.pair ?: "${it.leftSide}_${it.rightSide}"
val leftSideCurrency = preferences.currencies.first { c -> it.leftSide == c.symbol }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ class OrderListener(private val orderManager: OrderManager) : OrderSubmitRequest
event.quantity,
event.direction,
event.matchConstraint,
event.orderType
event.orderType,
event.userLevel
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import java.time.LocalDateTime

open class OrderManagerImpl(
private val pairConfigLoader: PairConfigLoader,
private val userLevelLoader: UserLevelLoader,
private val financialActionPersister: FinancialActionPersister,
private val financeActionLoader: FinancialActionLoader,
private val orderPersister: OrderPersister,
Expand All @@ -32,7 +33,13 @@ open class OrderManagerImpl(
} else {
submitOrderEvent.pair.rightSideName
}
val pairFeeConfig = pairConfigLoader.load(submitOrderEvent.pair.toString(), submitOrderEvent.direction, "")

val level = userLevelLoader.load(submitOrderEvent.uuid)
val pairFeeConfig = pairConfigLoader.load(
submitOrderEvent.pair.toString(),
submitOrderEvent.direction,
level
)
val makerFee = pairFeeConfig.makerFee * BigDecimal.ONE //user level formula
val takerFee = pairFeeConfig.takerFee * BigDecimal.ONE //user level formula

Expand Down Expand Up @@ -70,7 +77,7 @@ open class OrderManagerImpl(
pairFeeConfig.pairConfig.leftSideFraction,
pairFeeConfig.pairConfig.rightSideFraction,
submitOrderEvent.uuid,
"",
submitOrderEvent.userLevel,
submitOrderEvent.direction,
submitOrderEvent.matchConstraint,
submitOrderEvent.orderType,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package co.nilin.opex.accountant.core.spi

interface UserLevelLoader {

suspend fun load(uuid: String): String

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ internal class OrderManagerImplTest {
private val tempEventPersister = mockk<TempEventPersister>()
private val pairConfigLoader = mockk<PairConfigLoader>()
private val richOrderPublisher = mockk<RichOrderPublisher>()
private val userLevelLoader = mockk<UserLevelLoader>()

private val orderManager = OrderManagerImpl(
pairConfigLoader,
userLevelLoader,
financialActionPersister,
financialActionLoader,
orderPersister,
Expand All @@ -50,6 +52,7 @@ internal class OrderManagerImplTest {
coEvery { tempEventPersister.saveTempEvent(any(), any()) } returns any()
coEvery { financialActionLoader.findLast(any(), any()) } returns null
coEvery { financialActionPersister.persist(any()) } returnsArgument (0)
coEvery { userLevelLoader.load(any()) } returns "*"
}

@Test
Expand All @@ -68,7 +71,7 @@ internal class OrderManagerImplTest {
)

coEvery {
pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, "")
pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, any())
} returns PairFeeConfig(
pairConfig,
submitOrderEvent.direction.toString(),
Expand Down Expand Up @@ -124,7 +127,7 @@ internal class OrderManagerImplTest {
)

coEvery {
pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, "")
pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, any())
} returns PairFeeConfig(
pairConfig,
submitOrderEvent.direction.toString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ internal class TradeManagerImplTest {
private val tempEventPersister = mockk<TempEventPersister>()
private val richOrderPublisher = mockk<RichOrderPublisher>()
private val richTradePublisher = mockk<RichTradePublisher>()
private val userLevelLoader = mockk<UserLevelLoader>()

private val orderManager = OrderManagerImpl(
pairConfigLoader,
userLevelLoader,
financialActionPersister,
financeActionLoader,
orderPersister,
Expand All @@ -48,10 +50,11 @@ internal class TradeManagerImplTest {

init {
coEvery { tempEventPersister.loadTempEvents(any()) } returns emptyList()
coEvery { orderPersister.save(any()) } returnsArgument(0)
coEvery { financeActionLoader.findLast(any(),any()) } returns null
coEvery { orderPersister.save(any()) } returnsArgument (0)
coEvery { financeActionLoader.findLast(any(), any()) } returns null
coEvery { richOrderPublisher.publish(any()) } returns Unit
coEvery { richTradePublisher.publish(any()) } returns Unit
coEvery { userLevelLoader.load(any()) } returns "*"
}

@Test
Expand Down Expand Up @@ -184,7 +187,7 @@ internal class TradeManagerImplTest {
takerFee: BigDecimal
) {
coEvery {
pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, "")
pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, any())
} returns PairFeeConfig(
pairConfig,
submitOrderEvent.direction.toString(),
Expand All @@ -210,7 +213,7 @@ internal class TradeManagerImplTest {
orderPairFeeConfig.pairConfig.leftSideFraction,
orderPairFeeConfig.pairConfig.rightSideFraction,
submitOrderEvent.uuid,
"",
submitOrderEvent.userLevel,
submitOrderEvent.direction,
submitOrderEvent.matchConstraint,
submitOrderEvent.orderType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ data class OrderSubmitRequest(
val direction: OrderDirection,
val matchConstraint: MatchConstraint,
val orderType: OrderType,
val userLevel: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package co.nilin.opex.accountant.ports.postgres.dao

import co.nilin.opex.accountant.ports.postgres.model.UserLevelMapperModel
import org.springframework.data.repository.reactive.ReactiveCrudRepository
import org.springframework.stereotype.Repository
import reactor.core.publisher.Mono

@Repository
interface UserLevelMapperRepository : ReactiveCrudRepository<UserLevelMapperModel, Long> {

fun findByUuid(uuid: String): Mono<UserLevelMapperModel>

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package co.nilin.opex.accountant.ports.postgres.dao

import co.nilin.opex.accountant.ports.postgres.model.UserLevelModel
import org.springframework.data.r2dbc.repository.Query
import org.springframework.data.repository.reactive.ReactiveCrudRepository
import org.springframework.stereotype.Repository
import reactor.core.publisher.Mono

@Repository
interface UserLevelRepository : ReactiveCrudRepository<UserLevelModel, String> {

@Query("insert into user_level (level) values (:level) on conflict do nothing")
fun insert(level: String): Mono<Void>

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import co.nilin.opex.accountant.core.model.PairFeeConfig
import co.nilin.opex.accountant.core.spi.PairConfigLoader
import co.nilin.opex.accountant.ports.postgres.dao.PairConfigRepository
import co.nilin.opex.accountant.ports.postgres.dao.PairFeeConfigRepository
import co.nilin.opex.accountant.ports.postgres.dao.UserLevelMapperRepository
import co.nilin.opex.accountant.ports.postgres.model.PairConfigModel
import co.nilin.opex.accountant.ports.postgres.model.PairFeeConfigModel
import co.nilin.opex.matching.engine.core.model.OrderDirection
Expand All @@ -19,8 +20,8 @@ import java.math.BigDecimal

@Component
class PairConfigLoaderImpl(
val pairConfigRepository: PairConfigRepository,
val pairFeeConfigRepository: PairFeeConfigRepository
private val pairConfigRepository: PairConfigRepository,
private val pairFeeConfigRepository: PairFeeConfigRepository
) : PairConfigLoader {

override suspend fun loadPairConfigs(): List<PairConfig> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package co.nilin.opex.accountant.ports.postgres.impl

import co.nilin.opex.accountant.core.spi.UserLevelLoader
import co.nilin.opex.accountant.ports.postgres.dao.UserLevelMapperRepository
import kotlinx.coroutines.reactor.awaitSingleOrNull
import org.springframework.stereotype.Component

@Component
class UserLevelLoaderImpl(private val userLevelMapperRepository: UserLevelMapperRepository) : UserLevelLoader {

override suspend fun load(uuid: String): String {
val mapper = userLevelMapperRepository.findByUuid(uuid).awaitSingleOrNull()
return mapper?.userLevel ?: "*"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package co.nilin.opex.accountant.ports.postgres.model

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

@Table("user_level_mapper")
data class UserLevelMapperModel(
@Id val id: Long,
val uuid: String,
val userLevel: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package co.nilin.opex.accountant.ports.postgres.model

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

@Table("user_level")
data class UserLevelModel(@Id val level: String)
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,32 @@ CREATE TABLE IF NOT EXISTS pair_config
right_side_wallet_symbol VARCHAR(36) NOT NULL,
left_side_fraction DECIMAL NOT NULL,
right_side_fraction DECIMAL NOT NULL,
UNIQUE (
left_side_wallet_symbol,
right_side_wallet_symbol
)
UNIQUE (left_side_wallet_symbol, right_side_wallet_symbol)
);

CREATE TABLE IF NOT EXISTS user_level
(
level VARCHAR(36) PRIMARY KEY
);

CREATE TABLE IF NOT EXISTS pair_fee_config
(
id SERIAL PRIMARY KEY,
pair_config_id VARCHAR(72) NOT NULL REFERENCES pair_config (pair),
direction VARCHAR(36) NOT NULL,
user_level VARCHAR(36) NOT NULL,
user_level VARCHAR(36) NOT NULL REFERENCES user_level (level),
maker_fee DECIMAL NOT NULL,
taker_fee DECIMAL NOT NULL,
UNIQUE (direction, user_level, pair_config_id)
);

CREATE TABLE IF NOT EXISTS user_level_mapper
(
id SERIAL PRIMARY KEY,
uuid VARCHAR(36) NOT NULL UNIQUE,
user_level VARCHAR(36) NOT NULL REFERENCES user_level (level)
);

CREATE TABLE IF NOT EXISTS temp_events
(
id SERIAL PRIMARY KEY,
Expand Down
4 changes: 4 additions & 0 deletions api/api-app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>co.nilin.opex.utility.log</groupId>
<artifactId>logging-handler</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package co.nilin.opex.api.app

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.cache.annotation.EnableCaching
import org.springframework.context.annotation.ComponentScan
import springfox.documentation.swagger2.annotations.EnableSwagger2

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package co.nilin.opex.api.app.config

import org.springframework.cache.CacheManager
import org.springframework.cache.annotation.EnableCaching
import org.springframework.cache.concurrent.ConcurrentMapCacheManager
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
@EnableCaching
class CacheConfig {

@Bean
fun apiKeyCacheManager(): CacheManager {
return ConcurrentMapCacheManager("apiKey")
}

}
Loading