Topics
Forum Topics not found
Replies
amusleh
23 Jul 2021, 14:02
Hi,
You can use a chart trend line CalculateY method to check if the price is touched or not, this sample might help you:
using cAlgo.API;
using System;
using System.Linq;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class LineAlert : Indicator
{
#region Parameters
[Parameter("Single Alert", DefaultValue = true, Group = "General")]
public bool SingleAlert { get; set; }
[Parameter("Trend/Ray", DefaultValue = true, Group = "Line Types")]
public bool TrendLine { get; set; }
[Parameter("Horizontal", DefaultValue = true, Group = "Line Types")]
public bool HorizontalLine { get; set; }
[Parameter("Vertical", DefaultValue = true, Group = "Line Types")]
public bool VerticalLine { get; set; }
[Parameter("Show Comment", DefaultValue = true, Group = "Comment")]
public bool ShowComment { get; set; }
[Parameter("Comment Suffix", Group = "Comment")]
public string CommentSuffix { get; set; }
#endregion Parameters
#region Overridden methods
protected override void Initialize()
{
}
public override void Calculate(int index)
{
foreach (var chartObject in Chart.Objects)
{
if (!string.IsNullOrEmpty(CommentSuffix) && !chartObject.Comment.EndsWith(CommentSuffix, StringComparison.InvariantCultureIgnoreCase))
{
continue;
}
var isAlert = false;
if (chartObject.ObjectType == ChartObjectType.TrendLine || chartObject.ObjectType == ChartObjectType.HorizontalLine)
{
var linePriceValue = double.NaN;
if (TrendLine && chartObject.ObjectType == ChartObjectType.TrendLine)
{
var chartTrendLine = chartObject as ChartTrendLine;
if (chartTrendLine != null) linePriceValue = chartTrendLine.CalculateY(index);
}
else if (HorizontalLine && chartObject.ObjectType == ChartObjectType.HorizontalLine)
{
var chartHorizontalLine = chartObject as ChartHorizontalLine;
if (chartHorizontalLine != null) linePriceValue = chartHorizontalLine.Y;
}
if (Bars.ClosePrices[index] >= linePriceValue && Bars.ClosePrices[index - 1] < linePriceValue)
{
isAlert = true;
}
if (Bars.ClosePrices[index] <= linePriceValue && Bars.ClosePrices[index - 1] > linePriceValue)
{
isAlert = true;
}
}
else if (VerticalLine && chartObject.ObjectType == ChartObjectType.VerticalLine)
{
var chartVerticalLine = chartObject as ChartVerticalLine;
if (chartVerticalLine != null
&& Bars.OpenTimes[index] >= chartVerticalLine.Time
&& Bars.OpenTimes[index - 1] < chartVerticalLine.Time)
{
isAlert = true;
}
}
if (isAlert)
{
// The code for alert goes here
}
}
}
#endregion Overridden methods
}
}
@amusleh
amusleh
23 Jul 2021, 10:19
Hi,
It's really hard to understand what you are after, the code works fine on my system:
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
namespace cAlgo
{
[Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class Test : Indicator
{
[Parameter(DefaultValue = 10)]
public int Period { get; set; }
protected override void Initialize()
{
var verticalLine = Chart.DrawVerticalLine("verticalLine", Bars.OpenTimes.Last(Period), Color.Red);
var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(verticalLine.Time);
var rectangle = Chart.DrawRectangle("rectangle", verticalLineBarIndex, Bars.LowPrices.Minimum(Period), verticalLineBarIndex - Period, Bars.HighPrices.Maximum(Period), Color.FromArgb(100, Color.Red));
rectangle.IsFilled = true;
//rectangle.IsInteractive = true;
rectangle.IsFilled = false;
rectangle.Thickness = 3;
}
public override void Calculate(int index)
{
}
}
}
@amusleh
amusleh
23 Jul 2021, 09:27
Hi,
Please read the API references, check the examples, I see you don't understand how the DrawRectangle works, and it's not clear at all what you are trying to do.
I recommend you before you open a thread here, read the API references, play with code examples, then if something was not clear you can ask here.
@amusleh
amusleh
23 Jul 2021, 08:14
You can change the vertical line time to bar index by using Bars.OpenTimes.GetIndexByTime:
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
{
protected override void OnStart()
{
var verticalLine = Chart.DrawVerticalLine("verticalLine", Bars.OpenTimes.LastValue, Color.Red);
// It only works if the vertical line is drawn on the past, if its drawn on future where there is no bar then it will not work
var verticalLineBarIndex = Bars.OpenTimes.GetIndexByTime(verticalLine.Time);
}
}
}
@amusleh
amusleh
22 Jul 2021, 10:17
Hi,
There is a scaling issue with MACD and Stochastic indicators, MACD usually fluctuates between -1 and 1, Stochastic fluctuates between 0-100.
If you place both indicators on the same chart with the same Y-axis then you will not be able to display the one with a lower scale properly, to solve this issue you have to change the scale of both to the same scale by using a scaling method like normalization or min/max scaling.
@amusleh
amusleh
22 Jul 2021, 10:09
Hi,
Yes, you can use the Chart.ObjectAdded event and then check the type of added object if it's a trend line or not.
using cAlgo.API;
using System.Linq;
namespace cAlgo
{
[Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class Test : Indicator
{
protected override void Initialize()
{
Chart.ObjectsAdded += Chart_ObjectsAdded;
}
private void Chart_ObjectsAdded(ChartObjectsAddedEventArgs obj)
{
if (obj.ChartObjects.All(chartObject => chartObject.ObjectType == ChartObjectType.TrendLine))
{
// If all of the new added objects were trend line the code here will be executed
}
}
public override void Calculate(int index)
{
}
}
}
@amusleh
amusleh
22 Jul 2021, 10:06
Hi,
Your question is not clear at all, nor is your code.
Please read the Automate API references before asking for help.
@amusleh
amusleh
20 Jul 2021, 10:08
Hi,
You can directly access Open API from Azure functions by writing code to interact with API.
You can get an account balance from Open API and cTrader Automate API, not sure about FIX I have to check.
If you don't want to use Open API, you can send your account balance to Azure via a cBot and then use it on your functions.
@amusleh
amusleh
20 Jul 2021, 08:56
Hi,
Its possible but Open API is not the rioght solution for what you are after, Open API is for building trading apps and it uses OAuth authentication.
You have to first get an access token and then you will be able to use the API, and the access token has an expiry which you have to monitor and refresh it by using the refresh token.
What you can do is to get an acess token for your API application, then use that access token on your Azure Functions to access API, you also have to refresh the token once is expired or before its expiry.
I recommend you to read the Open API documentation and check our samples for Open API.NET.
@amusleh
amusleh
19 Jul 2021, 09:22
( Updated at: 19 Jul 2021, 09:31 )
Hi,
You can use Print method to check if the indicator thread execution flow reaches the Chart.AddControl(scrollViewer) line or not, if it desn't reach the line and stuck somewhere then the scroll viewer control will not be displayed on your chart.
There is no issue with indicator code, it just gets some time to iterate over all available symbols of your broker, if you limit the number of symbols to 50 by using a break it will come up faster:
using cAlgo.API;
namespace cAlgo
{
// This sample shows how to use Symbols collection to get symbols data
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class SymbolsSample : Indicator
{
protected override void Initialize()
{
var scrollViewer = new ScrollViewer
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
BackgroundColor = Color.Gold,
Opacity = 0.7,
HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
VerticalScrollBarVisibility = ScrollBarVisibility.Visible,
Height = 300
};
var grid = new Grid(Symbols.Count + 1, 2)
{
BackgroundColor = Color.Gold,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
scrollViewer.Content = grid;
grid.AddChild(new TextBlock
{
Text = "Name",
Margin = 5,
ForegroundColor = Color.Black,
FontWeight = FontWeight.ExtraBold
}, 0, 0);
grid.AddChild(new TextBlock
{
Text = "Description",
Margin = 5,
ForegroundColor = Color.Black,
FontWeight = FontWeight.ExtraBold
}, 0, 1);
for (int iSymbol = 1; iSymbol < Symbols.Count - 1; iSymbol++)
{
if (iSymbol > 50) break;
var symbolName = Symbols[iSymbol];
var symbol = Symbols.GetSymbol(symbolName);
if (!symbol.MarketHours.IsOpened())
continue;
grid.AddChild(new TextBlock
{
Text = symbolName,
Margin = 5,
ForegroundColor = Color.Black,
FontWeight = FontWeight.ExtraBold
}, iSymbol, 0);
grid.AddChild(new Button
{
Text = symbol.Description,
Margin = 5,
ForegroundColor = Color.Black,
FontWeight = FontWeight.ExtraBold
}, iSymbol, 1);
}
Print("Done");
Chart.AddControl(scrollViewer);
}
public override void Calculate(int index)
{
}
}
}
@amusleh
amusleh
09 Jul 2021, 16:17
You have to define your controls as fields on your indicator class:
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class AWEMA : Indicator
{
private ExponentialMovingAverage _ema5, _ema24;
private TextBlock _text;
private Border _border;
[Parameter("Source", DefaultValue = Price.High)]
public Price Source { get; set; }
protected override void Initialize()
{
var series = GetBaseSeries();
_ema5 = Indicators.ExponentialMovingAverage(series, 5);
_ema24 = Indicators.ExponentialMovingAverage(series, 24);
_border = new Border
{
BorderColor = Color.Red,
Opacity = 0.5,
BackgroundColor = Color.Yellow,
BorderThickness = 1.5,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top,
CornerRadius = 10,
Width = 130,
Height = 55,
Margin = new Thickness(2, 30, 10, 10)
};
var stackPanel = new StackPanel
{
Orientation = Orientation.Vertical
};
_text = new TextBlock
{
Margin = 5,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
FontWeight = FontWeight.ExtraBold
};
stackPanel.AddChild(_text);
_border.Child = stackPanel;
Chart.AddControl(_border);
}
public override void Calculate(int index)
{
// You can set the text by using _text text block text property
if (_ema5.Result.LastValue > _ema24.Result.LastValue)
{
_text.Text = "Green Text";
_border.BorderColor = Color.Green;
_border.BackgroundColor = Color.DarkGreen;
}
else
{
_text.Text = "Red Text";
_border.BorderColor = Color.Red;
_border.BackgroundColor = Color.DarkRed;
}
}
private DataSeries GetBaseSeries()
{
switch (Source)
{
case Price.Open:
return Bars.OpenPrices;
case Price.Close:
return Bars.ClosePrices;
case Price.High:
return Bars.HighPrices;
case Price.Low:
return Bars.LowPrices;
case Price.Median:
return Bars.MedianPrices;
case Price.Typical:
return Bars.TypicalPrices;
case Price.Weighted:
return Bars.WeightedPrices;
default:
return Bars.ClosePrices;
}
}
}
public enum Price
{
Open,
Close,
High,
Low,
Median,
Typical,
Weighted
}
}
You don't have to redraw it on each tick.
@amusleh
amusleh
24 Jul 2021, 11:15
RE: RE:
yaghouti said:
Hi,
Can you post the full code of your cBot, please?
@amusleh