Interactive Brokers and MATLAB Connection - matlab

I'm trying to connect MATLAB to interactive brokers. I'm aware there was a bug before. However, I got an email in August saying it was fixed. I'm currently running this code;
% establish connection to TWS ib = ibtws('',7497);
%% create currency handles ibEURUSD = ib.Handle.createContract; % set forex credentials ibEURUSD.symbol = 'EUR'; ibEURUSD.secType = 'CASH'; ibEURUSD.exchange = 'IDEALPRO'; ibEURUSD.currency = 'USD';
cur = getdata(ib,ibEURUSD);
% close IB connection close(ib);
Getting the result for cur of "not connected", has anyone managed to get IB working with MATLAB, if so could you point towards a good resource?
Thanks
Allan

Consider using the IB-Matlab connector (https://undocumentedmatlab.com/IB-Matlab), which is actively maintained since 2010 and is the highest-rated product on IB's Marketplace by a large margin.

Related

OPC Server: Start Stop Pause getData(again use) DYMOLA MATLAB

I am using a Dymola OPC server
DYMOLA HAS these many tags which can be controlled using SimControl.Run, SimControl.Stop ,etc
here i wrote it in MATLAB
hostInfo = opcserverinfo('localhost');
da = opcda('localhost','Dymosim.OPCServer.1');
connect(da);
fprintf("CONNECTED\n");
grp=addgroup(da,'Demo');
itmIDs={'ModelVariables.Tco','ModelVariables.der(Tco)'};
itm=additem(grp,itmIDs);
area=additem(grp,{'ModelVariables.Area'});
set(grp,'UpdateRate',0.2,'RecordsToAcquire',50);
start(grp);
wait(grp);
[logIDs,Tco]=getdata(grp,'double'); // PREVIOUS ONE
Now I want to change/write value to area so what I did is this
write(area,23);
Now I want to Relog or getdata
NEWTco=read(itm,'device').Value; //using This I can read one instance
[NewlogIDs,NewTco]=getdata(grp,'double');// GIVES ERR
Writing this helped me to solve this issue
grp2=addgroup(da,'Demo2');
Run=additem(grp2,{'SimControl.Run'});
Status=additem(grp2,{'SimControl.Status'});
Stop=additem(grp2,{'SimControl.Stop'});
Pause=additem(grp2,{'SimControl.Pause'});
RunStatusBefore=read(Run,'device');
StatusBefore=read(Status,'device').Value;
StopStatusBefore=read(Stop,'device');
PauseStatusBefore=read(Pause,'device');
write(Initialize,1); //INITITALIZE
write(Run,1); // RUN
write(Stop,1); // STOP
write(Pause,1); // PAUSE

How to succesfull read my tcpip connection

I implemented a few months ago a function that sends data from Matlab to a Weiss WSG50 gripper. This is a Robotic Gripper Tool and uses binary codes as commands. I established a connection with the tcpip function. I wrote my commands and sended them with ´fwrite´ as uint8-data to the gripper. My tcpip object is a client. The gripper a server. The gripper sucessful runs the command perfectly. Until here everthing works as I expected.
The Trouble begins, when I tryied to receive data back from the gripper. The gripper reacts with a awnser message on every sended command (Could be more then one message). But my ´BytesAvailable´ stays empty.
I know that could be diffcult to reproduce, because it may be necessary to have access to the gripper. But eventual I do something basic wrong with setting up the TCPIP object. I tryied already to use ´tcpclient´ but with this function sending is not working also.
%% WORKING PART
%Preparing the gripper
gripper = tcpip('172.16.6.72',1000);
gripper.OutputBufferSize = 3000;
gripper.ByteOrder = 'littleEndian';
gripper.Timeout = 1;
fopen(gripper);
%Command
release = [170; 170; 170; 38; 8; 0; 0; 0; 160; 64; 0; 0; 210; 67; 0; 0];
release = hex2dec(release);
fwrite(gripper, uint8(release), 'uint8');
fclose(gripper);
%% NOT WORKING PART
readdata = fread(gripper,gripper.BytesAvailable);
If ´BytesAvailable´ is empty it absolutly makes sense, that this is not working. No Data no reading. My Question is it a problem with the gripper or am I doing something totally wrong with the tcpip object configuration?

Matlab - Interactive Brokers - Getdata function

I am using the getdata function of the trading toolbox in Matlab (http://de.mathworks.com/help/trading/ibtws.getdata.html) to get real time price data of forex pairs (e.g. EURUSD) through the most up to date TraderWorkStation (TWS) with an Interactive Brokers (IB) demo account using the most recent API offered by IB (v9.71).
The TWS is running while executing my code (see below)
Here is the code I am using. It follows all the basic steps explained in the follwing tutorial by Mathworks (http://de.mathworks.com/videos/get-started-with-trading-toolbox-connect-to-interactive-brokers-1-of-3-91839.html).
% establish connection to TWS
ib = ibtws('',7497);
%% create currency handles
ibEURUSD = ib.Handle.createContract;
% set forex credentials
ibEURUSD.symbol = 'EUR';
ibEURUSD.secType = 'CASH';
ibEURUSD.exchange = 'IDEALPRO';
ibEURUSD.currency = 'USD';
cur = getdata(ib,ibEURUSD);
% close IB connection
close(ib);
In most of the cases (roughly 75%) this code deliveres the expected results and returns the requested financial data. However, in the remaining cases the variable "cur" does not contain the requested price data but the following error message: "HMDS data farm connection is OK:ushmds"
Which fist does not look like a problem. However this error message replaces the requested data so that during 25% of the runs no data will be received.
I apprechiate any hints to solve this.
It's bug in the MATLAB Trading Toolbox. There are a few messages that the IB API documentation describes as being safe to ignore, but the MATLAB errMsg event handler does not ignore them and instead terminates the ongoing getdata request while the price data is being received. The "HMDS data farm connection is OK:ushmds" is message number 2106 which is one of the ignorable messages.
Consider using the IB-Matlab connector, which does not have this problem.

Communicating between Pure Data and MATLAB using OSC

I'm trying to receive a message sent over OSC from Pure Data (or Max/MSP) to MATLAB.
I'm able to send OSC messages from Pure Data to Pure Data
I can send messages from MATLAB to MATLAB
I can even send messages from MATLAB to Pure Data
...I'm really struggling to get Pure Data to talk back to MATLAB
Here's my code that sends messages from MATLAB (I'm using the oscmex protocol):
host = 'localhost'; % local host UDP address
sendPort = 3333; % UDP port number to send over
receivePort = 3333; % UDP port number to receive from
oscAddress = osc_new_address(host, sendPort); % open send address
oscServer = osc_new_server(receivePort); % open server
dataPacket = struct('path','/foo','tt','f','data',{num2cell([1.0])}); % create packet
osc_send(oscAddress, dataPacket); % write packet to OSC
oscMessage = osc_recv(oscServer, 0.1); % listen for packet on OSC
% check to see if anything is there...
if length(oscMessage) > 0
fprintf('Found something!')
else
fprintf('Failed to find anything')
end
osc_free_address(oscAddress);
osc_free_server(oscServer);
If I send using host 'localhost', everything works fine sending from MATLAB to MATLAB using the code above. If I set it to '127.0.0.1', MATLAB sends to Pure Data, but MATLAB then can't receive its own messages.
Now for the other end of things. Here's my Pure Data patch:
Again, running the above patch alone successfully sends and receives messages through Pure Data.
The problem lies when I try to talk from one program to another. If I set things so that MATLAB is sending on port 3333 and Pure Data is receiving on 3333, and that Pure Data is sending on 2222 and MATLAB is receiving on 2222, I can make Pure Data receive if MATLAB's host is '127.0.0.1'. But, with '127.0.0.1', MATLAB can't send to itself.
In any case, no matter what I try, I'm unable to make Pure Data send to MATLAB, despite being able to get it to send to itself. I suspect it has something to do with the 'host' address.
My actual IPv4 address (found using 'ipconfig' of the MS command prompt) is completely different from 127.0.0.1, and using the value specified here doesn't seem to make things work any better.
I'm aware that I can't have more than one OSC server with the same port open at any one time and so my current attempt at a solution involves sending from MATLAB on one port, and sending from Pure Data on another, with only a single server open at one time on either port.
Note I'm also aware that I use /foo for messages from MATLAB and /test from Pure Data. However, my MATLAB code indiscriminately receives everything sent over OSC, so this makes no difference.
Any help getting PD to talk to MATLAB would be appreciated.
Update: Ive solved the 'localhost' issue and that doesn't seem to fix things (i had to add localhost to my Windows 'hosts' file). So, I may have been barking up the wrong tree by worrying about the localhost thing. But, I still can't get PD to talk to MATLAB.
Update #2: Amro has posted an elegant solution below and I still can't get MATLAB to receive messages from Pure Data. I've installed CloseTheDoor to monitor my UDP connections and notice that when MATLAB sets up a server, it uses the 'Interface' [::0], whereas PD sets uses 'Interface' 0.0.0.0. Since PureData is the one that successfully receives messages, perhaps I need to make MATLAB listen on 0.0.0.0 as well?
Let me start by saying that I've never used PureData or OSC before, and I just duplicated the graph/patch you've shown to create the server/client.
1) server in PureData, client in MATLAB:
First lets create the server in PureData:
Now here is a simple client implemented as a GUI in MATLAB:
function example_osc_client()
handles = createGUI();
osc = [];
function h = createGUI()
h.fig = figure('Menubar','none', 'Resize','off', ...
'CloseRequestFcn',#onClose, ...
'Name','OSC Client', 'Position',[100 100 220 140]);
movegui(h.fig, 'center')
h.conn = uicontrol('Style','pushbutton', 'String','Connect', ...
'Callback',{#onClick,'connect'}, ...
'Parent',h.fig, 'Position',[20 20 80 20]);
h.disconn = uicontrol('Style','pushbutton', 'String','Disconnect', ...
'Callback',{#onClick,'disconnect'}, ...
'Parent',h.fig, 'Position',[120 20 80 20]);
h.slid = uicontrol('Style','slider', 'Callback',#onSlide, ...
'Min',-10, 'Max',10, 'Value',0, ...
'Parent',h.fig, 'Position',[30 60 160 20]);
h.txt = uicontrol('Style','text', 'String','0.0', ...
'Parent',h.fig, 'Position',[80 100 60 20]);
set([h.slid;h.disconn], 'Enable','off');
drawnow
end
function onClick(~,~,action)
switch lower(action)
case 'connect'
osc = osc_new_address('127.0.0.1', 2222);
set(handles.conn, 'Enable','off')
set(handles.disconn, 'Enable','on')
set(handles.slid, 'Enable','on')
case 'disconnect'
osc_free_address(osc); osc = [];
set(handles.conn, 'Enable','on')
set(handles.disconn, 'Enable','off')
set(handles.slid, 'Enable','off')
end
drawnow
end
function onSlide(~,~)
if isempty(osc), return; end
val = single(get(handles.slid,'Value'));
m = struct('path','/test', 'tt','f', 'data',{{val}});
osc_send(osc, m);
set(handles.txt, 'String',num2str(val))
drawnow
end
function onClose(~,~)
if ~isempty(osc)
osc_free_address(osc);
end
delete(handles.fig);
end
end
As you move the slider, messages are sent to the server (using OSC-MEX interface), and the values are displayed in the PureData model.
While testing this, I noticed that double type was not supported, as I saw the following message in the PD log window:
unpackOSC: PrintTypeTaggedArgs: [A 64-bit float] not implemented
So it was necessary to either manually cast values as single or explicitly specify the hint type in the structure passed to osc_send OSC-MEX function:
val = single(1);
m = struct('path','/test', 'tt','f', 'data',{{val}});
osc_send(osc, m);
2) server in MATLAB, client in PureData:
Similarly we create the client in PureData:
Again, here is the server implemented as a MATLAB GUI:
function example_osc_server()
handles = createGUI();
osc = [];
function h = createGUI()
h.fig = figure('Menubar','none', 'Resize','off', ...
'CloseRequestFcn',#onClose, ...
'Name','OSC Server', 'Position',[100 100 220 140]);
movegui(h.fig, 'center')
h.start = uicontrol('Style','pushbutton', 'String','Start', ...
'Callback',{#onClick,'start'}, ...
'Parent',h.fig, 'Position',[20 20 80 20]);
h.stop = uicontrol('Style','pushbutton', 'String','Stop', ...
'Callback',{#onClick,'stop'}, ...
'Parent',h.fig, 'Position',[120 20 80 20]);
h.txt = uicontrol('Style','text', 'String','', ...
'Parent',h.fig, 'Position',[60 80 100 20]);
set(h.stop, 'Enable','off');
drawnow expose
h.timer = timer('TimerFcn',#receive, 'BusyMode','drop', ...
'ExecutionMode','fixedRate', 'Period',0.11);
end
function onClick(~,~,action)
switch lower(action)
case 'start'
set(handles.start, 'Enable','off')
set(handles.stop, 'Enable','on')
osc = osc_new_server(2222);
start(handles.timer);
case 'stop'
set(handles.start, 'Enable','on')
set(handles.stop, 'Enable','off')
osc_free_server(osc); osc = [];
stop(handles.timer);
end
drawnow expose
end
function receive(~,~)
if isempty(osc), return; end
m = osc_recv(osc, 0.1);
if isempty(m), return; end
set(handles.txt, 'String',num2str(m{1}.data{1}))
drawnow expose
end
function onClose(~,~)
if ~isempty(osc)
osc_free_server(osc);
end
stop(handles.timer); delete(handles.timer);
delete(handles.fig);
clear handles osc
end
end
The server part was a bit trickier in MATLAB. The idea is that we don't want MATLAB to block indefinitely waiting for messages. So I created a timer which executes every 0.11 second. Inside the timer function we try to receive message in a blocking manner but with a timeout of 0.1 sec. This way both the GUI and MATLAB IDE stay responsive.
3) other combinations:
Using the above solutions, you could also open both client and server in PureData, or both client and server in MATLAB. It should work either way.
Finally I should say that it made no difference whether I'm using the hostname as localhost or specified the IP address directly 127.0.0.1.
HTH
EDIT:
I managed to compile the OSC-MEX package myself, here are the steps. First download osc-mex sources and its dependencies. This includes: liblo sources, pthreads-win32 binaries, premake4 executable.
1) We start by building the liblo library:
Copy "premake4.exe" into the "build" directory, and run: premake4 --platform=x32 vs2010
open the generated "liblo.sln" solution file in VS2010. Select the "liblo" project and go to "Project > Properties". Add the include folder containing pthreads header files in the "Additional Include Directories" field. Similarly add the lib folder for the linker, and specify pthreadVC2.lib as additional dependency.
Select the "ReleaseLib" Win32 target and build the project. This should create the final target: lib\ReleaseLib\liblo.lib
Note that by default, IPv6 support is disabled in liblo because OSC applications like Pd have problems with IPv6. If you still want to enable it, add the following line to config.h file:
#define ENABLE_IPV6 1
2) Next we compile the MEX-functions in MATLAB:
Go to the folder containing the C-sources of the MEX-functions
copy liblo.lib from the previous step into this directory. Also copy pthreadVC2.lib from the pthreads library.
compile each function using:
mex -largeArrayDims -I../path/to/liblo-0.27 xxxxxx.c pthreadVC2.lib liblo.lib -lwsock32 -lws2_32 -liphlpapi
You should end up with six *.mexw32 files for each of the xxxxxx.c source files
Finally copy the pthreads DLL into this same folder: pthreadVC2.dll
To save you some troubles, here are the compiled MEX-files built on WinXP 32-bit and Win8 64-bit both using VS2010. Here are the sources if you would like to compile it yourself (simply build the solution in VS2010, then run osc_make.m in MATLAB)
localhost is an alias for 127.0.0.1; they really are the same IP-address. so if matlab only receives something if it is sending to localhost but not if sending to 127.0.0.1, they probably have a buggy implementation of OSC.
as long as you have [udpreceive 2222] in your patch, Pd will block the port UDP/2222, and matlab will not be able to receive anything on that port.
so the simple solution is: remove [udpreceive 2222] before creating the matlab server using osc_new_server(2222);

How to send an email without using the program RSCONN01?

I am trying to send an email with an excel attachment without using rsconn01. If this is possible could you show me how this is done?
I would also like a little bit more information about how rsconn01 works. I am using rsconn01 to send the emails but, I received a complaint that this program was also resending out emails that failed earlier that day.
This is the code I am using now. It works, but I want to know another way to do it without using rsconn01.
`CALL FUNCTION 'SO_DOCUMENT_SEND_API1'
EXPORTING
document_data = w_doc_data
put_in_outbox = 'X'
commit_work = 'X'
IMPORTING
sent_to_all = w_sent_all
TABLES
packing_list = t_packing_list
contents_bin = t_attachment
contents_txt = it_message
receivers = t_receivers
EXCEPTIONS
too_many_receivers = 1
document_not_sent = 2
document_type_not_exist = 3
operation_no_authorization = 4
parameter_error = 5
x_error = 6
enqueue_error = 7
OTHERS = 8.
if sy-subrc = 0.
WAIT UP TO 2 SECONDS.
SUBMIT rsconn01 WITH mode = 'INT'
WITH output = 'X'
AND RETURN.
else.
WRITE:/ 'ERROR IN MAIL ', sy-subrc.
endif.`
You will have to use RSCONN01 unless you'd like to implement your own protocol handling. You're using the standard SAPconnect functionality (although with an API that's a bit outdated, I'd switch to the BCS if I were in your shoes). As long as you're using this, you're stuck with that report. However, you usually won't have to call it for yourself. It's a background process that is called every few minutes to process outgoing mail. Perhaps you're working in a development environment where the SAPconnect system isn't properly setup - in that case, you should talk to your system administrators. There are ways to tune the SAPconnect system to work in many cases. You should try to use the existing and well supported facilities before trying to circumvent them.