Skip to content

Commit 92f378f

Browse files
committed
stockbroker: positions support added
1 parent 96d6b19 commit 92f378f

16 files changed

+371
-33
lines changed

src/com/lld/stockbroker/Main.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,18 @@ private static void test1() throws ExchangeException, PortfolioException {
2020
Sector sector2 = new Sector(SectorType.IT);
2121
Sector sector3 = new Sector(SectorType.HEALTH_CARE);
2222

23-
CompanyTicker companyTicker1 = new CompanyTicker("HDFCBANK");
23+
Exchange nseExchange = new Exchange("NSE");
24+
Exchange nasdaqExchange = new Exchange("NSE");
25+
26+
CompanyTicker companyTicker1 = new CompanyTicker("HDFCBANK", nseExchange);
2427
Company company1 = new Company("HDFC Bank", sector1, companyTicker1);
2528
exchangeService.registerCompany(company1);
2629

27-
CompanyTicker companyTicker2 = new CompanyTicker("MSFT");
30+
CompanyTicker companyTicker2 = new CompanyTicker("MSFT", nasdaqExchange);
2831
Company company2 = new Company("Microsoft", sector2, companyTicker2);
2932
exchangeService.registerCompany(company2);
3033

31-
CompanyTicker companyTicker3 = new CompanyTicker("APOLLO");
34+
CompanyTicker companyTicker3 = new CompanyTicker("APOLLO", nseExchange);
3235
Company company3 = new Company("Apollo", sector3, companyTicker3);
3336
exchangeService.registerCompany(company3);
3437

@@ -50,6 +53,25 @@ private static void test1() throws ExchangeException, PortfolioException {
5053
AssetType.EQUITY); // TODO: Check BuyingStrategy
5154
Order order = portfolioService.buy(orderData, user);
5255
System.out.println("Order placed = " + order);
56+
System.out.println("Positions when the first BUY order is placed: " + portfolioService.getPositions(AssetType.EQUITY, user));
57+
58+
System.out.println("Repeating the same order but with more quantity");
59+
orderData = new OrderData(company1,
60+
new MarketOrderStrategy(
61+
company1.getCompanyTicker().getLatestPrice().getAmount() * 5, 5),
62+
AssetType.EQUITY); // TODO: Check BuyingStrategy
63+
order = portfolioService.buy(orderData, user);
64+
System.out.println("Order placed = " + order);
65+
System.out.println("Positions when the second BUY order is placed: " + portfolioService.getPositions(AssetType.EQUITY, user));
66+
67+
System.out.println("Executing a SELL");
68+
orderData = new OrderData(company1,
69+
new MarketOrderStrategy(
70+
company1.getCompanyTicker().getLatestPrice().getAmount() * 2, 2),
71+
AssetType.EQUITY); // TODO: Check BuyingStrategy
72+
order = portfolioService.sell(orderData, user);
73+
System.out.println("Order placed = " + order);
74+
System.out.println("Positions when the first SELL order is placed: " + portfolioService.getPositions(AssetType.EQUITY, user));
5375

5476
System.out.println("Holdings when order not executed yet: " + portfolioService.getHoldings(AssetType.EQUITY, user));
5577

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.lld.stockbroker.constant;
2+
3+
public enum OrderType {
4+
BUY("BUY"),
5+
SELL("SELL");
6+
7+
private String type;
8+
OrderType(String type) {
9+
this.type = type;
10+
}
11+
12+
public String getType() {
13+
return type;
14+
}
15+
}
Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,82 @@
11
package com.lld.stockbroker.model;
22

3-
import java.util.ArrayList;
4-
import java.util.Arrays;
5-
import java.util.List;
3+
import com.lld.stockbroker.exception.NotImplementedException;
4+
5+
import java.util.*;
66

77
public class AnyHolding implements Holding {
88
private Double investedAmount;
99
private Double currentAmount;
1010
private Double absolutePnL;
1111
private Double absolutePnLChangePercentage;
12-
private List<Entry> entries;
12+
private Map<String, Entry> entries;
1313

1414
public AnyHolding() {
15-
this.entries = new ArrayList<>();
15+
this.entries = new HashMap<>();
1616
}
1717

1818
@Override
1919
public Double getInvestedAmount() {
20-
return null;
20+
return this.investedAmount;
2121
}
2222

2323
@Override
2424
public Double getCurrentTotalAmount() {
25+
// To be calculated from the current ticker amount
2526
return null;
2627
}
2728

2829
@Override
2930
public AmountChange getAbsolutePnL() {
31+
// To be calculated from the current ticker amount
3032
return null;
3133
}
3234

3335
@Override
3436
public AmountChange getPnLChangePercentage() {
37+
// To be calculated from the current ticker amount
3538
return null;
3639
}
3740

3841
@Override
3942
public List<Entry> getEntries() {
40-
return null;
43+
return this.entries.values().stream().toList();
4144
}
4245

4346
@Override
44-
public void addEntry(Entry entry) {
45-
this.entries.add(entry);
47+
public void addEntry(Entry entry) throws NotImplementedException {
48+
String symbol = entry.getCompany().getCompanyTicker().getStockSymbol();
49+
if (!this.entries.containsKey(symbol)) {
50+
this.entries.put(symbol, entry);
51+
} else {
52+
EquityHoldingEntry existingEntry = (EquityHoldingEntry) this.entries.get(symbol);
53+
EquityHoldingEntry newEntry = existingEntry.union((EquityHoldingEntry) entry);
54+
this.entries.put(symbol, newEntry);
55+
}
56+
57+
calculateInvestmentData();
58+
}
59+
60+
private void calculateInvestmentData() throws NotImplementedException {
61+
Double investedAmount = 0D;
62+
63+
for (String symbol: this.entries.keySet()) {
64+
investedAmount += this.entries.get(symbol).getTotalInvestedAmount();
65+
}
66+
67+
this.investedAmount = investedAmount;
4668
}
4769

4870
@Override
4971
public String toString() {
72+
List<Map.Entry<String, Entry>> printable = new ArrayList<>(this.entries.entrySet());
73+
5074
return "AnyHolding{" +
5175
"investedAmount=" + investedAmount +
5276
", currentAmount=" + currentAmount +
5377
", absolutePnL=" + absolutePnL +
5478
", absolutePnLChangePercentage=" + absolutePnLChangePercentage +
55-
", entries=" + Arrays.deepToString(entries.toArray()) +
79+
", entries=" + Arrays.deepToString(printable.toArray()) +
5680
'}';
5781
}
5882
}

src/com/lld/stockbroker/model/Company.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.lld.stockbroker.model;
22

3+
import java.util.Objects;
4+
35
public class Company {
46
private String name;
57
private Sector sector;
@@ -50,6 +52,18 @@ public void setCompanyGrowth(CompanyGrowth companyGrowth) {
5052
this.companyGrowth = companyGrowth;
5153
}
5254

55+
@Override
56+
public boolean equals(Object o) {
57+
if (this == o) return true;
58+
if (!(o instanceof Company company)) return false;
59+
return Objects.equals(getSector(), company.getSector()) && Objects.equals(getCompanyTicker(), company.getCompanyTicker());
60+
}
61+
62+
@Override
63+
public int hashCode() {
64+
return Objects.hash(getSector(), getCompanyTicker());
65+
}
66+
5367
@Override
5468
public String toString() {
5569
return "Company{" +

src/com/lld/stockbroker/model/CompanyTicker.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
package com.lld.stockbroker.model;
22

3+
import java.util.Objects;
4+
35
public class CompanyTicker implements Ticker {
46
private String stockSymbol;
57
private Money latestPrice;
68
private Exchange sourceExchange;
79
private Double fiftyTwoWeeksLow;
810
private Double getFiftyTwoWeeksHigh;
911

10-
public CompanyTicker(String symbol) {
12+
public CompanyTicker(String symbol, Exchange exchange) {
1113
this.stockSymbol = symbol;
14+
this.sourceExchange = exchange;
1215
}
1316

1417
public String getStockSymbol() {
@@ -36,6 +39,18 @@ public void feedValue(Money amount) {
3639
this.latestPrice = amount;
3740
}
3841

42+
@Override
43+
public boolean equals(Object o) {
44+
if (this == o) return true;
45+
if (!(o instanceof CompanyTicker that)) return false;
46+
return Objects.equals(getStockSymbol(), that.getStockSymbol()) && Objects.equals(getSourceExchange(), that.getSourceExchange());
47+
}
48+
49+
@Override
50+
public int hashCode() {
51+
return Objects.hash(getStockSymbol(), getSourceExchange());
52+
}
53+
3954
@Override
4055
public String toString() {
4156
return "CompanyTicker{" +

src/com/lld/stockbroker/model/EquityHoldingEntry.java

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.lld.stockbroker.model;
22

3+
import java.util.Objects;
4+
35
public class EquityHoldingEntry implements Entry {
46
private Company company;
57
private Integer quantity;
@@ -16,6 +18,13 @@ public EquityHoldingEntry(Company company, Integer quantity, Double investedAmou
1618
this.investedAmount = investedAmount;
1719
}
1820

21+
public EquityHoldingEntry union(EquityHoldingEntry other) {
22+
this.quantity += other.quantity;
23+
this.investedAmount += other.investedAmount;
24+
this.averagePrice = this.investedAmount / this.quantity;
25+
return this;
26+
}
27+
1928
@Override
2029
public Company getCompany() {
2130
return this.company;
@@ -46,15 +55,27 @@ public AmountChange getPercentageAmountChange() {
4655
return null;
4756
}
4857

58+
@Override
59+
public boolean equals(Object o) {
60+
if (this == o) return true;
61+
if (!(o instanceof EquityHoldingEntry that)) return false;
62+
return Objects.equals(getCompany(), that.getCompany());
63+
}
64+
65+
@Override
66+
public int hashCode() {
67+
return Objects.hash(getCompany());
68+
}
69+
4970
@Override
5071
public String toString() {
5172
return "EquityPortfolioEntry{" +
52-
"company=" + company +
53-
", quantity=" + quantity +
54-
", averagePrice=" + averagePrice +
55-
", investedAmount=" + investedAmount +
56-
", absoluteAmountChange=" + absoluteAmountChange +
57-
", absoluteChangePercentage=" + absoluteChangePercentage +
73+
"company=" + getCompany() +
74+
", quantity=" + getQuantity() +
75+
", averagePrice=" + getAveragePrice() +
76+
", investedAmount=" + getTotalInvestedAmount() +
77+
", absoluteAmountChange=" + getAbsoluteAmountChange() +
78+
", absoluteChangePercentage=" + getPercentageAmountChange() +
5879
'}';
5980
}
6081
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.lld.stockbroker.model;
2+
3+
public class EquityPositionEntry implements Entry {
4+
private Company company;
5+
private Integer quantity;
6+
private Double averagePrice;
7+
private Double investedAmount;
8+
9+
// Dynamic data
10+
private Double absoluteAmountChange;
11+
private Double absoluteChangePercentage;
12+
13+
public EquityPositionEntry(Company company, Integer quantity, Double investedAmount) {
14+
this.company = company;
15+
this.quantity = quantity;
16+
this.investedAmount = investedAmount;
17+
}
18+
19+
public EquityPositionEntry union(EquityPositionEntry otherEntry) {
20+
if (otherEntry != null) {
21+
this.investedAmount += otherEntry.investedAmount;
22+
this.quantity += otherEntry.quantity;
23+
this.averagePrice = this.investedAmount / this.quantity;
24+
}
25+
26+
return this;
27+
}
28+
29+
@Override
30+
public Company getCompany() {
31+
return this.company;
32+
}
33+
34+
@Override
35+
public Integer getQuantity() {
36+
return this.quantity;
37+
}
38+
39+
@Override
40+
public Double getAveragePrice() {
41+
return this.investedAmount / this.quantity;
42+
}
43+
44+
@Override
45+
public Double getTotalInvestedAmount() {
46+
return this.investedAmount;
47+
}
48+
49+
@Override
50+
public AmountChange getAbsoluteAmountChange() {
51+
return null;
52+
}
53+
54+
@Override
55+
public AmountChange getPercentageAmountChange() {
56+
return null;
57+
}
58+
59+
@Override
60+
public String toString() {
61+
return "EquityPortfolioEntry{" +
62+
"company=" + getCompany() +
63+
", quantity=" + getQuantity() +
64+
", averagePrice=" + getAveragePrice() +
65+
", investedAmount=" + getTotalInvestedAmount() +
66+
", absoluteAmountChange=" + getAbsoluteAmountChange() +
67+
", absoluteChangePercentage=" + getPercentageAmountChange() +
68+
'}';
69+
}
70+
}

src/com/lld/stockbroker/model/Exchange.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.lld.stockbroker.model;
22

3+
import java.util.Objects;
4+
35
public class Exchange {
46
private String name;
57

@@ -10,4 +12,23 @@ public Exchange(String name) {
1012
public String getName() {
1113
return name;
1214
}
15+
16+
@Override
17+
public boolean equals(Object o) {
18+
if (this == o) return true;
19+
if (!(o instanceof Exchange exchange)) return false;
20+
return Objects.equals(getName(), exchange.getName());
21+
}
22+
23+
@Override
24+
public int hashCode() {
25+
return Objects.hash(getName());
26+
}
27+
28+
@Override
29+
public String toString() {
30+
return "Exchange{" +
31+
"name='" + name + '\'' +
32+
'}';
33+
}
1334
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.lld.stockbroker.model;
22

3+
import com.lld.stockbroker.exception.NotImplementedException;
4+
35
import java.util.List;
46

57
public interface Holding {
@@ -8,5 +10,5 @@ public interface Holding {
810
AmountChange getAbsolutePnL();
911
AmountChange getPnLChangePercentage();
1012
List<Entry> getEntries();
11-
void addEntry(Entry entry);
13+
void addEntry(Entry entry) throws NotImplementedException;
1214
}

0 commit comments

Comments
 (0)