Replies

Symposium
16 Jul 2019, 07:44

SuperTrend with Line...

// Added a customisable Moving Average Type Parameter. (Default.WilderSmoothing) 

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

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class Supertrend : Indicator
    {
        [Parameter(DefaultValue = 10)]
        public int Period { get; set; }

        [Parameter(DefaultValue = 3.0)]
        public double Multiplier { get; set; }

        [Parameter("Moving Average Type", DefaultValue = MovingAverageType.WilderSmoothing)]
        public MovingAverageType MaType { get; set; }

        [Output("UpTrend", PlotType = PlotType.DiscontinuousLine, Color = Colors.Lime, Thickness = 1)]
        public IndicatorDataSeries UpTrend { get; set; }

        [Output("DownTrend", PlotType = PlotType.DiscontinuousLine, Color = Colors.Red, Thickness = 1)]
        public IndicatorDataSeries DownTrend { get; set; }

        private IndicatorDataSeries _upBuffer;
        private IndicatorDataSeries _downBuffer;
        private AverageTrueRange _averageTrueRange;
        private int[] _trend;
        private bool _changeofTrend;

        protected override void Initialize()
        {
            _trend = new int[1];
            _upBuffer = CreateDataSeries();
            _downBuffer = CreateDataSeries();
            _averageTrueRange = Indicators.AverageTrueRange(Period, MaType);
        }

        public override void Calculate(int index)
        {
            // Init
            UpTrend[index] = double.NaN;
            DownTrend[index] = double.NaN;

            double median = (MarketSeries.High[index] + MarketSeries.Low[index]) / 2;
            double atr = _averageTrueRange.Result[index];

            _upBuffer[index] = median + Multiplier * atr;
            _downBuffer[index] = median - Multiplier * atr;


            if (index < 1)
            {
                _trend[index] = 1;
                return;
            }

            Array.Resize(ref _trend, _trend.Length + 1);

            // Main Logic
            if (MarketSeries.Close[index] > _upBuffer[index - 1])
            {
                _trend[index] = 1;
                if (_trend[index - 1] == -1)
                    _changeofTrend = true;
            }
            else if (MarketSeries.Close[index] < _downBuffer[index - 1])
            {
                _trend[index] = -1;
                if (_trend[index - 1] == -1)
                    _changeofTrend = true;
            }
            else if (_trend[index - 1] == 1)
            {
                _trend[index] = 1;
                _changeofTrend = false;
            }
            else if (_trend[index - 1] == -1)
            {
                _trend[index] = -1;
                _changeofTrend = false;
            }

            if (_trend[index] < 0 && _trend[index - 1] > 0)
                _upBuffer[index] = median + (Multiplier * atr);
            else if (_trend[index] < 0 && _upBuffer[index] > _upBuffer[index - 1])
                _upBuffer[index] = _upBuffer[index - 1];

            if (_trend[index] > 0 && _trend[index - 1] < 0)
                _downBuffer[index] = median - (Multiplier * atr);
            else if (_trend[index] > 0 && _downBuffer[index] < _downBuffer[index - 1])
                _downBuffer[index] = _downBuffer[index - 1];

            // Draw Indicator
            if (_trend[index] == 1)
            {
                UpTrend[index] = _downBuffer[index];
                if (_changeofTrend)
                {
                    UpTrend[index - 1] = DownTrend[index - 1];
                    _changeofTrend = false;
                }
            }
            else if (_trend[index] == -1)
            {
                DownTrend[index] = _upBuffer[index];
                if (_changeofTrend)
                {
                    DownTrend[index - 1] = UpTrend[index - 1];
                    _changeofTrend = false;
                }
            }
        }
    }
}


@Symposium

Symposium
27 Jun 2019, 10:56

Big, Big Thanks... Panagiotis.... problem solved... :-)


@Symposium

Symposium
27 Jun 2019, 01:28

Sorry Panagiotis...

I can only input whole numbers ie: XAUUSD 1410, If I input 1410.60 the Parameter changes to Red and doesn't accept the Value? 

I have included a minimum value in the Parameter.... which hasn't fixed the issue...... Can this be fixed....?

 

[Parameter("Max Price Level", DefaultValue = 0, MinValue = 0)]
        public int Max { get; set; }

        [Parameter("Min Price Level", DefaultValue = 0, MinValue = 0)]
        public int Min { get; set; }

 


@Symposium

Symposium
26 Jun 2019, 12:49

Thank you Panagiotis.... as always with your code.... works perfectly..... Maybe a great addition to other buddying programers Code Snipet Libraries... 

 

 


