Page 1 of 1

Lesson 2 - defining external parameters

Posted: Fri Jul 11, 2008 11:32 am
by Terranin
In this lesson we will talk about external parameters of our strategy. User needs to change parameters of strategy, for example on which currency this strategy should work, or what stop loss it should use for orders and so on.

There are 8 types of parameters you can use:

ot_Longword - unsigned integer, 0..4294967295
ot_Integer - signed integer, -2147483648..2147483647
ot_Double - double, 5.0 x 10^-324 .. 1.7 x 10^308
ot_String - text string
ot_Boolean - true/false
ot_EnumType - you can define list of strings for this parameter, internal value will be position in this list 0...N-1
ot_Timeframe - this parameter represents available timeframes PERIOD_M1..PERIOD_W1
ot_Currency - this parameter contains currency name and will allow you to choose currency from currency list in dialog

You should define parameters in InitStrategy procedure. There are 5 procedures that you can use to do this:

RegOption - this procedure creates new parameter.

AddSeparator - just adds horizontal separator to parameters' dialog to separate one group of parameters from another.

AddOptionValue - this procedure adds new string value to parameter of type ot_EnumType to create drop down list of strings.

SetOptionRange - if you want to check user input for correct values you can set range of values for a parameter. Only for longword, integer and double parameters.

SetOptionDigits - defines how many digits after point you will see in dialog. Only for double parameter.

Let's add parameter to our strategy from lesson 1. First of all we need to define variable where this parameter will be stored:

Code: Select all

// external parameters
var
  Delta: double = 3.46;


This parameter will be initialized with value of 3.46 on the first start, after that this value will be stored in ini file for this strategy automatically.

And some extra strings in InitStrategy procedure:

Code: Select all

RegOption('Delta', ot_Double, Delta);
  SetOptionRange('Delta', 0, 100);
  SetOptionDigits('Delta', 2);


Simple, isn't it? With RegOption we created new parameter 'Delta' of type ot_Double and linked it with variable Delta.
With SetOptionRange we defined that this parameter can vary from 0 to 100.
With SetOptionDigits we said that we want to see only 2 digits after point in parameters dialog.

Our strategy code will looks like:

Code: Select all

library DemoStrategy;

uses
  SysUtils, StrategyInterfaceUnit, TechnicalFunctions;

// external parameters
var
  Delta: double = 3.46;

procedure InitStrategy; stdcall;
begin
  StrategyShortName('DemoStrategy');
  StrategyDescription('Demo strategy that does nothing');

  RegOption('Delta', ot_Double, Delta);
  SetOptionRange('Delta', 0, 100);
  SetOptionDigits('Delta', 2);
end;

procedure DoneStrategy; stdcall;
begin

end;

procedure ResetStrategy; stdcall;
begin

end;

procedure GetSingleTick; stdcall;
begin

end;

exports
  InitStrategy,
  DoneStrategy,
  ResetStrategy,
  GetSingleTick;

end.


If you do not want to do extra job, you can omit SetOptionRange and SetOptionDigits. In this case ForexTester will not control the range and use 2 digits after point by default.

And here it is our parameters' window after we copied our strategy and restarted ForexTester:

Image

Posted: Fri Jul 11, 2008 12:06 pm
by Terranin
Let's add more simple parameters:

Code: Select all

StopLoss: integer = 20;
Days: longword = 7;
UseStopLoss: boolean = true;


Code: Select all

RegOption('StopLoss', ot_Integer, StopLoss);
RegOption('Days', ot_Longword, Days);
RegOption('UseStopLoss', ot_Boolean, UseStopLoss);


And as a result we will see:

Image

Now it is time for more complicated parameters, I will add separator between them with AddSeparator. First will be enumeration, its internal representation is integer:

Code: Select all

List: integer = 0;


and in InitStrategy procedure we will add such lines:

Code: Select all

RegOption('List', ot_EnumType, List);
AddOptionValue('List', 'string 1');
AddOptionValue('List', 'string 2');
AddOptionValue('List', 'string 3');
List := 1;


Here we created drop down list with 3 strings 'string 1'..'string 3' and set default value to string 2. (because we count from 0) See next image:

Image

Full code:

Code: Select all

library DemoStrategy;

uses
  SysUtils, StrategyInterfaceUnit, TechnicalFunctions;

// external parameters
var
  Delta: double = 3.46;
  StopLoss: integer = 20;
  Days: longword = 7;
  UseStopLoss: boolean = true;
  List: integer = 0;

procedure InitStrategy; stdcall;
begin
  StrategyShortName('DemoStrategy');
  StrategyDescription('Demo strategy that does nothing');

  RegOption('Delta', ot_Double, Delta);
  SetOptionRange('Delta', 0, 100);
  SetOptionDigits('Delta', 2);

  RegOption('StopLoss', ot_Integer, StopLoss);
  RegOption('Days', ot_Longword, Days);
  RegOption('UseStopLoss', ot_Boolean, UseStopLoss);

  AddSeparator('Extra options');

  RegOption('List', ot_EnumType, List);
  AddOptionValue('List', 'string 1');
  AddOptionValue('List', 'string 2');
  AddOptionValue('List', 'string 3');
  List := 1;
