start_historical_data_subscription

start_historical_data_subscription(historical_data=None, hd_socket=None, subscription_id=None, contract=Contract({}), endDateTime='', durationStr='1 D', barSizeSetting='1 hour', whatToShow='Trades', useRTH=1, formatDate=1, keepUpToDate=0)

Reactively get historical data

Creates a subscription for historical data using the parameters supplied. Results will appear in the sb_rvs['historical_data'] object, where they are accessible by other functions in your app.

Parameters

Name Type Description Default
historical_data You probably want to pass sb_rvs['historical_data'] to this parameter unless you have declared a different reactive variable for storing your historical data queries. Unless you have a very specific use case to do otherwise, use sb_rvs['historical_data']. None
hd_socket The socket on which you want to make the historical data subscription. You almost certainly want to pass ib_socket as this parameter unless you have constructed an app that uses different sockets for different tasks. This is not recommended except for advanced use cases. None
subscription_id Identifier of the request. You may use your own system, such as using contract symbol as your ID if you wish. If not supplied, then ShinyBroker will assign the smallest number that isn’t already in use as a historical data subscription ID. None
contract The Contract object for which you want data Contract({})
endDateTime Ending datetime string formatted as “YYYYMMDD HH:mm:ss TMZ” specifying the end of the time period for which you want historical data. Leave it as the default “” to get historical data up to the current present moment. ''
durationStr A Duration String that specifies how far back in time you want to fetch data. '1 D'
barSizeSetting A Bar Size that specifies how fine-grained you want your historical data to be (daily, weekly, every 30 seconds, etc). '1 hour'
whatToShow You may select from any of the Historical Data Types but for most cases you’ll probably be happy with one of “BID_ASK”, “MIDPOINT”, or “TRADES”. 'Trades'
useRTH “Use Regular Trading Hours”. Set to False if you want the historical data to include after-hours/pre-market trading 1
formatDate Numeric code from the Format Date Received table that specifies how you want your dates formatted in the data. 1
keepUpToDate Set to True if you want to keep receiving new bar data as it becomes available. For a barSizeSetting of 5 min, that would mean you receive new data every 5 minutes. 0

Example

Run the app below for an informative exploration of this function and related objects.

import shinybroker as sb
from shiny import Inputs, Outputs, Session, ui, render, reactive, req

shdss_ui = ui.page_fluid(
    ui.h2("Historical Data Fetcher"),
    ui.p(
        'When you click the "Fetch Historical Data" button, this app ' +
        'feeds each of the labelled inputs to ',
        ui.code("start_historical_data_subscription"),
        "which assigns an ID to each query and makes the data request. " +
        "ShinyBroker then reactively receives the data as it comes in and " +
        "stores it in the reactive variable ",
        ui.code("sb_rvs['historical_data']"),
        ", which this app uses to populate the output fields."
    ),
    ui.p(
        "For simplicity, the contract object is defined here using ",
        ui.code("conId"),
        " only. Feel free to experiment with other IDs such as '76792991' " +
        "(Tesla), '43645865' (IBKR), '36285627' (GameStop), or use the " +
        "tools from the \"Inspect\" tab of ShinyBroker to look up more."
    ),
    ui.br(),
    ui.row(
        ui.column(
            3,
            ui.input_text(
                id='con_id',
                label='conId',
                value='265598'
            )
        ),
        ui.column(6),
        ui.column(
            3,
            ui.input_action_button(
                id='fetch_data',
                label='Fetch Historical Data'
            )
        )
    ),
    ui.row(
        ui.column(
            3,
            ui.input_text(
                id='endDateTime',
                label='endDateTime',
                value=''
            )
        ),
        ui.column(
            3,
            ui.input_text(
                id='durationStr',
                label='durationStr',
                value='1 W'
            )
        ),
        ui.column(
            3,
            ui.input_text(
                id='barSizeSetting',
                label='barSizeSetting',
                value='1 day'
            )
        ),
        ui.column(
            3,
            ui.input_text(
                id='whatToShow',
                label='whatToShow',
                value='Trades'
            )
        )
    ),
    ui.row(
        ui.column(
            3,
            ui.input_switch(id="useRTH", label="useRTH", value=True)
        ),
        ui.column(
            3,
            ui.input_radio_buttons(
                "formatDate",
                "formatDate",
                {
                    "1": "String Time Zone Date",
                    "2": "Epoch Date",
                    "3": "Day & Time Date"
                }
            )
        ),
        ui.column(
            3,
            ui.input_switch(
                id="keepUpToDate", label="keepUpToDate", value=False
            )
        ),
        ui.column(3)
    ),
    ui.output_ui('hd_selector'),
    ui.output_ui('hd_output')
)


# Server to support the new UI
# Signature must always contain the following five parameters:
#   input, output, session, ib_socket, and sb_rvs
def shdss_server(
        input: Inputs, output: Outputs, session: Session, ib_socket, sb_rvs
):

    @reactive.effect
    @reactive.event(input.fetch_data, ignore_init=True)
    def fetch_historical_data():
        sb.start_historical_data_subscription(
            historical_data=sb_rvs['historical_data'],
            hd_socket=ib_socket,
            contract=sb.Contract({'conId': input.con_id()}),
            endDateTime=input.endDateTime(),
            durationStr=input.durationStr(),
            barSizeSetting=input.barSizeSetting(),
            useRTH=input.useRTH(),
            formatDate=input.formatDate(),
            keepUpToDate=input.keepUpToDate()
        )

    @render.ui
    @reactive.event(input.fetch_data, ignore_init=True)
    def hd_selector():
        if len(sb_rvs['historical_data']().keys()) > 0:
            return ui.TagList(
                ui.input_radio_buttons(
                    id='selected_hd_id',
                    label='Select an ID to display historical data',
                    choices=dict(
                        zip(
                            sb_rvs['historical_data']().keys(),
                            sb_rvs['historical_data']().keys()
                        )
                    )
                ),
                ui.output_ui('hd_description'),
                ui.output_data_frame('selected_hd_data')
            )
        else:
            return ui.TagList(
                ui.p(
                    'Please make a historical data request and the results ' +
                    'will appear here.'
                )
            )

    @render.data_frame
    def selected_hd_data():
        selected_hd = sb_rvs['historical_data']().get(
            input.selected_hd_id(), {}
        ).get('hst_dta', False)
        req(selected_hd is not False, cancel_output=True)
        return render.DataTable(selected_hd)

    @render.ui
    @reactive.event(input.fetch_data, ignore_init=True)
    def hd_description():
        return ui.TagList(
            ui.br(),
            ui.h5(
                "Here is the output of all the elements of ",
                ui.code("sb_rvs['historical_data']"),
                " except for ",
                ui.code('\'hst_dta\''),
                ":"
            ),
            ui.code(str({
                key: value for (key, value) in
                sb_rvs['historical_data']().get(
                    input.selected_hd_id()).items() if
                key != 'hst_dta'
            })),
            ui.br(),
            ui.br(),
            ui.h5(
                '...and here are the contents of ',
                ui.code(
                    "sb_rvs['historical_data']().get(input.selected_hd_id)" +
                    ".get('hst_dta')"
                ),
                ", rendered as a data table output:"
            )
        )




# Create a ShinyBroker app with the new ui and server
app = sb.sb_app(
    shdss_ui,
    shdss_server,
    host='127.0.0.1',
    port=7497,
    client_id=10742
)

app.run()