Topics
Forum Topics not found
Replies
amusleh
16 May 2022, 09:57
( Updated at: 16 May 2022, 09:58 )
Hi,
There are several issues on your code, and you have to remember that Fractals are lagging indicator, and you have to access it's x previous values based on the period to passed to it.
Try this:
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 NewcBot : Robot
{
private double _volumeInUnits;
private Fractals _fractals;
private SimpleMovingAverage _sma;
[Parameter(DefaultValue = 20)]
public int Period { get; set; }
[Parameter("Source")]
public DataSeries Source { get; set; }
[Parameter("Volume (Lots)", DefaultValue = 0.5)]
public double VolumeInLots { get; set; }
[Parameter("Stop Loss (Pips)", DefaultValue = 20)]
public double StopLossInPips { get; set; }
[Parameter("Take Profit (Pips)", DefaultValue = 60)]
public double TakeProfitInPips { get; set; }
[Parameter("Label", DefaultValue = "Sample")]
public string Label { get; set; }
private Position[] BotPositions
{
get { return Positions.FindAll(Label); }
}
protected override void OnStart()
{
_sma = Indicators.SimpleMovingAverage(Source, Period);
_volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots);
_fractals = Indicators.Fractals(5);
}
protected override void OnBar()
{
double close = Bars.ClosePrices.Last(1);
double sma = _sma.Result.Last(1);
double upfr = _fractals.UpFractal.Last(5);
double dwfr = _fractals.DownFractal.Last(5);
if (upfr < close)
{
ClosePositions(TradeType.Sell);
if (sma < close && Positions.Count == 0)
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
}
}
else if (dwfr > close)
{
ClosePositions(TradeType.Buy);
if (sma > close && Positions.Count == 0)
{
ExecuteMarketOrder(TradeType.Sell, SymbolName, _volumeInUnits, Label, StopLossInPips, TakeProfitInPips);
}
}
}
private void ClosePositions(TradeType tradeType)
{
foreach (var position in BotPositions)
{
if (position.TradeType != tradeType)
continue;
ClosePosition(position);
}
}
}
}
@amusleh
amusleh
16 May 2022, 09:36
Hi,
The index is the current chart bars index, not the index of time frame that you loaded.
You have to change the index to the loaded time frame bars index first then use it, try this:
using cAlgo.API;
namespace cAlgo
{
[Indicator(IsOverlay = true, AccessRights = AccessRights.None, TimeZone = TimeZones.EAfricaStandardTime)]
public class Spring : Indicator
{
[Output("Up Fractal", Color = Colors.Red, PlotType = PlotType.Points, Thickness = 5)]
public IndicatorDataSeries UpFractal { get; set; }
[Output("Down Fractal", Color = Colors.Blue, PlotType = PlotType.Points, Thickness = 5)]
public IndicatorDataSeries DownFractal { get; set; }
private Bars HSeries;
protected override void Initialize()
{
HSeries = MarketData.GetBars(TimeFrame.Hour4);
}
public override void Calculate(int index)
{
if (index == 1)
return;
DrawUpFractal(index);
DrawDownFractal(index);
}
private void DrawUpFractal(int index)
{
var hSeriesIndex = HSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
int middleIndex = hSeriesIndex - 2;
double middleValue = HSeries.ClosePrices[middleIndex];
bool up = false;
for (int i = 1; i < HSeries.ClosePrices.Count - 1; i++)
{
if (HSeries.ClosePrices[middleIndex] > HSeries.ClosePrices[middleIndex - 1] && HSeries.ClosePrices[middleIndex] > HSeries.ClosePrices[middleIndex + 1])
{
up = true;
break;
}
}
if (up)
UpFractal[index] = middleValue;
}
private void DrawDownFractal(int index)
{
var hSeriesIndex = HSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
int middleIndex = hSeriesIndex - 2;
double middleValue = HSeries.ClosePrices[middleIndex];
bool down = false;
for (int i = 1; i < HSeries.ClosePrices.Count - 1; i++)
{
if (HSeries.ClosePrices[middleIndex] < HSeries.ClosePrices[middleIndex - 1] && HSeries.ClosePrices[middleIndex] < HSeries.ClosePrices[middleIndex + 1])
{
down = true;
break;
}
}
if (down)
DownFractal[index] = middleValue;
}
}
}
@amusleh
amusleh
13 May 2022, 11:18
RE: RE: still unable to connect to my live accounts
mcm187 said:
amusleh said:
Hi,
We are aware of this issue, it will be fixed as soon as possible.
Hi Amusleh do you have an estimated time for when this will be resolved?
Three days have passed and I am still unable to connect to my live accounts?
it is very frustrating when I am managing several accounts and my investment portfolios doing nothing every day that I am unable to connect to them is a major problem and costly
Hi,
We are still trying to resolve this issue on our Europe proxies, for the time being please try other proxies and flushing your system DNS cache.
@amusleh
amusleh
13 May 2022, 10:32
Hi,
Try this:
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Indicators
{
[Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
public class IchimokuKinkoHyo : Indicator
{
private int _lastAlertBar;
[Parameter(DefaultValue = 9)]
public int periodFast { get; set; }
[Parameter(DefaultValue = 26)]
public int periodMedium { get; set; }
[Parameter(DefaultValue = 52)]
public int periodSlow { get; set; }
[Parameter(DefaultValue = 26)]
public int DisplacementChikou { get; set; }
[Parameter(DefaultValue = 26)]
public int DisplacementCloud { get; set; }
[Parameter("Enable", DefaultValue = true, Group = "Alert")]
public bool IsAlertEnabled { get; set; }
[Parameter("Sound File Path", Group = "Alert")]
public string SoundFilePath { get; set; }
[Parameter("From Email", Group = "Alert")]
public string FromEmail { get; set; }
[Parameter("To Email", Group = "Alert")]
public string ToEmail { get; set; }
[Output("TenkanSen", Color = Colors.Red)]
public IndicatorDataSeries TenkanSen { get; set; }
[Output("Kijunsen", Color = Colors.Blue)]
public IndicatorDataSeries KijunSen { get; set; }
[Output("ChikouSpan", Color = Colors.DarkViolet)]
public IndicatorDataSeries ChikouSpan { get; set; }
[Output("SenkouSpanB", Color = Colors.Red, LineStyle = LineStyle.Lines)]
public IndicatorDataSeries SenkouSpanB { get; set; }
[Output("SenkouSpanA", Color = Colors.Green, LineStyle = LineStyle.Lines)]
public IndicatorDataSeries SenkouSpanA { get; set; }
private double maxfast, minfast, maxmedium, minmedium, maxslow, minslow;
public override void Calculate(int index)
{
if ((index < periodFast) || (index < periodSlow)) { return; }
maxfast = MarketSeries.High[index];
minfast = MarketSeries.Low[index];
maxmedium = MarketSeries.High[index];
minmedium = MarketSeries.Low[index];
maxslow = MarketSeries.High[index];
minslow = MarketSeries.Low[index];
for (int i = 0; i < periodFast; i++)
{
if (maxfast < MarketSeries.High[index - i]) { maxfast = MarketSeries.High[index - i]; }
if (minfast > MarketSeries.Low[index - i]) { minfast = MarketSeries.Low[index - i]; }
}
for (int i = 0; i < periodMedium; i++)
{
if (maxmedium < MarketSeries.High[index - i]) { maxmedium = MarketSeries.High[index - i]; }
if (minmedium > MarketSeries.Low[index - i]) { minmedium = MarketSeries.Low[index - i]; }
}
for (int i = 0; i < periodSlow; i++)
{
if (maxslow < MarketSeries.High[index - i]) { maxslow = MarketSeries.High[index - i]; }
if (minslow > MarketSeries.Low[index - i]) { minslow = MarketSeries.Low[index - i]; }
}
TenkanSen[index] = (maxfast + minfast) / 2;
KijunSen[index] = (maxmedium + minmedium) / 2;
ChikouSpan[index - DisplacementChikou] = MarketSeries.Close[index];
SenkouSpanA[index + DisplacementCloud] = (TenkanSen[index] + KijunSen[index]) / 2;
SenkouSpanB[index + DisplacementCloud] = (maxslow + minslow) / 2;
if (IsLastBar && IsAlertEnabled && _lastAlertBar != index)
{
_lastAlertBar = index;
if (TenkanSen.HasCrossedAbove(KijunSen, 0))
{
Notifications.PlaySound(SoundFilePath);
Notifications.SendEmail(FromEmail, ToEmail, "Ichimoku kinku hyo Alert | Bullish", "TenkanSen crossed above KijunSen");
}
else if (TenkanSen.HasCrossedBelow(KijunSen, 0))
{
Notifications.PlaySound(SoundFilePath);
Notifications.SendEmail(FromEmail, ToEmail, "Ichimoku kinku hyo Alert | Bearish", "TenkanSen crossed below KijunSen");
}
}
}
}
}
For email notification to work you have to first configure your cTrader email notification settings.
@amusleh
amusleh
13 May 2022, 10:19
Hi,
GetIndexByTime method returns the nearest bar index based on the date time you passed to it, if there is no bar for your passed date time then it will return -1.
Please post a indicator/cBot code sample that can reproduce the issue, then we will be able to help you.
@amusleh
amusleh
12 May 2022, 12:24
RE:
noob7 said:
Because of this change Ive lost over 100 euro.
Why you didnt notify me about this breaking changes?
Hi,
The change was not a breaking change, our old proxies are still working and they resolve to new nearest proxies.
We are still investigating the connection issue.
@amusleh
amusleh
12 May 2022, 10:38
Hi,
We updated API proxies: Proxies / Endpoints - cTrader Open API (spotware.github.io)
Please use the new proxies based on your region, and if you faced any connection issue try individual proxies of a region and then report the issue by providing the proxy you used.
@amusleh
amusleh
11 May 2022, 14:50
RE: RE:
ctid2032775 said:
amusleh said:
Hi,
Thanks for providing the details, we are investigating the issue now and if we were able to replicate it we will fix it.
Hi,
any news regarding this issue?
Thx & BR
Christian
Hi,
We tried everything to reproduce the issue you are facing but we couldn't.
@amusleh
amusleh
11 May 2022, 10:43
( Updated at: 21 Dec 2023, 09:22 )
Hi,
Open API returns Symbol min/max/step volumes in cents, you have to divide it by 100 to get the volume in symbol quote asset unit.
The US 30 minimum volume is 0.01 contracts on my TopFX demo account:
Not 1 contract, maybe you are using two different accounts for Open API and cTrader desktop.
@amusleh
amusleh
10 May 2022, 10:59
( Updated at: 10 May 2022, 11:06 )
RE:
darcome said:
Ok, as I wrote, this is what I am already doing.
I was hoping BeginInvokeOnMainThread could become an async function, so that it could be awaited.
Thank you anyway for the answer!
Hi,
Awaiting doesn't solve the issue, the code that calls BeginInvokeOnMainThread is executed on one thread and the action delegate you pass to BeginInvokeOnMainThread will run on cBot/Indicator main thread.
Even if you await, the cBot/Indicator thread has to either execute the continuation code by itself or dispatch it to the calling thread, during this time the calling thread will be free to do other stuff which is the benefit of asynchronous programming as you can do some other task while your passed action delegate to BeginInvokeOnMainThread is waiting to be executed.
To solve this issue you can create a pub/sub messaging agent, with a post method that will take your action delegate to BeginInvokeOnMainThread, and once the action delegate is executed by cBot/indicator main thread the agent will notify you, you can use .NET channels to avoid thread synchronization.
You can use such a wrapper over BeginInvokeOnMainThread to even get retuned values from your code that will be executed on cBot/Indicator main thread.
@amusleh
amusleh
10 May 2022, 09:41
Hi,
Try this:
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 SampleBreakoutRobot : Robot
{
[Parameter("Source")]
public DataSeries Source { get; set; }
[Parameter("Band Height (pips)", DefaultValue = 40.0, MinValue = 0)]
public double BandHeightPips { get; set; }
[Parameter("Stop Loss (pips)", DefaultValue = 20, MinValue = 1)]
public int StopLossInPips { get; set; }
[Parameter("Take Profit (pips)", DefaultValue = 40, MinValue = 1)]
public int TakeProfitInPips { get; set; }
[Parameter("Volume", DefaultValue = 10000, MinValue = 1000)]
public int Volume { get; set; }
[Parameter("Bollinger Bands Deviations", DefaultValue = 2)]
public int Deviations { get; set; }
[Parameter("Bollinger Bands Periods", DefaultValue = 20)]
public int Periods { get; set; }
[Parameter("Bollinger Bands MA Type")]
public MovingAverageType MAType { get; set; }
[Parameter("Consolidation Periods", DefaultValue = 2)]
public int ConsolidationPeriods { get; set; }
[Parameter("Enabled", DefaultValue = false, Group = "Single Direction")]
public bool IsSingleDirection { get; set; }
[Parameter("Trade Type", Group = "Single Direction")]
public TradeType SingleDirectionTradeType { get; set; }
private BollingerBands bollingerBands;
private string label = "SampleBreakoutRobot";
private int consolidation;
protected override void OnStart()
{
bollingerBands = Indicators.BollingerBands(Source, Periods, Deviations, MAType);
}
protected override void OnBar()
{
var top = bollingerBands.Top.Last(1);
var bottom = bollingerBands.Bottom.Last(1);
if (top - bottom <= BandHeightPips * Symbol.PipSize)
{
consolidation = consolidation + 1;
}
else
{
consolidation = 0;
}
if (consolidation >= ConsolidationPeriods)
{
if (Symbol.Ask > top && (IsSingleDirection == false || SingleDirectionTradeType == TradeType.Buy))
{
ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, label, StopLossInPips, TakeProfitInPips);
consolidation = 0;
}
else if (Symbol.Bid < bottom && (IsSingleDirection == false || SingleDirectionTradeType == TradeType.Sell))
{
ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, label, StopLossInPips, TakeProfitInPips);
consolidation = 0;
}
}
}
}
}
@amusleh
amusleh
16 May 2022, 09:59
RE: Can't establish new connection with old proxies
budda_dan2020 said:
Hi,
We will update you when the issue resolved, our previous proxies should work fine for now once the issue has been resolved.
@amusleh