Diese Strategie repliziert das Verhalten eines HFT-Spreaders auf dem FORTS-Markt. Sie überwacht kontinuierlich das Orderbuch und platziert Limit-Orders auf beiden Marktseiten, um die Geld-Brief-Spanne zu erfassen.
Strategielogik
Abonnieren von Echtzeit-Orderbuch-Updates.
Wenn keine Position offen ist und die Spanne groß genug ist (bestimmt durch SpreadMultiplier), platziert die Strategie:
Eine Kauf-Limit-Order einen Tick über dem besten Geldkurs.
Eine Verkauf-Limit-Order einen Tick unter dem besten Briefkurs.
Wenn eine Position besteht und keine aktiven Orders vorhanden sind, wird eine einzelne Limit-Order auf der Gegenseite platziert, um die Position zu schließen und umzukehren.
Orders werden storniert und ersetzt, wenn sich die besten Kurse bewegen, um sie an der Spitze des Buches zu halten.
Parameter
SpreadMultiplier – erforderliche Spanne in Ticks, um sowohl Kauf- als auch Verkaufsorders zu platzieren. Standard sind 4 Ticks.
Volume – Order-Volumen. Standard ist 1 Lot.
Verwendungshinweise
Entwickelt für Instrumente mit kleinen Tick-Größen, wie Futures an der FORTS-Börse.
Verwendet ausschließlich Limit-Orders; keine Marktorders werden gesendet, außer vom Schutzmechanismus wenn nötig.
Ausreichende Liquidität und eine Umgebung mit geringer Latenz für effektiven Betrieb sicherstellen.
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy that captures the spread on FORTS by trading when spread is wide enough.
/// </summary>
public class HftSpreaderForFortsStrategy : Strategy
{
private readonly StrategyParam<int> _spreadMultiplier;
private readonly StrategyParam<DataType> _candleType;
/// <summary>
/// Required spread in ticks to place both buy and sell orders.
/// </summary>
public int SpreadMultiplier
{
get => _spreadMultiplier.Value;
set => _spreadMultiplier.Value = value;
}
/// <summary>
/// Candle type for price feed.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initialize <see cref="HftSpreaderForFortsStrategy"/>.
/// </summary>
public HftSpreaderForFortsStrategy()
{
_spreadMultiplier = Param(nameof(SpreadMultiplier), 4)
.SetGreaterThanZero()
.SetDisplay("Spread Multiplier", "Spread ticks required to place orders", "General")
.SetOptimize(1, 10, 1);
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
.SetDisplay("Candle Type", "Candle type for price feed", "General");
Volume = 1;
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
StartProtection(null, null);
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
var step = Security.PriceStep ?? 1m;
var spread = candle.HighPrice - candle.LowPrice;
if (spread >= SpreadMultiplier * step)
{
if (Position == 0)
{
// Wide spread detected - buy at low, will exit when spread narrows
BuyMarket();
}
else if (Position > 0)
{
// Close long position for spread capture
SellMarket();
}
else if (Position < 0)
{
// Close short position for spread capture
BuyMarket();
}
}
}
}
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.Strategies import Strategy
class hft_spreader_for_forts_strategy(Strategy):
"""
HFT Spreader for FORTS: trades when candle spread is wide enough.
Opens and closes based on high-low range vs spread multiplier.
"""
def __init__(self):
super(hft_spreader_for_forts_strategy, self).__init__()
self._spread_multiplier = self.Param("SpreadMultiplier", 4) \
.SetDisplay("Spread Multiplier", "Spread ticks required to place orders", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(1))) \
.SetDisplay("Candle Type", "Candle type for price feed", "General")
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(hft_spreader_for_forts_strategy, self).OnStarted2(time)
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._process_candle).Start()
def _process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
step = 1.0
if self.Security is not None and self.Security.PriceStep is not None:
step = float(self.Security.PriceStep)
if step <= 0:
step = 1.0
spread = float(candle.HighPrice) - float(candle.LowPrice)
if spread >= self._spread_multiplier.Value * step:
if self.Position == 0:
self.BuyMarket()
elif self.Position > 0:
self.SellMarket()
elif self.Position < 0:
self.BuyMarket()
def CreateClone(self):
return hft_spreader_for_forts_strategy()