mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 12:15:44 +01:00
STOCKMARKET: Move and Reorganize Constants (#688)
This commit is contained in:
parent
e9bbe57902
commit
a85efbc4da
@ -31,11 +31,6 @@ export const CONSTANTS: {
|
||||
PurchasedServerMaxRam: number;
|
||||
MultipleAugMultiplier: number;
|
||||
TorRouterCost: number;
|
||||
WSEAccountCost: number;
|
||||
TIXAPICost: number;
|
||||
MarketData4SCost: number;
|
||||
MarketDataTixApi4SCost: number;
|
||||
StockMarketCommission: number;
|
||||
HospitalCostPerHp: number;
|
||||
IntelligenceCrimeWeight: number;
|
||||
IntelligenceInfiltrationWeight: number;
|
||||
@ -140,13 +135,6 @@ export const CONSTANTS: {
|
||||
// TOR Router
|
||||
TorRouterCost: 200e3,
|
||||
|
||||
// Stock market
|
||||
WSEAccountCost: 200e6,
|
||||
TIXAPICost: 5e9,
|
||||
MarketData4SCost: 1e9,
|
||||
MarketDataTixApi4SCost: 25e9,
|
||||
StockMarketCommission: 100e3,
|
||||
|
||||
// Hospital/Health
|
||||
HospitalCostPerHp: 100e3,
|
||||
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
|
||||
import { PositionType } from "@enums";
|
||||
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { StockMarketConstants } from "./data/Constants";
|
||||
import { Player } from "@player";
|
||||
|
||||
import { formatMoney, formatShares } from "../ui/formatNumber";
|
||||
@ -103,7 +103,7 @@ export function buyStock(
|
||||
|
||||
const origTotal = stock.playerShares * stock.playerAvgPx;
|
||||
Player.loseMoney(totalPrice, "stock");
|
||||
const newTotal = origTotal + totalPrice - CONSTANTS.StockMarketCommission;
|
||||
const newTotal = origTotal + totalPrice - StockMarketConstants.StockMarketCommission;
|
||||
stock.playerShares = Math.round(stock.playerShares + shares);
|
||||
stock.playerAvgPx = newTotal / stock.playerShares;
|
||||
processTransactionForecastMovement(stock, shares);
|
||||
@ -114,13 +114,13 @@ export function buyStock(
|
||||
if (ctx) {
|
||||
const resultTxt = `Bought ${formatShares(shares)} shares of ${stock.symbol} for ${formatMoney(
|
||||
totalPrice,
|
||||
)}. Paid ${formatMoney(CONSTANTS.StockMarketCommission)} in commission fees.`;
|
||||
)}. Paid ${formatMoney(StockMarketConstants.StockMarketCommission)} in commission fees.`;
|
||||
helpers.log(ctx, () => resultTxt);
|
||||
} else if (opts.suppressDialog !== true) {
|
||||
dialogBoxCreate(
|
||||
<>
|
||||
Bought {formatShares(shares)} shares of {stock.symbol} for <Money money={totalPrice} />. Paid{" "}
|
||||
<Money money={CONSTANTS.StockMarketCommission} /> in commission fees.
|
||||
<Money money={StockMarketConstants.StockMarketCommission} /> in commission fees.
|
||||
</>,
|
||||
);
|
||||
}
|
||||
@ -278,7 +278,7 @@ export function shortStock(
|
||||
|
||||
const origTotal = stock.playerShortShares * stock.playerAvgShortPx;
|
||||
Player.loseMoney(totalPrice, "stock");
|
||||
const newTotal = origTotal + totalPrice - CONSTANTS.StockMarketCommission;
|
||||
const newTotal = origTotal + totalPrice - StockMarketConstants.StockMarketCommission;
|
||||
stock.playerShortShares = Math.round(stock.playerShortShares + shares);
|
||||
stock.playerAvgShortPx = newTotal / stock.playerShortShares;
|
||||
processTransactionForecastMovement(stock, shares);
|
||||
@ -290,14 +290,14 @@ export function shortStock(
|
||||
if (ctx) {
|
||||
const resultTxt =
|
||||
`Bought a short position of ${formatShares(shares)} shares of ${stock.symbol} ` +
|
||||
`for ${formatMoney(totalPrice)}. Paid ${formatMoney(CONSTANTS.StockMarketCommission)} ` +
|
||||
`for ${formatMoney(totalPrice)}. Paid ${formatMoney(StockMarketConstants.StockMarketCommission)} ` +
|
||||
`in commission fees.`;
|
||||
helpers.log(ctx, () => resultTxt);
|
||||
} else if (!opts.suppressDialog) {
|
||||
dialogBoxCreate(
|
||||
<>
|
||||
Bought a short position of {formatShares(shares)} shares of {stock.symbol} for <Money money={totalPrice} />.
|
||||
Paid <Money money={CONSTANTS.StockMarketCommission} /> in commission fees.
|
||||
Paid <Money money={StockMarketConstants.StockMarketCommission} /> in commission fees.
|
||||
</>,
|
||||
);
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import type { IOrderBook } from "./IOrderBook";
|
||||
import type { IStockMarket } from "./IStockMarket";
|
||||
import { Order } from "./Order";
|
||||
import { StockMarketConstants } from "./data/Constants";
|
||||
import { processOrders } from "./OrderProcessing";
|
||||
import { Stock } from "./Stock";
|
||||
import { TicksPerCycle } from "./StockMarketConstants";
|
||||
import { InitStockMetadata } from "./data/InitStockMetadata";
|
||||
import { PositionType, OrderType, StockSymbol } from "@enums";
|
||||
|
||||
@ -165,7 +165,7 @@ export function initStockMarket(): void {
|
||||
|
||||
StockMarket.storedCycles = 0;
|
||||
StockMarket.lastUpdate = 0;
|
||||
StockMarket.ticksUntilCycle = TicksPerCycle;
|
||||
StockMarket.ticksUntilCycle = StockMarketConstants.TicksPerCycle;
|
||||
initSymbolToStockMap();
|
||||
}
|
||||
|
||||
@ -191,13 +191,11 @@ function stockMarketCycle(): void {
|
||||
stock.flipForecastForecast();
|
||||
}
|
||||
|
||||
StockMarket.ticksUntilCycle = TicksPerCycle;
|
||||
StockMarket.ticksUntilCycle = StockMarketConstants.TicksPerCycle;
|
||||
}
|
||||
}
|
||||
|
||||
// Stock prices updated every 6 seconds
|
||||
const msPerStockUpdate = 6e3;
|
||||
const cyclesPerStockUpdate = msPerStockUpdate / CONSTANTS.MilliPerCycle;
|
||||
const cyclesPerStockUpdate = StockMarketConstants.msPerStockUpdate / CONSTANTS.MilliPerCycle;
|
||||
export function processStockPrices(numCycles = 1): void {
|
||||
if (StockMarket.storedCycles == null || isNaN(StockMarket.storedCycles)) {
|
||||
StockMarket.storedCycles = 0;
|
||||
@ -211,14 +209,14 @@ export function processStockPrices(numCycles = 1): void {
|
||||
// We can process the update every 4 seconds as long as there are enough
|
||||
// stored cycles. This lets us account for offline time
|
||||
const timeNow = new Date().getTime();
|
||||
if (timeNow - StockMarket.lastUpdate < 4e3) return;
|
||||
if (timeNow - StockMarket.lastUpdate < StockMarketConstants.msPerStockUpdateMin) return;
|
||||
|
||||
StockMarket.lastUpdate = timeNow;
|
||||
StockMarket.storedCycles -= cyclesPerStockUpdate;
|
||||
|
||||
// Cycle
|
||||
if (StockMarket.ticksUntilCycle == null || typeof StockMarket.ticksUntilCycle !== "number") {
|
||||
StockMarket.ticksUntilCycle = TicksPerCycle;
|
||||
StockMarket.ticksUntilCycle = StockMarketConstants.TicksPerCycle;
|
||||
}
|
||||
--StockMarket.ticksUntilCycle;
|
||||
if (StockMarket.ticksUntilCycle <= 0) stockMarketCycle();
|
||||
|
@ -1,5 +0,0 @@
|
||||
/**
|
||||
* How many stock market 'ticks' before a 'cycle' is triggered.
|
||||
* A 'tick' is whenever stock prices update
|
||||
*/
|
||||
export const TicksPerCycle = 75;
|
@ -1,18 +1,18 @@
|
||||
import { currentNodeMults } from "../BitNode/BitNodeMultipliers";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { StockMarketConstants } from "./data/Constants";
|
||||
|
||||
export function getStockMarket4SDataCost(): number {
|
||||
return CONSTANTS.MarketData4SCost * currentNodeMults.FourSigmaMarketDataCost;
|
||||
return StockMarketConstants.MarketData4SCost * currentNodeMults.FourSigmaMarketDataCost;
|
||||
}
|
||||
|
||||
export function getStockMarket4STixApiCost(): number {
|
||||
return CONSTANTS.MarketDataTixApi4SCost * currentNodeMults.FourSigmaMarketDataApiCost;
|
||||
return StockMarketConstants.MarketDataTixApi4SCost * currentNodeMults.FourSigmaMarketDataApiCost;
|
||||
}
|
||||
|
||||
export function getStockMarketWseCost(): number {
|
||||
return CONSTANTS.WSEAccountCost;
|
||||
return StockMarketConstants.WSEAccountCost;
|
||||
}
|
||||
|
||||
export function getStockMarketTixApiCost(): number {
|
||||
return CONSTANTS.TIXAPICost;
|
||||
return StockMarketConstants.TIXAPICost;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Stock } from "./Stock";
|
||||
import { PositionType } from "@enums";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { StockMarketConstants } from "./data/Constants";
|
||||
|
||||
// Amount by which a stock's forecast changes during each price movement
|
||||
export const forecastChangePerPriceMovement = 0.006;
|
||||
@ -25,9 +25,9 @@ export function getBuyTransactionCost(stock: Stock, shares: number, posType: Pos
|
||||
|
||||
// If the number of shares doesn't trigger a price movement, its a simple calculation
|
||||
if (isLong) {
|
||||
return shares * stock.getAskPrice() + CONSTANTS.StockMarketCommission;
|
||||
return shares * stock.getAskPrice() + StockMarketConstants.StockMarketCommission;
|
||||
} else {
|
||||
return shares * stock.getBidPrice() + CONSTANTS.StockMarketCommission;
|
||||
return shares * stock.getBidPrice() + StockMarketConstants.StockMarketCommission;
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,11 +50,11 @@ export function getSellTransactionGain(stock: Stock, shares: number, posType: Po
|
||||
|
||||
const isLong = posType === PositionType.Long;
|
||||
if (isLong) {
|
||||
return shares * stock.getBidPrice() - CONSTANTS.StockMarketCommission;
|
||||
return shares * stock.getBidPrice() - StockMarketConstants.StockMarketCommission;
|
||||
} else {
|
||||
// Calculating gains for a short position requires calculating the profit made
|
||||
const origCost = shares * stock.playerAvgShortPx;
|
||||
const profit = (stock.playerAvgShortPx - stock.getAskPrice()) * shares - CONSTANTS.StockMarketCommission;
|
||||
const profit = (stock.playerAvgShortPx - stock.getAskPrice()) * shares - StockMarketConstants.StockMarketCommission;
|
||||
|
||||
return origCost + profit;
|
||||
}
|
||||
@ -124,7 +124,7 @@ export function calculateBuyMaxAmount(stock: Stock, posType: PositionType, money
|
||||
|
||||
const isLong = posType === PositionType.Long;
|
||||
|
||||
const remainingMoney = money - CONSTANTS.StockMarketCommission;
|
||||
const remainingMoney = money - StockMarketConstants.StockMarketCommission;
|
||||
const currPrice = isLong ? stock.getAskPrice() : stock.getBidPrice();
|
||||
|
||||
return Math.floor(remainingMoney / currPrice);
|
||||
|
15
src/StockMarket/data/Constants.ts
Normal file
15
src/StockMarket/data/Constants.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export const StockMarketConstants = {
|
||||
//stock tick times in milliseconds
|
||||
msPerStockUpdate: 6e3,
|
||||
msPerStockUpdateMin: 4e3,
|
||||
|
||||
//defines the length of the flip timer in stock cycles
|
||||
TicksPerCycle: 75,
|
||||
|
||||
// Stockmarket costs Constants
|
||||
WSEAccountCost: 200e6,
|
||||
TIXAPICost: 5e9,
|
||||
MarketData4SCost: 1e9,
|
||||
MarketDataTixApi4SCost: 25e9,
|
||||
StockMarketCommission: 100e3,
|
||||
};
|
@ -7,7 +7,7 @@ import React, { useState } from "react";
|
||||
|
||||
import { getStockMarket4SDataCost, getStockMarket4STixApiCost } from "../StockMarketCosts";
|
||||
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { StockMarketConstants } from "../data/Constants";
|
||||
import { Player } from "@player";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { initStockMarket } from "../StockMarket";
|
||||
@ -83,16 +83,16 @@ function PurchaseWseAccountButton(props: IProps): React.ReactElement {
|
||||
if (Player.hasWseAccount) {
|
||||
return;
|
||||
}
|
||||
if (!Player.canAfford(CONSTANTS.WSEAccountCost)) {
|
||||
if (!Player.canAfford(StockMarketConstants.WSEAccountCost)) {
|
||||
return;
|
||||
}
|
||||
Player.hasWseAccount = true;
|
||||
initStockMarket();
|
||||
Player.loseMoney(CONSTANTS.WSEAccountCost, "stock");
|
||||
Player.loseMoney(StockMarketConstants.WSEAccountCost, "stock");
|
||||
props.rerender();
|
||||
}
|
||||
|
||||
const cost = CONSTANTS.WSEAccountCost;
|
||||
const cost = StockMarketConstants.WSEAccountCost;
|
||||
return (
|
||||
<>
|
||||
<Typography>To begin trading, you must first purchase an account:</Typography>
|
||||
@ -109,11 +109,11 @@ function PurchaseTixApiAccessButton(props: IProps): React.ReactElement {
|
||||
if (Player.hasTixApiAccess) {
|
||||
return;
|
||||
}
|
||||
if (!Player.canAfford(CONSTANTS.TIXAPICost)) {
|
||||
if (!Player.canAfford(StockMarketConstants.TIXAPICost)) {
|
||||
return;
|
||||
}
|
||||
Player.hasTixApiAccess = true;
|
||||
Player.loseMoney(CONSTANTS.TIXAPICost, "stock");
|
||||
Player.loseMoney(StockMarketConstants.TIXAPICost, "stock");
|
||||
props.rerender();
|
||||
}
|
||||
|
||||
@ -124,7 +124,7 @@ function PurchaseTixApiAccessButton(props: IProps): React.ReactElement {
|
||||
</Typography>
|
||||
);
|
||||
} else {
|
||||
const cost = CONSTANTS.TIXAPICost;
|
||||
const cost = StockMarketConstants.TIXAPICost;
|
||||
return (
|
||||
<Button disabled={!Player.canAfford(cost) || !Player.hasWseAccount} onClick={purchaseTixApiAccess}>
|
||||
Buy Trade Information eXchange (TIX) API Access -
|
||||
@ -203,7 +203,7 @@ export function InfoAndPurchases(props: IProps): React.ReactElement {
|
||||
<Purchase4SMarketDataButton {...props} />
|
||||
<Typography>
|
||||
Commission Fees: Every transaction you make has a{" "}
|
||||
<Money money={CONSTANTS.StockMarketCommission} forPurchase={true} /> commission fee.
|
||||
<Money money={StockMarketConstants.StockMarketCommission} forPurchase={true} /> commission fee.
|
||||
</Typography>
|
||||
<br />
|
||||
<Typography>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { CONSTANTS } from "../../src/Constants";
|
||||
import { StockMarketConstants } from "../../src/StockMarket/data/Constants";
|
||||
import { Player } from "../../src/Player";
|
||||
|
||||
import { Company } from "../../src/Company/Company";
|
||||
@ -42,7 +42,7 @@ jest.mock(`!!raw-loader!../NetscriptDefinitions.d.ts`, () => "", {
|
||||
// }));
|
||||
|
||||
describe("Stock Market Tests", function () {
|
||||
const commission = CONSTANTS.StockMarketCommission;
|
||||
const commission = StockMarketConstants.StockMarketCommission;
|
||||
|
||||
// Generic Stock object that can be used by each test
|
||||
let stock: Stock;
|
||||
|
Loading…
Reference in New Issue
Block a user