Category Trend  Published on 09/11/2021

PABollingerScalper

Description

This bot makes use of price action mixed with standard Bollinger bands and an exponential moving average to find a good trading opportunity.

----------------------------------------------------------------------------------------------------------------
         Trading using leverage carries a high degree of risk to your capital, and it is possible to lose more than
          your initial investment. Only speculate with money you can afford to lose.

----------------------------------------------------------------------------------------------------------------

tested using NAS100 symbol and 2m chart.

Symbol                  =    NAS100
Timeframe             =    m2

Source                   =    Close
Period                    =    50
Volume                  =    1 lot

Bars Range                   =    5
Offset Pips StopLoss    =    15
BE Start                        =   15
TP/SL Ratio                  =    3
Trail                              =    2

BBO Source                =    Close
BBO MA Type             =    Exponential
Periods                       =    20
St. Dev                        =    2


Results :

Date                       =    Between 01/01/2020 and 08/11/2021 profit of $1070.30 USD (+107%)
Net profit                =    1070.30 USD
Ending Equity        =    2070.30 USD
Sharpe Ratio         =    0.13
Sortino Ratio         =    0.17
Effectiveness        =   162/235 = 68.9%

 

tested using BTCUSD symbol and h1chart.

Symbol                  =    BTCUSD
Timeframe             =    h1

Source                   =    Close
Period                    =    50
Volume                  =    0.1 lot

Bars Range                   =    5
Offset Pips StopLoss    =    50000
BE Start                        =    25000
TP/SL Ratio                  =    3
Trail                              =    100

BBO Source                =    Close
BBO MA Type             =    Exponential
Periods                       =    20
St. Dev                        =    2
 


Results :

Date                       =    Between 01/01/2020 and 08/11/2021 profit of $2805.20 USD (+285%)
Net profit                =    2805.20  USD
Ending Equity        =    3805.20  USD
Sharpe Ratio         =    0.64
Sortino Ratio         =    01.11
Effectiveness        =   6/8 = 75%

 

 





#region cBot Parameters Comments
//	Symbole			        =	NAS100
//	Timeframe		        =	m2
//
//	Source			        =	Close
//	Period			        =	50
//	Volume			        =	1 lot
//
//	Bars Range		        =	5
//	Offset Pips StopLoss	=	15
//  BE Start                =   15
//	TP/SL Ratio		        =	3
//	Trail			        =	2
//
//	BBO Source		        =	Close
//	BBO MA Type		        =	Exponential
//	Periods  		        =	20
//	St. Dev  		        =	2
//
//	Results :
//          Date			     =	Between 01/01/2020 and 08/11/2021 profit of $1070.30 USD (+107%)
//			Net profit			=	1070.30 USD
//			Ending Equity		=	2070.30 USD
//			Sharpe Ratio		=	0.13
//			Sortino Ratio      	=	0.17
//          effectiveness       =   162/235 = 68.9%
#endregion

