Workflow Overview

This workflow develops more complex Dynamic Competition around a Commodity Market between two Competitors selling identical Products. The last Building Blocks workflow BB-112 Commodity Dynamic Pricing simulated two rounds of dynamic competition. This workflow introduces a Recursive Loop that allows for an unlimited number of rounds of dynamic Competition. As before, each Competitor sets a Profit Maximizing Price assuming the other Competitor maintains their most recent Price. After many such rounds the Prices in the Market iterate closer to Marginal Costs. At that point, neither Competitor would be profitable. These results should be compared to the Building Blocks workflow BB-131 Orthogonal Competitive Loop where the Products are not a commodity. In that case, the Price War leads to a much better outcome with both Competitors coming to rest at profitable Prices.

This Building Blocks example assumes you have already downloaded the open-source KNIME analytics platform and installed the free Market Simulation (Community Edition) plugin. If not, start by returning to Getting Started.

Dynamic Commodity Market

This Commodity Market comprises of two Competitor each selling the exact same Product. Dynamic competition occurs over many rounds of competitive action-and-reaction. Here, both Competitors simultaneously try to set their Profit Maximizing Price. Neither expects the other Competitor to be doing the same. This competitive dynamic is repeated many times in a Recursive Loop.

Product Generator

As before, the ‘Product Generator’ node creates two identical Products by aggregating the list of Product Features and the set of Feature Customer Distributions for each.

Product Array

The two Competitive Products (Spacely Sprockets and Cogswell Cogs), along with their WTP Customer Distributions, are completely defined by the ‘Product Generator’ node.

Loop Start

The ‘Recursive Loop Start’ node returns the Competitors Prices from the last round of competition and re-injects them into the next round of competition.


The ‘Recursive Loop Start’ node does not need to be configured. The companion ‘Recursive Loop End’ node contains all of the configuration details.


The input to the ‘Recursive Loop Start’ node are the original Prices from the Product Generator.


The output from the ‘Recursive Loop Start’ node are the Competitors Prices from the end of the last round of competition.


At the beginning of each round, each Competitor again sets their expected Profit Maximizing Price.

Set Price

Price setting is based upon the assumption that the other Competitor maintains their Price from the previous round.

Demand Curve

Prices are adjusted downwards very slowly as the Demand Curve shows that each Competitor is already very close to their Profit Maximizing Price (a tiny Price discount will reach it).

Expected Results

In the final round, Spacely Sprockets calculates that a discount of less than $2 will get them to their Profit Maximizing Price.

New Market

The Market is re-created after both Competitors set their new Profit Maximizing Prices.

New Prices

In the final round, both Spacely Sprockets and Cogswell Cogs Price their Products at $84.66.

Loop End

The ‘Recursive Loop End’ node collects the results and passes the new Prices and Market conditions back to the ‘Recursive Loop Start’ node.


This Dynamic Competition has been configured to loop for 10 iterations (from Iteration 0 to Iteration 9).

Loop Results

At each loop iteration, the Product Prices drop from $150 to $105 to $102.25 all the way down to $84.66. The expected Quantity, Revenue, and Profit are all calculated.

Final Results

After the loop has finished, the final Prices are collected to calculate the final results.


The final Prices need to be sorted to the top of the loop iteration results.


The last Prices from each Competitor are then collected with a ‘Row Filter’ node.


Line Charts

The trends from the Recursive Loop can then be plotted using the ‘Line Chart’ node.

Price Trend

Prices are decreasing but at a slower and slower rate. It will take a large number of rounds of competition before Prices reach Marginal Cost.

Quantity Trend

At each iteration, the expected Quantity is increasing. But the last data point shows the actual Quantity after both Competitors set Price.

Profit Trend

Expected profitability declines after each iteration. The last data point shows the actual Profit after both Competitors set Price.

Bertrand Paradox

Joseph Bertrand (1852 - 1900)

Wikipedia: The Bertrand Paradox describes a situation in which two Competitors reach a Nash equilibrium where both charge a Price equal to Marginal Cost. The paradox is that each additional Competitor is supposed to cause Prices to convergence closer to Marginal Costs until eventually Perfect Competition is reached.

Suppose two Competitors sell a homogeneous commodity, each with the same cost, so that Customers choose the Product solely on the basis of Price. Demand is infinitely price-elastic because neither Competitor will set a higher Price than the other (doing so would yield the entire market to their rival). If they set the same Price, the Competitors will share the Profits.

However, if either Competitor were to lower its price, even a little, it would gain the whole market and substantially larger Profits. Since both Competitors know this, they will each try to undercut the other until the Product is selling at zero economic profit.


There are several reasons why the Bertrand Paradox is rarely seen in practice:

Capacity Constraints: Competitors often do not have enough Capacity to satisfy all demand from the entire Market. Hence Competitors seek to set Prices above Marginal Costs at the point which all of their Production Capacity is sold. See Also: MS-172 Bertrand–Edgeworth Competition which explores a Price War between Commodity Products where both Competitors have Capacity Constraints.

Search Costs: Consumers suffer Search Costs to find the full range of their options. But when Consumers are unwilling to bear these Search Costs, Price Dispersion can result such that there is variation in Prices across Competitors selling the same Product. See Also: MS-173 Bertrand Competition with Search Costs which explores another variation of Bertrand Competition. The Products in this Market are, again, undifferentiated Commodity Products, but there are Search Costs that limit Customer awareness of each Product.

Product Differentiation: If the Products are different then Customers may not switch to the Product with the lowest Price but will continue to buy those Products that yield the greatest Consumer Surplus. See Also: MS-174 Bertrand Competition with Product Differentiation which explores the limitations of Bertrand Competition when the Products are no longer Commodities but are Differentiated from one another. And See Also: BB-131 Orthogonal Competitive Loop which explores a Competitive Price War between differentiated Products.

Shipping Costs and Geographic Differentiation: If Customers have to pay different amounts for shipping or for acquiring the Product, then they will have a natural bias to buy the commodity Product that is more local to them – even if the local Product is a little more expensive. This bias will ensure that Prices never decline down as far as Marginal Cost and that Competitors can be Profitable. See Also: CS-102 Rise of the Microbrew – Part 02 Local Monopoly which shows how Geographic Differentiation can be a source of Market Power.