Hotkeys for Buy and Sell for MT5

 
Can somebody make  script or indicator to buy and sell at market price with a user-defined key of the keyboard ?
 
Enaud:
Can somebody make  script or indicator to buy and sell at market price with a user-defined key of the keyboard ?

Hello , consult this expert advisor code . Why an expert advisor ? indicators cannot trade , the script can be used and setup with a hotkey by default like this :

So if you want to create a buy script and set it up to fire with this method its very easy .

Now , in case you want to go the route of the expert advisor , which will also allow you to have inputs per the lot and stop levels etc later on you can consult this code :

#property copyright "Go To Discussion"
#property link      "https://www.mql5.com/en/forum/443162"
#property version   "1.00"
/*first we need a way to identify our key , for now we won't do any combos
  the chart events function provides a long a double and a string parameter
  so we create our own structure that contains those things . */
struct key_event_codes{
long l;//the long
double d;//the double
string s;//the string
       //default values once we create a key_event_codes object
       key_event_codes(void){l=0;d=0.0;s=NULL;}
       //we will need a way to set it 
  void set(long _l,double _d,string _s){
       l=_l;
       d=_d;
       s=_s;
       }    
       //and a way to detect them , a function that says "true" if this is our key 
  bool is_pressed(long _l,double _d,string _s){
       if(s!=NULL){
       if(l==_l&&d==_d&&s==_s){return(true);}
       }else{Print("You have not set the key event codes");}
       return(false);
       } 
       //we'll also need to save a key code so that the user does not constantly needs to set it up
  void save(int file_handle){
       FileWriteLong(file_handle,l);
       FileWriteDouble(file_handle,d);
       //length 
         ushort t[];
         int total_characters=StringToShortArray(s,t,0,-1);
         FileWriteInteger(file_handle,total_characters,INT_VALUE);
         for(int i=0;i<total_characters;i++){
            FileWriteInteger(file_handle,t[i],SHORT_VALUE);
            }
       }
       //and a loading function
  void load(int file_handle){
       l=(long)FileReadLong(file_handle);
       d=(double)FileReadDouble(file_handle);
       //length of string 
         ushort t[];
         int total_characters=(int)FileReadInteger(file_handle,INT_VALUE);
         if(total_characters>0){
         ArrayResize(t,total_characters,0);
         for(int i=0;i<total_characters;i++){
            t[i]=(ushort)FileReadInteger(file_handle,SHORT_VALUE);
            }
         s=ShortArrayToString(t,0,-1);
         }
       }
};
//done , what do we need now ? a key code for buying and one for selling 
key_event_codes BUY_KEY,SELL_KEY;
//cool now what ?
/*
in order to make the users life as easy as possible we will need to load any previous configuration of the buttons.
This is a system that does not depend on magic numbers or which symbol its running on as the user would probably
like the same 2 buttons for trading on all charts , so we have one folder and one filename to save and load our config.

*/
string config="KeyboardTrader\\config.txt";
//so this is how we save the config 
  void save_config(string filename){
       //if the file exists we delete it
       if(FileIsExist(filename)){FileDelete(filename);}
       //we create a new file for writing 
       int f=FileOpen(filename,FILE_WRITE|FILE_BIN);
       if(f!=INVALID_HANDLE){
         //we save the buy key
           BUY_KEY.save(f);//we pass the file handle f :)
         //we save the sell key
           SELL_KEY.save(f);//beautiful right?
         FileClose(f);
         }
       //and that is it saved 
       }
//we also need the load so 
  void load_config(string filename){
      //does the file exist ?
      if(FileIsExist(filename)){
      //open it if it does
        int f=FileOpen(filename,FILE_READ|FILE_BIN);
        if(f!=INVALID_HANDLE){
        Print("File exists");
        //we load the buy key 
          BUY_KEY.load(f);//we pass the file handle f
        //we load the save key
          SELL_KEY.load(f);
        FileClose(f);
        }
      }
      }
//all functions are in now what ?
/*
we need to give the user a way to setup their keys 
So , we'll have a pseudo panel with 2 buttons 
When one button is pressed it indicates we are recording
     the next keystroke and storing it 
If the keys are setup we have the buttons be green otherwise gray
So we need 2 boolean switches to indicate if we are recording but or sell key
If we were working with a list of keys we would use one boolean and an index.
So 
*/
bool RecordingBuy=false,RecordingSell=false;

