// Copyright 2015 Ivan Popivanov // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package net.tradelib.core; import java.math.BigDecimal; import java.util.Currency; import java.util.Objects; public class Instrument { public enum Type { NONE, FUTURE, INDEX, STOCK, FOREX } private final Type type; private final String symbol; private final BigDecimal tick; private final BigDecimal bpv; private String name; private final Currency currency; public boolean equals(Object o) { if(this == o) return true; if(o == null) return false; if(this.getClass() != o.getClass()) return false; final Instrument ii = (Instrument)o; if(type != ii.type) return false; if(isFuture()) { // If the tick, or the bpv, of either object is ZERO, // we consider them equal according to this criteria. // This approach allows us to lookup a future using // a subset of the information. if(tick.compareTo(BigDecimal.ZERO) != 0 && ii.tick.compareTo(BigDecimal.ZERO) != 0 && tick.compareTo(ii.tick) != 0) { return false; } if(bpv.compareTo(BigDecimal.ZERO) != 0 && ii.bpv.compareTo(BigDecimal.ZERO) != 0 && bpv.compareTo(ii.bpv) != 0) { return false; } } return true; } public int hashCode() { return Objects.hash(type, symbol, tick, bpv, name); } private Instrument(Type type, String symbol, BigDecimal tick, BigDecimal bpv, String name) { this(type, symbol, tick, bpv, name, Currency.getInstance("USD")); } private Instrument(Type type, String symbol, BigDecimal tick, BigDecimal bpv, String name, String currency) { this(type, symbol, tick, bpv, name, Currency.getInstance(currency)); } private Instrument(Type type, String symbol, BigDecimal tick, BigDecimal bpv, String name, Currency currency) { this.type = type; this.symbol = symbol; this.tick = tick; this.bpv = bpv; if(name != null && name.length() > 0) this.name = name; else this.name = null; this.currency = currency; } public static Instrument makeFuture(String symbol, BigDecimal tick, BigDecimal bpv) { return new Instrument(Type.FUTURE, symbol, tick, bpv, ""); } public static Instrument makeFuture(String symbol) { return new Instrument(Type.FUTURE, symbol, BigDecimal.ZERO, BigDecimal.ZERO, ""); } public static Instrument makeFuture(String symbol, BigDecimal tick, BigDecimal bpv, String name) { return new Instrument(Type.FUTURE, symbol, tick, bpv, name); } public static Instrument makeStock(String symbol) { return new Instrument(Type.STOCK, symbol, BigDecimal.valueOf(0.01), BigDecimal.valueOf(1.0), ""); } public static Instrument makeIndex(String symbol) { return new Instrument(Type.INDEX, symbol, BigDecimal.valueOf(0.01), BigDecimal.valueOf(1.0), ""); } public static Instrument makeForex(String symbol) { return new Instrument(Type.FOREX, symbol, BigDecimal.valueOf(0.0001), BigDecimal.valueOf(1.0), ""); } public static Instrument makeForex(String symbol, String currency) { return new Instrument(Type.FOREX, symbol, BigDecimal.valueOf(0.0001), BigDecimal.valueOf(1.0), "", currency); } public static Instrument makeForex(String symbol, BigDecimal tick, String currency) { return new Instrument(Type.FOREX, symbol, tick, BigDecimal.valueOf(1.0), "", currency); } public static Instrument makeForex(String symbol, BigDecimal tick) { return new Instrument(Type.FOREX, symbol, tick, BigDecimal.valueOf(1.0), ""); } public static Instrument make(Type type, String symbol) { Instrument result = null; switch(type) { case FUTURE: result = makeFuture(symbol); break; case INDEX: result = makeIndex(symbol); break; case STOCK: result = makeStock(symbol); break; case FOREX: result = makeForex(symbol); break; } return result; } public double getTick() { return tick.doubleValue(); } public BigDecimal getTickPrecise() { return tick; } public double getBpv() { return bpv.doubleValue(); } public BigDecimal getBpvPrecise() { return bpv; } public String getSymbol() { return symbol; } public String getName() { return name; } public void setName(String s) { this.name = s; } public Currency getCurrency() { return currency; } public Currency getCounterCurrency() { return getCurrency(); } public Currency getQuoteCurrenty() { return getCurrency(); } public Currency getBaseCurrency() { if(!isForex() || name.length() != 6) return null; return Currency.getInstance(name.substring(0, 3)); } public Type getType() { return type; } public boolean isFuture() { return getType() == Type.FUTURE; } public boolean isStock() { return getType() == Type.STOCK; } public boolean isIndex() { return getType() == Type.INDEX; } public boolean isForex() { return getType() == Type.FOREX; } public double tickCeil(double value) { return Math.ceil(value/getTick())*getTick(); } public double tickFloor(double value) { return Math.floor(value/getTick())*getTick(); } }