The E-Friday Session strategy replicates the classic MetaTrader expert advisor that trades only on Fridays. It observes the previous daily candle and opens a position at a configured hour at the start of Friday's session. The direction is contrarian: if the previous day closed below its open (bearish candle), the strategy buys; if the previous day closed above its open (bullish candle), the strategy sells. Positions are managed intraday and can be closed automatically after a configurable hour or by protective stops.
Trading Rules
Collect daily candles (default: 1 day) to obtain the prior day's open and close.
On Fridays, monitor intraday candles (default: 1 minute) to detect the configured entry hour.
At the first candle of the entry hour:
Go long when the previous day was bearish.
Go short when the previous day was bullish.
Skip trading if the previous day was a doji (open equals close).
Optionally close the position automatically once the configured exit hour is reached.
Manage exits using stop-loss, take-profit, and optional trailing stop logic that mimics the original Expert Advisor, including the profit activation and trailing step thresholds.
Implementation Notes
Uses StockSharp high-level candle subscriptions for both daily context and intraday timing.
Converts point-based risk controls from the MQL version into absolute price offsets using the security's price step.
Maintains trailing stops in code, updating them on each finished candle and closing the position when price extremes are breached.
Ensures only one trade per Friday by tracking daily state.
Supports both long and short entries, respecting the original magic-number gating by trading a single symbol per strategy instance.
Parameters
Name
Description
Default
Volume
Trade size in lots/contracts.
0.1
StopLossPoints
Stop-loss distance in price steps (0 disables).
75
TakeProfitPoints
Take-profit distance in price steps (0 disables).
0
HourOpen
Hour of the day (0-23) to open the position.
7
UseClosePositions
Enable automatic closing after the exit hour.
true
HourClose
Hour of the day (0-23) to close the position if enabled.
19
UseTrailing
Enable trailing stop adjustments.
true
ProfitTrailing
Require profit to exceed trailing distance before trailing activates.
true
TrailingStopPoints
Trailing stop distance in price steps.
60
TrailingStepPoints
Additional points required before tightening the trailing stop.
5
IntradayCandleType
Candle type for intraday timing (default 1-minute candles).
TimeSpan.FromMinutes(1)
DailyCandleType
Candle type for daily sentiment detection (default 1-day candles).
TimeSpan.FromDays(1)
Usage Tips
Align the instrument's trading session so that the Friday entry hour matches the desired market open.
When configuring stop-loss and trailing values, express them in the same "points" used by the symbol's price step to reproduce the MetaTrader behavior.
The strategy is designed for a single trade per Friday. To trade multiple symbols, run separate strategy instances per symbol.
Differences from the Original EA
Uses candle close data for decision making, whereas the original polled prices per tick.
Protective exits are executed via market orders when candles indicate that stop or target levels were touched within the interval.
Strategy parameters are exposed through StockSharp's StrategyParam system, supporting optimization and UI binding.
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// E-Friday Session strategy - candle body direction with EMA filter.
/// Buys when previous candle was bearish and current closes above EMA (reversal).
/// Sells when previous candle was bullish and current closes below EMA (reversal).
/// </summary>
public class EFridaySessionStrategy : Strategy
{
private readonly StrategyParam<int> _emaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevOpen;
private decimal _prevClose;
private bool _hasPrev;
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public EFridaySessionStrategy()
{
_emaPeriod = Param(nameof(EmaPeriod), 20)
.SetDisplay("EMA Period", "EMA trend filter", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
protected override void OnReseted() { base.OnReseted(); _prevOpen = 0m; _prevClose = 0m; _hasPrev = false; }
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_hasPrev = false;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ema, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal ema)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
if (!_hasPrev)
{
_prevOpen = candle.OpenPrice;
_prevClose = close;
_hasPrev = true;
return;
}
var prevBearish = _prevClose < _prevOpen;
var prevBullish = _prevClose > _prevOpen;
// Previous bearish + close above EMA = buy reversal
if (prevBearish && close > ema && Position <= 0)
{
if (Position < 0)
BuyMarket();
BuyMarket();
}
// Previous bullish + close below EMA = sell reversal
else if (prevBullish && close < ema && Position >= 0)
{
if (Position > 0)
SellMarket();
SellMarket();
}
_prevOpen = candle.OpenPrice;
_prevClose = close;
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class e_friday_session_strategy(Strategy):
def __init__(self):
super(e_friday_session_strategy, self).__init__()
self._ema_period = self.Param("EmaPeriod", 20).SetDisplay("EMA Period", "EMA trend filter", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Candle timeframe", "General")
self._prev_open = 0.0
self._prev_close = 0.0
self._has_prev = False
@property
def ema_period(self): return self._ema_period.Value
@property
def candle_type(self): return self._candle_type.Value
def OnReseted(self):
super(e_friday_session_strategy, self).OnReseted()
self._prev_open = 0.0; self._prev_close = 0.0; self._has_prev = False
def OnStarted2(self, time):
super(e_friday_session_strategy, self).OnStarted2(time)
self._has_prev = False
ema = ExponentialMovingAverage()
ema.Length = self.ema_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema, self.process_candle).Start()
def process_candle(self, candle, ema):
if candle.State != CandleStates.Finished: return
close = float(candle.ClosePrice)
ema_val = float(ema)
if not self._has_prev:
self._prev_open = float(candle.OpenPrice); self._prev_close = close; self._has_prev = True; return
prev_bearish = self._prev_close < self._prev_open
prev_bullish = self._prev_close > self._prev_open
if prev_bearish and close > ema_val and self.Position <= 0:
if self.Position < 0: self.BuyMarket()
self.BuyMarket()
elif prev_bullish and close < ema_val and self.Position >= 0:
if self.Position > 0: self.SellMarket()
self.SellMarket()
self._prev_open = float(candle.OpenPrice); self._prev_close = close
def CreateClone(self): return e_friday_session_strategy()