[in] The filename to save the template. The ".tpl" extension will be added to the filename automatically; there is no need to specify it. The template is saved in data_folder\templates\ and can be used for manual application in the terminal. If a template with the same filename already exists, the contents of this file will be overwritten.

Return Value

Returns true if the command has been added to chart queue, otherwise false. To get error details use the GetLastError() function.

Note

Using templates, you can save chart settings with all applied indicators and graphical objects, to then apply it to another chart.

Example:

//+------------------------------------------------------------------+//| Test_ChartSaveTemplate.mq4 |//| Copyright 2011, MetaQuotes Software Corp. |//| https://www.mql5.com |//+------------------------------------------------------------------+#propertycopyright"Copyright 2011, MetaQuotes Software Corp."#propertylink"https://www.mql5.com"#propertyversion"1.00"#propertyscript_show_inputs//--- input parametersinputstringsymbol="GBPUSD"; // The symbol of a new chartinputENUM_TIMEFRAMESperiod=PERIOD_H3; // The timeframe of a new chart//+------------------------------------------------------------------+//| Script program start function |//+------------------------------------------------------------------+voidOnStart() {//--- First attach indicators to the chartint handle;//--- Prepare the indicator for useif(!PrepareZigzag(NULL,0,handle)) return; // Failed, so exit//--- Attach the indicator to the current chart, but in a separate window.if(!ChartIndicatorAdd(0,1,handle)) {PrintFormat("Failed to attach to chart %s/%s an indicator with the handle=%d. Error code %d",_Symbol,EnumToString(_Period), handle,GetLastError());//--- Terminate the program operationreturn; }//--- Refresh the chart to see the indicatorChartRedraw();//--- Find the last two last fractures of the zigzagdouble two_values[];datetime two_times[];if(!GetLastTwoFractures(two_values,two_times,handle)) {PrintFormat("Failed to find two last fractures in the Zigzag!");//--- Terminate the program operationreturn; }//--- Now attach a standard deviation channelstring channel="StdDeviation Channel";if(!ObjectCreate(0,channel,OBJ_STDDEVCHANNEL,0,two_times[1],0)) {PrintFormat("Failed to create object %s. Error code %d",EnumToString(OBJ_STDDEVCHANNEL),GetLastError());return; }else {//--- The channel has been created, define the second pointObjectSetInteger(0,channel,OBJPROP_TIME,1,two_times[0]);//--- Set a tooltip text for the channelObjectSetString(0,channel,OBJPROP_TOOLTIP,"Demo from MQL4 Help");//--- Refresh the chartChartRedraw(); }//--- Save the result in a template ChartSaveTemplate(0,"StdDevChannelOnZigzag");//--- Open a new chart and apply a saved template to itlong new_chart=ChartOpen(symbol,period);//--- Enable tooltips for graphical objectsChartSetInteger(new_chart,CHART_SHOW_OBJECT_DESCR,true);if(new_chart!=0) {//--- Apply the saved template to a chartChartApplyTemplate(new_chart,"StdDevChannelOnZigzag"); }Sleep(10000); }//+------------------------------------------------------------------+//| Creates a zigzag handle and ensures readiness of its data |//+------------------------------------------------------------------+bool PrepareZigzag(string sym,ENUM_TIMEFRAMES tf,int &h) {ResetLastError();//--- The Zigzag indicator must be located in terminal_data_folder\MQL4\Examples h=iCustom(sym,tf,"Examples\\Zigzag");if(h==INVALID_HANDLE) {PrintFormat("%s: Failed to create the handle of the Zigzag indicator. Error code %d",__FUNCTION__,GetLastError());returnfalse; }//--- When creating an indicator handle, it requires time to calculate valuesint k=0; // The number of attempts to wait for the indicator calculation//--- Wait for the calculation in a loop, pausing to 50 milliseconds if the calculation is not yet readywhile(BarsCalculated(h)<=0) { k++;//--- Show the number of attemptsPrintFormat("%s: k=%d",__FUNCTION__,k);//--- Wait 50 milliseconds to wait until the indicator is calculatedSleep(50);//--- If more than 100 attempt, then something is wrongif(k>100) {//--- Report a problemPrintFormat("Failed to calculate the indicator for %d attempts!");//--- Terminate the program operationreturnfalse; } }//--- Everything is ready, the indicator is created and values are calculatedreturn true; }//+------------------------------------------------------------------+//| Searches for the last 2 zigzag fractures and places to arrays |//+------------------------------------------------------------------+bool GetLastTwoFractures(double &get_values[],datetime &get_times[],int handle) {double values[]; // An array for the values of the zigzagdatetime times[]; // An array to get timeint size=100; // Size of the arrayResetLastError();//--- Copy the last 100 values of the indicatorint copied=CopyBuffer(handle,0,0,size,values);//--- Check the number of values copiedif(copied<100) {PrintFormat("%s: Failed to copy %d values of the indicator with the handle=%d. Error code %d",__FUNCTION__,size,handle,GetLastError());return false; }//--- Define the order of access to the array as in a timeseriesArraySetAsSeries(values,true);//--- Write here the numbers of bars, in which fractures were foundint positions[];//--- Set array sizesArrayResize(get_values,3); ArrayResize(get_times,3); ArrayResize(positions,3);//--- Countersint i=0,k=0;//--- Start to search for fractureswhile(i<100) {double v=values[i];//--- We are not interested in empty valuesif(v!=0.0) {//--- Remember the bar number positions[k]=i;//--- Remember the value of a zigzag on the fracture get_values[k]=values[i];PrintFormat("%s: Zigzag[%d]=%G",__FUNCTION__,i,values[i]);//--- Increase the counter k++;//--- If two fractures found, break the loopif(k>2) break; } i++; }//--- Define the order of access to the arrays as in a timeseriesArraySetAsSeries(times,true); ArraySetAsSeries(get_times,true);if(CopyTime(_Symbol,_Period,0,size,times)<=0) {PrintFormat("%s: Failed to copy %d values from CopyTime(). Error code %d",__FUNCTION__,size,GetLastError());returnfalse; }//--- Open the bar open time, on which the last 2 fractures occurred get_times[0]=times[positions[1]];// The last but one value will be written as the first fracture get_times[1]=times[positions[2]];// The value third from the end will be the second fracturePrintFormat("%s: first=%s, second=%s",__FUNCTION__,TimeToString(get_times[1]),TimeToString(get_times[0]));//--- Successfulreturntrue; }