New Page 1
Продолжим писать класс статистического анализа индикатора
(repeat, until).
Все статьи по данной теме.
Сегодня мы продолжим писать класс для анализа индикатора
momentum, который начали на
прошлом уроке Мы уже
создали базовые классы. Теперь создадим основные, рабочие классы. Начнем с
TPASSStatAnalizMomentum:
TPASSStatAnalizMomentum=class(TPASSStatAnalizTemplate)
function FindSignal:boolean; override;
function FindSignalRotate:boolean; override;
procedure Test;
end; |
Как видим, в этом классе мы реализуем абстрактные методы FindSignal и
FindSignalRotate родительского класса:
function
TPASSStatAnalizMomentum.FindSignal:boolean;
var LastCandleIndex:integer; s:string;
begin
Result:=false;
LastCandleIndex:=1;
repeat
if
FIndicator.GetResultByFieldName('Value')=0
then LastCandleIndex:=2 else LastCandleIndex:=1;
if (FIndicator.GetResultByFieldName('Value')>=0)
and
(FIndicator.GetResultByFieldNameAndIndex('Value',FIndicator.PriceSource.CurrentItemIndex-LastCandleIndex)<0)
then
begin
FSignalType:=enBuy;
Result:=true;
exit;
end;
if (FIndicator.GetResultByFieldName('Value')<0)
and
(FIndicator.GetResultByFieldNameAndIndex('Value',FIndicator.PriceSource.CurrentItemIndex-LastCandleIndex)>=0)
then
begin
FSignalType:=enSell;
Result:=true;
exit;
end;
until not FIndicator.Next;
end;
function TPASSStatAnalizMomentum.FindSignalRotate:boolean;
var LastSignalType:TPASSSignalsTypes; toNext:boolean;
begin
LastSignalType:=FSignalType;
toNext:=true;
if not(FIndicator.PriceSource.NextItem) then
begin
Result:=false;
exit;
end;
repeat
if not FindSignal then
begin
Result:=false;
exit;
end;
if (LastSignalType=enBuy)
and (FSignalType=enSell) then
begin
Result:=true;
exit;
end;
if (LastSignalType=enSell)
and (FSignalType=enBuy) then
begin
Result:=true;
exit;
end;
until toNext;
Result:=false;
end; |
Сигнал ищется следующим образом:
Шаг 1. Проверяем условия сигнала на покупку
if (FIndicator.GetResultByFieldName('Value')>=0)
and
(FIndicator.GetResultByFieldNameAndIndex('Value',FIndicator.PriceSource.CurrentItemIndex-LastCandleIndex)<0)
then |
Если это условие выполняется, то считаем, что это сигнал на покупку и
завершаем подпрограмму:
FSignalType:=enBuy;
Result:=true;
exit; |
Шаг 2. Проверяем условия сигнала на продажу
if (FIndicator.GetResultByFieldName('Value')<0)
and
(FIndicator.GetResultByFieldNameAndIndex('Value',FIndicator.PriceSource.CurrentItemIndex-LastCandleIndex)>=0)
then |
Если это условие выполняется, то считеам, что это сигнал на продажу и выходим
из подпрограммы:
FSignalType:=enSell;
Result:=true;
exit; |
Шаг 3. Если у нас не последняя котировка, то переносим указатель на
следующую котировку и повторяем цикл, начина с шага 1 (выполняем еще раз то, что
находится между операторами repeat ... until
Как мы ищем обратный сигнал? Сперва запоминаем тип последнего сигнала и
проверяем, не последняя ли у нас котировка:
LastSignalType:=FSignalType;
toNext:=true;
if not(FIndicator.PriceSource.NextItem) then |
Затем в цикле ищем сигнал, не найдя которого решаем, что у нас нет обратного
сигнала:
repeat
if not FindSignal then
begin
Result:=false;
exit;
end; |
обратным считаем только тот сигнал, который обратный последнему (для покупки
- это продажа, для продажи - это покупка):
if (LastSignalType=enBuy) and (FSignalType=enSell) then
begin
Result:=true;
exit;
end;
if (LastSignalType=enSell)
and (FSignalType=enBuy) then
begin
Result:=true;
exit;
end; |
Ну, и наконец, цикл мы повторяем до тех пор, пока не просмотрели все
котировки до конца (либо пока не нашли сигнал):
в принципе, метод FindSignalRotate следовало бы объявить в классе
TPASSStatAnalizTemplate, потому что он будет одинаков, скорее всего, для всех
типов механических торговых систем. Но сейчас мы не будем ничего переписывать,
оптимизацией программы займемся, когда будем делать рефакторинг кода. А пока
будем продолжать писать классы, сейчас нам надо создать что то, что позволит
протестировать статистический анализатор котировок.
TPASSStatStoreDataList=class(TPASSStatStoreDataTemplate)
protected
FList:TStrings;
FCounter:integer;
public
constructor Create(AList:TStrings);
procedure AddData(AParameters:TPASSParameters);
override;
end; |
Как видим, данный класс очень простой. Он предназначен лишь для того, что бы
показать пользователю результаты первичного статистического анализа. Реализовов
его, мы сможем проверить, правильно ли у нас работает класс
TPASSStatAnalizMomentum:
constructor
TPASSStatStoreDataList.Create(AList:TStrings);
begin
inherited Create;
FList:=AList;
FCounter:=0;
end;
procedure TPASSStatStoreDataList.AddData(AParameters:TPASSParameters);
var s:string; i,cn:integer;
begin
s:='';
cn:=AParameters.Count-1;
for i:=0 to cn do s:=s+AParameters[i].Name+'='+AParameters.AsStringByNum(i)+';';
FList.Add(s);
FCounter:=FCounter+1;
end; |
Метод AddData класса TPASSStatStoreDataList простотупо и решительно все
параметры засовывает в строку и добавляет в список строк. Этого нам достаточно,
что бы отобразить результаты расчетов на экране. На следующем уроке мы этим и
займемся. А сейчас мы реализуем последний метод,
который еще не реализовали:
procedure
TPASSStatAnalizMomentum.Test;
begin
FIndicator.PriceSource.CurrentItemIndex:=FIndicator.GetParameterByName('DT')+3;
inherited Test;
end; |
|