int OnInit()
  {
//---
  //program starts : we load the buttons 
    load_config(config);
    RecordingBuy=false;
    RecordingSell=false;
    ObjectsDeleteAll(ChartID(),"KEYTRADER_");    
  //then we design an ugly panel real quick
    design_panel();
//---
   return(INIT_SUCCEEDED);
  }
//design a panel
  void design_panel(){
    //background 
      string name="KEYTRADER_BACK";
      ObjectCreate(ChartID(),name,OBJ_RECTANGLE_LABEL,0,0,0);
      ObjectSetInteger(ChartID(),name,OBJPROP_XSIZE,60);
      ObjectSetInteger(ChartID(),name,OBJPROP_YSIZE,50);
      ObjectSetInteger(ChartID(),name,OBJPROP_XDISTANCE,10);
      ObjectSetInteger(ChartID(),name,OBJPROP_YDISTANCE,10);
    //buy setup button 
      name="KEYTRADER_BUY";
      ObjectCreate(ChartID(),name,OBJ_BUTTON,0,0,0);
      ObjectSetInteger(ChartID(),name,OBJPROP_XSIZE,40);
      ObjectSetInteger(ChartID(),name,OBJPROP_YSIZE,20);
      ObjectSetInteger(ChartID(),name,OBJPROP_XDISTANCE,20);
      ObjectSetInteger(ChartID(),name,OBJPROP_YDISTANCE,15);
      ObjectSetString(ChartID(),name,OBJPROP_TEXT,"BUY");
    //sell setup button
      name="KEYTRADER_SELL";
      ObjectCreate(ChartID(),name,OBJ_BUTTON,0,0,0);
      ObjectSetInteger(ChartID(),name,OBJPROP_XSIZE,40);
      ObjectSetInteger(ChartID(),name,OBJPROP_YSIZE,20);
      ObjectSetInteger(ChartID(),name,OBJPROP_XDISTANCE,20);
      ObjectSetInteger(ChartID(),name,OBJPROP_YDISTANCE,35);
      ObjectSetString(ChartID(),name,OBJPROP_TEXT,"SELL");      
    //and you see the problem here right ? 
    //we need a function to color the buttons based on whether or not they have a configuration    
      display_config();//explanation follows   
  }
