Строим МТС-ку (сериализация, string, биржевой симулятор)
На прошлом уроке мы приняли решение, в каком направлении будем двигаться. Давайте посмотрим таблицу статистики для n=1 (максимальный профит и дродаун в течении одного месяца):
ProfitChange | DrawdownChange | SignalResult | SignalDate |
8,94% | 11,67% | Sell | 01.06.2002 |
9,68% | 2,06% | Buy | 01.10.2002 |
0,00% | 19,86% | Sell | 01.04.2003 |
28,79% | 2,77% | Buy | 01.05.2003 |
13,55% | 7,23% | Sell | 01.04.2004 |
8,93% | 7,54% | Buy | 01.09.2004 |
27,32% | 0,00% | Sell | 01.11.2004 |
0,00% | 16,56% | Buy | 01.02.2005 |
4,48% | 5,90% | Sell | 01.04.2005 |
14,83% | 0,29% | Buy | 01.06.2005 |
6,41% | 13,35% | Sell | 01.09.2006 |
4,24% | 3,46% | Buy | 01.10.2006 |
0,65% | 26,92% | Sell | 01.01.2008 |
6,32% | 7,60% | Buy | 01.02.2008 |
29,62% | 2,06% | Sell | 01.06.2008 |
39,62% | 3,66% | Buy | 01.03.2009 |
6,21% | 14,39% | Sell | 01.08.2009 |
Напоминаю, что средние значения ProfitChange и DrawdownChange у нас соответственно 12,33% и 8,55%. Давайте посчитаем, что будет, если мы выставим такие же стопы и профиты, а в случае, если не сработал ни один из них, то просто закрываемся через месяц. Но для этого нам надо будет разработать программу "Биржевой симулятор", при помощи которого будем тестировать идеи МТС-ок и оптимизировать их. В дальнейшем "Биржевой симулятор" ляжет в основу робота.
И так, начинаем писать симулятор. Сначала нам надо создать базовый класс, в котором мы предусмотрим возможность сериализации (нам потребуется сохранять результаты работы симулятора и настройки).
Базовый класс мы можем передать из библиотеки Easy Game Library и слегка модифицировать его. Вот текст модуля с базовым классом:
unit Base; interface uses Classes, SysUtils; type TESBBaseClass=class(TPersistent) protected FVersion:integer; FID:LongInt; function GetVersion:integer; virtual; public property ID:LongInt read FID; procedure Serialize(AStream:TStream); virtual; procedure Unserialize(AStream:TStream); virtual; end; implementation procedure SerializeString(AString:string; AStream:TStream); var l:integer; begin l:=Length(AString); AStream.Write(l,Sizeof(l)); if l>0 then AStream.WriteBuffer(AString[1],l); end; function UnserializeString(AStream:TStream):string; var l:integer; s:string; begin AStream.Read(l,Sizeof(l)); if l>0 then begin SetLength(s,L); AStream.ReadBuffer(s[1],L); end; Result:=s; end; // ********************************** TESBBaseClass ******************************* procedure TESBBaseClass.Serialize(AStream:TStream); var sign:string; version:integer; begin Sign:=ClassName; version:=GetVersion; SerializeString(sign, AStream); AStream.Write(version,sizeof(version)); AStream.Write(FID,sizeof(FID)); end; procedure TESBBaseClass.Unserialize(AStream:TStream); var sign:string; begin sign:=UnserializeString(AStream); if sign<>ClassName then Raise Exception.Create('TESBBaseClass.Unserialize: Неправильный формат файла (потока) класса '+ClassName); AStream.Read(FVersion,sizeof(FVersion)); AStream.Read(FID,sizeof(FID)); end; function TESBBaseClass.GetVersion:integer; begin Result:=1; end; end. |
Теперь немного комментариев к данному коду. Если уж мы сериализуем наши объекты, то обязательно делаем контроль версий. Вдруг в будущем что то изменим (добавим новые поля, которые тоже будем сериализовать), а нам надо что бы наша программа могла открывать файлы, сохраненные в предыдущей версии. Так же нам понадобятся функции для сериализации строк.
На этом пока все, в следующем уроке мы будем писать классы, необходимые для симулятора.