I've experienced very strange behavior. I have placed order of 4 contracts. Once completed I place LIMIT order (S:TP) for 2 contracts - 10 points from current placed order. Then I place 2 SL orders 2+2 contracts (S:SL1 and S:SL2) - 100 points from current order. Please see openPosSL1_2&TP.png.
Then once LIMIT order is filled both SL orders are cancelled, but I think only one SL order should be cancelled. What might happen is that since I am trading in 30 minutes range, my order is not protected by SL. See noOpenPos.png
Once the bar switches to the next bar, S:SL2 is triggered, but until that time many bad things may happen! See newBar.png
Here is the sample of my code:
Code: Select all
using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;
using ATCenterProxy.interop;
namespace PowerLanguage.Strategy {
[IOGMode(IOGMode.Enabled)]
public class TestOnly : SignalObject {
[Input]
public int TP_POINTS { get; set; }
[Input]
public int SL_POINTS { get; set; }
public TestOnly(object _ctx):base(_ctx)
{
TP_POINTS = 10;
SL_POINTS = 100;
}
private IOrderMarket sell_order;
private IOrderPriced buyTPorder, buySLorder1, buySLorder2;
private int CONTRACTS = 4;
private double tpPrice, slPrice1, slPrice2;
private int profitBar = -1;
protected override void Create() {
Output.Clear();
// create variable objects, function objects, order objects etc.
Contracts sellCon = Contracts.CreateUserSpecified(CONTRACTS);
sell_order = OrderCreator.MarketNextBar(new SOrderParameters(sellCon, EOrderAction.SellShort));
int CONTRACTS_1 = CONTRACTS/2;
Contracts slTp1Con = Contracts.CreateUserSpecified(CONTRACTS_1);
int CONTRACTS_2 = CONTRACTS - CONTRACTS_1;
Contracts sl2Con = Contracts.CreateUserSpecified(CONTRACTS_2);
Output.WriteLine("TP/SL1 contracts: {0}; SL2 contracts: {1}", slTp1Con.Contract, sl2Con.Contract);
buyTPorder = OrderCreator.Limit(new SOrderParameters(slTp1Con, "S:TP", EOrderAction.BuyToCover));
buySLorder1 = OrderCreator.Stop(new SOrderParameters(slTp1Con, "S:SL1", EOrderAction.BuyToCover));
buySLorder2 = OrderCreator.Stop(new SOrderParameters(sl2Con, "S:SL2", EOrderAction.BuyToCover));
}
protected override void StartCalc() {
// assign inputs
// here I'm initializating some properties which are reinitialized when calling AverageTrueRange
Output.WriteLine("Start calc CALL! {0}", this.Name);
}
protected override void CalcBar(){
if (!Environment.IsAutoTradingMode || !Environment.IsRealTimeCalc)
return;
Output.WriteLine("StrategyInfo.MarketPosition={0} OpenLots={1}", StrategyInfo.MarketPosition, CurrentPosition.OpenLots);
if (StrategyInfo.MarketPosition == 0)// && Bars.CurrentBar % 5 == 0)
{
//Output.WriteLine("Buy {0} at {1} ATR: {2}", Bars.Info.Name, Bars.CloseValue, atr_day);
tpPrice = Bars.CloseValue - TP_POINTS*Bars.Point;
slPrice1 = slPrice2 = Bars.CloseValue + SL_POINTS*Bars.Point;
Output.WriteLine("Placing sell order at: {0}, TP: {1}; SL1/2: {2}", Bars.CloseValue, tpPrice, slPrice1);
sell_order.Send();
}
else
{
if (StrategyInfo.MarketPosition != 0)
{
if (CurrentPosition.OpenLots == CONTRACTS)
{
buyTPorder.Send(tpPrice);
buySLorder1.Send(slPrice1);
buySLorder2.Send(slPrice2);
Output.WriteLine("SL1,2 & TP resend");
}
else
{
if (profitBar == -1)
{
profitBar = Bars.CurrentBar;// - Positions[0].OpenTrades[0].EntryOrder.BarNumber;
Output.WriteLine("Profit bar num: {0}", profitBar);
} else if (profitBar != Bars.CurrentBar)
{
profitBar = Bars.CurrentBar;
slPrice2 = Bars.High[1] + TP_POINTS*Bars.Point;
Output.WriteLine("Recalculated SL to {0} for bar num: {1}", slPrice2, profitBar);
}
Output.WriteLine("SL resend");
buySLorder2.Send(slPrice2);
}
GenerateExitOnClose();
}
}
}
}
}
I would consider it as bug, what do you think?
Here is output:
TP/SL1 contracts: 2; SL2 contracts: 2
Start calc CALL! TestOnly
Start calc CALL! TestOnly
StrategyInfo.MarketPosition=0 OpenLots=0
Placing sell order at: 1,70779, TP: 1,70769; SL1/2: 1,70879
StrategyInfo.MarketPosition=0 OpenLots=0
Placing sell order at: 1,7078, TP: 1,7077; SL1/2: 1,7088
StrategyInfo.MarketPosition=-4 OpenLots=4
SL1,2 & TP resend
StrategyInfo.MarketPosition=-4 OpenLots=4
SL1,2 & TP resend
StrategyInfo.MarketPosition=-4 OpenLots=4
SL1,2 & TP resend
StrategyInfo.MarketPosition=-2 OpenLots=2
Profit bar num: 2004
SL resend
StrategyInfo.MarketPosition=-2 OpenLots=2
SL resend
StrategyInfo.MarketPosition=-2 OpenLots=2
SL resend
StrategyInfo.MarketPosition=-2 OpenLots=2
SL resend
I've reproduced this behavior on the latest MC .net 8.8 64bit