You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
so ?????
did I make any mistake ???
In my opinion, none whatsoever.
Note that this thread has been up for 3 months now without objection from the Moderators.
Hello, I came across your post on FXBlue and wanted to express my sincere thanks. However, the script currently only works with XAUUSD; could you "unlock" and rewrite the source code so it works with all instruments? For instance, I trade gold on an Exness Zero account where the symbol is XAUUSDz rather than XAUUSD (without the 'z' suffix). Please rewrite it. Also, if possible, could you create versions for both MT4 and MT5? Thank you very much.
//+------------------------------------------------------------------+ //| Universal_Seconds.mq4| //| Universal Seconds Offline Chart Generator | //| MT4 Build 600+ | //+------------------------------------------------------------------+ #property strict #property show_inputs #property version "2.00" //+------------------------------------------------------------------+ //| Inputs | //+------------------------------------------------------------------+ input int InpSecondsPeriod = 10; // Seconds timeframe input bool InpAutoOpenChart = true; // Auto open offline chart input bool InpShowComment = true; // Show status comment //+------------------------------------------------------------------+ //| Global variables | //+------------------------------------------------------------------+ int ExtHandle = -1; long OfflineChartID = 0; int OfflinePeriod = 0; datetime CurrentBarTime = 0; MqlRates Rate; string CurrentSymbol; string OfflineFileName; //+------------------------------------------------------------------+ //| Script start | //+------------------------------------------------------------------+ void OnStart() { // Store the exact symbol to which the script is attached. // This automatically supports: // EURUSD // GBPUSD // XAUUSD // XAUUSDm // GOLD // BTCUSD // etc. CurrentSymbol = Symbol(); // Validate seconds period. if(InpSecondsPeriod < 1) { Alert("Seconds period must be >= 1"); return; } // Make sure the symbol has a valid market price. RefreshRates(); double current_bid = MarketInfo(CurrentSymbol, MODE_BID); if(current_bid <= 0.0) { Alert( "No valid market price is available for ", CurrentSymbol, ". Make sure the symbol is active and receiving ticks." ); return; } // --------------------------------------------------------------- // Create a unique offline timeframe. // // Example: // S10 -> 20010 // S30 -> 20030 // S60 -> 20060 // // The symbol itself remains part of the HST filename. // --------------------------------------------------------------- OfflinePeriod = 20000 + InpSecondsPeriod; // Use the actual broker symbol. OfflineFileName = CurrentSymbol + (string)OfflinePeriod + ".hst"; // --------------------------------------------------------------- // Open/create the offline history file. // FILE_WRITE creates a fresh file for this instance. // --------------------------------------------------------------- ExtHandle = FileOpenHistory( OfflineFileName, FILE_BIN | FILE_WRITE | FILE_SHARE_WRITE | FILE_SHARE_READ ); if(ExtHandle < 0) { Alert( "Failed to create offline history file.\n", "Symbol: ", CurrentSymbol, "\n", "File: ", OfflineFileName, "\n", "Error: ", GetLastError() ); return; } // Write standard MT4 HST header. WriteHistoryHeader(); // Wait for the first market tick. WaitForFirstTick(); if(IsStopped()) return; // Build the first seconds candle. BuildInitialBar(); // Open the offline chart if requested. if(InpAutoOpenChart) OpenOfflineChart(); // Start processing ticks. MainLoop(); } //+------------------------------------------------------------------+ //| Wait for first market tick | //+------------------------------------------------------------------+ void WaitForFirstTick() { while(!IsStopped()) { RefreshRates(); double bid = MarketInfo(CurrentSymbol, MODE_BID); datetime server_time = TimeCurrent(); if(server_time > 0 && bid > 0.0) break; Sleep(100); } } //+------------------------------------------------------------------+ //| Build first candle | //+------------------------------------------------------------------+ void BuildInitialBar() { RefreshRates(); double bid = MarketInfo(CurrentSymbol, MODE_BID); datetime now = TimeCurrent(); CurrentBarTime = NormalizeSecondTime(now); ZeroMemory(Rate); Rate.time = CurrentBarTime; Rate.open = bid; Rate.high = bid; Rate.low = bid; Rate.close = bid; Rate.tick_volume = 1; Rate.spread = (long)MarketInfo(CurrentSymbol, MODE_SPREAD); Rate.real_volume = 0; FileWriteStruct(ExtHandle, Rate); FileFlush(ExtHandle); } //+------------------------------------------------------------------+ //| Main processing loop | //+------------------------------------------------------------------+ void MainLoop() { datetime last_refresh = 0; while(!IsStopped()) { // Update market data. RefreshRates(); double bid = MarketInfo(CurrentSymbol, MODE_BID); // Some instruments can temporarily have no valid price. if(bid <= 0.0) { Sleep(20); continue; } datetime now = TimeCurrent(); if(now <= 0) { Sleep(20); continue; } datetime normalized = NormalizeSecondTime(now); // ------------------------------------------------------------ // A new seconds candle has started. // ------------------------------------------------------------ if(normalized > CurrentBarTime) { FinalizeCurrentBar(); StartNewBar(normalized); } else { // Same candle - update OHLC. UpdateCurrentBar(); } // ------------------------------------------------------------ // Display status. // ------------------------------------------------------------ if(InpShowComment) { Comment( "Universal Seconds Chart Generator\n", "Symbol : ", CurrentSymbol, "\n", "Seconds TF : S", InpSecondsPeriod, "\n", "Offline ID : ", OfflinePeriod, "\n", "Status : RUNNING\n", "Bid : ", DoubleToString(bid, (int)MarketInfo(CurrentSymbol, MODE_DIGITS)) ); } // ------------------------------------------------------------ // Refresh offline chart periodically. // ------------------------------------------------------------ if(TimeLocal() - last_refresh >= 2) { RefreshOfflineChart(); last_refresh = TimeLocal(); } Sleep(20); } Comment(""); } //+------------------------------------------------------------------+ //| Start new candle | //+------------------------------------------------------------------+ void StartNewBar(datetime bar_time) { RefreshRates(); double bid = MarketInfo(CurrentSymbol, MODE_BID); if(bid <= 0.0) return; CurrentBarTime = bar_time; ZeroMemory(Rate); Rate.time = CurrentBarTime; Rate.open = bid; Rate.high = bid; Rate.low = bid; Rate.close = bid; Rate.tick_volume = 1; Rate.spread = (long)MarketInfo(CurrentSymbol, MODE_SPREAD); Rate.real_volume = 0; FileWriteStruct(ExtHandle, Rate); FileFlush(ExtHandle); } //+------------------------------------------------------------------+ //| Update current candle | //+------------------------------------------------------------------+ void UpdateCurrentBar() { RefreshRates(); double bid = MarketInfo(CurrentSymbol, MODE_BID); if(bid <= 0.0) return; // Update high. if(bid > Rate.high) Rate.high = bid; // Update low. if(bid < Rate.low) Rate.low = bid; // Update close. Rate.close = bid; // Count ticks. Rate.tick_volume++; // Update current spread. Rate.spread = (long)MarketInfo(CurrentSymbol, MODE_SPREAD); // Rewrite the last HST record. int struct_size = sizeof(MqlRates); if(FileSeek(ExtHandle, -struct_size, SEEK_END)) { FileWriteStruct(ExtHandle, Rate); FileFlush(ExtHandle); } } //+------------------------------------------------------------------+ //| Finalize current candle | //+------------------------------------------------------------------+ void FinalizeCurrentBar() { int struct_size = sizeof(MqlRates); if(FileSeek(ExtHandle, -struct_size, SEEK_END)) { FileWriteStruct(ExtHandle, Rate); FileFlush(ExtHandle); } } //+------------------------------------------------------------------+ //| Normalize time | //+------------------------------------------------------------------+ datetime NormalizeSecondTime(datetime t) { if(InpSecondsPeriod <= 1) return t; return (t / InpSecondsPeriod) * InpSecondsPeriod; } //+------------------------------------------------------------------+ //| Write HST header | //+------------------------------------------------------------------+ void WriteHistoryHeader() { int version = 401; string copyright = "Universal Seconds Chart"; string symbol = CurrentSymbol; int period = OfflinePeriod; int digits = (int)MarketInfo(CurrentSymbol, MODE_DIGITS); int unused[13]; ArrayInitialize(unused, 0); // HST header. FileWriteInteger(ExtHandle, version, LONG_VALUE); FileWriteString( ExtHandle, copyright, 64 ); FileWriteString( ExtHandle, symbol, 12 ); FileWriteInteger( ExtHandle, period, LONG_VALUE ); FileWriteInteger( ExtHandle, digits, LONG_VALUE ); FileWriteInteger( ExtHandle, 0, LONG_VALUE ); FileWriteInteger( ExtHandle, 0, LONG_VALUE ); FileWriteArray( ExtHandle, unused, 0, 13 ); } //+------------------------------------------------------------------+ //| Open offline chart | //+------------------------------------------------------------------+ void OpenOfflineChart() { // Open the exact current symbol. OfflineChartID = ChartOpen( CurrentSymbol, OfflinePeriod ); if(OfflineChartID <= 0) { Print( "Unable to open offline chart. ", "Symbol=", CurrentSymbol, " Period=", OfflinePeriod, " Error=", GetLastError() ); return; } Sleep(1000); RefreshOfflineChart(); } //+------------------------------------------------------------------+ //| Refresh offline chart | //+------------------------------------------------------------------+ void RefreshOfflineChart() { if(OfflineChartID <= 0) return; // Make sure the chart belongs to the correct symbol/timeframe. ChartSetSymbolPeriod( OfflineChartID, CurrentSymbol, OfflinePeriod ); ChartRedraw(OfflineChartID); } //+------------------------------------------------------------------+ //| Cleanup | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Comment(""); // Close history file. if(ExtHandle >= 0) { FileFlush(ExtHandle); FileClose(ExtHandle); ExtHandle = -1; } // We intentionally do NOT close the offline chart here. // The user may want to keep the chart open after stopping // the generator. OfflineChartID = 0; } //+------------------------------------------------------------------+//+------------------------------------------------------------------+ //| GoldSecondsMT5.mq5 | //| MT5 Native Seconds Chart Generator | //| Custom Symbol Engine Version | //+------------------------------------------------------------------+ #property strict enum ENUM_SOURCE_MODE { SOURCE_MODE_AUTO_GOLD = 0, // Auto-detect Gold (any XAU/GOLD name) SOURCE_MODE_CHART = 1, // Chart symbol (works for any instrument) SOURCE_MODE_MANUAL = 2 // Manual symbol (any instrument) }; input ENUM_SOURCE_MODE InpSourceMode = SOURCE_MODE_AUTO_GOLD; input string InpSourceSymbol = "XAUUSD"; input int InpSeconds = 10; input bool InpAutoOpen = true; string SourceSymbolName; string CustomSymbolName; MqlRates CurrentBar; datetime CurrentBarTime = 0; long LastTickTimeMSC = 0; //+------------------------------------------------------------------+ //| Expert initialization | //+------------------------------------------------------------------+ int OnInit() { if(InpSeconds < 1) { Print("Seconds must be >= 1"); return(INIT_FAILED); } //--- resolve the actual symbol to watch SourceSymbolName = ResolveSourceSymbol(); if(StringLen(SourceSymbolName) == 0) { Print("Failed to resolve source symbol. Check the inputs."); return(INIT_FAILED); } //--- ticks stream only for symbols selected in Market Watch if(!SymbolSelect(SourceSymbolName, true)) { Print("Failed to select symbol in Market Watch: ", SourceSymbolName, " (", GetLastError(), ")"); return(INIT_FAILED); } CustomSymbolName = MakeCustomSymbolName(SourceSymbolName, InpSeconds); Print("Source symbol: ", SourceSymbolName); Print("Creating custom symbol: ", CustomSymbolName); CreateCustomSymbol(); OpenCustomChart(); EventSetMillisecondTimer(50); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { EventKillTimer(); } //+------------------------------------------------------------------+ //| Millisecond timer | //+------------------------------------------------------------------+ void OnTimer() { MqlTick tick; if(!SymbolInfoTick(SourceSymbolName, tick)) return; if(tick.time_msc == LastTickTimeMSC) return; LastTickTimeMSC = tick.time_msc; ProcessTick(tick); } //+------------------------------------------------------------------+ //| Process incoming tick | //+------------------------------------------------------------------+ void ProcessTick(MqlTick &tick) { datetime bar_time = (datetime)((tick.time / InpSeconds) * InpSeconds); //--- First bar if(CurrentBarTime == 0) { StartNewBar(bar_time, tick); return; } //--- New candle if(bar_time > CurrentBarTime) { PushBarToCustomSymbol(CurrentBar); StartNewBar(bar_time, tick); } else { UpdateCurrentBar(tick); } } //+------------------------------------------------------------------+ //| Start new candle | //+------------------------------------------------------------------+ void StartNewBar(datetime bar_time, MqlTick &tick) { CurrentBarTime = bar_time; CurrentBar.time = bar_time; CurrentBar.open = tick.bid; CurrentBar.high = tick.bid; CurrentBar.low = tick.bid; CurrentBar.close = tick.bid; CurrentBar.tick_volume = 1; CurrentBar.spread = 0; CurrentBar.real_volume = 0; } //+------------------------------------------------------------------+ //| Update current candle | //+------------------------------------------------------------------+ void UpdateCurrentBar(MqlTick &tick) { if(tick.bid > CurrentBar.high) CurrentBar.high = tick.bid; if(tick.bid < CurrentBar.low) CurrentBar.low = tick.bid; CurrentBar.close = tick.bid; CurrentBar.tick_volume++; } //+------------------------------------------------------------------+ //| Push candle to custom symbol | //+------------------------------------------------------------------+ void PushBarToCustomSymbol(MqlRates &bar) { MqlRates rates[1]; rates[0] = bar; if(!CustomRatesUpdate(CustomSymbolName, rates)) { Print("CustomRatesUpdate failed. Error: ", GetLastError()); } } //+------------------------------------------------------------------+ //| Create custom symbol | //+------------------------------------------------------------------+ void CreateCustomSymbol() { //--- already exists if(SymbolSelect(CustomSymbolName, true)) { Print("Custom symbol already exists."); return; } //--- create if(!CustomSymbolCreate( CustomSymbolName, "Custom", SourceSymbolName)) { Print("Failed creating custom symbol. Error: ", GetLastError()); return; } //--- select SymbolSelect(CustomSymbolName, true); //--- synchronize properties CustomSymbolSetInteger( CustomSymbolName, SYMBOL_DIGITS, (int)SymbolInfoInteger(SourceSymbolName, SYMBOL_DIGITS) ); CustomSymbolSetDouble( CustomSymbolName, SYMBOL_POINT, SymbolInfoDouble(SourceSymbolName, SYMBOL_POINT) ); Print("Custom symbol created successfully."); } //+------------------------------------------------------------------+ //| Open custom chart | //+------------------------------------------------------------------+ void OpenCustomChart() { if(!InpAutoOpen) return; long chart_id = ChartOpen(CustomSymbolName, PERIOD_M1); if(chart_id > 0) { Print("Custom chart opened."); } else { Print("Failed opening chart."); } } //+------------------------------------------------------------------+ //| Resolve which symbol the script should watch | //+------------------------------------------------------------------+ string ResolveSourceSymbol() { if(InpSourceMode == SOURCE_MODE_CHART) return(_Symbol); if(InpSourceMode == SOURCE_MODE_MANUAL) { if(SymbolSelect(InpSourceSymbol, true)) return(InpSourceSymbol); return(""); } //--- AUTO_GOLD: look for any gold alias, Market Watch first, then all symbols string found = FindGoldSymbol(true); if(StringLen(found) == 0) found = FindGoldSymbol(false); if(StringLen(found) == 0) { Print("No XAU/GOLD symbol found. Falling back to: ", InpSourceSymbol); if(SymbolSelect(InpSourceSymbol, true)) found = InpSourceSymbol; } return(found); } //+------------------------------------------------------------------+ //| Scan terminal symbol list for a gold alias | //+------------------------------------------------------------------+ string FindGoldSymbol(bool market_watch_only) { string best_name = ""; int best_score = 0; int total = SymbolsTotal(market_watch_only); for(int i = 0; i < total; i++) { string name = SymbolName(i, market_watch_only); if(StringLen(name) == 0) continue; int score = GoldScore(name); if(score > best_score) { best_score = score; best_name = name; } } return(best_name); } //+------------------------------------------------------------------+ //| Score a symbol name as a gold alias (0 = not gold) | //+------------------------------------------------------------------+ int GoldScore(string symbol) { string ucase = symbol; StringToUpper(ucase); int score = 0; if(StringFind(ucase, "XAUUSD") >= 0) score += 100; else if(StringFind(ucase, "XAU") >= 0) score += 60; else if(StringFind(ucase, "GOLD") >= 0) score += 50; else return(0); //--- slight preference for the most common names if(ucase == "XAUUSD") score += 10; if(ucase == "XAUUSD.A") score += 8; if(ucase == "XAUUSDM") score += 8; if(ucase == "GOLD") score += 5; return(score); } //+------------------------------------------------------------------+ //| Build a valid unique custom symbol name | //+------------------------------------------------------------------+ string MakeCustomSymbolName(string source_symbol, int seconds) { string name = source_symbol + "_S" + IntegerToString(seconds); //--- sanitize characters that are unsafe in custom symbol names StringReplace(name, ".", "_"); StringReplace(name, "/", "_"); StringReplace(name, "\\", "_"); StringReplace(name, " ", "_"); //--- keep inside the terminal symbol name length limit if(StringLen(name) > 60) name = StringSubstr(name, 0, 60); return(name); } //+------------------------------------------------------------------+