Drawing lines from robots and indicators

cAlgo_Development's avatar

cAlgo_Development since: 20 Feb 2013;

  14 May 2013, 16:04
Drawing lines from robots and indicators

Three new methods will be introduced in ChartObjects object next release:

1. Generic line:

ChartObjects.DrawLine(objectName, date1, y1, date2, y2, color, [optional] thickness, [optional] style))
ChartObjects.DrawLine(objectName, index1, y1, index2, y2, color, [optional] thickness, [optional] style)

 

2. Horizontal line:

ChartObjects.DrawHorizontalLine(objectName, y, color, [optional] thickness, [optional] style)

 

3. Vertical line:

ChartObjects.DrawVerticalLine(objectName, date, color, [optional] thickness, [optional] style)
ChartObjects.DrawVerticalLine(objectName, index, color, [optional] thickness, [optional] style)


The logic of adding, updating and removing chart objects is the same as we already have in DrawText  method: objectName identifiers unique created object, if you draw second object with the same name, old one is removed (updated). So if you want to have e.g. several lines at the same time you have to use different object names.


All methods are available in both robots and indicators.


Here we will post several examples of usage.

TRADERS FIRST
cAlgo_Development's avatar

cAlgo_Development since: 20 Feb 2013;

  14 May 2013, 16:11

Indicator drawing trend-lines automatically using specified period (minimum distance between high and low extremums):

Source code:

using System;
using cAlgo.API;
using cAlgo.API.Indicators;

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true)]
    public class TrendLines : Indicator
    {
    	[Parameter(DefaultValue = 30, MinValue = 1)]
        public int Period { get; set; }	
    
        protected override void Initialize()
        {
            RedrawLines();
        }
    
        public override void Calculate(int index)
        {
            if (IsRealTime)
                RedrawLines();
        }
        
        private void RedrawLines()
        {
            int count = MarketSeries.Close.Count;
        
            int maxIndex1 = FindNextLocalExtremum(MarketSeries.High, count - 1, true);
            int maxIndex2 = FindNextLocalExtremum(MarketSeries.High, maxIndex1 - Period, true);
        	
            int minIndex1 = FindNextLocalExtremum(MarketSeries.Low, count - 1, false);
            int minIndex2 = FindNextLocalExtremum(MarketSeries.Low, minIndex1 - Period, false);
            
            int startIndex = Math.Min(maxIndex2, minIndex2) - 100;
            int endIndex = count + 100;
            
            DrawTrendLine("high", startIndex, endIndex, maxIndex1, MarketSeries.High[maxIndex1], 
                maxIndex2, MarketSeries.High[maxIndex2]);

            DrawTrendLine("low", startIndex, endIndex, minIndex1, MarketSeries.Low[minIndex1], 
                minIndex2, MarketSeries.Low[minIndex2]);
        }
        
        private void DrawTrendLine(string lineName, int startIndex, 
            int endIndex, int index1, double value1, int index2, double value2)
        {
            double gradient = (value2 - value1) / (index2 - index1);
            
            double startValue = value1 + (startIndex - index1) * gradient;
            double endValue = value1 + (endIndex - index1) * gradient;
            
            ChartObjects.DrawLine(lineName, startIndex, startValue, endIndex, endValue, Colors.Gray);
            ChartObjects.DrawLine(lineName+"_red", index1, value1, index2, value2, Colors.Red);
        }
        
        private int FindNextLocalExtremum(DataSeries series, int maxIndex, bool findMax)
        {
            for (int index = maxIndex; index >= 0; index --)
            {
                if (IsLocalExtremum(series, index, findMax))
                {
                    return index;
                }
            }
            return 0;
        }
        
        private bool IsLocalExtremum(DataSeries series, int index, bool findMax)
        {	
        	int end = Math.Min(index + Period, series.Count - 1);
        	int start = Math.Max(index - Period, 0);
        	
        	double value = series[index];
        
        	for (int i = start; i < end; i++)
        	{
        		if (findMax && value < series[i])
        			return false;
        			
    			if (!findMax && value > series[i])
        			return false;
        	}
        	return true;
        }
    }
}
TRADERS FIRST
cAlgo_Fanatic's avatar

cAlgo_Fanatic since: 10 Jan 2013;

  14 May 2013, 17:07

Indicator showing Round Numbers based on input step pips calculated between the chart High and Low.

Source Code:

