Calculate PipSize for Symbols in MT4 - mql4

My Question is How can I calculate Pip Size in MT4 (without checking symbol name)?
My first Answer is based on checking symbol name:
Use the Digits variable for 5 or 4 digits symbols and set PipSize = 0.0001. if Symbols are JPY fractions, use another values and so on other symbols in Shares and Indices or Spot Metals (like Silver)
double pipSize = 0.0001;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
if(StringFind("-,XAUUSD,Gold,GOLD,Gold.m,GOLD.m,-",","+Symbol()+",")>0){
pipSize = 0.1; // updated
}else if(StringFind("-,XAGUSD,Silver,SILVER,Silver.m,SILVER.m,-",","+Symbol()+",")>0){
pipSize = 1/500;
}
//---
return(INIT_SUCCEEDED);
}

GOLD 1 pip is 0.10 not 0.01 (according to COMEX)
double PIP = Point()*(Digits%2==1 ? 10 : 1); // for forex only

The problem is that the pip size definition is subjective (or at best intersubjective). There is no way to automate this in MetaTrader unless you find a broker with tick size symbol parameter equal to your definition of the pip size for all trading instruments.

Related

Limit bars used for an indicator?

Trying to find a way to limit the amount of bars the EA is looking at for the indicator Ichimoku Kinko Hyo, its looking at a silly amount of bars and erroring as not enough memory.
I have tried going into options and setting the max bars on chart and in history to 5000 but its not working.
Is there a way I can code this into the script to only use the last x amount of bars for the indicator?
2021.05.04 11:29:03.007 Not enough memory for 7994468 bars for indicator Ichimoku Kinko Hyo (USDJPY,M1)
the code is just pulling out the value for the senkou A and B lines;
SenkouA = NormalizeDouble(iIchimoku(Symbol(),PERIOD_CURRENT,9,26,52,MODE_SENKOUSPANA,0),_Digits); //value of senkouspanA at current candle
and same again but for span B
Yeah sure, just starting off really, trying too get it to store the value of the top and bottom of the sumo cloud before I move onto the next bits.
It works fine on strategy tester, but when I put it on a live chart it comes up with the error above, I assumed its because on strategy tester it only has the last bars that have been played, but on a live chart it has all the brokers history right? :
double SenkouA;
double SenkouB;
double Kumo_top;
double Kumo_btm;
void OnTick()
{
SenkouA = NormalizeDouble(iIchimoku(Symbol(),PERIOD_CURRENT,9,26,52,MODE_SENKOUSPANA,0),_Digits); //value of senkouspanA at current candle
SenkouB = NormalizeDouble(iIchimoku(Symbol(),PERIOD_CURRENT,9,26,52,MODE_SENKOUSPANB,0),_Digits); //value of senkouspanB at current candle
Kumo_top = MathMax(SenkouA,SenkouB);
Kumo_btm = MathMin(SenkouA,SenkouB);
Comment ("SenkouA = " + SenkouA + "\n" +
"SenkouB = " + SenkouB)
}
Try the following code (note this is an EA and should be in the Experts folder).
//+------------------------------------------------------------------+
//| test.mq4 |
//| Copyright 2021, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
double SenkouA=iIchimoku(NULL,0,9,26,52,MODE_SENKOUSPANA,0);
double SenkouB=iIchimoku(NULL,0,9,26,52,MODE_SENKOUSPANB,0);
double Kumo_top=MathMax(SenkouA,SenkouB);
double Kumo_btm=MathMin(SenkouA,SenkouB);
Comment ("SenkouA = "+DoubleToStr(SenkouA,Digits)+"\n"+"SenkouB = "+DoubleToStr(SenkouB,Digits));
//---
}

Why doesn't the WindowPriceOnDrop() function serve as a store of price in my code?

