. Create class Commodity which stores:
.. peak hours
.. shortest timeperiod
.. start of deliveryperiod (offset_hours)

. split base, peak, offpeak function into index and stamp

---

Use cases:

[x] = easy / doable / done
[ ] = more difficult / to-do

1) FWC data as flat-price-PfLine:
.. increase by xx Eur/MWh or multiply with factor [x]
.. decompose in peak and offpeak [x]
.. change frequency [x]

2) Sourced futures as flat-complete-PfLine:
.. extract price-part, volume-part, or revenue-part (as flat PfLine) [x]
.. decompose in peak and offpeak [x]
.. change frequency [x]

3) Sourced futures as nested-complete-PfLine:
.. extract price-part, volume-part, or revenue-part [ ] --> volume-part and revenue-part can be nested; price-part must be flattened.
.. change frequency [x]

4) Offtake with contract prices as flat-complete-PfLine:
.. Increase offtake while keeping prices the same [ ] 
.. change frequency [x]

5) Offtake with contract prices, combining a nestad-volume-PfLine with a nested-price-PfLine
   (e.g. volumes = current offtake + expected churn)
   (e.g. prices = energyprice + risk premium A + risk premium B)
.. [ ]


---

Use-case (5) requires that we can create a complete-PfLine 
from a nested-volume-PfLine and a nested-price-PfLine, or 
from a nested-volume-PfLine and a nested-revenue-PfLine.
These constituent PfLines should stay separate in the complete-PfLine. 

Possible implementations:

A)

Allow nested-PfLines to have hetrogeneous children.
  So: if all children are price/volume/revenue-PfLines, the containing PfLine is also a price/volume/revenue-PfLine,
  and if children are a mix of two (volume and price, or volume and revenue), the containing PfLine is a complete-PfLine.
  Not allowed: mixing price and revenue or esp. mixing all three (volume, price, and revenue)

  Consequences:
  .. All children need to be named, but a name is not always available. E.g., 
     combining a flat-volume-PfLine with a nested-price-PfLine, we don't have a name for
     the volume-PfLine.
  

B) 

*ALL* complete-PfLines are a combination of two non-complete-PfLines, stored under 
  the _vol, _pri, or _rev attribute (one of which is None). Each of these can be a flat
  or a nested PfLine.

  Consequences:
  .. We have the following objects and their "core data"
     . flat-volume, flat-price, flat-revenue: dataframe
     . nested-volume, nested-price, nested-revenue: dictionary of PfLines (=children)
     . flat-complete: two flat-noncomplete-PfLines (_vol, _pri, _rev)
     . nested-complete: two noncomplete-PfLines (_vol, _pri, _rev), of which at least 1 is nested, 
                    OR: dictionary of PfLines (=children)
  .. Difficulty: handling both types of nested-complete-PfLines: the ones which are a collection
     of >1 complete-PfLines (like "sourced") and the ones which are a collection of 2 non-complete
     PfLines (like "offtake-with-contract-prices").
     .. Nested-complete-PfLine which is a collection of complete-PfLins:
         sourced = nested-complete
         . "spot" = flat-complete
         . . _vol = flat-volume
         . . _rev = flat-revenue
         . "forward" = nested-complete
         . . "quarters" = complete
         . . . _vol = flat-volume-PfLine
         . . . _rev = flat-revenue-PfLine
         . . "months" = flat-complete
         . . . _vol = flat-volume-PfLine
         . . . _rev = flat-revenue-PfLine
     .. Nested-complete-PfLine which is a collection of a price-PfLine and a volume-PfLine
         offtake = nested-complete
         . _vol = nested-volume
         . . "current_offtake" = flat-volume
         . . "expected_churn" = flat-volume
         . _pri = nested-price
         . . "energy" = flate-price
         . . "premiumA" = flate-price
         . . "premiumB" = flate-price
     What's the API of both 


------

Wanted/Useful operations:

Flat/nested-vol/pri/rev-PfLine, here: flat/nested-revenue-PfLine:
. . add revenue
    --> API: flat-rev-PfLine + flat-rev <1>                    = flat-rev-PfLine
    --> API: flat-rev-PfLine + nested-rev <2>                  = NOTIMPLEMENTED
    --> API: nested-rev-PfLine + nested-rev <2>                = nested-rev-PfLine
    --> API: nested-rev-PfLine + flat-rev <1>                  = NOTIMPLEMENTED
. . add float, add volume, add price, add complete             = NOTIMPLEMENTED
. . multiply with or divide by dimensionless factor
    --> API: flat/nested-rev-PfLine * float-Series <3>         = flat/nested-rev-PfLine