//function for displaying existing config
  void display_config(){
  //if buy key has a config 
    if(BUY_KEY.l!=0&&BUY_KEY.d!=0.0&&BUY_KEY.s!=NULL){
    ObjectSetInteger(ChartID(),"KEYTRADER_BUY",OBJPROP_BGCOLOR,clrGreen);
    ObjectSetInteger(ChartID(),"KEYTRADER_BUY",OBJPROP_BORDER_COLOR,clrDarkGreen);
    ObjectSetInteger(ChartID(),"KEYTRADER_BUY",OBJPROP_COLOR,clrWhite);
    ObjectSetInteger(ChartID(),"KEYTRADER_BUY",OBJPROP_STATE,false);
    }else{
    ObjectSetInteger(ChartID(),"KEYTRADER_BUY",OBJPROP_BGCOLOR,clrGray);
    ObjectSetInteger(ChartID(),"KEYTRADER_BUY",OBJPROP_BORDER_COLOR,clrGray);
    ObjectSetInteger(ChartID(),"KEYTRADER_BUY",OBJPROP_COLOR,clrBlack);
    ObjectSetInteger(ChartID(),"KEYTRADER_BUY",OBJPROP_STATE,false);    
    }
  //same for the sell key
    if(SELL_KEY.l!=0&&SELL_KEY.d!=0.0&&SELL_KEY.s!=NULL){
    ObjectSetInteger(ChartID(),"KEYTRADER_SELL",OBJPROP_BGCOLOR,clrGreen);
    ObjectSetInteger(ChartID(),"KEYTRADER_SELL",OBJPROP_BORDER_COLOR,clrDarkGreen);
    ObjectSetInteger(ChartID(),"KEYTRADER_SELL",OBJPROP_COLOR,clrWhite);
    ObjectSetInteger(ChartID(),"KEYTRADER_SELL",OBJPROP_STATE,false);
    }else{
    ObjectSetInteger(ChartID(),"KEYTRADER_SELL",OBJPROP_BGCOLOR,clrGray);
    ObjectSetInteger(ChartID(),"KEYTRADER_SELL",OBJPROP_BORDER_COLOR,clrGray);
    ObjectSetInteger(ChartID(),"KEYTRADER_SELL",OBJPROP_COLOR,clrBlack);
    ObjectSetInteger(ChartID(),"KEYTRADER_SELL",OBJPROP_STATE,false);    
    }  
  ChartRedraw(0);
  }
  //so now we can go back up to the init function and call the config display
  /*
  almost done 
  What we need now is :
  If a click occurs on the setup buttons , enable setup mode and capture the key (and save the config)
  If a keypress occurs outside the setup mode we fire the command (which you will setup)
  So first of all , a key press needs a minimum time to have passed before the next one occurs 
  The keydown event that we'll use is continuous 
  So , we need to ignore it if its the same as before 
  and we need the delay between presses.
  For the delay we will utilize the built in millisecond continuous counter and try and get 
      the distance in milliseconds since the last keypress
  And
  Guess what we'll use for remembering the button we pressed last ... yes the key structure we built so:
  */
  key_event_codes LASTKEY;//so any keystroke is stored here too when it occurs 
  //the last time in the continuous ms counter that we had a keypress (any keypress)
  uint last_key_press=0;
  //and we'll also need to define the minimum accepted ms distance to register a keypress
  long key_press_min_distance_in_ms=300;
  void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam)
    {
    //so let's get down to busssinnness
      //first of all , is a key pressed ? 
        if(id==CHARTEVENT_KEYDOWN)
        {
        //are we allowed to accept that key ?
        //first limit , ms since last press
          /* now the ms counter of the system is a ring counter so when it hits the limit 
             (the limit is UINT_MAX) it goes back to 0
             So , if the time now is before the time in the past it means we have gone through 
             a cycle , its very rare but it happens
             So the following says :
             -if the future is after the past (most common first) set the value as ms_now-ms_then
             -if the future is before the past set the value as ms_now+(UINT_MAX-ms_then)
          */ 
          uint ms=GetTickCount();
          long distance_in_ms=(ms>=last_key_press)?ms-last_key_press:ms+(UINT_MAX-last_key_press);
        //so is the distance higher than the min required ?
          if(distance_in_ms>=key_press_min_distance_in_ms)
            {
            //now , are we recording the buy key ? 
              if(RecordingBuy)
              {
              //pass the buy key 
                BUY_KEY.set(lparam,dparam,sparam);
              //save the config
                save_config(config);
              //disable recording 
                RecordingBuy=false;
              //Reset the screen message (will make sense later)
                Comment("");
              //rebuild the panel 
                design_panel();
              //display config update
                display_config();
              }
            //or are we recoding the sell key ? 
              else if(RecordingSell)
              {
              //pass the sell key 
                SELL_KEY.set(lparam,dparam,sparam);
              //save the config
                save_config(config);  
              //disable recording 
                RecordingSell=false;
              //Reset the screen message (will make sense later)
                Comment("");
              //rebuild the panel 
                design_panel();
              //display config update
                display_config();                       
              }
            //or its a fresh key and we are not recording 
              else{
              //so now we check if we need to execute any commands 
                //buy command - you'll fill in the buy stuff
                  if(BUY_KEY.is_pressed(lparam,dparam,sparam)){
                  Alert("BOUGHT SOME");
                  /*
                  so what did we do here ?
                  The chart event function is telling us what happens via id , lparam , dparam and sparam
                  We have used the 3 last values to identify a specific key press
                  And whenever we see that pattern we fire a command 
                  */
                  }
                //sell command - 
                  else if(SELL_KEY.is_pressed(lparam,dparam,sparam)){
                  Alert("SOLD IT");
                  }
              }
            }
        //update the last keypress time (the last time it was active)
        last_key_press=GetTickCount();
        }
        //that was fun but we are not done yet
        //we need to capture the button pressing (the visible screen buttons with the mouse) to setup the key pressing
        //so
        //if an object on the screen is clicked
        else if(id==CHARTEVENT_OBJECT_CLICK){
        //and it is the buy setup 
          if(sparam=="KEYTRADER_BUY"){
          //enable recording mode 
            RecordingBuy=true;
          //remove the panel 
            ObjectsDeleteAll(ChartID(),"KEYTRADER_");
          //display a message with instructions on the screen 
            Comment("PRESS A KEY TO BECOME THE NEW BUY KEY SHORTCUT");
          }
        //if it is the sell setup 
          else if(sparam=="KEYTRADER_SELL"){
          //enable recording mode 
            RecordingSell=true;
          //remove the panel 
            ObjectsDeleteAll(ChartID(),"KEYTRADER_");
          //display a message with instructions on the screen 
            Comment("PRESS A KEY TO BECOME THE NEW SELL KEY SHORTCUT");
          }        
        }
    }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  ObjectsDeleteAll(ChartID(),"KEYTRADER_");     
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }