重映射 MT4 的快捷键像同花顺一样

  1. 需要写指标响应 CHARTEVENT_KEYDOWN 事件
  2. 需要 Autohotkey 重映射快捷键

效果:

  1. </> 切换品种
  2. Ctrl+Left/Ctrl+Right 快速移动图表
  3. Up/Down 放大缩小图表
  4. 0 键 还原图表坐标轴缩放
  5. P 键 隐藏/显示坐标轴
  6. M 月线 W 周线 D 日线

MT4 指标

Symbol changer-hotkeys.mq4

// Symbol changer-hotkeys 1.0.0

#property indicator_chart_window
#property indicator_buffers 0
#property strict

extern int currentIndex = 0;
extern string  Symbols = "US30;NAS100;SPX500;US2000;GER30;UK100;FRA40;*;USDOLLAR;USDJPY;EURUSD;GBPUSD;AUDUSD;USDCNH;*;XAUUSD;XAGUSD;*;USOil;UKOil;*;BTCUSD;ETHUSD"; // List of symbols (separated by ";"
extern string  str1 = "";                        // and "*" new line)
extern string  prefix        = "";               // prefix Symbol
extern string  suffix        = "";               // suffix Symbol
extern string  UniqueID      = "SymbolChanger-hotkeys"; // Indicator unique ID
extern int     WindowIndex   = 0;                // SubWIndow
extern int     XShift        = 8;                //  Horizontal shift
extern int     YShift        = 16;               // Vertical shift
extern int     XSize         = 52;               // Width of buttons
extern int     YSize         = 18;               // Height of buttons
extern int     FSize         = 8;                // Font size
extern color   Bcolor        = C'53,53,53';      // Button color
extern color   Dcolor        = clrDimGray;       // Button border color
extern color   SBcolor       = clrDodgerBlue;    // Button selected color
extern color   SDcolor       = clrDeepSkyBlue;   // Button selected border color
extern color   Tncolor       = clrDarkGray;      // Text color - normal
extern color   Sncolor       = clrGold;          // Text color - selected
extern bool    Transparent   = false;            // Transparent buttons?
// extern bool    ShowTimeframe = false;            // Show Timeframe buttons
extern bool    UseAsMasterChart = true;        // Use this Chart as Master
extern string    sound = "tick.wav"; // Play sound on button click
extern string ProfitLossColorInput = "===================================";
extern color  TradeInProfitBColor  = C'53,53,53';  // Trade in PROFIT background color
extern color  TradeInProfitDColor  = clrLimeGreen; // Trade in PROFIT border color
extern color  TradeInLossBColor  = clrMaroon;      // Trade in LOSS background color
extern color  TradeInLossDColor  = clrRed;         // Trade in LOSS border color
extern color  TradeInZeroBColor  = clrGray;        // Trade in ZERO or PENDING background color
extern color  TradeInZeroDColor  = clrWhite;       // Trade in ZERO or PENDING border color


#define KEY_MONTHLY 57
#define KEY_WEEKLY 56
#define KEY_DAILY 55
#define KEY_4HOUR 54
#define KEY_1HOUR 53
#define KEY_5MIN 50
#define KEY_30MIN 52
#define KEY_15MIN 51
#define KEY_1MIN 49
#define KEY_CHARTFIX 48
#define KEY_P 80

//-----------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------

string aSymbols[];
int    yswitch;
bool   visibleButtons = true;

