Gerbil M5 Scalper

by Zaknafein Zakynthos in category Range at 31/10/2018
Description

Described in the article here:

http://dswp.co.uk/index.php/2018/10/31/thepipsmasteruk-zulutrade-strategy/

Also works well on H1 chart.

Donations welcome to:
BTC: 33gjtYhKVqFxmcbcko63WnwiVJvew3PauQ
ETH: 0xb54dF35117D94a43Ca25A3A348Ac20DF7F667F7b
LTC: M8YRuyH5USv2MvJyyF55U5ik1yMfm6TtMH

Cheers,

Zaknafein Z.

Download
923 downloads
How to install
Warning! Executing the following cBot may result in loss of funds. Use it at your own risk.
Notification Publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section you may use the Copyright Infringement Notification form to submit a claim.
Formula / Source Code
Language: C#
Trading Platform: cAlgo
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.GMTStandardTime, AccessRights = AccessRights.None)]
    public class Gerbil : Robot
    {
        [Parameter("Trade Start Hour", DefaultValue = 23, MinValue = 0, Step = 1)]
        public int TradeStart { get; set; }
        [Parameter("Trade End Hour", DefaultValue = 1, MinValue = 0, Step = 1)]
        public int TradeEnd { get; set; }
        [Parameter("Take Profit (Pips)", DefaultValue = 6, MinValue = 1, Step = 1)]
        public int TakeProfit { get; set; }
        [Parameter("Stop Loss (Pips)", DefaultValue = 150, MinValue = 1, Step = 1)]
        public int StopLoss { get; set; }
        [Parameter("Calculate Volume by Percentage?", DefaultValue = false)]
        public bool RiskPercent { get; set; }
        [Parameter("Quantity (%Risk or Lots)", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)]
        public double Quantity { get; set; }
        [Parameter("RSI Source")]
        public DataSeries RSISource { get; set; }
        [Parameter("RSI Period", DefaultValue = 7, MinValue = 1, Step = 1)]
        public int RSIPeriods { get; set; }
        [Parameter("RSI Overbought Level", DefaultValue = 80, MinValue = 1, Step = 1)]
        public int RSIOverB { get; set; }
        [Parameter("RSI Oversold Level", DefaultValue = 40, MinValue = 1, Step = 1)]
        public int RSIOverS { get; set; }
        [Parameter("ATR Periods", DefaultValue = 15, MinValue = 1, Step = 1)]
        public int ATRPeriods { get; set; }
        [Parameter("ATR From", DefaultValue = 10, MinValue = 1, Step = 1)]
        public int ATRFrom { get; set; }
        [Parameter("ATR To", DefaultValue = 100, MinValue = 1, Step = 1)]
        public int ATRTo { get; set; }
        [Parameter("Max Positions", DefaultValue = 1, MinValue = 1, Step = 1)]
        public int MaxPos { get; set; }
        [Parameter("Max DD Positions", DefaultValue = 0, MinValue = 0, Step = 1)]
        public int MaxDDPos { get; set; }
        [Parameter("KillHours", DefaultValue = 0, MinValue = 0, Step = 1)]
        public int KillHours { get; set; }

        private RelativeStrengthIndex rsi;
        private AverageTrueRange atr;
        private int DDPos = 0;

        protected override void OnStart()
        {
            rsi = Indicators.RelativeStrengthIndex(RSISource, RSIPeriods);
            atr = Indicators.AverageTrueRange(ATRPeriods, MovingAverageType.Simple);
        }

        protected override void OnBar()
        {
            if (Time.Hour >= TradeStart || Time.Hour < TradeEnd)
            {
                var atrVal = atr.Result.LastValue * 100000;
                if (atrVal > ATRFrom && atrVal < ATRTo)
                {
                    if (Positions.Count < MaxPos)
                    {
                        if (rsi.Result.LastValue < RSIOverS)
                        {
                            Open(TradeType.Buy);
                        }
                        else if (rsi.Result.LastValue > RSIOverB)
                        {
                            Open(TradeType.Sell);
                        }
                    }
                }
            }
            if (KillHours != 0)
            {
                foreach (var position in Positions.FindAll("SampleRSI", Symbol))
                {
                    if (Time > position.EntryTime.AddMinutes(KillHours * 60))
                        ClosePosition(position);
                }
            }
        }


        private void Open(TradeType tradeType)
        {
            //var position = Positions.Find("SampleRSI", Symbol, tradeType);
            var volumeInUnits = CalculateVolume();

            ExecuteMarketOrder(tradeType, Symbol, volumeInUnits, "SampleRSI", StopLoss, TakeProfit);
        }



        double CalculateVolume()
        {
            if (!RiskPercent)
            {
                return (Symbol.QuantityToVolumeInUnits(Quantity));
            }
            else
            {
                // Calculate the total risk allowed per trade.
                double riskPerTrade = (Account.Balance * Quantity) / 100;
                double totalSLPipValue = (StopLoss + Symbol.Spread) * Symbol.PipValue;
                double calculatedVolume = riskPerTrade / totalSLPipValue;

                double normalizedCalculatedVolume = Symbol.NormalizeVolumeInUnits(calculatedVolume, RoundingMode.ToNearest);
                return normalizedCalculatedVolume;
            }
        }


    }
}
Comments

Zaknafein Zakynthos - November 13, 2018 @ 16:10

Hi all,

Here are some observations.  I can quite easily modify the Cbot to take account of these, but I won't post updates here unless I get some feedback.  There are 130 downloads, and I simply can't be bothered to provide an update unless I get feedback from the Ctrader community.   I am making this freely available after all.

Also: just to pre-empt any copyright claims.  I didn't copy any code from another EA.  I am just making an accurate copy of the logic.  You can't copyright a strategy.

I find that the take profit settings on the Hamster EA are quite different from my 'Gerbil' CBot.   On my Cbot I just scalp for 6 pips profit each time.  But Hamster has 2 options:

  • "Lossless"
  • "From Last Order"

I think that this refers to open positions only, while standard TP is 6 (while no previous orders are open).  But I am not 100% sure.  Maybe it doesn't just apply to currently open positions, but I can't imagine it works on closed orders (even in loss).  I will work on this.

There are some other differences between Hamster and my 'Gerbil' Cbot:

  • No news filter (in fact I don't think many people use this, but manually pause the EA on days of high volatility 
  • I don't use 'virtual' SL or TP.  I set the SL and TP on the order.  I did this because it's easier and I don't use a VPS.  I just have a laptop running in the garage for live trading, but it's on Windows 10 and it resets itself for Windows Update all the time, so Virtual TP and SL is dangerous because it must be always online.

qpwo603604 - November 21, 2018 @ 10:27

Hi, when i'm using hamster, i found the spread is a little bit higher in MT4 platform, so i came here to see if there's a bot for cTrader, and i found you, when i see the code using RSI and ATR.

the difference you talking about, i think it close all buy(sell) order at average TP 6pips. Just caculating he opening position. especially in new hamster version and some sets, it open less order, so it's easy to caculated.

Another  different i think may be it use 2 ATR indicator? i'm not a coder, just guess from the setting and your code.

Anyway i will try to use this bot on try to set it on a tiny live account to see how it works.

Thanks for your sharing! Do you got any telegrame or something we can have a chat and discuss?

ricky.global9 - December 27, 2018 @ 11:48

Few trades but accurate and works good, but whenever SL is triggered it gives a huge loss. Can you not do something for this?

marius38@gmail.com - February 11, 2019 @ 01:42

How works the EA ? When does enter trades, can you show on a chart ?

I know is using the ATR and the RSI but will be easier to see on a chart if possible

Thanks

 

sascha.dawe - February 11, 2019 @ 02:36

Hi Zaknafein,

Great work on this cbot. I have made a slight modification, so that when counting max positions, it only counts the open Gerbil positions. This allows you to open manual trades or run other cbots on the same account concurrently, if the max positions are set to one.

I would like to work on this with you further. If you are interested, please contact me via my email account.

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.GMTStandardTime, AccessRights = AccessRights.None)]
    public class Gerbil : Robot
    {
        [Parameter("Trade Start Hour", DefaultValue = 23, MinValue = 0, Step = 1)]
        public int TradeStart { get; set; }
        [Parameter("Trade End Hour", DefaultValue = 1, MinValue = 0, Step = 1)]
        public int TradeEnd { get; set; }
        [Parameter("Take Profit (Pips)", DefaultValue = 6, MinValue = 1, Step = 1)]
        public int TakeProfit { get; set; }
        [Parameter("Stop Loss (Pips)", DefaultValue = 150, MinValue = 1, Step = 1)]
        public int StopLoss { get; set; }
        [Parameter("Calculate Volume by Percentage?", DefaultValue = false)]
        public bool RiskPercent { get; set; }
        [Parameter("Quantity (%Risk or Lots)", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)]
        public double Quantity { get; set; }
        [Parameter("RSI Source")]
        public DataSeries RSISource { get; set; }
        [Parameter("RSI Period", DefaultValue = 7, MinValue = 1, Step = 1)]
        public int RSIPeriods { get; set; }
        [Parameter("RSI Overbought Level", DefaultValue = 80, MinValue = 1, Step = 1)]
        public int RSIOverB { get; set; }
        [Parameter("RSI Oversold Level", DefaultValue = 40, MinValue = 1, Step = 1)]
        public int RSIOverS { get; set; }
        [Parameter("ATR Periods", DefaultValue = 15, MinValue = 1, Step = 1)]
        public int ATRPeriods { get; set; }
        [Parameter("ATR From", DefaultValue = 10, MinValue = 1, Step = 1)]
        public int ATRFrom { get; set; }
        [Parameter("ATR To", DefaultValue = 100, MinValue = 1, Step = 1)]
        public int ATRTo { get; set; }
        [Parameter("Max Positions", DefaultValue = 1, MinValue = 1, Step = 1)]
        public int MaxPos { get; set; }
        [Parameter("Max DD Positions", DefaultValue = 0, MinValue = 0, Step = 1)]
        public int MaxDDPos { get; set; }
        [Parameter("KillHours", DefaultValue = 0, MinValue = 0, Step = 1)]
        public int KillHours { get; set; }

        private RelativeStrengthIndex rsi;
        private AverageTrueRange atr;
        private int DDPos = 0;

        protected override void OnStart()
        {
            rsi = Indicators.RelativeStrengthIndex(RSISource, RSIPeriods);
            atr = Indicators.AverageTrueRange(ATRPeriods, MovingAverageType.Simple);
        }

        protected override void OnBar()
        {
            if (Time.Hour >= TradeStart || Time.Hour < TradeEnd)
            {
                var atrVal = atr.Result.LastValue * 100000;
                if (atrVal > ATRFrom && atrVal < ATRTo)
                {
                    var positionsGerbil = Positions.FindAll("Gerbil", Symbol);
                    if (positionsGerbil.Length < MaxPos)
                    {
                        if (rsi.Result.LastValue < RSIOverS)
                        {
                            Open(TradeType.Buy);
                        }
                        else if (rsi.Result.LastValue > RSIOverB)
                        {
                            Open(TradeType.Sell);
                        }
                    }
                }
            }
            if (KillHours != 0)
            {

                foreach (var position in Positions.FindAll("Gerbil", Symbol))
                {
                    if (Time > position.EntryTime.AddMinutes(KillHours * 60))
                        ClosePosition(position);
                }
            }
        }


        private void Open(TradeType tradeType)
        {
            //var position = Positions.Find("SampleRSI", Symbol, tradeType);
            var volumeInUnits = CalculateVolume();

            ExecuteMarketOrder(tradeType, Symbol, volumeInUnits, "Gerbil", StopLoss, TakeProfit);
        }

        double CalculateVolume()
        {
            if (!RiskPercent)
            {
                return (Symbol.QuantityToVolumeInUnits(Quantity));
            }
            else
            {
                // Calculate the total risk allowed per trade.
                double riskPerTrade = (Account.Balance * Quantity) / 100;
                double totalSLPipValue = (StopLoss + Symbol.Spread) * Symbol.PipValue;
                double calculatedVolume = riskPerTrade / totalSLPipValue;

                double normalizedCalculatedVolume = Symbol.NormalizeVolumeInUnits(calculatedVolume, RoundingMode.ToNearest);
                return normalizedCalculatedVolume;
            }
        }


    }
}

frutoide - February 17, 2019 @ 21:29

Hi Zaknafein Zakynthos, thanks for the code. I've not been able to try it yet, because i'm pretty new to cTrader and I don't even know if there is already a backtest tool like in mt4. It would be very very nice if you could upload an updated version. VPS SL and TP could be a good thing, but otherwise, any kind of update that you have implemented, it would be really nice to try. Since I'm also a programmer, although new in cAlgo, I hope I could help in something to make it better. My email is frutoide@gmail.com, please contact me :)

5