Strategie der Nachfeiertagsschwäche
Die Nachfeiertagsschwäche bezeichnet die Tendenz, dass Kurse unmittelbar nach einem großen Feiertag fallen, wenn das Volumen noch gering ist. Da viele Marktteilnehmer noch abwesend sind, können Gegentrendbewegungen an Fahrt gewinnen.
Tests zeigen eine durchschnittliche jährliche Rendite von etwa 112%. Sie funktioniert am besten am Forex-Markt.
Die Strategie geht am Tag nach dem Feiertag short und schließt die Position schnell, sobald die normale Marktbeteiligung zurückkehrt.
Ein kleiner Stop wird verwendet, um übermäßige Verluste bei Handel mit geringer Liquidität zu vermeiden.
Details
- Einstiegskriterien: Kalendereffekt-Auslöser
- Long/Short: Beide
- Ausstiegskriterien: Stop-Loss oder entgegengesetztes Signal
- Stops: Ja, prozentbasiert
- Standardwerte:
CandleType= 15 minuteStopLoss= 2%
- Filter:
- Kategorie: Saisonalität
- Richtung: Beide
- Indikatoren: Saisonalität
- Stops: Ja
- Komplexität: Mittel
- Zeitrahmen: Intraday
- Saisonalität: Ja
- Neuronale Netze: Nein
- Divergenz: Nein
- Risikolevel: Mittel
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Implementation of Post-Holiday Weakness trading strategy.
/// Sells short on Monday (post-weekend weakness) if below MA, covers Wednesday.
/// Buys on Wednesday if above MA, exits Friday.
/// </summary>
public class PostHolidayWeaknessStrategy : Strategy
{
private readonly StrategyParam<int> _maPeriod;
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _cooldownBars;
private SimpleMovingAverage _ma;
private int _cooldown;
private DayOfWeek _prevDayOfWeek;
private bool _enteredThisDay;
/// <summary>
/// Moving average period.
/// </summary>
public int MaPeriod
{
get => _maPeriod.Value;
set => _maPeriod.Value = value;
}
/// <summary>
/// Candle type for strategy.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Cooldown bars between trades.
/// </summary>
public int CooldownBars
{
get => _cooldownBars.Value;
set => _cooldownBars.Value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="PostHolidayWeaknessStrategy"/>.
/// </summary>
public PostHolidayWeaknessStrategy()
{
_maPeriod = Param(nameof(MaPeriod), 20)
.SetGreaterThanZero()
.SetDisplay("MA Period", "Moving average period", "Strategy");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles for strategy", "Strategy");
_cooldownBars = Param(nameof(CooldownBars), 30)
.SetDisplay("Cooldown Bars", "Bars between trades", "General")
.SetRange(5, 500);
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_ma = default;
_cooldown = 0;
_prevDayOfWeek = DayOfWeek.Sunday;
_enteredThisDay = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_ma = new SimpleMovingAverage { Length = MaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_ma, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _ma);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal maValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var close = candle.ClosePrice;
var dayOfWeek = candle.OpenTime.DayOfWeek;
if (dayOfWeek != _prevDayOfWeek)
_enteredThisDay = false;
if (_cooldown > 0)
{
_cooldown--;
_prevDayOfWeek = dayOfWeek;
return;
}
// Monday: post-weekend weakness - short if below MA
if (dayOfWeek == DayOfWeek.Monday && !_enteredThisDay && Position == 0 && close < maValue)
{
SellMarket();
_cooldown = CooldownBars;
_enteredThisDay = true;
}
// Wednesday: cover short
else if (dayOfWeek == DayOfWeek.Wednesday && Position < 0 && !_enteredThisDay)
{
BuyMarket();
_cooldown = CooldownBars;
_enteredThisDay = true;
}
// Wednesday: buy if above MA
else if (dayOfWeek == DayOfWeek.Wednesday && !_enteredThisDay && Position == 0 && close > maValue)
{
BuyMarket();
_cooldown = CooldownBars;
_enteredThisDay = true;
}
// Friday: exit long
else if (dayOfWeek == DayOfWeek.Friday && Position > 0 && !_enteredThisDay)
{
SellMarket();
_cooldown = CooldownBars;
_enteredThisDay = true;
}
_prevDayOfWeek = dayOfWeek;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, DayOfWeek
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class post_holiday_weakness_strategy(Strategy):
"""
Post-Holiday Weakness trading strategy.
Sells short on Monday (post-weekend weakness) if below MA, covers Wednesday.
Buys on Wednesday if above MA, exits Friday.
"""
def __init__(self):
super(post_holiday_weakness_strategy, self).__init__()
self._ma_period = self.Param("MaPeriod", 20).SetDisplay("MA Period", "Moving average period", "Strategy")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))).SetDisplay("Candle Type", "Type of candles for strategy", "Strategy")
self._cooldown_bars = self.Param("CooldownBars", 30).SetDisplay("Cooldown Bars", "Bars between trades", "General")
self._cooldown = 0
self._prev_day_of_week = DayOfWeek.Sunday
self._entered_this_day = False
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(post_holiday_weakness_strategy, self).OnReseted()
self._cooldown = 0
self._prev_day_of_week = DayOfWeek.Sunday
self._entered_this_day = False
def OnStarted2(self, time):
super(post_holiday_weakness_strategy, self).OnStarted2(time)
self._cooldown = 0
self._prev_day_of_week = DayOfWeek.Sunday
self._entered_this_day = False
sma = SimpleMovingAverage()
sma.Length = self._ma_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(sma, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, sma)
self.DrawOwnTrades(area)
def _process_candle(self, candle, ma_val):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
ma = float(ma_val)
day_of_week = candle.OpenTime.DayOfWeek
cd = self._cooldown_bars.Value
if day_of_week != self._prev_day_of_week:
self._entered_this_day = False
if self._cooldown > 0:
self._cooldown -= 1
self._prev_day_of_week = day_of_week
return
# Monday: post-weekend weakness - short if below MA
if day_of_week == DayOfWeek.Monday and not self._entered_this_day and self.Position == 0 and close < ma:
self.SellMarket()
self._cooldown = cd
self._entered_this_day = True
# Wednesday: cover short
elif day_of_week == DayOfWeek.Wednesday and self.Position < 0 and not self._entered_this_day:
self.BuyMarket()
self._cooldown = cd
self._entered_this_day = True
# Wednesday: buy if above MA
elif day_of_week == DayOfWeek.Wednesday and not self._entered_this_day and self.Position == 0 and close > ma:
self.BuyMarket()
self._cooldown = cd
self._entered_this_day = True
# Friday: exit long
elif day_of_week == DayOfWeek.Friday and self.Position > 0 and not self._entered_this_day:
self.SellMarket()
self._cooldown = cd
self._entered_this_day = True
self._prev_day_of_week = day_of_week
def CreateClone(self):
return post_holiday_weakness_strategy()