StockSharp

Форк
0
296 строк · 8.6 Кб
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: SampleHistoryTestingParallel.SampleHistoryTestingParallelPublic
10
File: MainWindow.xaml.cs
11
Created: 2015, 11, 11, 2:32 PM
12

13
Copyright 2010 by StockSharp, LLC
14
*******************************************************************************************/
15
#endregion S# License
16

17
namespace SampleHistoryTestingParallel
18
{
19
	using System;
20
	using System.IO;
21
	using System.Linq;
22
	using System.Windows;
23
	using System.Windows.Media;
24
	using System.Collections.Generic;
25

26
	using Ecng.Xaml;
27
	using Ecng.Common;
28
	using Ecng.Serialization;
29
	using Ecng.Compilation;
30
	using Ecng.Configuration;
31
	using Ecng.Compilation.Roslyn;
32
	using Ecng.ComponentModel;
33
	using Ecng.Collections;
34

35
	using StockSharp.Algo;
36
	using StockSharp.Algo.Storages;
37
	using StockSharp.Algo.Strategies;
38
	using StockSharp.Algo.Strategies.Optimization;
39
	using StockSharp.Algo.Commissions;
40
	using StockSharp.BusinessEntities;
41
	using StockSharp.Logging;
42
	using StockSharp.Messages;
43
	using StockSharp.Localization;
44
	using StockSharp.Configuration;
45

46
	public partial class MainWindow
47
	{
48
		private DateTime _startEmulationTime;
49

50
		private BaseOptimizer _optimizer;
51

52
		public MainWindow()
53
		{
54
			InitializeComponent();
55

56
			ConfigManager.RegisterService<ICompiler>(new RoslynCompiler());
57
			HistoryPath.Folder = Paths.HistoryDataPath;
58
			GeneticSettings.SelectedObject = new GeneticSettings();
59
		}
60

61
		private void StartBtnClick(object sender, RoutedEventArgs e)
62
		{
63
			if (_optimizer != null)
64
			{
65
				_optimizer.Resume();
66
				return;
67
			}
68

69
			OptimizeTypeGrid.IsEnabled = false;
70

71
			if (HistoryPath.Folder.IsEmpty() || !Directory.Exists(HistoryPath.Folder))
72
			{
73
				MessageBox.Show(this, LocalizedStrings.WrongPath);
74
				return;
75
			}
76

77
			TestingProcess.Value = 0;
78
			TestingProcessText.Text = string.Empty;
79

80
			Stat.Clear();
81
			Stat.ClearColumns();
82
			Stat.CreateColumns(new SampleHistoryTesting.SmaStrategy());
83

84
			var logManager = new LogManager();
85
			var fileLogListener = new FileLogListener("sample.log");
86
			logManager.Listeners.Add(fileLogListener);
87

88
			(int min, int max, int step) longRange = new(50, 100, 5);
89
			(int min, int max, int step) shortRange = new(20, 40, 1);
90
			(TimeSpan min, TimeSpan max, TimeSpan step) tfRange = new(TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(15), TimeSpan.FromMinutes(5));
91

92
			// SMA periods
93
			var periods = new List<(int longMa, int shortMa, TimeSpan tf, Color color)>();
94

95
			for (var l = longRange.max; l >= longRange.min; l -= longRange.step)
96
			{
97
				for (var s = shortRange.max; s >= shortRange.min; s -= shortRange.step)
98
				{
99
					for (var t = tfRange.max; t >= tfRange.min; t -= tfRange.step)
100
					{
101
						periods.Add((l, s, t, Color.FromRgb((byte)RandomGen.GetInt(255), (byte)RandomGen.GetInt(255), (byte)RandomGen.GetInt(255))));
102
					}
103
				}
104
			}
105

106
			// storage to historical data
107
			var storageRegistry = new StorageRegistry
108
			{
109
				// set historical path
110
				DefaultDrive = new LocalMarketDataDrive(HistoryPath.Folder)
111
			};
112

113
			// create test security
114
			var security = new Security
115
			{
116
				Id = "SBER@TQBR", // sec id has the same name as folder with historical data
117
				Code = "SBER",
118
				Name = "SBER",
119
				Board = ExchangeBoard.Micex,
120
				PriceStep = 0.01m,
121
			};
122

123
			var startTime = Paths.HistoryBeginDate;
124
			var stopTime = Paths.HistoryEndDate;
125

126
			// test portfolio
127
			var portfolio = Portfolio.CreateSimulator();
128

129
			var secProvider = new CollectionSecurityProvider(new[] { security });
130
			var pfProvider = new CollectionPortfolioProvider(new[] { portfolio });
131

132
			if (BruteForce.IsChecked == true)
133
				_optimizer = new BruteForceOptimizer(secProvider, pfProvider, storageRegistry);
134
			else
135
				_optimizer = new GeneticOptimizer(secProvider, pfProvider, storageRegistry);
136

137
			var settings = _optimizer.EmulationSettings;
138

139
			// set max possible iteration to 100
140
			settings.MaxIterations = 100;
141

142
			// 1 cent commission for trade
143
			settings.CommissionRules = new ICommissionRule[]
144
			{
145
				new CommissionPerTradeRule { Value = 0.01m },
146
			};
147

148
			// count of parallel testing strategies
149
			// if not set, then CPU count * 2
150
			//_optimizer.EmulationSettings.BatchSize = 1;
151

152
			// settings caching mode non security optimized param
153
			_optimizer.AdapterCache = new();
154

155
			var ids = new SynchronizedSet<Guid>();
156

157
			// handle single iteration progress
158
			_optimizer.SingleProgressChanged += (s, a, p) =>
159
			{
160
				if (ids.TryAdd(s.Id))
161
					this.GuiAsync(() => Stat.AddStrategy(s));
162
				else
163
					this.GuiAsync(() => Stat.UpdateProgress(s, p));
164
			};
165

166
			// handle historical time for update ProgressBar
167
			_optimizer.TotalProgressChanged += (progress, duration, remaining) => this.GuiAsync(() =>
168
			{
169
				TestingProcess.Value = progress;
170

171
				var remainingSeconds = remaining == TimeSpan.MaxValue ? "unk" : ((int)remaining.TotalSeconds).To<string>();
172
				TestingProcessText.Text = $"{progress}% | {(int)duration.TotalSeconds} sec left | {remainingSeconds} sec rem";
173
			});
174

175
			_optimizer.StateChanged += (oldState, newState) =>
176
			{
177
				this.GuiAsync(() =>
178
				{
179
					switch (newState)
180
					{
181
						case ChannelStates.Stopping:
182
						case ChannelStates.Starting:
183
						case ChannelStates.Suspending:
184
							SetIsEnabled(false, false, false, false);
185
							break;
186
						case ChannelStates.Stopped:
187
							SetIsEnabled(true, false, false, true);
188

189
							if (!_optimizer.IsCancelled)
190
							{
191
								TestingProcess.Value = TestingProcess.Maximum;
192
								MessageBox.Show(this, LocalizedStrings.CompletedIn.Put(DateTime.Now - _startEmulationTime));
193
							}
194
							else
195
								MessageBox.Show(this, LocalizedStrings.Cancelled);
196

197
							_optimizer = null;
198

199
							break;
200
						case ChannelStates.Started:
201
							SetIsEnabled(false, true, true, false);
202
							break;
203
						case ChannelStates.Suspended:
204
							SetIsEnabled(true, false, true, false);
205
							break;
206
						default:
207
							throw new ArgumentOutOfRangeException(newState.ToString());
208
					}
209
				});
210
			};
211

212
			_startEmulationTime = DateTime.Now;
213

214
			if (_optimizer is BruteForceOptimizer btOptimizer)
215
			{
216
				var strategies = periods
217
					.Select(period =>
218
					{
219
						// create strategy based SMA
220
						var strategy = new SampleHistoryTesting.SmaStrategy
221
						{
222
							ShortSma = period.shortMa,
223
							LongSma = period.longMa,
224

225
							Volume = 1,
226
							Security = security,
227
							Portfolio = portfolio,
228
							//Connector = connector,
229

230
							// by default interval is 1 min,
231
							// it is excessively for time range with several months
232
							UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To<TimeSpan>(),
233

234
							Name = $"L={period.longMa} S={period.shortMa}",
235

236
							CandleTimeFrame = period.tf,
237
						};
238

239
						return ((Strategy)strategy, new IStrategyParam[]
240
						{
241
							strategy.Parameters.GetByName(nameof(strategy.ShortSma)),
242
							strategy.Parameters.GetByName(nameof(strategy.LongSma)),
243
							strategy.Parameters.GetByName(nameof(strategy.CandleTimeFrame)),
244
						});
245
					});
246

247
				// start emulation
248
				btOptimizer.Start(startTime, stopTime, strategies, periods.Count);
249
			}
250
			else
251
			{
252
				var strategy = new SampleHistoryTesting.SmaStrategy
253
				{
254
					Volume = 1,
255
					Security = security,
256
					Portfolio = portfolio,
257
					//Connector = connector,
258

259
					// by default interval is 1 min,
260
					// it is excessively for time range with several months
261
					UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To<TimeSpan>(),
262
				};
263

264
				var go = (GeneticOptimizer)_optimizer;
265
				go.Settings.Apply((GeneticSettings)GeneticSettings.SelectedObject);
266
				go.Start(startTime, stopTime, strategy, new (IStrategyParam, object, object, object, object)[]
267
				{
268
					(strategy.Parameters.GetByName(nameof(strategy.ShortSma)), shortRange.min, shortRange.max, shortRange.step, null),
269
					(strategy.Parameters.GetByName(nameof(strategy.LongSma)), longRange.min, longRange.max, longRange.step, null),
270
					(strategy.Parameters.GetByName(nameof(strategy.CandleTimeFrame)), tfRange.min, tfRange.max, tfRange.step, null),
271
				});
272
			}
273
		}
274

275
		private void SetIsEnabled(bool canStart, bool canSuspend, bool canStop, bool canType)
276
		{
277
			this.GuiAsync(() =>
278
			{
279
				StopBtn.IsEnabled = canStop;
280
				StartBtn.IsEnabled = canStart;
281
				PauseBtn.IsEnabled = canSuspend;
282
				OptimizeTypeGrid.IsEnabled = canType;
283
			});
284
		}
285

286
		private void StopBtnClick(object sender, RoutedEventArgs e)
287
		{
288
			_optimizer.Stop();
289
		}
290

291
		private void PauseBtnClick(object sender, RoutedEventArgs e)
292
		{
293
			_optimizer.Suspend();
294
		}
295
	}
296
}
297

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

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

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

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