CustomTimeFrames
interface cAlgo.API Since 5.3
DesktopCLICloud
Represents collection of custom time frames.
Environment behaviour
CLI — not supported. Available to plugins only, and plugins cannot run in the CLI.
Cloud — not supported. Available to plugins only, and plugins cannot run in the cloud.
Definition
public interface CustomTimeFrames
Namespace: cAlgo.API · Group: Custom
Examples
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using System.Linq;
namespace cAlgo.Plugins;
public partial class CustomTimeFrameTest : Plugin
{
private const string InitialDescription = "This is custom time frame initial description";
private const string ChangedDescription = "This is custom time frame changed description";
private bool _isLoadMoreEnabled = true;
private CustomTimeFrame _customTimeFrame;
private CustomBars _customBars;
protected override void OnStart()
{
var panel = new StackPanel();
var addCustomTimeFrameButton = new Button { Text = "Add Custom Time Frame" };
addCustomTimeFrameButton.Click += OnAddCustomTimeFrameButtonClick;
panel.AddChild(addCustomTimeFrameButton);
var removeCustomTimeFrameButton = new Button { Text = "Remove Custom Time Frame" };
removeCustomTimeFrameButton.Click += OnRemoveCustomTimeFrameButtonClick;
panel.AddChild(removeCustomTimeFrameButton);
var displayChartInfoButton = new Button { Text = "Display Charts Info" };
displayChartInfoButton.Click += OnDisplayChartInfoButtonClick;
panel.AddChild(displayChartInfoButton);
var changeDescriptionButton = new Button { Text = "Change Description" };
changeDescriptionButton.Click += OnChangeDescriptionButtonClick;
panel.AddChild(changeDescriptionButton);
var pauseOrResumeLoadMoreButton = new Button { Text = "Pause / Resume Load More" };
pauseOrResumeLoadMoreButton.Click += OnPauseOrResumeLoadMoreButtonClick;
panel.AddChild(pauseOrResumeLoadMoreButton);
var showRegularBarsInfoButton = new Button { Text = "Show Regular Bars Info" };
showRegularBarsInfoButton.Click += OnShowRegularBarsInfoButtonClick;
panel.AddChild(showRegularBarsInfoButton);
var addBarsButton = new Button { Text = "Add Bars For Active Chart Symbol" };
addBarsButton.Click += OnAddBarsButtonClick;
panel.AddChild(addBarsButton);
var removeBarsButton = new Button { Text = "Remove Bars For Active Chart Symbol" };
removeBarsButton.Click += OnRemoveBarsButtonClick;
panel.AddChild(removeBarsButton);
var updateLastBarButton = new Button { Text = "Update Last Bar" };
updateLastBarButton.Click += OnUpdateLastBarButtonClick;
panel.AddChild(updateLastBarButton);
var block = Asp.SymbolTab.AddBlock("Custom Time Frame Test");
block.Child = panel;
ChartManager.FramesAdded += OnChartManagerFramesAdded;
TimeFrames.Added += OnTimeFramesAdded;
TimeFrames.Removed += OnTimeFramesRemoved;
}
private void OnTimeFramesRemoved(TimeFramesRemovedEventArgs args)
{
Print($"TimeFrames Removed: {string.Join(", ", args.TimeFrames.Select(tf => tf.Name))}");
}
private void OnTimeFramesAdded(TimeFramesAddedEventArgs args)
{
Print($"TimeFrames Added: {string.Join(", ", args.TimeFrames.Select(tf => tf.Name))}");
}
private void OnChartManagerFramesAdded(FramesAddedEventArgs obj)
{
if (obj.AddedFrames[0] is not ChartFrame chartFrame)
return;
Print($"New chart frame added, {chartFrame.Symbol.Name} {chartFrame.TimeFrame.Name}");
}
private void OnUpdateLastBarButtonClick(ButtonClickEventArgs obj)
{
var changeAmount = (_customBars.Bars.LastBar.High - _customBars.Bars.LastBar.Low) * (Random.Shared.NextDouble() + 0.5) * 2;
Print($"Chaning Last Bar: {_customBars.Bars.LastBar} | change: {changeAmount}");
_customBars.UpdateLastBar(_customBars.Bars.LastBar.Open, _customBars.Bars.LastBar.Open + changeAmount, _customBars.Bars.LastBar.Open - changeAmount, _customBars.Bars.LastBar.Close + changeAmount, (int)_customBars.Bars.LastBar.TickVolume + 1);
}
private void OnRemoveCustomTimeFrameButtonClick(ButtonClickEventArgs obj)
{
TimeFrameManager.Custom.Remove(_customTimeFrame);
Print($"Custom Time frame '{_customTimeFrame.Name}' has been removed.");
}
private void OnDisplayChartInfoButtonClick(ButtonClickEventArgs obj)
{
DisplayChartsInfo();
}
private void OnChangeDescriptionButtonClick(ButtonClickEventArgs obj)
{
_customTimeFrame.Description = _customTimeFrame.Description == InitialDescription ? ChangedDescription : InitialDescription;
Print($"Changed description to: {_customTimeFrame.Description}");
}
private void OnPauseOrResumeLoadMoreButtonClick(ButtonClickEventArgs obj)
{
_isLoadMoreEnabled = !_isLoadMoreEnabled;
}
private void OnAddBarsButtonClick(ButtonClickEventArgs obj)
{
if (ChartManager.ActiveFrame is not ChartFrame { Chart: var chart })
return;
var bars = _customTimeFrame.AddBars(chart.Symbol);
Print($"Added Bars, Count: {bars.Bars.Count}, Get: {bars == _customTimeFrame.GetBars(chart.Symbol)}");
}
private void OnRemoveBarsButtonClick(ButtonClickEventArgs obj)
{
if (ChartManager.ActiveFrame is not ChartFrame { Chart: var chart })
return;
var result = _customTimeFrame.RemoveBars(chart.Symbol);
Print($"Removed Bars, Result: {result}, Get is null: {_customTimeFrame.GetBars(chart.Symbol) == null}");
}
private void OnShowRegularBarsInfoButtonClick(ButtonClickEventArgs obj)
{
Print($"Regular Bars, Count: {_customBars.Bars.Count}, LastBar: {_customBars.Bars.LastBar}, FirstBar: {_customBars.Bars[0]}");
}
private void OnAddCustomTimeFrameButtonClick(ButtonClickEventArgs obj)
{
_customTimeFrame = TimeFrameManager.Custom.Add("Test");
_customTimeFrame.Description = InitialDescription;
_customTimeFrame.BarsNeeded = OnCustomTimeFrameBarsNeeded;
Print($"Custom Time frame '{_customTimeFrame.Name}' has been added.");
DisplayChartsInfo();
}
private void DisplayChartsInfo()
{
foreach (var frame in ChartManager)
{
if (frame is not ChartFrame chartFrame)
continue;
Print($"Chart, {chartFrame.Symbol.Name} {chartFrame.TimeFrame.Name}");
}
}
private void OnCustomTimeFrameBarsNeeded(CustomTimeFrameBarsNeededArgs args)
{
Print($"Bars Needed for custom time frame, Symbol: {args.CustomBars.Symbol}, Name: {args.CustomTimeFrame.Name}");
_customBars = args.CustomBars;
MarketData.GetBarsAsync(TimeFrame.Daily, args.CustomBars.Symbol.Name, bars =>
{
Print($"Bars Loaded: {bars.Count}");
Sleep(TimeSpan.FromSeconds(5));
args.CustomBars.AppendBars(bars.Select(bar => new CustomBar(bar.OpenTime, bar.Open, bar.High, bar.Low, bar.Close, (int)bar.TickVolume)));
args.CustomBars.NeedsMore += _ =>
{
if (!_isLoadMoreEnabled)
{
Print("Needs more requested but load more is disabled");
return;
}
Print($"Bars NeedsMore");
bars.LoadMoreHistoryAsync(loadedMoreArgs =>
{
Print($"Bars Loaded more: {loadedMoreArgs.Count}");
if (loadedMoreArgs.Count == 0)
return;
Sleep(TimeSpan.FromSeconds(5));
args.CustomBars.PrependBars(bars.Take(loadedMoreArgs.Count).Select(bar => new CustomBar(bar.OpenTime, bar.Open, bar.High, bar.Low, bar.Close, (int)bar.TickVolume)));
});
};
});
}
}
import clr
clr.AddReference("cAlgo.API")
from cAlgo.API import *
from System import Action, TimeSpan, Array, DayOfWeek
import random
class Test():
InitialDescription = "This is custom time frame initial description"
ChangedDescription = "This is custom time frame changed description"
def on_start(self):
self.isLoadMoreEnabled = True
self.customTimeFrame = None
panel = StackPanel()
addCustomTimeFrameButton = Button()
addCustomTimeFrameButton.Text = "Add Custom TimeFrame"
addCustomTimeFrameButton.Click += self.on_add_custom_time_frame_button_click
panel.AddChild(addCustomTimeFrameButton)
removeCustomTimeFrameButton = Button()
removeCustomTimeFrameButton.Text = "Remove Custom TimeFrame"
removeCustomTimeFrameButton.Click += self.on_remove_custom_time_frame_button_click
panel.AddChild(removeCustomTimeFrameButton)
displayChartInfoButton = Button()
displayChartInfoButton.Text = "Display Charts Info"
displayChartInfoButton.Click += self.on_display_chart_info_button_click
panel.AddChild(displayChartInfoButton)
changeDescriptionButton = Button()
changeDescriptionButton.Text = "Change Description"
changeDescriptionButton.Click += self.on_change_description_button_click
panel.AddChild(changeDescriptionButton)
pauseOrResumeLoadMoreButton = Button()
pauseOrResumeLoadMoreButton.Text = "Pause / Resume Load More"
pauseOrResumeLoadMoreButton.Click += self.on_pause_or_resume_load_more_button_click
panel.AddChild(pauseOrResumeLoadMoreButton)
showRegularBarsInfoButton = Button()
showRegularBarsInfoButton.Text = "Show Regular Bars Info"
showRegularBarsInfoButton.Click += self.on_show_regular_bars_info_button_click
panel.AddChild(showRegularBarsInfoButton)
addBarsButton = Button()
addBarsButton.Text = "Add Bars For Active Chart Symbol"
addBarsButton.Click += self.on_add_bars_button_click
panel.AddChild(addBarsButton)
removeBarsButton = Button()
removeBarsButton.Text = "Remove Bars For Active Chart Symbol"
removeBarsButton.Click += self.on_remove_bars_button_click
panel.AddChild(removeBarsButton)
updateLastBarButton = Button()
updateLastBarButton.Text = "Update Last Bar"
updateLastBarButton.Click += self.on_update_last_bar_button_click
panel.AddChild(updateLastBarButton)
block = api.Asp.SymbolTab.AddBlock("Custom TimeFrame Test")
block.Child = panel
block.Height = 550
api.ChartManager.FramesAdded += self.on_chart_manager_frames_addded
api.TimeFrames.Added += self.on_time_frames_added
api.TimeFrames.Removed += self.on_time_frames_removed
def on_add_custom_time_frame_button_click(self, args):
self.customTimeFrame = api.TimeFrameManager.Custom.Add("Test")
self.customTimeFrame.Description = self.InitialDescription
self.customTimeFrame.BarsNeeded = Action[CustomTimeFrameBarsNeededArgs](self.on_custom_time_frame_bars_needed)
print(f"custom TimeFrame '{self.customTimeFrame.Name}' has been added.")
def on_custom_time_frame_bars_needed(self, args):
print(f"Bars Needed for custom TimeFrame, Symbol: {args.CustomBars.Symbol}, Name: {args.CustomTimeFrame.Name}")
self.customBars = args.CustomBars
api.MarketData.GetBarsAsync(TimeFrame.Daily, args.CustomBars.Symbol.Name, Action[Bars](self.on_bars_received))
def on_bars_received(self, bars):
print(f"Bars Loaded: {bars.Count}")
api.Sleep(2000)
self.customBars.AppendBars(self.to_array([CustomBar(bar.OpenTime, bar.Open, bar.High, bar.Low, bar.Close, int(bar.TickVolume)) for bar in bars], CustomBar))
self.customBars.NeedsMore += lambda args: self.on_custom_bars_needs_more(bars, args.CustomBars)
bars.BarOpened += lambda args: self.on_bar_opened(self.customBars, args.Bars)
bars.Tick += lambda args: self.on_tick(self.customBars, args.Bars)
def on_custom_bars_needs_more(self, bars, customBars):
if self.isLoadMoreEnabled is False:
print("Needs more requested but load more is disabled")
return
print("Bars NeedsMore")
bars.LoadMoreHistoryAsync(Action[BarsHistoryLoadedEventArgs](lambda args: self.on_bars_more_history_loaded(customBars, bars, args.Count)))
def on_bars_more_history_loaded(self, customBars, bars, loadedCount):
print(f"Bars Loaded more: {loadedCount}")
if loadedCount == 0:
return
api.Sleep(2000)
loadedBars = []
for i, bar in enumerate(bars):
if i >= loadedCount:
break
loadedBars.append(CustomBar(bar.OpenTime, bar.Open, bar.High, bar.Low, bar.Close, int(bar.TickVolume)))
customBars.PrependBars(self.to_array(loadedBars, CustomBar))
def on_bar_opened(self, customBars, bars):
if self.customTimeFrame is None:
return
customBars.AppendBar(CustomBar(bars.LastBar.OpenTime, bars.LastBar.Open, bars.LastBar.High, bars.LastBar.Low, bars.LastBar.Close, bars.LastBar.TickVolume))
def on_tick(self, customBars, bars):
if self.customTimeFrame is None:
return
customBars.UpdateLastBar(bars.LastBar.Open, bars.LastBar.High, bars.LastBar.Low, bars.LastBar.Close, bars.LastBar.TickVolume)
def on_remove_custom_time_frame_button_click(self, args):
if api.TimeFrameManager.Custom.Remove(self.customTimeFrame) == False:
return
print(f"custom TimeFrame '{self.customTimeFrame.Name}' has been removed.")
self.customTimeFrame = None
def on_display_chart_info_button_click(self, args):
for frame in api.ChartManager:
if isinstance(frame.__implementation__, ChartFrame) == False:
continue
chartFrame = ChartFrame(frame)
print(f"Chart, {chartFrame.Symbol.Name} {chartFrame.TimeFrame.Name}")
def on_change_description_button_click(self, args):
self.customTimeFrame.Description = self.ChangedDescription if self.customTimeFrame.Description == self.InitialDescription else self.InitialDescription
print(f"Changed description to: {self.customTimeFrame.Description}")
def to_array(self, iterable, itemType):
length = len(iterable)
array = Array[itemType](length)
for i in range(length):
array[i] = iterable[i]
return array
def on_pause_or_resume_load_more_button_click(self, args):
self.isLoadMoreEnabled = not self.isLoadMoreEnabled
def on_show_regular_bars_info_button_click(self, args):
print(f"Regular Bars, Count: {self.customBars.Bars.Count}, LastBar: {self.customBars.Bars.LastBar}, FirstBar: {self.customBars.Bars[0]}")
def on_add_bars_button_click(self, args):
if isinstance(api.ChartManager.ActiveFrame.__implementation__, ChartFrame) == False:
return
chart = ChartFrame(api.ChartManager.ActiveFrame).Chart
bars = self.customTimeFrame.AddBars(chart.Symbol)
print(f"Added Bars, Count: {bars.Bars.Count}, Get: {bars == self.customTimeFrame.GetBars(chart.Symbol)}")
def on_remove_bars_button_click(self, args):
if isinstance(api.ChartManager.ActiveFrame.__implementation__, ChartFrame) == False:
return
chart = ChartFrame(api.ChartManager.ActiveFrame).Chart
result = self.customTimeFrame.RemoveBars(chart.Symbol)
print(f"Removed Bars, Result: {result}, Get is None: {self.customTimeFrame.GetBars(chart.Symbol) is None}")
def on_update_last_bar_button_click(self, args):
changeAmount = (self.customBars.Bars.LastBar.High - self.customBars.Bars.LastBar.Low) * (random.random() + 0.5) * 2
print(f"Changing Last Bar: {self.customBars.Bars.LastBar} | change: {changeAmount}")
bars = self.customBars.Bars
self.customBars.UpdateLastBar(bars.LastBar.Open, bars.LastBar.Open + changeAmount, bars.LastBar.Open - changeAmount, bars.LastBar.Close + changeAmount, int(bars.LastBar.TickVolume + 1))
def on_chart_manager_frames_addded(self, args):
for frame in args.AddedFrames:
if isinstance(frame.__implementation__, ChartFrame) == False:
continue
chartFrame = ChartFrame(frame)
print(f"New chart frame added, {chartFrame.Symbol.Name} {chartFrame.TimeFrame.Name}")
def on_time_frames_added(self, args):
print(f"TimeFrames Added: {', '.join([tf.Name for tf in args.TimeFrames])}")
def on_time_frames_removed(self, args):
print(f"TimeFrames Removed: {', '.join([tf.Name for tf in args.TimeFrames])}")
{
"AccessRights": "None"
}
Methods
| Name | Description |
|---|---|
AddDesktopCLICloudCustomTimeFrame | Adds a new custom time frame. |
GetDesktopCLICloudCustomTimeFrame | Returns a custom time frame by it's name. |
RemoveDesktopCLICloudbool | Removes a custom time frame. |