mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-22 15:43:49 +01:00
Fixed Stock Market UI. Added documentation for stock market changes
This commit is contained in:
parent
3a601a015d
commit
dd9df0a18c
@ -7,10 +7,14 @@ buy and sell stocks in order to make money.
|
|||||||
|
|
||||||
The WSE can be found in the 'City' tab, and is accessible in every city.
|
The WSE can be found in the 'City' tab, and is accessible in every city.
|
||||||
|
|
||||||
Automating the Stock Market
|
Fundamentals
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
------------
|
||||||
You can write scripts to perform automatic and algorithmic trading on the Stock Market.
|
The Stock Market is not as simple as "buy at price X and sell at price Y". The following
|
||||||
See :ref:`netscript_tixapi` for more details.
|
are several fundamental concepts you need to understand about the stock market.
|
||||||
|
|
||||||
|
.. note:: For those that have experience with finance/trading/investing, please be aware
|
||||||
|
that the game's stock market does not function exactly like it does in the real
|
||||||
|
world. So these concepts below should seem similar, but won't be exactly the same.
|
||||||
|
|
||||||
Positions: Long vs Short
|
Positions: Long vs Short
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -21,16 +25,61 @@ is the exact opposite. In a Short position you purchase shares of a stock and
|
|||||||
earn a profit if the price of that stock decreases. This is also called 'shorting'
|
earn a profit if the price of that stock decreases. This is also called 'shorting'
|
||||||
a stock.
|
a stock.
|
||||||
|
|
||||||
NOTE: Shorting stocks is not available immediately, and must be unlocked later in the
|
.. note:: Shorting stocks is not available immediately, and must be unlocked later in the
|
||||||
game.
|
game.
|
||||||
|
|
||||||
|
.. _gameplay_stock_market_spread:
|
||||||
|
|
||||||
|
Spread (Bid Price & Ask Price)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
The **bid price** is the maximum price at which someone will buy a stock on the
|
||||||
|
stock market.
|
||||||
|
|
||||||
|
The **ask price** is the minimum price that a seller is willing to receive for a stock
|
||||||
|
on the stock market
|
||||||
|
|
||||||
|
The ask price will always be higher than the bid price (This is because if a seller
|
||||||
|
is willing to receive less than the bid price, that transaction is guaranteed to
|
||||||
|
happen). The difference between the bid and ask price is known as the **spread**.
|
||||||
|
A stock's "price" will be the average of the bid and ask price.
|
||||||
|
|
||||||
|
The bid and ask price are important because these are the prices at which a
|
||||||
|
transaction actually occurs. If you purchase a stock in the long position, the cost
|
||||||
|
of your purchase depends on that stock's ask price. If you then try to sell that
|
||||||
|
stock (still in the long position), the price at which you sell is the stock's
|
||||||
|
bid price. Note that this is reversed for a short position. Purchasing a stock
|
||||||
|
in the short position will occur at the stock's bid price, and selling a stock
|
||||||
|
in the short position will occur at the stock's ask price.
|
||||||
|
|
||||||
|
.. _gameplay_stock_spread_price_movement:
|
||||||
|
|
||||||
|
Transactions Influencing Stock Price
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Buying or selling a large number of shares of a stock will influence that stock's price.
|
||||||
|
|
||||||
|
Buying a stock in the long position will cause that stock's price to
|
||||||
|
increase. Selling a stock in the long position will cause the stock's price to decrease.
|
||||||
|
The reverse occurs for the short position. The effect of this depends on how many shares
|
||||||
|
are being transacted. More shares will have a bigger effect on the stock price. If
|
||||||
|
only a small number of shares are being transacted, the stock price may not be affected.
|
||||||
|
|
||||||
|
Note that this "influencing" of the stock price **can happen in the middle of a transaction**.
|
||||||
|
For example, assume you are selling 1m shares of a stock. That stock's bid price
|
||||||
|
is currently $100. However, selling 100k shares of the stock causes its price to drop
|
||||||
|
by 1%. This means that for your transaction of 1m shares, the first 100k shares will be
|
||||||
|
sold at $100. Then the next 100k shares will be sold at $99. Then the next 100k shares will
|
||||||
|
be sold at $98.01, and so on.
|
||||||
|
|
||||||
|
This is an important concept to keep in mind if you are trying to purchase/sell a
|
||||||
|
large number of shares, as **it can negatively affect your profits**.
|
||||||
|
|
||||||
Order Types
|
Order Types
|
||||||
^^^^^^^^^^^
|
^^^^^^^^^^^
|
||||||
There are three different types of orders you can make to buy or sell stocks on the exchange:
|
There are three different types of orders you can make to buy or sell stocks on the exchange:
|
||||||
Market Order, Limit Order, and Stop Order.
|
Market Order, Limit Order, and Stop Order.
|
||||||
|
|
||||||
Note that Limit Orders and Stop Orders are not available immediately, and must be unlocked
|
.. note:: Limit Orders and Stop Orders are not available immediately, and must be unlocked
|
||||||
later in the game.
|
later in the game.
|
||||||
|
|
||||||
When you place a Market Order to buy or sell a stock, the order executes immediately at
|
When you place a Market Order to buy or sell a stock, the order executes immediately at
|
||||||
whatever the current price of the stock is. For example if you choose to short a stock
|
whatever the current price of the stock is. For example if you choose to short a stock
|
||||||
@ -71,3 +120,8 @@ A Limit Order to sell will execute if the stock's price <= order's price
|
|||||||
A Stop Order to buy will execute if the stock's price <= order's price
|
A Stop Order to buy will execute if the stock's price <= order's price
|
||||||
|
|
||||||
A Stop Order to sell will execute if the stock's price >= order's price.
|
A Stop Order to sell will execute if the stock's price >= order's price.
|
||||||
|
|
||||||
|
Automating the Stock Market
|
||||||
|
---------------------------
|
||||||
|
You can write scripts to perform automatic and algorithmic trading on the Stock Market.
|
||||||
|
See :ref:`netscript_tixapi` for more details.
|
||||||
|
@ -15,11 +15,15 @@ access even after you 'reset' by installing Augmentations
|
|||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:caption: API Functions:
|
:caption: API Functions:
|
||||||
|
|
||||||
getStockSymbols() <tixapi/getStockSymbols>
|
getStockSymbols() <tixapi/getStockSymbols>
|
||||||
getStockPrice() <tixapi/getStockPrice>
|
getStockPrice() <tixapi/getStockPrice>
|
||||||
|
getStockAskPrice() <tixapi/getStockAskPrice>
|
||||||
|
getStockBidPrice() <tixapi/getStockBidPrice>
|
||||||
getStockPosition() <tixapi/getStockPosition>
|
getStockPosition() <tixapi/getStockPosition>
|
||||||
getStockMaxShares() <tixapi/getStockMaxShares>
|
getStockMaxShares() <tixapi/getStockMaxShares>
|
||||||
|
getStockPurchaseCost() <tixapi/getStockPurchaseCost>
|
||||||
|
getStockSaleGain() <tixapi/getStockSaleGain>
|
||||||
buyStock() <tixapi/buyStock>
|
buyStock() <tixapi/buyStock>
|
||||||
sellStock() <tixapi/sellStock>
|
sellStock() <tixapi/sellStock>
|
||||||
shortStock() <tixapi/shortStock>
|
shortStock() <tixapi/shortStock>
|
||||||
|
12
doc/source/netscript/tixapi/getStockAskPrice.rst
Normal file
12
doc/source/netscript/tixapi/getStockAskPrice.rst
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
getStockAskPrice() Netscript Function
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
.. js:function:: getStockAskPrice(sym)
|
||||||
|
|
||||||
|
:param string sym: Stock symbol
|
||||||
|
:RAM cost: 2 GB
|
||||||
|
|
||||||
|
Given a stock's symbol, returns the ask price of that stock (the symbol is a sequence
|
||||||
|
of two to four capital letters, **not** the name of the company to which that stock belongs).
|
||||||
|
|
||||||
|
See :ref:`gameplay_stock_market_spread` for details on what the ask price is.
|
12
doc/source/netscript/tixapi/getStockBidPrice.rst
Normal file
12
doc/source/netscript/tixapi/getStockBidPrice.rst
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
getStockBidPrice() Netscript Function
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
.. js:function:: getStockBidPrice(sym)
|
||||||
|
|
||||||
|
:param string sym: Stock symbol
|
||||||
|
:RAM cost: 2 GB
|
||||||
|
|
||||||
|
Given a stock's symbol, returns the bid price of that stock (the symbol is a sequence
|
||||||
|
of two to four capital letters, **not** the name of the company to which that stock belongs).
|
||||||
|
|
||||||
|
See :ref:`gameplay_stock_market_spread` for details on what the bid price is.
|
@ -6,9 +6,12 @@ getStockPrice() Netscript Function
|
|||||||
:param string sym: Stock symbol
|
:param string sym: Stock symbol
|
||||||
:RAM cost: 2 GB
|
:RAM cost: 2 GB
|
||||||
|
|
||||||
Returns the price of a stock, given its symbol (NOT the company name). The symbol is a sequence
|
Given a stock's symbol, returns the price of that stock (the symbol is a sequence
|
||||||
of two to four capital letters.
|
of two to four capital letters, **not** the name of the company to which that stock belongs).
|
||||||
|
|
||||||
|
.. note:: The stock's price is the average of its bid and ask price.
|
||||||
|
See :ref:`gameplay_stock_market_spread` for details on what this means.
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
getStockPrice("FISG");
|
getStockPrice("FSIG");
|
||||||
|
15
doc/source/netscript/tixapi/getStockPurchaseCost.rst
Normal file
15
doc/source/netscript/tixapi/getStockPurchaseCost.rst
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
getStockPurchaseCost() Netscript Function
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
.. js:function:: getStockPurchaseCost(sym, shares, posType)
|
||||||
|
|
||||||
|
:param string sym: Stock symbol
|
||||||
|
:param number shares: Number of shares to purchase
|
||||||
|
:param string posType: Specifies whether the order is a "Long" or "Short" position.
|
||||||
|
The values "L" or "S" can also be used.
|
||||||
|
:RAM cost: 2 GB
|
||||||
|
|
||||||
|
Calculates and returns how much it would cost to buy a given number of
|
||||||
|
shares of a stock. This takes into account :ref:`spread <gameplay_stock_market_spread>`,
|
||||||
|
:ref:`large transactions influencing the price of the stock <gameplay_stock_spread_price_movement>`
|
||||||
|
and commission fees.
|
15
doc/source/netscript/tixapi/getStockSaleGain.rst
Normal file
15
doc/source/netscript/tixapi/getStockSaleGain.rst
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
getStockSaleGain() Netscript Function
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
.. js:function:: getStockSaleGain(sym, shares, posType)
|
||||||
|
|
||||||
|
:param string sym: Stock symbol
|
||||||
|
:param number shares: Number of shares to purchase
|
||||||
|
:param string posType: Specifies whether the order is a "Long" or "Short" position.
|
||||||
|
The values "L" or "S" can also be used.
|
||||||
|
:RAM cost: 2 GB
|
||||||
|
|
||||||
|
Calculates and returns how much you would gain from selling a given number of
|
||||||
|
shares of a stock. This takes into account :ref:`spread <gameplay_stock_market_spread>`,
|
||||||
|
:ref:`large transactions influencing the price of the stock <gameplay_stock_spread_price_movement>`
|
||||||
|
and commission fees.
|
@ -275,35 +275,15 @@ export let CONSTANTS: IMap<any> = {
|
|||||||
|
|
||||||
LatestUpdate:
|
LatestUpdate:
|
||||||
`
|
`
|
||||||
v0.46.3
|
v0.47.0
|
||||||
* Added a new Augmentation: The Shadow's Simulacrum
|
* Stock Market changes:
|
||||||
* Improved tab autocompletion feature in Terminal so that it works better with directories
|
** Implemented spread. Stock's now have bid and ask prices at which transactions occur
|
||||||
* Bug Fix: Tech vendor location UI now properly refreshed when purchasing a TOR router
|
** Large transactions will now influence a stock's price.
|
||||||
* Bug Fix: Fixed UI issue with faction donations
|
** This "influencing" can take effect in the middle of a transaction
|
||||||
* Bug Fix: The money statistics & breakdown should now properly track money earned from Hacknet Server (hashes -> money)
|
** See documentation for more details on these changes
|
||||||
* Bug Fix: Fixed issue with changing input in 'Minimum Path Sum in a Triangle' coding contract problem
|
** Added getStockAskPrice(), getStockBidPrice() Netscript functions to the TIX API
|
||||||
* Fixed several typos in various places
|
** Added getStockPurchaseCost(), getStockSaleGain() Netscript functions to the TIX API
|
||||||
|
|
||||||
v0.46.2
|
|
||||||
* Source-File 2 now allows you to form gangs in other BitNodes when your karma reaches a very large negative value
|
|
||||||
** (Karma is a hidden stat and is lowered by committing crimes)
|
|
||||||
* Gang changes:
|
|
||||||
** Bug Fix: Gangs can no longer clash with themselve
|
|
||||||
** Bug Fix: Winning against another gang should properly reduce their power
|
|
||||||
|
|
||||||
* Bug Fix: Terminal 'wget' command now works properly
|
|
||||||
* Bug Fix: Hacknet Server Hash upgrades now properly reset upon installing Augs/switching BitNodes
|
|
||||||
* Bug Fix: Fixed button for creating Corporations
|
|
||||||
|
|
||||||
v0.46.1
|
|
||||||
* Added a very rudimentary directory system to the Terminal
|
|
||||||
** Details here: https://bitburner.readthedocs.io/en/latest/basicgameplay/terminal.html#filesystem-directories
|
|
||||||
* Added numHashes(), hashCost(), and spendHashes() functions to the Netscript Hacknet Node API
|
|
||||||
* 'Generate Coding Contract' hash upgrade is now more expensive
|
|
||||||
* 'Generate Coding Contract' hash upgrade now generates the contract randomly on the server, rather than on home computer
|
|
||||||
* The cost of selling hashes for money no longer increases each time
|
|
||||||
* Selling hashes for money now costs 4 hashes (in exchange for $1m)
|
|
||||||
* Bug Fix: Hacknet Node earnings should work properly when game is inactive/offline
|
|
||||||
* Bug Fix: Duplicate Sleeve augmentations are now properly reset when switching to a new BitNode
|
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,10 @@ import {
|
|||||||
placeOrder,
|
placeOrder,
|
||||||
cancelOrder
|
cancelOrder
|
||||||
} from "./StockMarket/StockMarket";
|
} from "./StockMarket/StockMarket";
|
||||||
|
import {
|
||||||
|
getBuyTransactionCost,
|
||||||
|
getSellTransactionGain,
|
||||||
|
} from "./StockMarket/StockMarketHelpers";
|
||||||
import { OrderTypes } from "./StockMarket/data/OrderTypes";
|
import { OrderTypes } from "./StockMarket/data/OrderTypes";
|
||||||
import { PositionTypes } from "./StockMarket/data/PositionTypes";
|
import { PositionTypes } from "./StockMarket/data/PositionTypes";
|
||||||
import { StockSymbols } from "./StockMarket/data/StockSymbols";
|
import { StockSymbols } from "./StockMarket/data/StockSymbols";
|
||||||
@ -280,6 +284,29 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the player has TIX API access. Throws an error if the player does not
|
||||||
|
*/
|
||||||
|
const checkTixApiAccess = function(callingFn="") {
|
||||||
|
if (!Player.hasTixApiAccess) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, `You don't have TIX API Access! Cannot use ${callingFn}()`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a stock, given its symbol. Throws an error if the symbol is invalid
|
||||||
|
* @param {string} symbol - Stock's symbol
|
||||||
|
* @returns {Stock} stock object
|
||||||
|
*/
|
||||||
|
const getStockFromSymbol = function(symbol, callingFn="") {
|
||||||
|
const stock = SymbolToStockMap[symbol];
|
||||||
|
if (stock == null) {
|
||||||
|
throw makeRuntimeRejectMsg(workerScript, `Invalid stock symbol passed into ${callingFn}()`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stock;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to fail a function if the function's target is a Hacknet Server.
|
* Used to fail a function if the function's target is a Hacknet Server.
|
||||||
* This is used for functions that should run on normal Servers, but not Hacknet Servers
|
* This is used for functions that should run on normal Servers, but not Hacknet Servers
|
||||||
@ -1585,9 +1612,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return updateStaticRam("getStockSymbols", CONSTANTS.ScriptGetStockRamCost);
|
return updateStaticRam("getStockSymbols", CONSTANTS.ScriptGetStockRamCost);
|
||||||
}
|
}
|
||||||
updateDynamicRam("getStockSymbols", CONSTANTS.ScriptGetStockRamCost);
|
updateDynamicRam("getStockSymbols", CONSTANTS.ScriptGetStockRamCost);
|
||||||
if (!Player.hasTixApiAccess) {
|
checkTixApiAccess("getStockSymbols");
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use getStockSymbols()");
|
|
||||||
}
|
|
||||||
return Object.values(StockSymbols);
|
return Object.values(StockSymbols);
|
||||||
},
|
},
|
||||||
getStockPrice : function(symbol) {
|
getStockPrice : function(symbol) {
|
||||||
@ -1595,23 +1620,37 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return updateStaticRam("getStockPrice", CONSTANTS.ScriptGetStockRamCost);
|
return updateStaticRam("getStockPrice", CONSTANTS.ScriptGetStockRamCost);
|
||||||
}
|
}
|
||||||
updateDynamicRam("getStockPrice", CONSTANTS.ScriptGetStockRamCost);
|
updateDynamicRam("getStockPrice", CONSTANTS.ScriptGetStockRamCost);
|
||||||
if (!Player.hasTixApiAccess) {
|
checkTixApiAccess("getStockPrice");
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use getStockPrice()");
|
const stock = getStockFromSymbol(symbol, "getStockPrice");
|
||||||
|
|
||||||
|
return stock.price;
|
||||||
|
},
|
||||||
|
getStockAskPrice : function(symbol) {
|
||||||
|
if (workerScript.checkingRam) {
|
||||||
|
return updateStaticRam("getStockAskPrice", CONSTANTS.ScriptGetStockRamCost);
|
||||||
}
|
}
|
||||||
var stock = SymbolToStockMap[symbol];
|
updateDynamicRam("getStockAskPrice", CONSTANTS.ScriptGetStockRamCost);
|
||||||
if (stock == null) {
|
checkTixApiAccess("getStockAskPrice");
|
||||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into getStockPrice()");
|
const stock = getStockFromSymbol(symbol, "getStockAskPrice");
|
||||||
|
|
||||||
|
return stock.getAskPrice();
|
||||||
|
},
|
||||||
|
getStockBidPrice : function(symbol) {
|
||||||
|
if (workerScript.checkingRam) {
|
||||||
|
return updateStaticRam("getStockBidPrice", CONSTANTS.ScriptGetStockRamCost);
|
||||||
}
|
}
|
||||||
return parseFloat(stock.price.toFixed(3));
|
updateDynamicRam("getStockBidPrice", CONSTANTS.ScriptGetStockRamCost);
|
||||||
|
checkTixApiAccess("getStockBidPrice");
|
||||||
|
const stock = getStockFromSymbol(symbol, "getStockBidPrice");
|
||||||
|
|
||||||
|
return stock.getBidPrice();
|
||||||
},
|
},
|
||||||
getStockPosition : function(symbol) {
|
getStockPosition : function(symbol) {
|
||||||
if (workerScript.checkingRam) {
|
if (workerScript.checkingRam) {
|
||||||
return updateStaticRam("getStockPosition", CONSTANTS.ScriptGetStockRamCost);
|
return updateStaticRam("getStockPosition", CONSTANTS.ScriptGetStockRamCost);
|
||||||
}
|
}
|
||||||
updateDynamicRam("getStockPosition", CONSTANTS.ScriptGetStockRamCost);
|
updateDynamicRam("getStockPosition", CONSTANTS.ScriptGetStockRamCost);
|
||||||
if (!Player.hasTixApiAccess) {
|
checkTixApiAccess("getStockPosition");
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use getStockPosition()");
|
|
||||||
}
|
|
||||||
var stock = SymbolToStockMap[symbol];
|
var stock = SymbolToStockMap[symbol];
|
||||||
if (stock == null) {
|
if (stock == null) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into getStockPosition()");
|
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into getStockPosition()");
|
||||||
@ -1623,29 +1662,66 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return updateStaticRam("getStockMaxShares", CONSTANTS.ScriptGetStockRamCost);
|
return updateStaticRam("getStockMaxShares", CONSTANTS.ScriptGetStockRamCost);
|
||||||
}
|
}
|
||||||
updateDynamicRam("getStockMaxShares", CONSTANTS.ScriptGetStockRamCost);
|
updateDynamicRam("getStockMaxShares", CONSTANTS.ScriptGetStockRamCost);
|
||||||
|
checkTixApiAccess("getStockMaxShares");
|
||||||
if (!Player.hasTixApiAccess) {
|
const stock = getStockFromSymbol(symbol, "getStockMaxShares");
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use getStockMaxShares()");
|
|
||||||
}
|
|
||||||
const stock = SymbolToStockMap[symbol];
|
|
||||||
if (stock == null) {
|
|
||||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into getStockMaxShares()");
|
|
||||||
}
|
|
||||||
|
|
||||||
return stock.maxShares;
|
return stock.maxShares;
|
||||||
},
|
},
|
||||||
|
getStockPurchaseCost : function(symbol, shares, posType) {
|
||||||
|
if (workerScript.checkingRam) {
|
||||||
|
return updateStaticRam("getStockPurchaseCost", CONSTANTS.ScriptGetStockRamCost);
|
||||||
|
}
|
||||||
|
updateDynamicRam("getStockPurchaseCost", CONSTANTS.ScriptGetStockRamCost);
|
||||||
|
checkTixApiAccess("getStockPurchaseCost");
|
||||||
|
const stock = getStockFromSymbol(symbol, "getStockPurchaseCost");
|
||||||
|
shares = Math.round(shares);
|
||||||
|
|
||||||
|
let pos;
|
||||||
|
const sanitizedPosType = posType.toLowerCase();
|
||||||
|
if (sanitizedPosType.includes("l")) {
|
||||||
|
pos = PositionTypes.Long;
|
||||||
|
} else if (sanitizedPosType.includes("s")) {
|
||||||
|
pos = PositionTypes.Short;
|
||||||
|
} else {
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = getBuyTransactionCost(stock, shares, pos);
|
||||||
|
if (res == null) { return Infinity; }
|
||||||
|
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
getStockSaleGain : function(symbol, shares, posType) {
|
||||||
|
if (workerScript.checkingRam) {
|
||||||
|
return updateStaticRam("getStockSaleGain", CONSTANTS.ScriptGetStockRamCost);
|
||||||
|
}
|
||||||
|
updateDynamicRam("getStockSaleGain", CONSTANTS.ScriptGetStockRamCost);
|
||||||
|
checkTixApiAccess("getStockSaleGain");
|
||||||
|
const stock = getStockFromSymbol(symbol, "getStockSaleGain");
|
||||||
|
shares = Math.round(shares);
|
||||||
|
|
||||||
|
let pos;
|
||||||
|
const sanitizedPosType = posType.toLowerCase();
|
||||||
|
if (sanitizedPosType.includes("l")) {
|
||||||
|
pos = PositionTypes.Long;
|
||||||
|
} else if (sanitizedPosType.includes("s")) {
|
||||||
|
pos = PositionTypes.Short;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = getSellTransactionGain(stock, shares, pos);
|
||||||
|
if (res == null) { return 0; }
|
||||||
|
|
||||||
|
return res;
|
||||||
|
},
|
||||||
buyStock : function(symbol, shares) {
|
buyStock : function(symbol, shares) {
|
||||||
if (workerScript.checkingRam) {
|
if (workerScript.checkingRam) {
|
||||||
return updateStaticRam("buyStock", CONSTANTS.ScriptBuySellStockRamCost);
|
return updateStaticRam("buyStock", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
}
|
}
|
||||||
updateDynamicRam("buyStock", CONSTANTS.ScriptBuySellStockRamCost);
|
updateDynamicRam("buyStock", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
if (!Player.hasTixApiAccess) {
|
checkTixApiAccess("buyStock");
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use buyStock()");
|
const stock = getStockFromSymbol(symbol, "buyStock");
|
||||||
}
|
|
||||||
var stock = SymbolToStockMap[symbol];
|
|
||||||
if (stock == null) {
|
|
||||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into buyStock()");
|
|
||||||
}
|
|
||||||
const res = buyStock(stock, shares, workerScript);
|
const res = buyStock(stock, shares, workerScript);
|
||||||
|
|
||||||
return res ? stock.price : 0;
|
return res ? stock.price : 0;
|
||||||
@ -1655,77 +1731,57 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return updateStaticRam("sellStock", CONSTANTS.ScriptBuySellStockRamCost);
|
return updateStaticRam("sellStock", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
}
|
}
|
||||||
updateDynamicRam("sellStock", CONSTANTS.ScriptBuySellStockRamCost);
|
updateDynamicRam("sellStock", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
if (!Player.hasTixApiAccess) {
|
checkTixApiAccess("sellStock");
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use sellStock()");
|
const stock = getStockFromSymbol(symbol, "sellStock");
|
||||||
}
|
|
||||||
var stock = SymbolToStockMap[symbol];
|
|
||||||
if (stock == null) {
|
|
||||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into sellStock()");
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = sellStock(stock, shares, workerScript);
|
const res = sellStock(stock, shares, workerScript);
|
||||||
|
|
||||||
return res ? stock.price : 0;
|
return res ? stock.price : 0;
|
||||||
},
|
},
|
||||||
shortStock(symbol, shares) {
|
shortStock : function(symbol, shares) {
|
||||||
if (workerScript.checkingRam) {
|
if (workerScript.checkingRam) {
|
||||||
return updateStaticRam("shortStock", CONSTANTS.ScriptBuySellStockRamCost);
|
return updateStaticRam("shortStock", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
}
|
}
|
||||||
updateDynamicRam("shortStock", CONSTANTS.ScriptBuySellStockRamCost);
|
updateDynamicRam("shortStock", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
if (!Player.hasTixApiAccess) {
|
checkTixApiAccess("shortStock");
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use shortStock()");
|
|
||||||
}
|
|
||||||
if (Player.bitNodeN !== 8) {
|
if (Player.bitNodeN !== 8) {
|
||||||
if (!(hasWallStreetSF && wallStreetSFLvl >= 2)) {
|
if (!(hasWallStreetSF && wallStreetSFLvl >= 2)) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Cannot use shortStock(). You must either be in BitNode-8 or you must have Level 2 of Source-File 8");
|
throw makeRuntimeRejectMsg(workerScript, "ERROR: Cannot use shortStock(). You must either be in BitNode-8 or you must have Level 2 of Source-File 8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var stock = SymbolToStockMap[symbol];
|
const stock = getStockFromSymbol(symbol, "shortStock");
|
||||||
if (stock == null) {
|
|
||||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into shortStock()");
|
|
||||||
}
|
|
||||||
const res = shortStock(stock, shares, workerScript);
|
const res = shortStock(stock, shares, workerScript);
|
||||||
|
|
||||||
return res ? stock.price : 0;
|
return res ? stock.price : 0;
|
||||||
},
|
},
|
||||||
sellShort(symbol, shares) {
|
sellShort : function(symbol, shares) {
|
||||||
if (workerScript.checkingRam) {
|
if (workerScript.checkingRam) {
|
||||||
return updateStaticRam("sellShort", CONSTANTS.ScriptBuySellStockRamCost);
|
return updateStaticRam("sellShort", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
}
|
}
|
||||||
updateDynamicRam("sellShort", CONSTANTS.ScriptBuySellStockRamCost);
|
updateDynamicRam("sellShort", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
if (!Player.hasTixApiAccess) {
|
checkTixApiAccess("sellShort");
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use sellShort()");
|
|
||||||
}
|
|
||||||
if (Player.bitNodeN !== 8) {
|
if (Player.bitNodeN !== 8) {
|
||||||
if (!(hasWallStreetSF && wallStreetSFLvl >= 2)) {
|
if (!(hasWallStreetSF && wallStreetSFLvl >= 2)) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Cannot use sellShort(). You must either be in BitNode-8 or you must have Level 2 of Source-File 8");
|
throw makeRuntimeRejectMsg(workerScript, "ERROR: Cannot use sellShort(). You must either be in BitNode-8 or you must have Level 2 of Source-File 8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var stock = SymbolToStockMap[symbol];
|
const stock = getStockFromSymbol(symbol, "sellShort");
|
||||||
if (stock == null) {
|
|
||||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into sellShort()");
|
|
||||||
}
|
|
||||||
const res = sellShort(stock, shares, workerScript);
|
const res = sellShort(stock, shares, workerScript);
|
||||||
|
|
||||||
return res ? stock.price : 0;
|
return res ? stock.price : 0;
|
||||||
},
|
},
|
||||||
placeOrder(symbol, shares, price, type, pos) {
|
placeOrder : function(symbol, shares, price, type, pos) {
|
||||||
if (workerScript.checkingRam) {
|
if (workerScript.checkingRam) {
|
||||||
return updateStaticRam("placeOrder", CONSTANTS.ScriptBuySellStockRamCost);
|
return updateStaticRam("placeOrder", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
}
|
}
|
||||||
updateDynamicRam("placeOrder", CONSTANTS.ScriptBuySellStockRamCost);
|
updateDynamicRam("placeOrder", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
if (!Player.hasTixApiAccess) {
|
checkTixApiAccess("placeOrder");
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use placeOrder()");
|
|
||||||
}
|
|
||||||
if (Player.bitNodeN !== 8) {
|
if (Player.bitNodeN !== 8) {
|
||||||
if (!(hasWallStreetSF && wallStreetSFLvl >= 3)) {
|
if (!(hasWallStreetSF && wallStreetSFLvl >= 3)) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Cannot use placeOrder(). You must either be in BitNode-8 or have Level 3 of Source-File 8");
|
throw makeRuntimeRejectMsg(workerScript, "ERROR: Cannot use placeOrder(). You must either be in BitNode-8 or have Level 3 of Source-File 8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var stock = SymbolToStockMap[symbol];
|
const stock = getStockFromSymbol(symbol, "placeOrder");
|
||||||
if (stock == null) {
|
|
||||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into placeOrder()");
|
|
||||||
}
|
|
||||||
var orderType, orderPos;
|
var orderType, orderPos;
|
||||||
type = type.toLowerCase();
|
type = type.toLowerCase();
|
||||||
if (type.includes("limit") && type.includes("buy")) {
|
if (type.includes("limit") && type.includes("buy")) {
|
||||||
@ -1751,23 +1807,18 @@ function NetscriptFunctions(workerScript) {
|
|||||||
|
|
||||||
return placeOrder(stock, shares, price, orderType, orderPos, workerScript);
|
return placeOrder(stock, shares, price, orderType, orderPos, workerScript);
|
||||||
},
|
},
|
||||||
cancelOrder(symbol, shares, price, type, pos) {
|
cancelOrder : function(symbol, shares, price, type, pos) {
|
||||||
if (workerScript.checkingRam) {
|
if (workerScript.checkingRam) {
|
||||||
return updateStaticRam("cancelOrder", CONSTANTS.ScriptBuySellStockRamCost);
|
return updateStaticRam("cancelOrder", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
}
|
}
|
||||||
updateDynamicRam("cancelOrder", CONSTANTS.ScriptBuySellStockRamCost);
|
updateDynamicRam("cancelOrder", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
if (!Player.hasTixApiAccess) {
|
checkTixApiAccess("cancelOrder");
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use cancelOrder()");
|
|
||||||
}
|
|
||||||
if (Player.bitNodeN !== 8) {
|
if (Player.bitNodeN !== 8) {
|
||||||
if (!(hasWallStreetSF && wallStreetSFLvl >= 3)) {
|
if (!(hasWallStreetSF && wallStreetSFLvl >= 3)) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Cannot use cancelOrder(). You must either be in BitNode-8 or have Level 3 of Source-File 8");
|
throw makeRuntimeRejectMsg(workerScript, "ERROR: Cannot use cancelOrder(). You must either be in BitNode-8 or have Level 3 of Source-File 8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var stock = SymbolToStockMap[symbol];
|
const stock = getStockFrom(symbol, "cancelOrder");
|
||||||
if (stock == null) {
|
|
||||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into cancelOrder()");
|
|
||||||
}
|
|
||||||
if (isNaN(shares) || isNaN(price)) {
|
if (isNaN(shares) || isNaN(price)) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid shares or price argument passed into cancelOrder(). Must be numeric");
|
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid shares or price argument passed into cancelOrder(). Must be numeric");
|
||||||
}
|
}
|
||||||
@ -1844,10 +1895,8 @@ function NetscriptFunctions(workerScript) {
|
|||||||
if (!Player.has4SDataTixApi) {
|
if (!Player.has4SDataTixApi) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have 4S Market Data TIX API Access! Cannot use getStockVolatility()");
|
throw makeRuntimeRejectMsg(workerScript, "You don't have 4S Market Data TIX API Access! Cannot use getStockVolatility()");
|
||||||
}
|
}
|
||||||
var stock = SymbolToStockMap[symbol];
|
const stock = getStockFromSymbol(symbol, "getStockVolatility");
|
||||||
if (stock == null) {
|
|
||||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into getStockVolatility()");
|
|
||||||
}
|
|
||||||
return stock.mv / 100; // Convert from percentage to decimal
|
return stock.mv / 100; // Convert from percentage to decimal
|
||||||
},
|
},
|
||||||
getStockForecast : function(symbol) {
|
getStockForecast : function(symbol) {
|
||||||
@ -1858,10 +1907,8 @@ function NetscriptFunctions(workerScript) {
|
|||||||
if (!Player.has4SDataTixApi) {
|
if (!Player.has4SDataTixApi) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have 4S Market Data TIX API Access! Cannot use getStockForecast()");
|
throw makeRuntimeRejectMsg(workerScript, "You don't have 4S Market Data TIX API Access! Cannot use getStockForecast()");
|
||||||
}
|
}
|
||||||
var stock = SymbolToStockMap[symbol];
|
const stock = getStockFromSymbol(symbol, "getStockForecast");
|
||||||
if (stock == null) {
|
|
||||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into getStockForecast()");
|
|
||||||
}
|
|
||||||
var forecast = 50;
|
var forecast = 50;
|
||||||
stock.b ? forecast += stock.otlkMag : forecast -= stock.otlkMag;
|
stock.b ? forecast += stock.otlkMag : forecast -= stock.otlkMag;
|
||||||
return forecast / 100; // Convert from percentage to decimal
|
return forecast / 100; // Convert from percentage to decimal
|
||||||
@ -1871,10 +1918,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return updateStaticRam("purchase4SMarketData", CONSTANTS.ScriptBuySellStockRamCost);
|
return updateStaticRam("purchase4SMarketData", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
}
|
}
|
||||||
updateDynamicRam("purchase4SMarketData", CONSTANTS.ScriptBuySellStockRamCost);
|
updateDynamicRam("purchase4SMarketData", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
|
checkTixApiAccess("purchase4SMarketData");
|
||||||
if (!Player.hasTixApiAccess) {
|
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use purchase4SMarketData()");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Player.has4SData) {
|
if (Player.has4SData) {
|
||||||
if (workerScript.shouldLog("purchase4SMarketData")) {
|
if (workerScript.shouldLog("purchase4SMarketData")) {
|
||||||
@ -1902,10 +1946,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return updateStaticRam("purchase4SMarketDataTixApi", CONSTANTS.ScriptBuySellStockRamCost);
|
return updateStaticRam("purchase4SMarketDataTixApi", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
}
|
}
|
||||||
updateDynamicRam("purchase4SMarketDataTixApi", CONSTANTS.ScriptBuySellStockRamCost);
|
updateDynamicRam("purchase4SMarketDataTixApi", CONSTANTS.ScriptBuySellStockRamCost);
|
||||||
|
checkTixApiAccess("purchase4SMarketDataTixApi");
|
||||||
if (!Player.hasTixApiAccess) {
|
|
||||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use purchase4SMarketDataTixApi()");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Player.has4SDataTixApi) {
|
if (Player.has4SDataTixApi) {
|
||||||
if (workerScript.shouldLog("purchase4SMarketDataTixApi")) {
|
if (workerScript.shouldLog("purchase4SMarketDataTixApi")) {
|
||||||
|
@ -182,7 +182,7 @@ export class Stock {
|
|||||||
this.totalShares = Math.round(totalSharesUnrounded / 1e5) * 1e5;
|
this.totalShares = Math.round(totalSharesUnrounded / 1e5) * 1e5;
|
||||||
|
|
||||||
// Max Shares (Outstanding shares) is a percentage of total shares
|
// Max Shares (Outstanding shares) is a percentage of total shares
|
||||||
const outstandingSharePercentage: number = 0.15;
|
const outstandingSharePercentage: number = 0.2;
|
||||||
this.maxShares = Math.round((this.totalShares * outstandingSharePercentage) / 1e5) * 1e5;
|
this.maxShares = Math.round((this.totalShares * outstandingSharePercentage) / 1e5) * 1e5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 1,
|
min: 1,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 10e3,
|
max: 30e3,
|
||||||
min: 5e3,
|
min: 10e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.AevumECorp],
|
symbol: StockSymbols[LocationName.AevumECorp],
|
||||||
},
|
},
|
||||||
@ -59,8 +59,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 1,
|
min: 1,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 10e3,
|
max: 30e3,
|
||||||
min: 5e3,
|
min: 10e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.Sector12MegaCorp],
|
symbol: StockSymbols[LocationName.Sector12MegaCorp],
|
||||||
},
|
},
|
||||||
@ -85,8 +85,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 1,
|
min: 1,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 10e3,
|
max: 30e3,
|
||||||
min: 5e3,
|
min: 10e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.Sector12BladeIndustries],
|
symbol: StockSymbols[LocationName.Sector12BladeIndustries],
|
||||||
},
|
},
|
||||||
@ -111,8 +111,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 1,
|
min: 1,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 10e3,
|
max: 30e3,
|
||||||
min: 5e3,
|
min: 10e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.AevumClarkeIncorporated],
|
symbol: StockSymbols[LocationName.AevumClarkeIncorporated],
|
||||||
},
|
},
|
||||||
@ -137,8 +137,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 1,
|
min: 1,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 10e3,
|
max: 30e3,
|
||||||
min: 5e3,
|
min: 10e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.VolhavenOmniTekIncorporated],
|
symbol: StockSymbols[LocationName.VolhavenOmniTekIncorporated],
|
||||||
},
|
},
|
||||||
@ -163,8 +163,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 1,
|
min: 1,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 10e3,
|
max: 30e3,
|
||||||
min: 5e3,
|
min: 10e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.Sector12FourSigma],
|
symbol: StockSymbols[LocationName.Sector12FourSigma],
|
||||||
},
|
},
|
||||||
@ -189,8 +189,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 1,
|
min: 1,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 10e3,
|
max: 30e3,
|
||||||
min: 5e3,
|
min: 10e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.ChongqingKuaiGongInternational],
|
symbol: StockSymbols[LocationName.ChongqingKuaiGongInternational],
|
||||||
},
|
},
|
||||||
@ -215,8 +215,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 1,
|
min: 1,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 10e3,
|
max: 30e3,
|
||||||
min: 5e3,
|
min: 10e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.AevumFulcrumTechnologies],
|
symbol: StockSymbols[LocationName.AevumFulcrumTechnologies],
|
||||||
},
|
},
|
||||||
@ -241,8 +241,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 2,
|
min: 2,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 12e3,
|
max: 36e3,
|
||||||
min: 6e3,
|
min: 12e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.IshimaStormTechnologies],
|
symbol: StockSymbols[LocationName.IshimaStormTechnologies],
|
||||||
},
|
},
|
||||||
@ -267,8 +267,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 2,
|
min: 2,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 12e3,
|
max: 36e3,
|
||||||
min: 6e3,
|
min: 12e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.NewTokyoDefComm],
|
symbol: StockSymbols[LocationName.NewTokyoDefComm],
|
||||||
},
|
},
|
||||||
@ -293,8 +293,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 2,
|
min: 2,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 12e3,
|
max: 36e3,
|
||||||
min: 6e3,
|
min: 12e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.VolhavenHeliosLabs],
|
symbol: StockSymbols[LocationName.VolhavenHeliosLabs],
|
||||||
},
|
},
|
||||||
@ -319,8 +319,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 2,
|
min: 2,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 12e3,
|
max: 36e3,
|
||||||
min: 6e3,
|
min: 12e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.NewTokyoVitaLife],
|
symbol: StockSymbols[LocationName.NewTokyoVitaLife],
|
||||||
},
|
},
|
||||||
@ -345,8 +345,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 3,
|
min: 3,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 12e3,
|
max: 36e3,
|
||||||
min: 6e3,
|
min: 12e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.Sector12IcarusMicrosystems],
|
symbol: StockSymbols[LocationName.Sector12IcarusMicrosystems],
|
||||||
},
|
},
|
||||||
@ -371,8 +371,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 2,
|
min: 2,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 12e3,
|
max: 36e3,
|
||||||
min: 6e3,
|
min: 12e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.Sector12UniversalEnergy],
|
symbol: StockSymbols[LocationName.Sector12UniversalEnergy],
|
||||||
},
|
},
|
||||||
@ -397,8 +397,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 3,
|
min: 3,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 14e3,
|
max: 42e3,
|
||||||
min: 7e3,
|
min: 14e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.AevumAeroCorp],
|
symbol: StockSymbols[LocationName.AevumAeroCorp],
|
||||||
},
|
},
|
||||||
@ -423,8 +423,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 4,
|
min: 4,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 14e3,
|
max: 42e3,
|
||||||
min: 7e3,
|
min: 14e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.VolhavenOmniaCybersystems],
|
symbol: StockSymbols[LocationName.VolhavenOmniaCybersystems],
|
||||||
},
|
},
|
||||||
@ -449,8 +449,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 4,
|
min: 4,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 14e3,
|
max: 42e3,
|
||||||
min: 7e3,
|
min: 14e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.ChongqingSolarisSpaceSystems],
|
symbol: StockSymbols[LocationName.ChongqingSolarisSpaceSystems],
|
||||||
},
|
},
|
||||||
@ -475,8 +475,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 4,
|
min: 4,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 14e3,
|
max: 42e3,
|
||||||
min: 7e3,
|
min: 14e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.NewTokyoGlobalPharmaceuticals],
|
symbol: StockSymbols[LocationName.NewTokyoGlobalPharmaceuticals],
|
||||||
},
|
},
|
||||||
@ -501,8 +501,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 4,
|
min: 4,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 14e3,
|
max: 42e3,
|
||||||
min: 7e3,
|
min: 14e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.IshimaNovaMedical],
|
symbol: StockSymbols[LocationName.IshimaNovaMedical],
|
||||||
},
|
},
|
||||||
@ -527,8 +527,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 5,
|
min: 5,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 6e3,
|
max: 18e3,
|
||||||
min: 2e3,
|
min: 4e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.AevumWatchdogSecurity],
|
symbol: StockSymbols[LocationName.AevumWatchdogSecurity],
|
||||||
},
|
},
|
||||||
@ -553,8 +553,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 5,
|
min: 5,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 12e3,
|
max: 36e3,
|
||||||
min: 6e3,
|
min: 12e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.VolhavenLexoCorp],
|
symbol: StockSymbols[LocationName.VolhavenLexoCorp],
|
||||||
},
|
},
|
||||||
@ -579,8 +579,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 3,
|
min: 3,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 20e3,
|
max: 42e3,
|
||||||
min: 10e3,
|
min: 20e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.AevumRhoConstruction],
|
symbol: StockSymbols[LocationName.AevumRhoConstruction],
|
||||||
},
|
},
|
||||||
@ -605,8 +605,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 5,
|
min: 5,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 10e3,
|
max: 30e3,
|
||||||
min: 5e3,
|
min: 10e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.Sector12AlphaEnterprises],
|
symbol: StockSymbols[LocationName.Sector12AlphaEnterprises],
|
||||||
},
|
},
|
||||||
@ -631,8 +631,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 5,
|
min: 5,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 10e3,
|
max: 30e3,
|
||||||
min: 5e3,
|
min: 10e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.VolhavenSysCoreSecurities],
|
symbol: StockSymbols[LocationName.VolhavenSysCoreSecurities],
|
||||||
},
|
},
|
||||||
@ -657,8 +657,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 4,
|
min: 4,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 15e3,
|
max: 42e3,
|
||||||
min: 10e3,
|
min: 20e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.VolhavenCompuTek],
|
symbol: StockSymbols[LocationName.VolhavenCompuTek],
|
||||||
},
|
},
|
||||||
@ -683,8 +683,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 5,
|
min: 5,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 6e3,
|
max: 18e3,
|
||||||
min: 3e3,
|
min: 6e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.AevumNetLinkTechnologies],
|
symbol: StockSymbols[LocationName.AevumNetLinkTechnologies],
|
||||||
},
|
},
|
||||||
@ -709,8 +709,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 4,
|
min: 4,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 10e3,
|
max: 30e3,
|
||||||
min: 5e3,
|
min: 10e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.IshimaOmegaSoftware],
|
symbol: StockSymbols[LocationName.IshimaOmegaSoftware],
|
||||||
},
|
},
|
||||||
@ -735,8 +735,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 6,
|
min: 6,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 20e3,
|
max: 60e3,
|
||||||
min: 10e3,
|
min: 20e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols[LocationName.Sector12FoodNStuff],
|
symbol: StockSymbols[LocationName.Sector12FoodNStuff],
|
||||||
},
|
},
|
||||||
@ -761,8 +761,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 6,
|
min: 6,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 8e3,
|
max: 28e3,
|
||||||
min: 4e3,
|
min: 8e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols["Sigma Cosmetics"],
|
symbol: StockSymbols["Sigma Cosmetics"],
|
||||||
},
|
},
|
||||||
@ -787,8 +787,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 6,
|
min: 6,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 7e3,
|
max: 21e3,
|
||||||
min: 3e3,
|
min: 6e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols["Joes Guns"],
|
symbol: StockSymbols["Joes Guns"],
|
||||||
},
|
},
|
||||||
@ -813,8 +813,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 5,
|
min: 5,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 8e3,
|
max: 24e3,
|
||||||
min: 4e3,
|
min: 8e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols["Catalyst Ventures"],
|
symbol: StockSymbols["Catalyst Ventures"],
|
||||||
},
|
},
|
||||||
@ -839,8 +839,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 3,
|
min: 3,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 25e3,
|
max: 72e3,
|
||||||
min: 15e3,
|
min: 30e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols["Microdyne Technologies"],
|
symbol: StockSymbols["Microdyne Technologies"],
|
||||||
},
|
},
|
||||||
@ -865,8 +865,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
|||||||
min: 2,
|
min: 2,
|
||||||
},
|
},
|
||||||
shareTxForMovement: {
|
shareTxForMovement: {
|
||||||
max: 25e3,
|
max: 72e3,
|
||||||
min: 15e3,
|
min: 30e3,
|
||||||
},
|
},
|
||||||
symbol: StockSymbols["Titan Laboratories"],
|
symbol: StockSymbols["Titan Laboratories"],
|
||||||
},
|
},
|
||||||
|
@ -39,16 +39,6 @@ export class InfoAndPurchases extends React.Component<IProps, any> {
|
|||||||
this.purchase4SMarketDataTixApiAccess = this.purchase4SMarketDataTixApiAccess.bind(this);
|
this.purchase4SMarketDataTixApiAccess = this.purchase4SMarketDataTixApiAccess.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps: IProps) {
|
|
||||||
// This only need to rerender if the player has purchased something new
|
|
||||||
if (this.props.p.hasWseAccount !== nextProps.p.hasWseAccount) { return true; }
|
|
||||||
if (this.props.p.hasTixApiAccess !== nextProps.p.hasTixApiAccess) { return true; }
|
|
||||||
if (this.props.p.has4SData !== nextProps.p.has4SData) { return true; }
|
|
||||||
if (this.props.p.has4SDataTixApi !== nextProps.p.has4SDataTixApi) { return true; }
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleClick4SMarketDataHelpTip() {
|
handleClick4SMarketDataHelpTip() {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"Access to the 4S Market Data feed will display two additional pieces " +
|
"Access to the 4S Market Data feed will display two additional pieces " +
|
||||||
|
@ -109,10 +109,12 @@ export class StockTicker extends React.Component<IProps, IState> {
|
|||||||
const stock = this.props.stock;
|
const stock = this.props.stock;
|
||||||
const qty: number = this.getQuantity();
|
const qty: number = this.getQuantity();
|
||||||
if (isNaN(qty)) { return ""; }
|
if (isNaN(qty)) { return ""; }
|
||||||
const cost = getBuyTransactionCost(this.props.stock, qty, this.state.position);
|
|
||||||
|
const cost = getBuyTransactionCost(stock, qty, this.state.position);
|
||||||
if (cost == null) { return ""; }
|
if (cost == null) { return ""; }
|
||||||
|
|
||||||
let costTxt = `Purchasing ${numeralWrapper.formatBigNumber(qty)} shares will cost ${numeralWrapper.formatMoney(cost)}. `;
|
let costTxt = `Purchasing ${numeralWrapper.formatBigNumber(qty)} shares (${this.state.position === PositionTypes.Long ? "Long" : "Short"}) ` +
|
||||||
|
`will cost ${numeralWrapper.formatMoney(cost)}. `;
|
||||||
|
|
||||||
const causesMovement = qty > stock.shareTxUntilMovement;
|
const causesMovement = qty > stock.shareTxUntilMovement;
|
||||||
if (causesMovement) {
|
if (causesMovement) {
|
||||||
@ -130,10 +132,22 @@ export class StockTicker extends React.Component<IProps, IState> {
|
|||||||
const stock = this.props.stock;
|
const stock = this.props.stock;
|
||||||
const qty: number = this.getQuantity();
|
const qty: number = this.getQuantity();
|
||||||
if (isNaN(qty)) { return ""; }
|
if (isNaN(qty)) { return ""; }
|
||||||
const cost = getSellTransactionGain(this.props.stock, qty, this.state.position);
|
|
||||||
|
if (this.state.position === PositionTypes.Long) {
|
||||||
|
if (qty > stock.playerShares) {
|
||||||
|
return `You do not have this many shares in the Long position`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (qty > stock.playerShortShares) {
|
||||||
|
return `You do not have this many shares in the Short position`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cost = getSellTransactionGain(stock, qty, this.state.position);
|
||||||
if (cost == null) { return ""; }
|
if (cost == null) { return ""; }
|
||||||
|
|
||||||
let costTxt = `Selling ${numeralWrapper.formatBigNumber(qty)} shares will result in a gain of ${numeralWrapper.formatMoney(cost)}. `;
|
let costTxt = `Selling ${numeralWrapper.formatBigNumber(qty)} shares (${this.state.position === PositionTypes.Long ? "Long" : "Short"}) ` +
|
||||||
|
`will result in a gain of ${numeralWrapper.formatMoney(cost)}. `;
|
||||||
|
|
||||||
const causesMovement = qty > stock.shareTxUntilMovement;
|
const causesMovement = qty > stock.shareTxUntilMovement;
|
||||||
if (causesMovement) {
|
if (causesMovement) {
|
||||||
@ -264,7 +278,7 @@ export class StockTicker extends React.Component<IProps, IState> {
|
|||||||
handlePositionTypeChange(e: React.ChangeEvent<HTMLSelectElement>) {
|
handlePositionTypeChange(e: React.ChangeEvent<HTMLSelectElement>) {
|
||||||
const val = e.target.value;
|
const val = e.target.value;
|
||||||
|
|
||||||
if (val === "Short") {
|
if (val === PositionTypes.Short) {
|
||||||
this.setState({
|
this.setState({
|
||||||
position: PositionTypes.Short,
|
position: PositionTypes.Short,
|
||||||
});
|
});
|
||||||
@ -369,19 +383,19 @@ export class StockTicker extends React.Component<IProps, IState> {
|
|||||||
panelContent={
|
panelContent={
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
className={"stock-market-input"}
|
className="stock-market-input"
|
||||||
onChange={this.handleQuantityChange}
|
onChange={this.handleQuantityChange}
|
||||||
placeholder={"Quantity (Shares)"}
|
placeholder="Quantity (Shares)"
|
||||||
value={this.state.qty}
|
value={this.state.qty}
|
||||||
/>
|
/>
|
||||||
<select className={"stock-market-input dropdown"} onChange={this.handlePositionTypeChange} value={this.state.position}>
|
<select className="stock-market-input dropdown" onChange={this.handlePositionTypeChange} value={this.state.position}>
|
||||||
<option value={"Long"}>Long</option>
|
<option value={PositionTypes.Long}>Long</option>
|
||||||
{
|
{
|
||||||
this.hasShortAccess() &&
|
this.hasShortAccess() &&
|
||||||
<option value={"Short"}>Short</option>
|
<option value={PositionTypes.Short}>Short</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
<select className={"stock-market-input dropdown"} onChange={this.handleOrderTypeChange} value={this.state.orderType}>
|
<select className="stock-market-input dropdown" onChange={this.handleOrderTypeChange} value={this.state.orderType}>
|
||||||
<option value={SelectorOrderType.Market}>{SelectorOrderType.Market}</option>
|
<option value={SelectorOrderType.Market}>{SelectorOrderType.Market}</option>
|
||||||
{
|
{
|
||||||
this.hasOrderAccess() &&
|
this.hasOrderAccess() &&
|
||||||
@ -402,7 +416,7 @@ export class StockTicker extends React.Component<IProps, IState> {
|
|||||||
<p className="stock-market-price-movement-warning">
|
<p className="stock-market-price-movement-warning">
|
||||||
WARNING: Buying/Selling {numeralWrapper.formatBigNumber(qty)} shares will affect
|
WARNING: Buying/Selling {numeralWrapper.formatBigNumber(qty)} shares will affect
|
||||||
the stock's price. This applies during the transaction itself as well. See Investopedia
|
the stock's price. This applies during the transaction itself as well. See Investopedia
|
||||||
for more details.
|
for more details.
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
<StockTickerPositionText p={this.props.p} stock={this.props.stock} />
|
<StockTickerPositionText p={this.props.p} stock={this.props.stock} />
|
||||||
|
@ -32,7 +32,7 @@ export class StockTickerPositionText extends React.Component<IProps, any> {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3 className={"tooltip"}>
|
<h3 className={"tooltip"}>
|
||||||
Short Position:
|
Long Position:
|
||||||
<span className={"tooltiptext"}>
|
<span className={"tooltiptext"}>
|
||||||
Shares in the long position will increase in value if the price
|
Shares in the long position will increase in value if the price
|
||||||
of the corresponding stock increases
|
of the corresponding stock increases
|
||||||
|
Loading…
Reference in New Issue
Block a user