I can only open one position on multiple bots and multiple instances
I can only open one position on multiple bots and multiple instances
05 Jan 2022, 12:44
Hi guys,
I am struggling with my bots to open more than one position. The bots, I plan to have multiple running at the same time, I am using will be multiple instances each with their own name.
Currently I can only get 1 position to open from multiple bots and multiple positions. I am pretty sure it is the position count part, but I am struggling with my code ability. The code below is a simple bot for example purpose, but has the same "open" and "close" functions as most of my other ones.
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.None)]
public class SuperTrend : Robot
{
#region User defined parameters
[Parameter("Instance Name", Group = "Parameters", DefaultValue = "001")]
public string InstanceName { get; set; }
[Parameter("Source MA", Group = "Long Trend Moving Average")]
public DataSeries Sourcehma { get; set; }
[Parameter("Moving Average Period", Group = "Long Trend Moving Average", DefaultValue = 200, MinValue = 10, MaxValue = 300)]
public int Periodshma { get; set; }
[Parameter("Moving Average Type", Group = "Long Trend Moving Average", DefaultValue = MovingAverageType.Exponential)]
public MovingAverageType MAType { get; set; }
[Parameter("Source MA", Group = "Fast Moving Average")]
public DataSeries Sourcema2 { get; set; }
[Parameter("Moving Average Period", Group = "Fast Moving Average", DefaultValue = 50, MinValue = 10, MaxValue = 80)]
public int Periodsma2 { get; set; }
[Parameter("Moving Average Type", Group = "Fast Moving Average", DefaultValue = MovingAverageType.Hull)]
public MovingAverageType MAType2 { get; set; }
[Parameter("ATR Stop Loss ", Group = "Money Management", DefaultValue = 2, MinValue = 0.5, MaxValue = 5, Step = 0.5)]
public double SLATR { get; set; }
[Parameter("ATR Take Profit ", Group = "Money Management", DefaultValue = 2, MinValue = 0.5, MaxValue = 5, Step = 0.5)]
public double TPATR { get; set; }
[Parameter("% per trade", Group = "Money Management", DefaultValue = 2, MinValue = 0.5, MaxValue = 4, Step = 0.2)]
public double PerTrade { get; set; }
[Parameter("Trigger (pips)", Group = "Optimiser", DefaultValue = 2.0, MinValue = 0, MaxValue = 10)]
public double TriggerPips { get; set; }
[Parameter("Trail SL (pips)", Group = "Optimiser", DefaultValue = 10.0, MinValue = 1, MaxValue = 100)]
public double TrailSLPips { get; set; }
[Parameter("Trail TP (pips)", Group = "Optimiser", DefaultValue = 10, MinValue = 1, MaxValue = 100)]
public double TrailTPPips { get; set; }
#endregion
#region Indicator declarations
private MovingAverage hma { get; set; }
private MovingAverage ma2 { get; set; }
private AverageTrueRange atr { get; set; }
/// These are for the trader optimiser function
Symbol currentSymbol;
Position currentPosition;
double? newStopLoss = 0;
double? newTakeProfit = 0;
int lookback;
#endregion
#region cTrader events
protected override void OnStart()
{
/// construct the indicators
atr = Indicators.AverageTrueRange(14, MovingAverageType.Exponential);
hma = Indicators.MovingAverage(Sourcehma, Periodshma, MAType);
ma2 = Indicators.MovingAverage(Sourcema2, Periodsma2, MAType2);
/// the MAType is from the independent moving average, not this indicator
}
/// <summary>
/// This method is called every time the price changes for the symbol
/// </summary>
protected override void OnTick()
{
var hmaline = hma.Result.Last(1);
var Prevhmaline = hma.Result.Last(2);
var Prev2hmaline = hma.Result.Last(3);
var hmaline2 = ma2.Result.Last(1);
var Prevhmaline2 = ma2.Result.Last(2);
var Prev2hmaline2 = ma2.Result.Last(3);
var zerovalue = 0;
var day = Server.Time.DayOfWeek;
if (day == DayOfWeek.Monday || day == DayOfWeek.Tuesday || day == DayOfWeek.Wednesday || day == DayOfWeek.Thursday || day == DayOfWeek.Friday || day == DayOfWeek.Saturday || day == DayOfWeek.Sunday)
{
///if (rsi.Result.HasCrossedAbove(RSILow, RSIlookback) && ma2.Result.HasCrossedBelow(atrband1up, atrbandlookback) && hmaline > Prev2hmaline && Bars.ClosePrices.Last(1) > hmaline && super1.UpTrend.Last(1) < Bars.LowPrices.Last(1))
if (hmaline > Prevhmaline)
{
ClosePositions(InstanceName, TradeType.Sell);
OpenPosition(InstanceName, TradeType.Buy);
}
else if (hmaline < Prev2hmaline)
{
ClosePositions(InstanceName, TradeType.Buy);
OpenPosition(InstanceName, TradeType.Sell);
}
}
foreach (var pos in Positions)
{
this.currentSymbol = Symbols.GetSymbol(SymbolName);
this.currentPosition = pos;
if (isNearTarget())
{
CalcNewValues();
AdjustPosition();
}
}
}
protected override void OnBar()
{
}
protected override void OnStop()
{
// unused
}
#endregion
#region Private Subs
private void OpenPosition(string Label, TradeType TradeDirection)
{
//Calculate Trade Amount base on the ATR
var PrevATR = Math.Round(atr.Result.Last(1) / Symbol.PipSize);
var PerTradeadjust = PerTrade / 100;
var TradeAmount = (Account.Equity * PerTradeadjust) / (PrevATR * Symbol.PipValue);
TradeAmount = Symbol.NormalizeVolumeInUnits(TradeAmount, RoundingMode.Down);
///var cBotPositions = Positions.FindAll(InstanceName); not used
{
if (Positions.Count(x => x.Label == InstanceName) == 0)
{
ExecuteMarketOrder(TradeDirection, SymbolName, TradeAmount, InstanceName, null, null);
}
}
}
private void ClosePositions(string Label, TradeType type)
{
var p = Positions.Find(InstanceName, this.Symbol, type);
if (p != null)
{
ClosePosition(p);
}
}
void CalcNewValues()
{
if (currentPosition.TradeType == TradeType.Buy)
{
newStopLoss = currentSymbol.Bid - (this.currentSymbol.PipSize * this.TrailSLPips);
newTakeProfit = currentSymbol.Bid + (this.currentSymbol.PipSize * this.TrailTPPips);
}
else
{
newStopLoss = currentSymbol.Ask + (this.currentSymbol.PipSize * this.TrailSLPips);
newTakeProfit = currentSymbol.Ask - (this.currentSymbol.PipSize * this.TrailTPPips);
}
}
void AdjustPosition()
{
if (newStopLoss == 0 || newTakeProfit == 0)
return;
ModifyPosition(currentPosition, newStopLoss, newTakeProfit);
}
bool isNearTarget()
{
if (this.currentPosition.TradeType == TradeType.Buy)
{
if (currentSymbol.Bid > this.currentPosition.TakeProfit - (this.currentSymbol.PipSize * this.TriggerPips))
return true;
}
else
{
if (currentSymbol.Ask < this.currentPosition.TakeProfit + (this.currentSymbol.PipSize * this.TriggerPips))
return true;
}
return false;
}
#endregion
}
}
amusleh
07 Jan 2022, 07:27 ( Updated at: 07 Jan 2022, 07:28 )
Hi,
You should use different values for your cBot "Instance Name" parameter for each instance, otherwise all the instances will only open one position.
Or you should change the code at:
@amusleh