Код: Выделить всё
//-------------------------------------------------------------------------
// Example of strategy based on 2 crossing SMA (c) Koshelev M.A.
// Поправлено Евгением ;)
//-------------------------------------------------------------------------
library SMAStrategy;
uses
SysUtils, Classes, StrategyInterfaceUnit;
var
// Внешние параметры
Currency: PChar = nil;
TimeFrame: integer;
LotSize: double;
StopLoss: double;
TakeProfit: double;
period1: integer;
period2: integer;
LossSize: integer;
ProfitSize: integer;
// Внутренние переменные
OrderHandle: integer;
OrderStyle: TTradePositionType;
OpenTime: TDateTime;
//--------------------------------------
// инициализация
//--------------------------------------
procedure InitStrategy; stdcall;
begin
StrategyShortName('SimpleSMA');
StrategyDescription('Стратегия по пересечению 2х SMA');
// регистрация внешних параметров
RegOption('Currency', ot_Currency, Currency);
ReplaceStr(Currency, 'EURUSD');
RegOption('Timeframe', ot_Timeframe, TimeFrame);
TimeFrame := PERIOD_H1;
RegOption('LotSize', ot_Double, LotSize);
SetOptionDigits('LotSize', 1);
lotSize := 0.1;
RegOption('SMA1 period', ot_Integer, period1);
SetOptionRange('SMA1 period', 2, MaxInt);
period1 := 16;
RegOption('SMA2 period', ot_Integer, period2);
SetOptionRange('SMA2 period', 2, MaxInt);
period2 := 32;
RegOption('StopLoss', ot_Integer, LossSize);
SetOptionRange('StopLoss', 0, MaxInt);
LossSize := 30;
RegOption('TakeProfit', ot_Integer, ProfitSize);
SetOptionRange('TakeProfit', 0, MaxInt);
ProfitSize := 50;
end;
//--------------------------------------
// деинициализация
//--------------------------------------
procedure DoneStrategy; stdcall;
begin
FreeMem(Currency); // освободить строку PChar
end;
//--------------------------------------
// сбросить временные параметры
//--------------------------------------
procedure ResetStrategy; stdcall;
begin
OrderHandle := -1;
end;
// рассчет SMA
function GetSMA(period: integer): double;
var
i: integer;
sum: double;
begin
sum := 0;
for i:=0 to period - 1 do
sum := sum + Close(i);
result := sum/period;
end;
//---------------------------------------
// Обработать тик
//---------------------------------------
procedure GetSingleTick; stdcall;
var
sma1, sma2: double;
begin
// проверка валюты
if Symbol <> string(Currency) then exit;
// установить валюту и таймфрейм
SetCurrencyAndTimeframe(Symbol, TimeFrame);
// проверка числа баров
if (Bars < period1) or (Bars < period2) then exit;
// рассчет SMA
sma1 := GetSMA(period1);
sma2 := GetSMA(period2);
// если ордер открыт на покупку и быстрая sma1 пересекает sma2
// сверху вниз и прошли как минимум 1 бар то закрыть ордер
if (OrderHandle <> -1) and (OrderStyle = tp_Buy) and
(OpenTime <> Time(0)) and (sma1 < sma2) then
begin
CloseOrder(OrderHandle);
OrderHandle := -1;
end;
// если ордер открыт на продажу и быстрая sma1 пересекает sma2
// снизу вверх и прошли как минимум 1 бар то закрыть ордер
if (OrderHandle <> -1) and (OrderStyle = tp_Sell) and
(OpenTime <> Time(0)) and (sma1 > sma2) then
begin
CloseOrder(OrderHandle);
OrderHandle := -1;
end;
// если нет ордеров и быстрая sma1 пересекает sma2
// сверху вниз то открыть ордер на продажу
if (OrderHandle = -1) and (sma1 < sma2) then
begin
StopLoss := Bid + LossSize*Point;
TakeProfit := Bid - ProfitSize*Point;
SendInstantOrder(Symbol, op_Sell, LotSize, StopLoss, TakeProfit, OrderHandle);
OrderStyle := tp_Sell;
OpenTime := Time(0);
end;
// если нет ордеров и быстрая sma1 пересекает sma2
// снизу вверх то открыть ордер на покупку
if (OrderHandle = -1) and (sma1 > sma2) then
begin
StopLoss := Ask - LossSize*Point;
TakeProfit := Ask + ProfitSize*Point;
SendInstantOrder(Symbol, op_Buy, LotSize, StopLoss, TakeProfit, OrderHandle);
OrderStyle := tp_Buy;
OpenTime := Time(0);
end;
end;
exports
InitStrategy, DoneStrategy, ResetStrategy, GetSingleTick;
end.