Beispiel #1
0
def test_get_extended_prices():
    print("Running test_get_extended_prices()")
    """
    This base method uses the following prioritization to populate the price horizon needed by this local asset:
        1. Actual marginal prices offered by the market.
        2. Actual marginal prices in prior sequential markets that are similar to the market.
        3. Actual marginal prices in prior markets that are being corrected by the market.
        4. Modeled prices using the market's price model
        5. The market's default price value.
        6. Nothing
    """
    # ******************************************************************************************************************
    print("  Case 1. Actual marginal prices offered by the market."
          )  # *****************************************
    # The test setup is such that the local asset should use Methods 1 to find an existing marginal price in its market.
    now = datetime.now()
    # test_asset = LocalAsset()
    test_asset_model = LocalAsset()
    # test_asset = test_asset_model
    # test_asset_model.object = test_asset
    test_asset_model.schedulingHorizon = timedelta(hours=0.5)
    test_market = Market()
    test_interval = TimeInterval(now, timedelta(hours=1), test_market, now,
                                 now)
    price = 3.14159
    test_price = IntervalValue(None, test_interval, test_market, 'test', price)
    test_market.timeIntervals = [test_interval]
    test_market.marginalPrices = [test_price]
    test_mtn = TransactiveNode()
    test_mtn.markets = [test_market]
    test_mtn.localAssets = [test_asset_model]

    assert len(test_market.marginalPrices
               ) == 1, 'The market was supposed to have a marginal price'
    assert datetime.now() + test_asset_model.schedulingHorizon \
           < test_market.timeIntervals[0].startTime + test_market.intervalDuration, \
        'For this test, the existing marginal price intervals should not extend beyond the scheduling horizon.'

    try:
        price_set = test_asset_model.get_extended_prices(test_market)
        print("  The case ran without errors.")
    except RuntimeWarning as cause:
        print("  The case encountered errors.", cause)
        price_set = []

    assert len(price_set) == 1, 'An unexpected number of prices was found'
    assert price_set[0].value == price, 'The price was no correct'

    # ******************************************************************************************************************
    print(
        "  Case 2. Actual marginal prices in prior sequential market that is similar to the market."
    )  # ****
    # The test setup is such that the local asset should sequentially use Methods 1, & 2 to find two marginal prices.
    now = datetime.now()

    test_asset_model = LocalAsset()

    test_asset_model.schedulingHorizon = timedelta(
        hours=1.5)  # Should cause asset to use prior market

    test_market = Market()

    test_interval0 = TimeInterval(now, timedelta(hours=1), test_market, now,
                                  now)
    price0 = 3.14159
    test_price0 = IntervalValue(None, test_interval0, test_market, 'test',
                                price0)
    test_market.timeIntervals = [test_interval0]
    test_market.marginalPrices = [test_price0]
    test_market.marketSeriesName = "Test Market"
    test_market.marketClearingTime = now

    prior_market = Market()
    test_interval1 = TimeInterval(now, timedelta(hours=1), prior_market, now,
                                  now)
    test_interval2 = TimeInterval(now, timedelta(hours=1), prior_market, now,
                                  now + timedelta(hours=1))
    price1 = 10
    test_price1 = IntervalValue(None, test_interval1, prior_market, 'test',
                                price1)
    test_price2 = IntervalValue(None, test_interval2, prior_market, 'test',
                                price1)
    prior_market.timeIntervals = [test_interval1, test_interval2]
    prior_market.marginalPrices = [test_price1, test_price2]
    prior_market.marketSeriesName = test_market.marketSeriesName
    prior_market.marketClearingTime = test_market.marketClearingTime - timedelta(
        hours=1)

    test_market.priorMarketInSeries = prior_market  # Important pointer to preceding market interval in market series.

    test_mtn = TransactiveNode()
    test_mtn.markets = [prior_market, test_market]
    test_mtn.localAssets = [test_asset_model]

    assert len(test_market.marginalPrices
               ) == 1, 'The market was supposed to have a marginal price'
    assert len(prior_market.marginalPrices
               ) == 2, "The prior market should have had two prices"
    assert test_market.marketSeriesName == prior_market.marketSeriesName, 'The market names must be the same'
    assert test_market.priorMarketInSeries == prior_market, "The market must point to its predecessor in market series"

    try:
        price_set = test_asset_model.get_extended_prices(test_market)
        print("  The case ran without errors.")
    except RuntimeWarning as result:
        print("  The case encountered errors.", result)

    assert len(price_set) == 2, 'An unexpected number of prices was found'
    assert price_set[0].value == price0, 'The first price was not correct'
    assert price_set[1].value == price1, 'The second price was not correct'

    # ******************************************************************************************************************
    print(
        "  Case 3. Actual marginal prices in prior markets that are being corrected by the market."
    )  # *******
    # The test setup is such that the local asset should sequentially use Methods 1, 2, & 3 to find three marginal
    # prices.
    now = datetime.now()
    # test_asset = LocalAsset()
    test_asset_model = LocalAsset()
    # test_asset.model = test_asset_model
    # test_asset_model.object = test_asset
    test_asset_model.schedulingHorizon = timedelta(
        hours=2.5)  # Should cause asset to use prior market

    test_market = Market()

    test_interval0 = TimeInterval(now, timedelta(hours=1), test_market, now,
                                  now)
    price0 = 3.14159
    test_price0 = IntervalValue(None, test_interval0, test_market, 'test',
                                price0)
    test_market.timeIntervals = [test_interval0]
    test_market.marginalPrices = [test_price0]
    test_market.marketSeriesName = "Test Market"
    test_market.marketClearingTime = now

    prior_market = Market()
    test_interval1 = TimeInterval(now, timedelta(hours=1), prior_market, now,
                                  now)
    test_interval2 = TimeInterval(now, timedelta(hours=1), prior_market, now,
                                  now + timedelta(hours=1))
    price1 = 10
    test_price1 = IntervalValue(None, test_interval1, prior_market, 'test',
                                price1)
    test_price2 = IntervalValue(None, test_interval2, prior_market, 'test',
                                price1)
    prior_market.timeIntervals = [test_interval1, test_interval2]
    prior_market.marginalPrices = [test_price1, test_price2]
    prior_market.marketSeriesName = test_market.marketSeriesName
    prior_market.marketClearingTime = test_market.marketClearingTime - timedelta(
        hours=1)

    test_market.priorMarketInSeries = prior_market

    corrected_market = Market()
    price2 = 20
    test_interval3 = TimeInterval(now, timedelta(hours=1), corrected_market,
                                  now, now + timedelta(hours=2))
    test_price3 = IntervalValue(None, test_interval1, corrected_market, 'test',
                                price2)
    test_price4 = IntervalValue(None, test_interval2, corrected_market, 'test',
                                price2)
    test_price5 = IntervalValue(None, test_interval3, corrected_market, 'test',
                                price2)
    corrected_market.timeIntervals = [
        test_interval1, test_interval2, test_interval3
    ]
    corrected_market.marginalPrices = [test_price3, test_price4, test_price5]
    corrected_market.marketSeriesName = "Corrected Market"
    corrected_market.marketClearingTime = test_market.marketClearingTime - timedelta(
        hours=2)
    corrected_market.intervalDuration = timedelta(hours=1)

    test_market.priorRefinedMarket = corrected_market

    test_mtn = TransactiveNode()
    test_mtn.markets = [corrected_market, prior_market, test_market]
    test_mtn.localAssets = [test_asset_model]

    assert len(test_market.marginalPrices
               ) == 1, 'The market was supposed to have a marginal price'
    assert len(prior_market.marginalPrices
               ) == 2, "The prior market should have had two prices"
    assert len(corrected_market.marginalPrices
               ) == 3, 'The corrected market should have three prices'
    assert test_market.marketSeriesName == prior_market.marketSeriesName, 'The market names must be the same'

    try:
        price_set = test_asset_model.get_extended_prices(test_market)
        print("  The case ran without errors.")
    except RuntimeWarning as result:
        print("  The case encountered errors.", result)
        price_set = []

    assert len(price_set) == 3, 'An unexpected number of prices was found'
    assert price_set[0].value == price0, 'The first price was not correct'
    assert price_set[1].value == price1, 'The second price was not correct'
    assert price_set[2].value == price2, 'The third price was not correct'

    # ******************************************************************************************************************
    print("  Case 4. Modeled prices using the market's price model."
          )  # ***********************************************
    # The test setup is such that the local asset should use Methods 1 & 4 to find four marginal prices.
    now = datetime.now()
    test_asset_model = LocalAsset()
    test_asset_model.schedulingHorizon = timedelta(
        hours=3.5)  # Should cause asset to use prior market

    test_market = Market()

    test_interval0 = TimeInterval(now, timedelta(hours=1), test_market, now,
                                  now)
    price0 = 3.14159
    test_price0 = IntervalValue(None, test_interval0, test_market, 'test',
                                price0)
    test_market.timeIntervals = [test_interval0]
    test_market.marginalPrices = [test_price0]
    test_market.marketSeriesName = "Test Market"
    test_market.marketClearingTime = now
    test_market.priorMarketInSeries = None
    test_market.priorRefinedMarket = None
    avg_price = 30
    std_price = 0.1
    test_market.priceModel = [avg_price, std_price
                              ] * 24  # Critical to this test
    test_mtn = TransactiveNode()
    test_mtn.markets = [test_market]
    test_mtn.localAssets = [test_asset_model]

    assert len(test_market.marginalPrices
               ) == 1, 'The market was supposed to have a marginal price'
    assert len(test_market.priceModel
               ) == 48, 'A price model must exist for all 2 * 24 hours'

    try:
        price_set = test_asset_model.get_extended_prices(test_market)
        print("  The case ran without errors.")
    except RuntimeWarning as result:
        print("  The case encountered errors.", result)
        price_set = []

    # 200207DJH: The assignment of modeled prices now completes the prior successful method to the top of the next hour.
    #            Thereafter, modeled prices are assigned through the top of the hour that exceeds the scheduling
    #            horizon. Therefore, there is some variability in the count of
    assert len(price_set) == 4 or len(price_set) == 5, \
        ('An unexpected number', len(price_set), ' of prices was found')
    assert price_set[0].value == price0, 'The first price was not correct'
    assert all([price_set[x].value == avg_price for x in range(1, len(price_set))]), \
        'Prices 1 - 4 were not correct'

    # ******************************************************************************************************************
    print("  Case 5. The market's default price value."
          )  # ************************************************************

    test_asset_model = LocalAsset()

    test_asset_model.schedulingHorizon = timedelta(hours=4.5)

    test_market = Market()
    default_price = 1.2345
    test_market.defaultPrice = default_price
    test_market.priceModel = None
    test_market.intervalsToClear = 24
    test_market.intervalDuration = timedelta(hours=1)
    test_market.activationLeadTime = timedelta(days=2)
    test_market.priorRefinedMarket = None

    test_mtn = TransactiveNode()
    test_mtn.markets = [test_market]

    assert type(test_market.defaultPrice
                ) == float, 'A valid default price must be defined'

    try:
        price_set = test_asset_model.get_extended_prices(test_market)
        print("  The case ran without errors.")
    except RuntimeWarning:
        print("  The case encountered errors.")

    assert len(price_set) == 5, 'The number of horizon prices was unexpected'
    assert all([price_set[x].value == default_price for x in range(1, len(price_set))]), \
        'The default prices were not used'

    print("Method test_get_extended_prices() ran to completion.\n")
Beispiel #2
0
def test_update_dual_costs():
    # TEST_UPDATE_DUAL_COSTS() - test method update_dual_costs() that creates or revises the dual costs in active time
    # intervals using active vertices, scheduled powers, and marginal prices.
    # NOTE: This test is virtually identical to the Neighbor test of the same name.
    print('Running LocalAsset.test_update_dual_costs()')

    #   Create a test Market object.
    test_market = Market()

    #   Create and store a TimeInterval object.
    dt = datetime.now(
    )  # datetime that may be used for most datetime arguments
    time_interval = TimeInterval(dt, timedelta(hours=1), test_market, dt, dt)
    test_market.timeIntervals = [time_interval]

    #   Create and store a marginal price IntervalValue object.
    test_market.marginalPrices = [
        IntervalValue(test_market, time_interval, test_market,
                      MeasurementType.MarginalPrice, 0.1)
    ]

    #   Create a test LocalAsset.
    test_model = LocalAsset()

    #   Create and store a scheduled power IntervalValue in the active time interval.
    test_model.scheduledPowers = [
        IntervalValue(test_model, time_interval, test_market,
                      MeasurementType.ScheduledPower, 100)
    ]

    #   Create and store a production cost IntervalValue in the active time interval.
    test_model.productionCosts = [
        IntervalValue(test_model, time_interval, test_market,
                      MeasurementType.ProductionCost, 1000)
    ]

    # TEST 1
    print('- Test 1: First calculation of a dual cost')

    try:
        test_model.update_dual_costs(test_market)
        print('  The test ran without errors')
    except RuntimeWarning as cause:
        print('  The test encountered errors', cause)

    assert len(test_model.dualCosts
               ) == 1, 'The wrong number of dual cost values was created'

    dual_cost = test_model.dualCosts[0].value

    assert dual_cost == (1000 -
                         100 * 0.1), 'An unexpected dual cost value was found'

    # TEST 2
    print('- Test 2: Reassignment of an existing dual cost')

    #   Configure the test by modifying the marginal price value.
    test_market.marginalPrices[0].value = 0.2

    try:
        test_model.update_dual_costs(test_market)
        print('  The test ran without errors')
    except RuntimeWarning as cause:
        print('  The test encountered errors', cause)

    assert len(test_model.dualCosts
               ) == 1, 'The wrong number of dual cost values was created'

    dual_cost = test_model.dualCosts[0].value

    assert dual_cost == (1000 -
                         100 * 0.2), 'An unexpected dual cost value was found'

    # Success.
    print('Method test_update_dual_costs() ran to completion.\n')