I am not sure what the problem is but if you subscribe to market data using 35=V, then you will receive 35=W and 35=X responses, which are real market data.
hello can I get the script for sample advanced take profit
I dont know what I did it just stop playing thank you hanselkate@outlook.com
Hi there,
Here it is
// -------------------------------------------------------------------------------------------------
//
// This code is a cTrader Automate API example.
//
// This cBot is intended to be used as a sample and does not guarantee any particular outcome or
// profit of any kind. Use it at your own risk.
//
// All changes to this file might be lost on the next application update.
// If you are going to modify this file please make a copy using the "Duplicate" command.
//
// -------------------------------------------------------------------------------------------------
using System;
using System.Linq;
using cAlgo.API;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class SampleAdvancedTakeProfit : Robot
{
private const string DefaultPositionIdParameterValue = "PID";
[Parameter("Position Id", Group = "Position", DefaultValue = DefaultPositionIdParameterValue)]
public string PositionId { get; set; }
[Parameter("Enabled", Group = "Take Profit 1", DefaultValue = false)]
public bool TakeProfit1Enabled { get; set; }
[Parameter("Pips", Group = "Take Profit 1", DefaultValue = 10)]
public double TakeProfit1Pips { get; set; }
[Parameter("Volume", Group = "Take Profit 1", DefaultValue = 1000)]
public int TakeProfit1Volume { get; set; }
[Parameter("Enabled", Group = "Take Profit 2", DefaultValue = false)]
public bool TakeProfit2Enabled { get; set; }
[Parameter("Pips", Group = "Take Profit 2", DefaultValue = 20)]
public double TakeProfit2Pips { get; set; }
[Parameter("Volume", Group = "Take Profit 2", DefaultValue = 2000)]
public int TakeProfit2Volume { get; set; }
[Parameter("Enabled", Group = "Take Profit 3", DefaultValue = false)]
public bool TakeProfit3Enabled { get; set; }
[Parameter("Pips", Group = "Take Profit 3", DefaultValue = 10)]
public double TakeProfit3Pips { get; set; }
[Parameter("Volume", Group = "Take Profit 3", DefaultValue = 3000)]
public int TakeProfit3Volume { get; set; }
private TakeProfitLevel[] _levels;
private SymbolInfo _symbolInfo;
protected override void OnStart()
{
if (PositionId == DefaultPositionIdParameterValue)
PrintErrorAndStop("You have to specify \"Position Id\" in cBot Parameters");
var position = FindPositionOrStop();
_symbolInfo = Symbols.GetSymbolInfo(position.SymbolName);
_levels = GetTakeProfitLevels();
ValidateLevels(position);
}
private void ValidateLevels(Position position)
{
MakeSureAnyLevelEnabled();
ValidateTotalVolume(position);
ValidateReachedLevels(position);
ValidateVolumes();
}
private void ValidateVolumes()
{
var enabledLevels = _levels.Where(level => level.IsEnabled);
foreach (var level in enabledLevels)
{
if (level.Volume < _symbolInfo.VolumeInUnitsMin)
PrintErrorAndStop("Volume for " + _symbolInfo.Name + " cannot be less than " + _symbolInfo.VolumeInUnitsMin);
if (level.Volume > _symbolInfo.VolumeInUnitsMax)
PrintErrorAndStop("Volume for " + _symbolInfo.Name + " cannot be greater than " + _symbolInfo.VolumeInUnitsMax);
if (level.Volume % _symbolInfo.VolumeInUnitsMin != 0)
PrintErrorAndStop("Volume " + level.Volume + " is invalid");
}
}
private void ValidateReachedLevels(Position position)
{
var reachedLevel = _levels.FirstOrDefault(l => l.Pips <= position.Pips);
if (reachedLevel != null)
PrintErrorAndStop("Level " + reachedLevel.Name + " is already reached. The amount of Pips must be more than the amount of Pips that the Position is already gaining");
}
private void MakeSureAnyLevelEnabled()
{
if (_levels.All(level => !level.IsEnabled))
PrintErrorAndStop("You have to enable at least one \"Take Profit\" in cBot Parameters");
}
private void ValidateTotalVolume(Position position)
{
var totalVolume = _levels.Where(level => level.IsEnabled).Sum(level => level.Volume);
if (totalVolume > position.VolumeInUnits)
PrintErrorAndStop("The sum of all Take Profit respective volumes cannot be larger than the Position's volume");
}
private TakeProfitLevel[] GetTakeProfitLevels()
{
return new[]
{
new TakeProfitLevel("Take Profit 1", TakeProfit1Enabled, TakeProfit1Pips, TakeProfit1Volume),
new TakeProfitLevel("Take Profit 2", TakeProfit2Enabled, TakeProfit2Pips, TakeProfit2Volume),
new TakeProfitLevel("Take Profit 3", TakeProfit3Enabled, TakeProfit3Pips, TakeProfit3Volume)
};
}
private Position FindPositionOrStop()
{
var position = Positions.FirstOrDefault(p => "PID" + p.Id == PositionId || p.Id.ToString() == PositionId);
if (position == null)
PrintErrorAndStop("Position with Id = " + PositionId + " doesn't exist");
return position;
}
private void PrintErrorAndStop(string errorMessage)
{
Print(errorMessage);
Stop();
throw new Exception(errorMessage);
}
protected override void OnTick()
{
var position = FindPositionOrStop();
var reachedLevels = _levels.Where(level => level.IsEnabled && !level.IsTriggered && level.Pips <= position.Pips);
foreach (var reachedLevel in reachedLevels)
{
reachedLevel.MarkAsTriggered();
Print("Level \"" + reachedLevel.Name + "\" is reached. Level.Pips: " + reachedLevel.Pips + ", Position.Pips: " + position.Pips + ", Position.Id: " + position.Id);
var volumeToClose = Math.Min(reachedLevel.Volume, position.VolumeInUnits);
ClosePosition(position, volumeToClose);
if (!LastResult.IsSuccessful)
Print("Cannot close position, Id: " + position.Id + ", Error: " + LastResult.Error);
var remainingLevels = _levels.Where(level => level.IsEnabled && !level.IsTriggered);
if (!remainingLevels.Any())
{
Print("All levels were reached. cBot is stopping...");
Stop();
return;
}
}
}
}
internal class TakeProfitLevel
{
public TakeProfitLevel(string name, bool isEnabled, double pips, int volume)
{
Name = name;
IsEnabled = isEnabled;
Pips = pips;
Volume = volume;
}
public string Name { get; private set; }
public bool IsEnabled { get; private set; }
public double Pips { get; private set; }
public int Volume { get; private set; }
public bool IsTriggered { get; private set; }
public void MarkAsTriggered()
{
IsTriggered = true;
}
}
}
The bug is in your code. The difference between visual and non visual is that in visual mode, the indicator is calculated on every tick, while in non visual mode, the indicator is calculated once at the end of the backtesting. So in visual mode, your condition will become true at some tick while in non visual mode, it will never become true, since the calculate method is only called once per bar, considering only the closed prices.
I would suggest you use High/Low values instead of Close values to resolve the problem.
I don't think this was ever working. When the indicator is unloaded and destroyed, all references created by the indicator will do as well, same for the indicator's log. If you want to check this, write in an external file.
Please provide us with dates, cBot parameters and backtesting settings so that we can reproduce this behavior on backtesting. Also share some screenshots demonstrating these positions.
Best regards,
Panagiotis
Parameters are the default ones built into the bot as it's just an example and it's what I used to replicate. Back testing was a number of markets (forex, spot metals, spot indices, crypto, whatever else I tested it on) and dates are anything available in the range of 2013 - now that runs for longer than 100 trades. Tested on both 1m, the 2h and 15m charts I was testing on and tick data.
See below to show that the balance and equity is basically full but margin is more than the balance of the account:
And then you can see here the only position I have open is minimum lot size:
Thanks Vik,
We managed to reproduce the problem and it will be fixed in an upcoming update.
Best regards,
Panagiotis
Ah fantastic, glad to see it wasn't something I was doing! You got a rough timeframe on when that update may be?
Unfortunately we do not have a timeframe at the moment
PanagiotisCharalampous hey mate the issue seems to have returned again? It was working fine after the last update but I'm running into it again.
Hi there,
Can you share new screenshots showing the version as well?
Best regards,
Panagiotis
Thank you, the fix for this issue was not released yet. It will be released in an upcoming update.
Please provide us with dates, cBot parameters and backtesting settings so that we can reproduce this behavior on backtesting. Also share some screenshots demonstrating these positions.
Best regards,
Panagiotis
Parameters are the default ones built into the bot as it's just an example and it's what I used to replicate. Back testing was a number of markets (forex, spot metals, spot indices, crypto, whatever else I tested it on) and dates are anything available in the range of 2013 - now that runs for longer than 100 trades. Tested on both 1m, the 2h and 15m charts I was testing on and tick data.
See below to show that the balance and equity is basically full but margin is more than the balance of the account:
And then you can see here the only position I have open is minimum lot size:
Thanks Vik,
We managed to reproduce the problem and it will be fixed in an upcoming update.
Best regards,
Panagiotis
Ah fantastic, glad to see it wasn't something I was doing! You got a rough timeframe on when that update may be?
Unfortunately we do not have a timeframe at the moment
PanagiotisCharalampous hey mate the issue seems to have returned again? It was working fine after the last update but I'm running into it again.
Hi there,
Can you share new screenshots showing the version as well?
I cannot reproduce such an issue. Can you demonstrate this problem with screenshots e.g. comparing desktop and web and showing that the trades are missing from the desktop?
PanagiotisCharalampous
21 Jun 2024, 05:52
Hi there,
Please share the actual code so that we can reproduce what you are looking at.
Best regards,
Panagiotis
@PanagiotisCharalampous