Metadata-Version: 2.1
Name: elektra
Version: 0.0.22
Summary: Power block price creation and conversion
Home-page: https://github.com/wearemolecule/elektra
Author: Molecule
Author-email: dev@molecule.io
License: UNKNOWN
Description: # Elektra
        
        Elektra is Molecule's core framework for block logic (i.e., how to compute mwh from 5x16, 2x16, etc. blocks). It's derived from a set of logic internal to the Molecule application, and we're happy to share it with the world -- because nobody should ever have to fight with North American power blocks _ever_ again.
        
        Elektra is in pre-release, which means that signatures may change over time as we evolve the project to 1.0. Submissions are welcome; just submit a pull request with your change.
        
        ## Installing Elektra
        
        Either clone this repo, or use pip:
        
        > pip3 install elektra
        > 
        ## Using Elektra
        
        In your python project, `import elektra` and use away. Usage examples are in `examples/examples.py`. A sample input CSV is there too. For the examples below, we will use that CSV. You can also use the table of data at the end of this file.
        
        ## Methods
        
        These are the primary methods available in Elektra. Other methods are available, but are undocumented.
        * [create_prices](#create_prices): Creates block prices from raw LMP input
        * [scrub_hourly_prices](#scrub_hourly_prices): Verifies that enough hourly LMPs are present
        * [convert](#convert): Converts hours in one block, to equivalent hours in another
        * [translate_blocks](#translate_blocks): Wraps [convert](#convert), and adds MW and/or MWh conversions
        * [is_dst_transition](#is_dst_transition): Determines if a date is a DST changeover day
        
        
        ### create_prices
        This method creates block prices, given hourly prices for a period of time and a handful of other parameters. A key function of this method is that it validates whether enough prices have been submitted to do the calculation. So, if the `block` is 5x16, but a price is missing for a Wednesday at 11 AM, an exception will be thrown. Daylight Savings Time is also contemplated.
        
        The *create_prices* method takes the following parameters:
        
        * `flow_date` - *date* | The as of date for the power prices (i.e., the settlement/reporting date needed)
        * `ticker` - *string* | The ticker symbol for the power product (Molecule ticker; used for identification, not calculation)
        * `node` - *string* | The node on the power grid (used for identification, not calculation)
        * `iso` - *Elektra.Iso* | The name of the Independent System Operator (ISO). Acceptable ISOs are listed in the enum. CA-ISO is not currently supported.
        * `block` - *Elektra.Block* | The desired power block for the output prices
        * `frequency` *Elektra.Frequency* | The desired frequency for the output prices either Daily or Monthly
        * `prices` *DataFrame* | A Pandas dataframe of prices consisting of `flow_date`, `hour_ending`, and `price`
        
        The response from the method is a single floating-point price.
        
        #### Example
        ``` python
        import elektra
        import pandas as pd
        import filecmp
        import datetime as dt
        
        flow_date = dt.datetime(2020, 10, 17)
        prices = pd.read_csv('lmps.csv')
        
        result = elektra.create_prices(flow_date, 'M.XXXX', 'INDIANA.HUB', 'miso', '2x16', 'Daily', prices)
        print(result)
        
        ```
        
        ### scrub_hourly_prices
        This method validates that a submitted dataframe contains all the necessary hourly prices for a flow date, and returns a DataFrame with these prices. Daylight Savings Time (long-day and short-day) is contemplated.
        
        The *scrub_hourly_prices* method takes the following parameters:
        
        * `flow_date` - *date* | The as of date for the power prices (i.e., the settlement/reporting date needed)
        * `ticker` - *string* | The ticker symbol for the power product (Molecule ticker; used for identification, not calculation)
        * `node` - *string* | The node on the power grid (used for identification, not calculation)
        * `iso` - *Elektra.Iso* | The name of the Independent System Operator (ISO). Acceptable ISOs are listed in the enum. CA-ISO is not currently supported.
        * `prices` *DataFrame* | A Pandas dataframe of prices consisting of `flow_date`, `hour_ending`, and `price`
        
        The response from the method is a Pandas dataframe with the following columns of data:
        
        * Hour Beginning
        * Hour Ending
        * Required
        * Special
        * Value
        
        #### Example
        ``` python
        import elektra
        import pandas as pd
        import filecmp
        import datetime as dt
        
        flow_date = dt.datetime(2020, 10, 17)
        prices = pd.read_csv('lmps.csv')
        
        result = elektra.scrub_hourly_prices(flow_date,'M.XXXX', '116013753', 'pjm', prices)
        print(result)
        
        ```
        
        
        ### convert
        Given a flow date and an input block (i.e., 5x16), this method returns the number of hours in another block.
        
        For example, if today is Wednesday, November 4, 2020, and I have a 7x24 block (24 hours), but I want to see how many 5x16 hours that implies -- I'll get 16. On the other hand, if today is Saturday, October 31, 2020, and I have a Wrap block (24 hours that day), that only implies 8 hours of 7x8. This is useful when trying to convert a position purchased in one block, to a volume of another block. It works in tandem with the TranslateBlocks method.
        
        The *convert* method takes the following parameters:
        
        * `flow_date` - *date* | The as of date for the power prices (i.e., the settlement/reporting date needed)
        * `input_block` -- (text: Wrap, 5x16, 2x16, 7x8, 7x16, 1x1) | The input block.
        * `output_block` -- (text: Wrap, 5x16, 2x16, 7x8, 7x16, 1x1) | The block for which we want to see hours.
        
        The response from this method is an integer, representing the number of hours in the output block.
        
        #### Example
        ``` python
        import elektra
        import datetime as dt
        
        flow_date = dt.datetime(2020, 10, 17)
        
        result = elektra.convert(flow_date, '7x24', '2x16') # 16: (October 17 2020 is a Saturday, and has 16 peak hours)
        result = elektra.convert(flow_date, '7x24', '5x16') # 0: (October 17 2020 is a Saturday, and has 0 weekday peak hours)
        result = elektra.convert(flow_date, '5x16', '2x16') # 0: (October 17 2020 is a Saturday, and there could not be a 5x16 input block)
        
        ```
        
        ### translate_blocks
        Wrapper for `convert`, which adds the ability to convert a MW position for a term block (i.e., 7x24 monthly) to another block (or blocks) for that same term (i.e., 5x16, 2x16).
        
        The *translateBlocks* method takes the following parameters:
        * `iso` - *string* | The short name of the Independent System Operator (Elektra.Iso). This is not currently used, so beware when using for CAISO.
        * `mw` - *decimal* | The number of megawatts on the input block to be used for mw/mwh computation
        * `frequency` - *text* | monthly, daily, or hourly. Currently only monthly is implemented.
        * `contract_start` *date* | The first flow date of the block. This method will compute the last flow date.
        * `in_block` - *string* | 7x24, 5x16, Wrap, 2x16, 7x8
        * `out_blocks` - *string array* | accepted values include 7x24, 5x16, Wrap, 2x16, 7x8
        * `out_uom` - *string* | Set to `MW` for a megawatt number. Default is `mwh`.
        
        The response from this method is a DataFrame with the following columns:
        * date (i.e., flow date)
        * one column for each `out_block`, representing the number of MW or MWh for each date
        
        #### Example
        ``` python
        import elektra
        import datetime as dt
        
        flow_date = dt.datetime(2020, 10, 1)
        result = elektra.translateBlocks('pjm', 20, 'monthly', flow_date, '7x24', ['5x16', '2x16'], 'mwh')
        print(result)
        ```
        
        ### is_dst_transition
        Responds with two variables that indicate whether the input date is the _short day_ of the year (i.e., spring DST transition day) or the _long day_ of the year (fall). If the date is neither, both variables are false.
        
        The method takes the following parameter:
        * `as_of` - *date* | The date to test
        
        The method returns the following parameters:
        * `short_day` - *boolean* | True, if the supplied date is the short day
        * `long_day` - *boolean* | True, if the supplied date is the long day
        
        #### Example
        ``` python
        import elektra
        import datetime as dt
        flow_date = dt.datetime(2021, 3, 14)
        
        short_day, long_day = elektra.is_dst_transition(flow_date)
        print(short_day) # True; this is the sprint DST transition date
        print(long_day) # False; that would be the "fall back" date
        ```
        
        ## Sample Data
        This data is suitable for inputs to the hourly and block price converters:
        
        | flow_date  | hour_ending | price |
        |------------|-------------|-------|
        | 2020-10-17 | 1.0         | 26.48 |
        | 2020-10-17 | 2.0         | 20.35 |
        | 2020-10-17 | 3.0         | 17.19 |
        | 2020-10-17 | 4.0         | 17.16 |
        | 2020-10-17 | 5.0         | 20.28 |
        | 2020-10-17 | 6.0         | 34.25 |
        | 2020-10-17 | 7.0         | 21.24 |
        | 2020-10-17 | 8.0         | 23.67 |
        | 2020-10-17 | 9.0         | 22.37 |
        | 2020-10-17 | 10.0        | 20.81 |
        | 2020-10-17 | 11.0        | 21.10 |
        | 2020-10-17 | 12.0        | 19.28 |
        | 2020-10-17 | 13.0        | 18.94 |
        | 2020-10-17 | 14.0        | 18.07 |
        | 2020-10-17 | 15.0        | 19.43 |
        | 2020-10-17 | 16.0        | 18.94 |
        | 2020-10-17 | 17.0        | 18.85 |
        | 2020-10-17 | 18.0        | 22.40 |
        | 2020-10-17 | 19.0        | 60.50 |
        | 2020-10-17 | 20.0        | 19.12 |
        | 2020-10-17 | 21.0        | 20.36 |
        | 2020-10-17 | 22.0        | 19.39 |
        | 2020-10-17 | 23.0        | 17.67 |
        | 2020-10-17 | 24.0        | 17.55 |
        
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
