Ver en GitHub

Estrategia de Trading por Teoría de Juegos

La Estrategia de Trading por Teoría de Juegos combina análisis del comportamiento de manada, detección de trampas de liquidez, flujo institucional y zonas de equilibrio de Nash para operar movimientos contrarios y de momentum.

La estrategia observa los extremos del RSI y los picos de volumen para identificar compras o ventas masivas. Las trampas de liquidez alrededor de máximos y mínimos recientes, junto con el indicador de acumulación/distribución y el sesgo del dinero inteligente, refinan las entradas. Las bandas de precio construidas a partir de una media móvil y la desviación estándar definen el equilibrio de Nash para operaciones de reversión. El tamaño de la posición se adapta cuando el precio está cerca del equilibrio o aparece volumen institucional.

Detalles

  • Datos: Velas de precio y volumen.
  • Criterios de entrada: Señales contrarias, de momentum o de reversión Nash.
  • Criterios de salida: Stop loss / take profit o señales opuestas.
  • Stops: Stop loss y take profit opcionales.
  • Valores predeterminados:
    • RsiLength = 14
    • VolumeMaLength = 20
    • HerdThreshold = 2.0
    • LiquidityLookback = 50
    • InstVolumeMultiplier = 2.5
    • InstMaLength = 21
    • NashPeriod = 100
    • NashDeviation = 0.02
    • UseStopLoss = True
    • StopLossPercent = 2
    • UseTakeProfit = True
    • TakeProfitPercent = 5
  • Filtros:
    • Categoría: Mixto contrario/momentum
    • Dirección: Largo y Corto
    • Indicadores: RSI, SMA, Accumulation/Distribution, StandardDeviation, Highest/Lowest
    • Complejidad: Avanzado
    • Nivel de riesgo: Medio
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;

public class GameTheoryTradingStrategy : Strategy
{
	private readonly StrategyParam<int> _fastEmaPeriod;
	private readonly StrategyParam<int> _slowEmaPeriod;
	private readonly StrategyParam<DataType> _candleType;
	private decimal _prevFastEma;
	private decimal _prevSlowEma;

	public int FastEmaPeriod { get => _fastEmaPeriod.Value; set => _fastEmaPeriod.Value = value; }
	public int SlowEmaPeriod { get => _slowEmaPeriod.Value; set => _slowEmaPeriod.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public GameTheoryTradingStrategy()
	{
		_fastEmaPeriod = Param(nameof(FastEmaPeriod), 120)
			.SetGreaterThanZero()
			.SetDisplay("Fast EMA", "Fast EMA period", "Indicators");
		_slowEmaPeriod = Param(nameof(SlowEmaPeriod), 450)
			.SetGreaterThanZero()
			.SetDisplay("Slow EMA", "Slow EMA period", "Indicators");
		_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(1).TimeFrame())
			.SetDisplay("Candle Type", "Type of candles to use", "General");
	}

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_prevFastEma = 0m;
		_prevSlowEma = 0m;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);
		var fastEma = new ExponentialMovingAverage { Length = FastEmaPeriod };
		var slowEma = new ExponentialMovingAverage { Length = SlowEmaPeriod };
		var subscription = SubscribeCandles(CandleType);
		subscription.Bind(fastEma, slowEma, ProcessCandle).Start();
		var area = CreateChartArea();
		if (area != null)
		{
			DrawCandles(area, subscription);
			DrawIndicator(area, fastEma);
			DrawIndicator(area, slowEma);
			DrawOwnTrades(area);
		}
	}

	private void ProcessCandle(ICandleMessage candle, decimal fastEmaValue, decimal slowEmaValue)
	{
		if (candle.State != CandleStates.Finished) return;
		if (_prevFastEma == 0m || _prevSlowEma == 0m)
		{
			_prevFastEma = fastEmaValue;
			_prevSlowEma = slowEmaValue;
			return;
		}
		if (_prevFastEma <= _prevSlowEma && fastEmaValue > slowEmaValue && Position <= 0)
			BuyMarket();
		else if (_prevFastEma >= _prevSlowEma && fastEmaValue < slowEmaValue && Position >= 0)
			SellMarket();
		_prevFastEma = fastEmaValue;
		_prevSlowEma = slowEmaValue;
	}
}