Estrategia de Referencia con Lanzamiento de Moneda Aleatorio
Esta estrategia replica el clásico ejemplo de GuruTrader donde la dirección del trade se determina mediante un lanzamiento de moneda.
En cada vela terminada, si no hay ninguna posición abierta, se genera un número pseudoaleatorio y se trata como un lanzamiento de moneda.
Cara abre una posición larga mientras que cruz abre una corta.
Cada trade aplica distancias fijas de take-profit y stop-loss medidas en unidades de precio absoluto.
Parámetros
Take Profit – distancia desde el precio de entrada para colocar la orden de take-profit.
Stop Loss – distancia desde el precio de entrada para colocar la orden de stop-loss.
Use Time Seed – inicializa el generador aleatorio con la hora actual para obtener resultados diferentes en cada ejecución. Cuando está desactivado, se usa una semilla fija.
Candle Type – tipo de velas procesadas por la estrategia.
Lógica de Trading
Esperar una vela terminada.
Asegurarse de que la estrategia puede operar y no hay posición abierta.
Generar un valor aleatorio y elegir la dirección basándose en el lanzamiento de moneda.
Proteger la posición con las distancias predefinidas de stop-loss y take-profit.
Advertencia: Esta estrategia es solo para fines educativos y nunca debe usarse en cuentas reales.
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy that tosses a virtual coin to decide trade direction.
/// A long position is opened on heads, a short position on tails.
/// Closes after N candles and re-enters.
/// </summary>
public class RandomCoinTossBaselineStrategy : Strategy
{
private readonly StrategyParam<int> _holdBars;
private readonly StrategyParam<DataType> _candleType;
private Random _random;
private int _barsInPosition;
public int HoldBars
{
get => _holdBars.Value;
set => _holdBars.Value = value;
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public RandomCoinTossBaselineStrategy()
{
_holdBars = Param(nameof(HoldBars), 10)
.SetGreaterThanZero()
.SetDisplay("Hold Bars", "Number of bars to hold position", "General");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to process", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_random = null;
_barsInPosition = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_random = new Random(42);
_barsInPosition = 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;
// Close position after holding for N bars
if (Position != 0)
{
_barsInPosition++;
if (_barsInPosition >= HoldBars)
{
if (Position > 0)
SellMarket();
else
BuyMarket();
_barsInPosition = 0;
}
return;
}
// Flip coin and enter
var coin = _random.Next(2);
if (coin == 0)
BuyMarket();
else
SellMarket();
_barsInPosition = 0;
}
}
import clr
import random as py_random
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 random_coin_toss_baseline_strategy(Strategy):
def __init__(self):
super(random_coin_toss_baseline_strategy, self).__init__()
self._hold_bars = self.Param("HoldBars", 10) \
.SetDisplay("Hold Bars", "Number of bars to hold position", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles to process", "General")
self._random = None
self._bars_in_position = 0
@property
def hold_bars(self):
return self._hold_bars.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(random_coin_toss_baseline_strategy, self).OnReseted()
self._random = None
self._bars_in_position = 0
def OnStarted2(self, time):
super(random_coin_toss_baseline_strategy, self).OnStarted2(time)
self._random = py_random.Random(42)
self._bars_in_position = 0
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
if self.Position != 0:
self._bars_in_position += 1
if self._bars_in_position >= int(self.hold_bars):
if self.Position > 0:
self.SellMarket()
else:
self.BuyMarket()
self._bars_in_position = 0
return
coin = self._random.randint(0, 1)
if coin == 0:
self.BuyMarket()
else:
self.SellMarket()
self._bars_in_position = 0
def CreateClone(self):
return random_coin_toss_baseline_strategy()