Interactive borkers - requesting market data - interactive-brokers

I'm having a bit of a disaster trying to do something simple - in short getting ib api to work. I'd like to get the current market prices for a stock on the LSE, I've subscribed to the correct market feed and ran this code:
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
import threading
import time
from ibapi.contract import Contract
class IBapi(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
def tickPrice(self, reqId, tickType, price, attrib):
if tickType == 2 and reqId == 1:
print('The current ask price is: ', price)
def run_loop():
app.run()
app = IBapi()
app.connect('127.0.0.1', 7497, 4002)
#Start the socket in a thread
api_thread = threading.Thread(target=run_loop, daemon=True)
api_thread.start()
time.sleep(1) #Sleep interval to allow time for connection to server
#Create contract object
apple_contract = Contract()
apple_contract.symbol = 'BARC'
apple_contract.secType = 'STK'
apple_contract.exchange = 'LSE'
apple_contract.currency = 'GBP'
#Request Market Data
app.reqMktData(1, apple_contract, '', False, False, [])
time.sleep(10) #Sleep interval to allow time for incoming price data
app.disconnect()
However I'm getting this error back:
The current ask price is: -100.0
unhandled exception in EReader thread
Traceback (most recent call last):
File "C:\TWS API\source\pythonclient\ibapi\reader.py", line 34, in run
data = self.conn.recvMsg()
File "C:\TWS API\source\pythonclient\ibapi\connection.py", line 99, in recvMsg
buf = self._recvAllMsg()
File "C:\TWS API\source\pythonclient\ibapi\connection.py", line 119, in _recvAllMsg
buf = self.socket.recv(4096)
OSError: [WinError 10038] An operation was attempted on something that is not a socket
If anyone can help, it'd be greatly appreciated! Thanks,

I'm guessing the -100 is because the exchange is closed. The error can be ignored, see https://stackoverflow.com/a/58684561/2855515
It seems like your code is working fine even if a little unorthodox.

Related

Monitor Changing file in python

How to create a program that monitors a file (for example, text, and when you wrote something new to this file, the program should output that something was added to the file, and when, on the contrary, part of the text was deleted from it, it should write that something was deleted
And it should print to the console exactly which words were deleted or added?
Explanation
I use watchdog to follow the file.
On instantiation of the handler, I read the file's size.
When the file is modified, watchdog calls the on_modified function.
When this method is called, I compare the file's current size to its previous size to determine if the change was additive or subtractive.
You have a few other options when it comes to tracking the file. For example, you could also compare:
the number of lines
the number of words
the number of characters
the exact contents of the file
import os
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class EventHandler(FileSystemEventHandler):
def __init__(self, file_path_to_watch):
self.file_path_to_watch = file_path_to_watch
self._file_size = self._read_file_size()
def _read_file_size(self):
return os.path.getsize(self.file_path_to_watch)
def _print_change(self, new_file_size):
if new_file_size > self._file_size:
print('File modified with additions')
elif new_file_size < self._file_size:
print('File modified with deletions')
def on_modified(self, event):
if event.src_path != self.file_path_to_watch:
return
new_file_size = self._read_file_size()
self._print_change(new_file_size)
self._file_size = new_file_size
if __name__ == "__main__":
file_to_watch = '/path/to/watch.txt'
event_handler = EventHandler(file_to_watch)
observer = Observer()
observer.schedule(event_handler, path=file_to_watch, recursive=False)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()

How can I send the output of buttons via MQTT to a broker?

I've only been programming Python for two days. I want to send the output of buttons via MQTT to a broker (and then of course to a subscriber). I have programmed the buttons so far and would like to start the publisher-part now.
import tkinter as tk
from tkinter import ttk
from tkinter import Button
import paho.mqtt.client as mqtt
root = tk.Tk()
root.attributes('-fullscreen', True)
root.bind('<Escape>',lambda e: root.destroy())
a=0
def close_window():
root.destroy()
def callback():
print ("1")
a=1
def callback1():
print ("2")
a=2
def callback2():
print ("3")
a=3
s=ttk.Style()
s.configure('my.TButton', font=('Helvetica', '70'))
bx = ttk.Button(root, text = "x", style='my.TButton', command = close_window)
bx.pack(fill=tk.BOTH, anchor=tk.N, ipady=60)
c = Button(root, text="", height=15)
c.pack(fill=tk.BOTH, anchor=tk.N,)
b1 = ttk.Button(root, text="1", style='my.TButton', command=callback)
b1.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
b2 = ttk.Button(root, text="2", style='my.TButton', command=callback1)
b2.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
b3 = ttk.Button(root, text="3", style='my.TButton', command=callback2)
b3.pack(side=tk.RIGHT, fill=tk.BOTH, expand=1)
broker_address="xxxx"
client1 = mqtt.Client("Publisher1")
client1.connect("xxxx")
client1.publish("Button/Number", a, qos=2)
root.mainloop()
I want the variable "a" to change with each button stroke, and then be sent 1 time. I have now added the basic publisher script but get many different error messages like:
ConnectionRefusedError: [Errno 61] Connection refused (Btw, I want to use my Laptop as a broker, I took the local IP address)
and:
PermissionError: [Errno 13] Permission denied (same story)
I am aware that the Publisher Part will not work, but I don't know what I am missing or what I need to add.

Can't Parse DHCP packets with Ryu's get_protocol(dhcp.dhcp)

I'm using the Ryu SDN controller with an Open vSwitch on mininet using OpenFlow 1.3 to parse DHCP packets. Following online examples and the Ryu resources, I've implemented a DHCP packet parser. However, it does not work as I expected it to, and I'm wondering if anyone has any insight as to why my first solution does not work?
An example of a code snippet for parsing a DHCP packet is below:
from ryu.lib.packet import dhcp
...
...
#set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def _packet_in_handler(self, ev):
msg = ev.msg
datapath = msg.datapath
pkt = packet.Packet(msg.data)
dhcpPacket = pkt.get_protocol(dhcp.dhcp)
My code follows a similar vein:
from ryu.lib.packet import dhcp
...
...
#set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
def _packet_in_handler(self, ev):
pkt = {}
pkt['msg'] = ev.msg
pkt['dp'] = pkt['msg'].datapath
pkt['pkt'] = packet.Packet(pkt['msg'].data)
pkt['dhcp'] = pkt['pkt'].get_protocol(dhcp.dhcp)
This seems reasonable as I am following this exact sequence with other protocols like ARP, ICMP, IP, etc. Examples below.
pkt['arp'] = pkt['pkt'].get_protocol(arp.arp)
pkt['ip'] = pkt['pkt'].get_protocol(ipv4.ipv4)
pkt['icmp'] = pkt['pkt'].get_protocol(icmp.icmp)
The only problem is that the three parsers I list above actually return data, while the get_protocol for DHCP consistently returns None. I have already tested this by sending DHCP packets through my switch.
What does work is the following code snippet where I identify packet lists having more than three values. I save the value at index three and set that as my DHCP packet. In the DHCP packet, I concentrate of parsing the string at index 2. That contains the data I'm interested in.
# pkt['dhcp'] = pkt['pkt'].get_protocol(dhcp.dhcp)
# Check if pkt['pkt]] > 3 elements, if so, parse DHCP string
#Standard pkt['dhcp'] = (None, None, String)
if len(pkt['pkt']) > 3:
pkt['dhcp'] = dhcp.dhcp.parser(pkt['pkt'][3])
pkt['op'] = hex(ord(dhcp_p[2][0]))
pkt['htype'] = hex(ord(dhcp_p[2][1]))
pkt['hlen'] = hex(ord(dhcp_p[2][2]))
pkt['hops'] = hex(ord(dhcp_p[2][3]))
def parseDHCP(pkt_d,start,stop):
s_value = ''
stop += 1
for val in range(start,stop):
s_value += str(hex(ord(pkt_d[val])))
return s_value
pkt['xid'] = parseDHCP(dhcp_p[2],4,7)
pkt['secs'] = parseDHCP(dhcp_p[2],8,9)
pkt['flags'] = parseDHCP(dhcp_p[2],10,11)
pkt['ciaddr'] = parseDHCP(dhcp_p[2],12,15)
pkt['yiaddr'] = parseDHCP(dhcp_p[2],16,19)
pkt['siaddr'] = parseDHCP(dhcp_p[2],20,23)
pkt['giaddr'] = parseDHCP(dhcp_p[2],24,27)
pkt['chaddr'] = parseDHCP(dhcp_p[2],28,33)
pkt['pad'] = parseDHCP(dhcp_p[2],34,43)
A print out of these values looks like so:
0x1
0x1
0x6
0x0
0x440x30x980x11
0x00x0
0x00x0
0x00x00x00x0
0x00x00x00x0
0x00x00x00x0
0x00x00x00x0
0x7e0x1d0xcc0xe70xee0x4f
0x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x0
The above code allows me to observe the contents of DHCP packets, but I'm really trying to figure out why I'm not achieving similar results using the pkt['pkt'].get_protocol(dhcp.dhcp) method?
Ok, I found the problem. In lines 200 – 218 of dhcp.py there is a try except statement. I pulled the cls._parser out of the try to see the error it throws and I get this:
Ryuretic_coupler: Exception occurred during handler processing. Backtrace
from offending handler [initial_event] servicing event [EventOFPPacketIn] follows.
Traceback (most recent call last):
File "/home/ubuntu/ryu/ryu/base/app_manager.py", line 290, in _event_loop
handler(ev)
File "/home/ubuntu/ryu/ryu/app/Ryuretic/Ryuretic.py", line 72, in initial_event
pkt = parsPkt.handle_pkt(ev)
File "/home/ubuntu/ryu/ryu/app/Ryuretic/Pkt_Parse13.py", line 81, in handle_pkt
dhcp_p = pkt['dhcp'] = dhcp.dhcp.parser(pkt['pkt'][3])
File "/home/ubuntu/ryu/ryu/lib/packet/dhcp.py", line 212, in parser
return cls._parser(buf)
File "/home/ubuntu/ryu/ryu/lib/packet/dhcp.py", line 192, in _parser
) = struct.unpack_from(unpack_str, buf)
error: unpack_from requires a buffer of at least 233 bytes
So, dhcp.py is not receiving the 233 bytes that it requires. Unfortunately, I am using an Open vSwitch on the VM provided by SDN hub, and 128 bytes seems to be a limit. So, I have a conflict with Ryu's dhcp.py file. My solution was to modify dhcp.py. How that was done follows.
Before modifying the code, I recommend you first update your Ryu controller. The procedures are as follows:
Step 1: If you are using a VM. Take a stapshot or clone it now.
Step 2: Update Ryu
cd ryu
git pull
If you were running an older version like I was, then the following error may occur when you next attempt to run your Ryu controller:
Traceback (most recent call last):
File "./bin/ryu-manager", line 18, in <module>
from ryu.cmd.manager import main
File "/home/ubuntu/ryu/ryu/cmd/manager.py", line 31, in <module>
from ryu.base.app_manager import AppManager
File "/home/ubuntu/ryu/ryu/base/app_manager.py", line 37, in <module>
from ryu.controller.controller import Datapath
File "/home/ubuntu/ryu/ryu/controller/controller.py", line 74, in <module>
help='Maximum number of unreplied echo requests before datapath is disconnected.')
File "/usr/local/lib/python2.7/dist-packages/oslo_config/cfg.py", line 1033, in __init__
super(IntOpt, self).__init__(name, type=types.Integer(), **kwargs)
TypeError: __init__() got an unexpected keyword argument 'min'
Step 3: Update your oslo_config file
sudo pip install oslo.config --upgrade
The TypeError from step 2 should now be resolved. (Hopefully, you cloned your VM just in case.)
Step 3: Modify Ryu's dhcp.py file
Ryu's dhcp.py file (located at /ryu/ryu/lib/packet) expects to receive a buffer of more than 235 bytes. Otherwise, it throws and error and returns nothing to the controller. Since my buffer only receives a buffer size of about 81 bytes. I modified the Ryu dhcp.py file as follows.
The error occurs because dhcp.py specifies a string format of '!BBBBIHH4s4s4s4s16s64s128s'. In #1, I created a second option. Do so, allows me to insert a few if statements to handle the packet differently if a packet arrives that is smaller than 100 bytes. Likewise, if the packet is greater than 235 bytes, then dhcp.py's handles the packet normally and returns the extra values.
class dhcp(packet_base.PacketBase):
"""DHCP (RFC 2131) header encoder/decoder class.
....deleted....
"""
_MIN_LEN = 236
_HLEN_UNPACK_STR = '!BBB'
_HLEN_UNPACK_LEN = struct.calcsize(_HLEN_UNPACK_STR)
_DHCP_UNPACK_STR = '!BIHH4s4s4s4s%ds%ds64s128s'
##################################################
#1(mod) Created second option for unpacking string
_DHCP_UNPACK_STR2 = '!BIHH4s4s4s4s%ds%ds40s'
_DHCP_PACK_STR = '!BBBBIHH4s4s4s4s16s64s128s'
#################################################
_DHCP_CHADDR_LEN = 16
_HARDWARE_TYPE_ETHERNET = 1
_class_prefixes = ['options']
_TYPE = {
'ascii': [
'ciaddr', 'yiaddr', 'siaddr', 'giaddr', 'chaddr', 'sname'
]
}
def __init__(self, op, chaddr, options, htype=_HARDWARE_TYPE_ETHERNET,
hlen=0, hops=0, xid=None, secs=0, flags=0,
ciaddr='0.0.0.0', yiaddr='0.0.0.0', siaddr='0.0.0.0',
giaddr='0.0.0.0', sname='', boot_file=b''):
super(dhcp, self).__init__()
#...Deleted No Changes made to init.
#classmethod
def _parser(cls, buf):
(op, htype, hlen) = struct.unpack_from(cls._HLEN_UNPACK_STR, buf)
buf = buf[cls._HLEN_UNPACK_LEN:]
####################################################
#2(mod) provided option for smaller packet sizes
if len(buf) < 100:
unpack_str = cls._DHCP_UNPACK_STR2 % (hlen,
(cls._DHCP_CHADDR_LEN - hlen))
else:
unpack_str = cls._DHCP_UNPACK_STR % (hlen,
(cls._DHCP_CHADDR_LEN - hlen))
#####################################################
min_len = struct.calcsize(unpack_str)
######################################################
#3(mod) provided option for smaller packets, set bootfile to b''
if min_len > 233:
(hops, xid, secs, flags, ciaddr, yiaddr, siaddr, giaddr,
chaddr, dummy, sname, boot_file
) = struct.unpack_from(unpack_str, buf)
else:
boot_file=b''
(hops, xid, secs, flags, ciaddr, yiaddr, siaddr, giaddr,
chaddr, dummy, sname, boot_file
) = struct.unpack_from(unpack_str, buf)+(boot_file,)
########################################################
length = min_len
########################################################
# (mod) provided option for smaller packet sizes, no parse_opt
if len(buf) > 233:
parse_opt = options.parser(buf[min_len:])
length += parse_opt.options_len
else:
parse_opt = None
length = min_len
#########################################################
return (cls(op, addrconv.mac.bin_to_text(chaddr), parse_opt,
htype, hlen, hops, xid, secs, flags,
addrconv.ipv4.bin_to_text(ciaddr),
addrconv.ipv4.bin_to_text(yiaddr),
addrconv.ipv4.bin_to_text(siaddr),
addrconv.ipv4.bin_to_text(giaddr),
sname.decode('ascii'), boot_file),
None, buf[length:])
The complete file will soon be on https://github.com/Ryuretic/RyureticLabs/tree/master/ryu/ryu/app/Ryuretic/Support_Files.
If you make these adjustements to the dhcp.py file, then you will gain access to the following header fields:
============== ====================
Attribute Description
============== ====================
op Message op code / message type.\
1 = BOOTREQUEST, 2 = BOOTREPLY
htype Hardware address type (e.g. '1' = 10mb ethernet).
hlen Hardware address length (e.g. '6' = 10mb ethernet).
hops Client sets to zero, optionally used by relay agent\
when booting via a relay agent.
xid Transaction ID, a random number chosen by the client,\
used by the client and serverto associate messages\
and responses between a client and a server.
secs Filled in by client, seconds elapsed since client\
began address acquisition or renewal process.
flags Flags.
ciaddr Client IP address; only filled in if client is in\
BOUND, RENEW or REBINDING state and can respond\
to ARP requests.
yiaddr 'your' (client) IP address.
siaddr IP address of next server to use in bootstrap;\
returned in DHCPOFFER, DHserver.
giaddr Relay agent IP address, used in booting via a\
relay agent.
chaddr Client hardware address.
sname(partial) Optional server host name, null terminated string.