using System;
using cAlgo.API;

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true)]
    public class RoundNumbers : Indicator
    {
        [Parameter(DefaultValue = 100)]
        public int StepPips { get; set; }

        protected override void Initialize()
        {
            double max = MarketSeries.High.Maximum(MarketSeries.High.Count);
            double min = MarketSeries.Low.Minimum(MarketSeries.Low.Count);

            double step = Symbol.PipSize*StepPips;
            double start = Math.Floor(min/step)*step;

            for (double level = start; level <= max + step; level += step)
            {
                ChartObjects.DrawHorizontalLine("line_" + level, level, Colors.Gray);
            }
        }

        public override void Calculate(int index)
        {
        }
    }
}



TRADERS FIRST™
cAlgo_Fanatic's avatar

cAlgo_Fanatic since: 10 Jan 2013;

  14 May 2013, 17:39

Daily High and Low Indicator. Displays horizontal lines that correspond to the daily high and low.

Source Code:

using System;
using cAlgo.API;

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true)]
    public class DailyHighLow : Indicator
    {
        public override void Calculate(int index)
        {
            DateTime today = MarketSeries.OpenTime[index].Date;
            DateTime tomorrow = today.AddDays(1);

            double high = MarketSeries.High.LastValue;
            double low = MarketSeries.Low.LastValue;

            for (int i = MarketSeries.Close.Count - 1; i > 0; i--)
            {
                if (MarketSeries.OpenTime[i].Date < today)
                    break;

                high = Math.Max(high, MarketSeries.High[i]);
                low = Math.Min(low, MarketSeries.Low[i]);
            }

            ChartObjects.DrawLine("high " + today, today, high, tomorrow, high, Colors.Pink);
            ChartObjects.DrawLine("low " + today, today, low, tomorrow, low, Colors.Pink);
        }
    }
}



TRADERS FIRST™
lec0456's avatar

lec0456 since: 14 Nov 2012;

  20 May 2013, 07:09

why do you have toinitialize ReddrawLines?  Intead of just calling it  OnCalculate

protected override void Initialize()
        {
            RedrawLines();
        }
cAlgo_Fanatic's avatar

cAlgo_Fanatic since: 10 Jan 2013;

  20 May 2013, 10:00

This is so that the calculation occurs only on loading of the indicator, in the Initialize() method and thereon only when there are new bars, in the Calculate() method.

TRADERS FIRST™

FrankMan since: 11 Jun 2013;

  11 Jun 2013, 14:12
Color as user input

How would I go about getting the color as an external paramenter which the user can set?

Kate since: 09 Mar 2013;

  11 Jun 2013, 15:03

Hi, as far as I know, native support for color parameters is not implemented. You can check workaround that I've done here: /algos/indicators/show/289

Abhi since: 31 Aug 2014;

  28 Sep 2014, 15:38
RE:

cAlgo_Fanatic said:

Daily High and Low Indicator. Displays horizontal lines that correspond to the daily high and low.

Source Code:

using System;
using cAlgo.API;

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true)]
    public class DailyHighLow : Indicator
    {
        public override void Calculate(int index)
        {
            DateTime today = MarketSeries.OpenTime[index].Date;
            DateTime tomorrow = today.AddDays(1);

            double high = MarketSeries.High.LastValue;
            double low = MarketSeries.Low.LastValue;

            for (int i = MarketSeries.Close.Count - 1; i > 0; i--)
            {
                if (MarketSeries.OpenTime[i].Date < today)
                    break;

                high = Math.Max(high, MarketSeries.High[i]);
                low = Math.Min(low, MarketSeries.Low[i]);
            }

            ChartObjects.DrawLine("high " + today, today, high, tomorrow, high, Colors.Pink);
            ChartObjects.DrawLine("low " + today, today, low, tomorrow, low, Colors.Pink);
        }
    }
}


 

Hi Spotware team, I managed to do some coding but ran into some issues. My chart time settings are UTC+1 (UK time).

I could plot high and low for New York time session between 1 pm and 10 pm but for some reason I cannot plot high and low for the time session between 1 pm and 1:15 pm.

Please can you help.

