Пример #1
0
def get_table(date,
              stem,
              future_type,
              status,
              we_trade=True,
              nac=4,
              ncb=1,
              data_download=False):
    """Generate a table of all the contracts available for a market and the associated last date.

    :param date: str - Date reference for the active or expired contracts
    :param stem: str - Market Stem
    :param future_type: Enum FutureType - Type of contract
    :param status: Enum Status - Status needed for the chain
    :param we_trade: bool - Whether or not the contract is considered as traded
    :param nac: int - Number of active contracts to get (depending on the markets)
    :param ncb: int - Number of contracts in between (not for outrights)
    :param data_download: bool - Option for data download (as we need to use LTD for completeness)
    :return: A dataframe of all the available tickers with the last date
    """
    ld_rule = 'LTD' if data_download else oci.get(stem, 'Reference')
    # Get the contract table
    ct_df = oci.ctrmth(stem, we_trade)
    # Generate the contracts
    contracts = []
    active = 0
    min_ctrmth = 20000000 if future_type == oci.FutureType.Outright else 20070000
    for index, row in ct_df[ct_df['CtrMth'] > min_ctrmth].iterrows():
        cts = generate_contracts(stem, row['CtrMth'], future_type, ct_df, ncb)
        for c in cts:
            if not isinstance(row[ld_rule], str):
                raise ChainError('Problem in CtrMth table for: {}!'.format(c))
            # Add 5 days to the end if ActivePlus Status (to continue downloading data for expired contracts)
            end = (
                dt.datetime.strptime(row[ld_rule], '%Y-%m-%d') + o.BDay(5)
            ).strftime(
                '%Y-%m-%d') if status == Status.ActivePlus else row[ld_rule]
            # Add the contract depending on the status
            if status == Status.Active or status == Status.ActiveLive or status == Status.ActivePlus:
                if date > end or active >= nac * ncb:
                    continue
                if date < row[
                        ld_rule]:  # Not counting expired contracts for data download in ActivePlus mode
                    active += 1
            elif status == Status.Expired and date < row[ld_rule]:
                break
            # Add the contract to the list of contracts
            contracts.append(
                co.OrderedDict({
                    'Ticker': c,
                    'LastDate': row[ld_rule]
                }))

    return pd.DataFrame(contracts)
Пример #2
0
def test_generate_contracts(stem, ctr_mth, future_type, ncb):
    df = oci.ctrmth(stem, True)
    lc = occ.generate_contracts(stem, ctr_mth, future_type, df, ncb)
    print(lc)
    # Check if list is returned
    assert isinstance(lc, list)
    # Check if length list is as expected
    if future_type == oci.FutureType.Outright:
        assert len(lc) == 1
    else:
        assert len(lc) == ncb
    # Check if an element is a string (if it is it must be a ticker)
    assert isinstance(lc[0], str)
Пример #3
0
def generate_curvature_list():
    """Generate a list of symbols for data download for the curvature strategy. This is to be used only to generate
    the symbols for the Excel Quotes sheet.

    :return: list - Active Tickers for ED and FF
    """
    log = logging.getLogger(__name__)

    log.debug('Generate list of tickers for Curvature')
    date = dt.datetime.today().strftime('%Y-%m-%d')
    tickers = []
    for m in ['ED', 'FF']:
        mcm = oci.ctrmth(m)
        fm = mcm[mcm['LTD'] >= date].iloc[0]['CtrMth']
        tickers.extend(
            generate_tickers_for_curvature(oci.ym_maturity(fm), m,
                                           1 if m == 'FF' else 3))
    # Transform to short maturities (specific to Curvature)
    tickers = ['{}{}'.format(t[0:-2], t[-1]) for t in tickers]
    return tickers
Пример #4
0
def amend_ctrmth(stem, amendments):
    """Amend the Contract Month table - This is a hard amend, as is, the old file will be overwritten with the changes.
    Must provide tuples of letters and status.

    :param stem: str - Customized Stem
    :param amendments: list - List of tuples (example: [('J', True)]
    """
    log = logging.getLogger(__name__)

    df = oci.ctrmth(stem, we_trade=False)
    # Amendments
    for a in amendments:
        df.loc[df['Letter'] == a[0], 'WeTrd'] = (-1 if a[1] else 0)
    log.debug('CtrMth table updated for: {} - Changes: {}'.format(stem, amendments))
    # Save new Contract Month table
    ric = oci.get_stem(stem, 'Reuters')
    file = os.path.join(c.cfg['default']['data'], 'CtrMth', '{}.csv'.format(ric))
    fields = ['CtrMth', 'WeTrd', 'LTD', 'FND', 'PosFstDt', 'PosLstDt']

    df[fields].to_csv(file, sep=',', index=False, header=True)
Пример #5
0
def per_contract(future_chain, field='Volume'):
    """Plot heatmap of the average Volume or Open Interest of the last 90 days. Display it by year for each contract.
    This should be useful to find out which contract are traded/not traded and where

    :param future_chain: object - Future Chain initialized with data
    :param field: str - Volume or OI
    :return: object - Plot Plotly chart
    """
    log = logging.getLogger(__name__)

    if field != 'Volume' and field != 'OI':
        raise Exception('Field provided must be str Volume or OI!')

    stem = future_chain.stem
    df = future_chain.chain
    data = future_chain.data
    # Average Volume
    df['Month'] = df.apply(lambda x: x['Ticker'][2:3], axis=1)
    df['Year'] = df.apply(lambda x: 2000 + int(x['Ticker'][-2:]), axis=1)
    # Add average volume of last 90 days
    df['AvgVol'] = 0
    for idx, row in df.iterrows():
        mdf = data[row['Ticker']]
        df.loc[idx, 'AvgVol'] = int(mdf[-90:][field].mean())
    # Transformation to HeatMap DF
    years = []
    for year in df['Year'].unique():
        ydf = df[df['Year'] == year][['Month', 'AvgVol']]
        ydf.set_index('Month', drop=True, inplace=True)
        ydf.index.names = [None]
        ydf.columns = [year]
        years.append(ydf)
    hdf = pd.concat(years, axis=1)
    # Index
    cdf = oci.ctrmth(stem, we_trade=False)
    cdf['Letter'] = cdf.apply(lambda x: oci.ym_maturity(x['CtrMth'])[0],
                              axis=1)
    lw = cdf.groupby('Letter').mean()
    lw['Index'] = lw.apply(lambda x: '{} (T: {})'.format(x.name, x['WeTrd']),
                           axis=1)
    rlw = lw.reindex(index=lw.index[::-1])
    # Plot
    rhdf = hdf.reindex(index=hdf.index[::-1])
    values = rhdf.values
    values = [[int(vi) if not math.isnan(vi) else float('NaN') for vi in v]
              for v in values]
    try:
        fig = pff.create_annotated_heatmap(values,
                                           x=list(rhdf.columns),
                                           y=list(rlw['Index']),
                                           colorscale='Jet',
                                           font_colors=['white'],
                                           hoverinfo='z')
        for i in range(len(fig.layout.annotations)):  # Make text size smaller
            fig.layout.annotations[i].font.size = 10
        fig.layout.title = '{} - {}'.format(stem, field)

        plo.iplot(fig)
    except ple.PlotlyError:
        log.error(
            'Most likely a problem with axis length: x: {} - y: {} - z: {}'.
            format(list(rhdf.columns), list(rlw['Index']), len(values)))
Пример #6
0
def test_ctrmth(stem, we_trade):
    df = oci.ctrmth(stem, we_trade)
    assert isinstance(df, pd.DataFrame)
    print(df.head())