Position Sizing - Help Needed

How to create strategies and indicators
Message
Author
pthomas82
Posts: 60
Joined: Tue Aug 10, 2010 8:39 pm

Position Sizing - Help Needed

#1 Postby pthomas82 » Sat Dec 31, 2011 6:02 am

Hi Guys,

Im trying to build code to add fixed % position sizing for any pair, and im really finding this difficult. I was wondering if someone could look over this and help get this working!

I guess the hard part is the fact that the calculatin changes if it is a ***/USD , ***/JPY or other pair. And the calculation is relying on a value of another pair.

So here is the code im working on - and next post I'll put it in a system form:



Code: Select all


var
lotsize: double;
JPYCUR: double;
JPYSTP: double;
USDCUR: double;
USDSTP: double;
ALLCUR: double;
ALLSTP: double;
CADCUR: double;
CADSTP: double;
CHFCUR: double;
CHFSTP: double;
JPYCLOSE: DOUBLE;
CHFCLOSE: DOUBLE;
CADCLOSE: DOUBLE;
PATR: integer;


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

procedure InitStrategy; stdcall;

begin

RegOption('Percentage to risk', ot_Integer, PATR);
PATR := 2;

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

procedure GetSingleTick; stdcall;


begin

baseCur := LeftStr(CURRENCY, 3);
secondCur := RightStr(Currency, 3);
JPYCLOSE :=  iClose('USDJPY', timeframe, 0);
JPYCUR := (100/JPYCLOSE)*10;
JPYSTP := STOPLOSS*JPYCUR;
USDCUR := 10;
USDSTP :=  STOPLOSS*USDCUR;
CADCLOSE :=  iClose('USDCAD', timeframe, 0);
CADCUR :=  (10/CADCLOSE)*10;
CADSTP :=  STOPLOSS*CADCUR;
CHFCLOSE :=  iClose('USDCHF', timeframe, 0);
CHFCUR :=  (10/CHFCLOSE)*10;
CHFSTP :=  STOPLOSS*CHFCUR;

// position sizing



if GetCurrencyInfo(secondCur+'JPY', info) then
 begin
 Lotsize := (AccountEquity*(PATR*0.01))/JPYSTP;
 end;

 if GetCurrencyInfo(secondCur+'USD', info) then
 begin
 Lotsize := (AccountEquity*(PATR*0.01))/USDSTP;
 end  ;

  if GetCurrencyInfo(secondCur+'CAD', info) then
 begin
 Lotsize := (AccountEquity*(PATR*0.01))/CADSTP;
 end  ;

   if GetCurrencyInfo(secondCur+'CHF', info) then
 begin
 Lotsize := (AccountEquity*(PATR*0.01))/CHFSTP;
 end  ;





So where am I going wrong?

Ohh and... HAPPY NEW YEARS!
Last edited by pthomas82 on Sat Dec 31, 2011 6:22 am, edited 1 time in total.

pthomas82
Posts: 60
Joined: Tue Aug 10, 2010 8:39 pm

#2 Postby pthomas82 » Sat Dec 31, 2011 6:02 am

Here is the code attached to a simple system - I keep getting "ERROR IN STRATEGY" and i've traced it back to the lotsize calculation.

Code: Select all

library MBPositionsizing;


uses
  SysUtils,
  Classes,
  StrategyInterfaceUnit,
  technicalfunctions,
  Strutils;

var

// External parameters

Currency: PChar = nil;
BANDDEV: Double;
BANDS: Integer;
BANDTIME: integer;
LotSize: double;
LOWERBAND: double;
LOWERBAND1: double;
PATR: integer;
STOPLOSS: integer;
Takeprofit: integer;
TimeFrame: integer;
UPPERBAND: double;
UPPERBAND1: double;
Breakeven: integer;
Breakeven1: integer;
Maperiod: integer;
MA1: integer;
Mavalue: double;
MAprev: double;
UPPERPREV: double;
Lowerprev: double;
baseCur: ANSIString;
secondCur: ANSIString;
info: PCurrencyInfo;
JPYCUR: double;
JPYSTP: double;
USDCUR: double;
USDSTP: double;
ALLCUR: double;
ALLSTP: double;
CADCUR: double;
CADSTP: double;
CHFCUR: double;
CHFSTP: double;
JPYCLOSE: DOUBLE;
CHFCLOSE: DOUBLE;
CADCLOSE: DOUBLE;



