hope you're in best of everything.
My Macd crossover strategy works ok. The flaw is that it sometimes falsely executes a trade when there is no cross, or does not close/initiate a trade when there is a valid/clear cross.
I have tried comparing up to 3 different values of the crossing lines. screen shots are attached.
Code: Select all
ie
if line1's_previous_previous > line2's_previous_previous and
line1's_previous >= line2's_previous and
line1's_current < line2's_current
then a cross down
but still no use. With this flaw i can't even begin my back testing.
So any help form anyone will be greatly appreciated. You will find the code below.
regards,
Sheraz
Code: Select all
//-------------------------------------------------------------------------
// A strategy based on Macd crossover by Sheraz Afzal
//-------------------------------------------------------------------------
library Macd_strategy;
uses
SysUtils, Classes, StrategyInterfaceUnit;
var
// External parameters
Currency: PChar = nil;
TimeFrame: integer;
LotSize: double;
period1: integer;
period2: integer;
period3: integer;
ApplyToPricetemp: integer;
ApplyToPrice: string;
StopLoss: integer = 20;
Days: longword = 7;
UseStopLoss: boolean = true;
// custom variables
OrderHandle: integer;
handle: integer;
OrderStyle: TTradePositionType;
OpenTime: TDateTime;
PrevTime: TDateTime;
{-----Init strategy---------------------------------------------------------}
procedure InitStrategy; stdcall;
begin
StrategyShortName('Macd_strategy');
StrategyDescription('Orders based on Macd crossovers');
// Register external parameters
RegOption('Currency', ot_Currency, Currency);
ReplaceStr(Currency, 'GBPUSD');
RegOption('Timeframe', ot_Timeframe, TimeFrame);
TimeFrame := PERIOD_H1;
RegOption('LotSize', ot_Double, LotSize);
SetOptionDigits('LotSize', 1);
lotSize := 0.1;
RegOption('Fast EMA period', ot_Integer, period1);
SetOptionRange('Fast EMA period', 2, MaxInt);
period1 := 12;
RegOption('Slow EMA period', ot_Integer, period2);
SetOptionRange('Slow EMA period', 2, MaxInt);
period2 := 26;
RegOption('SMA period', ot_Integer, period3);
SetOptionRange('SMA period', 2, MaxInt);
period3 := 9;
RegOption('Apply to price', ot_EnumType, ApplyToPricetemp);
AddOptionValue('Apply to price', 'Close');
AddOptionValue('Apply to price', 'Open');
AddOptionValue('Apply to price', 'High');
AddOptionValue('Apply to price', 'Low');
AddOptionValue('Apply to price', '(High + Low)/2');
AddOptionValue('Apply to price', '(High + Low + Close)/3');
AddOptionValue('Apply to price', '(High + Low + Close + Close)/4');
ApplyToPricetemp := 0;
RegOption('StopLoss', ot_Integer, StopLoss);
RegOption('Days', ot_Longword, Days);
RegOption('UseStopLoss', ot_Boolean, UseStopLoss);
end;
{-----Done strategy---------------------------------------------------------}
procedure DoneStrategy; stdcall;
begin
FreeMem(Currency);
end;
{-----Reset strategy--------------------------------------------------------}
procedure ResetStrategy; stdcall;
begin
case ApplyToPricetemp of
0: ApplyToPrice := 'Close';
1: ApplyToPrice := 'Open';
2: ApplyToPrice := 'High';
3: ApplyToPrice := 'Low';
4: ApplyToPrice := '(High + Low)/2';
5: ApplyToPrice := '(High + Low + Close)/3';
6: ApplyToPrice := '(High + Low + Close + Close)/4';
end;
// handle := CreateIndicator('GBPUSD', PERIOD_M15, 'MACDnew', '12;26;9;Close');
// handle := CreateIndicator(symbol(), TimeFrame, 'MACDnew', inttostr(period1) + ';' + inttostr(period2) + ';' + inttostr(period3) + ';' +ApplyToPrice);
handle := CreateIndicator(Currency, TimeFrame, 'MACDnew', inttostr(period1) + ';' + inttostr(period2) + ';' + inttostr(period3) + ';' +ApplyToPrice);
OrderHandle := -1;
PrevTime:= 0;
end;
{-----Process single tick---------------------------------------------------}
procedure GetSingleTick; stdcall;
var
//to get Macd values
macd_line_current, macd_line_previous, macd_line_previous_previous,
signal_line_current, signal_line_previous, signal_line_previous_previous,
histogram_current, histogram_previous, histogram_previous_previous: double;
begin
// check our currency
if Symbol <> string(Currency) then exit;
// set currency and timeframe
SetCurrencyAndTimeframe(Symbol, TimeFrame);
//wait for a new candle
{
if Time(0) <> PrevTime then
begin
PrevTime := Time(0);
// here it is new bar appears
end
else
exit;
}
// check number of bars and SMA period
if (Bars < period1) or (Bars < period2) or (Bars < period3) then exit;
// get Macdnew values
// v1 := GetIndicatorValue(handle, 1, 0); // fast ema (not visible)
// v2 := GetIndicatorValue(handle, 1, 1); // slow ema (not visible)
macd_line_current := GetIndicatorValue(handle, 0, 2); // macd line (blue)
macd_line_previous := GetIndicatorValue(handle, 1, 2); // macd line (blue)
macd_line_previous_previous := GetIndicatorValue(handle, 2, 2); // macd line (blue)
signal_line_current := GetIndicatorValue(handle, 0, 3); // sma signal (red)
signal_line_previous := GetIndicatorValue(handle, 1, 3); // sma signal (red)
signal_line_previous_previous := GetIndicatorValue(handle, 2, 3); // sma signal (red)
histogram_current := GetIndicatorValue(handle, 0, 4); // histogram buffer
histogram_previous := GetIndicatorValue(handle, 1, 4); // histogram buffer
histogram_previous_previous := GetIndicatorValue(handle, 2, 4); // histogram buffer
// if BUY order exists and macd crosses signal from top
// then close order
if (OrderHandle <> -1) and (OrderStyle = tp_Buy) and
(OpenTime <> Time(0)) and
(macd_line_previous_previous > signal_line_previous_previous) and
(macd_line_previous >= signal_line_previous) and
(macd_line_current < signal_line_current) then
begin
CloseOrder(OrderHandle);
OrderHandle := -1;
end;
// if SELL order exists and macd crosses signal from bottom
// then close order
if (OrderHandle <> -1) and (OrderStyle = tp_Sell) and
(OpenTime <> Time(0)) and
(macd_line_previous_previous < signal_line_previous_previous) and
(macd_line_previous <= signal_line_previous) and
(macd_line_current > signal_line_current) then
begin
CloseOrder(OrderHandle);
OrderHandle := -1;
end;
// if there is no order and macd crosses signal from top
// then open SELL order
if (OrderHandle = -1) and
(macd_line_previous_previous > signal_line_previous_previous) and
(macd_line_previous >= signal_line_previous) and
(macd_line_current < signal_line_current) then
begin
SendInstantOrder(Symbol, op_Sell, LotSize, 0, 0, '', 0, OrderHandle);
OrderStyle := tp_Sell;
OpenTime := Time(0);
end;
// if there is no order and macd crosses signal from bottom
// then open BUY order
if (OrderHandle = -1) and
(macd_line_previous_previous < signal_line_previous_previous) and
(macd_line_previous <= signal_line_previous) and
(macd_line_current > signal_line_current) then
begin
SendInstantOrder(Symbol, op_Buy, LotSize, 0, 0, '', 0, OrderHandle);
OrderStyle := tp_Buy;
OpenTime := Time(0);
end;
end;
exports
InitStrategy,
DoneStrategy,
ResetStrategy,
GetSingleTick;
end.