// Snippet 3: one day of work per step, driven by a timer (TF_Engine.mqh and Tick_Forge.mq5) bool CTFEngine::Step(CTFResult &res) { if(Done()) { res.ok = true; return true; } if((int)(GetTickCount() - m_ready_at) < 0) return true; // symbol still settling datetime day = m_job.from + (datetime)m_i * 86400; bool ok = (m_job.mode == TF_MODE_TICKS ? WriteTicksDay(day, res) : WriteBarsChunk(day, day + 86400 - 60, res)); if(!ok) return false; if(m_bad > 0) { res.err = "function produced an invalid price"; return false; } TF_Status(StringFormat("%s day %d/%d ticks %I64d M1 bars %I64d", TimeToString(day, TIME_DATE), m_i + 1, m_days, res.ticks, res.bars)); m_i++; if(Done()) res.ok = true; return true; } void OnTimer() { if(g_dlg == NULL) return; g_dlg.Tick(); // one day / one month of work per call, so the window stays responsive if(g_dlg.Closed()) ExpertRemove(); }