Ver no GitHub

Estratégia Blonde Trader

Blonde Trader é uma estratégia de trading em grade convertida do MQL. Ela busca movimentos de preço afastando-se de extremos recentes e abre posições com uma grade de ordens pendentes.

Conceito

  • Calcular o máximo mais alto e o mínimo mais baixo nas últimas Period X velas.
  • Se o preço atual estiver abaixo da máxima recente por mais de Limit ticks, abrir uma posição comprada e colocar uma série de ordens buy limit formando uma grade.
  • Se o preço atual estiver acima da mínima recente por mais de Limit ticks, abrir uma posição vendida e colocar uma série de ordens sell limit formando uma grade.
  • Fechar todas as posições quando o lucro acumulado atingir Amount.
  • Opcionalmente, após o preço mover LockDown ticks em lucro, uma ordem stop é colocada no nível de equilíbrio para proteger a posição.

Parâmetros

Nome Descrição
PeriodX Período de retrocesso para a máxima mais alta e a mínima mais baixa.
Limit Distância mínima em ticks do preço atual até um extremo.
Grid Passo em ticks entre as ordens pendentes da grade.
Amount Meta de lucro na moeda da conta.
LockDown Distância em ticks para mover o stop ao ponto de equilíbrio.
CandleType Tipo de velas usadas para análise.

Indicadores

  • Highest – rastreia a máxima mais alta durante o período de retrocesso.
  • Lowest – rastreia a mínima mais baixa durante o período de retrocesso.

Lógica de Ordens

  1. Quando um setup comprado aparece:
    • Comprar a mercado com o volume padrão da estratégia.
    • Colocar quatro ordens buy limit adicionais abaixo da entrada, cada uma separada por Grid ticks e dobrando o volume.
  2. Quando um setup vendido aparece:
    • Vender a mercado com o volume padrão da estratégia.
    • Colocar quatro ordens sell limit adicionais acima da entrada com as mesmas regras de grade e duplicação de volume.
  3. Se PnL atingir Amount, todas as posições abertas e ordens pendentes são fechadas.
  4. Se LockDown for maior que zero e o preço tiver movido o número especificado de ticks a favor da posição, uma ordem stop protetora é colocada um tick além do preço de entrada.

Notas

Esta estratégia demonstra a lógica básica de trading em grade. Usa apenas recursos de API de alto nível: SubscribeCandles, vinculação de indicadores e auxiliares de ordens simples como BuyMarket, SellLimit e SellStop.

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;

/// <summary>
/// Blonde Trader strategy. Buys when price pulls back from recent high,
/// sells when price bounces from recent low. Uses Highest/Lowest indicators.
/// </summary>
public class BlondeTraderStrategy : Strategy
{
	private readonly StrategyParam<int> _lookback;
	private readonly StrategyParam<decimal> _threshold;
	private readonly StrategyParam<DataType> _candleType;

	private decimal _entryPrice;

	public int Lookback { get => _lookback.Value; set => _lookback.Value = value; }
	public decimal Threshold { get => _threshold.Value; set => _threshold.Value = value; }
	public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }

	public BlondeTraderStrategy()
	{
		_lookback = Param(nameof(Lookback), 20)
			.SetGreaterThanZero()
			.SetDisplay("Lookback", "Period for Highest/Lowest", "General");

		_threshold = Param(nameof(Threshold), 0.002m)
			.SetDisplay("Threshold", "Min distance ratio from extreme", "General");

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

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

	protected override void OnReseted()
	{
		base.OnReseted();
		_entryPrice = 0;
	}

	protected override void OnStarted2(DateTime time)
	{
		base.OnStarted2(time);

		var highest = new Highest { Length = Lookback };
		var lowest = new Lowest { Length = Lookback };

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

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

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

		var price = candle.ClosePrice;
		var range = high - low;

		if (range <= 0 || high == 0)
			return;

		var distFromHigh = (high - price) / high;
		var distFromLow = (price - low) / price;

		// Buy signal: price pulled back from high by at least threshold
		if (distFromHigh > Threshold && Position <= 0)
		{
			BuyMarket();
			_entryPrice = price;
		}
		// Sell signal: price bounced up from low by at least threshold
		else if (distFromLow > Threshold && Position >= 0)
		{
			SellMarket();
			_entryPrice = price;
		}
	}
}