@Symposium

Symposium
26 Jun 2019, 10:09

(REF: Code in Post Above )  Hi Panagiotis, I'm requiring a code snipet that will allow a Parameter set Price Level to Close All Positions and Stop the cBot.

ie: If price moves to (any pair) eg: 1.9000 = "Max" Parameter. The code will close all Positions and Stop the Bot.

It's for risk managment of a strategy using a range based system to protect against Trending price action.

Obviously there will be a Max and Min Parameter. If you can repair the code for the Max, I can replicate the Min.

Open to anyone that can help.... Thanks in Advance.... Cheers.


@Symposium

Symposium
21 May 2019, 03:23

RE:

nmaxcom said:

Hi,

What you are showing to us is the values that the equity fluctuated in between since closing the last position.

I'm not sure that sentence makes syntactical sense, could you clarify?

I use Print() every time a position is opened or closed. During the backtesting, positions open and close. But near the end, positions open and the backtesting ends. So in the log, you'd see it ends with "positions opened" X amount of times instead of "positions closed." So programmatically speaking my code doesn't have the chance to close those positions.

Hi Nmaxcom, Panagiotis is correct, you still have position(s) open when the backtest period ends. You should be able to see the unclosed position(s) in the events tab... 

In your example above, find the date (time) that the 22 position closes (or anyother number that closes on /above the balance line) and end the backtest on that date. You should see either positive equity or a lot less DD. Cheers

 


@Symposium

Symposium
19 Feb 2019, 12:22

Thanks Panagiotis..... My apologies.. It was text that displays on the Chart. I'm sure this is a new phenomenon, my code has contained txt print commands for over 7 months.

Another error that is new coming up is the one below.... 

BT Log:  Crashed in OnStart with ArgumentException: Incorrect parameters count. Parameter name: parameterValues

I seached the Ctrader site for a fix for both... very little info on error codes, statements, maybe something that can be added.

Thanks in advance Panagiotis

 


@Symposium

Symposium
10 Nov 2018, 04:09 ( Updated at: 21 Dec 2023, 09:20 )

RE:

Symposium said:

Hi Mastah1238, Parameters are shown in the image (Please find Code Below) Hope this is what you have asked to be displayed.

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

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

        [Parameter("Timeframe 1", DefaultValue = "Minute15")]
        public TimeFrame MATimeframe1 { get; set; }

        [Parameter("Period TF 1", DefaultValue = 14)]
        public int Periods1 { get; set; }

        [Parameter("Timeframe 2", DefaultValue = "Hour")]
        public TimeFrame MATimeframe2 { get; set; }

        [Parameter("Period TF 2", DefaultValue = 14)]
        public int Periods2 { get; set; }

        [Parameter("Timeframe 3", DefaultValue = "Hour4")]
        public TimeFrame MATimeframe3 { get; set; }

        [Parameter("Period TF 3", DefaultValue = 14)]
        public int Periods3 { get; set; }

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


        [Output("Timeframe 1", Color = Colors.Lime, Thickness = 1)]
        public IndicatorDataSeries MA1 { get; set; }

        [Output("Timeframe 2", Color = Colors.Red, Thickness = 1)]
        public IndicatorDataSeries MA2 { get; set; }

        [Output("Timeframe 3", Color = Colors.White, Thickness = 1)]
        public IndicatorDataSeries MA3 { get; set; }

        private MarketSeries series1;
        private MarketSeries series2;
        private MarketSeries series3;

        private MovingAverage Ma1;
        private MovingAverage Ma2;
        private MovingAverage Ma3;

        protected override void Initialize()
        {
            series1 = MarketData.GetSeries(MATimeframe1);
            series2 = MarketData.GetSeries(MATimeframe2);
            series3 = MarketData.GetSeries(MATimeframe3);

            Ma1 = Indicators.MovingAverage(series1.Close, Periods1, MAType);
            Ma2 = Indicators.MovingAverage(series2.Close, Periods2, MAType);
            Ma3 = Indicators.MovingAverage(series3.Close, Periods3, MAType);

        }

        public override void Calculate(int index)
        {



            {

                var index1 = GetIndexByDate(series1, MarketSeries.OpenTime[index]);
                if (index1 != -1)
                {
                    MA1[index] = Ma1.Result[index1];
                }

                var index2 = GetIndexByDate(series2, MarketSeries.OpenTime[index]);
                if (index2 != -1)
                {
                    MA2[index] = Ma2.Result[index2];
                }

                var index3 = GetIndexByDate(series3, MarketSeries.OpenTime[index]);
                if (index3 != -1)
                {
                    MA3[index] = Ma3.Result[index3];
                }

            }
        }


        private int GetIndexByDate(MarketSeries series, DateTime time)
        {
            for (int i = series.Close.Count - 1; i > 0; i--)
            {
                if (time == series.OpenTime[i])
                    return i;
            }
            return -1;
        }
    }
}