// custom variables

OrderHandle: integer;
OrderStyle: TTradePositionType;
OpenTime: TDateTime;
PrevTime: TDateTime;


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

procedure InitStrategy; stdcall;

begin

StrategyShortName('MA BANDS w/ Position sizing');
StrategyDescription('MA BAND');


// Register external parameters

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

RegOption('Timeframe', ot_Timeframe, TimeFrame);
TimeFrame := 15;

RegOption('TREND Stoploss', ot_Integer, STOPLOSS);
STOPLOSS := 20;

RegOption('TAKEPROFIT', ot_Integer, TAKEPROFIT);
TAKEPROFIT := 20;

RegOption('MA PERIOD', ot_Integer, MAPERIOD);
MAPERIOD := 20;

RegOption('BAND PERIOD', ot_Integer, BANDTIME);
BANDTIME := 200;

RegOption('BAND DEVIATION', ot_Double, BANDDEV);
BANDDEV := 0.35;

RegOption('Percentage to risk', ot_Integer, PATR);
PATR := 2;

end;


{-----Done strategy---------------------------------------}

procedure DoneStrategy; stdcall;

begin

FreeMem(Currency);

end;


{-----Reset strategy--------------------------------------}

procedure ResetStrategy; stdcall;

begin
BANDS := CreateIndicator (Currency, Timeframe, 'Envelopes', format('%d;%d;%s;%s;%.2f', [BANDTIME,0,'Simple (SMA)','close',BANDDEV]));
MA1 := CreateIndicator(Currency, Timeframe, 'MovingAverage',format('%d;0;0;%s;Close', [MAPeriod, 'Exponential (EMA)']));

end;

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

procedure GetSingleTick; stdcall;

var
i: integer;
b: integer;

begin

UPPERBAND := GetIndicatorValue(BANDS, 0, 0);
UPPERPREV := GetIndicatorValue(BANDS, 1, 0);
LOWERBAND := GetIndicatorValue(BANDS, 0, 1);
LOWERPREV := GetIndicatorValue(BANDS, 1, 1);
MAVALUE := GetIndicatorValue(MA1, 0, 0);
MAPREV := GetIndicatorValue(MA1, 1, 0);
baseCur := LeftStr(CURRENCY, 3);
secondCur := RightStr(Currency, 3);
JPYCLOSE :=  iClose('USDJPY', timeframe, 0);
JPYCUR := (100/JPYCLOSE)*10;
JPYSTP := STOPLOSS*JPYCUR;
USDCUR := 10;
USDSTP :=  STOPLOSS*USDCUR;
CADCLOSE :=  iClose('USDCAD', timeframe, 0);
CADCUR :=  (10/CADCLOSE)*10;
CADSTP :=  STOPLOSS*CADCUR;
CHFCLOSE :=  iClose('USDCHF', timeframe, 0);
CHFCUR :=  (10/CHFCLOSE)*10;
CHFSTP :=  STOPLOSS*CHFCUR;


// position sizing



if GetCurrencyInfo(secondCur+'JPY', info) then
 begin
 Lotsize := (AccountEquity*(PATR*0.01))/JPYSTP;
 end;

 if GetCurrencyInfo(secondCur+'USD', info) then
 begin
 Lotsize := (AccountEquity*(PATR*0.01))/USDSTP;
 end  ;

  if GetCurrencyInfo(secondCur+'CAD', info) then
 begin
 Lotsize := (AccountEquity*(PATR*0.01))/CADSTP;
 end  ;

   if GetCurrencyInfo(secondCur+'CHF', info) then
 begin
 Lotsize := (AccountEquity*(PATR*0.01))/CHFSTP;
 end  ;



// check our currency

if Symbol <> string(Currency) then exit;


// set currency and timeframe

SetCurrencyAndTimeframe(Symbol, TimeFrame);

// check number of bars for CHANNEL period

