Auf GitHub ansehen

CM Fishing Strategie

Überblick

Die CM Fishing Strategie ist ein Grid-Trading-Ansatz, der vom ursprünglichen MQL-Skript cm_fishing.mq4 adaptiert wurde. Die Strategie eröffnet Marktorders, wenn sich der Preis um eine feste Anzahl von Punkten vom letzten ausgeführten Trade bewegt. Sie kann ein Grid aus Long- oder Short-Positionen aufbauen und sie schließen, wenn ein bestimmtes Gewinnziel erreicht wird.

Diese Implementierung konzentriert sich auf die Kernhandelslogik ohne die grafische Benutzeroberfläche des ursprünglichen Skripts. Orders werden über die High-Level-API von StockSharp ausgeführt.

Parameter

Name Beschreibung
Buy Aktiviert oder deaktiviert das Öffnen von Long-Positionen.
Sell Aktiviert oder deaktiviert das Öffnen von Short-Positionen.
StepBuy Preisschritt in Punkten nach unten, bevor eine neue Long-Position eröffnet wird.
StepSell Preisschritt in Punkten nach oben, bevor eine neue Short-Position eröffnet wird.
CloseProfitBuy Gewinnschwelle zum Schließen aller Long-Positionen.
CloseProfitSell Gewinnschwelle zum Schließen aller Short-Positionen.
CloseProfit Gewinnschwelle, die jede offene Position unabhängig von der Richtung schließt.
BuyVolume Ordervolumen für jeden Long-Trade.
SellVolume Ordervolumen für jeden Short-Trade.

Handelslogik

  1. Trade-Preise in Echtzeit verfolgen.
  2. Wenn der Preis um StepBuy vom letzten Trade-Niveau fällt und Buy aktiviert ist, eine Markt-Kauforder senden.
  3. Wenn der Preis um StepSell vom letzten Trade-Niveau steigt und Sell aktiviert ist, eine Markt-Verkaufsorder senden.
  4. Den durchschnittlichen Einstiegspreis der aktuellen Position pflegen.
  5. Positionen schließen, wenn der unrealisierte Gewinn den entsprechenden CloseProfit*-Parameter überschreitet.

Die Strategie arbeitet mit Tick-Daten und eignet sich für Demonstrations- und Bildungszwecke.

Hinweise

  • Die Implementierung reproduziert nicht die Benutzeroberfläche des ursprünglichen Skripts.
  • Es wird zu jedem Zeitpunkt nur eine Netto-Position (Long oder Short) gehalten.
using System;
using System.Collections.Generic;

using Ecng.Common;

using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;

namespace StockSharp.Samples.Strategies;

/// <summary>
/// Grid trading strategy based on fixed price steps.
/// Buys when price drops by step amount, sells when price rises by step amount.
/// Closes on profit threshold.
/// </summary>
public class CmFishingStrategy : Strategy
{
	private readonly StrategyParam<decimal> _stepSize;
	private readonly StrategyParam<decimal> _profitTarget;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _referencePrice;
	private decimal _entryPrice;

	public decimal StepSize
	{
		get => _stepSize.Value;
		set => _stepSize.Value = value;
	}

	public decimal ProfitTarget
	{
		get => _profitTarget.Value;
		set => _profitTarget.Value = value;
	}

	public DataType CandleType
	{
		get => _candleType.Value;
		set => _candleType.Value = value;
	}

	public CmFishingStrategy()
	{
		_stepSize = Param(nameof(StepSize), 500m)
			.SetGreaterThanZero()
			.SetDisplay("Step Size", "Price step for grid entries", "Parameters");

		_profitTarget = Param(nameof(ProfitTarget), 300m)
			.SetGreaterThanZero()
			.SetDisplay("Profit Target", "Price profit to close position", "Parameters");

		_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
			.SetDisplay("Candle Type", "Candle timeframe", "General");
	}

	/// <inheritdoc />
	public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
	{
		return [(Security, CandleType)];
	}

	/// <inheritdoc />
	protected override void OnReseted()
	{
		base.OnReseted();
		_referencePrice = 0;
		_entryPrice = 0;
	}

	/// <inheritdoc />
	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		_referencePrice = 0;
		_entryPrice = 0;

		var subscription = SubscribeCandles(CandleType);
		subscription
			.Bind(ProcessCandle)
			.Start();

		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle)
	{
		if (candle.State != CandleStates.Finished)
			return;

		var price = candle.ClosePrice;

		if (_referencePrice == 0)
		{
			_referencePrice = price;
			return;
		}

		// Check profit target first
		if (Position > 0 && price >= _entryPrice + ProfitTarget)
		{
			SellMarket();
			_referencePrice = price;
			_entryPrice = 0;
			return;
		}
		else if (Position < 0 && price <= _entryPrice - ProfitTarget)
		{
			BuyMarket();
			_referencePrice = price;
			_entryPrice = 0;
			return;
		}

		// Grid entries: buy on dip, sell on rise
		if (price <= _referencePrice - StepSize && Position <= 0)
		{
			BuyMarket();
			_entryPrice = price;
			_referencePrice = price;
		}
		else if (price >= _referencePrice + StepSize && Position >= 0)
		{
			SellMarket();
			_entryPrice = price;
			_referencePrice = price;
		}
	}
}