// -------------------------------------------------------------------------------------------------
//
//    This code is a cAlgo API MACD Crossover indicator provided by njardim@email.com on Dec 2015.
//
//    Based on the original MACD Crossover indicator from cTrade.
//
// -------------------------------------------------------------------------------------------------
/*
 * Indicator was modified  by Telegram @Fibonacci2011 on Jan 2020.
 * 
 * Modifications:
 * 
 *  2020/1/21  Added MAType. Levels and Lookback feature
 *  2020/1/21  Added tick volume feature
 *  2020/1/22  Replaced lookback with MA smoothing feature
 *  2020/1/22  Added zero lag feature
 *  2020/2/10  Removed Tick Volume, error in logic
 
This is a modified version of the traditional MACD indicator.

Ma Smoothing attempts to show longer-term momentum and cycles better than the standard MACD.

Cut-Off levels indicate levels where MACD and signal line difference is greater than the level.

Tick volume feature takes into consideration the changes in tick volume. Increasing 
Tick Volume Factor will increasi tick volume feature relative weight


=====================================================================================================
                                            SETTINGS
=====================================================================================================

Traditional MACD:
MACD periods: 12 & 26 // Signal period: 9  // MA Type: Exponential

Linda Raschke:
MACD periods: 3 & 10 // Signal period: 16  // MA Type: Simple

Awesome Oscillator:
MACD periods: 5 & 34 // Signal period:N/A  // MA Type: Simple

*/
// -------------------------------------------------------------------------------------------------

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

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class MACDCrossover : Indicator
    {

        // public MACDCrossover MACDCrossover;

        [Parameter()]
        public DataSeries Source { get; set; }

        [Parameter("MA Type", Group = "--- MA Type ---", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MAType { get; set; }

        [Parameter("Long Cycle", Group = "--- Period ---", DefaultValue = 10)]
        public int LongCycle { get; set; }

        [Parameter("Short Cycle", Group = "--- Period ---", DefaultValue = 3)]
        public int ShortCycle { get; set; }

        [Parameter("Signal Periods", Group = "--- Period ---", DefaultValue = 16)]
        public int Periods { get; set; }

        [Parameter("Scale by bar time span (on tick charts)", Group = "--- Period ---", DefaultValue = true)]
        public bool ScaleByTimeSpan { get; set; }

        [Output("Histogram", PlotType = PlotType.Line, LineColor = "Transparent", Thickness = 1)]
        public IndicatorDataSeries Histogram { get; set; }

        [Output("Histogram UpSlope", PlotType = PlotType.Histogram, LineColor = "Green", Thickness = 5)]
        public IndicatorDataSeries HistogramRisingPositive { get; set; }

        [Output("Histogram UpDownSlope", PlotType = PlotType.Histogram, LineColor = "Aquamarine", Thickness = 5)]
        public IndicatorDataSeries HistogramRisingNegative { get; set; }

        [Output("Histogram DownSlope", PlotType = PlotType.Histogram, LineColor = "DarkRed", Thickness = 5)]
        public IndicatorDataSeries HistogramFallingNegative { get; set; }

        [Output("Histogram DownUpSlope", PlotType = PlotType.Histogram, LineColor = "Pink", Thickness = 5)]
        public IndicatorDataSeries HistogramFallingPositive { get; set; }

        [Output("Signal", LineColor = "Yellow", PlotType = PlotType.DiscontinuousLine, LineStyle = LineStyle.Lines, Thickness = 1)]
        public IndicatorDataSeries Signal { get; set; }

        public IndicatorDataSeries Times { get; set; }
 
        private MovingAverage SlowMa;
        private MovingAverage FastMa;
        private MovingAverage SignalMa;
        private MovingAverage TimesMa;

        public IndicatorDataSeries macd;

        protected override void Initialize()
        {
            SlowMa = Indicators.MovingAverage(Source, LongCycle, MAType);
            FastMa = Indicators.MovingAverage(Source, ShortCycle, MAType);

            macd = CreateDataSeries();
            Times = CreateDataSeries();
            SignalMa = Indicators.MovingAverage(macd, Periods, MAType);
            TimesMa = Indicators.MovingAverage(Times, 200, MovingAverageType.Simple );
        }

        public override void Calculate(int index)
        {
            if( index>0 )
            {
                var t0 = Bars.OpenTimes[index];
                var t1 = Bars.OpenTimes[index-1];
                if( t0.ToLocalTime().Date == t1.ToLocalTime().Date )
                    Times[index] = (t0-t1).TotalMinutes;
                else
                    Times[index] = 0;
            }

            macd[index] = (FastMa.Result[index] - SlowMa.Result[index]);
            Histogram[index] = macd[index];
            if( ScaleByTimeSpan && Times[index]>0)
                Histogram[index] *= TimesMa.Result[index] / Times[index];
                
            Signal[index] = SignalMa.Result[index];            

            HistogramRisingPositive[index] = 0;
            HistogramRisingNegative[index] = 0;
            HistogramFallingPositive[index] = 0;
            HistogramFallingNegative[index] = 0;

            if (Histogram[index] > 0)
            {
                if (Histogram.IsRising())
                    HistogramRisingPositive[index] = Histogram[index];
                else
                    HistogramRisingNegative[index] = Histogram[index];
            }
            else if (Histogram[index] < 0)
            {
                if (Histogram.IsRising())
                    HistogramFallingPositive[index] = Histogram[index];
                else
                    HistogramFallingNegative[index] = Histogram[index];
            }
        }
    }
}
