using System; using System.Collections.Generic; using System.Linq; using StockSharp.Algo.Candles; using StockSharp.Algo.Logging; using StockSharp.Algo; using StockSharp.Algo.Strategies; using StockSharp.BusinessEntities; namespace SampleHistoryTesting { class MyStopLossStrategy : Strategy { private readonly CandleSeries _series; private readonly TimeSpan _timeFrame; private Exchange _excheng; private Random _random; private Order _order=new Order(); private static readonly object Locker = new object (); public MyStopLossStrategy( CandleSeries series, TimeSpan timeFrame ) { _series = series; _timeFrame = timeFrame; } protected override void OnStarted() { _excheng = Security.Exchange; _series .WhenCandlesFinished () .Do ( ProcessCandle ).Apply ( this ); // Инициализируем генератор случ величин _random = new Random ( 1 ); base.OnStarted (); } private void ProcessCandle( Candle candle ) { /* Три условия вхождения в сделку * 1. пришла последняя свечка * 2. Protective стратегия больше не активна */ var lastTime = _timeFrame.GetCandleBounds ( Trader.GetMarketTime (_excheng) ).Min - _timeFrame; #region InfoLog this.AddInfoLog(string.Format("LastTime / candle.OpenTime // {0} / {1} //", lastTime, candle.OpenTime)); this.AddInfoLog(string.Format("StopLoss (активна -true) = {0}", IsActiveChildStrat())); #endregion lock (Locker) { //var lastTime = Trader.GetMarketTime ( _excheng ); //var endInterval = candle.CloseTime + TimeSpan.FromSeconds ( 5 ); if (lastTime <= candle.OpenTime) { if (_order.State == OrderStates.Active) CancelActiveOrders (); if (!IsActiveChildStrat ()) { _order = null; // Определяем направление сделки var rd = 1 - 2 * _random.NextDouble (); // -1 < rd < 1 var direction = OrderDirections.Sell; if (rd >= 0) direction = OrderDirections.Buy; _order = this.CreateOrder ( direction, (decimal)Security.GetCurrentPrice ( direction ), Volume ); //Обрабатываем новые сделки только от _order. _order.WhenNewTrades ().Do ( NewMyTrade ).Apply ( this ); RegisterOrder ( _order ); this.AddOrderInfoLog ( _order, "" ); } } } } private void NewMyTrade( IEnumerable trades ) { try { lock (Locker) { var trade = trades.Last (); var sl = new StopLossStrategy ( trade, (int)UnitTypes.Absolute ) { IsTrailing = true, ProtectiveLevel =Security.MinStepSize, Security = Security, }; // Удоляем следы работы дочерней стратегии sl.WhenStopped ().Do ( strategy => { ChildStrategies.Remove ( strategy ); this.AddInfoLog ( string.Format ( "Кол. StopLoss активных стратегий = {0}",ChildStrategies.Count)); } ).Once ().Apply ( this ); ChildStrategies.Add ( sl ); this.AddInfoLog ( string.Format ( "ProtectivePrice / ProtectiveDirection= //{0} / {1} ", sl.ActivationPrice.ToString("F2"), sl.ProtectiveDirection.ToString() ) ); this.AddInfoLog ( string.Format ( "StopLoss = {0}", sl.IsActivated.ToString() ) ); } } catch (Exception e) { this.AddErrorLog ( string.Format ( " Err {0}", e ) ); } } /* Метод проверяет активность одной из нескольких стратегий, * если хотя бы одна активна возвращает true */ public bool IsActiveChildStrat() { try { if (ChildStrategies.Count == 0) return false; if (ChildStrategies.Count > 0) return true; /* if (ChildStrategies.Any ( childStrategy => childStrategy.ProcessState == ProcessStates.Started || childStrategy.ProcessState == ProcessStates.Stopping )) { return true; } */ } catch (Exception e) { this.AddErrorLog ( string.Format ( " Err {0}", e ) ); } return false; } protected override void OnStopping() { //останавливаем все доч. стратегии foreach (var str in ChildStrategies) { str.Stop (); } ChildStrategies.Clear (); CancelActiveOrders (); base.OnStopping (); } } }