How do you get OpenTimes of bars of a smaller time frame when you're on a higher time frame chart?
How do you get OpenTimes of bars of a smaller time frame when you're on a higher time frame chart?
25 Sep 2020, 06:56
How do you get OpenTimes of bars of a smaller time frame when you're on a higher time frame chart?
For example, pretend this code is in an indicator that's added to the M15 chart. However, the SourceTimeFrame is set to TimeFrame.Minute5
If the current bar's open time is 08:15, how is it possible to get the indexes for the 08:20 and 08:25 bars that should be happening in the M5 timeframe? Since the M15 timeframe never has an open time of 08:20, the below method won't work - it will only ever return the 08:15 bar of the M5 timeframe when on the M15 chart.
private Bars _marketSeries;
protected override void Initialize()
{
if (SourceTimeFrame != null)
_marketSeries = MarketData.GetBars(SourceTimeFrame, Symbol.Name);
else
_marketSeries = MarketData.GetBars(Bars.TimeFrame, Symbol.Name);
}
public override void Calculate(int index)
{
int altIndex = index;
if (Bars.TimeFrame != _marketSeries.TimeFrame)
{
altIndex = _marketSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
}
// blah blah blah
}
Does cTrader have the ability to plot 3 smaller time frame bar values in the space of 1 bar on a higher time frame?
Eg, in the example above, it would have to plot 3 M5 bars within the space of 1 M15 bar on the M15 chart.
Thank you.
Replies
firemyst
25 Sep 2020, 10:28
RE:
PanagiotisCharalampous said:
Hi firemyst,
You will need to program your own methods to calculate those times.
Regarding
Does cTrader have the ability to plot 3 smaller time frame bar values in the space of 1 bar on a higher time frame?
I did not understand the question. You are trying to do something here but I do not understand what it is. Maybe it would be better to explain what are you trying to do instead discussing about a solution you thought would work.
Best Regards,
Panagiotis
I have a 15 minute chart, or a 1 hour chart, and I want to plot an indicator's values from the 5 minute timeframe on it.However, I can't find a way to plot those. For instance, all I can get it 1 M5 plot (instead of 3) for every M15 bar; or 1 M5 plot (instead of 12) for every H1 bar.
The only thing I can manage to do is pull up an M5 chart with just the one indicator I want the M5 value on, and then have to put the other indicators on the M5 chart and set them to either 15 minutes or 1 hour.
So I have an M15 chart:
* 1 indicator I want plotted against the M5 timeframe
* 5 indicators I want plotted on the M15 timeframe.
Best I can figure out is instead set the chart timeframe to M5 and:
* put the 1 M5 indicator on it
* 5 multi time frame indicators set to M15.
Does that make it more clear on what I'd like?
@firemyst
PanagiotisCharalampous
25 Sep 2020, 10:43
Hi firemyst,
OnCalculate method is called once per bar when the indicator is calculated for past values. Having that in mind, if you want your indicator to display values from lower timeframes, you need to write the corresponding logic that will take this into consideration. Here is a starting point, an indicator drawing vertical lines on lower tiimeframe open times
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class NewIndicator : Indicator
{
[Parameter(DefaultValue = 0.0)]
public TimeFrame SourceTimeFrame { get; set; }
[Output("Main")]
public IndicatorDataSeries Result { get; set; }
private Bars _marketSeries;
int previousAltIndex = 0;
protected override void Initialize()
{
if (SourceTimeFrame != null)
_marketSeries = MarketData.GetBars(SourceTimeFrame, Symbol.Name);
else
_marketSeries = MarketData.GetBars(Bars.TimeFrame, Symbol.Name);
}
public override void Calculate(int index)
{
int altIndex = index;
if (Bars.TimeFrame != _marketSeries.TimeFrame)
{
altIndex = _marketSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
for(int i = previousAltIndex; i < altIndex; i++)
{
Chart.DrawVerticalLine(_marketSeries.OpenTimes[i].ToString(), _marketSeries.OpenTimes[i], Color.Red);
}
altIndex = previousAltIndex;
}
// blah blah blah
}
}
}
Note that for current values, OnCalculate() is called on every tick, in case you need to take that into consideration.
Best Regards,
Panagiotis
@PanagiotisCharalampous
firemyst
25 Sep 2020, 11:14
RE:
PanagiotisCharalampous said:
Hi firemyst,
OnCalculate method is called once per bar when the indicator is calculated for past values. Having that in mind, if you want your indicator to display values from lower timeframes, you need to write the corresponding logic that will take this into consideration. Here is a starting point, an indicator drawing vertical lines on lower tiimeframe open times
Note that for current values, OnCalculate() is called on every tick, in case you need to take that into consideration.
Best Regards,
Panagiotis
Thanks for the code sample, but I don't believe it works.
It's because of this line:
altIndex = _marketSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
Here's why.
I'm on a 15-minute chart.
Let's say "index" number "500" is at 08:00; the next time Calculate is called index will be "501", but the time will be "08:15".
So when calling "Bars.OpenTimes[index]", it will be either 500 or 501, which is 08:00 or 08:15 respectively. The 5 minute indicator also needs the open times of 08:05 and :08:10.
Because it doesn't get that, the M5 indicator will only display the value from index 500 or 08:00, missing all the subsequent values until index 501 at 08:15.
So how to get those intermediate values too?
Or am I completely missing something?
@firemyst
PanagiotisCharalampous
25 Sep 2020, 11:19
( Updated at: 21 Dec 2023, 09:22 )
Hi firemyst,
Did you try my code? It prints a line on the starting time of every bar for the lower timeframe
Best Regards,
Panagiotis
@PanagiotisCharalampous
firemyst
25 Sep 2020, 13:40
RE:
Hi @Panagiotis:
Your code works for drawings, but how do you get it to work for indicators?
Example. Take the code below. Insert it on an H1 chart and set the timeframe of the indicator to be M5. I'd expect to see 12 psar dots in the space of one bar (60 / 5 = 12).
I can't get it to work because of the Result[index] that's needed; I've tried doing it with Result[altIndex] to no avail.
using System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Indicators
{
[Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
public class Test : Indicator
{
[Parameter()]
public TimeFrame SourceTimeFrame { get; set; }
[Parameter("Min AF", DefaultValue = 0.02)]
public double MinAF { get; set; }
[Parameter("Max AF", DefaultValue = 0.2)]
public double MaxAF { get; set; }
[Output("Main", PlotType = PlotType.Points, LineStyle = LineStyle.Dots, LineColor = "White", Thickness = 2)]
public IndicatorDataSeries Result { get; set; }
private Bars _marketSeries;
private ParabolicSAR _psar;
int previousAltIndex = 0;
protected override void Initialize()
{
if (SourceTimeFrame != null)
_marketSeries = MarketData.GetBars(SourceTimeFrame, Symbol.Name);
else
_marketSeries = MarketData.GetBars(Bars.TimeFrame, Symbol.Name);
_psar = Indicators.ParabolicSAR(_marketSeries, MinAF, MaxAF);
}
public override void Calculate(int index)
{
int altIndex = index;
if (Bars.TimeFrame != _marketSeries.TimeFrame)
{
altIndex = _marketSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
}
Result[index] = _psar.Result[altIndex];
//if (Bars.TimeFrame != _marketSeries.TimeFrame)
//{
// altIndex = _marketSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
// for (int i = previousAltIndex; i < altIndex; i++)
// {
// Chart.DrawVerticalLine(_marketSeries.OpenTimes[i].ToString(), _marketSeries.OpenTimes[i], Color.Red);
// }
// altIndex = previousAltIndex;
//}
// blah blah blah
}
}
}
@firemyst
PanagiotisCharalampous
25 Sep 2020, 14:47
Hi firemyst,
You cannot use Output IndicatorDataSeries to do this since they have a one to one correspondence with the chart timeframe's bar. You need to be more inventive. Here is a solution
using System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Indicators
{
[Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
public class Test : Indicator
{
[Parameter()]
public TimeFrame SourceTimeFrame { get; set; }
[Parameter("Min AF", DefaultValue = 0.02)]
public double MinAF { get; set; }
[Parameter("Max AF", DefaultValue = 0.2)]
public double MaxAF { get; set; }
[Output("Main", PlotType = PlotType.Points, LineStyle = LineStyle.Dots, LineColor = "White", Thickness = 2)]
public IndicatorDataSeries Result { get; set; }
private Bars _marketSeries;
private ParabolicSAR _psar;
int previousAltIndex = 0;
protected override void Initialize()
{
if (SourceTimeFrame != null)
_marketSeries = MarketData.GetBars(SourceTimeFrame, Symbol.Name);
else
_marketSeries = MarketData.GetBars(Bars.TimeFrame, Symbol.Name);
_psar = Indicators.ParabolicSAR(_marketSeries, MinAF, MaxAF);
}
public override void Calculate(int index)
{
int altIndex = index;
if (Bars.TimeFrame != _marketSeries.TimeFrame)
{
altIndex = _marketSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
}
if (Bars.TimeFrame != _marketSeries.TimeFrame)
{
altIndex = _marketSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
for (int i = previousAltIndex; i < altIndex; i++)
{
Chart.DrawIcon(_marketSeries.OpenTimes[i].ToString(), ChartIconType.Circle, _marketSeries.OpenTimes[i], _psar.Result[i], Color.Red);
}
altIndex = previousAltIndex;
}
// blah blah blah
}
}
}
Best Regards,
Panagiotis
@PanagiotisCharalampous
firemyst
28 Sep 2020, 08:52
( Updated at: 21 Dec 2023, 09:22 )
RE:
Hi @Panagiotis:
Thank you for the "inventive" solution!
It does lead to, however, an issue I've pointed out earlier with the short-comings of cTrader which I think your team at @Spotware really needs to consider implementing.
Look at the screen capture. What do you think is more "user friendly" and that users would appreciate more?
Having the configurations displayed as they are under the "Lines" section (2) ? Or having to create separate parameters for the color and styles without any sort of previews (1)?
Options #2 is definitely more "user friendly" and I think @Spotware seriously needs to consider allowing through the API the ability to access the color, style, size properties of "lines".
In this case, I would want to create an indicator data series (that holds nothing and just set to null) so I can allow users to select the color/style/size options nicely. Then in the API read those settings, and apply those to the chart icons drawn.
Thank you again though for the sample code solution.
@firemyst
PanagiotisCharalampous
25 Sep 2020, 07:59
Hi firemyst,
You will need to program your own methods to calculate those times.
Regarding
I did not understand the question. You are trying to do something here but I do not understand what it is. Maybe it would be better to explain what are you trying to do instead discussing about a solution you thought would work.
Best Regards,
Panagiotis
Join us on Telegram
@PanagiotisCharalampous