<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Bar data
Step1:  Historical data
To get the earliest date of available bar data the "head timestamp" can be requested
Step2:  To request hourly data of the last 60 trading days
Step3:  Convert the list of bars to a data frame and print the first and last rows
Step4:  Instruct the notebook to draw plot graphics inline
Step5:  Plot the close data
Step6:  There is also a utility function to plot bars as a candlestick plot. It can accept either a DataFrame or a list of bars. Here it will print the last 100 bars
Step7:  Historical data with realtime updates
A new feature of the API is to get live updates for historical bars. This is done by setting endDateTime to an empty string and the keepUpToDate parameter to True.
Let's get some bars with an keepUpToDate subscription
Step8:  Replot for every change of the last bar
Step9:  Realtime bars
With reqRealTimeBars a subscription is started that sends a new bar every 5 seconds.
First we'll set up a event handler for bar updates
Step10:  Then do the real request and connect the event handler,
Step11:  let it run for half a minute and then cancel the realtime bars.
Step12:  The advantage of reqRealTimeBars is that it behaves more robust when the connection to the IB server farms is interrupted. After the connection is restored, the bars from during the network outage will be backfilled and the live bars will resume.
reqHistoricalData + keepUpToDate will, at the moment of writing, leave the whole API inoperable after a network interruption.
<ASSISTANT_TASK:>
Python Code:
from ib_insync import *
util.startLoop()
ib = IB()
ib.connect('127.0.0.1', 7497, clientId=14)
Explanation: Bar data
End of explanation
contract = Stock('TSLA', 'SMART', 'USD')
ib.reqHeadTimeStamp(contract, whatToShow='TRADES', useRTH=True)
Explanation: Historical data
To get the earliest date of available bar data the "head timestamp" can be requested:
End of explanation
bars = ib.reqHistoricalData(
        contract,
        endDateTime='',
        durationStr='60 D',
        barSizeSetting='1 hour',
        whatToShow='TRADES',
        useRTH=True,
        formatDate=1)
bars[0]
Explanation: To request hourly data of the last 60 trading days:
End of explanation
df = util.df(bars)
display(df.head())
display(df.tail())
Explanation: Convert the list of bars to a data frame and print the first and last rows:
End of explanation
%matplotlib inline
Explanation: Instruct the notebook to draw plot graphics inline:
End of explanation
df.plot(y='close');
Explanation: Plot the close data
End of explanation
util.barplot(bars[-100:], title=contract.symbol);
Explanation: There is also a utility function to plot bars as a candlestick plot. It can accept either a DataFrame or a list of bars. Here it will print the last 100 bars:
End of explanation
contract = Forex('EURUSD')
bars = ib.reqHistoricalData(
        contract,
        endDateTime='',
        durationStr='900 S',
        barSizeSetting='10 secs',
        whatToShow='MIDPOINT',
        useRTH=True,
        formatDate=1,
        keepUpToDate=True)
Explanation: Historical data with realtime updates
A new feature of the API is to get live updates for historical bars. This is done by setting endDateTime to an empty string and the keepUpToDate parameter to True.
Let's get some bars with an keepUpToDate subscription:
End of explanation
from IPython.display import display, clear_output
import matplotlib.pyplot as plt
def onBarUpdate(bars, hasNewBar):
    plt.close()
    plot = util.barplot(bars)
    clear_output(wait=True)
    display(plot)
bars.updateEvent += onBarUpdate
ib.sleep(10)
ib.cancelHistoricalData(bars)
Explanation: Replot for every change of the last bar:
End of explanation
def onBarUpdate(bars, hasNewBar):
    print(bars[-1])
Explanation: Realtime bars
With reqRealTimeBars a subscription is started that sends a new bar every 5 seconds.
First we'll set up a event handler for bar updates:
End of explanation
bars = ib.reqRealTimeBars(contract, 5, 'MIDPOINT', False)
bars.updateEvent += onBarUpdate
Explanation: Then do the real request and connect the event handler,
End of explanation
ib.sleep(30)
ib.cancelRealTimeBars(bars)
Explanation: let it run for half a minute and then cancel the realtime bars.
End of explanation
ib.disconnect()
Explanation: The advantage of reqRealTimeBars is that it behaves more robust when the connection to the IB server farms is interrupted. After the connection is restored, the bars from during the network outage will be backfilled and the live bars will resume.
reqHistoricalData + keepUpToDate will, at the moment of writing, leave the whole API inoperable after a network interruption.
End of explanation
<END_TASK>