The Gonna Scalp strategy is a high-frequency MetaTrader expert advisor ported to the StockSharp high level API. The system hunts for rapid mean-reversion entries on a short-term chart while respecting the dominant market trend. Confirmation is produced by a voting mechanism that evaluates momentum, CCI, ATR, stochastic oscillator and MACD filters before permitting a trade. Only one position may be open at a time and every trade is protected by fixed stop-loss and take-profit distances expressed in MetaTrader points.
Trading Logic
Indicator preparation
Fast and slow weighted moving averages (WMA) computed on typical price.
Momentum (period 14) evaluated on the trading timeframe and converted into an absolute distance from the neutral value 100.
Commodity Channel Index (period 20) and Average True Range (period 12) used as directional filters.
Stochastic oscillator %K/%D (5/3/3) and MACD (12/26/9) processed on the same candle series.
Signal voting
Each indicator contributes one vote for the bullish or bearish side when its current reading supports the trend identified in the original MetaTrader code.
The strategy collects three recent momentum distances and requires at least one of them to exceed a configurable threshold before allowing a new trade.
Additional structure checks demand that the low of the bar two candles ago remains below the high of the previous bar for longs (mirror condition for shorts).
Order execution
When the bullish votes exceed bearish votes and all filters agree, the strategy opens a long position using the configured lot size.
When the bearish votes dominate the bullish votes and the momentum filter approves, a short position is opened.
Risk management
Each open trade is accompanied by fixed stop-loss and take-profit distances measured in MetaTrader points and translated into instrument price steps.
Protective logic closes the position on the current candle once either level has been breached.
Key Parameters
Name
Description
Default
TradeVolume
Base order size in lots after volume alignment.
0.01
FastMaPeriod
Length of the fast WMA filter.
1
SlowMaPeriod
Length of the slow WMA filter.
5
MomentumPeriod
Number of bars used by the momentum indicator.
14
MomentumBuyThreshold
Minimum absolute momentum deviation required for long entries.
0.3
MomentumSellThreshold
Minimum absolute momentum deviation required for short entries.
0.3
StopLossSteps
Stop-loss distance expressed in MetaTrader points.
200
TakeProfitSteps
Take-profit distance expressed in MetaTrader points.
200
CandleType
Timeframe used for all indicators (defaults to 5-minute candles).
M5
Usage Notes
Align the strategy volume with the traded instrument by adjusting TradeVolume; the implementation automatically normalizes it to the exchange lot step.
The stop-loss and take-profit parameters operate in MetaTrader points. They are converted to instrument price units based on the instrument precision.
At least three completed candles are required before the voting logic can produce signals because of the momentum history buffer.
The strategy deliberately avoids pyramiding; a new trade is not opened until the previous position has been closed by risk management or an opposite signal.
You can connect the strategy to StockSharp charts to visualize the WMAs, stochastic and MACD series for signal validation.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Gonna Scalp strategy: WMA crossover with CCI momentum filter.
/// Buys when fast WMA above slow WMA and CCI above -100.
/// Sells when fast WMA below slow WMA and CCI below 100.
/// </summary>
public class GonnaScalpStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _fastPeriod;
private readonly StrategyParam<int> _slowPeriod;
private readonly StrategyParam<int> _cciPeriod;
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public int FastPeriod
{
get => _fastPeriod.Value;
set => _fastPeriod.Value = value;
}
public int SlowPeriod
{
get => _slowPeriod.Value;
set => _slowPeriod.Value = value;
}
public int CciPeriod
{
get => _cciPeriod.Value;
set => _cciPeriod.Value = value;
}
public GonnaScalpStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_fastPeriod = Param(nameof(FastPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("Fast WMA", "Fast WMA period", "Indicators");
_slowPeriod = Param(nameof(SlowPeriod), 30)
.SetGreaterThanZero()
.SetDisplay("Slow WMA", "Slow WMA period", "Indicators");
_cciPeriod = Param(nameof(CciPeriod), 14)
.SetGreaterThanZero()
.SetDisplay("CCI Period", "CCI period", "Indicators");
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new WeightedMovingAverage { Length = FastPeriod };
var slow = new WeightedMovingAverage { Length = SlowPeriod };
var cci = new CommodityChannelIndex { Length = CciPeriod };
decimal? prevFast = null;
decimal? prevSlow = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fast, slow, cci, (candle, fastVal, slowVal, cciVal) =>
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (prevFast.HasValue && prevSlow.HasValue)
{
var crossUp = prevFast.Value <= prevSlow.Value && fastVal > slowVal;
var crossDown = prevFast.Value >= prevSlow.Value && fastVal < slowVal;
if (crossUp && cciVal > -100m && Position <= 0)
BuyMarket();
else if (crossDown && cciVal < 100m && Position >= 0)
SellMarket();
}
prevFast = fastVal;
prevSlow = slowVal;
})
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fast);
DrawIndicator(area, slow);
DrawOwnTrades(area);
}
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import WeightedMovingAverage, CommodityChannelIndex
from StockSharp.Algo.Strategies import Strategy
class gonna_scalp_strategy(Strategy):
def __init__(self):
super(gonna_scalp_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._fast_period = self.Param("FastPeriod", 10) \
.SetGreaterThanZero() \
.SetDisplay("Fast WMA", "Fast WMA period", "Indicators")
self._slow_period = self.Param("SlowPeriod", 30) \
.SetGreaterThanZero() \
.SetDisplay("Slow WMA", "Slow WMA period", "Indicators")
self._cci_period = self.Param("CciPeriod", 14) \
.SetGreaterThanZero() \
.SetDisplay("CCI Period", "CCI period", "Indicators")
self._prev_fast = None
self._prev_slow = None
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(gonna_scalp_strategy, self).OnReseted()
self._prev_fast = None
self._prev_slow = None
def OnStarted2(self, time):
super(gonna_scalp_strategy, self).OnStarted2(time)
self._fast_ind = WeightedMovingAverage()
self._fast_ind.Length = self._fast_period.Value
self._slow_ind = WeightedMovingAverage()
self._slow_ind.Length = self._slow_period.Value
self._cci_ind = CommodityChannelIndex()
self._cci_ind.Length = self._cci_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._fast_ind, self._slow_ind, self._cci_ind, self._process_candle).Start()
def _process_candle(self, candle, fast_value, slow_value, cci_value):
if candle.State != CandleStates.Finished:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
fast_val = float(fast_value)
slow_val = float(slow_value)
cci_val = float(cci_value)
if self._prev_fast is not None and self._prev_slow is not None:
cross_up = self._prev_fast <= self._prev_slow and fast_val > slow_val
cross_down = self._prev_fast >= self._prev_slow and fast_val < slow_val
if cross_up and cci_val > -100.0 and self.Position <= 0:
self.BuyMarket()
elif cross_down and cci_val < 100.0 and self.Position >= 0:
self.SellMarket()
self._prev_fast = fast_val
self._prev_slow = slow_val
def CreateClone(self):
return gonna_scalp_strategy()