Very Very Weird Problema -- Working Strategy Example

How to create strategies and indicators
Message
Author
charvo
Posts: 52
Joined: Tue Dec 04, 2012 1:15 pm

Very Very Weird Problema -- Working Strategy Example

#1 Postby charvo » Mon Jul 01, 2013 10:48 pm

Hi, Fellow Traders:

I met a very very weird problem

I coded a strategy that place long when month/day is bullish and W% in H1 oversold, and place short when month/day is bearish and W% in H1 overbought----very simple one.

The code is attached, and it is a working strategy with only 1 issue:

in the AddPosition() procedure, the SL and TP always return 0, though these two variables are external and specified. I don't understand why this happened, and I tried different ways (as you can see in the code) to define these two external var. the SL and TP value is printed correctly in GetSingleTick(), but is returning only 0 if referred from AddPosition().

shed me a light, comrades!

Thanks.

Code: Select all

library TriScreen;

uses
  Math,
  SysUtils,
  DateUtils,
  Graphics,
  Dialogs,
  Classes,
  StrategyInterfaceUnit,
  TechnicalFunctions;

var

// External parameters

Currency: PChar = nil;
Lot: double;
MagicNumber:   integer;
//SL:   integer;
//TP:   integer;

SL:     integer = 250;
TP:     integer = 350;

HiTF: integer;
MiTF: integer;
LoTF: integer;

MACDpara1: integer;
MACDpara2: integer;
MACDpara3: integer;

WPpara1: integer;

EntryInterval: integer;
PosCAP: integer;

// custom variables

OrderHandle1, OrderHandle2, MACDhandle, WPhandle: integer;
OrderStyle: TTradePositionType;

WeekTrend, DailyTrend, HourlyTrend: integer;
LongEntryValid, ShortEntryValid: boolean;

pairPoint:    double;

{-----Init strategy-----------------------------------------}

procedure InitStrategy; stdcall;

begin

StrategyShortName('Tri_Screen');
StrategyDescription('Tripple Screen');

// Register external parameters
RegOption('Currency', ot_Currency, Currency);

ReplaceStr(Currency, 'EURUSD');

RegOption('LotSize', ot_Double, Lot);
SetOptionDigits('LotSize', 1);
Lot := 0.1;

RegOption('stop loss', ot_Integer, SL);
RegOption('take profit', ot_Integer, TP);

//RegOption('stop loss', ot_Integer, SL);
//SetOptionRange('stop loss', 2, MaxInt);
//SL := 250;

//RegOption('take profit', ot_Integer, TP);
//SetOptionRange('take profit', 2, MaxInt);
//TP := 350;

RegOption('magic number', ot_Integer, MagicNumber);
SetOptionRange('magic number', 2, MaxInt);
MagicNumber := 301;

RegOption('Weekly', ot_Timeframe, HiTF);
HiTF := 10080;
RegOption('Daily', ot_Timeframe, MiTF);
MiTF := 1440;
RegOption('Hourly', ot_Timeframe, LoTF);
LoTF := 60;

RegOption('MACD parameter 1', ot_Integer, MACDpara1);
SetOptionRange('MACD parameter 1', 2, MaxInt);
MACDpara1 := 12;

RegOption('MACD parameter 2', ot_Integer, MACDpara2);
SetOptionRange('MACD parameter 2', 2, MaxInt);
MACDpara2 := 9;

RegOption('MACD parameter 3', ot_Integer, MACDpara3);
SetOptionRange('MACD parameter 3', 2, MaxInt);
MACDpara3 := 7;

RegOption('W% Parameter', ot_Integer, WPpara1);
SetOptionRange('W% parameter', 2, MaxInt);
WPpara1 := 14;

RegOption('Entry Interval', ot_Integer, EntryInterval);
SetOptionRange('Entry Interval', 2, MaxInt);
EntryInterval := 12;

RegOption('Position Limit', ot_Integer, PosCAP);
SetOptionRange('Position Limit', 2, MaxInt);
PosCAP := 5;

end;

{-----Done strategy---------------------------------------}
procedure DoneStrategy; stdcall;

begin
FreeMem(Currency);
end;

{-----Reset strategy--------------------------------------}
procedure ResetStrategy; stdcall;

begin
OrderHandle1 := -1;
MACDhandle := CreateIndicator(Currency, MiTF, 'MACD', '5;10;5;Close');
WPhandle   := CreateIndicator(Currency, LoTF, 'WPR', '14;Close');
end;

