hello support,
i have a trouble with my strategy, i don't know why the strategy don't take all the signal when the condition of signal is triggered.
see the attached file.
this is the code :
package jforex.strategies.indicators;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import com.dukascopy.api.IIndicators.AppliedPrice;
import com.dukascopy.api.IIndicators;
import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.indicators.IIndicator;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class reversalbar implements IStrategy {
private IEngine engine;
private IConsole console;
private IHistory history;
private int counter = 0;
private IOrder order;
private IIndicators indicators;
//ma indicators
@Configurable("MA period")
public int maPeriod = 21;
@Configurable("Take profit pips")
public int takeProfitPips = 100;
@Configurable("stop loss pips")
public int stopLossPips = 50;
@Configurable("Pips above p")
public int pipsAbove = 5;
@Configurable("Pips below p")
public int pipsBelow = 5;
@Configurable("Order expire candle count")
public int orderExpireCandles = 2;
@Configurable("Instrument")
public Instrument instrument = Instrument.EURUSD;
@Configurable("Period")
public Period selectedPeriod = Period.ONE_HOUR;
@Configurable("Slippage")
public double slippage = 1;
@Configurable("Amount")
public double amount = 0.02;
//break even
@Configurable("Lock-in Pips for Breakeven (SLBE)")
public int lockPip = 10;
@Configurable("Stoploss Break Even Trigger (SLBET)")
public int triggerPips = 50;
@Configurable("Move stop to breakeven?")
public boolean moveBE = true;
//trailing
@Configurable("Trailing trigger pips")
public int trailingPips = 50;
//time to trade
@Configurable("Open hour")
public int openHour = 5;
@Configurable("Open min")
public int openMin = 30;
@Configurable("Close hour")
public int closeHour = 20;
@Configurable("Close min")
public int closeMin = 30;
@Override
public void onStart(IContext context) throws JFException {
this.console = context.getConsole();
this.history = context.getHistory();
this.engine = context.getEngine();
this.indicators = context.getIndicators();
}
@Override
public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
if (period != this.selectedPeriod || instrument != this.instrument) {
return;
}
//if (!isActive(order)) {
// order = null;
// }
if(order != null && order.getState().equals(IOrder.State.OPENED)) {
printTime(order.getCreationTime());
printTime(askBar.getTime());
printTime(order.getCreationTime() + (period.getInterval() * orderExpireCandles));
if(order.getCreationTime() + (period.getInterval() * orderExpireCandles) <= askBar.getTime()) {
order.close();
order = null;
}
}
boolean sellSign = false;
boolean buySign = false;
double buyPrice = 0.0, sellPrice = 0.0;
double ma1 = indicators.ma(instrument,selectedPeriod,OfferSide.ASK,IIndicators.AppliedPrice.CLOSE,maPeriod,IIndicators.MaType.SMA,0);
double ma11 = indicators.ma(instrument,selectedPeriod,OfferSide.ASK,IIndicators.AppliedPrice.CLOSE,maPeriod,IIndicators.MaType.SMA,1);
double ma2 = indicators.ma(instrument,Period.ONE_HOUR,OfferSide.ASK,IIndicators.AppliedPrice.CLOSE,maPeriod,IIndicators.MaType.SMA,0);
double ma21 = indicators.ma(instrument,Period.ONE_HOUR,OfferSide.ASK,IIndicators.AppliedPrice.CLOSE,maPeriod,IIndicators.MaType.SMA,1);
// SIGNALS
IBar currBar = history.getBar(instrument, period, OfferSide.ASK,1);
IBar prevBar = history.getBar(instrument, period, OfferSide.ASK,2);
// reversal sell
if(currBar.getHigh() > prevBar.getHigh() && currBar.getClose() < prevBar.getLow()) {
sellSign = true;
sellPrice = currBar.getLow() - getPipPrice(pipsAbove);
}
// reversal buy
if(currBar.getLow() < prevBar.getLow() && currBar.getClose() > prevBar.getHigh()) {
buySign = true;
buyPrice = currBar.getHigh() + getPipPrice(pipsAbove);
}
// PLACE ORDER
if (buySign) {
if (order == null || !order.isLong()) {
closeOrder(order);
if (isRightTime(askBar.getTime(), openHour, openMin, closeHour, closeMin)){
order = submitOrder(OrderCommand.BUYSTOP, buyPrice, currBar.getClose());
}
}
} else if (sellSign) {
if (order == null || order.isLong()) {
closeOrder(order);
if (isRightTime(askBar.getTime(), openHour, openMin, closeHour, closeMin)){
order = submitOrder(OrderCommand.SELLSTOP, sellPrice, currBar.getClose());
}
}
}
}
public void onTick(Instrument instrument, ITick tick) throws JFException {
if (instrument != this.instrument) {
return;
}
updateTrailingStopLoss(tick, order, trailingPips, getRoundedPips(stopLossPips));
//break even
for (IOrder order : engine.getOrders(instrument)) {
if (order.getState() == IOrder.State.FILLED) {
boolean isLong;
double open, newStop, stopLoss;
String label = order.getLabel();
IChart chart;
isLong = order.isLong();
open = order.getOpenPrice();
stopLoss = order.getStopLossPrice();
if (isLong) { // long side order
if(open < stopLoss){
return;
}
if (moveBE && tick.getBid() > (open + toPrice(instrument, triggerPips))) {
// make it breakeven trade + lock in a few pips
newStop = open + toPrice(instrument, lockPip);
order.setStopLossPrice(newStop);
console.getOut().println(label + ": Moved stop to breakeven");
}
} else { // short side order
if(open > stopLoss){
return;
}
// Move to breakeven
if (moveBE && tick.getAsk() < (open - toPrice(instrument, triggerPips))) { // diff is negative
// make it breakeven trade + lock in a few pips
newStop = open - toPrice(instrument, lockPip);
order.setStopLossPrice(newStop);
console.getOut().println(label + ": Moved stop to breakeven");
}
}
}
}
}
private double toPrice(Instrument instr, int pips) {
return instr.getPipValue() * pips;
}
private IOrder submitOrder(OrderCommand orderCmd, double price, double stopLossPrice) throws JFException {
double takeProfitPrice = 0.0;
ITick tick = history.getLastTick(instrument);
// Calculating order price, stop loss and take profit prices
if (orderCmd == OrderCommand.BUYSTOP) {
if (takeProfitPips > 0) {
takeProfitPrice = price + getPipPrice(takeProfitPips);
stopLossPrice = price - getPipPrice(stopLossPips);
}
} else {
if (takeProfitPips > 0) {
takeProfitPrice = price - getPipPrice(takeProfitPips);
stopLossPrice = price + getPipPrice(stopLossPips);
}
}
return engine.submitOrder(getLabel(instrument), instrument, orderCmd, amount, price, slippage, stopLossPrice, takeProfitPrice);
}
private void closeOrder(IOrder order) throws JFException {
if (order != null && isActive(order)) {
order.close();
}
}
private boolean isActive(IOrder order) throws JFException {
if (order != null && order.getState() != IOrder.State.CLOSED && order.getState() != IOrder.State.CREATED && order.getState() != IOrder.State.CANCELED) {
return true;
}
return false;
}
private double getPipPrice(double pips) {
return pips * this.instrument.getPipValue();
}
private String getLabel(Instrument instrument) {
String label = instrument.name();
label = label + (counter++);
label = label.toUpperCase();
return label;
}
//trailing
public boolean updateTrailingStopLoss(ITick tick, IOrder pOrder, double pTriggerPips, double pStopLossPips) throws JFException {
boolean triggered = false;
if (pTriggerPips > 0 && pStopLossPips > 0
&& pOrder != null && pOrder.getState() == IOrder.State.FILLED) {
double newStop;
double openPrice = pOrder.getOpenPrice();
double currentStopLoss = pOrder.getStopLossPrice();
// (START) trailing stop loss is activated when price is higher than oper price + trailingTrigger pips
// (TRAILING STOP) if price moves further up (for BUY order), stop loss is updated to stopLossPips
if (pOrder.isLong()) { // long side order
if (tick.getBid() > currentStopLoss + getPipPrice(pStopLossPips)
&& tick.getBid() > openPrice + getPipPrice(pTriggerPips)) {
// trailing stop loss
newStop = tick.getBid() - getPipPrice(pStopLossPips);
newStop = (new BigDecimal(newStop)).setScale(instrument.getPipScale(), BigDecimal.ROUND_HALF_UP).doubleValue();
if (currentStopLoss != newStop) {
pOrder.setStopLossPrice(newStop);
triggered = true;
}
}
} else { // short side order
if (tick.getAsk() < currentStopLoss - getPipPrice(pStopLossPips)
&& tick.getAsk() < openPrice - getPipPrice(pTriggerPips)) {
// trailing stop loss
newStop = tick.getAsk() + getPipPrice(pStopLossPips);
newStop = (new BigDecimal(newStop)).setScale(instrument.getPipScale(), BigDecimal.ROUND_HALF_UP).doubleValue();
if (currentStopLoss != newStop) {
pOrder.setStopLossPrice(newStop);
triggered = true;
}
}
}
}
return triggered;
}
//calendar
public boolean timeIsEqual(long time, int hour, int min){
Calendar cal = new GregorianCalendar();
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
cal.setTimeInMillis(time);
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, min);
Calendar cal2 = new GregorianCalendar();
cal2.setTimeZone(TimeZone.getTimeZone("GMT"));
cal2.setTimeInMillis(cal.getTimeInMillis());
cal2.add(Calendar.MINUTE, 5);
if(cal.getTimeInMillis() <= time
&& time <= cal2.getTimeInMillis() ) {
return true;
}
return false;
}
//time to trade
public boolean isRightTime(long time, int fromHour, int fromMin, int toHour, int toMin) {
Calendar cal = new GregorianCalendar();
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
cal.setTimeInMillis(time);
cal.set(Calendar.HOUR_OF_DAY, fromHour);
cal.set(Calendar.MINUTE, fromMin);
Calendar cal2 = new GregorianCalendar();
cal2.setTimeZone(TimeZone.getTimeZone("GMT"));
cal2.setTimeInMillis(time);
cal2.set(Calendar.HOUR_OF_DAY, toHour);
cal2.set(Calendar.MINUTE, toMin);
if (cal.getTimeInMillis() <= time
&& time <= cal2.getTimeInMillis()) {
return true;
}
return false;
}
private double getRoundedPrice(double price) {
BigDecimal bd = new BigDecimal(price);
bd = bd.setScale(instrument.getPipScale() + 1, RoundingMode.HALF_UP);
return bd.doubleValue();
}
private double getRoundedPips(double pips) {
BigDecimal bd = new BigDecimal(pips);
bd = bd.setScale(1, RoundingMode.HALF_UP);
return bd.doubleValue();
}
public void onMessage(IMessage message) throws JFException {
}
public void onAccount(IAccount account) throws JFException {
}
public void onStop() throws JFException {
}
/**************** debug print functions ***********************/
private void print(Object... o) {
for (Object ob : o) {
//console.getOut().print(ob + " ");
if (ob instanceof Double) {
print2(toStr((Double) ob));
} else if (ob instanceof double[]) {
print((double[]) ob);
} else if (ob instanceof double[]) {
print((double[][]) ob);
} else if (ob instanceof Long) {
print2(toStr((Long) ob));
} else if (ob instanceof IBar) {
print2(toStr((IBar) ob));
} else {
print2(ob);
}
print2(" ");
}
console.getOut().println();
}
private void print(Object o) {
console.getOut().println(o);
}
private void print2(Object o) {
console.getOut().print(o);
}
private void print(double d) {
print(toStr(d));
}
private void print(double[] arr) {
print(toStr(arr));
}
private void print(double[][] arr) {
print(toStr(arr));
}
private void print(IBar bar) {
print(toStr(bar));
}
private void printIndicatorInfos(IIndicator ind) {
for (int i = 0; i < ind.getIndicatorInfo().getNumberOfInputs(); i++) {
print(ind.getIndicatorInfo().getName() + " Input " + ind.getInputParameterInfo(i).getName() + " " + ind.getInputParameterInfo(i).getType());
}
for (int i = 0; i < ind.getIndicatorInfo().getNumberOfOptionalInputs(); i++) {
print(ind.getIndicatorInfo().getName() + " Opt Input " + ind.getOptInputParameterInfo(i).getName() + " " + ind.getOptInputParameterInfo(i).getType());
}
for (int i = 0; i < ind.getIndicatorInfo().getNumberOfOutputs(); i++) {
print(ind.getIndicatorInfo().getName() + " Output " + ind.getOutputParameterInfo(i).getName() + " " + ind.getOutputParameterInfo(i).getType());
}
console.getOut().println();
}
public static String toStr(double[] arr) {
String str = "";
for (int r = 0; r < arr.length; r++) {
str += "[" + r + "] " + (new DecimalFormat("#.#######")).format(arr[r]) + "; ";
}
return str;
}
public static String toStr(double[][] arr) {
String str = "";
if (arr == null) {
return "null";
}
for (int r = 0; r < arr.length; r++) {
for (int c = 0; c < arr[r].length; c++) {
str += "[" + r + "][" + c + "] " + (new DecimalFormat("#.#######")).format(arr[r][c]);
}
str += "; ";
}
return str;
}
public String toStr(double d) {
return (new DecimalFormat("#.#######")).format(d);
}
public String toStr(Long time) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") {
{
setTimeZone(TimeZone.getTimeZone("GMT"));
}
};
return sdf.format(time);
}
private String toStr(IBar bar) {
return toStr(bar.getTime()) + " O:" + bar.getOpen() + " C:" + bar.getClose() + " H:" + bar.getHigh() + " L:" + bar.getLow();
}
private void printTime(Long time) {
console.getOut().println(toStr(time));
}
}
i have a another question :
the strategy when found a new signal, the strategy cut the opened position. well i prefer that:
if the opened position is long and the new signal is long then keep the current position and add a new one
if the opened position is long and the new signal is short then cut the current position and add a new one.
but how to do that?
i would like to define high and low of a group of candle but i don't have any idea how to define this. could you give me a simple syntax of the code?
sorry for my stupid question and for my english but i try to learn the programming and i start least than zero and the english too

.
best regards