bool ShowTimeframe = 1;
int ButtonsInARow;
// ------------------------------------------------
int OnInit() {
    Symbols = StringTrimLeft(StringTrimRight(Symbols));
    if(StringSubstr(Symbols, StringLen(Symbols) - 1, 1) != ";")
        Symbols = StringConcatenate(Symbols, ";");

    int s = 0, i = StringFind(Symbols, ";", s);
    string current;
    while(i > 0) {
        current = StringSubstr(Symbols, s, i - s);
        if(current != "*")
            current = StringConcatenate(prefix, current, suffix);
        ArrayResize(aSymbols, ArraySize(aSymbols) + 1);
        aSymbols[ArraySize(aSymbols) - 1] = current;
        s = i + 1;
        i = StringFind(Symbols, ";", s);
    }

    int xpos = 0, ypos = 0, maxx = 0, maxy = 0;

    yswitch = YShift + 1;
    createButton(UniqueID + ":master:", "v", XShift, yswitch, 16, 16);
    ObjectSet(UniqueID + ":master:", OBJPROP_BGCOLOR, White);
    ObjectSetText(UniqueID + ":master:", "v", FSize, "Arial", Black);
    ObjectSetString(WindowIndex, UniqueID + ":master:", OBJPROP_TOOLTIP, "Symbol Changer");

    ypos += YSize + 1;
    for(i = 0; i < ArraySize(aSymbols); i++) {
        if(aSymbols[i] == "*") {
            xpos = 0;
            ypos += YSize + 1;
        } else {
            createButton(UniqueID + ":symbol:" + string(i), aSymbols[i], XShift + xpos, YShift + ypos, XSize, YSize);
            xpos += XSize + 1;
        }
    }

    xpos = 0;
    ypos += YSize * 2;

    if(ShowTimeframe)
        for(i = 0; i < ArraySize(sTfTable); i++) {
            if(i > 0 && MathMod(i, ButtonsInARow) == 0) {
                xpos = 0;
                ypos += YSize + 1;
            }
            createButton(UniqueID + ":time:" + string(i), sTfTable[i], XShift + xpos + 25, yswitch, XSize - 1, YSize - 1);
            xpos += XSize + 1;
        }

    setSymbolButtonColor();
    setPeriodButtonColor();

//  if (ShowTimeframe) setTimeFrameButtonColor();

// Set MasterChart
    if(UseAsMasterChart) StoreChartPair();

    IndicatorShortName("");

    EventSetTimer(3);

    return(0);
}
// ------------------------------------------------
void OnDeinit(const int reason) {



    switch(reason) {
    case REASON_CHARTCHANGE :
    case REASON_RECOMPILE   :
    case REASON_CLOSE       :
        break;
    default : {
        string lookFor       = UniqueID + ":";
        int    lookForLength = StringLen(lookFor);
        for(int i = ObjectsTotal() - 1; i >= 0; i--) {
            string objectName = ObjectName(i);
            if(StringSubstr(objectName, 0, lookForLength) == lookFor) ObjectDelete(objectName);
        }
    }
    }
    EventKillTimer();
}
// ------------------------------------------------
void createButton(string name, string caption, int xpos, int ypos, int xsize, int ysize) {
    if(ObjectFind(name) != 0)
        ObjectCreate(0, name, OBJ_BUTTON, WindowIndex, 0, 0, 0);
    ObjectSet(name, OBJPROP_CORNER, 0);
    ObjectSet(name, OBJPROP_XDISTANCE, xpos);
    ObjectSet(name, OBJPROP_YDISTANCE, ypos);
    ObjectSet(name, OBJPROP_XSIZE, xsize);
    ObjectSet(name, OBJPROP_YSIZE, ysize);
    ObjectSetText(name, caption, FSize, "Arial", Tncolor);
    ObjectSet(name, OBJPROP_FONTSIZE, FSize);
    ObjectSet(name, OBJPROP_BORDER_TYPE, BORDER_FLAT);
    ObjectSet(name, OBJPROP_COLOR, Tncolor);
    ObjectSet(name, OBJPROP_BGCOLOR, Bcolor);
    ObjectSet(name, OBJPROP_BACK, Transparent);
    ObjectSet(name, OBJPROP_BORDER_COLOR, Dcolor);
    ObjectSet(name, OBJPROP_STATE, false);
    ObjectSet(name, OBJPROP_HIDDEN, true);
}
// ------------------------------------------------
void setSymbolButtonColor() {
    string lookFor       = UniqueID + ":symbol:";
    int    lookForLength = StringLen(lookFor);
    for(int i = ObjectsTotal() - 1; i >= 0; i--) {
        string objectName = ObjectName(i);
        if(StringSubstr(objectName, 0, lookForLength) == lookFor) {
            string symbol = ObjectGetString(0, objectName, OBJPROP_TEXT);
            if(symbol != _Symbol)
                ObjectSet(objectName, OBJPROP_COLOR, Tncolor);
            else  ObjectSet(objectName, OBJPROP_COLOR, Sncolor);
        }
    }
}
// ------------------------------------------------
void setPeriodButtonColor() {
    string lookFor       = UniqueID + ":time:";
    int    lookForLength = StringLen(lookFor);
    for(int i = ObjectsTotal() - 1; i >= 0; i--) {
        string objectName = ObjectName(i);
        if(StringSubstr(objectName, 0, lookForLength) == lookFor) {
            string period = ObjectGetString(0, objectName, OBJPROP_TEXT);
            if(stringToTimeFrame(period) != _Period)
                ObjectSet(objectName, OBJPROP_COLOR, Tncolor);
            else  ObjectSet(objectName, OBJPROP_COLOR, Sncolor);
        }
    }
}
// ------------------------------------------------
void setTimeFrameButtonColor() {
    string lookFor       = UniqueID + ":time:";
    int    lookForLength = StringLen(lookFor);
    for(int i = ObjectsTotal() - 1; i >= 0; i--) {
        string objectName = ObjectName(i);
        if(StringSubstr(objectName, 0, lookForLength) == lookFor) {
            int time = stringToTimeFrame(ObjectGetString(0, objectName, OBJPROP_TEXT));
            if(time != _Period)
                ObjectSet(objectName, OBJPROP_COLOR, Tncolor);
            else  ObjectSet(objectName, OBJPROP_COLOR, Sncolor);
        }
    }
}

