Closed masfen closed 4 months ago
sorry i forgot to include the code and some more info, pyzmq came pre-installed with anaconda3
full error traceback:
Time= trade.get_Time2(symbol= 'EURUSD', timeframe= 'H1', start_bar=0, end_bar=2)
Traceback (most recent call last):
File "<ipython-input-3-9df761737036>", line 1, in <module>
Time= trade.get_Time2(symbol= 'EURUSD', timeframe= 'H1', start_bar=0, end_bar=2)
File "C:\Users\User\Documents\Programming\PFTNNS\pythonicMT4.py", line 145, in get_Time2
self.remote_send(self.reqSocket, self.time)
File "C:\Users\User\Documents\Programming\PFTNNS\pythonicMT4.py", line 27, in remote_send
msg_send = socket.recv_string()
File "C:\Users\User\Anaconda3\lib\site-packages\zmq\sugar\socket.py", line 585, in recv_string
return self._deserialize(msg, lambda buf: buf.decode(encoding))
File "C:\Users\User\Anaconda3\lib\site-packages\zmq\sugar\socket.py", line 491, in _deserialize
return load(recvd)
File "C:\Users\User\Anaconda3\lib\site-packages\zmq\sugar\socket.py", line 585, in <lambda>
return self._deserialize(msg, lambda buf: buf.decode(encoding))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x84 in position 0: invalid start byte
the code:
import zmq
import numpy as np
class zmq_python():
def __init__(self):
# Create ZMQ Context
self.context = zmq.Context()
# Create REQ Socket
self.reqSocket = self.context.socket(zmq.REQ)
self.reqSocket.connect("tcp://localhost:5555")
# Create PULL Socket
self.pullSocket = self.context.socket(zmq.PULL)
self.pullSocket.connect("tcp://localhost:5556")
# Create PULL2 Socket
self.pullSocket2 = self.context.socket(zmq.PULL)
self.pullSocket2.connect("tcp://localhost:5557")
def remote_send(self, socket, data):
try:
socket.send_string(data)
msg_send = socket.recv_string()
print (msg_send)
except zmq.Again as e:
print ("Waiting for PUSH from MetaTrader 4..")
print (str(e))
def remote_pull(self, socket):
try:
msg_pull = ''
msg_pull = socket.recv(flags=zmq.NOBLOCK)
print (msg_pull)
return msg_pull
except zmq.Again as e:
print ("Waiting for PUSH from MetaTrader 4..")
print (str(e))
def get_Open(self, symbol, timeframe, start_bar, end_bar):
'''
only start_bar and end_bar as int
'''
self.open = "OPEN|"+ symbol+"|"+"PERIOD_"+timeframe+"|"+str(start_bar)+"|"+str(end_bar+1)
self.remote_send(self.reqSocket, self.open)
Open = self.remote_pull(self.pullSocket)
Open_str= str(Open)
if 'OPEN' in Open_str:
Open_lst= Open_str.split(sep='|')[1:-1]
Open_lst= [float(i) for i in Open_lst]
Open_lst= Open_lst[::-1]
Open_arr= np.array(Open_lst)
return Open_arr
def get_High(self, symbol, timeframe, start_bar, end_bar):
'''
only start_bar and end_bar as int
'''
self.high = "HIGH|"+ symbol+"|"+"PERIOD_"+timeframe+"|"+str(start_bar)+"|"+str(end_bar+1)
self.remote_send(self.reqSocket, self.high)
High= self.remote_pull(self.pullSocket)
High_str= str(High)
if 'HIGH' in High_str:
High_lst= High_str.split(sep='|')[1:-1]
High_lst= [float(i) for i in High_lst]
High_lst= High_lst[::-1]
High_arr= np.array(High_lst)
return High_arr
def get_Low(self, symbol, timeframe, start_bar, end_bar):
'''
only start_bar and end_bar as int
'''
self.low = "LOW|"+ symbol+"|"+"PERIOD_"+timeframe+"|"+str(start_bar)+"|"+str(end_bar+1)
self.remote_send(self.reqSocket, self.low)
Low= self.remote_pull(self.pullSocket)
Low_str= str(Low)
if 'LOW' in Low_str:
Low_lst= Low_str.split(sep='|')[1:-1]
Low_lst= [float(i) for i in Low_lst]
Low_lst= Low_lst[::-1]
Low_arr= np.array(Low_lst)
return Low_arr
def get_Close(self, symbol, timeframe, start_bar, end_bar):
'''
only start_bar and end_bar as int
'''
self.close = "CLOSE|"+ symbol+"|"+"PERIOD_"+timeframe+"|"+str(start_bar)+"|"+str(end_bar+1)
self.remote_send(self.reqSocket, self.close)
Close= self.remote_pull(self.pullSocket)
Close_str= str(Close)
if 'CLOSE' in Close_str:
Close_lst= Close_str.split(sep='|')[1:-1]
Close_lst= [float(i) for i in Close_lst]
Close_lst= Close_lst[::-1]
Close_arr= np.array(Close_lst)
return Close_arr
def get_Vol(self, symbol, timeframe, start_bar, end_bar):
'''
only start_bar and end_bar as int
'''
self.vol = "VOL|"+ symbol+"|"+"PERIOD_"+timeframe+"|"+str(start_bar)+"|"+str(end_bar+1)
self.remote_send(self.reqSocket, self.vol)
volumne= self.remote_pull(self.pullSocket)
volumne_str= str(volumne)
if 'VOL' in volumne_str:
volumne_lst= volumne_str.split(sep='|')[1:-1]
volumne_lst= [float(i) for i in volumne_lst]
volumne_lst= volumne_lst[::-1]
volumne_arr= np.array(volumne_lst)
return volumne_arr
def get_Time(self, symbol, timeframe, start_bar, end_bar):
'''
only start_bar and end_bar as int
'''
self.time = "TIME|"+ symbol+"|"+"PERIOD_"+timeframe+"|"+str(start_bar)+"|"+str(end_bar+1)
self.remote_send(self.reqSocket, self.time)
times= self.remote_pull(self.pullSocket)
time_str= str(times)
if 'TIME' in time_str:
time_lst= time_str.split(sep = '|')[1:-1]
time_lst= [j.split()[-1] for j in time_lst]
time_lst= [str(i) for i in time_lst]
time_lst= time_lst[::-1]
time_arr= np.array(time_lst)
return time_arr
def get_Time2(self, symbol, timeframe, start_bar, end_bar):
'''
only start_bar and end_bar as int
'''
self.time = "TIME|"+ symbol+"|"+"PERIOD_"+timeframe+"|"+str(start_bar)+"|"+str(end_bar+1)
self.remote_send(self.reqSocket, self.time)
times= self.remote_pull(self.pullSocket)
time_str= str(times)
if 'TIME' in time_str:
time_lst= time_str.split(sep = '|')[1:-1]
time_lst= [str(i) for i in time_lst]
time_lst= time_lst[::-1]
time_arr= np.array(time_lst)
return time_arr
def get_Ask(self, symbol, timeframe, start_bar, end_bar):
'''
only start_bar and end_bar as int
'''
self.ask = "ASK|"+ symbol+"|"+"PERIOD_"+timeframe+"|"+str(start_bar)+"|"+str(end_bar+1)
self.remote_send(self.reqSocket, self.time)
ask= self.remote_pull(self.pullSocket2)
ask_str= str(ask)
if 'ASK' in ask_str:
ask_lst= ask_str.split(sep='|')[1:-1]
ask_lst= [float(i) for i in ask_lst]
ask_lst= ask_lst[::-1]
ask_arr= np.array(ask_lst)
return ask_arr
def get_Bid(self, symbol, timeframe, start_bar, end_bar):
'''
only start_bar and end_bar as int
'''
self.bid = "BID|"+ symbol+"|"+"PERIOD_"+timeframe+"|"+str(start_bar)+"|"+str(end_bar+1)
self.remote_send(self.reqSocket, self.time)
bid= self.remote_pull(self.pullSocket2)
bid_str= str(bid)
if 'BID' in bid_str:
bid_lst= bid_str.split(sep='|')[1:-1]
bid_lst= [float(i) for i in bid_lst]
bid_lst= bid_lst[::-1]
bid_arr= np.array(bid_lst)
return bid_arr
def get_ACCINFO(self, INFO):
self.acc = "ACC|"+ INFO
self.remote_send(self.reqSocket, self.acc)
acc= self.remote_pull(self.pullSocket)
acc_str= str(acc)
acc_str = acc_str.replace("b", '')
acc_str = acc_str.replace("'", '')
if 'NAME' in acc_str:
acc_str = acc_str.replace("NAME|", '')
acc_nm = str(acc_str)
return acc_nm
elif 'BALANCE' in acc_str:
acc_str = acc_str.replace("BALANCE|", '')
acc_bal = float(acc_str)
return acc_bal
elif 'EQUITY' in acc_str:
acc_str = acc_str.replace("EQUITY|", '')
acc_eq = float(acc_str)
return acc_eq
elif 'MARGIN' in acc_str:
acc_str = acc_str.replace("MARGIN|", '')
acc_mgn = float(acc_str)
return acc_mgn
elif 'FREE' in acc_str:
acc_str = acc_str.replace("FREE|", '')
acc_fm = float(acc_str)
return acc_fm
elif 'PROFIT' in acc_str:
acc_str = acc_str.replace("PROFIT|", '')
acc_pt = float(acc_str)
return acc_pt
elif 'UNKNOW' in acc_str:
acc_un = str(acc_str)
return acc_un
def buy_order(self, symbol, stop_loss, take_profit):
self.buy= "TRADE|OPEN|0|"+ str(symbol)+"|"+str(stop_loss)+"|"+str(take_profit)
self.remote_send(self.reqSocket, self.buy)
reply= self.remote_pull(self.pullSocket)
return reply
def sell_order(self, symbol, stop_loss, take_profit):
self.buy= "TRADE|OPEN|1|"+ str(symbol)+"|"+str(stop_loss)+"|"+str(take_profit)
self.remote_send(self.reqSocket, self.buy)
reply= self.remote_pull(self.pullSocket)
return reply
def close_buy_order(self):
self.close_buy= "TRADE|CLOSE|0"
self.remote_send(self.reqSocket, self.close_buy)
reply= self.remote_pull(self.pullSocket)
return reply
def close_sell_order(self):
self.close_sell= "TRADE|CLOSE|1"
self.remote_send(self.reqSocket, self.close_sell)
reply= self.remote_pull(self.pullSocket)
return reply
It would appear that the response to remote_send
is not a utf8-encoded string. It looks like the code that's sending the reply is not included here. You might have better luck debugging if you show the actual reply:
reply = socket.recv_multipart()
print(reply) # or enter a debugger, if you prefer
I suspect that you aren't getting the reply you expect here. What should the reply look like?
this is the code that sends the reply
//+------------------------------------------------------------------+
//| ZeroMQ_MT4_EA_Template.mq4 |
//| Copyright 2017, Darwinex Labs |
//| https://www.darwinex.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Darwinex Labs."
#property link "https://www.darwinex.com/"
#property version "1.00"
#property strict
// Required: MQL-ZMQ from https://github.com/dingmaotu/mql-zmq
#include <Zmq/Zmq.mqh>
extern string PROJECT_NAME = "DWX_ZeroMQ_Example";
extern string ZEROMQ_PROTOCOL = "tcp";
extern string HOSTNAME = "*";
extern int REP_PORT = 5555;
extern int PUSH_PORT = 5556;
extern int PUSH_PORT2 = 5557;
extern int MILLISECOND_TIMER = 100; // 1 millisecond
extern string t0 = "--- Trading Parameters ---";
extern int MagicNumber = 123456;
extern int MaximumOrders = 1;
extern double MaximumLotSize = 0.01;
extern int Slippage = 3;
int Total, Ticket, Ticket2;
double StopLossLevel, TakeProfitLevel, StopLevel;
// CREATE ZeroMQ Context
Context context(PROJECT_NAME);
// CREATE ZMQ_REP SOCKET
Socket repSocket(context,ZMQ_REP);
// CREATE ZMQ_PUSH SOCKET
Socket pushSocket(context,ZMQ_PUSH);
Socket pushSocket2(context,ZMQ_PUSH);
// VARIABLES FOR LATER
uchar data[];
ZmqMsg request;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
EventSetMillisecondTimer(MILLISECOND_TIMER); // Set Millisecond Timer to get client socket input
Print("[REP] Binding MT4 Server to Socket on Port " + REP_PORT + "..");
Print("[PUSH1] Binding MT4 Server to Socket on Port " + PUSH_PORT + "..");
Print("[PUSH2] Binding MT4 Server to Socket on Port " + PUSH_PORT2 + "..");
repSocket.bind(StringFormat("%s://%s:%d", ZEROMQ_PROTOCOL, HOSTNAME, REP_PORT));
pushSocket.bind(StringFormat("%s://%s:%d", ZEROMQ_PROTOCOL, HOSTNAME, PUSH_PORT));
pushSocket2.bind(StringFormat("%s://%s:%d", ZEROMQ_PROTOCOL, HOSTNAME, PUSH_PORT2));
/*
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):
*/
repSocket.setLinger(5000); // 1000 milliseconds
/*
If we initiate socket.send() without having a corresponding socket draining the queue,
we'll eat up memory as the socket just keeps enqueueing messages.
So how many messages do we want ZeroMQ to buffer in RAM before blocking the socket?
*/
repSocket.setSendHighWaterMark(20); // 5 messages only.
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
Print("[REP] Unbinding MT4 Server from Socket on Port " + REP_PORT + "..");
repSocket.unbind(StringFormat("%s://%s:%d", ZEROMQ_PROTOCOL, HOSTNAME, REP_PORT));
Print("[PUSH] Unbinding MT4 Server from Socket on Port " + PUSH_PORT + "..");
pushSocket.unbind(StringFormat("%s://%s:%d", ZEROMQ_PROTOCOL, HOSTNAME, PUSH_PORT));
Print("[PUSH] Unbinding MT4 Server from Socket on Port " + PUSH_PORT + "..");
pushSocket2.unbind(StringFormat("%s://%s:%d", ZEROMQ_PROTOCOL, HOSTNAME, PUSH_PORT2));
}
//+------------------------------------------------------------------+
//| Expert timer function |
//+------------------------------------------------------------------+
void OnTimer()
{
//---
/*
For this example, we need:
1) socket.recv(request,true)
2) MessageHandler() to process the request
3) socket.send(reply)
*/
// Get client's response, but don't wait.
repSocket.recv(request,true);
// MessageHandler() should go here.
ZmqMsg reply = MessageHandler(request);
// socket.send(reply) should go here.
repSocket.send(reply);
}
//+------------------------------------------------------------------+
ZmqMsg MessageHandler(ZmqMsg &request) {
// Output object
ZmqMsg reply;
// Message components for later.
string components[];
if(request.size() > 0) {
// Get data from request
ArrayResize(data, request.size());
request.getData(data);
string dataStr = CharArrayToString(data);
// Process data
ParseZmqMessage(dataStr, components);
// Interpret data
InterpretZmqMessage(&pushSocket, components);
// Construct response
ZmqMsg ret(StringFormat("[SERVER] Processing: %s", dataStr));
reply = ret;
}
else {
// NO DATA RECEIVED
}
return(reply);
}
// Interpret Zmq Message and perform actions
void InterpretZmqMessage(Socket &pSocket, string& compArray[]) {
Print("ZMQ: Interpreting Message..");
// Message Structures:
// 1) Trading
// TRADE|ACTION|TYPE|SYMBOL|PRICE|SL|TP|COMMENT|TICKET
// e.g. TRADE|OPEN|1|EURUSD|0|50|50|R-to-MetaTrader4|12345678
// The 12345678 at the end is the ticket ID, for MODIFY and CLOSE.
// 2) Data Requests
// 2.1) RATES|SYMBOL -> Returns Current Bid/Ask
// 2.2) DATA|SYMBOL|TIMEFRAME|START_DATETIME|END_DATETIME
// NOTE: datetime has format: D'2015.01.01 00:00'
/*
compArray[0] = TRADE or RATES
If RATES -> compArray[1] = Symbol
If TRADE ->
compArray[0] = TRADE
compArray[1] = ACTION (e.g. OPEN, MODIFY, CLOSE)
compArray[2] = TYPE (e.g. OP_BUY, OP_SELL, etc - only used when ACTION=OPEN)
// ORDER TYPES:
// https://docs.mql4.com/constants/tradingconstants/orderproperties
// OP_BUY = 0
// OP_SELL = 1
// OP_BUYLIMIT = 2
// OP_SELLLIMIT = 3
// OP_BUYSTOP = 4
// OP_SELLSTOP = 5
compArray[3] = Symbol (e.g. EURUSD, etc.)
compArray[4] = Open/Close Price (ignored if ACTION = MODIFY)
compArray[5] = SL
compArray[6] = TP
compArray[7] = Trade Comment
*/
int switch_action = 0;
if(compArray[0] == "TRADE" && compArray[1] == "OPEN")
switch_action = 1;
if(compArray[0] == "RATES")
switch_action = 2;
if(compArray[0] == "TRADE" && compArray[1] == "CLOSE")
switch_action = 3;
if(compArray[0] == "TIME")
switch_action = 4;
if(compArray[0] == "OPEN")
switch_action = 5;
if (compArray[0] == "HIGH")
switch_action = 6;
if(compArray[0] == "LOW")
switch_action = 7;
if(compArray[0] =="CLOSE")
switch_action = 8;
if (compArray[0] == "VOL")
switch_action = 9;
if (compArray[0] == "ACC")
switch_action = 10;
string ret = "";
int ticket = -1;
bool ans = FALSE;
datetime time_array[];
ArraySetAsSeries(time_array, true);
double open_array[];
ArraySetAsSeries(open_array, true);
double high_array[];
ArraySetAsSeries(high_array, true);
double low_array[];
ArraySetAsSeries(low_array, true);
double close_array[];
ArraySetAsSeries(close_array, true);
long vol_array[];
ArraySetAsSeries(vol_array, true);
int time_count = 0;
int open_count = 0;
int high_count = 0;
int low_count = 0;
int close_count = 0;
int vol_count = 0;
switch(switch_action)
{
case 1:
//InformPullClient(pSocket, "OPEN TRADE Instruction Received");
if (compArray[2] == "0") {
StopLossLevel = Ask - StrToDouble(compArray[4]) * Point;
TakeProfitLevel = Ask + StrToDouble(compArray[5]) * Point;
//InformPullClient(pSocket, "Buy Order");
Ticket= OrderSend(compArray[3], OP_BUY, MaximumLotSize, Ask, Slippage, StopLossLevel,TakeProfitLevel, "Buy(#" + MagicNumber + ")", MagicNumber, 0, DodgerBlue);
if(Ticket > 0) {
if (OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES)) {
Print("BUY order opened : ", OrderOpenPrice());
InformPullClient(pSocket, "OrderSend placed successfully");}
}
else {
InformPullClient(pSocket, "OrderSend failed");
Print("Error opening BUY order : ", GetLastError());
}
}
if (compArray[2] == "1") {
StopLossLevel = Bid + StrToDouble(compArray[4]) * Point;
TakeProfitLevel = Bid - StrToDouble(compArray[5]) * Point;
//InformPullClient(pSocket, "Buy Order");
Ticket= OrderSend(compArray[3], OP_SELL, MaximumLotSize, Bid, Slippage, StopLossLevel,TakeProfitLevel, "Sell(#" + MagicNumber + ")", MagicNumber, 0, DodgerBlue);
if(Ticket > 0) {
if (OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES)) {
Print("SELL order opened : ", OrderOpenPrice());
InformPullClient(pSocket, "OrderSend placed successfully");}
}
else {
InformPullClient(pSocket, "OrderSend failed");
Print("Error opening SELL order : ", GetLastError());
}
}
break;
case 2:
ret = "N/A";
if(ArraySize(compArray) > 1)
ret = GetBidAsk(compArray[1]);
InformPullClient(pSocket, ret);
break;
case 3:
if (compArray[2] == "0") {
OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES);
Ticket2=OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, MediumSeaGreen);
ret = StringFormat("Trade Closed (Ticket: %d)", ticket);
InformPullClient(pSocket, ret);
}
if (compArray[2] == "1") {
OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES);
Ticket2 = OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, DarkOrange);
}
break;
case 4:
//InformPullClient(pSocket, "HISTORICAL DATA Instruction Received");
// Format: TIME|SYMBOL|TIMEFRAME|START_DATETIME|END_DATETIME
time_count = CopyTime(compArray[1], StrToInteger(compArray[2]),
StrToInteger(compArray[3]), StrToInteger(compArray[4]),
time_array);
if (time_count > 0) {
ret = "";
// Construct string of time|time|time|.. etc and send to PULL client.
for(int i = 0; i < time_count; i++ ) {
if(i == 0)
ret = compArray[0] + "|" + TimeToStr(time_array[i]);
else if(i > 0) {
ret = ret + "|" + TimeToStr(time_array[i]);
}
}
Print("Sending: " + ret);
// Send data to PULL client.
InformPullClient(pSocket, StringFormat("%s", ret));
// ret = "";
}
break;
case 5:
//InformPullClient(pSocket, "HISTORICAL DATA Instruction Received");
// Format: OPEN|SYMBOL|TIMEFRAME|START_DATETIME|END_DATETIME
open_count = CopyOpen(compArray[1], StrToInteger(compArray[2]),
StrToInteger(compArray[3]), StrToInteger(compArray[4]),
open_array);
if (open_count > 0) {
ret = "";
// Construct string of open|open|open|.. etc and send to PULL client.
for(int i = 0; i < open_count; i++ ) {
if(i == 0)
ret = compArray[0] + "|" + DoubleToStr(open_array[i], 5);
else if(i > 0) {
ret = ret + "|" + DoubleToStr(open_array[i], 5);
}
}
Print("Sending: " + ret);
// Send data to PULL client.
InformPullClient(pSocket, StringFormat("%s", ret));
// ret = "";
}
break;
case 6:
//InformPullClient(pSocket, "HISTORICAL DATA Instruction Received");
// Format: HIGH|SYMBOL|TIMEFRAME|START_DATETIME|END_DATETIME
high_count = CopyHigh(compArray[1], StrToInteger(compArray[2]),
StrToInteger(compArray[3]), StrToInteger(compArray[4]),
high_array);
if (high_count > 0) {
ret = "";
// Construct string of price|price|price|.. etc and send to PULL client.
for(int i = 0; i < high_count; i++ ) {
if(i == 0)
ret = compArray[0] + "|" + DoubleToStr(high_array[i], 5);
else if(i > 0) {
ret = ret + "|" + DoubleToStr(high_array[i], 5);
}
}
Print("Sending: " + ret);
// Send data to PULL client.
InformPullClient(pSocket, StringFormat("%s", ret));
// ret = "";
}
break;
case 7:
//InformPullClient(pSocket, "HISTORICAL DATA Instruction Received");
// Format: LOW|SYMBOL|TIMEFRAME|START_DATETIME|END_DATETIME
low_count = CopyLow(compArray[1], StrToInteger(compArray[2]),
StrToInteger(compArray[3]), StrToInteger(compArray[4]),
low_array);
if (low_count > 0) {
ret = "";
// Construct string of price|price|price|.. etc and send to PULL client.
for(int i = 0; i < low_count; i++ ) {
if(i == 0)
ret = compArray[0] + "|" + DoubleToStr(low_array[i], 5);
else if(i > 0) {
ret = ret + "|" + DoubleToStr(low_array[i], 5);
}
}
Print("Sending: " + ret);
// Send data to PULL client.
InformPullClient(pSocket, StringFormat("%s", ret));
// ret = "";
}
break;
case 8:
//InformPullClient(pSocket, "HISTORICAL DATA Instruction Received");
// Format: DATA|SYMBOL|TIMEFRAME|START_DATETIME|END_DATETIME
close_count = CopyClose(compArray[1], StrToInteger(compArray[2]),
StrToInteger(compArray[3]), StrToInteger(compArray[4]),
close_array);
if (close_count > 0) {
ret = "";
// Construct string of price|price|price|.. etc and send to PULL client.
for(int i = 0; i < close_count; i++ ) {
if(i == 0)
ret = compArray[0] + "|" + DoubleToStr(close_array[i], 5);
else if(i > 0) {
ret = ret + "|" + DoubleToStr(close_array[i], 5);
}
}
Print("Sending: " + ret);
// Send data to PULL client.
InformPullClient(pSocket, StringFormat("%s", ret));
// ret = "";
}
break;
case 9:
//InformPullClient(pSocket, "HISTORICAL DATA Instruction Received");
// Format: DATA|SYMBOL|TIMEFRAME|START_DATETIME|END_DATETIME
vol_count = CopyTickVolume(compArray[1], StrToInteger(compArray[2]),
StrToInteger(compArray[3]), StrToInteger(compArray[4]),
vol_array);
if (vol_count > 0) {
ret = "";
// Construct string of price|price|price|.. etc and send to PULL client.
for(int i = 0; i < vol_count; i++ ) {
if(i == 0)
ret = compArray[0] + "|" + DoubleToStr(vol_array[i], 5);
else if(i > 0) {
ret = ret + "|" + DoubleToStr(vol_array[i], 5);
}
}
Print("Sending: " + ret);
// Send data to PULL client.
InformPullClient(pSocket, StringFormat("%s", ret));
// ret = "";
}
break;
case 10:
//InformPullClient(pSocket, "ACC DATA Instruction Received");
ret = "";
if(compArray[1] == "NAME"){
string name = AccountName();
ret = compArray[1] + "|" + name;
}
else if(compArray[1] == "BALANCE"){
double balance = AccountBalance();
ret = compArray[1] + "|" + DoubleToStr(balance, 2);
}
else if(compArray[1] == "EQUITY"){
double equity = AccountEquity();
ret = compArray[1] + "|" + DoubleToStr(equity, 5);
}
else if(compArray[1] == "MARGIN"){
double margin = AccountMargin();
ret = compArray[1] + "|" + DoubleToStr(margin, 5);
}
else if(compArray[1] == "FREE"){
double mf = AccountFreeMargin();
ret = compArray[1] + "|" + DoubleToStr(mf, 2);
}
else if (compArray[1]== "PROFIT"){
double profit = AccountProfit();
ret = compArray[1] + "|" + DoubleToStr(profit, 2);
}
else{
ret = "UNKNOW";
}
Print("Sending: " + ret);
// Send data to PULL client.
InformPullClient(pSocket, StringFormat("%s", ret));
// ret = "";
break;
default:
break;
}
}
// Parse Zmq Message
void ParseZmqMessage(string& message, string& retArray[]) {
Print("Parsing: " + message);
string sep = "|";
ushort u_sep = StringGetCharacter(sep,0);
int splits = StringSplit(message, u_sep, retArray);
for(int i = 0; i < splits; i++) {
Print(i + ") " + retArray[i]);
}
}
//+------------------------------------------------------------------+
// Generate string for Bid/Ask by symbol
string GetBidAsk(string symbol) {
double bid = MarketInfo(symbol, MODE_BID);
double ask = MarketInfo(symbol, MODE_ASK);
return(StringFormat("%f|%f", bid, ask));
}
// Inform Client
void InformPullClient(Socket& pushSocket, string message) {
ZmqMsg pushReply(StringFormat("%s", message));
// pushSocket.send(pushReply,true,false);
pushSocket.send(pushReply,true); // NON-BLOCKING
// pushSocket.send(pushReply,false); // BLOCKING
}
void InformPullClient2(Socket& pushSocket, string message) {
ZmqMsg pushReply(StringFormat("%s", message));
// pushSocket.send(pushReply,true,false);
pushSocket2.send(pushReply,true); // NON-BLOCKING
// pushSocket2.send(pushReply,false); // BLOCKING
}
here is the part I don't quite understand, below the error occurs in the first execution and then doesn't in the second
Time= trade.get_Time2(symbol= 'EURUSD', timeframe= 'H1', start_bar=0, end_bar=2)
Traceback (most recent call last):
File "<ipython-input-15-9df761737036>", line 1, in <module>
Time= trade.get_Time2(symbol= 'EURUSD', timeframe= 'H1', start_bar=0, end_bar=2)
File "C:\Users\User\Documents\Programming\PFTNNS\pythonicMT4.py", line 148, in get_Time2
self.remote_send(self.reqSocket, self.time)
File "C:\Users\User\Documents\Programming\PFTNNS\pythonicMT4.py", line 28, in remote_send
msg_send = socket.recv_string()
File "C:\Users\User\Anaconda3\lib\site-packages\zmq\sugar\socket.py", line 585, in recv_string
return self._deserialize(msg, lambda buf: buf.decode(encoding))
File "C:\Users\User\Anaconda3\lib\site-packages\zmq\sugar\socket.py", line 491, in _deserialize
return load(recvd)
File "C:\Users\User\Anaconda3\lib\site-packages\zmq\sugar\socket.py", line 585, in <lambda>
return self._deserialize(msg, lambda buf: buf.decode(encoding))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc7 in position 5: invalid continuation byte
Time= trade.get_Time2(symbol= 'EURUSD', timeframe= 'H1', start_bar=0, end_bar=2)
[b'TIME|2018.09.05 10:00|2018.09.05 09:00|2018.09.05 08:00']
b'TIME|2018.09.05 10:00|2018.09.05 09:00|2018.09.05 08:00'
I was having this very issue with pyzmq 17.0.0
but fixed it by updating my package to pyzmq 17.1.0
. Perhaps there's a clue there?
Start by looking at the message that you are receiving. That's usually where the clue is that either what you are sending or receiving is not what you expect or intend:
reply = socket.recv_multipart()
print(reply) # or enter a debugger, if you prefer
thank you @lunarplasma this seems to have fix the problem
@masfen Can you confirm that updating to pyzmq 17.1.0+
fixed your problem? Your initial post
https://github.com/zeromq/pyzmq/issues/1221#issue-354295421 seems to imply you were already above that version.
I was presuming that this bug is actually an underlying issue in libzmq, and pyzmq 17.1.0 bundles the libzmq 4.2.5 which fixed the problem, but I have no evidence.
I'm seeing a similar issue during installation of pyzmq>=17
which is currently at 18.0.0
.
Downloading https://files.pythonhosted.org/packages/64/8d/78975da77627fd863c08e8ea3c7cebce7e51bed2936be5118de6b0050638/pyzmq-18.0.0.tar.gz (1.2MB)
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/pip-install-rv3k_yvp/pyzmq/setup.py", line 1241, in <module>
long_desc = f.read()
File "/usr/lib64/python3.4/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 29: ordinal not in range(128)
I put a small PR together to at least fix my issue 🙂 I'll submit it shortly.
The PR to fix README.md
parsing is here #1265
Good Day
I am a bit a of newbie to pyzmq and am getting an error UnicodeDecodeError: 'utf-8' codec can't decode byte 0xac in position 22: invalid start byte.
I am using python 3.6.5, on spyder 3.3.1 and version 17.1.2 of pyzmq
this error does not occur all the time