In [28]:
from __future__ import division
import datetime
import pandas
import numpy
import matplotlib.pyplot as plt
import seaborn
seaborn.set_style("whitegrid")
seaborn.despine()
%matplotlib inline
%config InlineBackend.figure_formats = {'svg',}

In [29]:
def market_design(param):
    # Create a range of ratio
    ratios = numpy.linspace(0.01, param['ratio_end'], num=param['ratio_num'])

    # Create vectors
    sells = []
    buys = []
    PVprods = []
    LOADconss = []
    for ratio in ratios:
        # Fake Load and PV
        PVprod = 10
        LOADcons = ratio * PVprod /100
#         LOADcons = 10
#         PVprod = LOADcons * 100 / ratio

        # Clear price
        buy, sell = ratio_to_price(ratio, param)
        sells.append(sell)
        buys.append(buy)
        PVprods.append(PVprod)
        LOADconss.append(LOADcons)
    
    # Create plots
    plot_prices(ratios, sells, buys, PVprods, LOADconss, param)

def ratio_to_price(ratio, param):
    """Clearing price mechanism"""
    # Retailing price $/kW
    pge_buy = param['pge_buy']
    pge_sell = param['pge_sell']

    # Upper/lower margin coef
    upper_ratio = param['upper_ratio']
    lower_ratio = param['lower_ratio']

    # Maximum local electricity price
    minimum_local_sell = param['minimum_local_sell']

    # Minimum local electricity prices
    maximum_local_buy = param['maximum_local_buy']

    # If no feed back to main grid
    if ratio >= upper_ratio:
        # Selling price
        sell = minimum_local_sell

        # Buying price
        # buy = ((maximum_local_sell * PVprod) + (pge * (LOADcons - PVprod))) / LOADcons
        buy = minimum_local_sell * 1 /ratio + pge_sell * (1 - 1 /ratio)

    # RE production is around 66%
    elif ratio < upper_ratio and ratio > lower_ratio:
        # Selling price
        a = (minimum_local_sell - maximum_local_buy) / (upper_ratio - lower_ratio)
        b = maximum_local_buy - a * lower_ratio
        sell = a * ratio + b

        # Buying price
#         a = (maximum_local_buy - minimum_local_buy) / (upper_ratio - lower_ratio)
#         b = minimum_local_buy - a * lower_ratio
#         buy = a * ratio + b
        buy = sell * 1 /ratio + pge_sell * (1 - 1 /ratio)

    # RE production is bigger than local needs
    else:
        buy = maximum_local_buy
        sell = maximum_local_buy * ratio / 1 + pge_buy * (1 - ratio / 1)


    return buy, sell

def plot_prices(ratios, sells, buys, PVprods, LOADconss, param):
    # Check buy and sell match
    localProdPrice = [PVprods[i] * sells[i] for i in range(0, len(sells))]
    pgePrice = [(LOADconss[i] - PVprods[i]) * param['pge_sell'] 
                if (LOADconss[i] - PVprods[i]) >= 0 
                else (LOADconss[i] - PVprods[i]) * param['pge_buy'] 
                for i in range(0, len(sells))]
    localConsPrice = [LOADconss[i] * buys[i] for i in range(0, len(sells))]
    totalConsPrice = [localProdPrice[i] + pgePrice[i] for i in range(0, len(ratios))]

    # Plot price for different ratios
    seaborn.set(font_scale=1.5)
    seaborn.set_style("whitegrid")
    seaborn.despine()
    plt.figure(figsize=(11, 5), dpi=200)
    plt.plot(ratios, buys, label='Local buying price', linewidth=3)
    plt.plot(ratios, sells, label='Local selling price', linewidth=3)
    plt.plot(ratios, [param['pge_sell']] * len(ratios), '--', label='Utility selling price', linewidth=2.5)
    plt.plot(ratios, [param['pge_buy']] * len(ratios), '--',label='Utility buying price', linewidth=2.5)
    plt.ylim([0.06, 0.130])
    plt.ylabel('Price [$/kWh]')
    plt.xlabel('Ratio [Consumption/Generation]')
    plt.legend(loc=0)

    # Plot 
    plt.figure(figsize=(11, 5), dpi=200)
    plt.plot(LOADconss, localProdPrice, label='Local energy payment', linewidth=3)
    plt.plot(LOADconss, pgePrice, label='Utility energy payment', linewidth=3)
    plt.plot(LOADconss, localConsPrice, label='Local energy payment', linewidth=2)
    plt.plot(LOADconss, totalConsPrice, label='Utility and local producer payment', linewidth=10, alpha=0.3)
    plt.ylabel('Price $')
    plt.xlabel('Load demand if generation is set to 10kWh [kWh]')
    plt.legend(loc=0)
    plt.show()

In [30]:
param = {}

# Retailing price $/kW
param['pge_sell'] = 0.1
param['pge_buy'] = 0.07

# Upper/lower margin coef
param['upper_ratio'] = 1.66
param['lower_ratio'] = 1.00

# Maximum local electricity price
param['minimum_local_sell'] = 0.075

# Minimum local electricity prices
param['maximum_local_buy'] = 1.2 * param['pge_sell']

# bonus
param['ratio_end'] = 4
param['ratio_num'] = 500

market_design(param)


<matplotlib.figure.Figure at 0x1189ee350>