parameter passed by reference behavior

 
I would like to implement a library function that can modify a given value passed as parameter.
This is a Test Case for what i am looking for:

void modify_double(double value) { value = value + 1; } int start() { static double mydouble; mydouble = 1; Print("Mydouble: ",mydouble); modify_double(mydouble); Print("Mydouble: ",mydouble); }


I would like that the output would be:

Mydouble: 1 Mydouble: 2


But currently the output is Mydouble: 1 in both Prints
 
bar4ka

The problem you encountered is that a variable is only visible to the function that is described in that includes the start function. If you want all function to see a variable you must decleare it as a global scope variable out side of any function discription (see type A below), or pass it by referance (see type B below). Decleare the veriable mydouble out side of any function discription will make it a global variable. If you add the & in the function pamater discription it will change the value of the variable pased it. Also; It is not required with functions that don't return any values, but good coding style to use the return statement at the end of all function even if they return nothing as in a sub routine procedure.


type A using global scope variable
double mydouble ; void modify_double( ) { mydouble = mydouble + 1; return; } void start() { mydouble = 1; Print("Mydouble: ",mydouble); modify_double(); Print("Mydouble: ",mydouble); return; }



Type B passing by referance.

void modify_double(double& value) { value = value + 1; return; } void start() { double mydouble; mydouble = 1; Print("Mydouble: ",mydouble); modify_double(mydouble); Print("Mydouble: ",mydouble); return; }


The CockeyedCowboy


bar4ka:
I would like to implement a library function that can modify a given value passed as parameter.
This is a Test Case for what i am looking for:

void modify_double(double value) { value = value + 1; } int start() { static double mydouble; mydouble = 1; Print("Mydouble: ",mydouble); modify_double(mydouble); Print("Mydouble: ",mydouble); }


I would like that the output would be:

Mydouble: 1 Mydouble: 2


But currently the output is Mydouble: 1 in both Prints
 
Another way is:

double modify_double(double value) { value = value + 1; return (value); }
 
CockeyedCowboy:
bar4ka

If you add the & in the function pamater discription it will change the value of the variable pased it. Also; It is not required with functions that don't return any values, but good coding style to use the return statement at the end of all function even if they return nothing as in a sub routine procedure.

Type B passing by referance.

void modify_double(double& value) { value = value + 1; return; }
Despite my Test case use only one parameter in reality i need to pass a lot of parameters, so the & solves my problem.

Does mql has any support for composite types like c struct, pascal record, or even a class ?
 
bar4ka

MQL dosnot to my knoweladge support composite / class types, directly. You can simulate that effect with some code tricks. More work then its worth I think. What is it your trying to acheive.

MQL doesnot support Sub Routine Procedures ( only Function Precedures ). However, if you view a function that returns nothing, but performs a duty, as a sub routine then you can create sub routines (functions) that have the ability to alter a large number of variables ( global scope ) with ease.

Here is an example of a call to a sub routine to open orders ( pending or market ) were all you have to pass it is the order type you want and the price to establish it. So instead of using the OrderSend( ) function and passing it all the parameters you just have to place EstablishPosition( ordertype, price ); and the sub routine procedure will place your order. This is done because all the parameters to establish an order have been defind as global scope type. The Parameters by the way have been set in another sub routine InstituteNewCampaign( ordertype ); before hand. This is all acheived buy using global scope variables were needed in your code along with Sub Routine Precedures with in your code.

