Topics
Replies
hejnekem
07 Apr 2022, 14:17
( Updated at: 07 Apr 2022, 14:19 )
RE:
amusleh said:
Hi,
I think you have to re-write the Bot based on new cTrader Automate API, specifically those Trade calls.
I rewrote it, but it still doesnt work, I cant run two instances side by side.
[Parameter(DefaultValue = 10000, MinValue = 1000)]
public int FirstLot { get; set; }
[Parameter(DefaultValue = 10000, MinValue = 1000)]
public int LotStep { get; set; }
[Parameter("Stop_Loss", DefaultValue = 50, MinValue = 0)]
public int Stop_Loss { get; set; }
[Parameter("Take_Profit", DefaultValue = 180, MinValue = 10)]
public int TakeProfit { get; set; }
[Parameter("Tral_Start", DefaultValue = 50, MinValue = 10)]
public int Tral_Start { get; set; }
[Parameter("Tral_Stop", DefaultValue = 50, MinValue = 10)]
public int Tral_Stop { get; set; }
[Parameter(DefaultValue = 5, MinValue = 2)]
public int MaxOrders { get; set; }
private Position position;
private bool RobotStopped;
private string botLabel;
protected override void OnStart()
{
botLabel = ToString();
Positions.Opened += OnPositionOpened;
}
protected override void OnTick()
{
double Bid = Symbol.Bid;
double Ask = Symbol.Ask;
double Point = Symbol.TickSize;
if (Trade.IsExecuting)
return;
if (Positions.Count > 0 && RobotStopped)
return;
else
RobotStopped = false;
if (Positions.Count == 0)
SendFirstOrder(FirstLot);
else
ControlSeries();
foreach (var position in Positions.FindAll(botLabel, SymbolName))
{
if (position.SymbolName == Symbol.Name)
{
if (position.TradeType == TradeType.Buy)
{
if (Bid - GetAveragePrice(TradeType.Buy) >= Tral_Start * Point)
if (Bid - Tral_Stop * Point >= position.StopLoss)
ModifyPosition(position, Bid - Tral_Stop * Point,
position.TakeProfit);
}
if (position.TradeType == TradeType.Sell)
{
if (GetAveragePrice(TradeType.Sell) - Ask >= Tral_Start * Point)
if (Ask + Tral_Stop * Point <= position.StopLoss || position.StopLoss
== 0)
ModifyPosition(position, Ask + Tral_Stop * Point,
position.TakeProfit);
}
}
}
}
protected override void OnError(Error CodeOfError)
{
if (CodeOfError.Code == ErrorCode.NoMoney)
{
RobotStopped = true;
Print("ERROR!!! No money for order open, robot is stopped!");
}
else if (CodeOfError.Code == ErrorCode.BadVolume)
{
RobotStopped = true;
Print("ERROR!!! Bad volume for order open, robot is stopped!");
}
}
private void SendFirstOrder(int OrderVolume)
{
int Signal = GetStdIlanSignal();
if (!(Signal < 0))
switch (Signal)
{
case 0:
ExecuteMarketOrder(TradeType.Buy, SymbolName, OrderVolume, botLabel);
break;
case 1:
ExecuteMarketOrder(TradeType.Sell, SymbolName, OrderVolume, botLabel);
break;
}
}
private void OnPositionOpened(PositionOpenedEventArgs args)
{
double? StopLossPrice = null;
double? TakeProfitPrice = null;
if (Positions.Count == 1)
{
position = args.Position;
if (position.TradeType == TradeType.Buy)
TakeProfitPrice = position.EntryPrice + TakeProfit * Symbol.TickSize;
if (position.TradeType == TradeType.Sell)
TakeProfitPrice = position.EntryPrice - TakeProfit * Symbol.TickSize;
}
else
switch (GetPositionsSide())
{
case 0:
TakeProfitPrice = GetAveragePrice(TradeType.Buy) + TakeProfit *
Symbol.TickSize;
break;
case 1:
TakeProfitPrice = GetAveragePrice(TradeType.Sell) - TakeProfit *
Symbol.TickSize;
break;
}
for (int i = 0; i < Positions.Count; i++)
{
position = Positions[i];
if (StopLossPrice != null || TakeProfitPrice != null)
ModifyPosition(position, position.StopLoss, TakeProfitPrice);
}
}
private double GetAveragePrice(TradeType TypeOfTrade)
{
double Result = Symbol.Bid;
double AveragePrice = 0;
long Count = 0;
for (int i = 0; i < Positions.Count; i++)
{
position = Positions[i];
if (position.TradeType == TypeOfTrade)
{
AveragePrice += position.EntryPrice * position.Volume;
Count += position.Volume;
}
}
if (AveragePrice > 0 && Count > 0)
Result = AveragePrice / Count;
return Result;
}
private int GetPositionsSide()
{
int Result = -1;
int i, BuySide = 0, SellSide = 0;
for (i = 0; i < Positions.Count; i++)
{
if (Positions[i].TradeType == TradeType.Buy)
BuySide++;
if (Positions[i].TradeType == TradeType.Sell)
SellSide++;
}
if (BuySide == Positions.Count)
Result = 0;
if (SellSide == Positions.Count)
Result = 1;
return Result;
}
private void ControlSeries()
{
const int BarCount = 25;
int gradient = MaxOrders - 1;
foreach (Position position in Positions.FindAll(botLabel, SymbolName))
{
if (-position.Pips > Stop_Loss)
ClosePosition(position);
}
int _pipstep = GetDynamicPipstep(BarCount, gradient);
if (Positions.Count < MaxOrders)
{
long NewVolume = Symbol.NormalizeVolume(FirstLot + FirstLot * Positions.Count,
RoundingMode.ToNearest);
int positionSide = GetPositionsSide();
switch (positionSide)
{
case 0:
if (Symbol.Ask < FindLastPrice(TradeType.Buy) - _pipstep *
Symbol.TickSize)
{
if (NewVolume >= LotStep)
ExecuteMarketOrder(TradeType.Buy, SymbolName, NewVolume,
botLabel);
}
break;
case 1:
if (Symbol.Bid > FindLastPrice(TradeType.Sell) + _pipstep *
Symbol.TickSize)
{
if (NewVolume >= LotStep)
ExecuteMarketOrder(TradeType.Sell, SymbolName, NewVolume,
botLabel);
}
break;
}
}
}
private int GetDynamicPipstep(int CountOfBars, int gradient)
{
int Result;
double HighestPrice = 0, LowestPrice = 0;
int StartBar = Bars.ClosePrices.Count - 2 - CountOfBars;
int EndBar = Bars.ClosePrices.Count - 2;
for (int i = StartBar; i < EndBar; i++)
{
if (HighestPrice == 0 && LowestPrice == 0)
{
HighestPrice = Bars.HighPrices[i];
LowestPrice = Bars.LowPrices[i];
continue;
}
if (Bars.HighPrices[i] > HighestPrice)
HighestPrice = Bars.HighPrices[i];
if (Bars.LowPrices[i] < LowestPrice)
LowestPrice = Bars.LowPrices[i];
}
Result = (int)((HighestPrice - LowestPrice) / Symbol.TickSize / gradient);
return Result;
}
private double FindLastPrice(TradeType TypeOfTrade)
{
double LastPrice = 0;
for (int i = 0; i < Positions.Count; i++)
{
position = Positions[i];
if (TypeOfTrade == TradeType.Buy)
if (position.TradeType == TypeOfTrade)
{
if (LastPrice == 0)
{
LastPrice = position.EntryPrice;
continue;
}
if (position.EntryPrice < LastPrice)
LastPrice = position.EntryPrice;
}
if (TypeOfTrade == TradeType.Sell)
if (position.TradeType == TypeOfTrade)
{
if (LastPrice == 0)
{
LastPrice = position.EntryPrice;
continue;
}
if (position.EntryPrice > LastPrice)
LastPrice = position.EntryPrice;
}
}
return LastPrice;
}
private int GetStdIlanSignal()
{
int Result = -1;
int LastBarIndex = Bars.ClosePrices.Count - 2;
int PrevBarIndex = LastBarIndex - 1;
if (Bars.ClosePrices[LastBarIndex] > Bars.OpenPrices[LastBarIndex])
if (Bars.ClosePrices[PrevBarIndex] > Bars.OpenPrices[PrevBarIndex])
Result = 0;
if (Bars.ClosePrices[LastBarIndex] < Bars.OpenPrices[LastBarIndex])
if (Bars.ClosePrices[PrevBarIndex] < Bars.OpenPrices[PrevBarIndex])
Result = 1;
return Result;
}
@hejnekem
hejnekem
05 Apr 2022, 15:10
( Updated at: 21 Dec 2023, 09:22 )
RE: RE: RE:
amusleh said:
hejnekem said:
firemyst said:
> Hi, I would like to run this bot on different instances, but I couldnt do it. I tried label and symbol too.
What do you mean?
To run multiple instances of a bot, just add more "instances" under the bot and choose the symbol you want to run it against.
Example:
In teh above, one instance will run on EURUSD H1 timeframe, the other bot will run under the US30 symbol.
It doesnt work, because when I start a second instance it doesnt start, other times the first instance closes the second one.
Hi,
Are you sure it's a cTrader cBot code? It uses some APIs that is not part of cTrader automate API.
I am not sure, it's an old cbot. Should I fix the code so that would solve my problem?
@hejnekem
hejnekem
05 Apr 2022, 12:52
( Updated at: 21 Dec 2023, 09:22 )
RE:
firemyst said:
> Hi, I would like to run this bot on different instances, but I couldnt do it. I tried label and symbol too.
What do you mean?
To run multiple instances of a bot, just add more "instances" under the bot and choose the symbol you want to run it against.
Example:
In teh above, one instance will run on EURUSD H1 timeframe, the other bot will run under the US30 symbol.
It doesnt work, because when I start a second instance it doesnt start, other times the first instance closes the second one.
@hejnekem
hejnekem
08 Apr 2022, 11:37
RE:
amusleh said:
OK, thanks for your help!
@hejnekem