To modify Indicator so it overlays the chart (not display as an Oscillator) paste the line of code below (Overlay = true) in the code and recompile.

Line 8     [Indicator(IsOverlay = true, AccessRights = AccessRights.None, TimeZone = TimeZones.UTC)]

Change Timeframe 1 to Daily1, Period TF 1 to 20    |    Timeframe 2 to Daily1, Period TF 2 to 40    |    Timeframe 3 to Daily1, Period TF 3 to 200 (For reference)

This gives the result you requested........ Zoomed out, Looks terrific for long term position...... Good Luck

 


@Symposium

Symposium
10 Nov 2018, 03:11 ( Updated at: 21 Dec 2023, 09:20 )

Hi Mastah1238, Parameters are shown in the image (Please find Code Below) Hope this is what you have asked to be displayed.

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

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

        [Parameter("Timeframe 1", DefaultValue = "Minute15")]
        public TimeFrame MATimeframe1 { get; set; }

        [Parameter("Period TF 1", DefaultValue = 14)]
        public int Periods1 { get; set; }

        [Parameter("Timeframe 2", DefaultValue = "Hour")]
        public TimeFrame MATimeframe2 { get; set; }

        [Parameter("Period TF 2", DefaultValue = 14)]
        public int Periods2 { get; set; }

        [Parameter("Timeframe 3", DefaultValue = "Hour4")]
        public TimeFrame MATimeframe3 { get; set; }

        [Parameter("Period TF 3", DefaultValue = 14)]
        public int Periods3 { get; set; }

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


        [Output("Timeframe 1", Color = Colors.Lime, Thickness = 1)]
        public IndicatorDataSeries MA1 { get; set; }

        [Output("Timeframe 2", Color = Colors.Red, Thickness = 1)]
        public IndicatorDataSeries MA2 { get; set; }

        [Output("Timeframe 3", Color = Colors.White, Thickness = 1)]
        public IndicatorDataSeries MA3 { get; set; }

        private MarketSeries series1;
        private MarketSeries series2;
        private MarketSeries series3;

        private MovingAverage Ma1;
        private MovingAverage Ma2;
        private MovingAverage Ma3;

        protected override void Initialize()
        {
            series1 = MarketData.GetSeries(MATimeframe1);
            series2 = MarketData.GetSeries(MATimeframe2);
            series3 = MarketData.GetSeries(MATimeframe3);

            Ma1 = Indicators.MovingAverage(series1.Close, Periods1, MAType);
            Ma2 = Indicators.MovingAverage(series2.Close, Periods2, MAType);
            Ma3 = Indicators.MovingAverage(series3.Close, Periods3, MAType);

        }

        public override void Calculate(int index)
        {



            {

                var index1 = GetIndexByDate(series1, MarketSeries.OpenTime[index]);
                if (index1 != -1)
                {
                    MA1[index] = Ma1.Result[index1];
                }

                var index2 = GetIndexByDate(series2, MarketSeries.OpenTime[index]);
                if (index2 != -1)
                {
                    MA2[index] = Ma2.Result[index2];
                }

                var index3 = GetIndexByDate(series3, MarketSeries.OpenTime[index]);
                if (index3 != -1)
                {
                    MA3[index] = Ma3.Result[index3];
                }

            }
        }


        private int GetIndexByDate(MarketSeries series, DateTime time)
        {
            for (int i = series.Close.Count - 1; i > 0; i--)
            {
                if (time == series.OpenTime[i])
                    return i;
            }
            return -1;
        }
    }
}

 


@Symposium

Symposium
09 Nov 2018, 15:29

