Exemplo n.º 1
0
def get_cot(stem, cot_type='F'):
    """Get the cot data and cache it (Refresh it if file is older than 7 days).
    COT Types can be:
        -- F: Futures Only
        -- FO: Futures And Options
        -- F_L: Futures Only Legacy
        -- FO_L Futures And Options Only

    :param stem: str -  Market stem (customized)
    :param cot_type: String COT Type
    :return: Dataframe with COT data
    """
    log = logging.getLogger(__name__)

    # COT from CFTC Quandl or ICE
    log.debug('Get {} COT data for: {}'.format(cot_types[cot_type], stem))
    path = os.path.join(c.cfg['default']['data'], 'COT', cot_types[cot_type],
                        '{}.csv'.format(stem))
    if oci.get(stem, 'Exchange') == 'ICE':
        if cot_type == 'F_L' or cot_type == 'FO_L':
            raise Exception(
                'Legacy data for COT {} is not supported'.format(stem))
        else:
            if os.path.exists(path):

                # Read Data from csv file
                cot = pd.read_csv(path, index_col=0, parse_dates=True)

            else:
                raise Exception('File {} is not found'.format(path))
    else:
        # Check if file exists or is not too old
        if os.path.exists(path) \
               and dt.datetime.today() - dt.timedelta(days=2) < dt.datetime.fromtimestamp(os.stat(path).st_mtime):

            # Read Data from csv file
            cot = pd.read_csv(path, index_col=0, parse_dates=True)

        else:
            if cot_type in cot_types:
                try:
                    qdl_code = oci.get(stem, 'COT')
                    cot = qdl.get('CFTC/{}_{}_ALL'.format(qdl_code, cot_type))

                    cot.to_csv(path, header=True)

                except qdl.NotFoundError:
                    log.error('Incorrect code for download: {}'.format(stem))
                    return None
            else:
                raise Exception('COT Type {} not defined!'.format(cot_type))

    return cot
Exemplo n.º 2
0
def point(symbol):
    """Calculate the point value

    :param symbol: String symbol - Customized ticker
    :return: Float Point Value for the future
    """
    return oci.get(symbol[0:2], 'Point')
Exemplo n.º 3
0
def calculate_stds(df, length=20):
    """Calculate standard deviations for the spread in the specified dataframe. Returns a dataframe with a few
    extra columns. This is to be used in Excel.

    :param df: DataFrame universe of traded symbols
    :param length: Length for the standard deviation
    :return: DataFrame with results
    """
    log = logging.getLogger(__name__)

    df_stds = []
    for idx, row in df.iterrows():
        ticker = row['Ticker']
        log.debug('Process spread: {}'.format(ticker))
        # STD
        dfm = odu.get_market_df(ticker)
        if dfm is not None:
            dfm = dfm.tail(length)
            std = dfm['Close'].std()
        else:
            std = 0
        # COT
        cdf = odc.cot_data(ticker[0:2])
        hps = cdf.iloc[-1]['HPS']
        hph = cdf.iloc[-1]['HPH']
        # Add data
        df_stds.append({'Ticker': ticker, 'LastDate': row['LastDate'], 'DaysTo': row['DaysTo'],
                        'HPS': hps, 'HPH': hph, 'PVol':  std, 'IVol': std * i.get(ticker[0:2], 'Point')})
    # Return dataframe
    return pd.DataFrame(df_stds, columns=['Ticker', 'LastDate', 'DaysTo', 'HPS', 'HPH', 'PVol', 'IVol'])
Exemplo n.º 4
0
    def __init__(self, stem, future_type):
        """Future Chain Constructor

        :param stem:  str - Market Stem
        :param future_type:  Enum FutureType - Type of contract
        """
        self.log = logging.getLogger(__name__)

        self.stem = stem
        self.future_type = future_type
        self.status = None
        self.days_back = None
        self.chain = None
        self.contracts = None
        self.data = None
        self.margin = oci.get(stem, 'Margin')
        self.commission = oci.raw_comms(stem, dt.datetime.today())
        self.point = oci.get(stem, 'Point')
Exemplo n.º 5
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)
Exemplo n.º 6
0
 def date(self, ticker, last_day, days):
     try:
         sl_type = oci.get(ticker[0:2], 'Spot')
     except oci.InstrumentError:
         raise EventsError('Spot Limit not defined in database.json!')
     if sl_type == 'Close of trading on the first business day of the contract month':
         return self._close_first_business_day(ticker, days)
     elif sl_type == 'During the last x trading days of the contract':
         nb = oci.get(ticker[0:2], 'Rule')
         return self._last_x_business_days(last_day, -nb + days)
     elif sl_type == 'x Business Day following the expiration of the regular option contract traded on the expiring futures contract':
         nb = oci.get(ticker[0:2], 'Rule')
         return self._x_business_days_after_third_friday(
             last_day, nb + days)
     elif sl_type == 'Close of trading x business days prior to last trading day of the contract':
         nb = oci.get(ticker[0:2], 'Rule')
         return self._last_x_business_days(last_day, -nb + days)
     elif sl_type == 'Close of trading on the business day prior to the first notice day of the delivery month':
         nb = oci.get(ticker[0:2], 'Rule')
         return self._close_first_business_day(ticker, -nb + days)
     elif sl_type == 'Close of trading x business days prior to the first trading day of the delivery month':
         nb = oci.get(ticker[0:2], 'Rule')
         return self._close_first_business_day(ticker, -nb + days)
     elif sl_type == 'On and after First Notice Day':
         return self._on_fnd(last_day, days)
     else:
         raise EventsError('Spot Limit function not defined!')
Exemplo n.º 7
0
def generate_tickers_df(stem, status=occ.Status.Active):
    """Generate a DataFrame of symbols for a given stem for data download

    :param stem: str - Customized Stem
    :param status: Enum Status - Status needed for download
    :return: DataFrame with Ticker Column
    """
    log = logging.getLogger(__name__)

    dfs = []
    # Get number of active contracts and number of contracts in between
    # TODO: Populate database.json with values for all contracts!
    try:
        dl = oci.get(stem, 'Download')
        nac, ncb = dl['nac'], dl['ncb']
    except oci.InstrumentError:
        log.warning('{} - Set Download Parameters!'.format(stem))
        nac, ncb = 4, 1  # Default behaviour when no parameters
    params = {'as_dataframe': True, 'data_download': True}
    ot = occ.FutureChain(stem, oci.FutureType.Outright).initialize_contracts(
        status, we_trade=False, nac=nac, **params)
    st = occ.FutureChain(stem, oci.FutureType.Spread).initialize_contracts(
        status,
        we_trade=(False if stem != 'ED' else True),
        nac=nac - 1,
        ncb=ncb,
        **params)
    bt = occ.FutureChain(stem, oci.FutureType.Butterfly).initialize_contracts(
        status, we_trade=True, nac=nac -
        2, ncb=ncb, **params) if stem == 'ED' else None
    dfs.append(ot)
    dfs.append(st)
    if bt is not None:
        dfs.append(bt)
    sdf = pd.concat(dfs)

    return sdf.reset_index(drop=True)
Exemplo n.º 8
0
 def add_tick(self):
     # TODO: ED has half tick (implement if needed)
     self.row.append(i.get(self.ticker[0:2], 'Tick'))