#region advertisement
// -------------------------------------------------------------------------------
//			Trading using leverage carries a high degree of risk to your capital, and it is possible to lose more than
//			your initial investment. Only speculate with money you can afford to lose.
// -------------------------------------------------------------------------------
#endregion


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.UTC, AccessRights = AccessRights.None)]
    public class PABollingerScalper : Robot
    {
        #region Prameters
        [Parameter("Source EMA")]
        public DataSeries Source_EMA { get; set; }

        [Parameter("Periods EMA", DefaultValue = 50)]
        public int Periods_EMA { get; set; }

        [Parameter("Volume", DefaultValue = 1, MinValue = 1E-06)]
        public double Volume { get; set; }

        [Parameter("Bars Range", DefaultValue = 5, MinValue = 1)]
        public int barsRange { get; set; }

        [Parameter("Offset Pips StopLoss", DefaultValue = 15, MinValue = 1)]
        public int offsetStopLoss { get; set; }

        [Parameter("TP/SL Ratio", DefaultValue = 3, MinValue = 1)]
        public int ratio { get; set; }

        [Parameter("BE Start", DefaultValue = 15, MinValue = 1)]
        public int BE_Start { get; set; }

        [Parameter("Trail", DefaultValue = 2, MinValue = 1)]
        public int Trail { get; set; }

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

        [Parameter("BBO MA Type", DefaultValue = MovingAverageType.Exponential)]
        public MovingAverageType BBO_MaType { get; set; }

        [Parameter("Periods", DefaultValue = 20)]
        public int BBO_Periods { get; set; }

        [Parameter("St. Dev", DefaultValue = 2)]
        public int BBO_ST_Dev { get; set; }
        #endregion

        #region Globals

        private ExponentialMovingAverage _EMA;
        private BollingerBands _BBO;
        // Bot Name
        private const string botName = "PABollingerScalper";
        private const int highCeil = 80;
        private const int lowCeil = 20;
        private double extremeHigh = 0;
        private double extremeLow = 0;
        private int idxHigh = 0;
        private int idxLow = 0;
        #endregion

        #region cBot Events
        protected override void OnStart()
        {
            base.OnStart();
            _EMA = Indicators.ExponentialMovingAverage(Source_EMA, Periods_EMA);
            _BBO = Indicators.BollingerBands(source_BBO, BBO_Periods, BBO_ST_Dev, BBO_MaType);

            Positions.Closed += OnPositionClosed;


        }

        protected override void OnStop()
        {
            base.OnStop();
            closePositions();

        }

        protected override void OnTick()
        {

            foreach (var position in Positions.FindAll(botName, Symbol.Name))
            {
                if (position.Pips > BE_Start)
                {
                    double actualPrice = isBuy(position) ? Symbol.Bid : Symbol.Ask;
                    int factor = isBuy(position) ? 1 : -1;

                    double? newStopLoss = position.StopLoss;
                    /// Stop a ZERO
                    if ((position.EntryPrice - newStopLoss) * factor > 0)
                    {
                        newStopLoss = position.EntryPrice;
                    }
                    if ((actualPrice - newStopLoss) * factor > Trail * Symbol.PipSize)
                    {
                        newStopLoss += factor * Trail * Symbol.PipSize;
                        if (newStopLoss != position.StopLoss)
                            ModifyPosition(position, newStopLoss, position.TakeProfit.Value);
                    }
                }

            }
            //searchSignals();


        }

        protected override void OnBar()
        {
            searchSignals();
        }

        private void searchSignals()
        {
            var index = this.Bars.ClosePrices.Count - 2;
            var earliest = index - barsRange;
            for (var i = index; i >= earliest; i--)
            {
                if (i >= 0)
                {
                    var high = this.Bars.HighPrices[i];
                    var low = this.Bars.LowPrices[i];
                    if (high > this.extremeHigh)
                    {
                        idxHigh = i;
                    }
                    if (low < this.extremeLow)
                    {
                        idxLow = i;
                    }

                    this.extremeHigh = Math.Max(high, this.extremeHigh);
                    this.extremeLow = this.extremeLow == 0 ? low : Math.Min(low, this.extremeLow);


                }
                else
                {
                    break;
                }
            }



            if (!isBuyPositions && isPABBuySignal)
            {
                closePositions(TradeType.Sell);
                Open(TradeType.Buy);
            }
            else if (!isSellPositions && isPABSellSignal)
            {
                closePositions(TradeType.Buy);
                Open(TradeType.Sell);
            }

            this.extremeLow = 0;
            this.extremeHigh = 0;
        }

        private void OnPositionClosed(PositionClosedEventArgs args)
        {
        }
        #endregion

        #region cBot Action
        private void Open(TradeType tradeType)
        {
            double actualPrice = isBuy(tradeType) ? Symbol.Bid : Symbol.Ask;
            int stopLoss = (int)(isBuy(tradeType) ? actualPrice - this.extremeLow : this.extremeHigh - actualPrice) + offsetStopLoss;
            ExecuteMarketOrder(tradeType, Symbol.Name, Volume, botName, stopLoss, stopLoss * ratio);
        }

        private void closePosition(Position position)
        {
            var result = ClosePosition(position);

            if (!result.IsSuccessful)
                Print("error : {0}", result.Error);

        }

        // Close all positiones by "tradeType"
        private void closePositions(TradeType tradeType)
        {
            foreach (Position position in Positions.FindAll(botName, Symbol.Name, tradeType))
                closePosition(position);

        }

        // Close all position
        private void closePositions()
        {
            closePositions(TradeType.Buy);
            closePositions(TradeType.Sell);
        }
        #endregion

        #region cBot Predicate

        private bool isPABBuySignal
        {
            get { return _BBO.Bottom[this.idxLow] > this.extremeLow && _EMA.Result.IsRising() && (Symbol.Bid > this.extremeHigh) && (Symbol.Bid > _BBO.Main.LastValue) && (Symbol.Bid < _BBO.Top.LastValue); }
        }


        private bool isPABSellSignal
        {
            get { return _BBO.Top[this.idxHigh] < this.extremeHigh && _EMA.Result.IsFalling() && (Symbol.Ask < this.extremeLow) && (Symbol.Ask < _BBO.Main.LastValue) && (Symbol.Ask > _BBO.Bottom.LastValue); }
        }

        private bool isBuy(Position position)
        {
            return TradeType.Buy == position.TradeType;
        }
        private bool isBuy(TradeType tradeType)
        {
            return TradeType.Buy == tradeType;
        }

        private bool isBuyPositions
        {
            get { return Positions.Find(botName, Symbol.Name, TradeType.Buy) != null; }
        }


        private bool isSellPositions
        {
            get { return Positions.Find(botName, Symbol.Name, TradeType.Sell) != null; }
        }

        #endregion

        #region cBot Utils
        private int OpenedTrades
        {
            get { return Positions.FindAll(botName, Symbol.Name).Count(); }
        }
        #endregion

    }
}


AN
andres.barar

Joined on 09.11.2021

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: PABollingerScalper.algo
  • Rating: 5
  • Installs: 2056
Comments
Log in to add a comment.
EF
efrencarterr · 1 year ago

Is it really working? Can we make it work on Gacha Neon? As it is the best-modified version of Gacha Club, also it has few features of Gacha Life too. 

CO
codey · 2 years ago

Which instrument it works on?  It doesn't work on Forex it seems?

What exactly is this bot doing?  When does it open/close positions?

What is 'Bars Range' parameter?

Thanks