end;

procedure DoneStrategy; stdcall;
begin

end;

procedure ResetStrategy; stdcall;
begin

end;

procedure GetSingleTick; stdcall;
begin

end;

exports
  InitStrategy,
  DoneStrategy,
  ResetStrategy,
  GetSingleTick;

end.

Posted: Fri Jul 11, 2008 12:34 pm
by Terranin
ot_Timeframe represents available timeframes for ForexTester from 1 minute to 1 week. Its internal representation is also integer:

Code: Select all

var
  timeframe: integer = PERIOD_M15;


Code: Select all

RegOption('Timeframe', ot_Timeframe, timeframe);


Strings and currency are slightly more difficult, because they require some extra code in DoneStrategy procedure to release their memory and to change its value you should use ReplaceStr function.

Code: Select all

var
  SomeInfo: PChar;
  Currency: PChar;


In InitStrategy:

Code: Select all

RegOption('SomeInfo', ot_String, SomeInfo);
ReplaceStr(SomeInfo, 'Information for user');

RegOption('Currency', ot_Currency, Currency);
ReplaceStr(Currency, 'EURUSD');


In DoneStrategy:

Code: Select all

FreeMem(SomeInfo);
FreeMem(Currency);


Image

Complete code:

Code: Select all

library DemoStrategy;

uses
  SysUtils, StrategyInterfaceUnit, TechnicalFunctions;

// external parameters
var
  Delta: double = 3.46;
  StopLoss: integer = 20;
  Days: longword = 7;
  UseStopLoss: boolean = true;
  List: integer = 0;
  timeframe: integer = PERIOD_M15;
  SomeInfo: PChar;
  Currency: PChar;

procedure InitStrategy; stdcall;
begin
  StrategyShortName('DemoStrategy');
  StrategyDescription('Demo strategy that does nothing');

  RegOption('Delta', ot_Double, Delta);
  SetOptionRange('Delta', 0, 100);
  SetOptionDigits('Delta', 2);

  RegOption('StopLoss', ot_Integer, StopLoss);
  RegOption('Days', ot_Longword, Days);
  RegOption('UseStopLoss', ot_Boolean, UseStopLoss);

  AddSeparator('Extra options');

  RegOption('List', ot_EnumType, List);
  AddOptionValue('List', 'string 1');
  AddOptionValue('List', 'string 2');
  AddOptionValue('List', 'string 3');
  List := 1;

  RegOption('Timeframe', ot_Timeframe, timeframe);

  RegOption('SomeInfo', ot_String, SomeInfo);
  ReplaceStr(SomeInfo, 'Information for user');

  RegOption('Currency', ot_Currency, Currency);
  ReplaceStr(Currency, 'EURUSD');
end;

procedure DoneStrategy; stdcall;
begin
  FreeMem(SomeInfo);
  FreeMem(Currency);
end;

procedure ResetStrategy; stdcall;
begin

end;

procedure GetSingleTick; stdcall;
begin

end;

exports
  InitStrategy,
  DoneStrategy,
  ResetStrategy,
  GetSingleTick;

end.


C++ code:

Code: Select all

#include <windows.h>
#include "StrategyInterfaceUnit.h"
#include "TechnicalFunctions.h"

// external parameters
double  Delta = 3.46;
int     StopLoss = 20;
long    Days = 7;
bool    UseStopLoss = true;
int     List = 0;
int     timeframe = PERIOD_M15;
char*   SomeInfo;
char*   Currency;

EXPORT void __stdcall InitStrategy()
{
  StrategyShortName("DemoStrategy");
  StrategyDescription("Demo strategy that does nothing");

  RegOption("Delta", ot_double, &Delta);
  SetOptionRange("Delta", 0, 100);
  SetOptionDigits("Delta", 2);

  RegOption("StopLoss", ot_Integer, &StopLoss);
  RegOption("Days", ot_Longword, &Days);
  RegOption("UseStopLoss", ot_Boolean, &UseStopLoss);

  AddSeparator("Extra options");

  RegOption("List", ot_EnumType, &List);
  AddOptionValue("List", "string 1");
  AddOptionValue("List", "string 2");
  AddOptionValue("List", "string 3");
  List = 1;

  RegOption("Timeframe", ot_TimeFrame, &timeframe);

  RegOption("SomeInfo", ot_String, &SomeInfo);
  ReplaceStr(SomeInfo, "Information for user");

  RegOption("Currency", ot_Currency, &Currency);
  ReplaceStr(Currency, "EURUSD");
}

EXPORT void __stdcall DoneStrategy()
{
  free(SomeInfo);
  free(Currency);
}

EXPORT void __stdcall  ResetStrategy()
{

}

EXPORT void __stdcall GetSingleTick()
{

}



Note:
There is a mistake in StrategyInterfaceUnit.h, string

EXPORT void __stdcall ReplaceStr(PChar dest, PChar source);

should be changed to

