How to never miss out any cross

How to create strategies and indicators
Message
Author
forextester
Posts: 33
Joined: Thu Feb 19, 2009 8:40 am

How to never miss out any cross

#1 Postby forextester » Sun Mar 29, 2009 6:16 pm

Dear Mike, Gordon and Tantalus,

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.
Attachments
screen_00002.gif
screen_00002.gif (15.56 KiB) Viewed 8904 times
screen_00001.gif
screen_00001.gif (32.1 KiB) Viewed 8904 times

User avatar
Terranin
Site Admin
Posts: 833
Joined: Sat Oct 21, 2006 4:39 pm

#2 Postby Terranin » Tue Mar 31, 2009 11:46 am

It is enough to have this condition:

if (line1's_previous >= line2's_previous) and (line1's_current < line2's_current)
then a cross down

also you need to keep in mind that while bar is growing, this condition can become true, but after bar is closed it can inverse to false (depending on how it was growing). If you want to work only with closed bars then you need to:

1. find when bar was just closed
2. rewrite condition to:

Code: Select all

if (line1's_2 >= line2's_2) and (line1's_1 < line2's_1)
then a cross down


you are on 0 index now (have just 1 tick for a new bar) and should use index 1 and 2 to get indicator values from previous bars.

to find moment when previous bar is closed use this construction:

Code: Select all

var
  // global variable, should be set to 0 in ResetStrategy
  ptime: TDateTime;

if Time(0) <> ptime then
  begin
    ptime := Time(0);
    // here our condition met
    ...
  end;
Hasta la vista
Mike

forextester
Posts: 33
Joined: Thu Feb 19, 2009 8:40 am

crosses are still ignored

#3 Postby forextester » Tue Mar 31, 2009 2:24 pm

Dear Mike,

Thanks for the reply. I have done everything you asked, even waited till a candle close, but still i am getting erroneous behavior from Fxtester.

ie opens trade when no cross; doesn't open/close trade when there's a valid cross.

and the scary part is that these errors appear consistently. in fact quite often. I have more screen shots than i can post.

Please tell me what's wrong and what's the solution because crosses are very important to my back testing.

Thanks in advance.
regards,

Code: Select all

//-------------------------------------------------------------------------
// A strategy based on Macd crossover by Sheraz Afzal
//-------------------------------------------------------------------------
library Macd_strategy;

uses
  SysUtils, dateutils, 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: double; //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)   // and
//     ( Hourof(time(0)) > 5 ) and ( Hourof(time(0)) < 19 )
     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)    //and
//     ( Hourof(time(0)) > 5 ) and ( Hourof(time(0)) < 19 )
     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)//and
//     ( Hourof(time(0)) > 5 ) and ( Hourof(time(0)) < 19 )
     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) //and
//     ( Hourof(time(0)) > 5 ) and ( Hourof(time(0)) < 19 )
     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.
Attachments
screen_00006.jpg
screen_00006.jpg (74.78 KiB) Viewed 8891 times
screen_00005.jpg
screen_00005.jpg (79.52 KiB) Viewed 8891 times
screen_00003.jpg
screen_00003.jpg (71.59 KiB) Viewed 8891 times

User avatar
Terranin
Site Admin
Posts: 833
Joined: Sat Oct 21, 2006 4:39 pm

#4 Postby Terranin » Wed Apr 01, 2009 6:54 pm

You missed all that I said.

Code: Select all

// check our currency
  if Symbol <> string(Currency) then exit;

  // set currency and timeframe
  SetCurrencyAndTimeframe(Symbol, TimeFrame);

if Time(0) <> PrevTime then
  begin
    PrevTime := Time(0);
 
   // you should put all your code here!

  end;


and use not 0 and 1 bar indexes, but 1 and 2 instead.
Hasta la vista

Mike


Return to “FT API”

Who is online

Users browsing this forum: No registered users and 27 guests