summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--service/src/main/java/market/guess/service/LocalGuessMarketContext.java3
-rw-r--r--service/src/main/java/market/guess/service/domain/Account.java31
-rw-r--r--service/src/main/java/market/guess/service/domain/AccountType.java6
-rw-r--r--service/src/main/java/market/guess/service/domain/Event.java44
-rw-r--r--service/src/main/java/market/guess/service/domain/LedgerEntry.java7
-rw-r--r--service/src/main/java/market/guess/service/domain/User.java2
6 files changed, 67 insertions, 26 deletions
diff --git a/service/src/main/java/market/guess/service/LocalGuessMarketContext.java b/service/src/main/java/market/guess/service/LocalGuessMarketContext.java
index a01d6d7..67e263f 100644
--- a/service/src/main/java/market/guess/service/LocalGuessMarketContext.java
+++ b/service/src/main/java/market/guess/service/LocalGuessMarketContext.java
@@ -9,6 +9,7 @@ import market.guess.api.GuessMarketContext;
9import market.guess.api.LoadResultDTO; 9import market.guess.api.LoadResultDTO;
10import market.guess.api.PurchaseReceiptDTO; 10import market.guess.api.PurchaseReceiptDTO;
11import market.guess.exception.GuessMarketException; 11import market.guess.exception.GuessMarketException;
12import market.guess.service.domain.Event;
12import market.guess.service.repository.EventRepository; 13import market.guess.service.repository.EventRepository;
13 14
14public final class LocalGuessMarketContext implements GuessMarketContext { 15public final class LocalGuessMarketContext implements GuessMarketContext {
@@ -26,7 +27,7 @@ public final class LocalGuessMarketContext implements GuessMarketContext {
26 27
27 @Override 28 @Override
28 public List<EventSummaryDTO> listEvents() { 29 public List<EventSummaryDTO> listEvents() {
29 throw new UnsupportedOperationException("Unimplemented method 'listEvents'"); 30 return eventRepository.getAllEvents().stream().map(Event::toEventSummary).toList();
30 } 31 }
31 32
32 @Override 33 @Override
diff --git a/service/src/main/java/market/guess/service/domain/Account.java b/service/src/main/java/market/guess/service/domain/Account.java
index 274260e..7e24cdb 100644
--- a/service/src/main/java/market/guess/service/domain/Account.java
+++ b/service/src/main/java/market/guess/service/domain/Account.java
@@ -4,28 +4,47 @@ import java.math.BigDecimal;
4import java.time.Clock; 4import java.time.Clock;
5import java.util.ArrayList; 5import java.util.ArrayList;
6import java.util.List; 6import java.util.List;
7import java.util.concurrent.atomic.AtomicInteger;
8import market.guess.api.LedgerType;
7 9
8public final class Account { 10public final class Account {
9
10 private final AccountType accountType;
11 private final String owner; 11 private final String owner;
12 private final Clock clock; 12 private final Clock clock;
13 private final List<LedgerEntry> entries = new ArrayList<>(); 13 private final List<LedgerEntry> entries = new ArrayList<>();
14 private BigDecimal balance; 14 private BigDecimal balance;
15 private AtomicInteger runningId = new AtomicInteger();
15 16
16 public Account(AccountType accountType, String owner, BigDecimal initialBalance) { 17 public Account(String owner, BigDecimal initialBalance) {
17 this(accountType, owner, initialBalance, Clock.systemUTC()); 18 this(owner, initialBalance, Clock.systemUTC());
18 } 19 }
19 20
20 public Account(AccountType accountType, String owner, BigDecimal initialBalance, Clock clock) { 21 public Account(String owner, BigDecimal initialBalance, Clock clock) {
21 super(); 22 super();
22 this.accountType = accountType;
23 this.owner = owner; 23 this.owner = owner;
24 this.balance = BigDecimalOptions.toMoney(initialBalance); 24 this.balance = BigDecimalOptions.toMoney(initialBalance);
25 this.clock = clock; 25 this.clock = clock;
26 } 26 }
27 27
28 public String getOwner() {
29 return owner;
30 }
31
28 public BigDecimal getBalance() { 32 public BigDecimal getBalance() {
29 return balance; 33 return balance;
30 } 34 }
35
36 public boolean credit(LedgerType type, BigDecimal amount, String note) {
37 record(type, amount, note);
38 return true;
39 }
40
41 public boolean debit(LedgerType type, BigDecimal amount, String note) {
42 record(type, amount.negate(), note);
43 return true;
44 }
45
46 private void record(LedgerType type, BigDecimal amount, String note) {
47 entries.add(
48 new LedgerEntry(runningId.incrementAndGet(), clock.instant(), type, amount, balance, note));
49 }
31} 50}
diff --git a/service/src/main/java/market/guess/service/domain/AccountType.java b/service/src/main/java/market/guess/service/domain/AccountType.java
deleted file mode 100644
index 293ff4e..0000000
--- a/service/src/main/java/market/guess/service/domain/AccountType.java
+++ /dev/null
@@ -1,6 +0,0 @@
1package market.guess.service.domain;
2
3public enum AccountType {
4 EVENT,
5 USER
6}
diff --git a/service/src/main/java/market/guess/service/domain/Event.java b/service/src/main/java/market/guess/service/domain/Event.java
index 383126f..2d7ac39 100644
--- a/service/src/main/java/market/guess/service/domain/Event.java
+++ b/service/src/main/java/market/guess/service/domain/Event.java
@@ -1,8 +1,10 @@
1package market.guess.service.domain; 1package market.guess.service.domain;
2 2
3import java.math.BigDecimal; 3import java.math.BigDecimal;
4import java.time.Instant;
4import java.util.ArrayList; 5import java.util.ArrayList;
5import java.util.List; 6import java.util.List;
7import java.util.concurrent.atomic.AtomicInteger;
6import market.guess.api.CommissionTiming; 8import market.guess.api.CommissionTiming;
7import market.guess.api.EventStatus; 9import market.guess.api.EventStatus;
8import market.guess.api.EventSummaryDTO; 10import market.guess.api.EventSummaryDTO;
@@ -20,10 +22,10 @@ public final class Event {
20 private final Account account; 22 private final Account account;
21 private final String marketMaker; 23 private final String marketMaker;
22 24
25 private final AtomicInteger runningId = new AtomicInteger();
23 private final List<Trade> trades = new ArrayList<>(); 26 private final List<Trade> trades = new ArrayList<>();
24 private EventStatus status; 27 private EventStatus status;
25 private String winningOptionKey; 28 private String winningOptionKey;
26 private long nextTradeSeq = 1;
27 private BigDecimal settlementCommission = BigDecimalOptions.ZERO_MONEY; 29 private BigDecimal settlementCommission = BigDecimalOptions.ZERO_MONEY;
28 30
29 public Event( 31 public Event(
@@ -46,7 +48,7 @@ public final class Event {
46 this.mechanism = mechanism; 48 this.mechanism = mechanism;
47 this.options = List.copyOf(options); 49 this.options = List.copyOf(options);
48 this.marketMaker = marketMaker; 50 this.marketMaker = marketMaker;
49 this.account = new Account(AccountType.EVENT, eventKey, BigDecimalOptions.ZERO_MONEY); 51 this.account = new Account(eventKey, BigDecimalOptions.ZERO_MONEY);
50 this.status = status; 52 this.status = status;
51 } 53 }
52 54
@@ -114,20 +116,40 @@ public final class Event {
114 this.winningOptionKey = winningOptionKey; 116 this.winningOptionKey = winningOptionKey;
115 } 117 }
116 118
117 public long getNextTradeSeq() { 119 public Trade recordTrade(
118 return nextTradeSeq; 120 Instant time,
119 } 121 String user,
122 Option option,
123 int quantity,
124 BigDecimal cost,
125 BigDecimal commission) {
126 var trade =
127 new Trade(
128 runningId.incrementAndGet(),
129 time,
130 user,
131 option.getKey(),
132 option.getName(),
133 quantity,
134 cost,
135 commission);
136 trades.add(trade);
120 137
121 public void setNextTradeSeq(long nextTradeSeq) { 138 return trade;
122 this.nextTradeSeq = nextTradeSeq;
123 } 139 }
124 140
125 public BigDecimal getSettlementCommission() { 141 public BigDecimal tradeVolumeOf(String option) {
126 return settlementCommission; 142 return trades.stream()
143 .filter(trade -> trade.optionKey().equalsIgnoreCase(option))
144 .map(Trade::sharesCost)
145 .reduce(BigDecimalOptions.ZERO_MONEY, BigDecimal::add);
127 } 146 }
128 147
129 public void setSettlementCommission(BigDecimal settlementCommission) { 148 public BigDecimal getCommission() {
130 this.settlementCommission = settlementCommission; 149 return trades.stream()
150 .map(Trade::commission)
151 .reduce(BigDecimalOptions.ZERO_MONEY, BigDecimal::add)
152 .add(settlementCommission);
131 } 153 }
132 154
133 public EventSummaryDTO toEventSummary() { 155 public EventSummaryDTO toEventSummary() {
diff --git a/service/src/main/java/market/guess/service/domain/LedgerEntry.java b/service/src/main/java/market/guess/service/domain/LedgerEntry.java
index b9173c8..4ca4b92 100644
--- a/service/src/main/java/market/guess/service/domain/LedgerEntry.java
+++ b/service/src/main/java/market/guess/service/domain/LedgerEntry.java
@@ -5,4 +5,9 @@ import java.time.Instant;
5import market.guess.api.LedgerType; 5import market.guess.api.LedgerType;
6 6
7public record LedgerEntry( 7public record LedgerEntry(
8 Instant time, LedgerType type, BigDecimal amount, BigDecimal balanceAfter, String note) {} 8 int id,
9 Instant time,
10 LedgerType type,
11 BigDecimal amount,
12 BigDecimal balanceAfter,
13 String note) {}
diff --git a/service/src/main/java/market/guess/service/domain/User.java b/service/src/main/java/market/guess/service/domain/User.java
index 3ae1d0f..af9ac78 100644
--- a/service/src/main/java/market/guess/service/domain/User.java
+++ b/service/src/main/java/market/guess/service/domain/User.java
@@ -8,7 +8,7 @@ public final class User {
8 8
9 public User(String name, BigDecimal initialBalance) { 9 public User(String name, BigDecimal initialBalance) {
10 this.name = name; 10 this.name = name;
11 this.account = new Account(AccountType.USER, name, initialBalance); 11 this.account = new Account(name, initialBalance);
12 } 12 }
13 13
14 public String getName() { 14 public String getName() {