#property copyright "Copyright © 2010-2021, EarnForex.com" #property link "https://www.earnforex.com/guides/extrapolating-forex-curves-using-linear-algebra-methods/" #property version "1.01" #property description "Stores price patterns of the past and tries to match the current pattern with them. The best match is used to predict the result." #property description "For test & fun only!" #property indicator_chart_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_type1 DRAW_ARROW #property indicator_color1 clrRed #property indicator_width1 3 #define P 30000 // Number of patterns. #define N 100 // Number of candles in one pattern. double PatternSetting[P][N]; // Stores the input values of the pattern. double PatternResult[P]; // Stores the output value of the pattern. int LastBars = 0; bool HaveSolution = false; int handle; double Solution[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { SetIndexBuffer(0, Solution, INDICATOR_DATA); IndicatorSetInteger(INDICATOR_DIGITS, _Digits); PlotIndexSetInteger(0, PLOT_ARROW, 158); PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE); handle = FileOpen("matching-log.txt", FILE_WRITE|FILE_READ|FILE_CSV); if (handle == INVALID_HANDLE) Print("Couldn't open log file."); FileSeek(handle, 0, SEEK_END); } void OnDeinit(const int reason) { FileClose(handle); } //+------------------------------------------------------------------+ //| 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 &tickvolume[], const long &volume[], const int &spread[]) { if (LastBars == rates_total) return(0); else LastBars = rates_total; if (rates_total < P + N + 1) { Print("Not enought data. Need ", IntegerToString(rates_total - (P + N + 1)), " more bars."); return(0); } for (int i = 0; i < P; i++) { PatternResult[i] = (Close[rates_total - 2 - i] - Open[rates_total - 2 - i]) / Open[rates_total - 2 - i]; string s = ""; for (int j = 0; j < N; j++) { PatternSetting[i][N - 1 - j] = (Close[rates_total - 3 - i - j] - Open[rates_total - 3 - i - j]) / Open[rates_total - 3 - i - j]; s = DoubleToString(PatternSetting[i][N - 1 - j], 4) + " " + s; } } double MinDiff = -1; int best = -1; for (int i = 0; i < P; i++) { double Diff = 0; for (int j = 0; j < N; j++) { double coef = (3 * (j + 1)) / MathPow((j + 1), 3); Diff += MathPow(((((Close[rates_total - 2 - j] - Open[rates_total - 2 - j]) / Open[rates_total - 2 - j]) - PatternSetting[i][N - 1 - j]) / coef), 2); } Diff = MathSqrt(Diff); if ((MinDiff > Diff) || (MinDiff == -1)) { MinDiff = Diff; best = i; } } if (best == -1) { Print("Some error"); return(0); } Print("Best-Num: ", best); Print("MinDiff: ", MinDiff); Print("Best: ", PatternResult[best]); Solution[rates_total - 1] = PatternResult[best] * Open[rates_total - 1] + Open[rates_total - 1]; Print("Solution: ", Solution[rates_total - 1]); if (HaveSolution) { string Sign; int Profit; if (((Close[rates_total - 2] >= Open[rates_total - 2]) && (Solution[rates_total - 2] >= Open[rates_total - 2])) || ((Close[rates_total - 2] < Open[rates_total - 2]) && (Solution[rates_total - 2] < Open[rates_total - 2]))) Sign = "+"; else Sign = "-"; Profit = (int)MathRound(MathAbs(Close[rates_total - 2] - Open[rates_total - 2]) * 10000); if (Sign == "-") Profit = -Profit; FileWrite(handle, Sign, Profit); } HaveSolution = true; return(rates_total); } //+------------------------------------------------------------------+