EXPORT void __stdcall ReplaceStr(PChar& dest, PChar source);

Posted: Fri Jul 11, 2008 12:41 pm
by Terranin
That's all about external parameters, fortunately I created a small tool that can do all the dirty job for you. You can download it here:

http://forextester.com/forum/viewtopic.php?t=855

Posted: Sun Jul 11, 2010 4:00 am
by etw
Hello - using the C++ code I get c:\program files\forextester2\api\demostrategy\demostrategy.cpp(20) : error C2065: 'ot_double' : undeclared identifier

from VS 2008. Any advice?

Posted: Sun Jul 11, 2010 4:02 am
by etw
Ahh - turns out the identifier is ot_Double not ot_double. Small typo there.

help!-Currency list empty

Posted: Sun Sep 12, 2010 4:45 am
by aafx
I just follow lesson 2 to biuld DemoStrategy.dll by delphi. everything seems good but the Curreny list is empty. the curreny pair names wont appear! whats wrong?

Re: help!-Currency list empty

Posted: Sun Sep 12, 2010 9:43 am
by Terranin
aafx wrote:I just follow lesson 2 to biuld DemoStrategy.dll by delphi. everything seems good but the Curreny list is empty. the curreny pair names wont appear! whats wrong?


Can you see currencies in Testing Mode? Did you click on Currency list in strategy and it shows you empty drop down list?

Re: Lesson 2 - defining external parameters

Posted: Mon Aug 31, 2015 6:09 pm
by gabrielr
Hi, I made lesson 1 and y instaled the DemoStrategy program succesfully on FT2. When y made lesson 2, y put my first variable Delta, and when I wanted to install it on FT2, it gave me the following message:

Can not install strategy, file will be deleted. Have error: Can not get "ReplaceStr" proc address

I don´t know what I am doing wrong, as I am copying from your program code, and Delta is a Double type parameter (doesn´t need ReplaceStr function built on it).

Do yo know if there is anything I could do to solve this problem?

Regards,

Gabriel

Re: Lesson 2 - defining external parameters

Posted: Tue Sep 01, 2015 5:18 am
by FX Helper
Hello

You copied the code of the strategy from this page? Is it Delphi or C++ code?

What program to compile strategies do you use?

Re: Lesson 2 - defining external parameters

Posted: Tue Sep 01, 2015 6:21 am
by gabrielr
I copied from this page in Delphi.
I used Lazarus to compile. Worked fine for lesson 1 (no external parameters at that moment).
The problem arised when I included the first external parameter.

Re: Lesson 2 - defining external parameters

Posted: Wed Sep 02, 2015 4:22 am
by FX Helper
Hello,

Probably this issue is associated with Lazarus. Sorry, but we haven't worked with Lazarus so we can't help you with this.

Can you install any Delphi version? For example, please google for Delphi7_Lite_Full_Setup_v7.3.3.0_Build_2009-6-22_.rar
This should work for you.

Re: Lesson 2 - defining external parameters

Posted: Wed Sep 02, 2015 8:57 am
by gabrielr
Ok, I just installed it at it worked just fine. Thanks and Regards, Gabriel

Re: Lesson 2 - defining external parameters

Posted: Fri Sep 04, 2015 9:00 am
by gabrielr
Sorry to bother you again with the Delphi Software. I installed the Borland Delphi software that you recomended, and it worked ok for the first day. Then, I reached lesson 3, and when I tried to save the DemoStrategy1.dpr for the second part of the lesson, the software gave me the followng message:

Unable to rename C:\program Files(x86)\Borland\Delphi7\Projects\DemoStrategy1.$$$ to C:\program Files(x86)\Borland\Delphi7\Projects\Demostrategy1.dpr.

Then I tried to save the file with another name like DemoStrategy3.dpr, but when compiling it gave me an error with the following messages:

[Error] Write error on 'DemoStrategy3.dll'
[Error] RLINK32: Error writing file "DemoStrategy3.dll"

I can see the DemoStrategy3 file in the file open menu of Delphi7, but if I go with my windows explorer to the directory where there should be the DemoStrategy3.dpr file saved (path c:\Borland\Delphi7\project), the file is not there.
I seems it can not read the file when the software tries to compile the file.
Do you know if there is anything I can do to fix this problem?
Thanks and Regards,
Gabriel

Re: Lesson 2 - defining external parameters

Posted: Fri Sep 11, 2015 9:59 am
by FX Helper
Hello,

It seems that the issue is with the structure of the project, maybe some components were renamed or corrupted.

Please try to create a new project and compile it again, this should help

Re: Lesson 2 - defining external parameters

Posted: Thu Dec 01, 2016 2:37 pm
by kriteshh
Hi.

I also received the RLINK32 error. When I looked in the Delphi project for through Windows Explorer I could not see the DemoStrategy.drp file. However, when looked through the Delphi program (File -> Save Project As) I could see it which was strange.

So I just changed the security levels for the Boland folder in the Program Files folder to Full control for my user id and it worked. It was just a security/permissions issue.

Hope this helps someone...