The strategy below simply opens a long position of 1M, then opens a short position of 0.5M, and then closes all positions. If the flag UseMerge is true, then before closing all positions the long and short positions are merged.
The strategy was run with and without utilising order merging on an account size of 1M for GBPUSD starting from 04/10/2011 10:00:00. Without the merge, the commission was reported as 55.41 USD and account.getEquity() reported 999804.59 USD. With the merge, the commission was 36.94 and equity 999893.06 USD.
It is expected that the commission would be lower with merging. But adding back the commission to the account equity shows that the profit/loss without commissions for the two cases differ by 70 USD.
"Without merge" final account size before commission = 999804.59 + 55.41 = 999860
"With merge" final account size before commission = 999893.06 + 36.94 = 999930
Can somebody from DukasCopy please answer...
Is this behaviour expected? I thought that merging would not affect the amount of profit before the commission is subtracted.
PS I don't mean to shout, I write this in a pleasant mood, I just want to draw attention to the question part of this post since it is only four words and may be missed on a glancing read.
As I understand the code, in both cases the strategy holds 1M Long from tick 1 to tick 3, then it holds 0.5M Long (net position) from tick 3 onwards, then on tick 7 it holds 0M (i.e. no position at all). My understanding of the optional merge at tick 5 is that it should not affect the profit/loss from the position, it should only reduce the commissions since the net merged order size of 0.5M is closed in the market rather than closing 1.5M in the un-merged case. The positions being held are exactly the same for the two modes.
Is that correct?
Why are the profit/loss different for "UseMerge = false" vs "UseMerge = true" in the strategy below?
package Strategies;
import com.dukascopy.api.*;
public class MergeExample implements IStrategy {
static final boolean UseMerge = false;
int tickCount;
IContext context;
IOrder EntryOrder;
IOrder ExitOrder;
IOrder MergeOrder;
public void onTick(Instrument instrument, ITick tick) throws JFException {
if (tickCount == 1)
EntryOrder = context.getEngine().submitOrder("EntryOrder",
instrument, IEngine.OrderCommand.BUY, 1);
if (tickCount == 3)
ExitOrder = context.getEngine().submitOrder("ExitOrder",
instrument, IEngine.OrderCommand.SELL, 0.5);
if (tickCount == 5)
if (UseMerge)
MergeOrder = context.getEngine().mergeOrders("MergeOrder",
EntryOrder, ExitOrder);
if (tickCount == 7)
// Close anything that is not closed
for (IOrder order : context.getEngine().getOrders())
if (!IOrder.State.CLOSED.equals(order.getState()))
order.close();
tickCount = tickCount + 1;
}
public void onStart(IContext context) throws JFException {
this.context = context;
}
public void onMessage(IMessage message) throws JFException {
}
public void onAccount(IAccount account) throws JFException {
System.out.println("UseMerge = " + UseMerge + "; DukasEquity = " + account.getEquity());
}
public void onStop() throws JFException {
}
public void onBar(Instrument instrument, Period period, IBar askBar,
IBar bidBar) throws JFException {
}
}