Search code examples
c#apieventsevent-handlingmetatrader5

C# Can't handle OnTick event MetaTrader Api


I am working on the MetaTrader5 Api. There is TickSubscribe (Subscribe to the events associated with changes in the database of price data.) function and OnTick (A handler of the event of new quote arrival.) event. But in .Net version OnTick event works like void method not like as known event and i couldn't figure it out. I want to catch the OnTick event and see every arrival.

            MTTickShort shot = new MTTickShort();
            CIMTTickSink sink = new CIMTTickSink();

            sink.OnTick("EURUSD", shot);

            MTRetCode code = sink.RegisterSink();
            code = m_manager.TickSubscribe(sink);

Solution

    1. Add derived class from CIMTTickSink:
    public class TickSink : CIMTTickSink
    {
        private readonly Action<string, MTTickShort> _handler;
    
        public TickSink(Action<string, MTTickShort> handler)
        {
            _handler = handler ?? throw new ArgumentNullException(nameof(handler));
    
            if (RegisterSink() != MTRetCode.MT_RET_OK) throw new Exception();
        }
    
        public override void OnTick(string symbol, MTTickShort tick) =>
            _handler.Invoke(symbol, tick);
    }
    

    There are few other methods to override in CIMTTickSink. I feel like you need this one. Decompile to observe others.

    1. Сreate CIMTManagerAPI:
    SMTManagerAPIFactory.Initialize(@".\");
    var managerApi = SMTManagerAPIFactory.CreateManager(SMTManagerAPIFactory.ManagerAPIVersion, out var ret);
    if (ret != MTRetCode.MT_RET_OK) throw new Exception();
    
    1. Connect managerApi using Mt5 server IP and manager user credentials:
    var ret = managerApi.Connect(
        _ip,
        _user,
        _password,
        null,
        // probably this should not be FULL, but seems like mode affects nothing
        CIMTManagerAPI.EnPumpModes.PUMP_MODE_FULL,
        5_000);
    
    if (ret != MTRetCode.MT_RET_OK) throw new Exception();
    
    1. Instantiate TickSink using any action you need to perform with ticks as handler and subscribe it:
    tickSink = new TickSink(_tickHandler);
    var ret = managerApi.TickSubscribe(tickSink);
    if (ret != MTRetCode.MT_RET_OK) throw new Exception();
    
    1. Done. Don't forget than CIMTTickSink and CIMTManagerAPI are disposable. Wrap it with connection is alive checks and retries and all.