Problem with stop/buy order code
Problem with stop/buy order code
13 Jun 2019, 13:30
Hello,
I have a problem with a code which I can't solve, maybe somebody that knows better about coding can help me with this issue.
I posted the code below.
Issue:
If I create e.g. 1 bot for Gold and add 2 or more instances both for XAUUSD and configure them that they make 2 opposite standing orders on a certain time (e.g. 1 at 12:01 and the other at 12:02), if 1 order gets triggered from the first instance it cancels the other instance out that and all the rest for that matter that I configured for the other time.
This happens only with the instances configured for the same pair.
Somebody knows how this comes and how I can fix this issue?
Thanks in advance.
Best regards, Bjorn.
Code:
using System;
using System.Linq;
using System.Text;
using cAlgo.API;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class DayTradeG1 : Robot
{
[Parameter("News Hour", DefaultValue = 14, MinValue = 0, MaxValue = 23)]
public int NewsHour { get; set; }
[Parameter("News Minute", DefaultValue = 30, MinValue = 0, MaxValue = 59)]
public int NewsMinute { get; set; }
[Parameter("Pips away", DefaultValue = 10)]
public int PipsAway { get; set; }
[Parameter("Take Profit", DefaultValue = 50)]
public int TakeProfit { get; set; }
[Parameter("Stop Loss", DefaultValue = 10)]
public int StopLoss { get; set; }
[Parameter("Volume", DefaultValue = 100000, MinValue = 10)]
public int Volume { get; set; }
[Parameter("Seconds Before", DefaultValue = 10, MinValue = 1)]
public int SecondsBefore { get; set; }
[Parameter("Seconds Timeout", DefaultValue = 10, MinValue = 1)]
public int SecondsTimeout { get; set; }
[Parameter("One Cancels Other")]
public bool Oco { get; set; }
[Parameter("ShowTimeLeftNews", DefaultValue = false)]
public bool ShowTimeLeftToNews { get; set; }
[Parameter("ShowTimeLeftPlaceOrders", DefaultValue = true)]
public bool ShowTimeLeftToPlaceOrders { get; set; }
private bool _ordersCreated;
private DateTime _triggerTimeInServerTimeZone;
private const string Label = "News Straddler v1";
protected override void OnStart()
{
Positions.Opened += OnPositionOpened;
Timer.Start(1);
var triggerTimeInLocalTimeZone = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, NewsHour, NewsMinute, 0);
if (triggerTimeInLocalTimeZone < DateTime.Now)
triggerTimeInLocalTimeZone = triggerTimeInLocalTimeZone.AddDays(1);
_triggerTimeInServerTimeZone = TimeZoneInfo.ConvertTime(triggerTimeInLocalTimeZone, TimeZoneInfo.Local, TimeZone);
}
protected override void OnTimer()
{
var remainingTime = _triggerTimeInServerTimeZone - Server.Time;
DrawRemainingTime(remainingTime);
if (!_ordersCreated)
{
var sellOrderTargetPrice = Symbol.Bid - PipsAway * Symbol.PipSize;
ChartObjects.DrawHorizontalLine("sell target", sellOrderTargetPrice, Colors.Red, 1, LineStyle.DotsVeryRare);
var buyOrderTargetPrice = Symbol.Ask + PipsAway * Symbol.PipSize;
ChartObjects.DrawHorizontalLine("buy target", buyOrderTargetPrice, Colors.Blue, 1, LineStyle.DotsVeryRare);
if (Server.Time <= _triggerTimeInServerTimeZone && (_triggerTimeInServerTimeZone - Server.Time).TotalSeconds <= SecondsBefore)
{
_ordersCreated = true;
var expirationTime = _triggerTimeInServerTimeZone.AddSeconds(SecondsTimeout);
PlaceStopOrder(TradeType.Sell, Symbol, Volume, sellOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime);
PlaceStopOrder(TradeType.Buy, Symbol, Volume, buyOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime);
ChartObjects.RemoveObject("sell target");
ChartObjects.RemoveObject("buy target");
}
}
if (_ordersCreated && !PendingOrders.Any(o => o.Label == Label))
{
Print("Orders expired");
Stop();
}
}
private void DrawRemainingTime(TimeSpan remainingTimeToNews)
{
if (ShowTimeLeftToNews)
{
if (remainingTimeToNews > TimeSpan.Zero)
{
ChartObjects.DrawText("countdown1", "Time left to news: " + FormatTime(remainingTimeToNews), StaticPosition.TopLeft);
}
else
{
ChartObjects.RemoveObject("countdown1");
}
}
if (ShowTimeLeftToPlaceOrders)
{
var remainingTimeToOrders = remainingTimeToNews - TimeSpan.FromSeconds(SecondsBefore);
if (remainingTimeToOrders > TimeSpan.Zero)
{
ChartObjects.DrawText("countdown2", "Time left to place orders: " + FormatTime(remainingTimeToOrders), StaticPosition.TopRight);
}
else
{
ChartObjects.RemoveObject("countdown2");
}
}
}
private static StringBuilder FormatTime(TimeSpan remainingTime)
{
var remainingTimeStr = new StringBuilder();
if (remainingTime.TotalHours >= 1)
remainingTimeStr.Append((int)remainingTime.TotalHours + "h ");
if (remainingTime.TotalMinutes >= 1)
remainingTimeStr.Append(remainingTime.Minutes + "m ");
if (remainingTime.TotalSeconds > 0)
remainingTimeStr.Append(remainingTime.Seconds + "s");
return remainingTimeStr;
}
private void OnPositionOpened(PositionOpenedEventArgs args)
{
var position = args.Position;
if (position.Label == Label && position.SymbolCode == Symbol.Code)
{
if (Oco)
{
foreach (var order in PendingOrders)
{
if (order.Label == Label && order.SymbolCode == Symbol.Code)
{
CancelPendingOrderAsync(order);
}
}
}
Stop();
}
}
}
}
Replies
bjornvandekerkhof
13 Jun 2019, 14:21
RE:
Panagiotis Charalampous said:
Hi bjornvandekerkhof,
Thanks for posting in our forum. You should try setting a different label for each instance's orders.
Best Regards,
Panagiotis
Hello Panagiotis Charalampous,
Could you give an example please, I'm new to cTrader and this coding.
I found one thread on this: https://ctrader.com/forum/cbot-support/11619 but I don't think that is the same issue.
Would be much appriciated.
Best regards, Bjorn.
@bjornvandekerkhof
PanagiotisCharalampous
13 Jun 2019, 14:29
Hi Bjorn,
You set a label to each order but is constant
private const string Label = "News Straddler v1";
Your code filters out orders based on symbol and label
foreach (var order in PendingOrders) { if (order.Label == Label && order.SymbolCode == Symbol.Code) { CancelPendingOrderAsync(order); } }
You should make Label a parameter and set a different one for each instance so that each instance operates only on its orders.
Best Regards,
Panagiotis
@PanagiotisCharalampous
bjornvandekerkhof
13 Jun 2019, 14:45
RE:
Panagiotis Charalampous said:
Hi Bjorn,
You set a label to each order but is constant
private const string Label = "News Straddler v1";Your code filters out orders based on symbol and label
foreach (var order in PendingOrders) { if (order.Label == Label && order.SymbolCode == Symbol.Code) { CancelPendingOrderAsync(order); } }You should make Label a parameter and set a different one for each instance so that each instance operates only on its orders.
Best Regards,
Panagiotis
Hi Panagiotis,
I see, like I sayd I am completely newbie with this language.
Would I be able to use something from this code to add in my code to make it happen then?
I am trying to puzzle it out and put it together since I have minimum experience and that's with Python this is not the easiest.
Best regards, Bjorn.
using System.Collections.Generic; using System.Linq; using cAlgo.API; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class GroupsSample : Robot { public enum State { Gaining, BreakingEven, Loosing } public class Order { public Position Position { get; set; } public State State { get; set; } } private static List<Order> _orders; protected override void OnStart() { // creates new list if doesn't exist if (_orders == null) { _orders = new List<Order>(); } // subscribes to Positions.Closed event Positions.Closed += OnPositionClosed; } /// <summary> /// Method called on position closed /// </summary> private static void OnPositionClosed(PositionClosedEventArgs obj) { // finds matching order var matchingOrder = _orders.FirstOrDefault(x => x.Position == obj.Position); // if found if (matchingOrder != null) { // removes order from our list _orders.Remove(matchingOrder); } } /// <summary> /// Method called on each new bar /// </summary> protected override void OnBar() { // executes market order and calls back OnPositionOpened method when filled ExecuteMarketOrderAsync(MarketSeries.Open.Count % 2 == 0 ? TradeType.Buy : TradeType.Sell, Symbol, 1000, OnPositionOpened); // counts how many positions have certain state var gaining = _orders.Count(x => x.State == State.Gaining); var breakingEven = _orders.Count(x => x.State == State.BreakingEven); var loosing = _orders.Count(x => x.State == State.Loosing); // prints number of positions that are gaining, breaking even, loosing Print("Gaining = {0}, BreakingEven = {1}, Loosing = {2}", gaining, breakingEven, loosing); } /// <summary> /// Method called when position opened /// </summary> private void OnPositionOpened(TradeResult result) { // prints error and skips rest of the iteration if result wasn't successful if (!result.IsSuccessful) { Print(result.Error); return; } // adds new order into our list _orders.Add(new Order { Position = result.Position }); } /// <summary> /// Method called on each price change /// </summary> protected override void OnTick() { // loops through all orders in our list and sets their state foreach (var order in _orders) { if (order.Position.NetProfit > 0) { order.State = State.Gaining; } else if (order.Position.NetProfit < 0) { order.State = State.Loosing; } else { order.State = State.BreakingEven; } } } } }
@bjornvandekerkhof
PanagiotisCharalampous
13 Jun 2019, 14:49
Hi Bjorn,
Here it is
using System; using System.Linq; using System.Text; using cAlgo.API; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class DayTradeG1 : Robot { [Parameter("News Hour", DefaultValue = 14, MinValue = 0, MaxValue = 23)] public int NewsHour { get; set; } [Parameter("News Minute", DefaultValue = 30, MinValue = 0, MaxValue = 59)] public int NewsMinute { get; set; } [Parameter("Pips away", DefaultValue = 10)] public int PipsAway { get; set; } [Parameter("Take Profit", DefaultValue = 50)] public int TakeProfit { get; set; } [Parameter("Stop Loss", DefaultValue = 10)] public int StopLoss { get; set; } [Parameter("Volume", DefaultValue = 100000, MinValue = 10)] public int Volume { get; set; } [Parameter("Seconds Before", DefaultValue = 10, MinValue = 1)] public int SecondsBefore { get; set; } [Parameter("Seconds Timeout", DefaultValue = 10, MinValue = 1)] public int SecondsTimeout { get; set; } [Parameter("One Cancels Other")] public bool Oco { get; set; } [Parameter("ShowTimeLeftNews", DefaultValue = false)] public bool ShowTimeLeftToNews { get; set; } [Parameter("ShowTimeLeftPlaceOrders", DefaultValue = true)] public bool ShowTimeLeftToPlaceOrders { get; set; } [Parameter("Label", DefaultValue = "Label")] public string Label { get; set; } private bool _ordersCreated; private DateTime _triggerTimeInServerTimeZone; protected override void OnStart() { Positions.Opened += OnPositionOpened; Timer.Start(1); var triggerTimeInLocalTimeZone = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, NewsHour, NewsMinute, 0); if (triggerTimeInLocalTimeZone < DateTime.Now) triggerTimeInLocalTimeZone = triggerTimeInLocalTimeZone.AddDays(1); _triggerTimeInServerTimeZone = TimeZoneInfo.ConvertTime(triggerTimeInLocalTimeZone, TimeZoneInfo.Local, TimeZone); } protected override void OnTimer() { var remainingTime = _triggerTimeInServerTimeZone - Server.Time; DrawRemainingTime(remainingTime); if (!_ordersCreated) { var sellOrderTargetPrice = Symbol.Bid - PipsAway * Symbol.PipSize; ChartObjects.DrawHorizontalLine("sell target", sellOrderTargetPrice, Colors.Red, 1, LineStyle.DotsVeryRare); var buyOrderTargetPrice = Symbol.Ask + PipsAway * Symbol.PipSize; ChartObjects.DrawHorizontalLine("buy target", buyOrderTargetPrice, Colors.Blue, 1, LineStyle.DotsVeryRare); if (Server.Time <= _triggerTimeInServerTimeZone && (_triggerTimeInServerTimeZone - Server.Time).TotalSeconds <= SecondsBefore) { _ordersCreated = true; var expirationTime = _triggerTimeInServerTimeZone.AddSeconds(SecondsTimeout); PlaceStopOrder(TradeType.Sell, Symbol, Volume, sellOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime); PlaceStopOrder(TradeType.Buy, Symbol, Volume, buyOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime); ChartObjects.RemoveObject("sell target"); ChartObjects.RemoveObject("buy target"); } } if (_ordersCreated && !PendingOrders.Any(o => o.Label == Label)) { Print("Orders expired"); Stop(); } } private void DrawRemainingTime(TimeSpan remainingTimeToNews) { if (ShowTimeLeftToNews) { if (remainingTimeToNews > TimeSpan.Zero) { ChartObjects.DrawText("countdown1", "Time left to news: " + FormatTime(remainingTimeToNews), StaticPosition.TopLeft); } else { ChartObjects.RemoveObject("countdown1"); } } if (ShowTimeLeftToPlaceOrders) { var remainingTimeToOrders = remainingTimeToNews - TimeSpan.FromSeconds(SecondsBefore); if (remainingTimeToOrders > TimeSpan.Zero) { ChartObjects.DrawText("countdown2", "Time left to place orders: " + FormatTime(remainingTimeToOrders), StaticPosition.TopRight); } else { ChartObjects.RemoveObject("countdown2"); } } } private static StringBuilder FormatTime(TimeSpan remainingTime) { var remainingTimeStr = new StringBuilder(); if (remainingTime.TotalHours >= 1) remainingTimeStr.Append((int)remainingTime.TotalHours + "h "); if (remainingTime.TotalMinutes >= 1) remainingTimeStr.Append(remainingTime.Minutes + "m "); if (remainingTime.TotalSeconds > 0) remainingTimeStr.Append(remainingTime.Seconds + "s"); return remainingTimeStr; } private void OnPositionOpened(PositionOpenedEventArgs args) { var position = args.Position; if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (Oco) { foreach (var order in PendingOrders) { if (order.Label == Label && order.SymbolCode == Symbol.Code) { CancelPendingOrderAsync(order); } } } Stop(); } } } }
If you need assistance in changing your cBots, you can always reach out to a Consultant.
Best Regards,
Panagiotis
@PanagiotisCharalampous
bjornvandekerkhof
13 Jun 2019, 14:56
RE:
Panagiotis Charalampous said:
Hi Bjorn,
Here it is
using System; using System.Linq; using System.Text; using cAlgo.API; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class DayTradeG1 : Robot { [Parameter("News Hour", DefaultValue = 14, MinValue = 0, MaxValue = 23)] public int NewsHour { get; set; } [Parameter("News Minute", DefaultValue = 30, MinValue = 0, MaxValue = 59)] public int NewsMinute { get; set; } [Parameter("Pips away", DefaultValue = 10)] public int PipsAway { get; set; } [Parameter("Take Profit", DefaultValue = 50)] public int TakeProfit { get; set; } [Parameter("Stop Loss", DefaultValue = 10)] public int StopLoss { get; set; } [Parameter("Volume", DefaultValue = 100000, MinValue = 10)] public int Volume { get; set; } [Parameter("Seconds Before", DefaultValue = 10, MinValue = 1)] public int SecondsBefore { get; set; } [Parameter("Seconds Timeout", DefaultValue = 10, MinValue = 1)] public int SecondsTimeout { get; set; } [Parameter("One Cancels Other")] public bool Oco { get; set; } [Parameter("ShowTimeLeftNews", DefaultValue = false)] public bool ShowTimeLeftToNews { get; set; } [Parameter("ShowTimeLeftPlaceOrders", DefaultValue = true)] public bool ShowTimeLeftToPlaceOrders { get; set; } [Parameter("Label", DefaultValue = "Label")] public string Label { get; set; } private bool _ordersCreated; private DateTime _triggerTimeInServerTimeZone; protected override void OnStart() { Positions.Opened += OnPositionOpened; Timer.Start(1); var triggerTimeInLocalTimeZone = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, NewsHour, NewsMinute, 0); if (triggerTimeInLocalTimeZone < DateTime.Now) triggerTimeInLocalTimeZone = triggerTimeInLocalTimeZone.AddDays(1); _triggerTimeInServerTimeZone = TimeZoneInfo.ConvertTime(triggerTimeInLocalTimeZone, TimeZoneInfo.Local, TimeZone); } protected override void OnTimer() { var remainingTime = _triggerTimeInServerTimeZone - Server.Time; DrawRemainingTime(remainingTime); if (!_ordersCreated) { var sellOrderTargetPrice = Symbol.Bid - PipsAway * Symbol.PipSize; ChartObjects.DrawHorizontalLine("sell target", sellOrderTargetPrice, Colors.Red, 1, LineStyle.DotsVeryRare); var buyOrderTargetPrice = Symbol.Ask + PipsAway * Symbol.PipSize; ChartObjects.DrawHorizontalLine("buy target", buyOrderTargetPrice, Colors.Blue, 1, LineStyle.DotsVeryRare); if (Server.Time <= _triggerTimeInServerTimeZone && (_triggerTimeInServerTimeZone - Server.Time).TotalSeconds <= SecondsBefore) { _ordersCreated = true; var expirationTime = _triggerTimeInServerTimeZone.AddSeconds(SecondsTimeout); PlaceStopOrder(TradeType.Sell, Symbol, Volume, sellOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime); PlaceStopOrder(TradeType.Buy, Symbol, Volume, buyOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime); ChartObjects.RemoveObject("sell target"); ChartObjects.RemoveObject("buy target"); } } if (_ordersCreated && !PendingOrders.Any(o => o.Label == Label)) { Print("Orders expired"); Stop(); } } private void DrawRemainingTime(TimeSpan remainingTimeToNews) { if (ShowTimeLeftToNews) { if (remainingTimeToNews > TimeSpan.Zero) { ChartObjects.DrawText("countdown1", "Time left to news: " + FormatTime(remainingTimeToNews), StaticPosition.TopLeft); } else { ChartObjects.RemoveObject("countdown1"); } } if (ShowTimeLeftToPlaceOrders) { var remainingTimeToOrders = remainingTimeToNews - TimeSpan.FromSeconds(SecondsBefore); if (remainingTimeToOrders > TimeSpan.Zero) { ChartObjects.DrawText("countdown2", "Time left to place orders: " + FormatTime(remainingTimeToOrders), StaticPosition.TopRight); } else { ChartObjects.RemoveObject("countdown2"); } } } private static StringBuilder FormatTime(TimeSpan remainingTime) { var remainingTimeStr = new StringBuilder(); if (remainingTime.TotalHours >= 1) remainingTimeStr.Append((int)remainingTime.TotalHours + "h "); if (remainingTime.TotalMinutes >= 1) remainingTimeStr.Append(remainingTime.Minutes + "m "); if (remainingTime.TotalSeconds > 0) remainingTimeStr.Append(remainingTime.Seconds + "s"); return remainingTimeStr; } private void OnPositionOpened(PositionOpenedEventArgs args) { var position = args.Position; if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (Oco) { foreach (var order in PendingOrders) { if (order.Label == Label && order.SymbolCode == Symbol.Code) { CancelPendingOrderAsync(order); } } } Stop(); } } } }If you need assistance in changing your cBots, you can always reach out to a Consultant.
Best Regards,
Panagiotis
Hi Panagiotis,
Thank you very much, I am going to try that out.
and thank you for the Consulting advice too.
Best regards, Bjorn.
@bjornvandekerkhof
PanagiotisCharalampous
13 Jun 2019, 14:11
Hi bjornvandekerkhof,
Thanks for posting in our forum. You should try setting a different label for each instance's orders.
Best Regards,
Panagiotis
@PanagiotisCharalampous