public class Transaction {
private String externalTransactionID;
private String clientId;
private String securityId;
private Integer transactionType;
private java.util.Date transactionDate;
private Double marketValue;
private Boolean priority;
private Double transactionFees;
//getter, setter left for brevity
}
Sapient Fee Calculator: Coding problem in Java
Upasana | May 21, 2019 | 3 min read | 5,267 views | sapient interviews
Problem statement
Sapient has won the contract to implement processing fee calculator for a major investment bank (henceforth referred as client). Client receives transactions from various external sources. These transactions are received in a pre-configured format, for example, csv, excel, xml or a simple pipe delimited format text file placed at a file location. The client needs to calculate the processing fee for each transaction based on some criteria. Design a program for this scenario.
Github Source code
You can clone github repository for the accompanied source code:
Caveats with the current solution
Many important things are missing in the current solution:
-
Testcase are very important, they are not included yet. You need to invest sometime writing the testcases.
-
Implementation is only provided for CSV reader, not for xml/xls reader, which can be added later on.
Solution
There are two critical components in this coding problem:
-
Designing a generic reader for transactions that can read from CSV/JSON/XLS/XML file format. Strategy design pattern can be used in this case, where depending upon the file format we can choose the reader.
-
Designing the Fee Calculator. Fee calculator logic involves certain criteria like
-
Is transaction an intra-day transaction
-
Is transaction a Buy or Sell
-
etc.
current logic is very simple, but there is a scope to implement it using proper design pattern.
-
Creating a Model
We will create a transaction model that maps all attributes of transaction.
Generic Reader for reading transactions
Java 8 provides support for Functional interfaces (Conceptually, a functional interface has exactly one abstract method), we will create a Functional Interface for reading Transactions from a file format. We are providing three implementations for txt, excel and xml file format in form of lamda functions. Also we are providing a static factory method to read a given file and load all transactions into a list.
@FunctionalInterface
public interface TransactionReader {
List<Transaction> read(String filePath) throws IOException;
static List<Transaction> readFile(FILE_TYPE fileType, String filePath) throws IOException {
switch (fileType) {
case CSV:
return csvTrxReader().read(filePath);
case TEXT:
return textTrxReader().read(filePath);
case XML:
return xmlTrxReader().read(filePath);
default:
return null;
}
}
static TransactionReader textTrxReader() {
return transactionFile -> {
List<Transaction> list = new ArrayList<>();
String line = "";
String cvsSplitBy = ",";
try (BufferedReader br = new BufferedReader(new InputStreamReader(TransactionReader.class.getClassLoader().getResourceAsStream(transactionFile)));) {
while ((line = br.readLine()) != null) {
String[] transactionAttributes = line.split(cvsSplitBy);
Transaction transaction = Utils.getTransaction(transactionAttributes);
list.add(transaction);
}
return list;
}
};
}
static TransactionReader xmlTrxReader() {
throw new RuntimeException("not yet implemented");
}
static TransactionReader csvTrxReader() {
throw new RuntimeException("not yet implemented");
}
}
FeeCalculator logic
Fee calculator logic calculates the applicable fee for each transaction.
public class FeeCalculator {
private List<Transaction> transactionList = new ArrayList<>();
public void addTransaction(Transaction transaction) {
transactionList.add(calculateFee(transaction));
}
public void addTransaction(List<Transaction> transactions) {
transactions.forEach(this::addTransaction);
}
private Transaction calculateFee(Transaction transaction) {
if (isIntradayTransaction(transaction)) {
transaction.setTransactionFees(Constant.TRANSACTION_FEE.TEN.getFees());
} else {
if (transaction.getPriority()) {
transaction.setTransactionFees(Constant.TRANSACTION_FEE.FIVE_HUNDRED.getFees());
} else {
if (transaction.getTransactionType() == Constant.TRANSACTION_TYPE.SELL.getType() ||
transaction.getTransactionType() == Constant.TRANSACTION_TYPE.WITHDRAW.getType()) {
transaction.setTransactionFees(Constant.TRANSACTION_FEE.HUNDRED.getFees());
} else if (transaction.getTransactionType() == Constant.TRANSACTION_TYPE.BUY.getType() ||
transaction.getTransactionType() == Constant.TRANSACTION_TYPE.DEPOSIT.getType()) {
transaction.setTransactionFees(Constant.TRANSACTION_FEE.FIFTY.getFees());
}
}
}
return transaction;
}
private boolean isIntradayTransaction(Transaction other) {
boolean isIntraDayTransaction = false;
if (transactionList.size() > 0) {
for (Transaction transaction : transactionList) {
if (transaction.getClientId().equals(other.getClientId()) &&
transaction.getSecurityId().equals(other.getSecurityId()) &&
transaction.getTransactionDate().equals(other.getTransactionDate())) {
if ((transaction.getTransactionType() == Constant.TRANSACTION_TYPE.BUY.getType() &&
other.getTransactionType() == Constant.TRANSACTION_TYPE.SELL.getType()) ||
(transaction.getTransactionType() == Constant.TRANSACTION_TYPE.SELL.getType() &&
other.getTransactionType() == Constant.TRANSACTION_TYPE.BUY.getType())) {
isIntraDayTransaction = true;
transaction.setTransactionFees(Constant.TRANSACTION_FEE.TEN.getFees());
break;
}
}
}
}
return isIntraDayTransaction;
}
}
Sorting of transactions
We need to sort the results based on clientId, transactionType, transactionDate and priority. We will use Java 8 feature to do the same.
public void displayTransactionReport() {
transactionList.sort(Comparator.comparing(Transaction::getClientId)
.thenComparing(Transaction::getTransactionType)
.thenComparing(Transaction::getTransactionDate)
.thenComparing(Transaction::getPriority));
...rest of the logic to display the trxs
}
That’s all for now.
sapient interviews:
- Sapient Global Markets important topics in Java
- Sapient - Coding Exercise for Designing Smart Card System for Delhi Metro
- Sapient Global Market Java Interview Questions and Coding Exercise
Top articles in this category:
- Sapient Global Market Java Interview Questions and Coding Exercise
- Multi-threading Java Interview Questions for Investment Bank
- Goldman Sachs Java Interview Questions
- RBS Java Programming Interview Questions
- ION Trading Java Interview Questions
- Cracking core java interviews - question bank
- Sapient Global Markets important topics in Java