//+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #property description "Portfolio Modeller" #property description "Advanced synthetic optimization and analysis" #property description "Transcendreamer" #property strict #include //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #define MAX_SYMBOLS 32 #define MAX_LINES 512 #define FONTNAME "Verdana" #define FONTSIZE 9 #define SPACING 15 #define XMARGIN 5 #define YMARGIN 25 #define EQUAL '=' #define SPACE ' ' #define NARROW 1 #define BOLD 2 #define HISTOGRAM 2 #define COLOR_INTERVAL clrRed #define COLOR_FILTER clrMagenta #define COLOR_BID_ASK clrRed #define COLOR_MODEL clrRed #define CLICK_PIXELS 1 #define KEY_LEFT 188 #define KEY_RIGHT 190 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #property indicator_separate_window #property indicator_buffers MAX_LINES #property indicator_plots MAX_LINES #property indicator_level1 0 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ input string ______GENERAL______="______GENERAL______"; input string Portfolio_Name=""; input string Portfolio_Formula=""; enum ENUM_MODE {formula,decomposition,consolidation,import,terminal, basic28,fours35,threes35,fours105,threes420,twos210,indices }; input ENUM_MODE Generation_Type=fours35; input string Import_File=""; input string ______SCALING______="______SCALING______"; input bool Downscaling_Total=true; input double Multiplicator_Total=1; input double Portfolio_Value=0; input string ______MODEL______="______MODEL______"; enum ENUM_METHOD {fixed,spread,trend,oscillator,hybrid,root,exponent, fitting,principal,antiprincipal,volatility }; input ENUM_METHOD Model_Type=fixed; input double Model_Growth=0; input double Model_Amplitude=0; input double Model_Cycles=0; input double Model_Phase=0; input bool Model_Absolute=false; input bool Model_Backward=false; input double Target_RMSE=0; input string ______PERIOD______="______PERIOD______"; input ENUM_TIMEFRAMES Timeframe=PERIOD_D1; input bool Use_Time=false; input datetime Start_Time=D'2012.01.01 00:00'; input datetime Finish_Time=D'2035.01.01 00:00'; input int History_Shift=100; input int Optimization_Length=200; input bool Movable_Lines=false; input int Jumping_Bars=1; input string ______LIMITS______="______LIMITS______"; input int Limit_History=1000; input int Limit_Forward=1000; input int Limit_Model=100; input int Request_Bars=2000; input string ______TIMING______="______TIMING______"; input int Delay_Seconds=0; input int Sync_Seconds=60; input int Timer_Seconds=0; input string ______FILTERS______="______FILTERS______"; enum ENUM_FILTER {disabled,high_low,RMSE_min,RMSE_max,manual}; input ENUM_FILTER Filter_Type=disabled; input int Filter_Shift=-10; enum ENUM_SIGN {null,positive,negative}; input ENUM_SIGN Inversion_Mode=null; input int Highest_From=1; input int Highest_To=1; input int Lowest_From=1; input int Lowest_To=1; input ENUM_SIGN Position_Highest=positive; input ENUM_SIGN Position_Lowest=positive; input int RMSE_Selection=1; input int Manual_Selection=0; input string ______ANALYSIS______="______ANALYSIS______"; input int Main_Period=0; input int Fast_Period=0; input int Slow_Period=0; enum ENUM_CHANNELS {empty,standard,envelopes,transcendent,confidence1,confidence2,corridor,deviation}; input ENUM_CHANNELS Channels_Type=empty; input double Channel_Size=2; enum ENUM_SIGNALS {normal,zscore,MACD,WPR}; input ENUM_SIGNALS Signal_Transformation=normal; input int Signal_Period=0; input string ______EXPORT______="______EXPORT______"; input string CSV_Export_File=""; input string CSV_Separator=";"; #ifdef __MQL4__ input string ______OHLC______="______OHLC______"; input bool OHLC_Offline_Chart=false; input ENUM_TIMEFRAMES Data_Timeframe=PERIOD_M1; input int Chart_Timeframe=2; input double Price_Start=100000; #endif input string ______CHART______="______CHART______"; input double Chart_Grid_Size=0; input bool Realistic_Total=false; input bool Draw_Histogram=false; input bool Draw_Markers=false; input bool Hide_Model=false; input bool Hide_Total=false; input bool Hide_By_Filter=false; input bool Hide_Stream=false; input bool Hide_Zero_Lots=false; input bool Hide_Text_Data=false; input int Text_Indent=0; input ENUM_BASE_CORNER Text_Corner=CORNER_LEFT_UPPER; input string ______COLORS______="______COLORS______"; input color Main_Color=clrMagenta; input color Signal_Color=clrRed; input int Colors_Offset=96; input string ______OTHER______="______OTHER______"; enum ENUM_BID_ASK {none,single,longs,shorts}; input ENUM_BID_ASK Show_Bid_Ask=none; input double Commission_Rate=0; input string Chart_Currency="USD"; input int Lots_Digits=2; input string FX_Prefix=""; input string FX_Postfix=""; input bool Print_Details=false; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool error; long chart; int window; ulong file_position; string acc_currency; datetime saved_time; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool mode_stream; ENUM_BID_ASK mode_spread; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #ifdef __MQL4__ bool OHLC_mode; int OHLC_handle; long OHLC_chart; #endif //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int variables,points,components; int num_symbols,num_combos,dim_size,num_model,num_total,num_first; int num_main,num_slow,num_fast,num_upper,num_lower,num_zscore,num_macd; int index_start,index_finish,index_filter; int bar_start,bar_finish,bar_filter,bar_trading; int draw_begin,draw_end,model_begin,model_end; datetime time_start,time_finish,time_filter; double scale_total,scale_model; double bar_range,total_shift; double sum_spread,sum_margin,sum_comms,sum_value; double rmse,range,rmse2range; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string COMBINATIONS[MAX_LINES]; string SYMBOLS[MAX_SYMBOLS]; double LOTS[MAX_SYMBOLS]; double MODEL[],ROOTS[]; double VALUE[MAX_SYMBOLS],RMSE[MAX_LINES]; color COLORS[MAX_LINES]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ struct MASSIVE { int total,sign,position; int pointer[MAX_SYMBOLS]; double lot[MAX_SYMBOLS]; }; MASSIVE PORTFOLIOS[MAX_LINES]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ struct STREAM { double buffer[]; }; STREAM BUFFERS[MAX_LINES]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ struct CACHE { string symbol; double equity[],data[]; double opening,filter; double value; }; CACHE DATA[MAX_SYMBOLS]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnInit() { mode_spread=Show_Bid_Ask; mode_stream=Hide_Stream; SetupCombinations(); SetupBuffers(); #ifdef __MQL4__ FindOHLC(); #endif if(Timer_Seconds>0) EventSetTimer(Timer_Seconds); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { CleanAll(); if(Timer_Seconds>0) EventKillTimer(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ 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[]) { ArraySetAsSeries(time,true); if(time[0]!=saved_time && TimeCurrent()>=time[0]+Delay_Seconds) { UpdateFullChart(); saved_time=time[0]; } else { UpdateLastBar(); } return(rates_total); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTimer() { UpdateFullChart(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void UpdateFullChart() { error=false; Print(Portfolio_Name+": Starting portfolio calculation..."); CleanAll(); SetupCombinations(); SetupSymbols(); #ifdef __MQL5__ RequestData(); #endif SetupIntervals(); CalculateEquity(); for(int n=1; n<=num_combos; n++) CalculateOptimization(n); CalculateFilters(); CalculateSummarization(); CalculateScaling(); for(int n=1; n<=num_combos; n++) DrawPortfolio(n,true); DrawPortfolio(num_total,true); DrawModel(); DrawIndicators(true); UpdateFormula(); UpdateStatistics(); HideByFilter(); DrawChartGrid(); UpdateStatus(); ChartRedraw(chart); ExportCSV(); #ifdef __MQL4__ PrepareOHLC(); GenerateOHLC(true); RefreshOHLC(true); #endif } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void UpdateLastBar() { for(int n=1; n<=num_combos; n++) DrawPortfolio(n,false); DrawPortfolio(num_total,false); DrawIndicators(false); UpdateStatus(); #ifdef __MQL4__ GenerateOHLC(false); RefreshOHLC(false); #endif } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void SetupBuffers() { IndicatorSetInteger(INDICATOR_DIGITS,2); IndicatorSetString(INDICATOR_SHORTNAME,"Portfolio Modeller"); error=false; chart=ChartID(); window=ChartWindowFind(); acc_currency=AccountInfoString(ACCOUNT_CURRENCY); #ifdef __MQL4__ OHLC_chart=0; OHLC_mode=OHLC_Offline_Chart; #endif if(Portfolio_Name=="") { Alert("Empty portfolio name!"); error=true; return; } SetPlotName(num_first,Hide_Total?NULL:"Portfolio "+Portfolio_Name); SetPlotName(num_total,Hide_Total?NULL:"Total portfolio"); SetPlotName(num_model,Hide_Model?NULL:"Model function"); SetIndexBuffer(num_first,BUFFERS[num_first].buffer); SetIndexBuffer(num_total,BUFFERS[num_total].buffer); SetIndexBuffer(num_model,BUFFERS[num_model].buffer); SetPlotStyle(num_first,Hide_Total?DRAW_NONE:Draw_Histogram?DRAW_HISTOGRAM:DRAW_LINE,STYLE_SOLID,NARROW,Main_Color); SetPlotStyle(num_total,Hide_Total?DRAW_NONE:Draw_Markers?DRAW_ARROW:DRAW_LINE,STYLE_SOLID,mode_stream?NARROW:BOLD,Main_Color); SetPlotStyle(num_model,Hide_Model?DRAW_NONE:DRAW_LINE,STYLE_SOLID,NARROW,COLOR_MODEL); int offset=Colors_Offset%128; MathSrand(Colors_Offset); for(int n=1; n<=num_combos; n++) { int r=MathRand()%128+offset; int g=MathRand()%128+offset; int b=MathRand()%128+offset; COLORS[n]=color(r+g*256+b*65536); SetIndexBuffer(n,BUFFERS[n].buffer); SetPlotName(n,mode_stream?NULL:"Portfolio #"+string(n)); SetPlotStyle(n,DRAW_LINE,STYLE_SOLID,NARROW,COLORS[n]); } SetPlotName(num_main,(Main_Period==0)?NULL:"Main Average"); SetPlotName(num_fast,(Fast_Period==0)?NULL:"Fast Average"); SetPlotName(num_slow,(Slow_Period==0)?NULL:"Slow Average"); SetPlotName(num_upper,(Channels_Type==empty)?NULL:"Upper Boundary"); SetPlotName(num_lower,(Channels_Type==empty)?NULL:"Lower Boundary"); SetPlotName(num_zscore,NULL); SetPlotName(num_macd,NULL); SetIndexBuffer(num_main,BUFFERS[num_main].buffer,(Main_Period==0)?INDICATOR_CALCULATIONS:INDICATOR_DATA); SetIndexBuffer(num_fast,BUFFERS[num_fast].buffer,(Fast_Period==0)?INDICATOR_CALCULATIONS:INDICATOR_DATA); SetIndexBuffer(num_slow,BUFFERS[num_slow].buffer,(Slow_Period==0)?INDICATOR_CALCULATIONS:INDICATOR_DATA); SetIndexBuffer(num_upper,BUFFERS[num_upper].buffer,(Channels_Type==empty)?INDICATOR_CALCULATIONS:INDICATOR_DATA); SetIndexBuffer(num_lower,BUFFERS[num_lower].buffer,(Channels_Type==empty)?INDICATOR_CALCULATIONS:INDICATOR_DATA); SetIndexBuffer(num_zscore,BUFFERS[num_zscore].buffer,INDICATOR_CALCULATIONS); SetIndexBuffer(num_macd,BUFFERS[num_macd].buffer,INDICATOR_CALCULATIONS); SetPlotStyle(num_main,DRAW_LINE,STYLE_DOT,Draw_Histogram?HISTOGRAM:NARROW,Signal_Color); SetPlotStyle(num_fast,DRAW_LINE,STYLE_DOT,Draw_Histogram?HISTOGRAM:NARROW,Signal_Color); SetPlotStyle(num_slow,DRAW_LINE,STYLE_DOT,Draw_Histogram?HISTOGRAM:NARROW,Signal_Color); SetPlotStyle(num_upper,DRAW_LINE,STYLE_DOT,Draw_Histogram?HISTOGRAM:NARROW,Signal_Color); SetPlotStyle(num_lower,DRAW_LINE,STYLE_DOT,Draw_Histogram?HISTOGRAM:NARROW,Signal_Color); SetPlotStyle(num_zscore,DRAW_NONE,STYLE_DOT,Draw_Histogram?HISTOGRAM:NARROW,Signal_Color); SetPlotStyle(num_macd,DRAW_NONE,STYLE_DOT,Draw_Histogram?HISTOGRAM:NARROW,Signal_Color); if(Signal_Transformation!=normal) { SetPlotStyle(num_total,DRAW_NONE,STYLE_DOT,NARROW,Signal_Color); for(int n=1; n<=num_combos; n++) SetPlotName(n,NULL); } for(int n=dim_size; n=1; n--) { string name=ObjectName(chart,n-1,window); if(StringFind(name,"Formula-label-"+Portfolio_Name+"-")!=-1) ObjectDelete(chart,name); if(StringFind(name,"Data-label-"+Portfolio_Name+"-")!=-1) ObjectDelete(chart,name); if(StringFind(name,"Grid-level-"+Portfolio_Name+":")!=-1) ObjectDelete(chart,name); if(StringFind(name,"Z-level-upper-"+Portfolio_Name)!=-1) ObjectDelete(chart,name); if(StringFind(name,"Z-level-lower-"+Portfolio_Name)!=-1) ObjectDelete(chart,name); if(StringFind(name,"Portfolio-bid-"+Portfolio_Name)!=-1) ObjectDelete(chart,name); if(StringFind(name,"Portfolio-ask-"+Portfolio_Name)!=-1) ObjectDelete(chart,name); if(StringFind(name,"Portfolio-last-"+Portfolio_Name)!=-1) ObjectDelete(chart,name); if(StringFind(name,"CHART_"+Portfolio_Name)!=-1) ObjectDelete(chart,name); } if(!Movable_Lines) { ObjectDelete(chart,"Line-start-bar-"+Portfolio_Name); ObjectDelete(chart,"Line-finish-bar-"+Portfolio_Name); ObjectDelete(chart,"Line-filter-bar-"+Portfolio_Name); } GlobalVariableDel("Portfolio-"+Portfolio_Name); GlobalVariableDel("Quality-"+Portfolio_Name); GlobalVariableDel("Model-"+Portfolio_Name); GlobalVariableDel("Upper-"+Portfolio_Name); GlobalVariableDel("Lower-"+Portfolio_Name); GlobalVariableDel("Main-"+Portfolio_Name); GlobalVariableDel("Fast-"+Portfolio_Name); GlobalVariableDel("Slow-"+Portfolio_Name); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { //--- if(id==CHARTEVENT_KEYDOWN) while(Movable_Lines) { int shift_bars=0; if(int(lparam)==KEY_LEFT) shift_bars=+Jumping_Bars; if(int(lparam)==KEY_RIGHT) shift_bars=-Jumping_Bars; if(shift_bars==0) break; bar_start =shift_bars+iBarShift(_Symbol,_Period,time_start); bar_finish =shift_bars+iBarShift(_Symbol,_Period,time_finish); bar_filter =shift_bars+iBarShift(_Symbol,_Period,time_filter); time_start =iTime(_Symbol,_Period,bar_start); time_finish =iTime(_Symbol,_Period,bar_finish); time_filter =iTime(_Symbol,_Period,bar_filter); ObjectSetInteger(chart,"Line-start-bar-"+Portfolio_Name,OBJPROP_TIME,0,time_start); ObjectSetInteger(chart,"Line-finish-bar-"+Portfolio_Name,OBJPROP_TIME,0,time_finish); ObjectSetInteger(chart,"Line-filter-bar-"+Portfolio_Name,OBJPROP_TIME,0,time_filter); UpdateFullChart(); break; } //--- if(id==CHARTEVENT_OBJECT_DRAG) if(StringFind(sparam,"-bar-"+Portfolio_Name)!=-1) { if((TerminalInfoInteger(TERMINAL_KEYSTATE_SHIFT)&0x80)!=0) while(Movable_Lines) { datetime oldTime=0; if(sparam=="Line-start-bar-"+Portfolio_Name) oldTime=time_start; else if(sparam=="Line-finish-bar-"+Portfolio_Name) oldTime=time_finish; else if(sparam=="Line-filter-bar-"+Portfolio_Name) oldTime=time_filter; else break; datetime newTime=(datetime)ObjectGetInteger(chart,sparam,OBJPROP_TIME,0); int oldBar=iBarShift(_Symbol,_Period,oldTime); int newBar=iBarShift(_Symbol,_Period,newTime); int shiftBars=newBar-oldBar; if(shiftBars==0) break; bar_start =iBarShift(_Symbol,_Period,time_start)+shiftBars; bar_finish =iBarShift(_Symbol,_Period,time_finish)+shiftBars; bar_filter =iBarShift(_Symbol,_Period,time_filter)+shiftBars; time_start =iTime(_Symbol,_Period,bar_start); time_finish =iTime(_Symbol,_Period,bar_finish); time_filter =iTime(_Symbol,_Period,bar_filter); ObjectSetInteger(chart,"Line-start-bar-"+Portfolio_Name,OBJPROP_TIME,0,time_start); ObjectSetInteger(chart,"Line-finish-bar-"+Portfolio_Name,OBJPROP_TIME,0,time_finish); ObjectSetInteger(chart,"Line-filter-bar-"+Portfolio_Name,OBJPROP_TIME,0,time_filter); break; } UpdateFullChart(); } //--- if(id==CHARTEVENT_OBJECT_CLICK) if(StringFind(sparam,"Data-label-"+Portfolio_Name)!=-1) { if(mode_spread==none) { mode_spread=longs; UpdateStatus(); } else if(mode_spread==longs) { mode_spread=shorts; UpdateStatus(); } else if(mode_spread==shorts) { mode_spread=single; UpdateStatus(); } else if(mode_spread==single) { mode_spread=none; UpdateStatus(); } } //--- if(id==CHARTEVENT_OBJECT_CLICK) if(StringFind(sparam,"Formula-label-"+Portfolio_Name)!=-1) { mode_stream=!mode_stream; num_model=mode_stream?num_combos+1:0; num_total=mode_stream?0:num_combos+1; UpdateFullChart(); } //--- if(id==CHARTEVENT_CLICK) if((TerminalInfoInteger(TERMINAL_KEYSTATE_CONTROL)&0x80)!=0) { double price1,price2; datetime time; int subwindow=0; ChartXYToTimePrice(chart,(int)lparam,(int)dparam-CLICK_PIXELS,subwindow,time,price1); ChartXYToTimePrice(chart,(int)lparam,(int)dparam+CLICK_PIXELS,subwindow,time,price2); if(subwindow==window) { int bar=iBarShift(NULL,0,time); bool empty_select=true; for(int n=1; n<=num_combos; n++) if(BUFFERS[n].buffer[bar]>=price2 && BUFFERS[n].buffer[bar]=time_start) { bool check=true; for(int k=0; k=time_start) { bool check=true; for(int k=0; k=time_finish) { Alert("Incorrect interval settings!"); error=true; return; } //--- PlaceVertical("Line-start-bar-"+Portfolio_Name,time_start,COLOR_INTERVAL,STYLE_DASH,true,Movable_Lines,Movable_Lines); PlaceVertical("Line-finish-bar-"+Portfolio_Name,time_finish,COLOR_INTERVAL,STYLE_DASH,true,Movable_Lines,Movable_Lines); PlaceVertical("Line-filter-bar-"+Portfolio_Name,time_filter,COLOR_FILTER,STYLE_DOT,true,Movable_Lines,Movable_Lines); long periods=use_filter?OBJ_ALL_PERIODS:OBJ_NO_PERIODS; ObjectSetInteger(chart,"Line-filter-bar-"+Portfolio_Name,OBJPROP_TIMEFRAMES,periods); ObjectSetString(chart,"Line-start-bar-"+Portfolio_Name,OBJPROP_TEXT,TimeToString(time_start)); ObjectSetString(chart,"Line-finish-bar-"+Portfolio_Name,OBJPROP_TEXT,TimeToString(time_finish)); ObjectSetString(chart,"Line-filter-bar-"+Portfolio_Name,OBJPROP_TEXT,TimeToString(time_filter)); //--- int bars =Bars(_Symbol,_Period); bar_start =iBarShift(_Symbol,_Period,time_start); bar_finish =iBarShift(_Symbol,_Period,time_finish); bar_filter =iBarShift(_Symbol,_Period,time_filter); bar_trading =MathMin(bar_finish,bar_filter); draw_begin =MathMin(bar_start+Limit_History,bars-1); draw_end =MathMax(bar_finish-Limit_Forward,0); model_begin =MathMin(bar_start+Limit_Model,bars-1); model_end =MathMax(bar_finish-Limit_Model,0); //--- if(bar_start==-1 || bar_finish==-1 || bar_filter==-1) { Alert(time_start," : ",time_finish); Alert(time_start," : ",time_finish); Alert("Data buffers not ready!"); error=true; return; } //--- if(iTime(_Symbol,_Period,bars-1)<=time_start) bar_range=bar_start-bar_finish; else bar_range=PeriodSeconds(Timeframe)/PeriodSeconds(_Period)*(index_start-index_finish); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void SetupSymbols() { if(error) return; components=0; for(int n=1; n<=num_combos; n++) { ArrayInitialize(PORTFOLIOS[n].pointer,-1); SetupFormula(COMBINATIONS[n]); for(int i=0; i=time_start) { points++; for(int k=0; k=draw_end; j--) for(int k=0; k0) { double sumsq=0,count=0; for(int j=0; j0) { for(int i=0; inum_combos || Manual_Selection<1) { Alert("Incorrect manual selection!"); error=true; return; } for(int n=1; n<=num_combos; n++) { PORTFOLIOS[n].position=0; PORTFOLIOS[n].sign=0; } PORTFOLIOS[Manual_Selection].position=+1; PORTFOLIOS[Manual_Selection].sign=+1; if(Print_Details) Print("Portfolio #",Manual_Selection," included as positive"); return; } //--- if(Filter_Type==RMSE_max || Filter_Type==RMSE_min) { if(RMSE_Selection>num_combos || RMSE_Selection<1) { Alert("Incorrect RMSE selection!"); error=true; return; } double rmse_data[][2]; ArrayResize(rmse_data,num_combos); ArrayInitialize(rmse_data,0); for(int n=1; n<=num_combos; n++) { if(Filter_Type==RMSE_min) rmse_data[n-1][0]=+RMSE[n]; else rmse_data[n-1][0]=-RMSE[n]; rmse_data[n-1][1]=n; } ArraySort(rmse_data); for(int n=1; n<=num_combos; n++) { PORTFOLIOS[n].position=0; PORTFOLIOS[n].sign=1; } for(int m=1; m<=RMSE_Selection; m++) { int n=(int)rmse_data[m-1][1]; PORTFOLIOS[n].position=+1; PORTFOLIOS[n].sign=+1; if(Print_Details) Print(Portfolio_Name+": Portfolio #",n," included positive by RMSE"); } return; } //--- if(Filter_Type==high_low) { if(Highest_From>num_combos || Highest_From<1 || Highest_To>num_combos || Highest_To<1 || Lowest_From>num_combos || Lowest_From<1 || Lowest_To>num_combos || Lowest_To<1) { Alert("Incorrect filter selection!"); error=true; return; } int filter[]; int invert[]; double equity[][2]; ArrayResize(equity,num_combos); ArrayResize(filter,num_combos); ArrayResize(invert,num_combos); ArrayInitialize(filter,0); ArrayInitialize(invert,1); ArrayInitialize(equity,0); for(int n=1; n<=num_combos; n++) { equity[n-1][0]=0; equity[n-1][1]=n; variables=PORTFOLIOS[n].total; for(int i=0; i0) { invert[n-1]*=-1; equity[n-1][0]*=-1; if(Print_Details) Print(Portfolio_Name+": Portfolio #",n," inverted to negative"); } ArraySort(equity); if(Position_Lowest==positive) for(int m=Lowest_From; m<=Lowest_To; m++) { int n=(int)equity[m-1][1]; filter[n-1]=+1; if(Print_Details) Print(Portfolio_Name+": Portfolio #",n," selected as positive"); } if(Position_Lowest==negative) for(int m=Lowest_From; m<=Lowest_To; m++) { int n=(int)equity[m-1][1]; filter[n-1]=-1; if(Print_Details) Print(Portfolio_Name+": Portfolio #",n," selected as negative"); } if(Position_Highest==positive) for(int m=Highest_From; m<=Highest_To; m++) { int n=(int)equity[num_combos-m][1]; filter[n-1]=+1; if(Print_Details) Print(Portfolio_Name+": Portfolio #",n," selected as positive"); } if(Position_Highest==negative) for(int m=Highest_From; m<=Highest_To; m++) { int n=(int)equity[num_combos-m][1]; filter[n-1]=-1; if(Print_Details) Print(Portfolio_Name+": Portfolio #",n," selected as negative"); } for(int n=1; n<=num_combos; n++) { PORTFOLIOS[n].sign=invert[n-1]; PORTFOLIOS[n].position=filter[n-1]; } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CalculateSummarization() { if(error) return; //--- ArrayInitialize(PORTFOLIOS[num_total].pointer,-1); ArrayInitialize(PORTFOLIOS[num_total].lot,0); PORTFOLIOS[num_total].total=0; PORTFOLIOS[num_total].sign=+1; PORTFOLIOS[num_total].position=+1; //--- for(int n=1; n<=num_combos; n++) for(int i=0; i0) for(int i=0; i0) Print(Portfolio_Name+": Downscaling by volume: ",sum_volume); } //--- if(Portfolio_Value!=0) { double value_total=0; for(int i=0; i=bar_finish; j--) { double x=BUFFERS[num_total].buffer[j]; double m=BUFFERS[num_model].buffer[j]; if(x==EMPTY_VALUE) continue; if(m==EMPTY_VALUE) m=0; sumsq+=MathPow(x-m,2); count++; } rmse=MathSqrt(sumsq/count); //--- double max=-DBL_MAX,min=DBL_MAX; for(int j=bar_start; j>=bar_finish; j--) { double x=BUFFERS[num_total].buffer[j]; if(x==EMPTY_VALUE) continue; if(x>max) max=x; if(x=draw_end; j--) { double profit=0; for(int i=0; i=draw_end; j--) BUFFERS[number].buffer[j]-=total_shift; } } //--- else if(number==num_total) { if(draw_end>0) return; //--- if(Sync_Seconds>0) { datetime now_time=TimeCurrent(); for(int i=0; iSync_Seconds) { BUFFERS[number].buffer[0]=EMPTY_VALUE; return; } } //--- double profit=0; for(int i=0; i=model_end; j--) { double model=0; if(Model_Type==fixed) model=0; if(Model_Type==spread) model=0; if(Model_Type==principal) model=0; if(Model_Type==antiprincipal) model=0; if(Model_Type==fitting) model=0; if(Model_Type==hybrid) { int bar_distance=Model_Backward?(j-bar_finish):(bar_start-j); double x=bar_distance/bar_range*Model_Cycles-Model_Phase; if(Model_Absolute) x=MathAbs(x); model=Model_Amplitude*MathSin(2*M_PI*x)+Model_Growth*x; model*=scale_model; } if(Model_Type==oscillator) { int bar_distance=Model_Backward?(j-bar_finish):(bar_start-j); double x=bar_distance/bar_range*Model_Cycles-Model_Phase; if(Model_Absolute) x=MathAbs(x); model=Model_Amplitude*MathSin(2*M_PI*x); model*=scale_model; } if(Model_Type==trend) { int bar_distance=Model_Backward?(j-bar_finish):(bar_start-j); double x=bar_distance/bar_range-Model_Phase; if(Model_Absolute) x=MathAbs(x); model=Model_Growth*x; model*=scale_model; } if(Model_Type==root) { int bar_distance=Model_Backward?(j-bar_finish):(bar_start-j); double x=bar_distance/bar_range-Model_Phase; int sign=(int)MathSign(x); if(Model_Absolute) sign=1; model=sign*Model_Growth*MathSqrt(MathAbs(x)); model*=scale_model; } if(Model_Type==exponent) { int bar_distance=Model_Backward?(j-bar_finish):(bar_start-j); double x=bar_distance/bar_range*Model_Cycles-Model_Phase; if(Model_Absolute) x=MathAbs(x); model=Model_Growth*MathExp(x); model*=scale_model; } BUFFERS[num_model].buffer[j]=model; } //--- double model_shift=Model_Backward? BUFFERS[num_model].buffer[bar_finish]: BUFFERS[num_model].buffer[bar_start]; //--- for(int j=model_begin; j>=model_end; j--) BUFFERS[num_model].buffer[j]-=model_shift; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DrawIndicators(bool all_bars) { if(error) return; //--- if(!all_bars) { if(draw_end>0) return; draw_begin=0; draw_end=0; } else { ArrayInitialize(BUFFERS[num_main].buffer,EMPTY_VALUE); ArrayInitialize(BUFFERS[num_fast].buffer,EMPTY_VALUE); ArrayInitialize(BUFFERS[num_slow].buffer,EMPTY_VALUE); ArrayInitialize(BUFFERS[num_upper].buffer,EMPTY_VALUE); ArrayInitialize(BUFFERS[num_lower].buffer,EMPTY_VALUE); ArrayInitialize(BUFFERS[num_zscore].buffer,EMPTY_VALUE); ArrayInitialize(BUFFERS[num_macd].buffer,EMPTY_VALUE); ArrayInitialize(BUFFERS[num_first].buffer,EMPTY_VALUE); } //--- if(Signal_Transformation==normal) for(int j=draw_begin; j>=draw_end; j--) BUFFERS[num_first].buffer[j]=BUFFERS[num_total].buffer[j]; //--- if(Signal_Transformation==MACD) { if(Signal_Period==0) { Alert("Zero signal period!"); error=true; return; } int start_bar = all_bars ? draw_begin-(Signal_Period-1) : 0; for(int j=start_bar; j>=draw_end; j--) { if(BUFFERS[num_total].buffer[j]==EMPTY_VALUE) continue; double MA=0; for(int k=0; k=draw_end; j--) { if(BUFFERS[num_total].buffer[j]==EMPTY_VALUE) continue; double max=-DBL_MAX,min=+DBL_MAX; for(int k=0; kmax) max=BUFFERS[num_total].buffer[j+k]; if(BUFFERS[num_total].buffer[j+k]=draw_end; j--) { if(BUFFERS[num_total].buffer[j]==EMPTY_VALUE) continue; double MA=0,SD=0; for(int k=0; k0) { int start_bar=draw_begin-(Main_Period-1); if(Signal_Transformation!=normal) start_bar-=(Signal_Period-1); if(!all_bars) start_bar=0; for(int j=start_bar; j>=draw_end; j--) { if(BUFFERS[num_first].buffer[j]==EMPTY_VALUE) continue; double MA=0; for(int k=0; k0) { int start_bar=draw_begin-(Fast_Period-1); if(Signal_Transformation!=normal) start_bar-=(Signal_Period-1); if(!all_bars) start_bar=0; for(int j=start_bar; j>=draw_end; j--) { if(BUFFERS[num_first].buffer[j]==EMPTY_VALUE) continue; double MA=0; for(int k=0; k0) { int start_bar=draw_begin-(Slow_Period-1); if(Signal_Transformation!=normal) start_bar-=(Signal_Period-1); if(!all_bars) start_bar=0; for(int j=start_bar; j>=draw_end; j--) { if(BUFFERS[num_first].buffer[j]==EMPTY_VALUE) continue; double MA=0; for(int k=0; k0) { int start_bar=draw_begin-(Main_Period-1); if(Signal_Transformation!=normal) start_bar-=(Signal_Period-1); if(!all_bars) start_bar=0; for(int j=start_bar; j>=draw_end; j--) { if(BUFFERS[num_first].buffer[j]==EMPTY_VALUE) continue; double MA=BUFFERS[num_main].buffer[j]; BUFFERS[num_upper].buffer[j]=MA+Channel_Size; BUFFERS[num_lower].buffer[j]=MA-Channel_Size; } } //--- if(Channels_Type==standard) if(Main_Period>0) { int start_bar=draw_begin-(Main_Period-1); if(Signal_Transformation!=normal) start_bar-=(Signal_Period-1); if(!all_bars) start_bar=0; for(int j=start_bar; j>=draw_end; j--) { if(BUFFERS[num_first].buffer[j]==EMPTY_VALUE) continue; double MA=BUFFERS[num_main].buffer[j]; double SD=0; for(int k=0; k0) { int start_bar=draw_begin-(Main_Period-1); if(Signal_Transformation!=normal) start_bar-=(Signal_Period-1); if(!all_bars) start_bar=0; for(int j=start_bar; j>=draw_end; j--) { if(BUFFERS[num_first].buffer[j]==EMPTY_VALUE) continue; double MA=BUFFERS[num_main].buffer[j]; double sum=0; for(int k=0; k=draw_end; i--) { int x=bar_finish-i; BUFFERS[num_upper].buffer[i]=mean*x+standard*MathSqrt(x)*Channel_Size+b; BUFFERS[num_lower].buffer[i]=mean*x-standard*MathSqrt(x)*Channel_Size+b; } b=BUFFERS[num_model].buffer[bar_start]; for(int i=bar_start; i<=draw_begin; i++) { int x=i-bar_start; BUFFERS[num_upper].buffer[i]=-mean*x+standard*MathSqrt(x)*Channel_Size+b; BUFFERS[num_lower].buffer[i]=-mean*x-standard*MathSqrt(x)*Channel_Size+b; } } //--- if(Channels_Type==corridor) if(!Hide_Model) { for(int j=model_begin; j>=model_end; j--) { double line=BUFFERS[num_model].buffer[j]; BUFFERS[num_upper].buffer[j]=line+Channel_Size; BUFFERS[num_lower].buffer[j]=line-Channel_Size; } } //--- if(Channels_Type==deviation) if(!Hide_Model) { double sumsq=0,count=0; for(int j=bar_start; j>=bar_finish; j--) { double x=BUFFERS[num_total].buffer[j]; double m=BUFFERS[num_model].buffer[j]; if(x!=EMPTY_VALUE) if(m!=EMPTY_VALUE) { sumsq+=MathPow(x-m,2); count++; } } double dev=MathSqrt(sumsq/count); for(int j=model_begin; j>=model_end; j--) { double line=BUFFERS[num_model].buffer[j]; BUFFERS[num_upper].buffer[j]=line+Channel_Size*dev; BUFFERS[num_lower].buffer[j]=line-Channel_Size*dev; } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void UpdateStatus() { if(error) return; double last=BUFFERS[num_first].buffer[0]; double prev=BUFFERS[num_first].buffer[1]; sum_spread=0; for(int i=0; i0) GlobalVariableSet("Main-"+Portfolio_Name,BUFFERS[num_main].buffer[0]); if(Fast_Period>0) GlobalVariableSet("Fast-"+Portfolio_Name,BUFFERS[num_fast].buffer[0]); if(Slow_Period>0) GlobalVariableSet("Slow-"+Portfolio_Name,BUFFERS[num_slow].buffer[0]); if(Channels_Type!=empty) { GlobalVariableSet("Upper-"+Portfolio_Name,BUFFERS[num_upper].buffer[0]); GlobalVariableSet("Lower-"+Portfolio_Name,BUFFERS[num_lower].buffer[0]); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double ContractValue(string symbol,datetime time,ENUM_TIMEFRAMES period,string currency) { double value=SymbolInfoDouble(symbol,SYMBOL_TRADE_CONTRACT_SIZE); string quote=SymbolInfoString(symbol,SYMBOL_CURRENCY_PROFIT); if(value==0) value=1; if(quote!="USD") { string direct=(FX_Prefix+quote+"USD"+FX_Postfix); if(SymbolInfoDouble(direct,SYMBOL_POINT)!=0) { int shift=iBarShift(direct,period,time); double price=iClose(direct,period,shift); if(price>0) value*=price; } else { string indirect=FX_Prefix+"USD"+quote+FX_Postfix; int shift=iBarShift(indirect,period,time); double price=iClose(indirect,period,shift); if(price>0) value/=price; } } if(currency!="USD") { string direct=(FX_Prefix+currency+"USD"+FX_Postfix); if(SymbolInfoDouble(direct,SYMBOL_POINT)!=0) { int shift=iBarShift(direct,period,time); double price=iClose(direct,period,shift); if(price>0) value/=price; } else { string indirect=(FX_Prefix+"USD"+currency+FX_Postfix); int shift=iBarShift(indirect,period,time); double price=iClose(indirect,period,shift); if(price>0) value*=price; } } return(value); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void UpdateFormula() { if(!Hide_Text_Data) for(int i=0,c=0; i=0 ? "+" : "-")+ DoubleToString(MathAbs(LOTS[i]),Lots_Digits); string name="Formula-label-"+Portfolio_Name+"-"+(string)(i+1); PlaceLabel(name,Text_Indent+XMARGIN,YMARGIN+(c+8)*SPACING, Text_Corner,text,Main_Color,FONTNAME,FONTSIZE); if(LOTS[i]==0) continue; double minlot=SymbolInfoDouble(SYMBOLS[i],SYMBOL_VOLUME_MIN); if(MathAbs(LOTS[i])=0; j--) for(int n=0; nmax) max=X; if(Xmin) { level-=Chart_Grid_Size; string name="Grid-level-"+Portfolio_Name+":"+DoubleToString(level,2); PlaceHorizontal(name,level,colour,STYLE_DOT,true,false,false); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void PlaceLabel(string name,int x,int y,int corner,string text,int colour,string font,int size) { ENUM_ANCHOR_POINT anchor=0; if(corner==CORNER_LEFT_LOWER) anchor=ANCHOR_LEFT_LOWER; else if(corner==CORNER_LEFT_UPPER) anchor=ANCHOR_LEFT_UPPER; else if(corner==CORNER_RIGHT_LOWER) anchor=ANCHOR_RIGHT_LOWER; else if(corner==CORNER_RIGHT_UPPER) anchor=ANCHOR_RIGHT_UPPER; ObjectCreate(chart,name,OBJ_LABEL,window,0,0); ObjectSetInteger(chart,name,OBJPROP_CORNER,corner); ObjectSetInteger(chart,name,OBJPROP_ANCHOR,anchor); ObjectSetInteger(chart,name,OBJPROP_XDISTANCE,x); ObjectSetInteger(chart,name,OBJPROP_YDISTANCE,y); ObjectSetString(chart,name,OBJPROP_TEXT,text); ObjectSetString(chart,name,OBJPROP_FONT,font); ObjectSetInteger(chart,name,OBJPROP_FONTSIZE,size); ObjectSetInteger(chart,name,OBJPROP_COLOR,colour); ObjectSetInteger(chart,name,OBJPROP_SELECTABLE,false); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void PlaceVertical(string name,datetime time,int colour,int style,bool back,bool selectable,bool selected) { ObjectCreate(chart,name,OBJ_VLINE,window,time,0); ObjectSetInteger(chart,name,OBJPROP_TIME,time); ObjectSetInteger(chart,name,OBJPROP_COLOR,colour); ObjectSetInteger(chart,name,OBJPROP_STYLE,style); ObjectSetInteger(chart,name,OBJPROP_BACK,back); ObjectSetInteger(chart,name,OBJPROP_SELECTABLE,selectable); ObjectSetInteger(chart,name,OBJPROP_SELECTED,selected); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void PlaceHorizontal(string name,double price,int colour,int style,bool back,bool selectable,bool selected) { ObjectCreate(chart,name,OBJ_HLINE,window,0,price); ObjectSetDouble(chart,name,OBJPROP_PRICE,price); ObjectSetInteger(chart,name,OBJPROP_COLOR,colour); ObjectSetInteger(chart,name,OBJPROP_STYLE,style); ObjectSetInteger(chart,name,OBJPROP_BACK,back); ObjectSetInteger(chart,name,OBJPROP_SELECTABLE,selectable); ObjectSetInteger(chart,name,OBJPROP_SELECTED,selected); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ExportCSV() { if(error) return; if(CSV_Export_File=="") return; string working_name=CSV_Export_File+".csv"; PrepareFile(working_name); for(int j=draw_begin; j>=draw_end; j--) { string text=TimeToString(iTime(_Symbol,_Period,j)); for(int n=1; n<=num_combos; n++) { double value=BUFFERS[n].buffer[j]; if(value==EMPTY_VALUE) continue; text=(text+CSV_Separator+DoubleToString(value,2)); } double value=BUFFERS[num_total].buffer[j]; if(value==EMPTY_VALUE) continue; text=(text+CSV_Separator+DoubleToString(value,2)); WriteLine(working_name,text); } Alert("CSV data export completed."); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void PrepareFile(string file) { int handle=FileOpen(file,FILE_WRITE,CSV_Separator); if(handle==-1) { Alert("Error opening export file!"); error=true; return; } FileClose(handle); string text="DATE/TIME"; for(int n=1; n<=num_combos; n++) text+=(CSV_Separator+"PORTFOLIO #"+string(n)); text+=(CSV_Separator+"TOTAL PORTFOLIO"); WriteLine(file,text); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void WriteLine(string file,string text) { int handle=FileOpen(file,FILE_READ|FILE_WRITE,CSV_Separator); if(handle==-1) return; FileSeek(handle,0,SEEK_END); FileWrite(handle,text); FileClose(handle); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #ifdef __MQL4__ void PrepareOHLC() { if(error) return; if(!OHLC_mode) return; if(Data_Timeframe>_Period) { Alert("Incorrect aggregation timeframe!"); error=true; return; } string name=(_Symbol+(string)Chart_Timeframe+".hst"); OHLC_handle=-1; OHLC_handle=FileOpenHistory(name,FILE_BIN|FILE_WRITE|FILE_ANSI); FileClose(OHLC_handle); OHLC_handle=-1; OHLC_handle=FileOpenHistory(name,FILE_BIN|FILE_READ|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_ANSI); if(OHLC_handle<0) { Alert("Error opening OHLC history file!"); error=true; return; } int data_unused[13]; FileWriteInteger(OHLC_handle,401,LONG_VALUE); FileWriteString(OHLC_handle,"",64); FileWriteString(OHLC_handle,_Symbol,12); FileWriteInteger(OHLC_handle,Chart_Timeframe,LONG_VALUE); FileWriteInteger(OHLC_handle,2,LONG_VALUE); FileWriteInteger(OHLC_handle,0,LONG_VALUE); FileWriteInteger(OHLC_handle,0,LONG_VALUE); FileWriteArray(OHLC_handle,data_unused,0,13); } #endif //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #ifdef __MQL4__ void GenerateOHLC(bool all_bars) { if(error) return; if(!OHLC_mode) return; MqlRates rates; int SHIFTS[]; double OPENINGS[]; ArrayResize(OPENINGS,variables); ArrayResize(SHIFTS,variables); for(int i=0; i=draw_end; j--) { double bar_open=0,bar_high=0,bar_low=0,bar_close=0; for(int k=0; k0) sum_high += (high -OPENINGS[i]) *value*LOTS[i]; else sum_low += (high -OPENINGS[i]) *value*LOTS[i]; if(LOTS[i]>0) sum_low += (low -OPENINGS[i]) *value*LOTS[i]; else sum_high += (low -OPENINGS[i]) *value*LOTS[i]; } if(bar_high==0) bar_high=sum_high; if(sum_high>bar_high) bar_high=sum_high; if(bar_low==0) bar_low=sum_low; if(sum_lowMAX_SYMBOLS) { Alert("Too many orders: only ",MAX_SYMBOLS," will be used!"); total=MAX_SYMBOLS; } for(int i=0; iMAX_SYMBOLS) { Alert("Too many positions: only ",MAX_SYMBOLS," will be used!"); total=MAX_SYMBOLS; } for(int i=0; iMAX_LINES) { Alert("Maximum buffers number exceeded!"); error=true; return; } } //+------------------------------------------------------------------+