TimeFrameManager.Custom.Add(name) para registrar un nuevo perÃodo personalizado con un nombre definido por el usuario.
CustomTimeFrame.BarsNeeded para definir cómo y cuándo se cargan los datos para el gráfico.
CustomBars.AppendBars(), CustomBars.UpdateLastBar(), CustomBars.PrependBars() para gestionar dinámicamente la serie, donde cada CustomBar contiene estos seis campos: time, open, high, low, close y volume.
Una vez añadidos, los perÃodos personalizados se integran perfectamente en la interfaz de usuario PerÃodo de cTrader y aparecen en el menú desplegable junto con los perÃodos integrados. Los usuarios pueden entonces cambiar fácilmente entre perÃodos estándar y personalizados.
Consejo
Utilice perÃodos personalizados para visualizar mercados externos, simular tipos de barras experimentales, crear gráficos avanzados de correlación/arbitraje o hacer backtesting de estrategias con datos a medida.
Los objetos de API de perÃodos de tiempo personalizados se pueden utilizar para hacer lo siguiente:
CaracterÃstica u operación
Ejemplos
Mostrar datos de mercado alternativos
Cargar barras desde APIs REST (p. ej., AlphaVantage) Visualizar precios fuera de la plataforma
El plugin construye un perÃodo de tiempo de 25 minutos obteniendo barras nativas de un minuto para el sÃmbolo activo, agregándolas en velas OHLC de 25 minutos y luego transmitiendo el resultado a una serie CustomBar.
El nuevo perÃodo de tiempo aparece en el menú desplegable para seleccionar perÃodos de tiempo como 25Min.
Cuando los usuarios se desplazan hacia atrás en el gráfico, el plugin carga automáticamente más datos de minutos, antepone barras de 25 minutos más antiguas y mantiene la vista actualizada.
usingSystem;usingSystem.Linq;usingcAlgo.API;usingcAlgo.API.Internals;namespacecAlgo.Plugins{[Plugin(AccessRights = AccessRights.None)]publicclassTF25:Plugin{privateCustomTimeFrame_tf25Min;privatebool_isLoadMoreEnabled=true;protectedoverridevoidOnStart(){// Create the 25-minute TF_tf25Min=TimeFrameManager.Custom.Add("25Min");_tf25Min.Description="25‑minute aggregated from 1‑minute bars";// Hook initial load and on‑scroll‑back_tf25Min.NewChart+=OnNewChart;_tf25Min.BarsNeeded=OnBarsNeeded;}privatevoidOnNewChart(CustomTimeFrameNewChartEventArgsargs){varcb=args.CustomBars;varchart=args.Chart;// Show a loading indicatorvarloading=newTextBlock{Text="Loading 25‑min bars…",FontSize=12};chart.AddControl(loading);// Fetch the 1‑min bars and aggregateMarketData.GetBarsAsync(TimeFrame.Minute,cb.Symbol.Name,minuteBars=>{varaggregated=minuteBars.Select((bar,idx)=>new{bar,idx}).GroupBy(x=>x.idx/25).Select(g=>{varfirst=g.First().bar;varlast=g.Last().bar;returnnewCustomBar(time:first.OpenTime,open:first.Open,high:g.Max(x=>x.bar.High),low:g.Min(x=>x.bar.Low),close:last.Close,volume:g.Sum(x=>(int)x.bar.TickVolume));});chart.RemoveControl(loading);});}privatevoidOnBarsNeeded(CustomTimeFrameBarsNeededArgsargs){varcb=args.CustomBars;// Same logic for explicit BarsNeeded triggersMarketData.GetBarsAsync(TimeFrame.Minute,cb.Symbol.Name,minuteBars=>{varaggregated=minuteBars.Select((bar,idx)=>new{bar,idx}).GroupBy(x=>x.idx/25).Select(g=>newCustomBar(time:g.First().bar.OpenTime,open:g.First().bar.Open,high:g.Max(x=>x.bar.High),low:g.Min(x=>x.bar.Low),close:g.Last().bar.Close,volume:g.Sum(x=>(int)x.bar.TickVolume)));cb.AppendBars(aggregated);args.CustomBars.NeedsMore+=_=>{if(!_isLoadMoreEnabled){Print("Load‑more disabled; skipping additional bars.");return;}Print("NeedsMore fired; loading more history…");minuteBars.LoadMoreHistoryAsync(loadArgs=>{Print($"Loaded {loadArgs.Count} more 1‑min bars");if(loadArgs.Count==0)return;Sleep(TimeSpan.FromSeconds(1));args.CustomBars.PrependBars(minuteBars.Take(loadArgs.Count).Select(bar=>newCustomBar(bar.OpenTime,bar.Open,bar.High,bar.Low,bar.Close,(int)bar.TickVolume)));});};});}protectedoverridevoidOnStop(){}}}
Crear un perÃodo personalizado utilizando datos externos
El plugin aquà demuestra cómo obtener y mostrar datos financieros externos en los gráficos de cTrader utilizando objetos API de marco de tiempo personalizado.
El plugin crea un perÃodo personalizado en cTrader recuperando datos históricos diarios OHLC para IBM desde la API de AlphaVantage.
Analiza la respuesta CSV y carga los datos en una serie CustomBar, que luego se muestra como un perÃodo personalizado seleccionable llamado AlphaVantage en la interfaz de usuario del gráfico.
usingSystem;usingSystem.Collections.Generic;usingcAlgo.API;usingcAlgo.API.Collections;usingcAlgo.API.Indicators;usingcAlgo.API.Internals;namespacecAlgo.Plugins{[Plugin(AccessRights = AccessRights.None)]publicclassCustomTimeFrameAlphaVantage:Plugin{privateconststringApiKey="YOUR_ALPHA_VANTAGE_KEY";privateconststringSymbol="IBM";privateconststringEndpoint=$"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol={Symbol}&apikey={ApiKey}&datatype=csv&outputsize=full";privateCustomTimeFrame_customTimeFrame;protectedoverridevoidOnStart(){_customTimeFrame=TimeFrameManager.Custom.Add("AlphaVantage");_customTimeFrame.Description="Loads data from AlphaVantage";_customTimeFrame.BarsNeeded=args=>{varresponse=Http.Get(newUri(Endpoint));if(!response.IsSuccessful){Print($"Error loading data from AlphaVantage, status code: {response.StatusCode}, body: {response.Body}");return;}Print($"Response Received: {response.StatusCode}");varohlcData=response.Body.Split(Environment.NewLine)[1..];Array.Reverse(ohlcData);Print($"ohlcData Count: {ohlcData.Length}");varbars=newList<CustomBar>();foreach(varohlcinohlcData){varohlcSplit=ohlc.Split(',');if(ohlcSplit.Length<6)continue;vartime=DateTime.Parse(ohlcSplit[0]);varopen=double.Parse(ohlcSplit[1]);varhigh=double.Parse(ohlcSplit[2]);varlow=double.Parse(ohlcSplit[3]);varclose=double.Parse(ohlcSplit[4]);varvolume=long.Parse(ohlcSplit[5]);bars.Add(newCustomBar(time,open,high,low,close,volume));}Print($"AppendBars Count: {bars.Count}");args.CustomBars.AppendBars(bars);};}protectedoverridevoidOnStop(){// Handle Plugin stop here}}}