using System;
using System.Collections.Generic;
using System.Linq;
using MTApiService;
using System.Drawing;
using System.Collections;
using System.ServiceModel;
using MtApi.Requests;
using MtApi.Responses;
using Newtonsoft.Json;
using System.Threading.Tasks;
namespace MtApi
{
public delegate void MtApiQuoteHandler(object sender, string symbol, double bid, double ask);
public sealed class MtApiClient
{
#region MetaTrader Constants
//Special constant
public const int NULL = 0;
public const int EMPTY = -1;
private const string LogProfileName = "MtApiClient";
#endregion
#region Private Fields
private MtClient _client;
private readonly object _locker = new object();
private MtConnectionState _connectionState = MtConnectionState.Disconnected;
private volatile bool _isBacktestingMode;
private int _executorHandle;
#endregion
#region ctor
public MtApiClient()
{
LogConfigurator.Setup(LogProfileName);
}
#endregion
#region Public Methods
///
///Connect with MetaTrader API. Async method.
///
///Address of MetaTrader host (ex. 192.168.1.2)
///Port of host connection (default 8222)
public void BeginConnect(string host, int port)
{
Task.Factory.StartNew(() => Connect(host, port));
}
///
///Connect with MetaTrader API. Async method.
///
///Port of host connection (default 8222)
public void BeginConnect(int port)
{
Task.Factory.StartNew(() => Connect(port));
}
///
///Disconnect from MetaTrader API. Async method.
///
public void BeginDisconnect()
{
Task.Factory.StartNew(() => Disconnect(false));
}
///
///Load quotes connected into MetaTrader API.
///
public List GetQuotes()
{
var client = Client;
var quotes = client != null ? client.GetQuotes() : null;
return quotes?.Select(q => new MtQuote(q)).ToList();
}
#endregion
#region Properties
///
///Connection status of MetaTrader API.
///
public MtConnectionState ConnectionState
{
get
{
lock (_locker)
{
return _connectionState;
}
}
}
///
///Handle of expert used to execute commands
///
public int ExecutorHandle
{
get
{
lock (_locker)
{
return _executorHandle;
}
}
set
{
lock (_locker)
{
_executorHandle = value;
}
}
}
#endregion
#region Deprecated Methods
[Obsolete("OrderCloseByCurrentPrice is deprecated, please use OrderClose instead.")]
public bool OrderCloseByCurrentPrice(int ticket, int slippage)
{
return OrderClose(ticket, slippage);
}
[Obsolete("OrderClosePrice is deprecated, please use GetOrder instead.")]
public double OrderClosePrice()
{
return SendCommand(MtCommandType.OrderClosePrice, null);
}
[Obsolete("OrderClosePrice is deprecated, please use GetOrder instead.")]
public double OrderClosePrice(int ticket)
{
var commandParameters = new ArrayList { ticket };
double retVal = SendCommand(MtCommandType.OrderClosePriceByTicket, commandParameters);
return retVal;
}
[Obsolete("OrderCloseTime is deprecated, please use GetOrder instead.")]
public DateTime OrderCloseTime()
{
var commandResponse = SendCommand(MtCommandType.OrderCloseTime, null);
return MtApiTimeConverter.ConvertFromMtTime(commandResponse);
}
[Obsolete("OrderComment is deprecated, please use GetOrder instead.")]
public string OrderComment()
{
return SendCommand(MtCommandType.OrderComment, null);
}
[Obsolete("OrderCommission is deprecated, please use GetOrder instead.")]
public double OrderCommission()
{
return SendCommand(MtCommandType.OrderCommission, null);
}
[Obsolete("OrderExpiration is deprecated, please use GetOrder instead.")]
public DateTime OrderExpiration()
{
var commandResponse = SendCommand(MtCommandType.OrderExpiration, null);
return MtApiTimeConverter.ConvertFromMtTime(commandResponse);
}
[Obsolete("OrderLots is deprecated, please use GetOrder instead.")]
public double OrderLots()
{
return SendCommand(MtCommandType.OrderLots, null);
}
[Obsolete("OrderMagicNumber is deprecated, please use GetOrder instead.")]
public int OrderMagicNumber()
{
return SendCommand(MtCommandType.OrderMagicNumber, null);
}
[Obsolete("OrderOpenPrice is deprecated, please use GetOrder instead.")]
public double OrderOpenPrice()
{
return SendCommand(MtCommandType.OrderOpenPrice, null);
}
[Obsolete("OrderOpenPrice is deprecated, please use GetOrder instead.")]
public double OrderOpenPrice(int ticket)
{
var commandParameters = new ArrayList { ticket };
var retVal = SendCommand(MtCommandType.OrderOpenPriceByTicket, commandParameters);
return retVal;
}
[Obsolete("OrderOpenTime is deprecated, please use GetOrder instead.")]
public DateTime OrderOpenTime()
{
var commandResponse = SendCommand(MtCommandType.OrderOpenTime, null);
return MtApiTimeConverter.ConvertFromMtTime(commandResponse);
}
[Obsolete("OrderProfit is deprecated, please use GetOrder instead.")]
public double OrderProfit()
{
return SendCommand(MtCommandType.OrderProfit, null);
}
[Obsolete("OrderStopLoss is deprecated, please use GetOrder instead.")]
public double OrderStopLoss()
{
return SendCommand(MtCommandType.OrderStopLoss, null);
}
[Obsolete("OrderSymbol is deprecated, please use GetOrder instead.")]
public string OrderSymbol()
{
return SendCommand(MtCommandType.OrderSymbol, null);
}
[Obsolete("OrderTakeProfit is deprecated, please use GetOrder instead.")]
public double OrderTakeProfit()
{
return SendCommand(MtCommandType.OrderTakeProfit, null);
}
[Obsolete("OrderTicket is deprecated, please use GetOrder instead.")]
public int OrderTicket()
{
return SendCommand(MtCommandType.OrderTicket, null);
}
[Obsolete("OrderType is deprecated, please use GetOrder instead.")]
public TradeOperation OrderType()
{
var retVal = SendCommand(MtCommandType.OrderType, null);
return (TradeOperation)retVal;
}
[Obsolete("OrderSwap is deprecated, please use GetOrder instead.")]
public double OrderSwap()
{
return SendCommand(MtCommandType.OrderSwap, null);
}
#endregion
#region Trading functions
public int OrderSend(string symbol, TradeOperation cmd, double volume, double price, int slippage, double stoploss, double takeprofit
, string comment, int magic, DateTime expiration, Color arrowColor)
{
var response = SendRequest(new OrderSendRequest
{
Symbol = symbol,
Cmd = (int)cmd,
Volume = volume,
Price = price,
Slippage = slippage,
Stoploss = stoploss,
Takeprofit = takeprofit,
Comment = comment,
Magic = magic,
Expiration = MtApiTimeConverter.ConvertToMtTime(expiration),
ArrowColor = MtApiColorConverter.ConvertToMtColor(arrowColor)
});
return response?.Ticket ?? -1;
}
public int OrderSend(string symbol, TradeOperation cmd, double volume, double price, int slippage, double stoploss, double takeprofit
, string comment, int magic, DateTime expiration)
{
var response = SendRequest(new OrderSendRequest
{
Symbol = symbol,
Cmd = (int)cmd,
Volume = volume,
Price = price,
Slippage = slippage,
Stoploss = stoploss,
Takeprofit = takeprofit,
Comment = comment,
Magic = magic,
Expiration = MtApiTimeConverter.ConvertToMtTime(expiration)
});
return response?.Ticket ?? -1;
}
public int OrderSend(string symbol, TradeOperation cmd, double volume, double price, int slippage, double stoploss, double takeprofit
, string comment, int magic)
{
var response = SendRequest(new OrderSendRequest
{
Symbol = symbol,
Cmd = (int)cmd,
Volume = volume,
Price = price,
Slippage = slippage,
Stoploss = stoploss,
Takeprofit = takeprofit,
Comment = comment,
Magic = magic
});
return response?.Ticket ?? -1;
}
public int OrderSend(string symbol, TradeOperation cmd, double volume, double price, int slippage, double stoploss, double takeprofit
, string comment)
{
var response = SendRequest(new OrderSendRequest
{
Symbol = symbol,
Cmd = (int)cmd,
Volume = volume,
Price = price,
Slippage = slippage,
Stoploss = stoploss,
Takeprofit = takeprofit,
Comment = comment
});
return response?.Ticket ?? -1;
}
public int OrderSend(string symbol, TradeOperation cmd, double volume, double price, int slippage, double stoploss, double takeprofit)
{
var response = SendRequest(new OrderSendRequest
{
Symbol = symbol,
Cmd = (int)cmd,
Volume = volume,
Price = price,
Slippage = slippage,
Stoploss = stoploss,
Takeprofit = takeprofit,
});
return response?.Ticket ?? -1;
}
public int OrderSend(string symbol, TradeOperation cmd, double volume, string price, int slippage, double stoploss, double takeprofit)
{
double dPrice;
return double.TryParse(price, out dPrice) ?
OrderSend(symbol, cmd, volume, dPrice, slippage, stoploss, takeprofit) : 0;
}
public int OrderSendBuy(string symbol, double volume, int slippage)
{
return OrderSendBuy(symbol, volume, slippage, 0, 0, null, 0);
}
public int OrderSendSell(string symbol, double volume, int slippage)
{
return OrderSendSell(symbol, volume, slippage, 0, 0, null, 0);
}
public int OrderSendBuy(string symbol, double volume, int slippage, double stoploss, double takeprofit)
{
return OrderSendBuy(symbol, volume, slippage, stoploss, takeprofit, null, 0);
}
public int OrderSendSell(string symbol, double volume, int slippage, double stoploss, double takeprofit)
{
return OrderSendSell(symbol, volume, slippage, stoploss, takeprofit, null, 0);
}
public int OrderSendBuy(string symbol, double volume, int slippage, double stoploss, double takeprofit, string comment, int magic)
{
var response = SendRequest(new OrderSendRequest
{
Symbol = symbol,
Cmd = (int)TradeOperation.OP_BUY,
Volume = volume,
Slippage = slippage,
Stoploss = stoploss,
Takeprofit = takeprofit,
Comment = comment,
Magic = magic,
});
return response?.Ticket ?? -1;
}
public int OrderSendSell(string symbol, double volume, int slippage, double stoploss, double takeprofit, string comment, int magic)
{
var response = SendRequest(new OrderSendRequest
{
Symbol = symbol,
Cmd = (int)TradeOperation.OP_SELL,
Volume = volume,
Slippage = slippage,
Stoploss = stoploss,
Takeprofit = takeprofit,
Comment = comment,
Magic = magic,
});
return response?.Ticket ?? -1;
}
public bool OrderClose(int ticket, double lots, double price, int slippage, Color color)
{
var response = SendRequest(new OrderCloseRequest
{
Ticket = ticket,
Lots = lots,
Price = price,
Slippage = slippage,
ArrowColor = MtApiColorConverter.ConvertToMtColor(color)
});
return response != null;
}
public bool OrderClose(int ticket, double lots, double price, int slippage)
{
var response = SendRequest(new OrderCloseRequest
{
Ticket = ticket,
Lots = lots,
Price = price,
Slippage = slippage,
});
return response != null;
}
public bool OrderClose(int ticket, double lots, int slippage)
{
var response = SendRequest(new OrderCloseRequest
{
Ticket = ticket,
Lots = lots,
Slippage = slippage,
});
return response != null;
}
public bool OrderClose(int ticket, int slippage)
{
var response = SendRequest(new OrderCloseRequest
{
Ticket = ticket,
Slippage = slippage,
});
return response != null;
}
public bool OrderCloseBy(int ticket, int opposite, Color color)
{
var response = SendRequest(new OrderCloseByRequest
{
Ticket = ticket,
Opposite = opposite,
ArrowColor = MtApiColorConverter.ConvertToMtColor(color)
});
return response != null;
}
public bool OrderCloseBy(int ticket, int opposite)
{
var response = SendRequest(new OrderCloseByRequest
{
Ticket = ticket,
Opposite = opposite,
});
return response != null;
}
public bool OrderDelete(int ticket, Color color)
{
var response = SendRequest(new OrderDeleteRequest
{
Ticket = ticket,
ArrowColor = MtApiColorConverter.ConvertToMtColor(color),
});
return response != null;
}
public bool OrderDelete(int ticket)
{
var response = SendRequest(new OrderDeleteRequest
{
Ticket = ticket,
});
return response != null;
}
public bool OrderModify(int ticket, double price, double stoploss, double takeprofit, DateTime expiration, Color arrowColor)
{
var response = SendRequest(new OrderModifyRequest
{
Ticket = ticket,
Price = price,
Stoploss = stoploss,
Takeprofit = takeprofit,
Expiration = MtApiTimeConverter.ConvertToMtTime(expiration),
ArrowColor = MtApiColorConverter.ConvertToMtColor(arrowColor)
});
return response != null;
}
public bool OrderModify(int ticket, double price, double stoploss, double takeprofit, DateTime expiration)
{
var response = SendRequest(new OrderModifyRequest
{
Ticket = ticket,
Price = price,
Stoploss = stoploss,
Takeprofit = takeprofit,
Expiration = MtApiTimeConverter.ConvertToMtTime(expiration),
});
return response != null;
}
public void OrderPrint()
{
SendCommand