Use Kivy app while excel file is being built

So I am trying to create a Kivy app that allows a user to control and monitor various hardware components. Part of the code builds and continuously updates an Excel worksheet that imports temperature readings from the hardware's comm port, along with a time-stamp. I have been able to implement all of this so far, but I am unable to interact with the Kivy app while the Excel worksheet is being built/updated (i.e. while my hardware test is underway), and leaves me unable to use the app's features while the test is running (Such as the 'Pause' or 'Abort' buttons) until the worksheet is no longer being altered. So my question is: Is it possible to export to an Excel file while being able to simultaneously use the Kivy app? And if so, how?
This is part of my code that sets up the Excel worksheet. Thank you in advance!
from kivy.app import App
from openpyxl import Workbook, load_workbook
import time
class HomeScreen(Screen):
def build(self):
return HomeScreen()
def RunExcelFile(self):
wb = Workbook()
ws = wb.active
a = 0
i = 2
while (a < 5):
ws.cell('A1').value = 'Time'
ws.cell('B1').value = 'Batch 1'
ws.cell('C1').value = 'Batch 2'
column = 'A'
row = i
time_cell = column + str(row)
t = time.localtime()
ws.cell(time_cell).value = time.asctime(t)
a = (a + 1)
i = (i + 1)
time.sleep(1)
wb.save("scatter.xlsx")
If you are doing some background job without touching widgets or properties, you can use threading module without problems. Otherwise, you would need to use #mainthread decorator or Clock.
import time
import threading
class HomeScreen(Screen):
def run_excel_file(self):
def job():
for i in xrange(5):
print i
time.sleep(1)
print 'job done'
threading.Thread(target=job).start()

