Реклама

воскресенье, 14 ноября 2010 г.

Пишем робота Урок №14

Строим МТС-ку (сериализация, 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.
Теперь немного комментариев к данному коду. Если уж мы сериализуем наши объекты, то обязательно делаем контроль версий. Вдруг в будущем что то изменим (добавим новые поля, которые тоже будем сериализовать), а нам надо что бы наша программа могла открывать файлы, сохраненные в предыдущей версии. Так же нам понадобятся функции для сериализации строк.
На этом пока все, в следующем уроке мы будем писать классы, необходимые для симулятора.