mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 06:18:42 +02:00
DOCUMENTATION: Clarify Market-TA1, Market-TA2, MaxSalesVolume (#2014)
This commit is contained in:
@@ -185,7 +185,7 @@ They are not too important. It's fine to spend 1% of your current funds for them
|
||||
|
||||
#### Should I buy Market-TA1?
|
||||
|
||||
No, wait for Market-TA2. Market-TA1 is useless on its own.
|
||||
No, wait for Market-TA2. Market-TA1 is useless in most cases.
|
||||
|
||||
#### When should I buy Market-TA2?
|
||||
|
||||
@@ -193,8 +193,13 @@ As soon as possible, it greatly increases your profit because it can find the op
|
||||
|
||||
#### What is the difference between Market-TA1 and Market-TA2?
|
||||
|
||||
Market-TA1: set a price that ensures that you can sell all produced goods in storage.
|
||||
Market-TA2: set the highest possible price that ensures that you can sell all produced goods in storage.
|
||||
If you set the price of the material/product too much higher than the market price, you will get a penalty modifier that makes the material/product not be able to be sold as much as it should be.
|
||||
|
||||
Market-TA1 sets a price higher than the market price while ensuring that you don't get the penalty modifier.
|
||||
|
||||
Market-TA2 assumes that you can sell all stored units without any problems and can accept a penalty modifier. If that's the case, it finds the highest possible price.
|
||||
|
||||
With products, the price set by Market-TA2 is usually several orders of magnitude higher than Market-TA1.
|
||||
|
||||
#### I bought Market-TA2, but it does not set the optimal price for me.
|
||||
|
||||
@@ -204,6 +209,14 @@ You have to enable it.
|
||||
|
||||
Yes, you can reimplement Market-TA2. Implementing a custom Market-TA2 script is the best optimization in round 3+. Check this [section](./optimal-selling-price-market-ta2.md) to see how to do it.
|
||||
|
||||
### Why can I not sell all produced goods in the storage even after using Market-TA1 and Market-TA2?
|
||||
|
||||
In the SALE state, the game calculates `MaxSalesVolume` of the material/product. This is the number of items that can be sold in this state. This value is the product of many multipliers, and one of those multipliers is the markup multiplier. When it's higher than 1, it's a bonus multiplier helping you sell more items. When it's lower than 1, it's a penalty modifier making you sell fewer items.
|
||||
|
||||
With Market TA1 and Market TA2, the markup multiplier is always less than or equal to 1. In other words, they never help you sell more items than you can. Their job is to help you find a good price that is higher than the market price. If you want to sell more items than you can, you need to set the price below the market price. This is not the job of Market TA1 and Market TA2.
|
||||
|
||||
Check this [section](./optimal-selling-price-market-ta2.md) for more information and tips on how to increase `MaxSalesVolume`.
|
||||
|
||||
#### How do I discard materials/products?
|
||||
|
||||
Set the selling price to 0.
|
||||
|
||||
@@ -11,7 +11,8 @@ Market price:
|
||||
|
||||
$$ProductMarketPrice = ProductMarketPriceMult\ast\sum_{i = 1}^{n}{MaterialMarketPrice_i\ast MaterialCoefficient_i}$$
|
||||
|
||||
Markup limit:
|
||||
Markup limit: This is how high you can raise the price above the market price before the sales volume is affected negatively.
|
||||
For example: Let's say a product has MarketPrice = 5000 and MarkupLimit = 700. If you set the price smaller than or equal to 5700, the sales volume of this product will not be penalized.
|
||||
|
||||
- Material:
|
||||
|
||||
@@ -21,21 +22,31 @@ $$MaterialMarkupLimit = \frac{MaterialQuality}{MaterialMarkup}$$
|
||||
|
||||
$$ProductMarkupLimit = \frac{Max(ProductEffectiveRating,0.001)}{ProductMarkup}$$
|
||||
|
||||
## Maximize sales volume
|
||||
## Sales volume
|
||||
|
||||
Define:
|
||||
`MaxSalesVolume` is the maximum number of items that you can sell in the SALE state.
|
||||
|
||||
$$ExpectedSalesVolume = \frac{ProducedUnits}{10}$$
|
||||
`PotentialSalesVolume` is the sales volume in theory.
|
||||
|
||||
- This means we want to sell all produced units.
|
||||
`MarkupMultiplier` is defined by a piecewise function depending on selling price, market price, and markup limit.
|
||||
|
||||
In cycle's SALE state, game calculates `MaxSalesVolume` of material/product. If we set price too high, `MaxSalesVolume` is penalized. In order to maximize profit, we have to set the highest possible price while `MaxSalesVolume` is still equal to `ExpectedSalesVolume`. This is what Market-TA2 does.
|
||||
$$MaxSalesVolume = PotentialSalesVolume\ast MarkupMultiplier$$
|
||||
|
||||
Calculation of material and product is pretty similar, so I'll call them "item" and use 1 formula.
|
||||
### Potential sales volume
|
||||
|
||||
`MaxSalesVolume` is the product of 7 multipliers:
|
||||
`PotentialSalesVolume` depends on:
|
||||
|
||||
- Item multiplier:
|
||||
- The quality of materials and the effective rating of products.
|
||||
- Number of Business employees.
|
||||
- Advert.
|
||||
- Demand and Competition.
|
||||
- ABC SalesBots.
|
||||
|
||||
It is the product of 6 multipliers:
|
||||
|
||||
$$PotentialSalesVolume = \ ItemMultiplier\ast BusinessFactor\ast AdvertFactor\ast MarketFactor\ast SaleBotsBonus\ast ResearchBonus$$
|
||||
|
||||
- Quality/EffectiveRating multiplier:
|
||||
- Material:
|
||||
$$ItemMultiplier = MaterialQuality + 0.001$$
|
||||
- Product:
|
||||
@@ -61,49 +72,70 @@ $$MarketFactor = Max\left(0.1,{Demand\ast(100 - Competition)}\ast{0.01}\right)$$
|
||||
|
||||
- Corporation's upgrade bonus: `SalesBots` bonus.
|
||||
- Division's research bonus: this is always 1. Currently there is not any research that increases the sales bonus.
|
||||
- `MarkupMultiplier`: initialize with 1.
|
||||
- `SellingPrice` is the selling price that you set.
|
||||
- If we set `SellingPrice` to 0 or a negative number, `MarkupMultiplier` is $10^{12}$ (check the formula below). With an extremely high `MarkupMultiplier`, we can sell all units, regardless of other factors. This is the fastest way to discard stored units.
|
||||
- If `(SellingPrice > MarketPrice)`:
|
||||
- If `(SellingPrice > MarketPrice + MarkupLimit)`:
|
||||
$$MarkupMultiplier = \left(\frac{MarkupLimit}{SellingPrice - MarketPrice}\right)^{2}$$
|
||||
- If `(SellingPrice <= MarketPrice)`:
|
||||
|
||||
$$MarkupMultiplier = \begin{cases}\frac{MarketPrice}{SellingPrice}, & SellingPrice > 0 \newline 10^{12}, & SellingPrice \leq 0 \end{cases}$$
|
||||
### Markup multiplier
|
||||
|
||||
$$MarkupMultiplier = \begin{cases}10^{12} & SellingPrice \in (-\infty, 0] \newline \frac{MarketPrice}{SellingPrice} & SellingPrice \in (0, MarketPrice] \newline 1 & SellingPrice \in (MarketPrice, MarketPrice + MarkupLimit] \newline \left(\frac{MarkupLimit}{SellingPrice - MarketPrice}\right)^{2} & SellingPrice \in (MarketPrice + MarkupLimit, \infty) \end{cases}$$
|
||||
|
||||
Analysis for 4 ranges, in the same order of the above formula:
|
||||
|
||||
- Range 1: We can set `SellingPrice` to 0 and get an extremely high `MarkupMultiplier`. With this high value, we can sell all units, regardless of other factors. This is the fastest way to discard stored units.
|
||||
- Range 2: `MarkupMultiplier` is a "bonus multiplier". It boosts `PotentialSalesVolume`. This means you can boost the sales volume by setting `SellingPrice` below `MarketPrice`.
|
||||
- Range 3: `MaxSalesVolume` = `PotentialSalesVolume` (No bonus, no penalty). Market TA1 always set `SellingPrice` to `MarketPrice + MarkupLimit`. This means you can sell things at a price higher than the market price while ensuring the sales volume is not affected negatively.
|
||||
- Range 4: `MarkupMultiplier` is a penalty modifier. More about this case later.
|
||||
|
||||
### Maximize sales volume
|
||||
|
||||
In order to increase `MaxSalesVolume`, you can:
|
||||
|
||||
- Improve the quality of materials and the effective rating of products.
|
||||
- Use more Business employees.
|
||||
- Increase the level of Advert.
|
||||
- Increase the level of ABC SalesBots.
|
||||
- Set the price lower than the market price. Note that you should NOT do this in most cases. If you need to do this, it's very likely that your strategy is flawed, and you need to fix it.
|
||||
|
||||
## Optimal selling price
|
||||
|
||||
As we can see with previous part, `MarkupMultiplier` is basically a penalty modifier if we set `SellingPrice` greater than `(MarketPrice + MarkupLimit)`, and we'll always do this. This means we need to find out highest possible `SellingPrice` while `MaxSalesVolume` is still equal to `ExpectedSalesVolume`.
|
||||
Let's say that we want to sell all stored units. Define:
|
||||
|
||||
This is the reason why we should not bother with Market-TA1. It simply sets `SellingPrice = MarketPrice + MarkupLimit`. This means Market-TA1 sets a "safe" `SellingPrice` for us, it guarantees that we won't be penalized due to too high price. However, this "safe" `SellingPrice` is too low, and we can find a much higher `SellingPrice`.
|
||||
$$ExpectedSalesVolume = \frac{StoredUnits}{10}$$
|
||||
|
||||
Formula:
|
||||
|
||||
- Define:
|
||||
|
||||
$$M = \ ItemMultiplier\ast BusinessFactor\ast AdvertFactor\ast MarketFactor\ast SaleBotsBonus\ast ResearchBonus$$
|
||||
|
||||
- We want `MaxSalesVolume` to equal `ExpectedSalesVolume`:
|
||||
Assume that we can sell all stored units.
|
||||
|
||||
$$MaxSalesVolume = ExpectedSalesVolume$$
|
||||
|
||||
≡
|
||||
|
||||
$$M\ast\left(\frac{MarkupLimit}{SellingPrice - MarketPrice}\right)^{2} = ExpectedSalesVolume$$
|
||||
$$PotentialSalesVolume\ast MarkupMultiplier = ExpectedSalesVolume$$
|
||||
|
||||
≡
|
||||
|
||||
$$\frac{MarkupLimit}{SellingPrice - MarketPrice} = \sqrt{\frac{ExpectedSalesVolume}{M}}$$
|
||||
$$PotentialSalesVolume\ast\left(\frac{MarkupLimit}{SellingPrice - MarketPrice}\right)^{2} = ExpectedSalesVolume$$
|
||||
|
||||
≡
|
||||
|
||||
$$SellingPrice = \frac{MarkupLimit\ast\sqrt{M}}{\sqrt{ExpectedSalesVolume}} + MarketPrice$$
|
||||
$$\frac{MarkupLimit}{SellingPrice - MarketPrice} = \sqrt{\frac{ExpectedSalesVolume}{PotentialSalesVolume}}$$
|
||||
|
||||
In order to use this formula, we need `MarkupLimit`. With product, we need `ProductMarkup` to calculate `MarkupLimit`, but `ProductMarkup` is inaccessible via NS API. We have two solutions:
|
||||
≡
|
||||
|
||||
- Calculate approximation value. Check previous section to see how to do this.
|
||||
$$SellingPrice = \frac{MarkupLimit\ast\sqrt{PotentialSalesVolume}}{\sqrt{ExpectedSalesVolume}} + MarketPrice$$
|
||||
|
||||
There are 2 cases:
|
||||
|
||||
- When `PotentialSalesVolume` > `ExpectedSalesVolume`, we can accept a penalty modifier (`MarkupMultiplier` < 1) and raise the price above `MarketPrice + MarkupLimit`.
|
||||
- When `PotentialSalesVolume` <= `ExpectedSalesVolume`: `MarketPrice` <= `SellingPrice` <= `MarketPrice + MarkupLimit`.
|
||||
- The selling price is still higher than the market price.
|
||||
- There is no penalty modifier. In this case, we already cannot sell all items, so having no penalty modifier means that the situation is at least not worse.
|
||||
|
||||
This is what Market-TA2 does. It assumes that we can sell all stored units without any problems (`PotentialSalesVolume` > `ExpectedSalesVolume`) and can accept a penalty modifier. If that's the case, it assumes `MaxSalesVolume = ExpectedSalesVolume`, "exploits" the range 4 in the previous part, and finds the highest possible price. Otherwise, the price is in range 3, and `MaxSalesVolume` is not affected negatively.
|
||||
|
||||
This is also the reason why we should not bother with Market-TA1. It simply sets `SellingPrice = MarketPrice + MarkupLimit`. This means Market-TA1 only sets a "safe" `SellingPrice` for us and guarantees that we are not penalized due to setting the price too high. However, in most cases (high-quality materials, good products, high Advert, etc.), `PotentialSalesVolume` is much higher than `ExpectedSalesVolume`. In this case, the "safe" `SellingPrice` from Market-TA1 is too low, and we can find a much higher `SellingPrice` with Market-TA2.
|
||||
|
||||
In order to use the formula of Market-TA2, we need `MarkupLimit`. With products, we need `ProductMarkup` to calculate `MarkupLimit`, but `ProductMarkup` is inaccessible via NS API. We have two solutions:
|
||||
|
||||
- Calculate the approximation value. Check the previous section to see how to do this.
|
||||
- Calculate `MarkupLimit` directly:
|
||||
- Set `SellingPrice` to a very high value, it must be so high that we cannot sell all produced units (`MaxSalesVolume < ExpectedSalesVolume`). This forces the game applies the penalty modifier that contains `MarkupLimit`.
|
||||
- Set `SellingPrice` to a very high value. It must be so high that we cannot sell all produced units (`MaxSalesVolume < ExpectedSalesVolume`). This forces the game to apply the penalty modifier that contains `MarkupLimit`.
|
||||
- Wait for 1 cycle to get `ActualSalesVolume`. It's `product.actualSellAmount` and `material.actualSellAmount`.
|
||||
- Use `ActualSalesVolume` in place of `ExpectedSalesVolume` in previous formula: $MarkupLimit = (SellingPrice - MarketPrice)\ast\sqrt{\frac{ActualSalesVolume}{M}}$
|
||||
- Use `ActualSalesVolume` in place of `ExpectedSalesVolume` in the previous formula: $MarkupLimit = (SellingPrice - MarketPrice)\ast\sqrt{\frac{ActualSalesVolume}{M}}$
|
||||
- Calculate `ProductMarkup` from `MarkupLimit`, save `ProductMarkup` to reuse later. `ProductMarkup` never changes.
|
||||
|
||||
Reference in New Issue
Block a user