/* * Copyright (c) 2012 Jeremy Goetsch * * 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 com.jgoetsch.eventtrader; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; import com.jgoetsch.tradeframework.Contract; /** * A {@link com.jgoetsch.eventtrader.Msg Msg} from which a signal to * buy or sell some instrument has been parsed. * * @author jgoetsch * */ public class TradeSignal extends Msg { private static final long serialVersionUID = 1L; public static final String TYPE_BUY = "BUY"; public static final String TYPE_SELL = "SELL"; public static final String TYPE_SHORT = "SHORT"; public static final String TYPE_COVER = "COVER"; private String type; private int numShares; private double price; private Contract contract; private boolean partial; public TradeSignal(Msg msg) { super(msg); if (msg instanceof TradeSignal) { TradeSignal other = (TradeSignal) msg; this.type = other.type; this.numShares = other.numShares; this.price = other.price; this.contract = other.contract; this.partial = other.partial; } } public TradeSignal() { } /** * Construct a TradeSignal for the given side and symbol. * * @param side String "BUY" or "SELL". * @param symbol Ticker symbol. * @param msg The ChatMsg that this TradeSignal was derived from for reference. */ public TradeSignal(String side, Contract contract, Msg msg) { super(msg); this.type = side; this.contract = contract; } public TradeSignal(String side, String symbol, Msg msg) { super(msg); this.type = side; this.contract = Contract.stock(symbol); } public TradeSignal(String type, Contract contract, int numShares, double price) { this(type, contract, numShares, price, null); } public TradeSignal(String type, Contract contract, int numShares, double price, Msg msg) { super(msg); this.type = type; this.contract = contract; this.numShares = numShares; this.price = price; } /** * Creates a list of TradeSignal objects of the given side from a whitespace * delimited list of symbols. * * @param side String "BUY" or "SELL". * @param symbols Whitespace delimited symbol string. * @param msg The ChatMsg that this TradeSignal was derived from for reference. * @return List of TradeSignal objects. */ public static List<TradeSignal> fromList(String side, String symbols, Msg msg) { List<TradeSignal> list = new ArrayList<TradeSignal>(); for (String symbol : symbols.split("\\s+")) { list.add(new TradeSignal(side, Contract.stock(symbol), msg)); } return list; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; TradeSignal other = (TradeSignal) obj; if (getType() == null || !getType().equals(other.getType())) return false; if (getNumShares() != other.getNumShares()) return false; if (getPrice() != other.getPrice()) return false; if (getContract() == null || !getContract().equals(other.getContract())) return false; return true; } public String toString() { return getTradeString() + ": " + super.toString(); } public String getTradeString() { StringBuilder sb = new StringBuilder(); if (getType() != null) sb.append(getType()); if (getNumShares() != 0) sb.append(" ").append(getNumShares()); if (getContract() != null) sb.append(" ").append(getContract()); if (getPrice() != 0) sb.append(" at ").append(DecimalFormat.getCurrencyInstance().format(getPrice())); return sb.toString(); } public boolean isBuy() { return TYPE_BUY.equalsIgnoreCase(type) || TYPE_COVER.equalsIgnoreCase(type); } public boolean isSell() { return TYPE_SELL.equalsIgnoreCase(type) || TYPE_SHORT.equalsIgnoreCase(type); } public boolean isExit() { return TYPE_SELL.equalsIgnoreCase(type) || TYPE_COVER.equalsIgnoreCase(type); } public boolean isEntry() { return !isExit(); } public String getType() { return type; } public void setType(String type) { this.type = type; } public int getNumShares() { return numShares; } public void setNumShares(int numShares) { this.numShares = numShares; } public Contract getContract() { return contract; } public void setContract(Contract contract) { this.contract = contract; } public void setPrice(double price) { this.price = price; } public double getPrice() { return price; } public boolean isPartial() { return partial; } public void setPartial(boolean isPartial) { this.partial = isPartial; } }