The code below is taken from an EA I am currently working on, and is only an example of what can be done.
code:
RD!{must declare all global variables needed before the start function}: void start(){//»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»««««««««««««««««««««««««««««««««««««««««««« ... ... ... ... //«« LABEL 500 »» POSITION ASSESSMENT: »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» //«« <<<< Segment 510 >>>> »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» // Code block to set opening market order for starting new campaign . if( ! CampaignExists && StartNewCampaign ) { OrderID = (( SystemTag * OrderPortion ) + PositionLevel ); LastDirection = OrderDirection; if( OrderDirection == LongOrder ) { if( ! CombatVictories ) InstituteNewCampaign( LongOrder ); EstablishPosition( LongOrder, ChannelBuyRate ); if( DeBugMessages ) Print ( "Sent Long at ", ChannelBuyRate, ": ", lotsWagered, " Lots." ); } else if( OrderDirection == ShortOrder ) { if( ! CombatVictories ) InstituteNewCampaign( ShortOrder ); EstablishPosition( ShortOrder, ChannelSellRate ); if( DeBugMessages ) Print ( "Sent Short at ", ChannelSellRate, ": ", lotsWagered, " Lots." ); } else { // RD!{ErrorHandler recovery}: Print( "OverFlow Error in new order execution." ); } // End If, OrderDirection: } // End If, CampaignExists: //«« <<<< Segment 530 >>>> »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» // Code block to add new pending hedge order when last level was triggered. if( CampaignExists && HedgeNeeded ) { OrderID = (( SystemTag * OrderPortion ) + PositionLevel ); LastDirection = LastOrderPlaced; if( LastOrderPlaced == LongOrder ) { EstablishPosition( SellStop, ChannelSellRate ); if( DeBugMessages ) Print ( "SellStop Hedge Sent at", ChannelBuyRate, ": ", lotsWagered, " Lots." ); } else if( LastOrderPlaced == ShortOrder ) { EstablishPosition( BuyStop, ChannelBuyRate ); if( DeBugMessages ) Print ( "BuyStop Hedge Sent at ", ChannelSellRate, ": ", lotsWagered, " Lots." ); } else { // RD!{ErrorHandler Recovery}: if( DeBugMessages ) Print( "OverFlow Error in pending order execution." ); } // End If, LastOrderPlaced: } // End If, CampaignExists: ... ... ... ... ... return;}//»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»«««««««««««««««««««««««««««««««««««««««««« //«« ROUTINE PROCEDURES SECTION: »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» //«« <<<< Establish Positions, Sub Routine >>>> »»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»» void EstablishPosition( int PositionType, int Price ) { int Order = Failed; int AttemptsTried = Empty; int Position = Empty; bool PositionSet = False; color Arrow = DefaultColor; AccountAvailable = CheckWithOrderDesk(); while( AccountAvailable && ! PositionSet ) { AttemptsTried = AttemptsTried + 1; if( DeBugMessages ) Print( "Attempts Tried = ", AttemptsTried ); Order = OrderSend( Symbol(), PositionType, lotsWagered, Price, Slippage, StopLoss, TakeProfit, RunSerialNumber, OrderID, OrderExpires, Arrow ); if( ! IsTesting() ) Sleep( PauseInterval ); if( Order > Empty ) { PositionSet = True; Position = Order; Print( "Order ", Order, " Successful.", OrderID ); } else if( Order == Failed && AttemptsTried >= MaximumAttempts ) { AccountAvailable = False; ErrorFound = GetLastError(); Print( "Attempts in sending order ", OrderID, " Failed: Error ", ErrorFound, " was detected" ); } else { RefreshRates(); } // End If, Order: } // End While Loop, AccountAvailable: GetOrderComformation( Position, Order ); return; } // End Sub Procedure, EstablishPosition:



The CockeyedCowboy


bar4ka:
CockeyedCowboy:
bar4ka

If you add the & in the function pamater discription it will change the value of the variable pased it. Also; It is not required with functions that don't return any values, but good coding style to use the return statement at the end of all function even if they return nothing as in a sub routine procedure.

Type B passing by referance.

void modify_double(double& value) { value = value + 1; return; }
Despite my Test case use only one parameter in reality i need to pass a lot of parameters, so the & solves my problem.

Does mql has any support for composite types like c struct, pascal record, or even a class ?
Reason: