i write an expert in mql4.and i want to place an order(BuyStop Order) everyday at exactly everyday opening.
i write the following codes but the expert does not work.please help me
// y means yesterday
double yHigh=iHigh(Symbol(),PERIOD_D1,1);
double yLow=iLow(Symbol(),PERIOD_D1,1);
double yOpen=iOpen(Symbol(),PERIOD_D1,1);
double yClose=iClose(Symbol(),PERIOD_D1,1);
double yRange=yHigh-yLow;
double P=NormalizeDouble(((yHigh+yLow+yClose)/3),5);
double R3=NormalizeDouble((P+yRange*1.000),5) ;
double R2=NormalizeDouble((P+yRange*0.618),5) ;
double R1=NormalizeDouble((P+yRange*0.382),5) ;
double S1=NormalizeDouble((P-yRange*0.382),5) ;
double S2=NormalizeDouble((P-yRange*0.618),5) ;
double S3=NormalizeDouble((P-yRange*1.000),5) ;
void OnTick()
{
if (iVolume(Symbol(),PERIOD_D1,0)<=1)
int buyTicket=OrderSend(Symbol(),OP_BUYSTOP,0.01,P,3,S1,R1,"MyBuyPosition",7777,0,clrGreen);
{
// P and R1 and S1 are pivot points and calculated at the top
this expert calculates daily Pivot points and place a buystop order at exactly starting the new day.(exactly at starting daily candle)
why this Expert does not work? :(
i tried more and more.but it does not work.i think there is a problem with line below:
if (iVolume(Symbol(),PERIOD_D1,0)<=1)
is there the other way to show starting new day instead of this code line??
Using iVolume to determine a new day would be very unreliable. Instead simply use iTime. Try the following:
datetime currentDay;
void OnTick()
{
if(currentDay!=iTime(NULL, PERIOD_D1,0))
{
int buyTicket=OrderSend(Symbol(),OP_BUYSTOP,0.01,P,3,S1,R1,"MyBuyPosition",7777,0,clrGreen);
currentDay=iTime(NULL, PERIOD_D1, 0);
}
}
Related
#property strict
int ticket;
void OnTick()
{
double AccountBal;
double MAfast = iMA(_Symbol,PERIOD_CURRENT,20,0,MODE_EMA,PRICE_CLOSE,0);
double MAslow = iMA(_Symbol,PERIOD_CURRENT,30,0,MODE_EMA,PRICE_CLOSE,0);
AccountBal = AccountBalance()/10000;
double Force = iForce(_Symbol,PERIOD_CURRENT,13,MODE_SMA,PRICE_CLOSE,0);
double rsi = iRSI(_Symbol,PERIOD_CURRENT,7,PRICE_CLOSE,0);
if((rsi> 70)&&(OrdersTotal()==0)&&(MAfast>MAslow)){
ticket = OrderSend(_Symbol,OP_BUY,AccountBal,Ask,10,Ask-0.007,Ask+0.007,"This iS Buy",33,0,clrBlue);
}
if((rsi <30)&&(OrdersTotal()==0)&&(MAslow>MAfast)){
ticket = OrderSend(_Symbol,OP_SELL,AccountBal,Bid,10,Bid+0.007,Bid-0.007,"This is a Sell",33,0,clrRed);
}
}
The code works and everything is great but when a order is open like a buy order, even if the the conditions are true for sell order it wont place the order until the open one hits take profit or stop loss, the Orders Total function is screwing me over is there anyway I can replace it?
Unfortunately I am not able to post the code I am debugging as it is not mine and I am bound not to show it... BUT I will describe it as detailed as possible.
There are 4 strategies base on 4 indicators, custom, and not-custom ones. So basically instead of 4 different EAs running in 4 different charts with the same 4 indicators each... The client asked me to optimise them by putting them all in one to run 4 into 1 EAs in the same chart.
EVERYTHING is the same. They are tested as well that they are the same. They open the same trades, on the same moments. Nothing is changed 100%. The only thing I did (for this part of the debugging, because obviously I had a lot more to do before that) is to copy functions and code. And I seperated all different strategies with an "if" as input
input bool strategy1enabled = true; etc... so he/she can disable/enable individual strategies if wanted.
everything works BUT....
All but 1 strategies, does not show the Comment on the trades.
All 4 use the same Buy/Sell/CloseOrder functions so I just input the values to keep the code shorter.
//---
bool OrdClose (int ticket_number, double lt, int slp)
{
return OrderClose(ticket_number,lt,iClose(NULL,0,0),slp,clrViolet);
}
//---
int Buy(double lt, int slp, int slss, int tpft, string cmt, int mgc)
{
return OrderSend(NULL,OP_BUY,lt,Ask,slp,Ask-slss*Point,Ask+tpft*Point,cmt,mgc,0,clrDarkBlue);
}
//---
int Sell(double lt, int slp, int slss, int tpft, string cmt, int mgc)
{
return OrderSend(NULL,OP_SELL,lt,Bid,slp,Bid+slss*Point,Bid-tpft*Point,cmt,mgc,0,clrDarkRed);
}
1 strategy just refuses to put comment. Any ideas why? When used seperated WITH THE SAME CODE and the EXACT SAME functions... comment shows...
EDIT:
2021.05.04 18:30:48.670 The_Big_Holla_v1_8_EA CADJPY,H1: open #85710545 buy 0.06 CADJPY at 88.755 sl: 88.655 tp: 88.955 ok
2021.05.04 18:30:48.462 The_Big_Holla_v1_8_EA CADJPY,H1: Holla v4.9 || GreedInjectionMode
2021.05.04 18:30:48.462 The_Big_Holla_v1_8_EA CADJPY,H1: Holla v4.9 || GreedInjectionMode
Comment is passed properly and checked before being passed to function and before OrderSend within function:
The function:
int Sell(double lt, int slp, int slss, int tpft, string cmt, int mgc)
{
Print(cmt);
return OrderSend(NULL,OP_SELL,lt,Bid,slp,Bid+slss*Point,Bidtpft*Point,cmt,mgc,0,clrDarkRed);
}
How the function is called:
Print(EACommentInj);
ticket_val_inj = Buy(lotsizeInj,slippageInj,stoplossInj,takeprofitInj,EACommentInj,MagicInj);
This is how it is initialised and it NEVER changes. It is mentioned only where it is passed. Where I showed you above.
const string EACommentInjGreed = "Holla v4.9 || GreedInjectionMode Greed Mode";
Although this is undocumented, the "string comment=NULL" parameter of the trade function OrderSend() in MQL4 is limited to 31 characters. If this limit is exceeded then the string is rejected as a whole and treated as NULL.
In your code, just before the OrderSend() function, add the following line:
cmt=StringSubstr(cmt,0,31);
I store various formulas in Postgres and I want to use those formulas in my code. It would look something like this:
var amount = 100;
var formula = '5/105'; // normally something I would fetch from Postgres
var total = amount * formula; // should return 4.76
Is there a way to evaluate the string in this manner?
As far as I'm aware, there isn't a formula solver package developed for Dart yet. (If one exists or gets created after this post, we can edit it into the answer.)
EDIT: Mattia in the comments points out the math_expressions package, which looks pretty robust and easy to use.
There is a way to execute arbitrary Dart code as a string, but it has several problems. A] It's very roundabout and convoluted; B] it becomes a massive security issue; and C] it only works if the Dart is compiled in JIT mode (so in Flutter this means it will only work in debug builds, not release builds).
So the answer is that unfortunately, you will have to implement it yourself. The good news is that, for simple 4-function arithmetic, this is pretty straight-forward, and you can follow a tutorial on writing a calculator app like this one to see how it's done.
Of course, if all your formulas only contain two terms with an operator between them like in your example snippet, it becomes even easier. You can do the whole thing in just a few lines of code:
void main() {
final amount = 100;
final formula = '5/105';
final pattern = RegExp(r'(\d+)([\/+*-])(\d+)');
final match = pattern.firstMatch(formula);
final value = process(num.parse(match[1]), match[2], num.parse(match[3]));
final total = amount * value;
print(total); // Prints: 4.761904761904762
}
num process(num a, String operator, num b) {
switch (operator) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
}
throw ArgumentError(operator);
}
There are a few packages that can be used to accomplish this:
pub.dev/packages/function_tree
pub.dev/packages/math_expressions
pub.dev/packages/expressions
I used function_tree as follows:
double amount = 100.55;
String formula = '5/105*.5'; // From Postgres
final tax = amount * formula.interpret();
I haven't tried it, but using math_expressions it should look like this:
double amount = 100.55;
String formula = '5/105*.5'; // From Postgres
Parser p = Parser();
// Context is used to evaluate variables, can be empty in this case.
ContextModel cm = ContextModel();
Expression exp = p.parse(formula) * p.parse(amount.toString());
// or..
//Expression exp = p.parse(formula) * Number(amount);
double result = exp.evaluate(EvaluationType.REAL, cm);
// Result: 2.394047619047619
print('Result: ${result}');
Thanks to fkleon for the math_expressions help.
I have an EA with closes a trade on button click
//void CloseCurrentTrade(). It's called after successfull OrderSelect
int orderType = OrderType();
double price;
if (orderType == OP_BUY)
price = return MarketInfo(OrderSymbol(), MODE_BID);
else if (orderType == OP_SELL)
price = return MarketInfo(OrderSymbol(), MODE_ASK);
else
return;
int slippage = 20;
bool closed = OrderClose(OrderTicket(), OrderLots(), price, slippage);
if (closed)
return;
int lastError = GetLastError();
Sometimes it closes the trade and sometimes it returns error #129 (Invalid price). I can't figure out why. Most of the cases people just misuse bid/ask or don't have enouth slippage. I've try to use slippage up to 200, still the same error. Some EA's just try to close it several times (and it looks like a hack for me), but it does not help as well. There are some mentions that you need to call RefreshRates() before bid/ask, but documentaion says that you don't need to do that for MarketInfo.
I've run out of ideas what it could be. Why it can happen and how to avoid that? I'm testing it on FXCM Demo (if it is the case).
First make sure that you've selected the order properly, and try to use OrderClosePrice where possible(this will eliminate the need for checking the OP_SELL/OP_BUY)
//+------------------------------------------------------------------+
//| Close the latest order for this current symbol |
//+------------------------------------------------------------------+
void CloseCurrentTrade()
{
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
if(OrderSymbol()!=Symbol()) continue;
if(OrderMagicNumber()!=MagicNum) continue; // if there is no magic number set, then no need for this(manual orders)
if(OrderType()>OP_SELL) continue;
if(!OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage))
Print("Error in Closing the Order, Error : ",ErrorDescription(GetLastError()));
break; // assuming you want to close the latest trade only, exit the order closing loop
}
}
Also note that your broker might have restrictions on how far the closing price must be from the Order Opened price and other levels(sl/tp), in order to close an order. Refer here
Print and compare Ask/Bid && price when closed!=true. Beware that MarketInfo mode data is stored at Ask/Bid predefined variables already, so you can eliminate that if you OrderSelect in current symbol.
Does anyone know if it is possible to store the series of value of an indicator, over, for example 1 year, or of a boolean function calculated in an EA?
I would like tho store the value of a particular function calculated on the difference between two different EMA that I defined into an EA.
I need to store the value of this double function, calculated in my EA over few years (say from 2015 to 2017) and print it in some output file (.txt or some other formats)
int s15_60;
double B_M15_H1(int i) {
if (i>=0 && i<4 ) s15_60=0;
else if (i>=4 && i<8 ) s15_60=1;
else if (i>=8 && i<12 ) s15_60=2;
else if (i>=12 && i<16 ) s15_60=3;
else if (i>=16 && i<20 ) s15_60=4;
return NormalizeDouble(MathAbs(M15(i) - H1(s15_60)),Digits);
where M15 is a simple EMA calculated in the M15 timeframe, and H1 is the same EMA calculated in the H1 timeframe, and the double function is the distance between this two indicators calculated in M15 time steps.
My goal is to store this value in a output file for doing some statistical studies about this function.
EDIT:
This code works for my purpose:
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//--- show the window of input parameters when launching the script
#property script_show_inputs
//--- parameters for writing data to file
input string InpFileName="BOX.csv"; // File name
input string InpDirectoryName="Data"; // Folder name
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
double H1 (int shift) {double val = iCustom(NULL,PERIOD_H1, "my_funct",100,2.0,30.0,2.0,2.0,0,1,0,shift); return(val);}
double H4 (int shift) {double val = iCustom(NULL,PERIOD_H4, "my_funct",100,2.0,30.0,2.0,2.0,0,1,0,shift); return(val);}
int s60_240;
double B_H1_H4(int i) {
if (i>=0 && i<4 ) s60_240=0;
else if (i>=4 && i<8 ) s60_240=1;
else if (i>=8 && i<12 ) s60_240=2;
else if (i>=12 && i<16 ) s60_240=3;
else if (i>=16 && i<20 ) s60_240=4;
return NormalizeDouble( 10000*MathAbs( H1(i) - H4(s60_240) ) , Digits);
}
void OnStart()
{
double box_buff[]; // array of indicator values
datetime date_buff[]; // array of indicator dates
//--- copying the time from last 1000 bars
int copied=CopyTime(NULL,PERIOD_H1,0,1000,date_buff);
ArraySetAsSeries(date_buff,true);
//--- prepare box_buff array
ArrayResize(box_buff,copied);
//--- copy the values of main line of the iCustom indicator
for(int i=0;i<copied;i++)
{
box_buff[i]=B_H1_H4(i);
}
//--- open the file for writing the indicator values (if the file is absent, it will be created automatically)
ResetLastError();
int file_handle=FileOpen(InpDirectoryName+"//"+InpFileName,FILE_READ|FILE_WRITE|FILE_CSV);
if(file_handle!=INVALID_HANDLE)
{
PrintFormat("%s file is available for writing",InpFileName);
PrintFormat("File path: %s\\Files\\",TerminalInfoString(TERMINAL_DATA_PATH));
//--- first, write the number of signals
FileWrite(file_handle,copied);
//--- write the time and values of signals to the file
for(int i=0;i<copied;i++)
FileWrite(file_handle,date_buff[i],box_buff[i]);
//--- close the file
FileClose(file_handle);
PrintFormat("Data is written, %s file is closed",InpFileName);
}
else
PrintFormat("Failed to open %s file, Error code = %d",InpFileName,GetLastError());
}
Please provide your MCVE-code to see what you need. How would you like to store data and why you might need it? Indicator data is already stored in a buffer so simply call it using iCustom(). If you want to optimize your EA and indicator take much time to load and compute buffers - yes it is possible to compute indicator buffers once then write them into a file or DB and get before new optimization starts, in such case use CArrayObj or CArrayDouble as a dynamic array for storing large arrays