Коллекция ChartTemplates и объекты ChartTemplate позволяют программно сохранять, управлять и применять шаблоны графиков без необходимости работы с ручными конфигурациями. Эта функциональность полезна для:
Трейдеров, которым нужны алгоритмы для настройки и управления согласованными макетами графиков, плавного переключения шаблонов, захвата и хранения настроек, мониторинга и многого другого.
Разработчиков, которым нужны повторяемые среды графиков для расширенного анализа, мониторинга, отладки или развертывания вспомогательных индикаторов и сиБотов на множестве графиков.
Основные концепции
Один ChartTemplate предоставляет:
template.Apply(Chart) для применения шаблона к целевому графику.
template.Indicators для добавления или удаления индикаторов, доступа к их параметрам.
template.Robots для добавления или удаления сиБотов.
template.ColorSettings для работы с цветами графика или темы
template.DisplaySettings для работы с типом графика, масштабом и различными переключателями, включая позиции, ордера, сетку, настроения и многое другое.
Объект ChartTemplates, встроенная коллекция, предоставляет:
foreach (var t in ChartTemplates) ... для перечисления.
ChartTemplates.Get(name), ChartTemplates.Contains(name) для запросов.
ChartTemplates.Create(name) для создания пустых шаблонов.
ChartTemplates.Create(name, Chart) для захвата текущей конфигурации графика.
ChartTemplates.Duplicate(newName, sourceTemplate) для дублирования шаблонов.
ChartTemplates.Remove(template) для удаления шаблонов.
ChartTemplates.DefaultTemplate для применения шаблона по умолчанию (получение или установка).
Он также предоставляет события:
ChartTemplates.Added += ...
ChartTemplates.Removed += ...
Таблица ниже содержит сводку стандартных операций.
Операция
Примеры
Жизненный цикл шаблона
Создать пустой шаблон Создать шаблон из текущего графика Дублировать шаблон Удалить шаблон
Обнаружение шаблонов
Перечислить шаблоны и показать данные Проверить, существует ли шаблон Реагировать на добавление или удаление шаблона
Применение шаблонов
Применить шаблон к графику Изменить шаблон по умолчанию
Состав шаблона
Добавить или удалить индикатор Изменить параметры индикатора Добавить или удалить сиБота
Настройки макета и визуализации
Задать цвета графика Включить или отключить параметры отображения графика Изменить тип графика Настроить уровень масштабирования
Рассмотрим сиБота Chart Templates Manager, который при добавлении и запуске на графике отображает меню для выполнения различных задач с шаблонами графиков.
usingSystem;usingcAlgo.API;usingcAlgo.API.Collections;usingcAlgo.API.Indicators;usingcAlgo.API.Internals;usingSystem.Linq;namespacecAlgo.Robots{[Robot(AccessRights = AccessRights.None, AddIndicators = true)]publicclassChartTemplatesManager:Robot{protectedoverridevoidOnStart(){vartemplatesComboBox=newComboBox();templatesComboBox.AddItem("Click to view available templates");templatesComboBox.SelectedItem="Click to view available templates";foreach(vartemplateinChartTemplates){templatesComboBox.AddItem(template.Name);}ChartTemplates.Added+=args=>{templatesComboBox.AddItem(args.ChartTemplate.Name);Print($"A new template was added: {args.ChartTemplate.Name}");};ChartTemplates.Removed+=args=>{templatesComboBox.RemoveItem(args.ChartTemplate.Name);Print($"A template was removed: {args.ChartTemplate.Name}");};varshowTemplateInfoButton=newButton{Text="Show the template information"};showTemplateInfoButton.Click+=args=>{if(string.IsNullOrWhiteSpace(templatesComboBox.SelectedItem)){Print("No template is selected.");return;}vartemplate=ChartTemplates.Get(templatesComboBox.SelectedItem);Print($"Name: {template.Name} | Bots #: {template.Robots.Count} | Indicators #: {template.Indicators.Count}");};varshowDefaultTemplateInfoButton=newButton{Text="Show the default template information"};showDefaultTemplateInfoButton.Click+=args=>{Print($"Name: {ChartTemplates.DefaultTemplate.Name} | Bots #: {ChartTemplates.DefaultTemplate.Robots.Count} | Indicators #: {ChartTemplates.DefaultTemplate.Indicators.Count}");};varremoveTemplateButton=newButton{Text="Remove the selected template"};removeTemplateButton.Click+=_=>ChartTemplates.Remove(ChartTemplates.Get(templatesComboBox.SelectedItem));varapplyTemplateButton=newButton{Text="Apply the selected template"};applyTemplateButton.Click+=_=>ChartTemplates.Get(templatesComboBox.SelectedItem).Apply(Chart);varduplicateTemplateButton=newButton{Text="Duplicate the selected template"};duplicateTemplateButton.Click+=_=>ChartTemplates.Duplicate($"{templatesComboBox.SelectedItem} Duplicate",ChartTemplates.Get(templatesComboBox.SelectedItem));varcreateTemplateTextBox=newTextBox{Text="Click to type in a template name"};varcreateEmptyTemplateButton=newButton{Text="Create an empty template"};createEmptyTemplateButton.Click+=_=>ChartTemplates.Create(createTemplateTextBox.Text);varcreateTemplateBasedOnChartButton=newButton{Text="Create a template from the current chart"};createTemplateBasedOnChartButton.Click+=_=>ChartTemplates.Create(createTemplateTextBox.Text,Chart);varchangeDefaultTemplateToSelectedButton=newButton{Text="Set the selected template as the default"};changeDefaultTemplateToSelectedButton.Click+=_=>ChartTemplates.DefaultTemplate=ChartTemplates.Get(templatesComboBox.SelectedItem);varcheckSelectedTemplateExistsButton=newButton{Text="Check whether the selected template exists"};checkSelectedTemplateExistsButton.Click+=_=>Print($"The template '{templatesComboBox.SelectedItem}' exists: {ChartTemplates.Contains(templatesComboBox.SelectedItem)}");varremoveSelectedTemplateIndicator=newButton{Text="Remove an indicator from the selected template"};removeSelectedTemplateIndicator.Click+=_=>{if(string.IsNullOrWhiteSpace(templatesComboBox.SelectedItem)){Print("No template is selected.");return;}vartemplate=ChartTemplates.Get(templatesComboBox.SelectedItem);if(template.Indicators.Count==0)return;Print($"Removal result: {template.Indicators.Remove(template.Indicators.First())}");};varremoveSelectedTemplateBot=newButton{Text="Remove a cBot from the selected template"};removeSelectedTemplateBot.Click+=_=>{if(string.IsNullOrWhiteSpace(templatesComboBox.SelectedItem)){Print("No template is selected.");return;}vartemplate=ChartTemplates.Get(templatesComboBox.SelectedItem);if(template.Robots.Count==0)return;Print($"Removal result: {template.Robots.Remove(template.Robots.First())}");};varindicatorsCombobox=newComboBox();indicatorsCombobox.AddItem("Click to select an indicator");indicatorsCombobox.SelectedItem="Click to select an indicator";foreach(varindicatorinAlgoRegistry.Indicators.OrderBy(i=>i.Name)){indicatorsCombobox.AddItem(indicator.Name);}varaddIndicatorWithDefaultParametersToSelectedTemplate=newButton{Text="Add the selected indicator to the selected template using default parameters"};addIndicatorWithDefaultParametersToSelectedTemplate.Click+=_=>{if(string.IsNullOrWhiteSpace(templatesComboBox.SelectedItem)){Print("No template is selected.");return;}vartemplate=ChartTemplates.Get(templatesComboBox.SelectedItem);if(string.IsNullOrWhiteSpace(indicatorsCombobox.SelectedItem)){Print("No indicator is selected.");return;}Print($"Added the indicator {indicatorsCombobox.SelectedItem}.");template.Indicators.Add(indicatorsCombobox.SelectedItem);};varrobotsCombobox=newComboBox();robotsCombobox.AddItem("Click to select a cBot");robotsCombobox.SelectedItem="Click to select a cBot";foreach(varrobotinAlgoRegistry.Robots.OrderBy(i=>i.Name)){robotsCombobox.AddItem(robot.Name);}varaddRobotWithDefaultParametersToSelectedTemplate=newButton{Text="Add the selected cBot to the selected template using default parameters"};addRobotWithDefaultParametersToSelectedTemplate.Click+=_=>{if(string.IsNullOrWhiteSpace(templatesComboBox.SelectedItem)){Print("No template is selected.");return;}vartemplate=ChartTemplates.Get(templatesComboBox.SelectedItem);if(string.IsNullOrWhiteSpace(robotsCombobox.SelectedItem)){Print("No cBot is selected.");return;}Print($"Added the cBot {robotsCombobox.SelectedItem}.");template.Robots.Add(robotsCombobox.SelectedItem);};varaddEmaIndicatorWithDifferentParametersToSelectedTemplate=newButton{Text="Add an EMA indicator to the selected template using custom parameters"};addEmaIndicatorWithDifferentParametersToSelectedTemplate.Click+=_=>{if(string.IsNullOrWhiteSpace(templatesComboBox.SelectedItem)){Print("No template is selected.");return;}vartemplate=ChartTemplates.Get(templatesComboBox.SelectedItem);varemaType=AlgoRegistry.Get("Exponential Moving Average",AlgoKind.StandardIndicator)asIndicatorType;Print($"Added the indicator {emaType.Name} with a period of 100.");template.Indicators.Add(emaType,Bars.OpenPrices,100);};varchangeEmaIndicatorParametersForSelectedTemplate=newButton{Text="Change the EMA indicator parameters in the selected template"};changeEmaIndicatorParametersForSelectedTemplate.Click+=_=>{if(string.IsNullOrWhiteSpace(templatesComboBox.SelectedItem)){Print("No template is selected.");return;}vartemplate=ChartTemplates.Get(templatesComboBox.SelectedItem);varemaType=AlgoRegistry.Get("Exponential Moving Average",AlgoKind.StandardIndicator)asIndicatorType;if(template.Indicators.FirstOrDefault(i=>i.Type==emaType)isnot{}templateIndicator){Print($"The EMA indicator was not found in the template '{template.Name}'.");return;}Print($"Changing the indicator {emaType.Name} period to 200.");templateIndicator.Parameters["Periods"].Value=200;};varsetAllColorSettingsToRedForSelectedTemplate=newButton{Text="Set all colour settings to red for the selected template"};setAllColorSettingsToRedForSelectedTemplate.Click+=_=>{if(string.IsNullOrWhiteSpace(templatesComboBox.SelectedItem)){Print("No template is selected.");return;}vartemplate=ChartTemplates.Get(templatesComboBox.SelectedItem);template.ColorSettings.AskPriceLineColor=Color.Red;template.ColorSettings.BidPriceLineColor=Color.Red;template.ColorSettings.BackgroundColor=Color.Red;template.ColorSettings.BearFillColor=Color.Red;template.ColorSettings.BearOutlineColor=Color.Red;template.ColorSettings.BullFillColor=Color.Red;template.ColorSettings.BullOutlineColor=Color.Red;template.ColorSettings.BuyColor=Color.Red;template.ColorSettings.ForegroundColor=Color.Red;template.ColorSettings.GridLinesColor=Color.Red;template.ColorSettings.LosingDealColor=Color.Red;template.ColorSettings.PeriodSeparatorColor=Color.Red;template.ColorSettings.SellColor=Color.Red;template.ColorSettings.TickVolumeColor=Color.Red;template.ColorSettings.WinningDealColor=Color.Red;template.ColorSettings.AreaFillColor=Color.Red;};varenableAllDisplayOptionsForSelectedTemplate=newButton{Text="Enable all display options for the selected template"};enableAllDisplayOptionsForSelectedTemplate.Click+=_=>{if(string.IsNullOrWhiteSpace(templatesComboBox.SelectedItem)){Print("No template is selected.");return;}vartemplate=ChartTemplates.Get(templatesComboBox.SelectedItem);template.DisplaySettings.AskPriceLine=true;template.DisplaySettings.Bars=true;template.DisplaySettings.BidPriceLine=true;template.DisplaySettings.ChartScale=true;template.DisplaySettings.DealMap=true;template.DisplaySettings.Grid=true;template.DisplaySettings.IndicatorTitles=true;template.DisplaySettings.MarketSentiment=true;template.DisplaySettings.Orders=true;template.DisplaySettings.PeriodSeparators=true;template.DisplaySettings.Positions=true;template.DisplaySettings.PriceAlerts=true;template.DisplaySettings.PriceAxisOverlayButtons=true;template.DisplaySettings.QuickTradeButtons=true;template.DisplaySettings.Targets=true;template.DisplaySettings.TickVolume=true;template.DisplaySettings.AddRobotButton=true;};vardisableAllDisplayOptionsForSelectedTemplate=newButton{Text="Disable all display options for the selected template"};disableAllDisplayOptionsForSelectedTemplate.Click+=_=>{if(string.IsNullOrWhiteSpace(templatesComboBox.SelectedItem)){Print("No template is selected.");return;}vartemplate=ChartTemplates.Get(templatesComboBox.SelectedItem);template.DisplaySettings.AskPriceLine=false;template.DisplaySettings.Bars=false;template.DisplaySettings.BidPriceLine=false;template.DisplaySettings.ChartScale=false;template.DisplaySettings.DealMap=false;template.DisplaySettings.Grid=false;template.DisplaySettings.IndicatorTitles=false;template.DisplaySettings.MarketSentiment=false;template.DisplaySettings.Orders=false;template.DisplaySettings.PeriodSeparators=false;template.DisplaySettings.Positions=false;template.DisplaySettings.PriceAlerts=false;template.DisplaySettings.PriceAxisOverlayButtons=false;template.DisplaySettings.QuickTradeButtons=false;template.DisplaySettings.Targets=false;template.DisplaySettings.TickVolume=false;template.DisplaySettings.AddRobotButton=false;};varchangeChartTypeForSelectedTemplate=newButton{Text="Change the chart type for the selected template"};changeChartTypeForSelectedTemplate.Click+=_=>{if(string.IsNullOrWhiteSpace(templatesComboBox.SelectedItem)){Print("No template is selected.");return;}vartemplate=ChartTemplates.Get(templatesComboBox.SelectedItem);template.DisplaySettings.ChartType=template.DisplaySettings.ChartTypeswitch{ChartType.Area=>ChartType.Bars,ChartType.Bars=>ChartType.Candlesticks,ChartType.Candlesticks=>ChartType.Dots,ChartType.Dots=>ChartType.Hlc,ChartType.Hlc=>ChartType.Line,_=>ChartType.Area};Print($"Changed the template '{template.Name}' chart type to '{template.DisplaySettings.ChartType}'.");};varchangeZoomeLevelForSelectedTemplate=newButton{Text="Change the zoom level for the selected template"};changeZoomeLevelForSelectedTemplate.Click+=_=>{if(string.IsNullOrWhiteSpace(templatesComboBox.SelectedItem)){Print("No template is selected.");return;}vartemplate=ChartTemplates.Get(templatesComboBox.SelectedItem);template.DisplaySettings.ZoomLevel=template.DisplaySettings.ZoomLevelswitch{5=>400,400=>5,_=>5};Print($"Changed the template '{template.Name}' zoom level to '{template.DisplaySettings.ZoomLevel}'.");};varpanel=newStackPanel{Orientation=Orientation.Vertical,HorizontalAlignment=HorizontalAlignment.Center,VerticalAlignment=VerticalAlignment.Center};panel.AddChild(templatesComboBox);panel.AddChild(showTemplateInfoButton);panel.AddChild(showDefaultTemplateInfoButton);panel.AddChild(removeTemplateButton);panel.AddChild(applyTemplateButton);panel.AddChild(duplicateTemplateButton);panel.AddChild(createTemplateTextBox);panel.AddChild(createEmptyTemplateButton);panel.AddChild(createTemplateBasedOnChartButton);panel.AddChild(changeDefaultTemplateToSelectedButton);panel.AddChild(checkSelectedTemplateExistsButton);panel.AddChild(removeSelectedTemplateIndicator);panel.AddChild(removeSelectedTemplateBot);panel.AddChild(indicatorsCombobox);panel.AddChild(addIndicatorWithDefaultParametersToSelectedTemplate);panel.AddChild(robotsCombobox);panel.AddChild(addRobotWithDefaultParametersToSelectedTemplate);panel.AddChild(addEmaIndicatorWithDifferentParametersToSelectedTemplate);panel.AddChild(changeEmaIndicatorParametersForSelectedTemplate);panel.AddChild(setAllColorSettingsToRedForSelectedTemplate);panel.AddChild(enableAllDisplayOptionsForSelectedTemplate);panel.AddChild(disableAllDisplayOptionsForSelectedTemplate);panel.AddChild(changeChartTypeForSelectedTemplate);panel.AddChild(changeZoomeLevelForSelectedTemplate);Chart.AddControl(panel);}}}
Практическое применение
Сохранение текущих настроек
Разрабатывайте алгоритмы, которые программно сохраняют настройки графика, включая индикаторы, параметры, цвета и другие элементы, и сохраняют их в виде шаблона. Это позволяет автоматически сохранять рабочие настройки на любом этапе алгоритмической торговли и применять их к любым другим графикам.
Этот код на C# демонстрирует сиБота, который сохраняет шаблон графика:
usingSystem;usingcAlgo.API;usingcAlgo.API.Collections;usingcAlgo.API.Indicators;usingcAlgo.API.Internals;usingSystem.Linq;namespacecAlgo.Robots{[Robot(AccessRights = AccessRights.None)]publicclassCaptureChartAsTemplate:Robot{[Parameter("Template Name", DefaultValue = "My Golden Layout")]publicstringTemplateName{get;set;}protectedoverridevoidOnStart(){// If you want "overwrite", remove first (safe pattern).if(ChartTemplates.Contains(TemplateName)){varexisting=ChartTemplates.Get(TemplateName);ChartTemplates.Remove(existing);Print($"Removed existing template '{TemplateName}' to recapture.");}// Capture everything from the CURRENT chart (indicators/robots/colors/display settings).varcreated=ChartTemplates.Create(TemplateName,Chart);Print($"Captured template '{created.Name}' from current chart. "+$"Indicators={created.Indicators.Count}, Robots={created.Robots.Count}");}}}
Создание отдельных рабочих пространств
Структурируйте свой рабочий процесс ручной торговли на три отдельных макета графиков и мгновенно переключайтесь между ними. Типичный рабочий процесс ручной торговли включает:
Сканирование — минималистичный график, быстрая загрузка, чистые свечи, никакого беспорядка.
Подтверждение — индикаторы и контекстные наложения, такие как фильтры тренда/волатильности.
Исполнение — отображение ордеров/позиций/целей и кнопок Быстрого трейдинга, скрытие всего отвлекающего.
При торговле по тренду вы обычно полагаетесь на три основных элемента: фильтр тренда, такой как EMA, индикатор моментума или перекупленности-перепроданности, такой как RSI, и чистый график со свечами, стабильными цветами и читаемыми наложениями. Вы можете сохранить эту конфигурацию как единый шаблон и применять его к любому символу или таймфрейму, который открываете.
Стандартизированные настройки помогают избежать несоответствий параметров, уменьшить количество ошибок в настройках и гарантировать, что каждый график следует одной и той же структуре принятия решений.
Создание макетов для торговли на возврат к среднему
При торговле на возврат к среднему вы часто полагаетесь на больший контекст индикаторов, но при этом хотите сохранить чистый и контролируемый график. Используйте шаблоны, чтобы точно определить, что остается видимым во время анализа.
Отключите кнопки Быстрого трейдинга, чтобы предотвратить случайные входы. Скройте панель настроений, если она вас отвлекает. Оставьте видимыми сетку и ключевые уровни для точного позиционирования. Выберите тип графика, который соответствует вашему подходу: японские свечи для структуры или линейный график для ясности.
Когда вы находитесь в сделке, ваши приоритеты меняются. Вам нужна четкая видимость открытых позиций, отложенных ордеров и целевых уровней, а также стабильный и последовательный вид графика. Зафиксируйте уровень масштабирования, убедитесь, что ценовые линии четко отображаются, и удалите индикаторы, которые не поддерживают напрямую решения по управлению.
Если вы работаете в команде или следуете определенному стилю рабочей станции, используйте шаблоны для стандартизации таких элементов, как цвет фона, цвета бычьих и медвежьих свечей, видимость сетки и стиль линий. Применяйте один и тот же шаблон ко всем графикам, чтобы обеспечить единообразную визуальную структуру, уменьшить путаницу и улучшить коммуникацию.
Эта настройка становится особенно важной, когда вы делитесь скриншотами, проводите обзоры стратегий или передаете решения.
Когда волатильность меняется, меняются и ваши потребности в исполнении и анализе. Создайте шаблоны для определения двух различных рабочих пространств и переключайтесь между ними по мере изменения условий:
В шаблоне низкой волатильности используйте более узкий масштаб, уменьшите количество наложений и сохраните чистый вид, подходящий для торговли в диапазоне.
В шаблоне высокой волатильности используйте более широкий масштаб, более четкие ценовые линии, включите сетку и отобразите позиции и ордера для более жесткого контроля исполнения.
Вы часто используете разные параметры индикаторов, уровни масштабирования и визуальные предпочтения в зависимости от того, занимаетесь ли вы скальпингом или свинг-трейдингом. Вместо того чтобы вручную настраивать параметры каждый раз при переключении таймфреймов, создайте отдельные шаблоны для каждого вида.
Например, определите M1-Скальпинг для быстрого исполнения и более узкого масштаба, M15-Внутридневная для структурированной торговли в рамках сессии и H1-Свинг для более широкого контекста и более плавных наложений.
Если вы торгуете по нескольким семействам стратегий, рассмотрите возможность определения отдельного шаблона для каждого справочника. Например, вы можете:
Использовать шаблон справочника для пробоя с включенной сеткой, видимыми ордерами и позициями, более широким масштабом и четкими ценовыми линиями для ясности исполнения.
Использовать шаблон справочника для отката с примененными EMA и RSI, нормальным уровнем масштабирования и видимыми названиями индикаторов.
Использовать шаблон справочника для разворота с дополнительными контекстными индикаторами и типом свечей, который подчеркивает тени и структуру.
Закодировав каждый справочник как шаблон, вы можете переключать среды в зависимости от типа сигнала и поддерживать соответствие исполнения применяемой стратегии.