package net.quedex.marketmaker; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import java.math.BigDecimal; import static com.google.common.base.Preconditions.checkArgument; public class MarketMakerConfiguration { private final int timeSleepSeconds; private final int maxBatchSize; private final BigDecimal futuresSpreadFraction; private final double fairVolatility; private final double volatilitySpreadFraction; private final int numLevels; private final int qtyOnLevel; private final double vegaLimit; private final double deltaLimit; public MarketMakerConfiguration(final int timeSleepSeconds, final int maxBatchSize, final BigDecimal futuresSpreadFraction, final double fairVolatility, final double volatilitySpreadFraction, final int numLevels, final int qtyOnLevel, final double deltaLimit, final double vegaLimit) { checkArgument(timeSleepSeconds > 0, "timeSleepSeconds=%s <= 0", timeSleepSeconds); checkArgument(maxBatchSize > 0, "maxBatchSize <= 0"); checkArgument(maxBatchSize <= 3000, "maxBatchSize > 3000"); checkArgument( futuresSpreadFraction.compareTo(BigDecimal.ZERO) > 0, "futuresSpreadFraction=%s <=0", futuresSpreadFraction ); checkArgument(fairVolatility > 0, "fairVolatility=%s <= 0", fairVolatility); checkArgument(volatilitySpreadFraction > 0, "volatilitySpreadFraction=%s <= 0", volatilitySpreadFraction); checkArgument(numLevels > 0, "numLevels=%s <= 0", numLevels); checkArgument(qtyOnLevel > 0, "qtyOnLevel=%s <= 0", qtyOnLevel); checkArgument(deltaLimit >= 0, "deltaLimit=%s < 0", deltaLimit); checkArgument(vegaLimit >= 0, "vegaLimit=%s < 0", vegaLimit); checkArgument( fairVolatility - numLevels * fairVolatility * volatilitySpreadFraction > 0, "Nonpositive lowest level volatility" ); this.timeSleepSeconds = timeSleepSeconds; this.maxBatchSize = maxBatchSize; this.futuresSpreadFraction = futuresSpreadFraction; this.fairVolatility = fairVolatility; this.volatilitySpreadFraction = volatilitySpreadFraction; this.vegaLimit = vegaLimit; this.numLevels = numLevels; this.qtyOnLevel = qtyOnLevel; this.deltaLimit = deltaLimit; } public static MarketMakerConfiguration fromPropertiesFile(final String fileName) throws ConfigurationException { final Configuration configuration = new PropertiesConfiguration(fileName); return new MarketMakerConfiguration( configuration.getInt(ConfigKey.TIME_SLEEP_SECONDS.getKey()), configuration.getInt(ConfigKey.MAX_BATCH_SIZE.getKey()), new BigDecimal(configuration.getString(ConfigKey.SPREAD_FRACTION.getKey())), configuration.getDouble(ConfigKey.FAIR_VOLATILITY.getKey()), configuration.getDouble(ConfigKey.VOLATILITY_SPREAD_FRACTION.getKey()), configuration.getInt(ConfigKey.NUM_LEVELS.getKey()), configuration.getInt(ConfigKey.QUANTITY_ON_LEVEL.getKey()), configuration.getDouble(ConfigKey.DELTA_LIMIT.getKey()), configuration.getDouble(ConfigKey.VEGA_LIMIT.getKey()) ); } public int getTimeSleepSeconds() { return timeSleepSeconds; } public int getMaxBatchSize() { return maxBatchSize; } public BigDecimal getFuturesSpreadFraction() { return futuresSpreadFraction; } public double getFairVolatility() { return fairVolatility; } public double getVolatilitySpreadFraction() { return volatilitySpreadFraction; } public double getVegaLimit() { return vegaLimit; } public int getNumLevels() { return numLevels; } public int getQtyOnLevel() { return qtyOnLevel; } public double getDeltaLimit() { return deltaLimit; } private enum ConfigKey { TIME_SLEEP_SECONDS("timeSleepSeconds"), MAX_BATCH_SIZE("maxBatchSize"), SPREAD_FRACTION("futuresSpreadFraction"), FAIR_VOLATILITY("fairVolatility"), VOLATILITY_SPREAD_FRACTION("volatilitySpreadFraction"), NUM_LEVELS("numLevels"), QUANTITY_ON_LEVEL("quantityOnLevel"), VEGA_LIMIT("vegaLimit"), DELTA_LIMIT("deltaLimit"); private static final String COMMON_PREFIX = "net.quedex.marketmaker"; private static final char SEPARATOR = '.'; public static String getCommonPrefix() { return COMMON_PREFIX; } private final String keyFragment; ConfigKey(final String keyFragment) { this.keyFragment = keyFragment; } public String getKey() { return COMMON_PREFIX + SEPARATOR + keyFragment; } } }