<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def get_data_ib(instrument, start, resolution="1 min", blotter=None, output_path=None):
 """ Downloads historical data from Interactive Brokers :Parameters: instrument : mixed IB contract tuple / string (same as that given to strategy) start : str Backtest start date (YYYY-MM-DD [HH:MM:SS[.MS]) :Optional: resolution : str 1/5/15/30 secs, 1/2/3/5/15/30 min (default 1min), 1 hour, 1 day blotter : str Store MySQL server used by this Blotter (default is "auto detect") output_path : str Path to where the resulting CSV should be saved (optional) :Returns: data : pd.DataFrame Pandas DataFrame in a QTPyLib-compatible format and timezone """

    global _IB_HISTORY_DOWNLOADED
    _IB_HISTORY_DOWNLOADED = False

    # load blotter settings
    blotter_args = load_blotter_args(
        blotter, logger=logging.getLogger(__name__))

    # create contract string (no need for connection)
    ibConn = ezIBpy()
    ibConn.ibCallback = ibCallback

    if not ibConn.connected:
        ibConn.connect(clientId=997,
                       port=int(blotter_args['ibport']),
                       host=str(blotter_args['ibserver']))

    # generate a valid ib tuple
    instrument = tools.create_ib_tuple(instrument)
    contract_string = ibConn.contractString(instrument)
    contract = ibConn.createContract(instrument)

    ibConn.requestHistoricalData(contracts=[contract],
                                 data="TRADES", resolution=resolution,
                                 lookback=tools.ib_duration_str(start),
                                 rth=False)

    while not _IB_HISTORY_DOWNLOADED:
        time.sleep(1)

    ibConn.disconnect()

    data = ibConn.historicalData[contract_string]
    data['datetime'] = data.index
    return prepare_data(instrument, data, output_path=output_path)