RE: Detrended Price Indicator
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 DetrendedPriceIndicator : Indicator
    {
        [Parameter()]
        public DataSeries Source { get; set; }

        [Parameter("Period", DefaultValue = 14.0)]
        public int Period { get; set; }

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

        [Parameter("Display Current Trend", DefaultValue = true)]
        public bool IncludeSignal { get; set; }

        [Output("DPO Fast", PlotType = PlotType.DiscontinuousLine, Color = Colors.White, Thickness = 1)]
        public IndicatorDataSeries DPO { get; set; }

        [Output("Focus Level", PlotType = PlotType.DiscontinuousLine, Color = Colors.Gray, LineStyle = LineStyle.Lines, Thickness = 1)]
        public IndicatorDataSeries Focus { get; set; }

        public API.Indicators.DetrendedPriceOscillator dpo { get; set; }

        public bool IsBuy { get; set; }
        public bool IsSell { get; set; }

        private string _trend = string.Empty;
        private Colors trendColor = Colors.Red;

        protected override void Initialize()
        {
            dpo = Indicators.DetrendedPriceOscillator(Source, Period, MaType);
        }
        public override void Calculate(int index)
        {
            DPO[index] = dpo.Result[index];

            Focus[index] = 0;
            {
                if (index < 0.1)
                    return;

                DPO[index] = dpo.Result[index];

                // if bearish
                if (dpo.Result.LastValue < 0)
                {
                    // if the trigger for a bearish signal has not occurred
                    if (!IsSell)
                    {
                        // Sell Signal
                        IsBuy = false;
                        IsSell = true;

                        _trend = "Current Trend Signal   |   SELLING";
                        trendColor = Colors.Red;

                        if (IsLastBar)
                        {

                        }
                    }
                }

                // if bullish
                if (dpo.Result.LastValue > 0)
                {
                    if (!IsBuy)
                    {
                        // Buy Signal
                        IsBuy = true;
                        IsSell = false;

                        _trend = "Current Trend Signal   |   BUYING";
                        trendColor = Colors.Lime;

                        if (IsLastBar)
                        {

                        }
                    }
                }

                if (IncludeSignal)

                    ChartObjects.DrawText("trendText", _trend, StaticPosition.TopLeft, trendColor);
                {

                }
            }
        }
    }
}

lec0456 said:

Can i get an answer please?

 


@Symposium

Symposium
07 Nov 2018, 11:52 ( Updated at: 21 Dec 2023, 09:20 )

Hi Anghenly, you should also be able to right click on your chart and reattch to platform as shown in the example below.

Your Charts (OctaFX) Toolsets look a lot different (advanced) to mine (IC Markets).....

Hope this is of help to you.....


@Symposium

Symposium
23 Oct 2018, 01:09

Freeman is right, the longer the timeframe the more jaggered the line will appear in the lower TF's. ie: the weekly would look like a ZigZg Indicator..........

 

I have added an Oscillating version of a MA MTF Indicator (completely adjustable) which will smooth out the Moving Averages for you.....

If you want to place the chart change the line (8) of code below.

[Indicator(IsOverlay = true, AccessRights = AccessRights.None, TimeZone = TimeZones.UTC)]

Hope this is of some help...... Cheers

 

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

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None, TimeZone = TimeZones.UTC)]
    public class MovingAverageMTFOscillator : Indicator
    {
        [Parameter(DefaultValue = 14)]
        public int Periods { get; set; }

        [Parameter("Timeframe 1", DefaultValue = "Minute15")]
        public TimeFrame MATimeframe1 { get; set; }

        [Parameter("Timeframe 2", DefaultValue = "Hour")]
        public TimeFrame MATimeframe2 { get; set; }

        [Parameter("Timeframe 3", DefaultValue = "Hour4")]
        public TimeFrame MATimeframe3 { get; set; }

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


        [Output("Timeframe 1", Color = Colors.Lime, Thickness = 1)]
        public IndicatorDataSeries MA1 { get; set; }

        [Output("Timeframe 2", Color = Colors.Red, Thickness = 1)]
        public IndicatorDataSeries MA2 { get; set; }

        [Output("Timeframe 3", Color = Colors.White, Thickness = 1)]
        public IndicatorDataSeries MA3 { get; set; }

        private MarketSeries series1;
        private MarketSeries series2;
        private MarketSeries series3;

        private MovingAverage Ma1;
        private MovingAverage Ma2;
        private MovingAverage Ma3;

        protected override void Initialize()
        {
            series1 = MarketData.GetSeries(MATimeframe1);
            series2 = MarketData.GetSeries(MATimeframe2);
            series3 = MarketData.GetSeries(MATimeframe3);

            Ma1 = Indicators.MovingAverage(series1.Close, Periods, MAType);
            Ma2 = Indicators.MovingAverage(series2.Close, Periods, MAType);
            Ma3 = Indicators.MovingAverage(series3.Close, Periods, MAType);

        }

        public override void Calculate(int index)
        {

                        {

                var index1 = GetIndexByDate(series1, MarketSeries.OpenTime[index]);
                if (index1 != -1)
                {
                    MA1[index] = Ma1.Result[index1];
                }

                var index2 = GetIndexByDate(series2, MarketSeries.OpenTime[index]);
                if (index2 != -1)
                {
                    MA2[index] = Ma2.Result[index2];
                }

                var index3 = GetIndexByDate(series3, MarketSeries.OpenTime[index]);
                if (index3 != -1)
                {
                    MA3[index] = Ma3.Result[index3];
                }

            }
        }


        private int GetIndexByDate(MarketSeries series, DateTime time)
        {
            for (int i = series.Close.Count - 1; i > 0; i--)
            {
                if (time == series.OpenTime[i])
                    return i;
            }
            return -1;
        }
    }
}

 


