diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9bea433
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+
+.DS_Store
diff --git a/Experts/api.mq5 b/Experts/api.mq5
new file mode 100644
index 0000000..28140e4
Binary files /dev/null and b/Experts/api.mq5 differ
diff --git a/Experts/backtrader.mq5 b/Experts/backtrader.mq5
deleted file mode 100644
index ebc4839..0000000
--- a/Experts/backtrader.mq5
+++ /dev/null
@@ -1,611 +0,0 @@
-//+------------------------------------------------------------------+
-//
-// Copyright (C) 2019 Nikolai Khramkov
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-//
-//+------------------------------------------------------------------+
-
-// TODO: Close position
-// TODO: Close orders
-// TODO: Check If SymbolExist
-// TODO: Check TF according to request -> change
-// TODO: Check chart symbol according to request -> change
-// TODO: RETURN OK or error
-// TODO: Write comment about sockets
-// TODO: Add defauld dict check
-// TODO: Change description
-// TODO: Comissinos
-
-#property copyright "Copyright 2019, Nikolai Khramkov."
-#property link "https://github.com/khramkov"
-#property version "0.70"
-
-#include
-#include
-
-extern string PROJECT_NAME="Backtrader <-> Metatrader 5 interface";
-extern string PROTOCOL="tcp";
-extern string HOST="*";
-extern int SYS_PORT=15555;
-extern int DATA_PORT=15556;
-extern int LIVE_PORT=15557;
-extern int MILLISECOND_TIMER=1; // 1 millisecond
-
-// ZeroMQ Cnnections
-Context context(PROJECT_NAME);
-Socket sysSocket(context,ZMQ_REP);
-Socket dataSocket(context,ZMQ_PUSH);
-Socket liveSocket(context,ZMQ_PUSH);
-
-// Global variables
-bool debug = true;
-datetime lastBar = 0;
-string symbol = _Symbol;
-ENUM_TIMEFRAMES period = _Period;
-
-//+------------------------------------------------------------------+
-//| Expert initialization function |
-//+------------------------------------------------------------------+
-int OnInit()
- {
- /*
- Bindinig ZMQ ports on init
- */
-
- // Set Millisecond Timer to get client socket input
- EventSetMillisecondTimer(MILLISECOND_TIMER);
-
- Print("[REP] Binding System Socket on port "+IntegerToString(SYS_PORT)+"...");
- sysSocket.bind(StringFormat("%s://%s:%d",PROTOCOL,HOST,SYS_PORT));
-
- Print("[PUSH] Binding Data Socket on port "+IntegerToString(DATA_PORT)+"...");
- dataSocket.bind(StringFormat("%s://%s:%d",PROTOCOL,HOST,DATA_PORT));
-
- Print("[PUSH] Binding Live Socket on port "+IntegerToString(LIVE_PORT)+"...");
- liveSocket.bind(StringFormat("%s://%s:%d",PROTOCOL,HOST,LIVE_PORT));
-
- // Maximum amount of time in milliseconds that the thread will try to send messages
- // after its socket has been closed (the default value of -1 means to linger forever):
- sysSocket.setLinger(1000);
-
- // How many messages do we want ZeroMQ to buffer in RAM before blocking the socket?
- // 3 messages only.
- sysSocket.setSendHighWaterMark(3);
- dataSocket.setSendHighWaterMark(3);
- liveSocket.setSendHighWaterMark(3);
-
- return(INIT_SUCCEEDED);
- }
-//+------------------------------------------------------------------+
-//| Expert deinitialization function |
-//+------------------------------------------------------------------+
-void OnDeinit(const int reason)
- {
- /*
- Closing ports on denit
- */
- Print("[REP] Unbinding socket on port "+IntegerToString(SYS_PORT)+"..");
- sysSocket.unbind(StringFormat("%s://%s:%d",PROTOCOL,HOST,SYS_PORT));
-
- Print("[PUSH] Unbinding socket on port "+IntegerToString(DATA_PORT)+"..");
- dataSocket.unbind(StringFormat("%s://%s:%d",PROTOCOL,HOST,DATA_PORT));
-
- Print("[PUSH] Unbinding socket on port "+IntegerToString(LIVE_PORT)+"..");
- liveSocket.unbind(StringFormat("%s://%s:%d",PROTOCOL,HOST,LIVE_PORT));
-
- }
-//+------------------------------------------------------------------+
-//| Expert timer function |
-//+------------------------------------------------------------------+
-void OnTimer()
- {
- ZmqMsg request;
-
- // Get client's response, but don't wait.
- sysSocket.recv(request,true);
-
- // Generating reply by passing request to ZmqMsg MessageHandler() function.
- ZmqMsg reply=MessageHandler(request);
-
- // Reply to client via REP socket.
- sysSocket.send(reply);
- }
-
-//+------------------------------------------------------------------+
-//| Request handler |
-//+------------------------------------------------------------------+
-ZmqMsg MessageHandler(ZmqMsg &request)
- {
- ZmqMsg reply;
- CJAVal message;
-
- if(request.size()>0)
- {
-
- string msg=request.getData();
-
- if(debug==true) {Print("Processing request:"+msg);}
-
- if(!message.Deserialize(msg))
- {
- Alert("Deserialization Error");
-
- //ExpertRemove();
- //return;
- }
-
- string action = message["action"].ToStr();
-
- if(action=="CHECK") {CheckConnection(&dataSocket, &liveSocket);}
- else if(action=="CONFIG") {ConfigScript(&dataSocket, message);}
- else if(action=="ACCOUNT") {AccountInfo(&dataSocket);}
- else if(action=="BALANCE") {BalanceInfo(&dataSocket);}
- else if(action=="HISTORY") {HistoryInfo(&dataSocket, message);}
- else if(action=="POSITIONS_INFO") {GetPositionsInfo(&dataSocket);}
- else if(action=="ORDERS_INFO") {GetOrdersInfo(&dataSocket);}
- else if(action=="TRADE") {TradingModule(&dataSocket, message);}
- else {} // error processing
-
- // Construct response
- ZmqMsg ret("OK");
- reply=ret;
-
- }
- else
- {
- // NO DATA RECEIVED
- ZmqMsg ret("FALSE");
- reply=ret;
- }
-
- return(reply);
- }
-
-//+------------------------------------------------------------------+
-//| Check sockets connection |
-//+------------------------------------------------------------------+
-void CheckConnection (Socket &dataSocket, Socket &liveSocket)
- {
- InformClientSocket(dataSocket,"OK");
- InformClientSocket(liveSocket,"OK");
- }
-
-
-//+------------------------------------------------------------------+
-//| Reconfigure the script params |
-//+------------------------------------------------------------------+
-void ConfigScript(Socket &dataSocket, CJAVal &dataObject)
- {
-
- }
-
-//+------------------------------------------------------------------+
-//| Change chart timeframe |
-//+------------------------------------------------------------------+
-void CheckTimeframe(Socket &dataSocket, CJAVal &dataObject)
- {
- string chartTF=dataObject["chartTF"].ToStr();
-
- if(chartTF=="1m") {period=PERIOD_M1;}
- else if(chartTF=="5m") {period=PERIOD_M5;}
- else if(chartTF=="15m") {period=PERIOD_M15;}
- else if(chartTF=="30m") {period=PERIOD_M30;}
- else if(chartTF=="1h") {period=PERIOD_H1;}
- else if(chartTF=="2h") {period=PERIOD_H2;}
- else if(chartTF=="3h") {period=PERIOD_H3;}
- else if(chartTF=="4h") {period=PERIOD_H4;}
- else if(chartTF=="6h") {period=PERIOD_H6;}
- else if(chartTF=="8h") {period=PERIOD_H8;}
- else if(chartTF=="12h") {period=PERIOD_H12;}
- else if(chartTF=="1d") {period=PERIOD_D1;}
- else if(chartTF=="1w") {period=PERIOD_W1;}
- else if(chartTF=="1M") {period=PERIOD_MN1;}
- }
-
-//+------------------------------------------------------------------+
-//| Account information |
-//+------------------------------------------------------------------+
-void AccountInfo(Socket &dataSocket)
- {
- CJAVal info;
-
- info["brocker"] = AccountInfoString(ACCOUNT_COMPANY);
- info["currency"] = AccountInfoString(ACCOUNT_CURRENCY);
- info["server"] = AccountInfoString(ACCOUNT_SERVER);
- info["balance"] = AccountInfoDouble(ACCOUNT_BALANCE);
- info["equity"] = AccountInfoDouble(ACCOUNT_EQUITY);
- info["margin"] = AccountInfoDouble(ACCOUNT_MARGIN);
- info["margin_free"] = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
- info["margin_level"] = AccountInfoDouble(ACCOUNT_MARGIN_LEVEL);
- info["bot_trading"] = AccountInfoInteger(ACCOUNT_TRADE_EXPERT);
- string t=info.Serialize();
- if(debug==true) {Print(t);}
- InformClientSocket(dataSocket,t);
- }
-
-//+------------------------------------------------------------------+
-//| Balance information |
-//+------------------------------------------------------------------+
-void BalanceInfo(Socket &dataSocket)
- {
- CJAVal info;
-
- info["balance"] = AccountInfoDouble(ACCOUNT_BALANCE);
- info["equity"] = AccountInfoDouble(ACCOUNT_EQUITY);
- info["margin"] = AccountInfoDouble(ACCOUNT_MARGIN);
- info["margin_free"] = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
- string t=info.Serialize();
- if(debug==true) {Print(t);}
- InformClientSocket(dataSocket,t);
- }
-
-
-//+------------------------------------------------------------------+
-//| Get historical data |
-//+------------------------------------------------------------------+
-void HistoryInfo(Socket &dataSocket, CJAVal &dataObject)
- {
- CJAVal candles;
- MqlRates rates[];
-
- int copied;
- string actionType=dataObject["actionType"].ToStr();
- string symbol=dataObject["symbol"].ToStr();
- string chartTF=dataObject["chartTF"].ToStr();
- datetime startTime=dataObject["startTime"].ToInt();
-
- if(debug==true)
- {
- Print("Fetching HISTORY");
- Print("1) Symbol:"+symbol);
- Print("2) Timeframe:"+chartTF);
- Print("3) Date from:"+TimeToString(startTime));
- }
- copied=CopyRates(symbol,period,startTime,TimeCurrent(),rates);
- if(copied)
-
- {
- for(int i=0;i