StockSharp

Форк
0
294 строки · 8.0 Кб
1
#region S# License
2
/******************************************************************************************
3
NOTICE!!!  This program and source code is owned and licensed by
4
StockSharp, LLC, www.stocksharp.com
5
Viewing or use of this code requires your acceptance of the license
6
agreement found at https://github.com/StockSharp/StockSharp/blob/master/LICENSE
7
Removal of this comment is a violation of the license agreement.
8

9
Project: SampleHistoryTesting.SampleHistoryTestingPublic
10
File: SmaStrategy.cs
11
Created: 2015, 11, 11, 2:32 PM
12

13
Copyright 2010 by StockSharp, LLC
14
*******************************************************************************************/
15
#endregion S# License
16
namespace SampleHistoryTesting
17
{
18
	using System;
19
	using System.Linq;
20
	using System.Collections.Generic;
21

22
	using Ecng.Common;
23

24
	using StockSharp.Algo;
25
	using StockSharp.Algo.Indicators;
26
	using StockSharp.Algo.Strategies;
27
	using StockSharp.Logging;
28
	using StockSharp.BusinessEntities;
29
	using StockSharp.Messages;
30
	using StockSharp.Localization;
31
	using StockSharp.Charting;
32
	using StockSharp.Algo.Strategies.Protective;
33

34
	class SmaStrategy : Strategy
35
	{
36
		private readonly ProtectiveController _protectiveController = new();
37
		private IProtectivePositionController _posController;
38

39
		private IChart _chart;
40

41
		private readonly List<MyTrade> _myTrades = new();
42
		private bool? _isShortLessThenLong;
43
		private SimpleMovingAverage _shortSma;
44
		private SimpleMovingAverage _longSma;
45

46
		private IChartCandleElement _chartCandlesElem;
47
		private IChartTradeElement _chartTradesElem;
48
		private IChartIndicatorElement _chartLongElem;
49
		private IChartIndicatorElement _chartShortElem;
50

51
		public SmaStrategy()
52
        {
53
			_longSmaParam = this.Param(nameof(LongSma), 80);
54
			_shortSmaParam = this.Param(nameof(ShortSma), 30);
55
			_takeValue = this.Param(nameof(TakeValue), new Unit(1, UnitTypes.Percent));
56
			_stopValue = this.Param(nameof(StopValue), new Unit(2, UnitTypes.Percent));
57
			_candleTypeParam = this.Param(nameof(CandleType), DataType.TimeFrame(TimeSpan.FromMinutes(1))).NotNull();
58
			_candleTimeFrameParam = this.Param<TimeSpan?>(nameof(CandleTimeFrame));
59
			_buildFromParam = this.Param<DataType>(nameof(BuildFrom));
60
			_buildFieldParam = this.Param<Level1Fields?>(nameof(BuildField));
61
		}
62

63
		private readonly StrategyParam<TimeSpan?> _candleTimeFrameParam;
64

65
		public TimeSpan? CandleTimeFrame
66
		{
67
			get => _candleTimeFrameParam.Value;
68
			set => _candleTimeFrameParam.Value = value;
69
		}
70

71
		private readonly StrategyParam<int> _longSmaParam;
72

73
		public int LongSma
74
		{
75
			get => _longSmaParam.Value;
76
			set => _longSmaParam.Value = value;
77
		}
78

79
		private readonly StrategyParam<int> _shortSmaParam;
80

81
		public int ShortSma
82
		{
83
			get => _shortSmaParam.Value;
84
			set => _shortSmaParam.Value = value;
85
		}
86

87
		private readonly StrategyParam<DataType> _candleTypeParam;
88

89
		public DataType CandleType
90
		{
91
			get => _candleTypeParam.Value;
92
			set => _candleTypeParam.Value = value;
93
		}
94

95
		private readonly StrategyParam<DataType> _buildFromParam;
96

97
		public DataType BuildFrom
98
		{
99
			get => _buildFromParam.Value;
100
			set => _buildFromParam.Value = value;
101
		}
102

103
		private readonly StrategyParam<Level1Fields?> _buildFieldParam;
104

105
		public Level1Fields? BuildField
106
		{
107
			get => _buildFieldParam.Value;
108
			set => _buildFieldParam.Value = value;
109
		}
110

111
		private readonly StrategyParam<Unit> _takeValue;
112

113
		public Unit TakeValue
114
		{
115
			get => _takeValue.Value;
116
			set => _takeValue.Value = value;
117
		}
118

119
		private readonly StrategyParam<Unit> _stopValue;
120

121
		public Unit StopValue
122
		{
123
			get => _stopValue.Value;
124
			set => _stopValue.Value = value;
125
		}
126

127
		protected override void OnReseted()
128
		{
129
			base.OnReseted();
130

131
			_protectiveController.Clear();
132
			_posController = default;
133
		}
134

135
		protected override void OnStarted(DateTimeOffset time)
136
		{
137
			base.OnStarted(time);
138

139
			// !!! DO NOT FORGET add it in case use IsFormed property (see code below)
140
			Indicators.Add(_longSma = new SimpleMovingAverage { Length = LongSma });
141
			Indicators.Add(_shortSma = new SimpleMovingAverage { Length = ShortSma });
142
			
143
			_chart = this.GetChart();
144

145
			if (_chart != null)
146
			{
147
				var area = _chart.AddArea();
148

149
				_chartCandlesElem = area.AddCandles();
150
				_chartTradesElem = area.AddTrades();
151
				_chartShortElem = area.AddIndicator(_shortSma);
152
				_chartLongElem = area.AddIndicator(_longSma);
153

154
				// make short line coral color
155
				_chartShortElem.Color = System.Drawing.Color.Coral;
156
			}
157

158
			var dt = CandleType;
159

160
			if (CandleTimeFrame is not null)
161
			{
162
				dt = DataType.Create(dt.MessageType, CandleTimeFrame);
163
			}
164

165
			var subscription = new Subscription(dt, Security)
166
			{
167
				MarketData =
168
				{
169
					IsFinishedOnly = true,
170
					BuildFrom = BuildFrom,
171
					BuildMode = BuildFrom is null ? MarketDataBuildModes.LoadAndBuild : MarketDataBuildModes.Build,
172
					BuildField = BuildField,
173
				}
174
			};
175

176
			subscription
177
				.WhenCandleReceived(this)
178
				.Do(ProcessCandle)
179
				.Apply(this);
180

181
			this
182
				.WhenNewMyTrade()
183
				.Do(t =>
184
				{
185
					_myTrades.Add(t);
186

187
					var security = t.Order.Security;
188
					var portfolio = t.Order.Portfolio;
189

190
					if (TakeValue.IsSet() || StopValue.IsSet())
191
					{
192
						_posController ??= _protectiveController.GetController(
193
							security.ToSecurityId(),
194
							portfolio.Name,
195
							new LocalProtectiveBehaviourFactory(security.PriceStep, security.Decimals),
196
							TakeValue, StopValue, true, true, default, default, true);
197
					}
198

199
					var info = _posController?.Update(t.Trade.Price, t.GetPosition());
200

201
					if (info is not null)
202
						ActiveProtection(info.Value);
203
				})
204
				.Apply(this);
205

206
			_isShortLessThenLong = null;
207

208
			Subscribe(subscription);
209
		}
210

211
		private void ProcessCandle(ICandleMessage candle)
212
		{
213
			// strategy are stopping
214
			if (ProcessState == ProcessStates.Stopping)
215
			{
216
				CancelActiveOrders();
217
				return;
218
			}
219

220
			this.AddInfoLog(LocalizedStrings.SmaNewCandleLog, candle.OpenTime, candle.OpenPrice, candle.HighPrice, candle.LowPrice, candle.ClosePrice, candle.TotalVolume, candle.SecurityId);
221

222
			// try activate local stop orders (if they present)
223
			var info = _posController?.TryActivate(candle.ClosePrice, CurrentTime);
224

225
			if (info is not null)
226
				ActiveProtection(info.Value);
227

228
			// process new candle
229
			var longValue = _longSma.Process(candle);
230
			var shortValue = _shortSma.Process(candle);
231

232
			// all indicators added in OnStarted now is fully formed and we can use it
233
			// or user turned off allow trading
234
			if (this.IsFormedAndOnlineAndAllowTrading())
235
			{
236
				// in case we subscribed on non finished only candles
237
				if (candle.State == CandleStates.Finished)
238
				{
239
					// calc new values for short and long
240
					var isShortLessThenLong = shortValue.GetValue<decimal>() < longValue.GetValue<decimal>();
241

242
					if (_isShortLessThenLong == null)
243
					{
244
						_isShortLessThenLong = isShortLessThenLong;
245
					}
246
					else if (_isShortLessThenLong != isShortLessThenLong) // crossing happened
247
					{
248
						// if short less than long, the sale, otherwise buy
249
						var direction = isShortLessThenLong ? Sides.Sell : Sides.Buy;
250

251
						// calc size for open position or revert
252
						var volume = Position == 0 ? Volume : Position.Abs().Min(Volume) * 2;
253

254
						// calc order price as a close price
255
						var price = candle.ClosePrice;
256

257
						RegisterOrder(this.CreateOrder(direction, price, volume));
258

259
						// or revert position via market quoting
260
						//var strategy = new MarketQuotingStrategy(direction, volume);
261
						//ChildStrategies.Add(strategy);
262

263
						// store current values for short and long
264
						_isShortLessThenLong = isShortLessThenLong;
265
					}
266
				}
267
			}
268

269
			var trade = _myTrades.FirstOrDefault();
270
			_myTrades.Clear();
271

272
			if (_chart == null)
273
				return;
274

275
			var data = _chart.CreateData();
276

277
			data
278
				.Group(candle.OpenTime)
279
					.Add(_chartCandlesElem, candle)
280
					.Add(_chartShortElem, shortValue)
281
					.Add(_chartLongElem, longValue)
282
					.Add(_chartTradesElem, trade)
283
					;
284

285
			_chart.Draw(data);
286
		}
287

288
		private void ActiveProtection((bool isTake, Sides side, decimal price, decimal volume, OrderCondition condition) info)
289
		{
290
			// sending protection (=closing position) order as regular order
291
			RegisterOrder(this.CreateOrder(info.side, info.price, info.volume));
292
		}
293
	}
294
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.