/* ===========================================================
* TradeManager : An application to trade strategies for the Java(tm) platform
* ===========================================================
*
* (C) Copyright 2011-2011, by Simon Allen and Contributors.
*
* Project Info: org.trade test
*
* 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.strategy;
import java.time.ZonedDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.trade.broker.BrokerModel;
import org.trade.core.valuetype.Money;
import org.trade.dictionary.valuetype.Action;
import org.trade.dictionary.valuetype.OrderType;
import org.trade.dictionary.valuetype.Side;
import org.trade.strategy.data.CandleSeries;
import org.trade.strategy.data.StrategyData;
import org.trade.strategy.data.candle.CandleItem;
/**
*/
public class PosMgrAllOrNothingStrategy extends AbstractStrategyRule {
/**
* 1/ If the open position is filled create a STP (transmit=false see 2/ )
* and 1 Target (LMT) OCA order at xR with 100% of the filled quantity. Use
* the open position fill quantity, price and stop price to determine the
* target price. The STP order take an initial risk of 1R.
*
* 2/ Target/Stop prices should be round over/under whole/half numbers when
* ever they are calculated..
*
* 3/ Close any open positions at 15:58.
*
*/
private static final long serialVersionUID = 5998132222691879078L;
private final static Logger _log = LoggerFactory.getLogger(PosMgrAllOrNothingStrategy.class);
/**
* Default Constructor Note if you use class variables remember these will
* need to be initialized if the strategy is restarted i.e. if they are
* created on startup under a constraint you must find a way to populate
* that value if the strategy were to be restarted and the constraint is not
* met.
*
* @param brokerManagerModel
* BrokerModel
* @param strategyData
* StrategyData
* @param idTradestrategy
* Integer
*/
public PosMgrAllOrNothingStrategy(BrokerModel brokerManagerModel, StrategyData strategyData,
Integer idTradestrategy) {
super(brokerManagerModel, strategyData, idTradestrategy);
}
/**
* Method runStrategy.
*
* @param candleSeries
* CandleSeries
* @param newBar
* boolean
* @see org.trade.strategy.StrategyRule#runStrategy(CandleSeries, boolean)
*/
public void runStrategy(CandleSeries candleSeries, boolean newBar) {
try {
// Get the current candle
CandleItem currentCandleItem = (CandleItem) candleSeries.getDataItem(getCurrentCandleCount());
ZonedDateTime startPeriod = currentCandleItem.getPeriod().getStart();
// AbstractStrategyRule.logCandle(this,
// currentCandleItem.getCandle());
/*
* Get the current open trade. If no trade is open this Strategy
* will be closed down.
*/
if (!this.isThereOpenPosition()) {
_log.info("No open position so Cancel Strategy Mgr Symbol: " + getSymbol() + " Time:" + startPeriod);
this.cancel();
return;
}
/*
* If all trades are closed shut down the position manager
*
* Note this strategy is run as soon as we enter a position.
*
* Check to see if the open position is filled and the open quantity
* is > 0 also check to see if we already have this position
* covered.
*/
if (this.isThereOpenPosition() && !this.isPositionCovered()) {
/*
* Position has been opened and not covered submit the target
* and stop orders for the open quantity. One target at xR.
*/
_log.info("Open position submit Stop/Tgt orders Symbol: " + getSymbol() + " Time:" + startPeriod);
/*
* Risk amount is based of the average filled price and actual
* stop price not the rounded quantity. But if the stop price is
* not set use Risk Amount/Quantity.
*/
double riskAmount = 0;
if (null == this.getOpenPositionOrder().getStopPrice()) {
riskAmount = Math.abs(this.getTradestrategy().getRiskAmount().doubleValue()
/ this.getOpenPositionOrder().getFilledQuantity().doubleValue());
} else {
riskAmount = Math.abs(this.getOpenPositionOrder().getAverageFilledPrice().doubleValue()
- this.getOpenPositionOrder().getStopPrice().doubleValue());
}
String action = Action.BUY;
int buySellMultipliter = 1;
if (Side.BOT.equals(getOpenTradePosition().getSide())) {
action = Action.SELL;
buySellMultipliter = -1;
}
// Add a penny to the stop and target
double stop = this.getOpenPositionOrder().getAverageFilledPrice().doubleValue()
+ (riskAmount * 1 * buySellMultipliter);
Money auxPrice = addPennyAndRoundStop(stop, this.getOpenTradePosition().getSide(), action, -0.01);
this.createOrder(this.getTradestrategy().getContract(), action, OrderType.STP, null, auxPrice,
this.getOpenPositionOrder().getFilledQuantity(), null, false, true);
}
/*
* Close any opened positions with a market order at the end of the
* day.
*/
if (!currentCandleItem.getLastUpdateDate()
.isBefore(this.getTradestrategy().getTradingday().getClose().minusMinutes(2))) {
cancelOrdersClosePosition(true);
_log.info("PositionManagerStrategy 15:58:00 done: " + getSymbol() + " Time: " + startPeriod);
this.cancel();
}
} catch (StrategyRuleException ex) {
_log.error("Error Position Manager exception: " + ex.getMessage(), ex);
error(1, 30, "Error Position Manager exception: " + ex.getMessage());
}
}
}