DBSeqRecord cannot access annotations, features using BioSQL under BioPython

Running on Ubuntu 12.10 with Python 2.7, latest BioPython and BioSQL.
I have successfully established the MySQL-based BioSQL server, and I can load sequences into the system properly (or they seem to be proper--tables are populated correctly in MySQL and things are generally error-free).
However--when I retrieve via 'lookup,' I can only access the id, name, and description for the DBSeqRecords. Annotations and features are supposed to be called on demand, but this crashes things. For example:
File "/usr/lib/pymodules/python2.7/Bio/SeqRecord.py", line 595, in __str__
lines.append("Number of features: %i" % len(self.features))
File "/usr/lib/pymodules/python2.7/BioSQL/BioSeq.py", line 516, in __get_features
self._primary_id)
File "/usr/lib/pymodules/python2.7/BioSQL/BioSeq.py", line 280, in _retrieve_features
feature.location = SeqFeature.FeatureLocation(start, end)
File "/usr/lib/pymodules/python2.7/Bio/SeqFeature.py", line 561, in __init__
raise TypeError(start)
TypeError: 0
Any idea what is happening here?
I encountered the same error just this week.
A feature's start and end positions are retrieved from MySQL as type long (not int) but SeqFeature.py expects int only for start and end when instantiating a FeatureLocation. I don't know what has changed in mysql server, MySQLdb, BioSeqDatabase or SeqFeature to have provoked the problem.
Hopefully one of the biopython developers will be able to provide a long term solution but these are suggestions for temporary fixes:
try to get to the MySQLdb connection used by BioSeqDatabase and change the conversion behaviour with the conv keyword parameter of its connect function (I haven't been able to do this)
hack BioSeqDatabase so that start_pos and end_pos are converted to int after the values are fetched from MySQL (I haven't done this)
hack SeqFeature.py to allow long type for start and end when instantiating a FeatureLocation object (this is what I have done). Change this:
if isinstance(start, AbstractPosition):
self._start = start
elif isinstance(start, int):
self._start = ExactPosition(start)
else:
raise TypeError(start)
if isinstance(end, AbstractPosition):
self._end = end
elif isinstance(end, int):
self._end = ExactPosition(end)
else:
raise TypeError(end)
to this:
if isinstance(start, AbstractPosition):
self._start = start
elif isinstance(start, int) or isinstance(start, long):
self._start = ExactPosition(start)
else:
raise TypeError(start)
if isinstance(end, AbstractPosition):
self._end = end
elif isinstance(end, int) or isinstance(end, long):
self._end = ExactPosition(end)
else:
raise TypeError(end)

Resources