Esta estrategia de gestión de riesgo monitorea el capital de la cartera y cierra cualquier posición abierta cuando el capital supera el balance actual multiplicado por un multiplicador definido por el usuario. Está diseñada para asegurar ganancias una vez que el valor de la cuenta alcanza un porcentaje deseado sobre el valor base.
La estrategia realiza verificaciones periódicas utilizando velas y no genera entradas de operaciones por sí misma; solo gestiona una posición existente. Tras el cierre, el balance de referencia se actualiza, permitiendo que el proceso se repita para operaciones posteriores.
Detalles
Criterios de entrada: Ninguno (gestiona la posición existente).
Largo/Corto: Ambos direcciones.
Criterios de salida: Capital mayor que balance * EquityPercentFromBalance.
Stops: No.
Valores predeterminados:
EquityPercentFromBalance = 1.2m
CandleType = TimeSpan.FromMinutes(1)
Filtros:
Categoría: Gestión de riesgos
Dirección: Ambos
Indicadores: Ninguno
Stops: No
Complejidad: Básico
Marco temporal: Intradía (1m)
Estacionalidad: No
Redes neuronales: No
Divergencia: No
Nivel de riesgo: Bajo
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>
/// Closes position when equity exceeds balance by a given multiplier.
/// </summary>
public class CloseByEquityPercentStrategy : Strategy
{
private readonly StrategyParam<decimal> _equityPercent;
private readonly StrategyParam<DataType> _candleType;
private decimal _currentBalance;
/// <summary>
/// Equity to balance multiplier.
/// </summary>
public decimal EquityPercentFromBalance
{
get => _equityPercent.Value;
set => _equityPercent.Value = value;
}
/// <summary>
/// Candle type for periodic checks.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes a new instance of <see cref="CloseByEquityPercentStrategy"/>.
/// </summary>
public CloseByEquityPercentStrategy()
{
_equityPercent = Param(nameof(EquityPercentFromBalance), 1.2m)
.SetDisplay("Equity/Bal Multiplier", "Threshold multiplier for equity relative to balance", "Risk Management")
.SetOptimize(1.1m, 2m, 0.1m);
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles for periodic checks", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_currentBalance = 0m;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_currentBalance = Portfolio?.CurrentValue ?? 0m;
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 equity = Portfolio?.CurrentValue ?? 0m;
if (equity > _currentBalance * EquityPercentFromBalance)
{
if (Position > 0)
SellMarket(Position);
else if (Position < 0)
BuyMarket(-Position);
_currentBalance = equity;
return;
}
// Simple entry when flat
if (Position == 0)
{
_currentBalance = equity;
if (candle.ClosePrice > candle.OpenPrice)
BuyMarket();
else if (candle.ClosePrice < candle.OpenPrice)
SellMarket();
}
}
}
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 close_by_equity_percent_strategy(Strategy):
def __init__(self):
super(close_by_equity_percent_strategy, self).__init__()
self._equity_percent = self.Param("EquityPercentFromBalance", 1.2) \
.SetDisplay("Equity/Bal Multiplier", "Threshold multiplier for equity relative to balance", "Risk Management")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles for periodic checks", "General")
self._current_balance = 0.0
@property
def EquityPercentFromBalance(self):
return self._equity_percent.Value
@EquityPercentFromBalance.setter
def EquityPercentFromBalance(self, value):
self._equity_percent.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(close_by_equity_percent_strategy, self).OnStarted2(time)
portfolio = self.Portfolio
if portfolio is not None:
self._current_balance = float(portfolio.CurrentValue)
else:
self._current_balance = 0.0
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(self.ProcessCandle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def ProcessCandle(self, candle):
if candle.State != CandleStates.Finished:
return
portfolio = self.Portfolio
equity = float(portfolio.CurrentValue) if portfolio is not None else 0.0
if equity > self._current_balance * float(self.EquityPercentFromBalance):
pos = self.Position
if pos > 0:
self.SellMarket(pos)
elif pos < 0:
self.BuyMarket(-pos)
self._current_balance = equity
return
if self.Position == 0:
self._current_balance = equity
if candle.ClosePrice > candle.OpenPrice:
self.BuyMarket()
elif candle.ClosePrice < candle.OpenPrice:
self.SellMarket()
def OnReseted(self):
super(close_by_equity_percent_strategy, self).OnReseted()
self._current_balance = 0.0
def CreateClone(self):
return close_by_equity_percent_strategy()