I've been trading with grid orders for some time now, but just realized there is a WindowPriceOnDropped() function that I'd like to incorporate.
My standard order placement is written like this. Here is sample code for 5 orders spaced 5 pips apart, all micro lots, with 50 pip stops and 100 pip take profits. The first order appears close to market, just 1 pip down, and the rest follow:
int start()
{
int ticket;
double point;
//----
point=MarketInfo(Symbol(),MODE_POINT);
//----
ticket=OrderSend(Symbol(),OP_BUYLIMIT,0.01,Ask-100*point,0,Ask-600*point,Ask+900*point,"[5] 1k, 1 pip down");
ticket=OrderSend(Symbol(),OP_BUYLIMIT,0.01,Ask-150*point,0,Ask-650*point,Ask+850*point,"[5] 1k, 1 pip down");
ticket=OrderSend(Symbol(),OP_BUYLIMIT,0.01,Ask-200*point,0,Ask-700*point,Ask+800*point,"[5] 1k, 1 pip down");
ticket=OrderSend(Symbol(),OP_BUYLIMIT,0.01,Ask-250*point,0,Ask-750*point,Ask+750*point,"[5] 1k, 1 pip down");
ticket=OrderSend(Symbol(),OP_BUYLIMIT,0.01,Ask-300*point,0,Ask-800*point,Ask+700*point,"[5] 1k, 1 pip down");
//----
return(0);
}
//+------------------------------------------------------------------+
I'm testing WindowPriceOnDropped(), like this:
#include <stdlib.mqh>
#include <WinUser32.mqh>
int start()
{
int ticket;
double point;
double Price = WindowPriceOnDropped();
//----
point=MarketInfo(Symbol(),MODE_POINT);
//----
ticket=OrderSend(Symbol(),OP_BUYLIMIT,0.01,Price*point,0,Price-500*point,Price+1000*point, "[5] 1k test");
//----
return(0);
}
//+------------------------------------------------------------------+
However, the order doesn't appear at all. Am I missing something? The only thing I've changed is "Price", which ought to store the point value on drop due to the WindowPriceOnDropped() function, as opposed to Ask minus point value. Why can't I simply substitute the variable for "Ask" if the logic remains the same?
Thank you.
WindowPriceOnDropped() returns a normalized value of the price, you can normalize again with NormalizeDouble(double, _Digits). So instead of Price*point use just Price or its normalized value.

Can't calculate the right Volume RSI in MQL4 with a functioning Pine-Script Example

