First Commit
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
package win.tap_tap.papertrader
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.math.roundToLong
|
||||
|
||||
fun Double.toPercentString(relative: Boolean = false): String {
|
||||
var shifted = (this * 10000).toInt() / 100.0
|
||||
if (relative) shifted -= 100F
|
||||
val string = shifted.toString()
|
||||
val parts = string.split(".")
|
||||
val decimals = parts.getOrNull(1)?.padEnd(2, '0')?.take(2) ?: "00"
|
||||
return "${parts[0]}.$decimals%"
|
||||
}
|
||||
|
||||
fun getRelativePercentage(currentValue: Cash, startValue: Cash): String {
|
||||
if (startValue.asCents() == 0L) {
|
||||
return 0.0.toPercentString()
|
||||
}
|
||||
val percentages = (currentValue.asCents().toDouble() / startValue.asCents()
|
||||
.toDouble()
|
||||
).toPercentString(relative = true)
|
||||
return percentages
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Cash(
|
||||
val euro: Long,
|
||||
val cent: Long,
|
||||
) {
|
||||
fun asCents(): Long {
|
||||
return euro * 100 + cent
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "$euro,$cent€"
|
||||
}
|
||||
|
||||
operator fun times(other: Double): Cash {
|
||||
return fromCents((asCents() * other).roundToLong())
|
||||
}
|
||||
|
||||
operator fun times(other: Cash): Cash {
|
||||
return fromCents(asCents() * other.asCents())
|
||||
}
|
||||
|
||||
operator fun plus(other: Cash): Cash {
|
||||
return fromCents(asCents() + other.asCents())
|
||||
}
|
||||
|
||||
operator fun minus(other: Cash): Cash {
|
||||
return fromCents(asCents() - other.asCents())
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromCents(cents: Long): Cash {
|
||||
return Cash(cents / 100, cents % 100)
|
||||
}
|
||||
|
||||
fun fromFloat(cash: Float): Cash {
|
||||
return Cash(cash.toLong(), (cash % 1).toLong() * 100L)
|
||||
}
|
||||
|
||||
fun zero(): Cash {
|
||||
return Cash(0, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Asset(
|
||||
val id: Long, val symbol: String, val name: String,
|
||||
)
|
||||
|
||||
fun List<Position>.currentValue(): Cash {
|
||||
return Cash.fromCents(this.sumOf { it.currentPrice.asCents() * it.amount }.roundToLong())
|
||||
}
|
||||
|
||||
fun List<Position>.buyValue(): Cash {
|
||||
return Cash.fromCents(this.sumOf { it.buyPrice.asCents() * it.amount }.roundToLong())
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Position(
|
||||
val id: Long,
|
||||
val asset: Asset,
|
||||
val buyPrice: Cash,
|
||||
val currentPrice: Cash,
|
||||
val amount: Double,
|
||||
) {
|
||||
fun currentMarketValue(): Cash {
|
||||
return Cash.fromCents((currentPrice.asCents() * amount).roundToLong())
|
||||
}
|
||||
|
||||
fun buyMarketValue(): Cash {
|
||||
return Cash.fromCents((buyPrice.asCents() * amount).roundToLong())
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class Challenge(
|
||||
val id: Long, val name: String, val cash: Cash
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class Participant(val user: User, val cash: Cash)
|
||||
|
||||
@Serializable
|
||||
data class User(val id: Long, val name: String)
|
||||
@@ -0,0 +1,77 @@
|
||||
package win.tap_tap.papertrader
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
||||
// Single Requests
|
||||
|
||||
@Serializable
|
||||
data class RequestAddParticipant(val participantId: Long, val challengeId: Long)
|
||||
|
||||
@Serializable
|
||||
data class RequestRegisterUser(val username: String, val password: String, val passwordConfirm: String)
|
||||
|
||||
@Serializable
|
||||
data class RequestAssetBuy(val assetId: Long, val cash: Cash, val challengeId: Long)
|
||||
|
||||
@Serializable
|
||||
data class RequestAssetSell(val positionId: Long)
|
||||
|
||||
@Serializable
|
||||
data class RequestLeaveChallenge(val challengeId: Long)
|
||||
|
||||
@Serializable
|
||||
data class RequestChallengeKick(val challengeId: Long, val userId: Long)
|
||||
|
||||
// Single Responses
|
||||
|
||||
@Serializable
|
||||
data class ResponseGetChallenges(val challenges: List<Challenge>)
|
||||
|
||||
@Serializable
|
||||
data class ResponseGetStocks(val stocks: List<Asset>)
|
||||
|
||||
// Requests + Responses
|
||||
|
||||
@Serializable
|
||||
data class RequestLoginUser(val username: String, val password: String)
|
||||
|
||||
@Serializable
|
||||
data class ResponseLogin(val accessToken: String, val refreshToken: String, val expiresIn: Long)
|
||||
|
||||
@Serializable
|
||||
data class RequestLogoutUser(val accessToken: String, val refreshToken: String)
|
||||
|
||||
@Serializable
|
||||
data class RequestCreateChallenge(val name: String, val euros: Long, val cents: Long)
|
||||
|
||||
@Serializable
|
||||
data class RequestTokenRefresh(val refreshToken: String)
|
||||
|
||||
@Serializable
|
||||
data class ResponseTokenRefresh(val accessToken: String, val expiresIn: Long)
|
||||
|
||||
@Serializable
|
||||
data class RequestGetParticipants(val challengeId: Long)
|
||||
|
||||
@Serializable
|
||||
data class ResponseGetParticipants(val userIsCreator: Boolean, val user: Participant, val participants: List<User>)
|
||||
|
||||
@Serializable
|
||||
data class RequestGetMissingParticipants(val challengeId: Long)
|
||||
|
||||
@Serializable
|
||||
data class ResponseGetMissingParticipants(val users: List<User>)
|
||||
|
||||
@Serializable
|
||||
data class RequestChallengeData(val challengeId: Long)
|
||||
|
||||
@Serializable
|
||||
data class ResponseChallengeData(
|
||||
val userIsCreator: Boolean,
|
||||
val user: Participant,
|
||||
val positions: Map<Participant, List<Position>>
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package win.tap_tap.papertrader
|
||||
|
||||
//const val API_ENDPOINT = "http://127.0.0.1:8080"
|
||||
|
||||
const val API_ENDPOINT = "https://papertrader.tap-tap.win"
|
||||
|
||||
enum class Endpoints(val path: String) {
|
||||
LOGIN("/api/login"),
|
||||
REGISTER("/api/register"),
|
||||
LOGOUT("/api/logout"),
|
||||
GET_CHALLENGES("/api/get-challenges"),
|
||||
REFRESH_TOKEN("/api/refresh-token"),
|
||||
|
||||
// GET_PARTICIPANTS("/api/get-participants"),
|
||||
CREATE_CHALLENGE("/api/create-challenge"),
|
||||
GET_MISSING_PARTICIPANTS("/api/get-missing-participants"),
|
||||
ADD_PARTICIPANT("/api/add-participant"),
|
||||
GET_STOCKS("/api/get-stocks"),
|
||||
ASSET_BUY("/api/asset/buy"),
|
||||
ASSET_SELL("/api/asset/sell"),
|
||||
CHALLENGE_LEAVE("/api/challenge/leave"),
|
||||
CHALLENGE_KICK("/api/challenge/kick"),
|
||||
GET_CHALLENGE_DATA("/api/challenge/data"),
|
||||
USER_DELETE("/api/user/delete");
|
||||
|
||||
fun full(): String = API_ENDPOINT + this.path
|
||||
fun endpoint(): String = this.path
|
||||
}
|
||||
Reference in New Issue
Block a user