package net.gouline.riskybusiness;
import net.gouline.riskybusiness.data.ParsableParser;
import net.gouline.riskybusiness.model.Customer;
import net.gouline.riskybusiness.model.SettledBet;
import net.gouline.riskybusiness.model.UnsettledBet;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Evaluator of risk for bets.
*
* @author Mike Gouline
*/
public class RiskEvaluator {
public enum RiskType {
SUCCESS_RATE,
STAKE_AVERAGE,
STAKE_AVERAGE_HIGH,
STAKE_AMOUNT
}
private ParsableParser<SettledBet> settledBetParser;
private ParsableParser<UnsettledBet> unsettledBetParser;
public RiskEvaluator() {
settledBetParser = new ParsableParser<SettledBet>() {
@Override
protected SettledBet newInstance() {
return new SettledBet();
}
};
unsettledBetParser = new ParsableParser<UnsettledBet>() {
@Override
protected UnsettledBet newInstance() {
return new UnsettledBet();
}
};
}
public List<UnsettledBet> evaluate(String settledFilename, String unsettledFilename) throws IOException {
return evaluate(new FileReader(settledFilename), new FileReader(unsettledFilename));
}
/**
* Evaluates settled bets and assigns risk to unsettled bets.
*
* @param settledReader Reader of settled CSV data.
* @param unsettledReader Reader of unsettled CSV data.
* @return List of unsettled bets with risk assignment.
* @throws IOException
*/
public List<UnsettledBet> evaluate(Reader settledReader, Reader unsettledReader) throws IOException {
Map<Long, Customer> customers = new HashMap<Long, Customer>();
List<SettledBet> settledBets = settledBetParser.parse(settledReader, true);
for (SettledBet settledBet : settledBets) {
getCustomer(customers, settledBet.getCustomerId()).addSettledBet(settledBet);
}
DecimalFormat decimalFormat = new DecimalFormat("#.##");
List<UnsettledBet> unsettledBets = unsettledBetParser.parse(unsettledReader, true);
for (UnsettledBet unsettledBet : unsettledBets) {
Customer customer = getCustomer(customers, unsettledBet.getCustomerId());
double successRate = customer.getSuccessRate();
if (successRate > 0.6) {
unsettledBet.addRisk(RiskType.SUCCESS_RATE,
"Success rate: " + decimalFormat.format(successRate * 100) + "%");
}
double averageStake = customer.getAverageStake();
double stakeRatio = unsettledBet.getStake() / averageStake;
if (stakeRatio > 10) {
RiskType type = RiskType.STAKE_AVERAGE;
if (stakeRatio > 30) {
type = RiskType.STAKE_AVERAGE_HIGH;
}
unsettledBet.addRisk(type,
"Stake is " + decimalFormat.format(stakeRatio) + " times higher than average");
}
double toWin = unsettledBet.getToWin();
if (toWin > 1000.0) {
unsettledBet.addRisk(RiskType.STAKE_AMOUNT,
"Stake: $" + decimalFormat.format(toWin));
}
}
return unsettledBets;
}
private static Customer getCustomer(Map<Long, Customer> customers, long id) {
Customer customer = customers.get(id);
if (customer == null) {
customer = new Customer(id);
customers.put(id, customer);
}
return customer;
}
}