Water Pricing Model
The plant will set a base price of 10% of its daily profits to purchase its daily capacity. The price calculation logic is fixed for this version and depends on several factors:
- Urgency
- Trend
- Competition
- Demand Pressure
- Weighted Supply
Here is the code that will be used to set the price of H2O tokens. This code is completely generated by an AI model (Claude 3.7 sonnet) and the same model can be used to interpret the meaning of each of the factors involved in the pricing model.
// WaterPricingModel.ts
interface WaterSource {
name: string
quantity: number
distance: number
}
interface WaterPricingInput {
dailyRequirement: number
currentReserve: number
referencePrice?: number
maxDistance?: number
historicalInflow: number[]
sources: WaterSource[]
}
interface WaterPricingOutput {
fairPrice: number
urgencyFactor: number
trendFactor: number
competitionFactor: number
demandPressure: number
weightedSupply: number
}
class WaterPricingModel {
private dailyRequirement: number
private currentReserve: number
private referencePrice: number
private maxDistance: number
constructor(
dailyRequirement: number,
currentReserve: number,
referencePrice: number = 1.0,
maxDistance: number = 50
) {
this.dailyRequirement = dailyRequirement
this.currentReserve = currentReserve
this.referencePrice = referencePrice
this.maxDistance = maxDistance
}
// Calculate urgency factor based on current reserve level
private calculateUrgencyFactor(): number {
const R = this.currentReserve
if (R > 9) return 1.0
else if (R >= 3 && R <= 9) return 1.0 + (9 - R) / 6
else if (R > 1 && R < 3) return 2.0 + (3 - R) / 2
else return 3.0 + (1 - R) / 1
}
// Calculate trend factor based on 7-day historical inflow data
private calculateTrendFactor(historicalInflow: number[]): number {
if (historicalInflow.length !== 7) {
throw new Error('Historical inflow data must contain exactly 7 days')
}
const avgInflow = historicalInflow.reduce((sum, val) => sum + val, 0) / 7
return avgInflow > 0 ? this.dailyRequirement / avgInflow : 2.0
}
// Calculate source competition factor based on available sources
private calculateSourceCompetition(
sources: { quantity: number; distance: number }[],
daysToConsider: number = 7
): number {
const totalAvailable = sources.reduce(
(acc, source) =>
acc +
source.quantity * this.calculateDeliveryProbability(source.distance),
0
)
const futureNeed =
this.dailyRequirement * (this.currentReserve + daysToConsider)
return futureNeed > 0 ? totalAvailable / futureNeed : 0.1
}
// Calculate delivery probability based on distance using logistic decay
private calculateDeliveryProbability(distance: number): number {
return 1 / (1 + Math.exp(5 * (distance / this.maxDistance - 0.5)))
}
// Public method to calculate fair water price from a single input object
public static calculate(input: WaterPricingInput): WaterPricingOutput {
const model = new WaterPricingModel(
input.dailyRequirement,
input.currentReserve,
input.referencePrice ?? 1.0,
input.maxDistance ?? 50
)
const urgency = model.calculateUrgencyFactor()
const trend = model.calculateTrendFactor(input.historicalInflow)
const competition = model.calculateSourceCompetition(input.sources)
const weightedSupply = input.sources.reduce(
(acc, source) =>
acc +
source.quantity * model.calculateDeliveryProbability(source.distance),
0
)
const avgInflow =
input.historicalInflow.reduce((a, b) => a + b, 0) /
input.historicalInflow.length
const projectedDeficit = model.dailyRequirement - avgInflow
const demandPressure = Math.max(
0.5,
Math.min(2.0, 1.0 + projectedDeficit / model.dailyRequirement)
)
const fairPrice =
model.referencePrice *
urgency *
trend *
(1 / competition) *
demandPressure
return {
fairPrice,
urgencyFactor: urgency,
trendFactor: trend,
competitionFactor: 1 / competition,
demandPressure,
weightedSupply,
}
}
}
// Example usage
const input: WaterPricingInput = {
dailyRequirement: 100,
currentReserve: 5,
referencePrice: 10,
maxDistance: 50,
historicalInflow: [100, 100, 100, 100, 100, 100, 100],
sources: [
{ name: 'Local Well', quantity: 300, distance: 5 },
{ name: 'Community Reservoir', quantity: 1000, distance: 15 },
{ name: 'Municipal Supply', quantity: 5000, distance: 40 },
{ name: 'Private Vendor', quantity: 200, distance: 8 },
],
}
const result = WaterPricingModel.calculate(input)
console.log('\nSingle Fair Price Calculation:')
console.log(
`Fair Price to Offer: ${result.fairPrice.toFixed(2)} currency units`
)
console.log(`Urgency Factor: ${result.urgencyFactor.toFixed(2)}`)
console.log(`Trend Factor: ${result.trendFactor.toFixed(2)}`)
console.log(`Competition Factor: ${result.competitionFactor.toFixed(2)}`)
console.log(`Demand Pressure: ${result.demandPressure.toFixed(2)}`)
console.log(`Weighted Supply: ${result.weightedSupply.toFixed(2)} units`)
console.log('\nDelivery Probabilities:')
input.sources.forEach((source) => {
const prob =
1 / (1 + Math.exp(5 * (source.distance / (input.maxDistance ?? 50) - 0.5)))
console.log(
`${source.name} (distance ${source.distance}): ${(prob * 100).toFixed(
2
)}% probability`
)
})