if (Bars < BANDTIME) then exit;


  // INITAL ENTRY RULES!!!!

  //MAKE SURE NO TRADE OPEN

  IF (time(0) <> PrevTime) and (orderstotal = 0)  then
  BEGIN



  // BUY RULE

  IF (MAPREV < LOWERPREV) and (MAVALUE > LOWERBAND) then
  BEGIN
  SendInstantOrder(Symbol, op_BUY, LotSize, (CLOSE(0)-(STOPLOSS*POINT)), 0, '', 0, OrderHandle);
  PrevTime := time(0);
  END;


  // SELL RULE

  IF (MAPREV > UPPERPREV) and (MAVALUE < UPPERBAND) then
  BEGIN
  SendInstantOrder(Symbol, op_SELL, LotSize, (CLOSE(0)+(STOPLOSS*POINT)), 0, '', 0, OrderHandle);
  PrevTime := time(0);
  END;
  end;



 // EXIT RULES

 // look for open orders

  if (OrdersTotal > 0)  then
  Begin
  for i:=0  to OrdersTotal do
  begin
  OrderSelect(i, SELECT_BY_POS, MODE_TRADES);



// Takeprofit

 if (OrderProfitPips >= Takeprofit) then
  CloseOrder(OrderTicket);

    END;
    end;
    end;



exports

InitStrategy,
DoneStrategy,
ResetStrategy,
GetSingleTick;


end.

FT Support
Posts: 905
Joined: Sat Jul 11, 2009 10:54 am

#3 Postby FT Support » Sun Jan 01, 2012 6:07 pm

Hello,

Please try to remove code part by part and see if the error is gone. When you find a piece of code which causes the error it will be easier for you to fix it.
Check our other product here:
http://www.forexcopier.com

pthomas82
Posts: 60
Joined: Tue Aug 10, 2010 8:39 pm

#4 Postby pthomas82 » Mon Jan 02, 2012 1:55 am

Hi Mike,

I had tried heaps of different things - incl remove & print functions, but I had got stuck when I posted it. However I revisited after reading your post - and figured out the issue.

For anyone reading - please find updated code:

Code: Select all

library MBPositionsizing;


uses
  SysUtils,
  Classes,
  StrategyInterfaceUnit,
  technicalfunctions,
  Strutils;

var

// External parameters

Currency: PChar = nil;
BANDDEV: Double;
BANDS: Integer;
BANDTIME: integer;
LotSize: double;
LOWERBAND: double;
LOWERBAND1: double;
PATR: integer;
STOPLOSS: integer;
Takeprofit: integer;
TimeFrame: integer;
UPPERBAND: double;
UPPERBAND1: double;
Breakeven: integer;
Breakeven1: integer;
Maperiod: integer;
MA1: integer;
Mavalue: double;
MAprev: double;
UPPERPREV: double;
Lowerprev: double;
baseCur: ANSIString;
secondCur: ANSIString;
info: PCurrencyInfo;
JPYCUR: double;
JPYSTP: double;
USDCUR: double;
USDSTP: double;
ALLCUR: double;
ALLSTP: double;
CADCUR: double;
CADSTP: double;
CHFCUR: double;
CHFSTP: double;
JPYCLOSE: DOUBLE;
CHFCLOSE: DOUBLE;
CADCLOSE: DOUBLE;
AECALC : Double;



// custom variables

OrderHandle: integer;
OrderStyle: TTradePositionType;
OpenTime: TDateTime;
PrevTime: TDateTime;


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

procedure InitStrategy; stdcall;

begin

StrategyShortName('MA BANDS w/ Position sizing');
StrategyDescription('MA BAND');


// Register external parameters

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

RegOption('Timeframe', ot_Timeframe, TimeFrame);
TimeFrame := 15;

RegOption('TREND Stoploss', ot_Integer, STOPLOSS);
STOPLOSS := 20;

RegOption('TAKEPROFIT', ot_Integer, TAKEPROFIT);
TAKEPROFIT := 20;

RegOption('MA PERIOD', ot_Integer, MAPERIOD);
MAPERIOD := 20;

RegOption('BAND PERIOD', ot_Integer, BANDTIME);
BANDTIME := 200;

RegOption('BAND DEVIATION', ot_Double, BANDDEV);
BANDDEV := 0.35;

RegOption('Percentage to risk', ot_Integer, PATR);
PATR := 2;

end;


{-----Done strategy---------------------------------------}

procedure DoneStrategy; stdcall;

begin

FreeMem(Currency);

end;


{-----Reset strategy--------------------------------------}

procedure ResetStrategy; stdcall;

begin
BANDS := CreateIndicator (Currency, Timeframe, 'Envelopes', format('%d;%d;%s;%s;%.2f', [BANDTIME,0,'Simple (SMA)','close',BANDDEV]));
MA1 := CreateIndicator(Currency, Timeframe, 'MovingAverage',format('%d;0;0;%s;Close', [MAPeriod, 'Exponential (EMA)']));

