/* ===========================================================
* TradeManager : a application to trade strategies for the Java(tm) platform
* ===========================================================
*
* (C) Copyright 2011-2011, by Simon Allen and Contributors.
*
* Project Info: org.trade
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Oracle, Inc.
* in the United States and other countries.]
*
* (C) Copyright 2011-2011, by Simon Allen and Contributors.
*
* Original Author: Simon Allen;
* Contributor(s): -;
*
* Changes
* -------
*
*/
package org.trade.ui.models;
import java.util.Vector;
import javax.swing.event.TableModelEvent;
import org.trade.core.util.CoreUtils;
import org.trade.core.util.TradingCalendar;
import org.trade.core.valuetype.Date;
import org.trade.core.valuetype.Decimal;
import org.trade.core.valuetype.Money;
import org.trade.core.valuetype.Quantity;
import org.trade.core.valuetype.YesNo;
import org.trade.dictionary.valuetype.Action;
import org.trade.dictionary.valuetype.DAOEntryLimit;
import org.trade.dictionary.valuetype.OrderStatus;
import org.trade.dictionary.valuetype.OrderType;
import org.trade.dictionary.valuetype.Side;
import org.trade.persistent.dao.Entrylimit;
import org.trade.persistent.dao.TradeOrder;
import org.trade.persistent.dao.TradePosition;
import org.trade.persistent.dao.Tradestrategy;
import org.trade.ui.base.TableModel;
/**
*/
public class TradeOrderTableModel extends TableModel {
private static final long serialVersionUID = 3087514589731145479L;
private static final String SYMBOL = "Symbol*";
private static final String ORDER_KEY = " Order Key ";
private static final String QUANTITY = "Qty*";
private static final String ACTION = "Action*";
private static final String ORDER_TYPE = "Type*";
private static final String LMT_PRICE = "Lmt Price";
private static final String AUX_PRICE = "Aux Price";
private static final String TRANSMIT = "Transmit";
private static final String STATUS = " Status ";
private static final String OCA_GRP_NAME = "OCA Id";
private static final String AVG_PRICE = "Avg Price";
private static final String FILLED_DATE = "Filled Time";
private static final String FILLED_QTY = "Filled Qty";
private static final String STOP_PRICE = "Stop Price";
private static final String PROPERTIES = "Alloc Props";
private static final String[] columnHeaderToolTip = { null, "System generated key", "Buy/Sell/Short", null, null,
null, "Stop/Mkt price", "Transmit to mkt in TWS", null,
"One Cancels Another(OCA) id must be unique for day", null, null, null, null, "FA account assignment" };
private Tradestrategy m_data = null;
public TradeOrderTableModel() {
super(columnHeaderToolTip);
columnNames = new String[15];
columnNames[0] = SYMBOL;
columnNames[1] = ORDER_KEY;
columnNames[2] = ACTION;
columnNames[3] = ORDER_TYPE;
columnNames[4] = QUANTITY;
columnNames[5] = LMT_PRICE;
columnNames[6] = AUX_PRICE;
columnNames[7] = TRANSMIT;
columnNames[8] = STATUS;
columnNames[9] = OCA_GRP_NAME;
columnNames[10] = AVG_PRICE;
columnNames[11] = FILLED_DATE;
columnNames[12] = FILLED_QTY;
columnNames[13] = STOP_PRICE;
columnNames[14] = PROPERTIES;
}
/**
* Method isCellEditable.
*
* @param row
* int
* @param column
* int
* @return boolean
* @see javax.swing.table.TableModel#isCellEditable(int, int)
*/
public boolean isCellEditable(int row, int column) {
OrderStatus orderStatus = (OrderStatus) this.getValueAt(row, 8);
if (null != orderStatus) {
if (OrderStatus.CANCELLED.equals(orderStatus.getCode()) || OrderStatus.FILLED.equals(orderStatus.getCode())
|| OrderStatus.INACTIVE.equals(orderStatus.getCode())) {
return false;
}
}
if ((columnNames[column] == SYMBOL) || (columnNames[column] == ORDER_KEY) || (columnNames[column] == STATUS)
|| (columnNames[column] == AVG_PRICE) || (columnNames[column] == FILLED_DATE)
|| (columnNames[column] == FILLED_QTY) || (columnNames[column] == STOP_PRICE)) {
return false;
}
return true;
}
/**
* Method getValueAt.
*
*
* @param row
* int
* @param column
* int
* @return value Object
*/
public Object getValueAt(int row, int column) {
if (columnNames[column] == LMT_PRICE && null != super.getValueAt(row, column)) {
if (((OrderType) super.getValueAt(row, 3)).isValid()) {
if (((OrderType) super.getValueAt(row, 3)).getCode().equals(OrderType.MKT)
|| ((OrderType) super.getValueAt(row, 3)).getCode().equals(OrderType.STP)
|| ((OrderType) super.getValueAt(row, 3)).getCode().equals(OrderType.TRAIL)) {
if (((Money) super.getValueAt(row, column)).doubleValue() != 0) {
Money price = new Money(0);
this.setValueAt(price, row, column);
return price;
}
}
if (((OrderType) super.getValueAt(row, 3)).getCode().equals(OrderType.LMT)
|| ((OrderType) super.getValueAt(row, 3)).getCode().equals(OrderType.STPLMT)
|| ((OrderType) super.getValueAt(row, 3)).getCode().equals(OrderType.TRAILLIMIT)) {
if (((Money) super.getValueAt(row, column)).doubleValue() == 0) {
Money price = new Money(
this.getData().getStrategyData().getBaseCandleSeries().getContract().getLastPrice());
this.setValueAt(price, row, column);
return price;
}
}
}
}
if (columnNames[column] == AUX_PRICE && null != super.getValueAt(row, column)) {
if (((OrderType) super.getValueAt(row, 3)).isValid()) {
if (((OrderType) super.getValueAt(row, 3)).getCode().equals(OrderType.MKT)
|| ((OrderType) super.getValueAt(row, 3)).getCode().equals(OrderType.LMT)) {
if (((Money) super.getValueAt(row, column)).doubleValue() != 0) {
Money price = new Money(0);
this.setValueAt(price, row, column);
return price;
}
}
if (((OrderType) super.getValueAt(row, 3)).getCode().equals(OrderType.STP)
|| ((OrderType) super.getValueAt(row, 3)).getCode().equals(OrderType.STPLMT)) {
if (((Money) super.getValueAt(row, column)).doubleValue() == 0) {
Money price = new Money(
this.getData().getStrategyData().getBaseCandleSeries().getContract().getLastPrice());
this.setValueAt(price, row, column);
return price;
}
}
}
}
return super.getValueAt(row, column);
}
/**
* Method setValueAt.
*
* @param value
* Object
* @param row
* int
* @param column
* int
* @see javax.swing.table.TableModel#setValueAt(Object, int, int)
*/
public void setValueAt(Object value, int row, int column) {
if (null != value && !value.equals(super.getValueAt(row, column))) {
this.populateDAO(value, row, column);
Vector<Object> dataRow = rows.get(row);
dataRow.setElementAt(value, column);
fireTableCellUpdated(row, column);
}
}
/**
* Method getData.
*
* @return Tradestrategy
*/
public Tradestrategy getData() {
return m_data;
}
/**
* Method setData.
*
* @param data
* Tradestrategy
*/
public void setData(Tradestrategy data) {
this.m_data = data;
this.clearAll();
if (!getData().getTradeOrders().isEmpty()) {
for (final TradeOrder tradeOrder : getData().getTradeOrders()) {
final Vector<Object> newRow = new Vector<Object>();
getNewRow(newRow, tradeOrder);
rows.add(newRow);
}
fireTableDataChanged();
}
}
/**
* Method populateDAO.
*
* @param value
* Object
* @param row
* int
* @param column
* int
*/
public void populateDAO(Object value, int row, int column) {
TradeOrder element = null;
int i = 0;
for (final TradeOrder tradeOrder : getData().getTradeOrders()) {
if (i == row) {
element = tradeOrder;
break;
}
i++;
}
switch (column) {
case 0: {
element.getTradestrategy().getContract().setSymbol((String) value);
break;
}
case 1: {
element.setOrderKey(((Quantity) value).getIntegerValue());
break;
}
case 2: {
element.setAction(((Action) value).getCode());
break;
}
case 3: {
element.setOrderType(((OrderType) value).getCode());
break;
}
case 4: {
element.setQuantity(((Quantity) value).getIntegerValue());
break;
}
case 5: {
element.setLimitPrice(((Money) value).getBigDecimalValue());
break;
}
case 6: {
element.setAuxPrice(((Money) value).getBigDecimalValue());
break;
}
case 7: {
element.setTransmit(new Boolean(((YesNo) value).getCode()));
break;
}
case 8: {
element.setStatus(((OrderStatus) value).getCode());
break;
}
case 9: {
element.setOcaGroupName((String) value);
break;
}
case 10: {
element.setAverageFilledPrice(((Decimal) value).getBigDecimalValue());
break;
}
case 11: {
element.setFilledDate(((Date) value).getZonedDateTime());
break;
}
case 12: {
element.setFilledQuantity(((Quantity) value).getIntegerValue());
break;
}
case 13: {
element.setStopPrice(((Money) value).getBigDecimalValue());
break;
}
case 14: {
if (value instanceof TradeOrder) {
element.setFAProfile(((TradeOrder) value).getFAProfile());
element.setFAGroup(((TradeOrder) value).getFAGroup());
element.setFAMethod(((TradeOrder) value).getFAMethod());
element.setFAPercent(((TradeOrder) value).getFAPercent());
} else {
element.setFAProfile(null);
element.setFAGroup(null);
element.setFAMethod(null);
element.setFAPercent(null);
}
break;
}
default: {
}
}
}
/**
* Method deleteRow.
*
* @param selectedRow
* int
*/
public void deleteRow(int selectedRow) {
Integer orderKey = ((Quantity) this.getValueAt(selectedRow, 1)).getIntegerValue();
for (final TradeOrder tradeOrder : getData().getTradeOrders()) {
if (CoreUtils.nullSafeComparator(tradeOrder.getOrderKey(), orderKey) == 0) {
getData().getTradeOrders().remove(tradeOrder);
final Vector<Object> currRow = rows.get(selectedRow);
rows.remove(currRow);
this.fireTableRowsDeleted(selectedRow, selectedRow);
break;
}
}
}
/**
* Method addRow.
*
* @param element
* TradeOrder
*/
public void addRow(TradeOrder element) {
getData().addTradeOrder(element);
final Vector<Object> newRow = new Vector<Object>();
getNewRow(newRow, element);
rows.add(newRow);
this.fireTableRowsInserted(rows.size() - 1, rows.size() - 1);
}
public void addRow() {
final Tradestrategy tradestrategy = getData();
String side = tradestrategy.getSide();
if (null == side)
side = Side.BOT;
String orderType = OrderType.STPLMT;
String action = Action.BUY;
if (Side.SLD.equals(side)) {
action = Action.SELL;
}
double risk = tradestrategy.getRiskAmount().doubleValue();
double stop = 1.0d;
Money price = new Money(tradestrategy.getStrategyData().getBaseCandleSeries().getContract().getLastPrice());
final Entrylimit entrylimit = DAOEntryLimit.newInstance().getValue(price);
Money limitPrice = Action.BUY.equals(action) ? price.add(new Money(entrylimit.getLimitAmount().doubleValue()))
: price.subtract(new Money(entrylimit.getLimitAmount().doubleValue()));
int quantity = (int) ((int) risk / stop);
if (tradestrategy.isThereOpenTradePosition()) {
for (TradeOrder item : tradestrategy.getTradeOrders()) {
if (item.hasTradePosition()) {
TradePosition position = item.getTradePosition();
if (position.isOpen()) {
quantity = Math.abs(position.getOpenQuantity());
side = position.getSide();
action = Action.BUY;
if (Side.BOT.equals(side)) {
action = Action.SELL;
}
orderType = OrderType.LMT;
limitPrice = price;
}
}
}
}
final TradeOrder tradeOrder = new TradeOrder(tradestrategy, action, orderType, quantity,
price.getBigDecimalValue(), limitPrice.getBigDecimalValue(),
TradingCalendar.getDateTimeNowMarketTimeZone());
tradeOrder.setOcaGroupName("");
tradeOrder.setTransmit(true);
tradeOrder.setStatus(OrderStatus.UNSUBMIT);
tradestrategy.addTradeOrder(tradeOrder);
final Vector<Object> newRow = new Vector<Object>();
getNewRow(newRow, tradeOrder);
rows.add(newRow);
// Tell the listeners a new table has arrived.
fireTableChanged(new TableModelEvent(this));
}
/**
* Method getNewRow.
*
* @param newRow
* Vector<Object>
* @param element
* TradeOrder
*/
public void getNewRow(Vector<Object> newRow, TradeOrder element) {
newRow.addElement(element.getTradestrategy().getContract().getSymbol());
newRow.addElement(new Quantity(element.getOrderKey()));
if (null == element.getAction()) {
newRow.addElement(new Action());
} else {
newRow.addElement(Action.newInstance(element.getAction()));
}
if (null == element.getOrderType()) {
newRow.addElement(new OrderType());
} else {
newRow.addElement(OrderType.newInstance(element.getOrderType()));
}
newRow.addElement(new Quantity(element.getQuantity()));
newRow.addElement(new Money(element.getLimitPrice()));
newRow.addElement(new Money(element.getAuxPrice()));
newRow.addElement(YesNo.newInstance(element.getTransmit()));
if (null == element.getStatus()) {
newRow.addElement(new OrderStatus());
} else {
newRow.addElement(OrderStatus.newInstance(element.getStatus()));
}
if (null == element.getOcaGroupName()) {
newRow.addElement("");
} else {
newRow.addElement(element.getOcaGroupName());
}
if (null == element.getAverageFilledPrice()) {
newRow.addElement(new Decimal(3));
} else {
newRow.addElement(new Decimal(element.getAverageFilledPrice(), 3));
}
if (null == element.getFilledDate()) {
newRow.addElement(new Date());
} else {
newRow.addElement(new Date(element.getFilledDate()));
}
newRow.addElement(new Quantity(element.getFilledQuantity()));
newRow.addElement(new Money(element.getStopPrice()));
TradeOrder tradeOrder = new TradeOrder();
tradeOrder.setIdTradeOrder(1);
if (null == element.getFAProfile()) {
newRow.addElement(tradeOrder);
} else {
tradeOrder.setFAProfile(element.getFAProfile());
tradeOrder.setFAGroup(element.getFAGroup());
tradeOrder.setFAMethod(element.getFAMethod());
tradeOrder.setFAPercent(element.getFAPercent());
newRow.addElement(tradeOrder);
}
}
}