@Symposium

Symposium
21 Aug 2018, 10:56

RE:

Panagiotis Charalampous said:

Hi Symposium

You can use this

Notifications.SendEmail(EmailAddressF, EmailAddressT, TimeFrame.ToString() + " " + SymbolCode + " | XeroLag Indicator is now displaying a BUYING opportunity", emailBodyB);

Best Regards,

Panagiotis

Cheers Panagiotas, once again, thanks for your prompt reply and solution to my question. :-)

Hopefully the Email Notification coding in this thread can be of help to others trying to get some time away from the screens.


@Symposium

Symposium
20 Aug 2018, 17:17

Adding Chart Timeframe to email Header or Body??

if (SendEmail)

Notifications.SendEmail(EmailAddressF, EmailAddressT, TimeFrame, SymbolCode + " | XeroLag Indicator is now displaying a BUYING opportunity", emailBodyB);

Hi Panagiotis, I am now trying to add the Chart Timeframe to the email message that is sent when this alert is triggered. I have numerous charts open at one time and while the email alert (and sound alert) indicate a change in trend, I need the email to confirm which pair (chart) it originated from.....and be Parameter adjustable...

[Parameter("Symbol", DefaultValue = "EURUSD")]
 public string SymbolCode { get; set; }

Eg: Email Header    " (60min) EURUSD    |    XeroLag Indicator is now displaying a BUYING opportunity"

Thanks once again in Advance...


@Symposium

Symposium
25 Jul 2018, 10:09

RE: Email Notification

Panagiotis Charalampous said:

Hi hiba7rain,

First of all you need to sort out the logic of what you are trying to do. Do you want the indicator to send an email once and never again? Then just raise a flag and do not reset it ever. But I guess your purpose is not that. Probably you would like to send one email per bar, when conditions are met. That is why proposed a cBot since it is easier to track bar changes with the OnBar() method. If you still want to keep the code in an indicator, there is nothing wrong with that, you just need to decide when you want your flag to be reset.

Best Regards,

Panagiotis

Hi Panagiotis, I assume what is required with the Email Notification, most posters are requiring the email be generated each time the Indicator displays a change of trend signal.

Change of signal code needs to be generated by the Indicator Logic and then trigger the Email Notification......once each change of trend / condition.

Example for an MA Indicator.

 Downtrend[index - 1] = _movingAverage3.Result[index - 1];

// Sell signal
IsSell = true;
IsBuy = false;

if (SoundAlert)

Notifications.PlaySound(_soundFileS);

if (EmailAlert)

Notifications.SendEmail("email@gmail.com", "email@tgmail.com", "Heikin Ashi is indicating a SELL Signal", emailBodyS);

It can be done inside an Indicator, the Indicator Logic needs to signal once per condition change.... not every Tick or Bar. Hope I haven't added any confusion...


@Symposium

Symposium
20 Jul 2018, 13:42

RE:

Panagiotis Charalampous said:

Hi Symposium,

In the past cTrader allowed traders to sign in either with their trading account or with their cTID. Therefore you had the choice to unlink/remove an account from your cTID. From cTrader 3.0 and on, cTID will become the only choice for signing in. Therefore all trading accounts will need to be linked to a cTID and that is why the option has been removed. If you wish to get rid of the account, you need to contact your broker to unlink it for you.

Best Regards,

Panagiotis

I spoke with my Broker (Pepperstone) and they said they cannot remove them either? 

I'll just wait the 30 days for the system to clear them.

Thanks once again Panagiotis, much appreciated.


@Symposium

Symposium
16 Jul 2018, 16:40

RE: Thanks for such a prompt reply :-)

Worked perfectly, Thanks Panagiotis, much appreciated.


@Symposium