I want to "translate" a Pine-Script to MQL4 but I get the wrong output in MQL4 compared to the Pine-Script in Trading-view.
I wrote the Indicator in Pine-Script since it seems fairly easy to do so.
After I got the result that I was looking for I shortened the Pine-Script.
Here the working Pine-Script:
// Pinescript - whole Code to recreate the Indicator
study( "Volume RSI", shorttitle = "VoRSI" )
periode = input( 3, title = "Periode", minval = 1 )
VoRSI = rsi( volume, periode )
plot( VoRSI, color = #000000, linewidth = 2 )
Now I want to translate that code to MQL4 but I keep getting different outputs.
Here is the MQL4 code I wrote so far:
// MQL4 Code
input int InpRSIPeriod = 3; // RSI Period
double sumn = 0.0;
double sump = 0.0;
double VoRSI = 0.0;
int i = 0;
void OnTick() {
for ( i; i < InpRSIPeriod; i++ ) {
// Check if the Volume is buy or sell
double close = iClose( Symbol(), 0, i );
double old_close = iClose( Symbol(), 0, i + 1 );
if ( close - old_close < 0 )
{
// If the Volume is positive, add it up to the positive sum "sump"
sump = sump + iVolume( Symbol(), 0, i + 1 );
}
else
{
// If the Volume is negative, add it up to the negative sum "sumn"
sumn = sumn + iVolume( Symbol(), 0, i + 1 );
}
}
// Get the MA of the sump and sumn for the Input Period
double Volume_p = sump / InpRSIPeriod;
double Volume_n = sumn / InpRSIPeriod;
// Calculate the RSI for the Volume
VoRSI = 100 - 100 / ( 1 + Volume_p / Volume_n );
// Print Volume RSI for comparison with Tradingview
Print( VoRSI );
// Reset the Variables for the next "OnTick" Event
i = 0;
sumn = 0;
sump = 0;
}
I already checked if the Period, Symbol and timeframe are the same and also have a Screenshoot of the different outputs.
I already tried to follow the function-explanations in the pine-script for the rsi, max, rma and sma function but I cant get any results that seem to be halfway running.
I expect to translate the Pine-Script into MQL4.
I do not want to draw the whole Volume RSI as a Indicator in the Chart.
I just want to calculate the value of the Volume RSI of the last whole periode (when new candel opens) to check if it reaches higher than 80.
After that I want to check when it comes back below 80 again and use that as a threshold wether a trade should be opened or not.
I want a simple function that gets the Period as an input and takes the current pair and Timeframe to return the desired value between 0 and 100.
Up to now my translation persists to provide the wrong output value.
What am I missing in the Calculation? Can someone tell me what is the right way to calculate my Tradingview-Indicator with MQL4?
Q : Can someone tell me what is the right way to calculate my Tradingview-Indicator with MQL4?
Your main miss of the target is in putting the code into a wrong type of MQL4-code. MetaTrader Terminal can place an indicator via a Custom Indicator-type of MQL4-code.
There you have to declare so called IndicatorBuffer(s), that contain pre-computed values of the said indicator and these buffers are separately mapped onto indicator-lines ( depending on the type of the GUI-presentation style - lines, area-between-lines, etc ).
In case you insist on having a Custom-Indicator-less indicator, which is pretty legal and needed in some use-cases, than you need to implement you own "mechanisation" of drawing lines into a separate sub-window of the GUI in the Expert-Advisor-code, where you will manage all the settings and plotting "manually" as you wish, segment by segment ( we use this for many reasons during prototyping, so as to avoid all the Custom-Indicator dependencies and calling-interface gritty-nitties during the complex trading exosystem integration - so pretty well sure about doability and performance benefits & costs of going this way ).
The decision is yours, MQL4 can do it either way.
Q : What am I missing in the Calculation?
BONUS PART : A hidden gem for improving The Performance ...
In either way of going via Custom-Indicator-type-of-MQL4-code or an Expert-Advisor-type-of-MQL4-code a decision it is possible to avoid a per-QUOTE-arrival re-calculation of the whole "depth" of the RSI. There is a frozen-part and a one, hot-end of the indicator line and performance-wise it is more than wise to keep static records of "old" and frozen data and just update the "live"-hot-end of the indicator-line. That saves a lot of the response-latency your GUI consumes from any real-time response-loop...

1 000 000 000 000 000 000 th fibonacci number

The problem is Get Under 1,000,000,000,000,000,000th fibonacci number%1,000,000
#include <iostream>
#define fibo(a,b) {long long c=b;b=a;a=(b+c)%1000000;}
using namespace std;
int main(){
long long a=1,b=0; //two num
long long pa,pb,n,k,arr[2][1000]; //last two num,input,input<=2^k
cin>>n;
arr[0][0]=n/2;arr[1][0]=n%2;
for(unsigned long long i=1;n>3;i++){
arr[0][i]=arr[0][i-1]/2;
arr[1][i]=arr[0][i-1]%2;
if(arr[0][i]==1){
k=i;
break;
}
}
if(n<=3){ //special occasions
switch(n){
case 0:cout<<"0"<<endl;break;
case 3:cout<<"2"<<endl;break;
default:cout<<"1"<<endl;
}
return 0;
}
while(k>=0){ //calc
pa=a;pb=b;
a=((pa+pb*2)*pa)%1000000; //F(2n)=(F(n)+F(n-1)*2)*F(n)
b=(pa*pa+pb*pb)%1000000; //F(2n-1)=F(n)^2+F(n-1)^2
if(arr[1][k--]==1){fibo(a,b);} //F(n+1)=F(n)+F(n-1)
}
cout<<a<<endl;
return 0;
}
when is it wrong?
And why is it wrong?
I can't find different occasion.
An alternative approach you could consider using here is the fact that there are only 1,000,000 possible remainders for Fibonacci numbers, so if you were to compute the first 1,000,001 Fibonacci numbers, at some point you would find that the numbers would start to go in a cycle. So consider the following approach:
Compute the first 1,000,001 Fibonacci numbers.
The numbers will eventually enter a cycle. Determine how many steps k are needed to enter the cycle and how long l the cycle is.
The 1,000,000,000,000,000,000th Fibonacci number, mod 1,000,000, can be found by determining what position the 1,000,000,000,000,000,000th Fibonacci number would end up in the cycle, which is the ((1,000,000,000,000,000,000 - k) % l)th position. So look at that position and output the entry there.

How two UInt8 variables are added in iOS Swift?

Say there are two variables:
let number1 : UInt8 = 100;
let number2 : UInt8 = 100;
You add and print them
print(number1 + number2) //This prints 200
Now define one more
let number3 : UInt8 = 200;
And try to add now
print(number1 + number3) // Throws execution was interrupted
I understand that the sum of number1 and number3 would be out of range of UInt8 but explicit casting also does not help, for example following line also gives the same error:
print(UInt8(number1 + number3)) // Throws execution was interrupted
The way I found was to do the following:
print(Int(number1) + Int(number3))
Is there a better way of adding UInt8 number when their sum goes out of range?
Girish K Gupta,
UInt8 has max range 0 to 255. Which you can check using UInt8.min and UInt8.max. Basically 0 to 2 power 8.
Issue with print(number1 + number3) will return 300. 300 is greater then 255 hence crash.
When you add two UInt8 result will be by default casted to UInt8 hence the crash
Finally when you Int(number1) + Int(number3) you are forcefully casting number1 and number3 to Int.
When you use Int, range of its value depends on the platform on which you are running it either 32 bit or 64 bit. for example its range can be -2,147,483,648 to 2,147,483,647 for 32 bit.
When you add Int to Int result will be typecasted to Int. And believe me 300 is way inside the range :)
As per your question is there a better way to do it :)
Apple's docs clearly specifies and instructs to use Int rather then UInt8 or UInt32 or even UInt64 until and unless using UInt8, UInt32 or UInt64 is absolutely essential.
Here is the quote from apple's doc :)
“Use UInt only when you specifically need an unsigned integer type
with the same size as the platform’s native word size. If this is not
the case, Int is preferred, even when the values to be stored are
known to be non-negative. A consistent use of Int for integer values
aids code interoperability, avoids the need to convert between
different number types, and matches integer type inference,”
Excerpt From: Apple Inc. “The Swift Programming Language (Swift 2.2).”
iBooks. https://itun.es/in/jEUH0.l
So best thing for you to do :) follow apples instruction :) Change the number1,number2 and number3 to Int :) Problem solved :)
Hence no crash :)
As you've said casting both UInt8 variables to Int overrides the default exception on overflow as the resulting Int now has room to fit the sum.
To avoid casting the variables for every operation we would like to overload the operator like this:
func + (left: UInt8, right: UInt8) -> Int {
return Int(left) + Int(right)
}
However this will give us a compiler error as the + operator is already defined for adding two UInt8's.
What we could do instead is to define a custom operator, say ^+ to mean addition of two UInt8's but add them as Int's like so:
infix operator ^+ { associativity left precedence 140 }
func ^+ (left: UInt8, right: UInt8) -> Int {
return Int(left) + Int(right)
}
Then we can use it in our algorithms:
print(number1 ^+ number3) // Prints 300
If you however want the result to just overflow you can use the overflow operators from the standard library:
print(number1 &+ number3) // Prints 44

Resources