{-----Calculate 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 SetPoint(sym: string);

begin
    if (MarketInfo(sym, Mode_Bid) > 20)  then pairPoint := 0.01
    else                                      pairPoint := 0.0001;
end;

function ReadWeekly(sym: string): integer;

begin
  if (iOpen(sym, 43200, 1) < iClose(sym, 43200, 1)) then
  Result := 1;
  if (iOpen(sym, 43200, 1) > iClose(sym, 43200, 1)) then
  Result := -1;
  if (iOpen(sym, 43200, 1) = iClose(sym, 43200, 1)) then
  Result := 0;
end;

function ReadDaily(sym: string): integer;
var
  vMACD: double;
begin

  vMACD := GetIndicatorValue(MACDhandle, 1, 2);

  if (vMACD < 0) then Result := -1;
  if (vMACD > 0) then Result := 1;

end;

function ReadHourly(sym: string): integer;
var
  vWP: double;
begin

  vWP   := GetIndicatorValue(WPhandle, 1, 0);

  if (vWP >= -80) and (vWP <= -20) then Result := 0;
  if (vWP > -20) then Result := -1;
  if (vWP < -80) then Result := 1;
end;

// this function considers "time": in Delphi, Tdatetime is 'double',
// the most recent 'time' is largest, the integral is NO of days, the fractional part is fraction of 24 hour passed
// e.g.  if today's 8 am is 28943.3333333, then tomorrow's 8 pm is 28944.666666; so in my base below, i need two entries' Ddatetime has a difference more than 0.5, that is, 12 hours.
function EntryLimitsMet(dir: integer): boolean;
var
  n, NOofSells, NOofBuys:  integer;
  temp: boolean;
  LatestEntryTime: TDateTime;
begin

  NOofSells := 0;
  NOofBuys  := 0;

  //Print('Before Checking, n :{' + inttostr(n) + '}.');
  for n := 0 to OrdersTotal - 1 do
  begin
    OrderSelect(n, Select_By_Pos, mode_trades);
    if (OrderMagicNumber = MagicNumber) and (OrderLots = Lot) then
    begin
       if (dir = 1) and (OrderType = tp_Buy)  then
       begin
          NOofBuys  :=  NOofBuys  + 1;               //          Print('# of Buys :{' + IntToStr(NOofBuys) + '}.');
          if (LatestEntryTime < OrderOpenTime)  then LatestEntryTime := OrderOpenTime;
       end;
       if (dir = -1) and (OrderType = tp_Sell) then
       begin
          NOofSells :=  NOofSells + 1;
          if (LatestEntryTime < OrderOpenTime)  then LatestEntryTime := OrderOpenTime;
       end;
    end
  end;

  if (dir = 1) then  Print('Latest Entry @:{' + floattostr(LatestEntryTime) + '}, while NOW is:{' + floattostr(TimeCurrent) + '}, NO of Pos:{' + inttostr(NOofBuys) + '}.');
  if (dir = -1) then  Print('Latest Entry @:{' + floattostr(LatestEntryTime) + '}, while NOW is:{' + floattostr(TimeCurrent) + '}, NO of Pos:{' + inttostr(NOofSells) + '}.');

  temp  := false;
  if (dir = 1) and ( (TimeCurrent - LatestEntryTime < 0.5) or (NOofBuys >= PosCAP) )   then temp := true;
  if (dir = -1) and ( (TimeCurrent - LatestEntryTime < 0.5) or (NOofSells >= PosCAP) )  then temp := true;

  Result  := temp;
end;

procedure AddPosition(dir: integer);
var
  tp, sl: double;
begin

  if (dir = 1)  then
  begin

    Print('before, SL:{' + floatToStr(SL) + '}');
    sl := MarketInfo(Currency, MODE_ASK) - SL*pairPoint;
    Print('after, sl:{'+floattostr(sl)+'}');

    tp := MarketInfo(Currency, MODE_ASK) + TP*pairPoint;
    SendInstantOrder(Currency, OP_BUY,Lot, sl, tp, 'TriScreen',MagicNumber,OrderHandle1);
  end;

  if (dir = -1)  then
  begin
    sl := MarketInfo(Currency, MODE_BID) + SL * pairPoint;
    tp := MarketInfo(Currency, MODE_BID) - TP * pairPoint;
    SendInstantOrder(Currency, OP_SELL,Lot, sl, tp, 'TriScreen',MagicNumber,OrderHandle1);
  end;

end;

{-----Process single tick----------------------------------}

procedure GetSingleTick; stdcall;

begin

//Print(' @ begin,  SL:{' + floatToStr(SL) + '}'); //Print(' @ begin,  TP:{' + IntToStr(TP) + '}');

SetPoint(Currency);  //   menu, help, or regular way: SetCurrencyAndTimeframe(Currency, LoTF);    //any TF will do;

WeekTrend   := ReadWeekly(Currency);
DailyTrend  := ReadDaily(Currency);
HourlyTrend := ReadHourly(Currency);

//if (DailyTrend = 1) and (HourlyTrend = 1)     then  LongEntryValid := true;
if (WeekTrend = 1) and (DailyTrend = 1) and (HourlyTrend = 1)     then  LongEntryValid := true;
if (WeekTrend = -1) and (DailyTrend = -1) and (HourlyTrend = -1)  then  ShortEntryValid := true;
//if (DailyTrend = -1) and (HourlyTrend = -1)  then  ShortEntryValid := true;

if (LongEntryValid) and (not EntryLimitsMet(1))   then  AddPosition(1);
if (ShortEntryValid) and (not EntryLimitsMet(-1)) then  AddPosition(-1);

//reset! a MUST!
LongEntryValid  := false;
ShortEntryValid := false;



end;

exports
InitStrategy,
DoneStrategy,
ResetStrategy,
GetSingleTick;
end.

Phil_Trade
Posts: 94
Joined: Tue Jan 31, 2012 5:14 am
Contact:

Re: Very Very Weird Problema -- Working Strategy Example

#2 Postby Phil_Trade » Sat Jul 13, 2013 9:48 am

charvo wrote:Hi, Fellow Traders:

I met a very very weird problem

I coded a strategy that place long when month/day is bullish and W% in H1 oversold, and place short when month/day is bearish and W% in H1 overbought----very simple one.

The code is attached, and it is a working strategy with only 1 issue:

in the AddPosition() procedure, the SL and TP always return 0, though these two variables are external and specified. I don't understand why this happened, and I tried different ways (as you can see in the code) to define these two external var. the SL and TP value is printed correctly in GetSingleTick(), but is returning only 0 if referred from AddPosition().

shed me a light, comrades!

Thanks.

Code: Select all

library TriScreen;

uses
  Math,
  SysUtils,
  DateUtils,
  Graphics,
  Dialogs,
  Classes,
  StrategyInterfaceUnit,
  TechnicalFunctions;

var

// External parameters

Currency: PChar = nil;
Lot: double;
MagicNumber:   integer;
//SL:   integer;
//TP:   integer;

SL:     integer = 250;
TP:     integer = 350;

HiTF: integer;
MiTF: integer;
LoTF: integer;

MACDpara1: integer;
MACDpara2: integer;
MACDpara3: integer;

WPpara1: integer;

EntryInterval: integer;
PosCAP: integer;

// custom variables

OrderHandle1, OrderHandle2, MACDhandle, WPhandle: integer;
OrderStyle: TTradePositionType;

WeekTrend, DailyTrend, HourlyTrend: integer;
LongEntryValid, ShortEntryValid: boolean;

pairPoint:    double;

{-----Init strategy-----------------------------------------}

procedure InitStrategy; stdcall;

begin

StrategyShortName('Tri_Screen');
StrategyDescription('Tripple Screen');

// Register external parameters
RegOption('Currency', ot_Currency, Currency);

ReplaceStr(Currency, 'EURUSD');

RegOption('LotSize', ot_Double, Lot);
SetOptionDigits('LotSize', 1);
Lot := 0.1;

RegOption('stop loss', ot_Integer, SL);
RegOption('take profit', ot_Integer, TP);

//RegOption('stop loss', ot_Integer, SL);
//SetOptionRange('stop loss', 2, MaxInt);
//SL := 250;

//RegOption('take profit', ot_Integer, TP);
//SetOptionRange('take profit', 2, MaxInt);
//TP := 350;

RegOption('magic number', ot_Integer, MagicNumber);
SetOptionRange('magic number', 2, MaxInt);
MagicNumber := 301;

RegOption('Weekly', ot_Timeframe, HiTF);
HiTF := 10080;
RegOption('Daily', ot_Timeframe, MiTF);
MiTF := 1440;
RegOption('Hourly', ot_Timeframe, LoTF);
LoTF := 60;

RegOption('MACD parameter 1', ot_Integer, MACDpara1);
SetOptionRange('MACD parameter 1', 2, MaxInt);
MACDpara1 := 12;

RegOption('MACD parameter 2', ot_Integer, MACDpara2);
SetOptionRange('MACD parameter 2', 2, MaxInt);
MACDpara2 := 9;

RegOption('MACD parameter 3', ot_Integer, MACDpara3);
SetOptionRange('MACD parameter 3', 2, MaxInt);
MACDpara3 := 7;

RegOption('W% Parameter', ot_Integer, WPpara1);
SetOptionRange('W% parameter', 2, MaxInt);
WPpara1 := 14;

RegOption('Entry Interval', ot_Integer, EntryInterval);
SetOptionRange('Entry Interval', 2, MaxInt);
EntryInterval := 12;

RegOption('Position Limit', ot_Integer, PosCAP);
SetOptionRange('Position Limit', 2, MaxInt);
PosCAP := 5;

end;

{-----Done strategy---------------------------------------}
procedure DoneStrategy; stdcall;

begin
FreeMem(Currency);
end;

{-----Reset strategy--------------------------------------}
procedure ResetStrategy; stdcall;

begin
OrderHandle1 := -1;
MACDhandle := CreateIndicator(Currency, MiTF, 'MACD', '5;10;5;Close');
WPhandle   := CreateIndicator(Currency, LoTF, 'WPR', '14;Close');
end;

{-----Calculate 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 SetPoint(sym: string);

begin
    if (MarketInfo(sym, Mode_Bid) > 20)  then pairPoint := 0.01
    else                                      pairPoint := 0.0001;
end;

function ReadWeekly(sym: string): integer;

begin
  if (iOpen(sym, 43200, 1) < iClose(sym, 43200, 1)) then
  Result := 1;
  if (iOpen(sym, 43200, 1) > iClose(sym, 43200, 1)) then
  Result := -1;
  if (iOpen(sym, 43200, 1) = iClose(sym, 43200, 1)) then
  Result := 0;
end;

function ReadDaily(sym: string): integer;
var
  vMACD: double;
begin

  vMACD := GetIndicatorValue(MACDhandle, 1, 2);

  if (vMACD < 0) then Result := -1;
  if (vMACD > 0) then Result := 1;

end;

function ReadHourly(sym: string): integer;
var
  vWP: double;
begin

  vWP   := GetIndicatorValue(WPhandle, 1, 0);

  if (vWP >= -80) and (vWP <= -20) then Result := 0;
  if (vWP > -20) then Result := -1;
  if (vWP < -80) then Result := 1;
end;

// this function considers "time": in Delphi, Tdatetime is 'double',
// the most recent 'time' is largest, the integral is NO of days, the fractional part is fraction of 24 hour passed
// e.g.  if today's 8 am is 28943.3333333, then tomorrow's 8 pm is 28944.666666; so in my base below, i need two entries' Ddatetime has a difference more than 0.5, that is, 12 hours.
function EntryLimitsMet(dir: integer): boolean;
var
  n, NOofSells, NOofBuys:  integer;
  temp: boolean;
  LatestEntryTime: TDateTime;
begin

  NOofSells := 0;
  NOofBuys  := 0;

  //Print('Before Checking, n :{' + inttostr(n) + '}.');
  for n := 0 to OrdersTotal - 1 do
  begin
    OrderSelect(n, Select_By_Pos, mode_trades);
    if (OrderMagicNumber = MagicNumber) and (OrderLots = Lot) then
    begin
       if (dir = 1) and (OrderType = tp_Buy)  then
       begin
          NOofBuys  :=  NOofBuys  + 1;               //          Print('# of Buys :{' + IntToStr(NOofBuys) + '}.');
          if (LatestEntryTime < OrderOpenTime)  then LatestEntryTime := OrderOpenTime;
       end;
       if (dir = -1) and (OrderType = tp_Sell) then
       begin
          NOofSells :=  NOofSells + 1;
          if (LatestEntryTime < OrderOpenTime)  then LatestEntryTime := OrderOpenTime;
       end;
    end
  end;

  if (dir = 1) then  Print('Latest Entry @:{' + floattostr(LatestEntryTime) + '}, while NOW is:{' + floattostr(TimeCurrent) + '}, NO of Pos:{' + inttostr(NOofBuys) + '}.');
  if (dir = -1) then  Print('Latest Entry @:{' + floattostr(LatestEntryTime) + '}, while NOW is:{' + floattostr(TimeCurrent) + '}, NO of Pos:{' + inttostr(NOofSells) + '}.');

  temp  := false;
  if (dir = 1) and ( (TimeCurrent - LatestEntryTime < 0.5) or (NOofBuys >= PosCAP) )   then temp := true;
  if (dir = -1) and ( (TimeCurrent - LatestEntryTime < 0.5) or (NOofSells >= PosCAP) )  then temp := true;

  Result  := temp;
end;

procedure AddPosition(dir: integer);
var
  tp, sl: double;
begin

  if (dir = 1)  then
  begin

    Print('before, SL:{' + floatToStr(SL) + '}');
    sl := MarketInfo(Currency, MODE_ASK) - SL*pairPoint;
    Print('after, sl:{'+floattostr(sl)+'}');

    tp := MarketInfo(Currency, MODE_ASK) + TP*pairPoint;
    SendInstantOrder(Currency, OP_BUY,Lot, sl, tp, 'TriScreen',MagicNumber,OrderHandle1);
  end;

  if (dir = -1)  then
  begin
    sl := MarketInfo(Currency, MODE_BID) + SL * pairPoint;
    tp := MarketInfo(Currency, MODE_BID) - TP * pairPoint;
    SendInstantOrder(Currency, OP_SELL,Lot, sl, tp, 'TriScreen',MagicNumber,OrderHandle1);
  end;

end;

{-----Process single tick----------------------------------}

procedure GetSingleTick; stdcall;

begin

//Print(' @ begin,  SL:{' + floatToStr(SL) + '}'); //Print(' @ begin,  TP:{' + IntToStr(TP) + '}');

SetPoint(Currency);  //   menu, help, or regular way: SetCurrencyAndTimeframe(Currency, LoTF);    //any TF will do;

WeekTrend   := ReadWeekly(Currency);
DailyTrend  := ReadDaily(Currency);
HourlyTrend := ReadHourly(Currency);

//if (DailyTrend = 1) and (HourlyTrend = 1)     then  LongEntryValid := true;
if (WeekTrend = 1) and (DailyTrend = 1) and (HourlyTrend = 1)     then  LongEntryValid := true;
if (WeekTrend = -1) and (DailyTrend = -1) and (HourlyTrend = -1)  then  ShortEntryValid := true;
//if (DailyTrend = -1) and (HourlyTrend = -1)  then  ShortEntryValid := true;

if (LongEntryValid) and (not EntryLimitsMet(1))   then  AddPosition(1);
if (ShortEntryValid) and (not EntryLimitsMet(-1)) then  AddPosition(-1);

//reset! a MUST!
LongEntryValid  := false;
ShortEntryValid := false;



end;

exports
InitStrategy,
DoneStrategy,
ResetStrategy,
GetSingleTick;
end.


Hi

you define SL and TP in Global mode, but also SL, TP in local mode in your Addposition() procedure. So you never modify global variables but local one.

Code: Select all

procedure AddPosition(dir: integer);
var
  tp, sl: double;
begin


these are local variable. you have to delete this line so your procedure will update the global variables[/code]
my live account - 8 based pairs with optimized parameters : +188%
http://www.myfxbook.com/members/Philipp ... jpg/519044
TradeSlide : http://bit.ly/14R9Nf6

to be informed about Windev/MT4 services : a04486-tradingsignal@yahoo.fr

charvo
Posts: 52
Joined: Tue Dec 04, 2012 1:15 pm

Re: Very Very Weird Problema -- Working Strategy Example

#3 Postby charvo » Thu Jul 18, 2013 11:46 am

thanks a lot! Phil. I didn't realise that delphi doesn't care upper/lower cases.

btw, congradulations to your recent success on your live account!

Phil_Trade wrote:

Code: Select all

procedure AddPosition(dir: integer);
var
  tp, sl: double;
begin


these are local variable. you have to delete this line so your procedure will update the global variables[/code]

Phil_Trade
Posts: 94
Joined: Tue Jan 31, 2012 5:14 am
Contact:

Re: Very Very Weird Problema -- Working Strategy Example

#4 Postby Phil_Trade » Thu Jul 18, 2013 11:53 am

charvo wrote:thanks a lot! Phil. I didn't realise that delphi doesn't care upper/lower cases.

btw, congradulations to your recent success on your live account!

Phil_Trade wrote:

Code: Select all

procedure AddPosition(dir: integer);
var
  tp, sl: double;
begin


these are local variable. you have to delete this line so your procedure will update the global variables[/code]


you're welcome :P
my live account - 8 based pairs with optimized parameters : +188%

http://www.myfxbook.com/members/Philipp ... jpg/519044

TradeSlide : http://bit.ly/14R9Nf6



to be informed about Windev/MT4 services : a04486-tradingsignal@yahoo.fr


Return to “FT API”

Who is online

Users browsing this forum: No registered users and 30 guests