// More information about this indicator can be found at: // http://fxcodebase.com/ //+------------------------------------------------------------------+ //| Copyright © 2020, Gehtsoft USA LLC | //| http://fxcodebase.com | //+------------------------------------------------------------------+ //| Support our efforts by donating | //| Paypal: https://goo.gl/9Rj74e | //+------------------------------------------------------------------+ //| Developed by : Mario Jemic | //| mario.jemic@gmail.com | //| https://AppliedMachineLearning.systems | //| Patreon : https://goo.gl/GdXWeN | //+------------------------------------------------------------------+ #property copyright "Copyright © 2020, Gehtsoft USA LLC" #property link "http://fxcodebase.com" #property version "1.00" #property strict #property indicator_separate_window #include #property indicator_buffers 8 #property indicator_color1 clrWhite #property indicator_color2 clrRed #property indicator_color3 clrOrange #property indicator_color4 clrYellow #property indicator_color5 clrGreen #property indicator_color6 clrBlue #property indicator_color7 clrIndigo #property indicator_color8 clrViolet #define INDEX_LABEL_WIDTH 50 #define INDEX_LABEL_HEIGHT 20 #define INDEX_LABEL_FONT "Arial" #define INDEX_LABEL_FONT_SIZE 10 //--- input variables input ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT; input color Color_USDX = clrWhite; input color Color_AUDX = clrRed; input color Color_CADX = clrOrange; input color Color_CHFX = clrYellow; input color Color_EURX = clrGreen; input color Color_GBPX = clrBlue; input color Color_JPYX = clrIndigo; input color Color_NZDX = clrViolet; //--- buffers double USDX[]; double AUDX[]; double CADX[]; double CHFX[]; double EURX[]; double GBPX[]; double JPYX[]; double NZDX[]; //--- variables ENUM_TIMEFRAMES TimeFrameNormalized; string USDX_SymbolList[] = { "EURUSD", "USDJPY", "GBPUSD", "USDCAD", "USDSEK", "USDCHF" }; double USDX_SymbolPower[] = { -0.576, 0.136, -0.119, 0.091, 0.042, 0.036 }; string CurrencyIndex_List[] = { "USD", "AUD", "CAD", "CHF", "EUR", "GBP", "JPY", "NZD" }; color CurrencyIndex_Color[]; string CurrencyIndex_SymbolList[] = { "", "AUDUSD", "USDCAD", "USDCHF", "EURUSD", "GBPUSD", "USDJPY", "NZDUSD" }; double CurrencyIndex_SymbolPower[] = { 0, +1, -1, -1, +1, +1, -1, +1 }; int USDX_SymbolCnt; int CurrencyIndex_Cnt; string ShortName; string ObjectPrefix; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { if (TimeFrame == PERIOD_CURRENT) { TimeFrameNormalized = Period(); } else { TimeFrameNormalized = TimeFrame; if (TimeFrameNormalized < Period()) { Alert("[Warning] - [" + __FUNCTION__ + "]: TimeFrame setting is lower than chart's time frame so that chart's time frame will be used for calculation!"); TimeFrameNormalized = Period(); } } USDX_SymbolCnt = ArraySize(USDX_SymbolList); CurrencyIndex_Cnt = ArraySize(CurrencyIndex_List); ArrayResize(CurrencyIndex_Color, CurrencyIndex_Cnt); CurrencyIndex_Color[0] = Color_USDX; CurrencyIndex_Color[1] = Color_AUDX; CurrencyIndex_Color[2] = Color_CADX; CurrencyIndex_Color[3] = Color_CHFX; CurrencyIndex_Color[4] = Color_EURX; CurrencyIndex_Color[5] = Color_GBPX; CurrencyIndex_Color[6] = Color_JPYX; CurrencyIndex_Color[7] = Color_NZDX; for (int i = 0; i < USDX_SymbolCnt; i++) { if (!SymbolSelect(USDX_SymbolList[i], true)) { Alert("[Error] - [" + __FUNCTION__ + "]: Could not select symbol " + USDX_SymbolList[i] + "!Error: " + ErrorDescription(GetLastError()) + "!"); return INIT_FAILED; } datetime tmp = iTime(USDX_SymbolList[i], TimeFrameNormalized, 0); } for (int i = 0; i < CurrencyIndex_Cnt; i++) { if ((CurrencyIndex_SymbolList[i] != "") && !SymbolSelect(CurrencyIndex_SymbolList[i], true)) { Alert("[Error] - [" + __FUNCTION__ + "]: Could not select symbol " + CurrencyIndex_SymbolList[i] + "!Error: " + ErrorDescription(GetLastError()) + "!"); return INIT_FAILED; } datetime tmp = iTime(CurrencyIndex_SymbolList[i], TimeFrameNormalized, 0); } MathSrand(GetTickCount()); if (!FindUnusedShortName("Currency Index Indicator #", ShortName)) { Alert("[Error] - [" + __FUNCTION__ + "]: Could not find a suitable short name for the indicator! Exiting..."); return INIT_FAILED; } IndicatorShortName(ShortName); int subWindow = ChartWindowFind(0, ShortName); if (!FindUnusedObjectPrefix("FXCodeBase", ObjectPrefix)) { Alert("[Error] - [" + __FUNCTION__ + "]: Could not find a suitable prefix for graphical objects! Exiting..."); return INIT_FAILED; } for (int i = 0; i < CurrencyIndex_Cnt; i++) { if (!LabelCreate(0, ObjectPrefix + " - Label - " + CurrencyIndex_List[i] + "X", subWindow, (8 - i) * INDEX_LABEL_WIDTH, INDEX_LABEL_HEIGHT, CORNER_RIGHT_UPPER, CurrencyIndex_List[i] + "X", INDEX_LABEL_FONT, INDEX_LABEL_FONT_SIZE, CurrencyIndex_Color[i])) { return INIT_FAILED; } } //--- indicator buffers mapping IndicatorDigits(5); SetIndexShift(0, 0); SetIndexDrawBegin(0, 0); SetIndexBuffer(0, USDX); SetIndexStyle(0, DRAW_LINE, EMPTY, EMPTY, Color_USDX); SetIndexEmptyValue(0, EMPTY_VALUE); SetIndexLabel(0, "USDX"); SetIndexShift(1, 0); SetIndexDrawBegin(1, 0); SetIndexBuffer(1, AUDX); SetIndexStyle(1, DRAW_LINE, EMPTY, EMPTY, Color_AUDX); SetIndexEmptyValue(1, EMPTY_VALUE); SetIndexLabel(1, "AUDX"); SetIndexShift(2, 0); SetIndexDrawBegin(2, 0); SetIndexBuffer(2, CADX); SetIndexStyle(2, DRAW_LINE, EMPTY, EMPTY, Color_CADX); SetIndexEmptyValue(2, EMPTY_VALUE); SetIndexLabel(2, "CADX"); SetIndexShift(3, 0); SetIndexDrawBegin(3, 0); SetIndexBuffer(3, CHFX); SetIndexStyle(3, DRAW_LINE, EMPTY, EMPTY, Color_CHFX); SetIndexEmptyValue(3, EMPTY_VALUE); SetIndexLabel(3, "CHFX"); SetIndexShift(4, 0); SetIndexDrawBegin(4, 0); SetIndexBuffer(4, EURX); SetIndexStyle(4, DRAW_LINE, EMPTY, EMPTY, Color_EURX); SetIndexEmptyValue(4, EMPTY_VALUE); SetIndexLabel(4, "EURX"); SetIndexShift(5, 0); SetIndexDrawBegin(5, 0); SetIndexBuffer(5, GBPX); SetIndexStyle(5, DRAW_LINE, EMPTY, EMPTY, Color_GBPX); SetIndexEmptyValue(5, EMPTY_VALUE); SetIndexLabel(5, "GBPX"); SetIndexShift(6, 0); SetIndexDrawBegin(6, 0); SetIndexBuffer(6, JPYX); SetIndexStyle(6, DRAW_LINE, EMPTY, EMPTY, Color_JPYX); SetIndexEmptyValue(6, EMPTY_VALUE); SetIndexLabel(6, "JPYX"); SetIndexShift(7, 0); SetIndexDrawBegin(7, 0); SetIndexBuffer(7, NZDX); SetIndexStyle(7, DRAW_LINE, EMPTY, EMPTY, Color_NZDX); SetIndexEmptyValue(7, EMPTY_VALUE); SetIndexLabel(7, "NZDX"); //--- return (INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { if (ObjectPrefix != "") { ObjectsDeleteAll(0, ObjectPrefix); } } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- bool isDataReady = true; for (int i = 0; i < USDX_SymbolCnt; i++) { if ((iTime(USDX_SymbolList[i], TimeFrameNormalized, 0) == 0) || (iClose(USDX_SymbolList[i], TimeFrameNormalized, 0) == 0)) { isDataReady = false; if (!SymbolSelect(USDX_SymbolList[i], true)) { Alert("[Error] - [" + __FUNCTION__ + "]: Could not select symbol " + USDX_SymbolList[i] + "!Error: " + ErrorDescription(GetLastError()) + "!"); } } } for (int i = 0; i < CurrencyIndex_Cnt; i++) { if ((iTime(CurrencyIndex_SymbolList[i], TimeFrameNormalized, 0) == 0) || (iClose(CurrencyIndex_SymbolList[i], TimeFrameNormalized, 0) == 0)) { isDataReady = false; if (!SymbolSelect(CurrencyIndex_SymbolList[i], true)) { Alert("[Error] - [" + __FUNCTION__ + "]: Could not select symbol " + CurrencyIndex_SymbolList[i] + "!Error: " + ErrorDescription(GetLastError()) + "!"); } } } if (!isDataReady) { return prev_calculated; } int limit = rates_total - prev_calculated + 1; if ((prev_calculated <= 0) || (prev_calculated > rates_total)) { ArrayInitialize(USDX, EMPTY_VALUE); ArrayInitialize(AUDX, EMPTY_VALUE); ArrayInitialize(CADX, EMPTY_VALUE); ArrayInitialize(CHFX, EMPTY_VALUE); ArrayInitialize(EURX, EMPTY_VALUE); ArrayInitialize(GBPX, EMPTY_VALUE); ArrayInitialize(JPYX, EMPTY_VALUE); ArrayInitialize(NZDX, EMPTY_VALUE); } if ((limit >= rates_total) || (limit < 0)) { limit = rates_total - 1; } for (int i = limit; i >= 0; i--) { double tmp = 50.14348112; for (int j = 0; j < USDX_SymbolCnt; j++) { int index = iBarShift(USDX_SymbolList[j], TimeFrameNormalized, time[i]); double price = iClose(USDX_SymbolList[j], TimeFrameNormalized, index); double weight = USDX_SymbolPower[j]; tmp *= MathPow(price, weight); } USDX[i] = tmp; int indexAUD = iBarShift("AUDUSD", TimeFrameNormalized, time[i]); double priceAUD = iClose("AUDUSD", TimeFrameNormalized, indexAUD); AUDX[i] = tmp * priceAUD; int indexCAD = iBarShift("USDCAD", TimeFrameNormalized, time[i]); double priceCAD = iClose("USDCAD", TimeFrameNormalized, indexCAD); CADX[i] = tmp / priceCAD; int indexCHF = iBarShift("USDCHF", TimeFrameNormalized, time[i]); double priceCHF = iClose("USDCHF", TimeFrameNormalized, indexCHF); CHFX[i] = tmp / priceCHF; int indexEUR = iBarShift("EURUSD", TimeFrameNormalized, time[i]); double priceEUR = iClose("EURUSD", TimeFrameNormalized, indexEUR); EURX[i] = tmp * priceEUR; int indexGBP = iBarShift("GBPUSD", TimeFrameNormalized, time[i]); double priceGBP = iClose("GBPUSD", TimeFrameNormalized, indexGBP); GBPX[i] = tmp * priceGBP; int indexJPY = iBarShift("USDJPY", TimeFrameNormalized, time[i]); double priceJPY = iClose("USDJPY", TimeFrameNormalized, indexJPY); JPYX[i] = tmp / priceJPY; int indexNZD = iBarShift("NZDUSD", TimeFrameNormalized, time[i]); double priceNZD = iClose("NZDUSD", TimeFrameNormalized, indexNZD); NZDX[i] = tmp * priceNZD; } //--- return value of prev_calculated for next call return (rates_total); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Create a text label | //+------------------------------------------------------------------+ bool LabelCreate(const long chart_ID = 0, // chart's ID const string name = "Label", // label name const int sub_window = 0, // subwindow index const int x = 0, // X coordinate const int y = 0, // Y coordinate const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring const string text = "Label", // text const string font = "Arial", // font const int font_size = 10, // font size const color clr = clrNONE, // color const double angle = 0.0, // text slope const ENUM_ANCHOR_POINT anchor = ANCHOR_LEFT_UPPER, // anchor type const bool back = false, // in the background const bool selection = false, // highlight to move const bool hidden = true, // hidden in the object list const long z_order = 0) // priority for mouse click { //--- reset the error value ResetLastError(); //--- create a text label if (!ObjectCreate(chart_ID, name, OBJ_LABEL, sub_window, 0, 0)) { Alert("[Error] - [" + __FUNCTION__ + "]: Could not create the label! Error: " + ErrorDescription(GetLastError()) + "!"); return false; } //--- set label coordinates ObjectSetInteger(chart_ID, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(chart_ID, name, OBJPROP_YDISTANCE, y); //--- set the chart's corner, relative to which point coordinates are defined ObjectSetInteger(chart_ID, name, OBJPROP_CORNER, corner); //--- set the text ObjectSetString(chart_ID, name, OBJPROP_TEXT, text); //--- set text font ObjectSetString(chart_ID, name, OBJPROP_FONT, font); //--- set font size ObjectSetInteger(chart_ID, name, OBJPROP_FONTSIZE, font_size); //--- set the slope angle of the text ObjectSetDouble(chart_ID, name, OBJPROP_ANGLE, angle); //--- set anchor type ObjectSetInteger(chart_ID, name, OBJPROP_ANCHOR, anchor); //--- set color ObjectSetInteger(chart_ID, name, OBJPROP_COLOR, clr); //--- display in the foreground (false) or background (true) ObjectSetInteger(chart_ID, name, OBJPROP_BACK, back); //--- enable (true) or disable (false) the mode of moving the label by mouse ObjectSetInteger(chart_ID, name, OBJPROP_SELECTABLE, selection); ObjectSetInteger(chart_ID, name, OBJPROP_SELECTED, selection); //--- hide (true) or display (false) graphical object name in the object list ObjectSetInteger(chart_ID, name, OBJPROP_HIDDEN, hidden); //--- set the priority for receiving the event of a mouse click in the chart ObjectSetInteger(chart_ID, name, OBJPROP_ZORDER, z_order); //--- successful execution return (true); } bool FindUnusedShortName(string initStr, string &shortNameStr) { shortNameStr = ""; for (int i = 0; i < 1000; i++) { string str = initStr + IntegerToString(MathRand()); if (ChartWindowFind(0, str) < 0) { shortNameStr = str; return true; } } return false; } bool FindUnusedObjectPrefix(string initStr, string &prefixStr) { prefixStr = ""; for (int i = 0; i < 1000; i++) { string str = initStr + IntegerToString(MathRand()); if (ObjectFind(0, str) < 0) { prefixStr = str; return true; } } return false; }