. . multiply with or divide by revenue
    --> API: flat-rev-PfLine / flat-rev <1>                    = dimless-Series
    --> API: flat-rev-PfLine / nested-rev <2>                  = NOTIMPLEMENTED
    --> API: nested-rev-PfLine / flat/nested-rev               = NOTIMPLEMENTED
    --> API: flat/nested-rev-PfLine * flat/nested-rev          = NOTIMPLEMENTED
. . multiply with or divide by price or volume
    --> API: flat/nested-rev-PfLine / flat-pri <1>             = flat/nested-pri-PfLine
    --> API: flat/nested-rev-PfLine / nested-pri <2>           = NOTIMPLEMENTED
. . union with price or volume or revenue
    --> API: flat-rev-PfLine | flat-rev <1>                    = NOTIMPLEMENTED
    --> API: flat-rev-PfLine | flat-pri <1>                    = flat-com-PfLine
    --> API: flat-rev-PfLine | flat-vol <1>                    = flat-com-PfLine
    --> API: flat-rev-PfLine | flat-com <1>                    = NOTIMPLEMENTED
    --> API: flat-rev-PfLine | nested-pri <2>                  = nested2-com-PfLine <*>
    --> API: nested-rev-PfLine | flat-pri <1>                  = nested-com-PfLine <*>
    --> API: nested-rev-PfLine | nested-pri <2>                = nested-com-PfLine <*>
. . extract pint-Series:
    --> API: .w, .q, .p, .r                                    = pint-Series
. . extract pint-DataFrame:
    --> API: .df()                                             = pint-DataFrame
. . extract PfLine:
    --> API: .revenue                                          = flat/nested-rev-PfLine
    --> API: .volume, .price                                   = NOTIMPLEMENTED
. . flatten:
    --> API: .flatten()                                        = flat-rev-PfLine
<*> How to implement com-PfLine? TODO!
<1> flat-xxx-PfLine, or anything that can be turned into it, like pint-Quantity or pint-Series
<2> nested-xxx-PfLine, or anything that can be turned into it, like dictionary of children
<3> float-Series, or anything that can be turned into it, like single float



Flat/Nested1/Nested2-com-PfLine:
(Nested1 = collection of com-PfLines. 
 Nested2 = collection of one vol-PfLine and >= 1 pri-PfLines, or one vol-PfLine and >= 1 rev-PfLines.)
. . add complete
    --> API: flat-com-PfLine + flat-com <1>                    = flat-com-PfLine
    --> API: flat-com-PfLine + nested-com <2>                  = NOTIMPLEMENTED
    --> API: nested1-com-PfLine + flat-com <1>                 = NOTIMPLEMENTED
    --> API: nested1-com-PfLine + nested1-com <2>              = nested1-com-PfLine
    --> API: nested1-com-PfLine + nested2-com <2>              = NOTIMPLEMENTED
    --> API: nested2-com-PfLine + flat-com <1>                 = NOTIMPLEMENTED
    --> API: nested2-com-PfLine + nested1-com <2>              = NOTIMPLEMENTED
    --> API: nested2-com-PfLine + nested2-com <2>              = NOTIMPLEMENTED*
        *not implemented, because unclear what to do
. . add float, add volume, add price, add revenue              = NOTIMPLEMENTED
. . multiply with or divide by dimensionless factor
    --> API: flat/nested-com-PfLine * float-Series <3>         = flat/nested-com-PfLine
        (multiply volumes and revenues)
. . multiply with or divide by complete
    --> API: flat-com-PfLine / flat-com <1>                    = dimless-Series
    --> API: flat-com-PfLine / nested-com <2>                  = NOTIMPLEMENTED
    --> API: nested-com-PfLine / Any                           = NOTIMPLEMENTED
. . multiply with or divide by volume, price, revenue          = NOTIMPLEMENTED
. . union
    --> API: flat-com-PfLine | Any                             = NOTIMPLEMENTED
    --> API: nested-com-PfLine | Any                           = NOTIMPLEMENTED
. . extract pint-Series:
    --> API: .w, .q, .p, .r                                    = pint-Series
. . extract pint-DataFrame:
    --> API: .df()                                             = pint-DataFrame
. . extract PfLine:
    --> API: .revenue                                          = flat/nested-rev-PfLine
    --> API: .volume, .price                                   = NOTIMPLEMENTED
. . flatten:
    --> API: .flatten()                                        = flat-all-PfLine


