Added MtEvent into MtApiService. Added event LastTimeBar into MtApi (MT4)

This commit is contained in:
DW
2016-08-30 16:01:23 +03:00
parent e24502f303
commit edc7311104
18 changed files with 238 additions and 180 deletions
+1
View File
@@ -60,6 +60,7 @@
<Compile Include="MtApiProxy.cs" />
<Compile Include="MtClient.cs" />
<Compile Include="MtCommandTask.cs" />
<Compile Include="MtEvent.cs" />
<Compile Include="MtMqlBookInfo.cs" />
<Compile Include="MtMqlRates.cs" />
<Compile Include="MtMqlTick.cs" />
+10 -12
View File
@@ -224,20 +224,14 @@ namespace MTApiService
{
Debug.WriteLine("[INFO] MtClient::OnQuoteAdded");
if (QuoteAdded != null)
{
QuoteAdded(quote);
}
QuoteAdded?.Invoke(quote);
}
public void OnQuoteRemoved(MtQuote quote)
{
Debug.WriteLine("[INFO] MtClient::OnQuoteRemoved");
if (QuoteRemoved != null)
{
QuoteRemoved(quote);
}
QuoteRemoved?.Invoke(quote);
}
public void OnServerStopped()
@@ -246,10 +240,13 @@ namespace MTApiService
Close();
if (ServerDisconnected != null)
{
ServerDisconnected(this, EventArgs.Empty);
}
ServerDisconnected?.Invoke(this, EventArgs.Empty);
}
public void OnMtEvent(MtEvent mtEvent)
{
MtEventReceived?.Invoke(this, new MtEventArgs(mtEvent));
}
#endregion
@@ -301,6 +298,7 @@ namespace MTApiService
public event MtQuoteHandler QuoteUpdated;
public event EventHandler ServerDisconnected;
public event EventHandler ServerFailed;
public event EventHandler<MtEventArgs> MtEventReceived;
#endregion
#region Fields
+36
View File
@@ -0,0 +1,36 @@
using System;
using System.Runtime.Serialization;
namespace MTApiService
{
[DataContract]
public class MtEvent
{
[DataMember]
public int EventType { get; private set; }
[DataMember]
public string Payload { get; private set; }
public MtEvent(int eventType, string payload)
{
EventType = eventType;
Payload = payload;
}
public override string ToString()
{
return "MtEvent = " + EventType + ", Payload = " + Payload;
}
}
public class MtEventArgs: EventArgs
{
public MtEventArgs(MtEvent e)
{
Event = e;
}
public MtEvent Event { get; private set; }
}
}
+15 -15
View File
@@ -66,6 +66,7 @@ namespace MTApiService
}
}
}
#endregion
#region Public Methods
@@ -114,6 +115,11 @@ namespace MTApiService
return null;
}
public void SendEvent(MtEvent mtEvent)
{
FireOnMtEvent(mtEvent);
}
#endregion
#region IMtCommandExecutor
@@ -134,29 +140,22 @@ namespace MTApiService
private void FireOnQuoteChanged(MtQuote quote)
{
var handler = QuoteChanged;
if (handler != null)
{
handler(this, quote);
}
QuoteChanged?.Invoke(this, quote);
}
private void FireOnDeinited()
{
var handler = Deinited;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
Deinited?.Invoke(this, EventArgs.Empty);
}
private void FireOnCommandExecuted()
{
var handler = CommandExecuted;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
CommandExecuted?.Invoke(this, EventArgs.Empty);
}
private void FireOnMtEvent(MtEvent mtEvent)
{
OnMtEvent?.Invoke(this, new MtEventArgs(mtEvent));
}
#endregion
@@ -164,6 +163,7 @@ namespace MTApiService
public event EventHandler Deinited;
public event MtQuoteHandler QuoteChanged;
public event EventHandler CommandExecuted;
public event EventHandler<MtEventArgs> OnMtEvent;
#endregion
#region Private Fields
+7 -5
View File
@@ -107,6 +107,7 @@ namespace MTApiService
{
expert.Deinited += expert_Deinited;
expert.QuoteChanged += expert_QuoteChanged;
expert.OnMtEvent += Expert_OnMtEvent;
lock (_experts)
{
@@ -308,13 +309,14 @@ namespace MTApiService
_service.QuoteUpdate(quote);
}
private void Expert_OnMtEvent(object sender, MtEventArgs e)
{
_service.OnMtEvent(e.Event);
}
private void FireOnStopped()
{
var handler = Stopped;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
Stopped?.Invoke(this, EventArgs.Empty);
}
#endregion
+18
View File
@@ -101,6 +101,24 @@ namespace MTApiService
Debug.WriteLine("MtApiServerInstance::SendQuote: finish.");
}
public void SendEvent(int expertHandle, int eventType, string payload)
{
Debug.WriteLine("MtApiServerInstance::SendEvent called. eventType = {0}, payload = {1}", eventType, payload);
MtExpert expert = null;
lock (mExpertsDictionary)
{
expert = mExpertsDictionary[expertHandle];
}
if (expert != null)
{
expert.SendEvent(new MtEvent(eventType, payload));
}
Debug.WriteLine("MtApiServerInstance::SendEvent: finished");
}
public void SendResponse(int expertHandle, MtResponse response)
{
Debug.WriteLine("MtApiServerInstance::SendResponse: id = {0}, response = {1}", expertHandle, response);
+38 -132
View File
@@ -35,6 +35,9 @@ namespace MTApiService
[OperationContract(IsOneWay = true)]
void OnQuoteRemoved(MtQuote quote);
[OperationContract(IsOneWay = true)]
void OnMtEvent(MtEvent ntEvent);
}
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
@@ -123,171 +126,74 @@ namespace MTApiService
#region Public Methods
public void OnStopServer()
{
try
{
mClientsLocker.AcquireReaderLock(2000);
try
{
foreach (var callback in mClientCallbacks)
{
try
{
callback.OnServerStopped();
}
catch (Exception)
{
}
}
}
finally
{
mClientsLocker.ReleaseReaderLock();
}
}
catch (ApplicationException)
{
}
ExecuteCallbackAction(a => a.OnServerStopped());
}
public void QuoteUpdate(MtQuote quote)
{
try
{
mClientsLocker.AcquireReaderLock(200);
List<IMtApiCallback> crashedClientsCallback = null;
try
{
foreach (var callback in mClientCallbacks)
{
try
{
callback.OnQuoteUpdate(quote);
}
catch (Exception)
{
if (crashedClientsCallback == null)
crashedClientsCallback = new List<IMtApiCallback>();
crashedClientsCallback.Add(callback);
}
}
}
finally
{
mClientsLocker.ReleaseReaderLock();
}
removeCrashedClientCallbacks(crashedClientsCallback);
}
catch (ApplicationException)
{
}
ExecuteCallbackAction(a => a.OnQuoteUpdate(quote));
}
public void OnQuoteAdded(MtQuote quote)
{
try
{
mClientsLocker.AcquireReaderLock(2000);
List<IMtApiCallback> crashedClientsCallback = null;
try
{
foreach (var callback in mClientCallbacks)
{
try
{
callback.OnQuoteAdded(quote);
}
catch (Exception)
{
if (crashedClientsCallback == null)
crashedClientsCallback = new List<IMtApiCallback>();
crashedClientsCallback.Add(callback);
}
}
}
finally
{
mClientsLocker.ReleaseReaderLock();
}
removeCrashedClientCallbacks(crashedClientsCallback);
}
catch (ApplicationException)
{
}
ExecuteCallbackAction(a => a.OnQuoteAdded(quote));
}
public void OnQuoteRemoved(MtQuote quote)
{
try
{
mClientsLocker.AcquireReaderLock(2000);
ExecuteCallbackAction(a => a.OnQuoteRemoved(quote));
}
List<IMtApiCallback> crashedClientsCallback = null;
try
{
foreach (var callback in mClientCallbacks)
{
try
{
callback.OnQuoteRemoved(quote);
}
catch (Exception)
{
if (crashedClientsCallback == null)
crashedClientsCallback = new List<IMtApiCallback>();
crashedClientsCallback.Add(callback);
}
}
}
finally
{
mClientsLocker.ReleaseReaderLock();
}
removeCrashedClientCallbacks(crashedClientsCallback);
}
catch (ApplicationException)
{
}
public void OnMtEvent(MtEvent mtEvent)
{
ExecuteCallbackAction(a => a.OnMtEvent(mtEvent));
}
#endregion
#region Private Methods
private void removeCrashedClientCallbacks(List<IMtApiCallback> crashedClientCallbacks)
private void ExecuteCallbackAction(Action<IMtApiCallback> action)
{
if (crashedClientCallbacks != null)
try
{
mClientsLocker.AcquireReaderLock(2000);
List<IMtApiCallback> crashedClientCallbacks = null;
try
{
mClientsLocker.AcquireWriterLock(200);
foreach (var callback in mClientCallbacks)
{
try
{
action(callback);
}
catch (Exception)
{
if (crashedClientCallbacks == null)
crashedClientCallbacks = new List<IMtApiCallback>();
try
crashedClientCallbacks.Add(callback);
}
}
if (crashedClientCallbacks != null)
{
foreach (var crashedCallback in crashedClientCallbacks)
{
mClientCallbacks.Remove(crashedCallback);
}
}
finally
{
mClientsLocker.ReleaseWriterLock();
}
}
catch (ApplicationException)
finally
{
mClientsLocker.ReleaseReaderLock();
}
}
catch (ApplicationException)
{
//TODO: add logging
}
}
#endregion
+16
View File
@@ -71,6 +71,22 @@ int _stdcall updateQuote(int expertHandle, wchar_t* symbol, double bid, double a
return 1;
}
int _stdcall sendEvent(int expertHandle, int eventType, wchar_t* payload, wchar_t* err)
{
try
{
MtServerInstance::GetInstance()->SendEvent(expertHandle, eventType, gcnew String(payload));
}
catch (Exception^ e)
{
convertSystemString(err, e->Message);
Debug::WriteLine("[ERROR] MTConnector:updateTimeBar(): " + e->Message);
return 0;
}
return 1;
}
int _stdcall sendIntResponse(int expertHandle, int response)
{
try
+1
View File
@@ -3,6 +3,7 @@ LIBRARY MTConnector
EXPORTS initExpert
deinitExpert
updateQuote
sendEvent
sendIntResponse
sendBooleanResponse
sendDoubleResponse
+2 -8
View File
@@ -1,14 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MtApi
namespace MtApi
{
static class ExtensionMethods
{
public static MtQuote Parse(this MTApiService.MtQuote quote)
public static MtQuote Convert(this MTApiService.MtQuote quote)
{
return (quote != null) ? new MtQuote(quote.Instrument, quote.Bid, quote.Ask) : null;
}
+3
View File
@@ -66,10 +66,12 @@
<Compile Include="MtConnectionState.cs" />
<Compile Include="MtCommandType.cs" />
<Compile Include="MtErrorCode.cs" />
<Compile Include="MtEventTypes.cs" />
<Compile Include="MtExecutionException.cs" />
<Compile Include="MtOrder.cs" />
<Compile Include="MtQuote.cs" />
<Compile Include="MtQuoteEventArgs.cs" />
<Compile Include="MtTimeBar.cs" />
<Compile Include="MtTypes.cs" />
<Compile Include="PriceConstantsType.cs" />
<Compile Include="MarketInfoModeType.cs" />
@@ -95,6 +97,7 @@
<Compile Include="Responses\OrderSendResponse.cs" />
<Compile Include="Responses\ResponseBase.cs" />
<Compile Include="SeriesIdentifier.cs" />
<Compile Include="TimeBarArgs.cs" />
<Compile Include="TradeOperation.cs" />
<Compile Include="MtApiTimeConverter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+31 -8
View File
@@ -29,11 +29,12 @@ namespace MtApi
public MtApiClient()
{
_client.QuoteAdded +=new MtClient.MtQuoteHandler(mClient_QuoteAdded);
_client.QuoteRemoved += new MtClient.MtQuoteHandler(mClient_QuoteRemoved);
_client.QuoteUpdated += new MtClient.MtQuoteHandler(mClient_QuoteUpdated);
_client.ServerDisconnected += new EventHandler(mClient_ServerDisconnected);
_client.ServerFailed += new EventHandler(mClient_ServerFailed);
_client.QuoteAdded += mClient_QuoteAdded;
_client.QuoteRemoved += mClient_QuoteRemoved;
_client.QuoteUpdated += mClient_QuoteUpdated;
_client.ServerDisconnected += mClient_ServerDisconnected;
_client.ServerFailed += mClient_ServerFailed;
_client.MtEventReceived += _client_MtEventReceived;
}
#endregion
@@ -81,7 +82,7 @@ namespace MtApi
public IEnumerable<MtQuote> GetQuotes()
{
var quotes = _client.GetQuotes();
return quotes != null ? (from q in quotes select q.Parse()) : null;
return quotes != null ? (from q in quotes select q.Convert()) : null;
}
#endregion
@@ -1597,14 +1598,35 @@ namespace MtApi
private void mClient_QuoteRemoved(MTApiService.MtQuote quote)
{
var handler = QuoteRemoved;
handler?.BeginInvoke(this, new MtQuoteEventArgs(quote.Parse()), (a) => handler.EndInvoke(a), null);
handler?.BeginInvoke(this, new MtQuoteEventArgs(quote.Convert()), (a) => handler.EndInvoke(a), null);
}
private void mClient_QuoteAdded(MTApiService.MtQuote quote)
{
var handler = QuoteAdded;
handler?.BeginInvoke(this, new MtQuoteEventArgs(quote.Parse()), (a) => handler.EndInvoke(a), null);
handler?.BeginInvoke(this, new MtQuoteEventArgs(quote.Convert()), (a) => handler.EndInvoke(a), null);
}
private void _client_MtEventReceived(object sender, MtEventArgs e)
{
MtEventTypes eventType = (MtEventTypes) e.Event.EventType;
switch(eventType)
{
case MtEventTypes.LastTimeBar:
{
FireOnLastTimeBar(JsonConvert.DeserializeObject<MtTimeBar>(e.Event.Payload));
}
break;
}
}
private void FireOnLastTimeBar(MtTimeBar timeBar)
{
var handler = OnLastTimeBar;
handler?.BeginInvoke(this, new TimeBarArgs(timeBar), (a) => handler.EndInvoke(a), null);
}
#endregion
#region Events
@@ -1612,6 +1634,7 @@ namespace MtApi
public event EventHandler<MtQuoteEventArgs> QuoteAdded;
public event EventHandler<MtQuoteEventArgs> QuoteRemoved;
public event EventHandler<MtConnectionEventArgs> ConnectionStateChanged;
public event EventHandler<TimeBarArgs> OnLastTimeBar;
#endregion
#region Private Fields
+7
View File
@@ -0,0 +1,7 @@
namespace MtApi
{
public enum MtEventTypes
{
LastTimeBar = 1
}
}
+26
View File
@@ -0,0 +1,26 @@
using System;
namespace MtApi
{
public class MtTimeBar
{
public string Symbol { get; set; }
public int MtOpenTime { get; set; }
public int MtCloseTime { get; set; }
public double Open { get; set; }
public double Close { get; set; }
public double High { get; set; }
public double Low { get; set; }
public DateTime OpenTime
{
get { return MtApiTimeConverter.ConvertFromMtTime(MtOpenTime); }
}
public DateTime CloseTime
{
get { return MtApiTimeConverter.ConvertFromMtTime(MtCloseTime); }
}
}
}
+18
View File
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MtApi
{
public class TimeBarArgs: EventArgs
{
public TimeBarArgs(MtTimeBar timeBar)
{
TimeBar = timeBar;
}
public MtTimeBar TimeBar { get; private set; }
}
}
+9
View File
@@ -23,6 +23,7 @@ namespace TestApiClientUI
_apiClient.QuoteAdded += apiClient_QuoteAdded;
_apiClient.QuoteRemoved += apiClient_QuoteRemoved;
_apiClient.ConnectionStateChanged += apiClient_ConnectionStateChanged;
_apiClient.OnLastTimeBar += _apiClient_OnLastTimeBar;
initOrderCommandsGroup();
@@ -95,6 +96,14 @@ namespace TestApiClientUI
RunOnUiThread(() => AddNewQuote(e.Quote));
}
private void _apiClient_OnLastTimeBar(object sender, TimeBarArgs e)
{
string msg = string.Format("TimeBar: Symbol = {0}, OpenTime = {1}, CloseTime = {2}, Open = {3}, Close = {4}, High = {5}, Low = {6}",
e.TimeBar.Symbol, e.TimeBar.OpenTime, e.TimeBar.CloseTime, e.TimeBar.Open, e.TimeBar.Close, e.TimeBar.High, e.TimeBar.Low);
Console.WriteLine(msg);
AddToLog(msg);
}
private volatile bool IsUiQuoteUpdateReady = true;
private void apiClient_QuoteUpdated(object sender, string symbol, double bid, double ask)
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.