New Page 1
Биржевой симулятор: класс TESBInstrument -
симуляция покупки (продажи) акций.
Все статьи по данной теме.
Исходники к уроку можно скачать
здесь.
И так, продолжим писать биржевой симулятор. Сегодня мы
реализуем новый класс: TESBInstrument, при помощи которого будем имитировать
покупку и продажу акций. Пока, конечно, это будет тоже нечто вроде заготовки,
как и в случае с TESBAccount, но в дальнейшем мы соединим эти классы и расширим
функционал.
И так, объявление нового класса:
//класс симуляции
остатка по биржевому инструменту
TESBInstrument=class(TESBBaseClass)
protected
FPriceSource:TPASSPriceSource;
FCount:integer;
FName:string;
FCurrentCandle:LongInt;
FCanShort:boolean;
procedure SetPriceSource(APriceSource:TPASSPriceSource);
public
property PriceSource:TPASSPriceSource read
FPriceSource write SetPriceSource;
property Count:integer read FCount;
// количество акций
property Name:string read FName
write FName;
property CanShort:boolean read FCanShort
write FCanShort; //можно ли шортит
constructor Create;
function CurrentPrice:double;
//текущая цена по курсу открытия
procedure Buy(ACount:integer);
//купить
procedure Sell(ACount:integer);
//продать
procedure Serialize(AStream:TStream);
override;
procedure Unserialize(AStream:TStream);
override;
function Next:boolean;
end; |
Так как у нас используется класс TPASSPriceSource, то нам понадобится
библиотека PASSBaseObj, ее можно скачать вот
здесь Естественно, ее надо будет подключить к проекту, как вы уже научились
на
предыдущем уроке. Так же в
модуле Base нужно добавить эту библиотеку в раздел
uses*:
А теперь приступим к реализации класса:
// **************
TESBInstrument *****************
constructor TESBInstrument.Create;
begin
inherited Create;
FCanShort:=true;
FCount:=0;
FCurrentCandle:=0;
FPriceSource:=nil;
end;
function TESBInstrument.CurrentPrice:double;
begin
if FPriceSource<>nil then
begin
if FPriceSource.CurrentItemIndex<>FCurrentCandle
then FPriceSource.CurrentItemIndex:=FCurrentCandle;
Result:=FPriceSource.GetBarData.Open;
end else raise Exception.Create('TESBInstrument.CurrentPrice
-нет источника котировок');
end;
procedure TESBInstrument.Buy(ACount:integer);
begin
FCount:=FCount+ACount;
end;
procedure TESBInstrument.Sell(ACount:integer);
begin
if (ACount>FCount) and not(FCanShort)
then raise Exception.Create('TESBInstrument.Sell -
превышен лимит по инструменту');
FCount:=FCount-ACount;
end;
procedure TESBInstrument.Serialize(AStream:TStream);
begin
inherited Serialize(AStream);
AStream.Write(FCanShort,sizeof(FCanShort));
AStream.Write(FCount,sizeof(FCount));
AStream.Write(FCurrentCandle,sizeof(FCurrentCandle));
SerializeString(FName,AStream);
end;
procedure TESBInstrument.Unserialize(AStream:TStream);
begin
inherited Unserialize(AStream);
AStream.Read(FCanShort,sizeof(FCanShort));
AStream.Read(FCount,sizeof(FCount));
AStream.Read(FCurrentCandle,sizeof(FCurrentCandle));
FName:=UnserializeString(AStream);
end;
procedure TESBInstrument.SetPriceSource(APriceSource:TPASSPriceSource);
begin
FPriceSource:=APriceSource;
FCurrentCandle:=APriceSource.CurrentItemIndex;
end;
function TESBInstrument.Next:boolean;
begin
Result:=FPriceSource.NextItem;
FCurrentCandle:=FCurrentCandle+1;
end; |
И немного комментариев к коду. В прошлый раз, когда мы
проектировали класс TESBAccount, свойство Cash (наличные),
мы сделали только для чтения, предполагая, что его можно менять только методами.
Аналогично сделаем и свойство Count, метод
Buy увеличивает его, а Sell -уменьшает.
Если по данной акции допустимы шорты CanShort то мы можем уменьшить
Count в минус, иначе у нас при попытке продать больше
чем есть будет вызвано исключение. Ну, и конечно же, для того, что бы знать цену
акции, нам понадобиться источник котировок TPASSPriceSource. Данный класс
(TPASSPriceSource) позволяет загрузить котировки из текстового файла в формате,
скаченного с Финама,
а так же получить котировки на заданную свечу.
Теперь немного изменяем форму тестового примера, созданного
на
прошлом уроке*:
Вносим некоторые изменения в объявление класса TfrmStockBot*:
а затем переписываем обработчики событий:
procedure TfrmStockBot.FormCreate(Sender:
TObject);
begin
Instrument:=TESBInstrument.Create;
Instrument.CanShort:=false;
PriceSource:=nil;
end;
procedure TfrmStockBot.FormDestroy(Sender: TObject);
begin
FreeAndNil(Instrument);
if PriceSource<>nil then FreeAndNil(PriceSource);
end;
procedure TfrmStockBot.ShowCount;
begin
mmAccount.Lines.Add(FloatToStr(Instrument.Count));
end;
procedure TfrmStockBot.btnBuyClick(Sender: TObject);
begin
Instrument.Buy(StrToInt(edCount.Text));
ShowCount;
end;
procedure TfrmStockBot.btnSellClick(Sender: TObject);
begin
Instrument.Sell(StrToInt(edCount.Text));
ShowCount;
end;
procedure TfrmStockBot.itSaveClick(Sender: TObject);
var Stream:TFileStream;
begin
if SaveDialog.Execute then
begin
Stream:=TFileStream.Create(SaveDialog.FileName,fmCreate);
Instrument.Serialize(Stream);
FreeAndNil(Stream);
end;
end;
procedure TfrmStockBot.itOpenClick(Sender: TObject);
var Stream:TFileStream;
begin
if OpenDialog.Execute then
begin
Stream:=TFileStream.Create(OpenDialog.FileName,fmOpenRead);
FreeAndNil(Instrument);
Instrument:=TESBInstrument.Create;
Instrument.PriceSource:=PriceSource;
Instrument.Unserialize(Stream);
FreeAndNil(Stream);
mmAccount.Lines.Clear;
ShowCount;
lbPrice.Caption:=FloatToStr(Instrument.CurrentPrice);
end;
end;
procedure TfrmStockBot.itOpenPricesClick(Sender: TObject);
begin
if OpenDialogPrices.Execute then
begin
if PriceSource<>nil
then FreeAndNil(PriceSource);
PriceSource:=TPASSPriceSource.Create('',false);
PriceSource.LoadDataFromTextFile(OpenDialogPrices.FileName);
PriceSource.First;
Instrument.PriceSource:=PriceSource;
lbPrice.Caption:=FloatToStr(Instrument.CurrentPrice);
end;
end;
procedure TfrmStockBot.btnNextClick(Sender: TObject);
begin
Instrument.Next;
lbPrice.Caption:=FloatToStr(Instrument.CurrentPrice);
end; |
Также готовый тестовый пример можно
скачать здесь.
Затем запускаем программу, закачиваем котировки и приступаем
к тестированию:
Скриншоты, помеченные знаком * ,
являются цитатами и иллюстрациями программного
продукта "Delphi", авторское право на
который принадлежит "Borland Software Corporation, (a
Micro Focus Company).
|