end;

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

procedure GetSingleTick; stdcall;

var
i: integer;
b: integer;

begin

UPPERBAND := GetIndicatorValue(BANDS, 0, 0);
UPPERPREV := GetIndicatorValue(BANDS, 1, 0);
LOWERBAND := GetIndicatorValue(BANDS, 0, 1);
LOWERPREV := GetIndicatorValue(BANDS, 1, 1);
MAVALUE := GetIndicatorValue(MA1, 0, 0);
MAPREV := GetIndicatorValue(MA1, 1, 0);
baseCur := LeftStr(CURRENCY, 3);
secondCur := RightStr(Currency, 3);
AECALC :=  (AccountEquity*(PATR*0.01)) ;
JPYCLOSE :=  iClose('USDJPY', timeframe, 0);
JPYCUR := (100/JPYCLOSE)*10;
JPYSTP := STOPLOSS*JPYCUR;
USDCUR := 10;
USDSTP :=  STOPLOSS*USDCUR;
CADCLOSE :=  iClose('USDCAD', timeframe, 0);
CADCUR :=  (10/CADCLOSE)*10;
CADSTP :=  STOPLOSS*CADCUR;
CHFCLOSE :=  iClose('USDCHF', timeframe, 0);
CHFCUR :=  (10/CHFCLOSE)*10;
CHFSTP :=  STOPLOSS*CHFCUR;


// position sizing



 if SecondCur = 'JPY' then
 begin
 lotsize := AECALC / JPYSTP;
 end;

 if SecondCur = 'USD' then
begin
Lotsize := AECALC/USDSTP;
end  ;

if SecondCur = 'CAD' then
begin
Lotsize := AECALC/CADSTP;
end  ;

if Secondcur = 'CHF' then
begin
Lotsize := AECALC/CHFSTP;
end  ;





// check our currency

if Symbol <> string(Currency) then exit;


// set currency and timeframe

SetCurrencyAndTimeframe(Symbol, TimeFrame);

// check number of bars for CHANNEL period

if (Bars < BANDTIME) then exit;


  // INITAL ENTRY RULES!!!!

  //MAKE SURE NO TRADE OPEN

  IF (time(0) <> PrevTime) and (orderstotal = 0)  then
  BEGIN



  // BUY RULE

  IF (MAPREV < LOWERPREV) and (MAVALUE > LOWERBAND) then
  BEGIN
  SendInstantOrder(Symbol, op_BUY, LotSize, (CLOSE(0)-(STOPLOSS*POINT)), 0, '', 0, OrderHandle);
  PrevTime := time(0);
  Print(format('AE = %.4f', [AECALC]));
  Print(format('JPYSTP = %.4f', [JPYSTP]));
  Print(format('JPYCLOSE = %.4f', [LOTSIZE]));
  END;


  // SELL RULE

  IF (MAPREV > UPPERPREV) and (MAVALUE < UPPERBAND) then
  BEGIN
  SendInstantOrder(Symbol, op_SELL, LotSize, (CLOSE(0)+(STOPLOSS*POINT)), 0, '', 0, OrderHandle);
  PrevTime := time(0);
  Print(format('AE = %.4f', [AECALC]));
  Print(format('JPYSTP = %.4f', [JPYSTP]));
  Print(format('JPYCLOSE = %.4f', [LOTSIZE]));
  END;
  end;



 // EXIT RULES

 // look for open orders

  if (OrdersTotal > 0)  then
  Begin
  for i:=0  to OrdersTotal do
  begin
  OrderSelect(i, SELECT_BY_POS, MODE_TRADES);



// Takeprofit

 if (OrderProfitPips >= Takeprofit) then
  CloseOrder(OrderTicket);

    END;
    end;
    end;





exports

InitStrategy,
DoneStrategy,
ResetStrategy,
GetSingleTick;


end.

User avatar
Tantalus
Posts: 302
Joined: Fri Mar 23, 2007 3:51 pm
Contact:

#5 Postby Tantalus » Tue Jan 03, 2012 11:44 am

Congratulations - debugging can be a real bitch!!
Tantalus Research - Developing 21st Century Trading Systems.


Return to “FT API”

Who is online

Users browsing this forum: No registered users and 8 guests