vdemydiuk / mtapi

MetaTrader API (terminal bridge)
http://mtapi4.net/
MIT License
523 stars 281 forks source link

[Question] mtApi only called once #66

Closed mhamri closed 6 years ago

mhamri commented 6 years ago

hi, thanks for this awesome works

i wrote a small console application to test mtAPI and i have some issue to make it to run it smoothly.

I'm testing the mtAPi with the backtest. If I close the meta trader and open it again, then since it's the first time that mtAPI is called and there is only one quote, then everything is fine.

but if i stop the backtest, then start it again, then two problems happens

  1. the previous backtest quote still is running and connected (if you look at second picture there is two EURUSD quote, even i close the console application and run it again, the only way to restart it is to close metatrader)

  2. i can't get second backtest information, in the backtest log i'm getting waiting for remote client error (even my console already is connected!)

image

and the console application can't get the quote informations image

even if i close and open the console application, still it can't connect to quote successfully and backtest remain in waiting for remote client ... state

another problem that i have is i can't figure out what is the use case of TimerTradeMonitor and TimeframeTradeMonitor. do you have any documentation about this? I took a look at them and couldn't find what is the difference and the logic behind to call them.

the code is borrowed from the winform application, to help me to to figure out mechanic behind the mtAPI.

the code look like bellow

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MtApi;
using MtApi.Monitors;

namespace Test.ForexStart
{
    class Program
    {
        static MtApiClient _apiClient;
        static TimeframeTradeMonitor _timeframe;
        static TimerTradeMonitor _timerTrade; // 10 sec;
        static void Main(string[] args)
        {

            _apiClient = new MtApiClient();

            _timerTrade = new TimerTradeMonitor(_apiClient) { Interval = 10000 };
            _timerTrade.AvailabilityOrdersChanged += T2OnAvailabilityOrdersChanged;

            _timeframe = new TimeframeTradeMonitor(_apiClient);
            _timeframe.AvailabilityOrdersChanged += OnTimeframeOnAvailabilityOrdersChanged;

            _apiClient.QuoteUpdated += OnQuoteUpdated;
            _apiClient.QuoteUpdate += OnQuoteUpdate;
            _apiClient.QuoteAdded += OnQuoteAdded;
            _apiClient.ConnectionStateChanged += OnConnectionStateChanged;
            _apiClient.OnChartEvent += OnChartEvent;
            _apiClient.OnLastTimeBar += OnLastTimeBar;

            TryToConnect();
            ConsoleKeyInfo input;
            do
            {
                input = Console.ReadKey();
            } while (input.Key != ConsoleKey.Escape);

            TryToDisconnect();
        }

        private static void TryToConnect()
        {
            _timerTrade.Start();
            _timeframe.Start();

            _apiClient.BeginConnect("localhost", 8222);
        }

        private static void TryToDisconnect()
        {
            _timerTrade.Stop();
            _timeframe.Stop();

            _apiClient.BeginDisconnect();
        }

        private static void OnQuoteUpdated(object sender, string symbol, double bid, double ask)
        {
            Console.WriteLine("on quote updated!!");
        }

        private static void OnQuoteUpdate(object sender, MtQuoteEventArgs e)
        {
            Console.WriteLine("on quote update");
        }

        private static void OnQuoteAdded(object sender, MtQuoteEventArgs e)
        {
            if (e.Quote != null)
            {
                Console.WriteLine("on quoteAdded");
                Console.WriteLine(e.Quote);

            }

        }

        private static void OnLastTimeBar(object sender, TimeBarArgs e)
        {
            var msg =
                $"TimeBar: ExpertHandle = {e.ExpertHandle}, Symbol = {e.TimeBar.Symbol}, OpenTime = {e.TimeBar.OpenTime}, CloseTime = {e.TimeBar.CloseTime}, Open = {e.TimeBar.Open}, Close = {e.TimeBar.Close}, High = {e.TimeBar.High}, Low = {e.TimeBar.Low}";
            Console.WriteLine(msg);
        }

        private static void OnChartEvent(object sender, ChartEventArgs e)
        {
            Console.WriteLine("on chart event");
        }

        private static void OnConnectionStateChanged(object sender, MtConnectionEventArgs e)
        {
            Console.WriteLine("on connection change");
            Console.WriteLine(e.Status);
            var quotes = _apiClient.GetQuotes();

            if (quotes != null)
            {
                foreach (var quote in quotes)
                {
                    Console.WriteLine(quote.Instrument);
                }
            }

            if (e.Status != MtConnectionState.Connected || e.Status != MtConnectionState.Connecting)
            {
                Task.Delay(1000).ContinueWith(task => TryToConnect()).Wait();
            }
        }

        private static void T2OnAvailabilityOrdersChanged(object sender, AvailabilityOrdersEventArgs availabilityOrdersEventArgs)
        {
            Console.WriteLine("t2");
        }

        private static void OnTimeframeOnAvailabilityOrdersChanged(object sender, AvailabilityOrdersEventArgs availabilityOrdersEventArgs)
        {
            Console.WriteLine("t1");
        }
    }
}
mhamri commented 6 years ago

i found the solution for this by running this two line of code

Client.ExecutorHandle = availableQuote.ExpertId;

Client.UnlockTicks();
vdemydiuk commented 6 years ago

Ok. I am closing this issue.