The problem is not your English, post all the relevant code or don't expect useful help.
Thanks for the comment. I'll try to post more of the code and hope you guys find it usefull...
This is the function I'm using to send the order ( now I know that there are better ways to check the balance, and I'll fix it later )
/+------------------------------------------------------------------+ //| Places a buy order on the entry price | //+------------------------------------------------------------------+ void send_buy_order() { //--- declare and initialize the trade request and result of trade request MqlTradeRequest trade_request; MqlTradeResult trade_result; MqlTradeTransaction trade_transaction; //--- getting account balance double balance = AccountInfoDouble(ACCOUNT_BALANCE); //--- get proper volume based on the financial volume (from txt file) volume = floor_100(fin_volume/entry_price); if(volume==0.0){ Print("---------------------------------------"); Print("volume == 0.0"); Print("min balance needed > ", DoubleToString(entry_price*100,2)); Print("---------------------------------------"); //--- switching buy_order_sent = true; } //--- checking volume and permission to send order (again) if(volume>0 && buy_order_sent==false){ if(check_trading_balance(chart_symbol,volume)){ //--- zeroing ZeroMemory(trade_request); ZeroMemory(trade_result); //--- filling trade info trade_request.magic = EXPERT_MAGIC; trade_request.action = TRADE_ACTION_PENDING; trade_request.symbol = chart_symbol; trade_request.volume = volume; trade_request.type = ORDER_TYPE_BUY_LIMIT; trade_request.type_filling = ORDER_FILLING_IOC; trade_request.price = entry_price; trade_request.sl = stop_loss; trade_request.stoplimit = stop_loss; trade_request.tp = take_profit; //--- switching buy_order_sent = true; //--- send request if(!OrderSend(trade_request,trade_result)){ // if unable to send request, output error PrintFormat("OrderSend error %d ... symbol=%s volume=%d", GetLastError(),trade_request.symbol,DoubleToString(trade_request.volume)); } } } }
I'm also using this event to save the data from orders in a csv file
//+------------------------------------------------------------------+ //| Handling the trade transaction event | //+------------------------------------------------------------------+ void OnTradeTransaction(const MqlTradeTransaction &trans, const MqlTradeRequest &request, const MqlTradeResult &result) { //--- //--- result of trade request execution ulong lastOrderID =trans.order; ENUM_ORDER_TYPE lastOrderType =trans.order_type; ENUM_ORDER_STATE lastOrderState=trans.order_state; //--- the name of the symbol, for which a transaction was performed string trans_symbol=trans.symbol; //--- date and time variables MqlDateTime struct_date; TimeToStruct(TimeCurrent(),struct_date); string today_date = IntegerToString(struct_date.year) + "-" + IntegerToString(struct_date.mon) + "-" + IntegerToString(struct_date.day); string current_time = IntegerToString(struct_date.hour) + ":" + IntegerToString(struct_date.min) + ":" + IntegerToString(struct_date.sec); //--- type of transaction ENUM_TRADE_TRANSACTION_TYPE trans_type=trans.type; switch(trans.type) { case TRADE_TRANSACTION_POSITION: // position modification { ulong pos_ID=trans.position; PrintFormat("MqlTradeTransaction: Position #%d %s modified: SL=%.5f TP=%.5f", pos_ID,trans_symbol,trans.price_sl,trans.price_tp); } break; case TRADE_TRANSACTION_REQUEST: // sending a trade request PrintFormat("MqlTradeTransaction: TRADE_TRANSACTION_REQUEST"); break; case TRADE_TRANSACTION_DEAL_ADD: // adding a trade { ulong lastDealID =trans.deal; ENUM_DEAL_TYPE lastDealType =trans.deal_type; double lastDealVolume=trans.volume; //--- Trade ID in an external system - a ticket assigned by an exchange string Exchange_ticket=""; if(HistoryDealSelect(lastDealID)) Exchange_ticket=HistoryDealGetString(lastDealID,DEAL_EXTERNAL_ID); if(Exchange_ticket!="") Exchange_ticket=StringFormat("(Exchange deal=%s)",Exchange_ticket); PrintFormat("MqlTradeTransaction: %s deal #%d %s %s %.2f lot %s",EnumToString(trans_type), lastDealID,EnumToString(lastDealType),trans_symbol,lastDealVolume,Exchange_ticket); } break; case TRADE_TRANSACTION_HISTORY_ADD: // adding an order to the history { //--- order ID in an external system - a ticket assigned by an Exchange string Exchange_ticket=""; if(lastOrderState==ORDER_STATE_FILLED) { //--- setting the switch to keep track buy_order_filled=true; if(HistoryOrderSelect(lastOrderID)) Exchange_ticket=HistoryOrderGetString(lastOrderID,ORDER_EXTERNAL_ID); if(Exchange_ticket!="") Exchange_ticket=StringFormat("(Exchange ticket=%s)",Exchange_ticket); } // magic,date,time,symbol,deal,order_state,price,stop_loss,take_profit,volume write_csv(IntegerToString(EXPERT_MAGIC),today_date,current_time,chart_symbol,EnumToString(lastOrderType), EnumToString(lastOrderState),DoubleToString(entry_price),DoubleToString(0.0),DoubleToString(0.0), DoubleToString(volume)); PrintFormat("MqlTradeTransaction: %s order #%d %s %s %s %s",EnumToString(trans_type), lastOrderID,EnumToString(lastOrderType),trans_symbol,EnumToString(lastOrderState),Exchange_ticket); } break; default: // other transactions { //--- order ID in an external system - a ticket assigned by Exchange string Exchange_ticket=""; if(lastOrderState==ORDER_STATE_PLACED) { PrintFormat(">> csv order added - %s | %s <<",DoubleToString(entry_price),DoubleToString(volume)); // magic,date,time,symbol,deal,order_state,price,stop_loss,take_profit,volume write_csv(IntegerToString(EXPERT_MAGIC),today_date,current_time,chart_symbol,EnumToString(lastOrderType), EnumToString(lastOrderState),DoubleToString(entry_price),DoubleToString(0.0),DoubleToString(0.0), DoubleToString(volume)); if(OrderSelect(lastOrderID)) Exchange_ticket=OrderGetString(ORDER_EXTERNAL_ID); if(Exchange_ticket!="") Exchange_ticket=StringFormat("Exchange ticket=%s",Exchange_ticket); } PrintFormat("MqlTradeTransaction: %s order #%d %s %s %s",EnumToString(trans_type), lastOrderID,EnumToString(lastOrderType),EnumToString(lastOrderState),Exchange_ticket); } break; } //--- order ticket ulong orderID_result=result.order; string retcode_result=GetRetcodeID(result.retcode); if(orderID_result!=0) PrintFormat("MqlTradeResult: order #%d retcode=%s ",orderID_result,retcode_result); //--- }
And this is the function I'm using to check if there's a new bar ( I'm using a 1 minute chart to check the price )
//+------------------------------------------------------------------+ //| Returns true if a new bar has appeared for a symbol/period pair | //+------------------------------------------------------------------+ bool isNewBar() { //--- memorize the time of opening of the last bar in the static variable static datetime last_time=0; //--- current time //datetime lastbar_time=SeriesInfoInteger(Symbol(),Period(),SERIES_LASTBAR_DATE); datetime lastbar_time=(datetime)SeriesInfoInteger(chart_symbol,Period(),SERIES_LASTBAR_DATE); //--- if it is the first call of the function if(last_time==0) { //--- set the time and exit last_time=lastbar_time; return(true); // set to true to return the first bar } //--- if the time differs if(last_time!=lastbar_time) { //--- memorize the time and return true last_time=lastbar_time; return(true); } //--- if we passed to this line, then the bar is not new; return false return(false); }
And this is my OnTick()
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- MqlRates rates[]; MqlRates daily_rates[]; // to get the correct open price MqlDateTime bar_time; MqlDateTime today; TimeToStruct(TimeCurrent(), today); // getting today date //--- scanning every new 1min bar if(isNewBar()){ //--- looking at the current candle int copied=CopyRates(chart_symbol,PERIOD_M1,0,1,rates); if(copied<=0) Print("Error copying price data ",GetLastError()); else { // check if the new bar is the first bar of the day TimeToStruct(rates[0].time, bar_time); // getting today date if(bar_time.day_of_year==today.day_of_year){ //--- open price of the day to estimate the entry price if(entry_price==0.0){ //--- looking at the daily candle int copied_daily=CopyRates(chart_symbol,PERIOD_D1,0,1,daily_rates); if(copied_daily<=0) Print("Error copying daily price data ",GetLastError()); else { get_entry_price(daily_rates[0].open); // open price of the day //--- lines for debuggin ObjectsDeleteAll(0); if(!HLineCreate(0,"trigger_line",0,trigger_price,clrGold,STYLE_DASH,1,false,true,true,0)) return; if(!HLineCreate(0,"entry_line",0,entry_price,clrMediumBlue,STYLE_DASH,1,false,true,true,0)) return; if(!HLineCreate(0,"cancel_line",0,cancel_price,clrLightSlateGray,STYLE_DASH,1,false,true,true,0)) return; if(stop_loss!=0.0){ if(!HLineCreate(0,"stop_line",0,stop_loss,clrRed,STYLE_DASH,1,false,true,true,0)) return; } if(take_profit!=0.0){ if(!HLineCreate(0,"take_line",0,take_profit,clrSpringGreen,STYLE_DASH,1,false,true,true,0)) return; } } } else{ //--- checking to send buy order //--- checking symbol to try and avoid errors with EA on multiple charts at the same time if(rates[0].open<=trigger_price && buy_order_sent==false && chart_symbol==Symbol()){ //--- place buy order send_buy_order(); } //--- if the price comes back to the open price, cancel the order if(rates[0].open>=cancel_price && buy_order_sent==true && buy_order_filled==false && order_deleted==false && chart_symbol==Symbol()){ delete_orders(); } //--- checking to send sell order if(TimeCurrent()==StringToTime("16:54:00")) { //--- send sell order if(buy_order_sent==true && buy_order_filled==true && chart_symbol==Symbol()) send_sell_order(); //--- delete buy order if(buy_order_sent==true && buy_order_filled==false && order_deleted==false && chart_symbol==Symbol()) delete_orders(); } } } } }
Thanks again
Thanks for the comment. I'll try to post more of the code and hope you guys find it usefull...
This is the function I'm using to send the order ( now I know that there are better ways to check the balance, and I'll fix it later )
I'm also using this event to save the data from orders in a csv file
And this is the function I'm using to check if there's a new bar ( I'm using a 1 minute chart to check the price )
And this is my OnTick()
Thanks again
if open price - trigger price = 0 will that work? if it works you can further improve from there
Hi roshjardine,
Thanks for the tip. I'll take a look at it.
But my main problem is that MetaTrader is sending orders for every symbol with the EA.
For instance:
- if I have the EA on charts(0), charts(1) and charts(2)
- charts(0) sets the trigger to buy Asset A at 9.50
- EA is sending orders for charts(0), charts(1) and charts(2)
What I'm trying to do is send an order for Asset A only, because the price didn't reach the levels on charts(1) and charts(2).
Hi roshjardine,
Thanks for the tip. I'll take a look at it.
But my main problem is that MetaTrader is sending orders for every symbol with the EA.
For instance:
- if I have the EA on charts(0), charts(1) and charts(2)
- charts(0) sets the trigger to buy Asset A at 9.50
- EA is sending orders for charts(0), charts(1) and charts(2)
What I'm trying to do is send an order for Asset A only, because the price didn't reach the levels on charts(1) and charts(2).
you're explicitly allowing any value that is less than equal to trigger price..so any price below trigger price regardless the charts where the Ea runs will be impacted unless you specify each trigger price for each chart respectively and evaluate from there
On each chart I'm calculating the trigger and the order price with this function
//+------------------------------------------------------------------+ //| Calculates entry, trigger, stop loss and take profit | //+------------------------------------------------------------------+ void get_entry_price(double open_price) { //--- calculating the price of the order entry_price = NormalizeDouble(open_price + (open_price*(percentage/100)),2); //--- calculating the price to trigger the send of the order trigger_price = entry_price + ((open_price-entry_price)/3); //--- price to cancel the order in case the price didnt reach the order cancel_price = open_price; //--- calculating the stop loss if(perc_stop==0.0){stop_loss = 0.0;} else{stop_loss = NormalizeDouble(entry_price + (entry_price*(perc_stop/100)),2);} //--- calculating the take profit if(perc_take==0.0){take_profit=0.0;} else{take_profit = NormalizeDouble(entry_price + (entry_price*(perc_take/100)),2);} //--- for reference Print("open price > ", DoubleToString(open_price)); Print("entry price > ", DoubleToString(entry_price)); Print("trigger_price > ", DoubleToString(trigger_price)); Print("stop_loss > ", DoubleToString(stop_loss)); Print("take_profit > ", DoubleToString(take_profit)); Print("fin_volume > ", DoubleToString(fin_volume)); }
And I am also checking if the rates of the symbol of the chart are below the trigger before I send the buy order
//--- checking to send buy order //--- checking symbol to try and avoid errors with EA on multiple charts at the same time if(rates[0].open<=trigger_price && buy_order_sent==false && chart_symbol==Symbol()){ //--- place buy order send_buy_order(); }
And the variable for the trigger ( and all global variables ) are been initialized outside the OnInit() and "reinitialized" on the OnInit()
int OnInit() { //--- //--- reinitializing global variables to try and fix errors when sending orders // https://www.mql5.com/en/forum/122969 EXPERT_MAGIC = makeMagicNumber(Symbol() + IntegerToString(Period())); entry_price = 0.0; // price of the order percentage = 0.0; // percent the order must be from the opening price perc_stop = 0.0; // percent to calculate the stop_loss perc_take = 0.0; // percent to calculate the take_profit fin_volume = 0.0; // financial volume for the order cancel_price = 0.0; // price to cancel order in case didnt trigger the buy order stop_loss = 0.0; // price for the stop loss take_profit = 0.0; // price for the take profit trigger_price = 0.0; // price to trigger the order volume = 0.0; // order volume buy_order_sent = false; // switch to control if the order has been sent or not buy_order_filled = false; // switch to control if the order has been filled or not sell_order_sent = false; // switch to control if the order has been sent or not sell_order_filled = false; // switch to control if the order has been filled or not order_deleted = false; // switch to control if the order has been deleted chart_symbol = Symbol(); // trying to avoid multiple send orders if(!get_data_from_txt()){ Print(chart_symbol + " not found in price_on_open.txt . Waiting to try again"); Sleep(10000); // 10 sec if(!get_data_from_txt()){ Print(chart_symbol + " not found in price_on_open.txt for the second time. Check the file"); } } else{ Print(chart_symbol + " percentage > " + DoubleToString(percentage)); } PrintFormat("Symbol -> %s | EXPERT_MAGIC -> %s", chart_symbol,IntegerToString(EXPERT_MAGIC)); //--- return(INIT_SUCCEEDED); }
Hi roshjardine,
Thanks for the tip. I'll take a look at it.
But my main problem is that MetaTrader is sending orders for every symbol with the EA.
For instance:
- if I have the EA on charts(0), charts(1) and charts(2)
- charts(0) sets the trigger to buy Asset A at 9.50
- EA is sending orders for charts(0), charts(1) and charts(2)
What I'm trying to do is send an order for Asset A only, because the price didn't reach the levels on charts(1) and charts(2).
It sounds like that your EA is not associated independently to each symbol, but that it evaluates all symbols together. I guess that your focus should be on that.
Hi WindmillMQ,
Thank you for your input and I think this might be the problem.
I'll make some tests today and hope to get back to you with some good news or more information.
Thanks a lot
- www.mql5.com
Doubles are rarely equal. Understand the links in:
The == operand. - MQL4 programming forum #2 2013.06.07
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I developed an EA that places a limit buy order when the asset price reaches a determined price. For instance: if Asset A reaches 10.00, the EA will add a limit buy order at 9.50.
As I'm using this strategy on many assets ( stocks ), I created a simple script to open a new graph for each symbol and apply a template with the EA.
The script to open the charts is working fine and placing the EA on each chart. The problem is when the price of one asset reaches the level and send the order.
The order is been sent for every open asset, each with its own price, even if the other assets haven't reached its own triggers ( the price levels ). Something like this:
The price reached the level on Asset A and sent the buy order at 9.50, but it also is sending orders ( at the same time ) for all other assets ( with its own settings ): Asset A - 9.50 | Asset B - 8.35 | Asset C - 6.48
Here is what I've tryed:
- random Magic Number ( based on this > https://www.mql5.com/en/forum/141280 )
- open the charts with the script, but place the EA manually
- open the charts manually and also place the EA manually
- create a global variable at the begining of the EA to get the chart symbol and compare it with Symbol() before sending the buy order
- reinitializing global variables on the OnInit() after reading this > https://www.mql5.com/en/forum/122969
This is the checking I'm doing to call the function to place the order:
And the build of my MetaTrader 5 is 2450 ( May 2020 )
Thank you all for the help, and sorry for my english.