// ------------------------------------------------
string sTfTable[] = {"M1", "M5", "M15", "M30", "H1", "H4", "D1", "W1", "MN"};
int    iTfTable[] = {1, 5, 15, 30, 60, 240, 1440, 10080, 43200};
//string sTfTable[] = {"H4","D1","W1","MN"};
//int    iTfTable[] = {240,1440,10080,43200};

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string timeFrameToString(int tf) {
    for(int i = ArraySize(iTfTable) - 1; i >= 0; i--)
        if(tf == iTfTable[i]) return(sTfTable[i]);
    return("");
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int stringToTimeFrame(string tf) {
    for(int i = ArraySize(sTfTable) - 1; i >= 0; i--)
        if(tf == sTfTable[i]) return(iTfTable[i]);
    return(0);
}
// ------------------------------------------------

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void StoreChartPair() {
    string n = "SC-" + Symbol();
    varDel("SC-");
    GlobalVariableSet(n, 0);

}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string varDel(string sVarPrefix) {
    string text;
    int nVar = GlobalVariablesTotal();

    for(int jVar = 0; jVar < nVar; jVar++) {
        string sVarName = GlobalVariableName(jVar);
        int x = StringFind(sVarName, sVarPrefix);
        if(x >= 0) {
            GlobalVariableDel(sVarName);
        }
    }

    return(text);
}
// ------------------------------------------------

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) {

    if(id == CHARTEVENT_KEYDOWN) {
        int keycode = int(lparam);

        Print(keycode);

        if (keycode == 188) {

            currentIndex = (int)GlobalVariableGet("hotkey:currentIndex");



            if (currentIndex > 0)
                currentIndex--;
            else
                currentIndex = ArraySize(aSymbols) - 1;

            if (aSymbols[currentIndex] == "*") {
                currentIndex--;

            }


            GlobalVariableSet("hotkey:currentIndex", currentIndex);

            Print(aSymbols[currentIndex]);
            ChartSetSymbolPeriod(0, aSymbols[currentIndex], _Period);
        }



        if (keycode == 190) {

            currentIndex = (int)GlobalVariableGet("hotkey:currentIndex");



            if (currentIndex < ArraySize(aSymbols) - 1)
                currentIndex++;
            else
                currentIndex = 0;

            if (aSymbols[currentIndex] == "*") {
                currentIndex++;

            }


            GlobalVariableSet("hotkey:currentIndex", currentIndex);

            Print(aSymbols[currentIndex]);
            ChartSetSymbolPeriod(0, aSymbols[currentIndex], _Period);
        }






        if (keycode == KEY_MONTHLY || keycode == 77) {
            ChartSetSymbolPeriod(0, NULL, 43200);
        } else if (keycode == KEY_WEEKLY || keycode == 87) {
            ChartSetSymbolPeriod(0, NULL, 10080);
        } else if (keycode == KEY_DAILY || keycode == 68) {
            ChartSetSymbolPeriod(0, NULL, 1440);
        } else if (keycode == KEY_4HOUR) {
            ChartSetSymbolPeriod(0, NULL, 240);
        } else if (keycode == KEY_1HOUR) {
            ChartSetSymbolPeriod(0, NULL, 60);
        } else if (keycode == KEY_5MIN) {
            ChartSetSymbolPeriod(0, NULL, 5);
        } else if (keycode == KEY_30MIN) {
            ChartSetSymbolPeriod(0, NULL, 30);
        } else if (keycode == KEY_15MIN) {
            ChartSetSymbolPeriod(0, NULL, 15);
        } else if (keycode == KEY_1MIN) {
            ChartSetSymbolPeriod(0, NULL, 1);
        } else if (keycode == KEY_CHARTFIX) {
            bool isFixed = ChartGetInteger(0, CHART_SCALEFIX, true);
            if(!isFixed) {
                ChartSetInteger(0, CHART_SCALEFIX, true);
            } else {
                ChartSetInteger(0, CHART_SCALEFIX, false);
            }
        } else if (keycode == KEY_P) {
            bool isFixed = ChartGetInteger(0, CHART_SHOW_PRICE_SCALE, true);
            if(!isFixed) {
                ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, true);
            } else {
                ChartSetInteger(0, CHART_SHOW_PRICE_SCALE, false);
            }
        }


    }








    if(id == CHARTEVENT_OBJECT_CLICK && ObjectGet(sparam, OBJPROP_TYPE) == OBJ_BUTTON) {

        if(StringFind(sparam, UniqueID + ":symbol:", 0) == 0)
            ChartSetSymbolPeriod(0, ObjectGetString(0, sparam, OBJPROP_TEXT), _Period);

        if(StringFind(sparam, UniqueID + ":time:", 0) == 0) ChartSetSymbolPeriod(0, _Symbol, stringToTimeFrame(ObjectGetString(0, sparam, OBJPROP_TEXT)));
        if(StringFind(sparam, UniqueID + ":back:", 0) == 0) ObjectSet(sparam, OBJPROP_STATE, false);
        if(StringFind(sparam, UniqueID + ":master:", 0) == 0) {
            hideButtons();
            visibleButtons = !visibleButtons;
        }
        if(UseAsMasterChart) StoreChartPair();
        if(sound != "") PlaySound(sound);
        setSymbolButtonColorProfit();
    }
}
//
//
//
//
//

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start() {
    setSymbolButtonColorProfit();
    return(0);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTimer() {
    setSymbolButtonColorProfit();
    return;
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void hideButtons() {

    string lookFor = UniqueID + ":";
    int    lookForLength = StringLen(lookFor);
    for(int i = ObjectsTotal() - 1; i >= 0; i--) {

        string objectName = ObjectName(i);
        if(objectName == UniqueID + ":master:") continue;
        if(StringSubstr(objectName, 0, lookForLength) == lookFor) {
            // ObjectDelete(objectName);
            if(visibleButtons) ObjectSetInteger(WindowIndex, objectName, OBJPROP_TIMEFRAMES, OBJ_NO_PERIODS);
            else ObjectSetInteger(WindowIndex, objectName, OBJPROP_TIMEFRAMES, OBJ_ALL_PERIODS);

        }
    }
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void setSymbolButtonColorProfit() {
    if(!visibleButtons) return;
    int tip, b, s, bo, so;
    int i;
    string objectName, symbol;
    double Profit, profit;
    string lookFor       = UniqueID + ":symbol:";
    int    lookForLength = StringLen(lookFor);
    for(int j = ObjectsTotal() - 1; j >= 0; j--) {
        objectName = ObjectName(j);
        if(StringSubstr(objectName, 0, lookForLength) == lookFor) {
            symbol = ObjectGetString(0, objectName, OBJPROP_TEXT);
            b = 0;
            s = 0;
            bo = 0;
            so = 0;
            profit = 0.0;
            Profit = 0.0;
            for(i = 0; i < OrdersTotal(); i++) {
                if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
                    // && (Magic == OrderMagicNumber() || Magic == -1)
                    if(OrderSymbol() == symbol) {
                        profit = OrderProfit() + OrderSwap() + OrderCommission();
                        Profit += profit;
                        //                  price = OrderOpenPrice();
                        //                  lot = OrderLots();
                        tip = OrderType();
                        if(tip == OP_BUY) {
                            //                     ProfitB += profit;
                            //                   price_b += price*lot;
                            b++;
                            //                     lot_b+=lot;
                        }
                        if(tip == OP_SELL) {
                            //                     ProfitS += profit;
                            //                     price_s += price*lot;
                            s++;
                            //                     lot_s+=lot;
                        }
                        if(tip == OP_BUYSTOP || tip == OP_BUYLIMIT) {
                            //                     price_bo += price*lot;
                            //                     lot_bo+=lot;
                            bo++;
                        }
                        if(tip == OP_SELLSTOP || tip == OP_SELLLIMIT) {
                            //                     price_so += price*lot;
                            //                     lot_so+=lot;
                            so++;
                        }
                    }
                }
            }

            if(Profit > 0) {
                ObjectSet(objectName, OBJPROP_BGCOLOR, TradeInProfitBColor);
                if(bo + so > 0)
                    ObjectSet(objectName, OBJPROP_BORDER_COLOR, TradeInZeroDColor);
                else
                    ObjectSet(objectName, OBJPROP_BORDER_COLOR, TradeInProfitDColor);
            } else {
                if(Profit < 0) {
                    ObjectSet(objectName, OBJPROP_BGCOLOR, TradeInLossBColor);
                    if(bo + so > 0)
                        ObjectSet(objectName, OBJPROP_BORDER_COLOR, TradeInZeroDColor);
                    else
                        ObjectSet(objectName, OBJPROP_BORDER_COLOR, TradeInLossDColor);
                } else {
                    if(Profit == 0.0 && b + s + bo + so > 0) {
                        ObjectSet(objectName, OBJPROP_BGCOLOR, TradeInZeroBColor);
                        ObjectSet(objectName, OBJPROP_BORDER_COLOR, TradeInZeroDColor);
                    } else {
                        if(symbol != _Symbol) {
                            ObjectSet(objectName, OBJPROP_BGCOLOR, Bcolor);
                            ObjectSet(objectName, OBJPROP_BORDER_COLOR, Dcolor);
                        } else {
                            ObjectSet(objectName, OBJPROP_BGCOLOR, SBcolor);
                            ObjectSet(objectName, OBJPROP_BORDER_COLOR, SDcolor);
                        }
                    }
                }
            }
        }
    }
    return;
}
//+------------------------------------------------------------------+

AHK 脚本

MT4.ahk

#SingleInstance force
    #NoEnv
    #MaxHotkeysPerInterval 1000
    DetectHiddenWindows, On
    SetTitleMatchMode, RegEx
    SetTitleMatchMode, Slow
    SetWorkingDir %A_ScriptDir%

    

;------------------------------------------------
; MT4
#ifWinActive, ahk_exe terminal.exe

Up::
    send {NumpadAdd}
return

Down::
    send {NumpadSub}
return


^Left::
    send {PgUp}
return


^Right::
    send {PgDn}
return
  

#ifWinActive

脚本打包下载

打印/导出