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)