Silver and Gold mystery

 
Hi:
I'm trying to set my EA up to accommodate more than currencies. Instruments like Gold, Silver, Oil, and some Indices like S&P500, etc.
I started off with Gold and Silver but ran into trouble due to broker differences in Contract Sizes and Price Quote differences (2 digits after the point vs 3 digits after the point etc.
IBFX for instance is a 2 Digit broker (both Gold and Silver) and Alpari is a 3 Digits broker (Gold and Silver). A further complication is that
Alpari offers 5000 oz Silver contracts versus IBFX offers 500 Oz Silver contracts and Alpari offers 100 oz Gold contracts and IBFX offers 10 Oz contracts.

So the problem (or the objective rather) would be to buid a "CalculateLots" Function that will handle all these "subtle" differences on the GO with no problems at all.

Maybe there is a Good and Brilliant Person out there that did this already
double CalcLots(bool sendDynamicLotSize, double sendEquityPercent,double sendStopLoss, double sendFixedLotSize)
   {
   double WorkingBalance = MathMin(BalanceZ,MathMin(AccountEquity(),AccountBalance()));
  
   double LotStep   = MarketInfo(Symbol(), MODE_LOTSTEP);    
   double TickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
   double TickSize  = MarketInfo(Symbol(), MODE_TICKSIZE);
   double Contract  = MarketInfo(Symbol(), MODE_LOTSIZE);  
   double MaxLots   = MarketInfo(Symbol(), MODE_MAXLOT);  
   double MinLots   = MarketInfo(Symbol(), MODE_MINLOT);  
//--------------------------------------------------------------------------------------------------------  
   if(sendDynamicLotSize == true && sendStopLoss > 0 && PercentageBased == true)
              {
         double RiskAmount = WorkingBalance * (sendEquityPercent / 100);
         if(Point == 0.001 || Point == 0.00001) TickValue = TickValue*10;
         if(Contract != 10 && Contract != 500 && sendStopLoss != 0 && TickValue != 0) double LotSize = (RiskAmount / sendStopLoss) / MarketInfo(Symbol(), MODE_TICKVALUE);
         if(Contract == 10 || Contract == 500 && sendStopLoss != 0 && TickValue != 0)        LotSize = ((RiskAmount / sendStopLoss) / MarketInfo(Symbol(), MODE_TICKVALUE))/10;}
   
   if(LotSize > MaximumLotsAllowed)   LotSize = MaximumLotsAllowed;
   if(LotStep == 0.1)   LotSize = NormalizeDouble(LotSize,1);
   if(LotStep == 0.01)  LotSize = NormalizeDouble(LotSize,2);
   if(LotStep == 0.001) LotSize = NormalizeDouble(LotSize,3);
   if(LotStep != 0)     LotSize = MathFloor(LotSize/LotStep)*LotStep;
   return(LotSize);
   }
..? Or - would it be possible to point me in the right direction? This will be HUGE...

The code below works on Alpari but not on IBFX. I tried to do something by inserting the contracts in the IF statement but to no avail. I get an error 131 all the time.

Thank you for reading...
 
apes001:
Hi:
I'm trying to set my EA up to accommodate more than currencies. Instruments like Gold, Silver, Oil, and some Indices like S&P500, etc.
I started off with Gold and Silver but ran into trouble due to broker differences in Contract Sizes and Price Quote differences (2 digits after the point vs 3 digits after the point etc.
IBFX for instance is a 2 Digit broker (both Gold and Silver) and Alpari is a 3 Digits broker (Gold and Silver). A further complication is that
Alpari offers 5000 oz Silver contracts versus IBFX offers 500 Oz Silver contracts and Alpari offers 100 oz Gold contracts and IBFX offers 10 Oz contracts.

So the problem (or the objective rather) would be to buid a "CalculateLots" Function that will handle all these "subtle" differences on the GO with no problems at all.

Maybe there is a Good and Brilliant Person out there that did this already.. ? Or - would it be possible to point me in the right direction? This will be HUGE...

The code below works on Alpari but not on IBFX. I tried to do something by inserting the contracts in the IF statement but to no avail. I get an error 131 all the time.

Thank you for reading...
Did you do some research ?
 

angevoyageur - yes I did.

I 'm visting this Forum for quite some time now (many a year) and usually found my answers here. I also tried MoneyTec, ForexFactory, Forex-Td and of course apart from these - also good old Google. It could be that developers don't have this requirement, I don't know. And then - it could be that I'm growing too old to figure this out... :-)

But anyway - thanks for reading my first post.

 
 
Just to illustrate the "descrepencies":

IBFX
a. MarketInfo(Symbol(), MODE_LOTSIZE): 500 oz (Silver) 10 oz (Gold) Not the same for both Brokers
b. MarketInfo(Symbol(), MODE_LOTSTEP): 0.1 0.1 Same for both Brokers
c. MarketInfo(Symbol(), MODE_TICKSIZE): 0.01 0.01 Not the same for the 2 Brokers
d. MarketInfo(Symbol(), MODE_TICKVALUE): 5.0 0.1 Same for both Brokers

ALPARI
a. MarketInfo(Symbol(), MODE_LOTSIZE): 5000 oz (Silver) 100 oz (Gold)
b. MarketInfo(Symbol(), MODE_LOTSTEP): 0.1 0.1
c. MarketInfo(Symbol(), MODE_TICKSIZE): 0.001 0.001
d. MarketInfo(Symbol(), MODE_TICKVALUE): 5.0 0.1

I'm testing WHRoeder's DeltaValuePerLot() and saw that on ALPARI it all went well... Currecies as well as Metals (100%). No Problem.
On IBFX however - the currencies do 100% what they are suppose to be doing BUT the Metals don't even come to the table.

I can also see in the Journal that the Number of Lots calculated is 10 times too high. And then of cause I get error 131.

@WHRoeder - thankyou for the suggestion. I'm still trying to work trough the EA that you supplied on the forum as well. I have great respect for your work.

@angevoyageur - I only saw (after I went to town) that you supplied a link. But yes - I did go through all those as well. Thanks - I appreciate...

 

You have to use this formula to calculate your lot size :

      LotSize = RiskAmount/(sendStopLoss*Point) / (TickValue/TickSize);
 
Three changes were made according to WHRoeder's work (this is only my understanding / or how I thought I need to implement it ). See the
int init()
{
.
.
   if (Digits == 5 || Digits == 3){    
      pips2dbl = Point*10; pips2points = 10; Digits.pips = 1;
      } else {   pips2dbl = Point; pips2points = 1; Digits.pips = 0;}  <--------------------------Put these in the INIT function
.
.
.

   if(sendDynamicLotSize == true && sendStopLoss > 0 && PercentageBased == true)
              {
         double RiskAmount = SomBalans * (sendEquityPercent / 100);
         double PipValuePerLot = DeltaValuePerLot() * pips2dbl; <---------------------------------------------------------Changed in CalcLots function
         if(sendStopLoss != 0 && PipValuePerLot != 0) double LotSize = (RiskAmount/sendStopLoss)/PipValuePerLot;} <---------Changed in CalcLots function
.
.
.

double  DeltaValuePerLot() <------------- Function on its own
   {
   return(MarketInfo(Symbol(), MODE_TICKVALUE) / MarketInfo(Symbol(), MODE_TICKSIZE)); 
   }
3 the pieces of code above...
Now - these changes worked as expected on Alpari (both currencies & metals (Gold/Silver). It even worked as expected on IBFX currencies -
which are quoted in Digits=3 or Digits = 5. BUT.... It won't work on Metals (both Silver and Gold).

@angevoyageur: If I put the *point in the formula, the system is multiplying the lot sizes out of proportion. I will do some more test though...!

 
apes001:
...
@angevoyageur: If I put the *point in the formula, the system is multiplying the lot sizes out of proportion. I will do some more test though...!

Maybe I misunderstood what was your sendStopLoss variable. In my formula it's intended to be a value in point, something like 100.
 

Answers on Print Statements

The previous post shows the formula that ar eidentical for both Brokers. pips2dbl stays the same although IBFX is a 2 Digits broker (on the chart that is).

This problem is way above my "coding" grade... :-)

I don't know what else to check...

 
apes001:

The previous post shows the formula that ar eidentical for both Brokers. pips2dbl stays the same although IBFX is a 2 Digits broker (on the chart that is).

This problem is way above my "coding" grade... :-)

I don't know what else to check...

For IBFX, Minlot & Maxlot are both at 0.1 so you can only set lotsize to 0.1.
 

@angevoyageur: Thanks for your patience.

I hardcoded 0.1 Lots in the CalcLots function - the only lotsize that can come out of that function - and still.... error 4051.

So it must be something odd that I'm not capable of seeing.

Bearing in mind the CalcFunction is doing it's job superbly on the other broker (Alpari). What's really funny (odd) is the pips2dbl variable which is the same for both the 3 and 2 digit brokers.