Bot not creating pending orders for all instances
Bot not creating pending orders for all instances
08 Apr 2022, 09:51
Hi,
I have a bot that works in backtests and forward tests. The problem is that when I add multiple instances to the bot, the bot only makes pending orders for one of the pairs added.
I do need each instance to communicate with each other regarding volume updates (see PositionsOnClosed and how it uses _PendingOrders.Label), so I am unsure if giving each instance a pair-specific name will break this functionality.
Any advice would be appreciated, thanks!
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
public class DemoBot : Robot
{
[Parameter("Name", Group = "Global Settings", DefaultValue = "DemoBot")]
public string _name { get; set; }
[Parameter("High/Low Timeframe", Group = "Global Settings", DefaultValue = "Daily")]
public TimeFrame _hltf { get; set; }
[Parameter("Take Profit", Group = "Risk", DefaultValue = 15.0, MinValue = 0.1, MaxValue = 1000000.0)]
public double _takeprofit { get; set; }
[Parameter("Risk %", Group = "Risk", DefaultValue = 1.0, MinValue = 0.1, MaxValue = 100.0)]
public double _riskpercent { get; set; }
[Parameter("Stop Loss", Group = "Risk", DefaultValue = 10.0, MinValue = 0.1, MaxValue = 1000000.0)]
public double _stoploss { get; set; }
[Parameter("Safety (Pips)", Group = "Risk", DefaultValue = 3.0, MinValue = 0.1, MaxValue = 10000.0)]
public double _safety { get; set; }
private Bars _hlbars;
private double _previoushigh, _previouslow, _volume;
private bool _todaybuyhappened, _todaysellhappened;
protected override void OnStart()
{
_hlbars = MarketData.GetBars(_hltf);
_hlbars.BarOpened += _hlbars_BarOpened;
_safety *= Symbol.PipSize;
Positions.Closed += PositionsOnClosed;
_todaybuyhappened = true;
_todaysellhappened = true;
}
private void _hlbars_BarOpened(BarOpenedEventArgs obj)
{
_todaybuyhappened = false;
_todaysellhappened = false;
foreach (var _PendingOrders in PendingOrders)
{
if (_PendingOrders.Label == _name)
{
CancelPendingOrder(_PendingOrders);
}
}
if (_hlbars.OpenPrices.Last(0) > _hlbars.HighPrices.Last(1))
{
_todaybuyhappened = true;
}
if (_hlbars.OpenPrices.Last(0) < _hlbars.LowPrices.Last(1))
{
_todaysellhappened = true;
}
_volume = GetVolume();
_previoushigh = Math.Abs(_hlbars.HighPrices.Last(1) + _safety);
_previouslow = Math.Abs(_hlbars.LowPrices.Last(1) - _safety);
if (!_todaybuyhappened)
{
PlaceStopOrder(TradeType.Buy, Symbol.Name, _volume, _previoushigh, _name, _stoploss, _takeprofit);
_todaybuyhappened = true;
}
if (!_todaysellhappened)
{
PlaceStopOrder(TradeType.Sell, Symbol.Name, _volume, _previouslow, _name, _stoploss, _takeprofit);
_todaysellhappened = true;
}
}
private void PositionsOnClosed(PositionClosedEventArgs args)
{
_volume = GetVolume();
foreach (var _PendingOrders in PendingOrders)
{
if (_PendingOrders.Label == _name)
{
if (_PendingOrders.VolumeInUnits != _volume)
{
_PendingOrders.ModifyVolume(_volume);
}
}
}
}
private double GetVolume()
{
double costPerPip = (double)((int)(Symbol.PipValue * 10000000)) / 100;
double baseNumber = Account.Balance;
double sizeInLots = Math.Round((baseNumber * _riskpercent / 100) / (_stoploss * costPerPip), 2);
var result = Symbol.QuantityToVolumeInUnits(sizeInLots);
if (result > Symbol.VolumeInUnitsMax)
{
result = Symbol.VolumeInUnitsMax;
}
else if (result < Symbol.VolumeInUnitsMin)
{
result = Symbol.VolumeInUnitsMin;
}
else if (result % Symbol.VolumeInUnitsStep != 0)
{
result = result - (result % Symbol.VolumeInUnitsStep);
}
return result;
}
}
}
Replies
waym77
11 Apr 2022, 07:25
RE:
amusleh said:
Hi,
You can separate each instance orders by using the Symbol name, example:
using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; using System.Collections.Generic; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)] public class DemoBot : Robot { [Parameter("Name", Group = "Global Settings", DefaultValue = "DemoBot")] public string _name { get; set; } [Parameter("High/Low Timeframe", Group = "Global Settings", DefaultValue = "Daily")] public TimeFrame _hltf { get; set; } [Parameter("Take Profit", Group = "Risk", DefaultValue = 15.0, MinValue = 0.1, MaxValue = 1000000.0)] public double _takeprofit { get; set; } [Parameter("Risk %", Group = "Risk", DefaultValue = 1.0, MinValue = 0.1, MaxValue = 100.0)] public double _riskpercent { get; set; } [Parameter("Stop Loss", Group = "Risk", DefaultValue = 10.0, MinValue = 0.1, MaxValue = 1000000.0)] public double _stoploss { get; set; } [Parameter("Safety (Pips)", Group = "Risk", DefaultValue = 3.0, MinValue = 0.1, MaxValue = 10000.0)] public double _safety { get; set; } private Bars _hlbars; private double _previoushigh, _previouslow, _volume; private bool _todaybuyhappened, _todaysellhappened; public IEnumerable<PendingOrder> BotPendingOrders { get { return PendingOrders.Where(order => order.SymbolName.Equals(SymbolName, StringComparison.Ordinal) && order.Label.Equals(_name, StringComparison.Ordinal)); } } protected override void OnStart() { _hlbars = MarketData.GetBars(_hltf); _hlbars.BarOpened += _hlbars_BarOpened; _safety *= Symbol.PipSize; Positions.Closed += PositionsOnClosed; _todaybuyhappened = true; _todaysellhappened = true; } private void _hlbars_BarOpened(BarOpenedEventArgs obj) { _todaybuyhappened = false; _todaysellhappened = false; foreach (var _PendingOrders in BotPendingOrders) { CancelPendingOrder(_PendingOrders); } if (_hlbars.OpenPrices.Last(0) > _hlbars.HighPrices.Last(1)) { _todaybuyhappened = true; } if (_hlbars.OpenPrices.Last(0) < _hlbars.LowPrices.Last(1)) { _todaysellhappened = true; } _volume = GetVolume(); _previoushigh = Math.Abs(_hlbars.HighPrices.Last(1) + _safety); _previouslow = Math.Abs(_hlbars.LowPrices.Last(1) - _safety); if (!_todaybuyhappened) { PlaceStopOrder(TradeType.Buy, Symbol.Name, _volume, _previoushigh, _name, _stoploss, _takeprofit); _todaybuyhappened = true; } if (!_todaysellhappened) { PlaceStopOrder(TradeType.Sell, Symbol.Name, _volume, _previouslow, _name, _stoploss, _takeprofit); _todaysellhappened = true; } } private void PositionsOnClosed(PositionClosedEventArgs args) { _volume = GetVolume(); foreach (var _PendingOrders in BotPendingOrders) { if (_PendingOrders.VolumeInUnits != _volume) { _PendingOrders.ModifyVolume(_volume); } } } private double GetVolume() { double costPerPip = (double)((int)(Symbol.PipValue * 10000000)) / 100; double baseNumber = Account.Balance; double sizeInLots = Math.Round((baseNumber * _riskpercent / 100) / (_stoploss * costPerPip), 2); var result = Symbol.QuantityToVolumeInUnits(sizeInLots); if (result > Symbol.VolumeInUnitsMax) { result = Symbol.VolumeInUnitsMax; } else if (result < Symbol.VolumeInUnitsMin) { result = Symbol.VolumeInUnitsMin; } else if (result % Symbol.VolumeInUnitsStep != 0) { result = result - (result % Symbol.VolumeInUnitsStep); } return result; } } }
The BotPendingOrders enumerable will give you only those orders that are from same symbol and with same Label.
Hi, this works perfectly, thanks!
@waym77
amusleh
08 Apr 2022, 10:40
Hi,
You can separate each instance orders by using the Symbol name, example:
The BotPendingOrders enumerable will give you only those orders that are from same symbol and with same Label.
@amusleh