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
}
}
andres.barar
Joined on 09.11.2021
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: PABollingerScalper.algo
- Rating: 5
- Installs: 2252
- Modified: 09/11/2021 19:20
Comments
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
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.