// Start of the code here

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.CentralEuropeanStandardTime, AccessRights = AccessRights.None)]
    public class AbhiCharts : Indicator
    {

        protected DateTime today, tomorrow;
        protected int ORMinute;

        protected TimeSpan NewYorkStartTime, NewYorkEndTime;
        protected TimeSpan NewYorkORStartTime, NewYorkOREndTime;


        protected double High_NewYorkStartTime, Low_NewYorkEndTime;
        protected double High_NewYorkORStartTime, Low_NewYorkOREndTime;


        protected DateTime plot_NewYorkStartTime, plot_NewYorkEndTime;


        protected int NewYorkStartHour, NewYorkEndHour;
        protected int NewYorkORStartHour, NewYorkOREndHour;

        protected override void Initialize()
        {
            ORMinute = 15;
            NewYorkStartHour = 14;
            NewYorkEndHour = 23;


            NewYorkStartTime = new TimeSpan(NewYorkStartHour, 0, 0);
            NewYorkEndTime = new TimeSpan(NewYorkEndHour, 0, 0);
            NewYorkORStartTime = new TimeSpan(NewYorkStartHour, 0, 0);
            NewYorkOREndTime = new TimeSpan(NewYorkStartHour, ORMinute, 0);




        }

        public override void Calculate(int index)
        {

            today = MarketSeries.OpenTime[index].Date;
            tomorrow = today.AddDays(1);


            plot_NewYorkStartTime = today.Date.AddHours(NewYorkStartHour);
            plot_NewYorkEndTime = today.Date.AddHours(NewYorkEndHour);


            High_NewYorkStartTime = MarketSeries.High.LastValue;
            Low_NewYorkEndTime = MarketSeries.Low.LastValue;
            High_NewYorkORStartTime = MarketSeries.High.LastValue;
            Low_NewYorkOREndTime = MarketSeries.Low.LastValue;

            for (int i = MarketSeries.Close.Count - 1; i > 0; i--)
            {
                if (MarketSeries.OpenTime[i].Date < today)
                    break;

                if ((MarketSeries.OpenTime[i].TimeOfDay >= NewYorkStartTime) && (MarketSeries.OpenTime[i].TimeOfDay <= NewYorkEndTime))
                {
                    High_NewYorkStartTime = Math.Max(High_NewYorkStartTime, MarketSeries.High[i]);
                    Low_NewYorkEndTime = Math.Min(Low_NewYorkEndTime, MarketSeries.Low[i]);
                }


                if ((MarketSeries.OpenTime[i].TimeOfDay >= NewYorkORStartTime) && (MarketSeries.OpenTime[i].TimeOfDay <= NewYorkOREndTime))
                {
                    High_NewYorkORStartTime = Math.Max(High_NewYorkORStartTime, MarketSeries.High[i]);
                    Low_NewYorkOREndTime = Math.Min(Low_NewYorkOREndTime, MarketSeries.Low[i]);

                }
            }


            ChartObjects.DrawLine("High " + today, plot_NewYorkStartTime, High_NewYorkStartTime, plot_NewYorkEndTime, High_NewYorkStartTime, Colors.Red);
            ChartObjects.DrawLine("Low " + today, plot_NewYorkStartTime, Low_NewYorkEndTime, plot_NewYorkEndTime, Low_NewYorkEndTime, Colors.Green);
            ChartObjects.DrawText("TextHigh " + today, string.Format("{0}", High_NewYorkStartTime), index, High_NewYorkStartTime, VerticalAlignment.Top, HorizontalAlignment.Right, Colors.Red);
            ChartObjects.DrawText("TextLow " + today, string.Format("{0}", Low_NewYorkEndTime), index, Low_NewYorkEndTime, VerticalAlignment.Top, HorizontalAlignment.Right, Colors.Green);

            ChartObjects.DrawLine("HighOR " + today, plot_NewYorkStartTime, High_NewYorkORStartTime, plot_NewYorkEndTime, High_NewYorkORStartTime, Colors.Yellow);
            ChartObjects.DrawLine("LowOR " + today, plot_NewYorkStartTime, Low_NewYorkOREndTime, plot_NewYorkEndTime, Low_NewYorkOREndTime, Colors.Yellow);
            ChartObjects.DrawText("TextHighOR " + today, string.Format("High: {0}", High_NewYorkORStartTime), index, High_NewYorkORStartTime, VerticalAlignment.Top, HorizontalAlignment.Right, Colors.Yellow);
            ChartObjects.DrawText("TextLowOR " + today, string.Format("Low: {0}", Low_NewYorkOREndTime), index, Low_NewYorkOREndTime, VerticalAlignment.Top, HorizontalAlignment.Right, Colors.Yellow);



            //string text = string.Format("MarketSeries.OpenTime[i].TimeOfDay : {0}", MarketSeries.OpenTime[i].TimeOfDay);

            //ChartObjects.DrawText("Diff", text, StaticPosition.TopLeft, Colors.Lime);




        }
    }
}

Abhi since: 31 Aug 2014;

  28 Sep 2014, 16:11

Attached Chart