mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-09 09:13:52 +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.
|
||||
|
||||
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.
|
||||
Fundamentals
|
||||
------------
|
||||
The Stock Market is not as simple as "buy at price X and sell at price Y". The following
|
||||
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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -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'
|
||||
a stock.
|
||||
|
||||
NOTE: Shorting stocks is not available immediately, and must be unlocked later in the
|
||||
game.
|
||||
.. note:: Shorting stocks is not available immediately, and must be unlocked later in the
|
||||
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
|
||||
^^^^^^^^^^^
|
||||
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.
|
||||
|
||||
Note that Limit Orders and Stop Orders are not available immediately, and must be unlocked
|
||||
later in the game.
|
||||
.. note:: Limit Orders and Stop Orders are not available immediately, and must be unlocked
|
||||
later in the game.
|
||||
|
||||
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
|
||||
@ -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 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::
|
||||
:caption: API Functions:
|
||||
|
||||
|
||||
getStockSymbols() <tixapi/getStockSymbols>
|
||||
getStockPrice() <tixapi/getStockPrice>
|
||||
getStockAskPrice() <tixapi/getStockAskPrice>
|
||||
getStockBidPrice() <tixapi/getStockBidPrice>
|
||||
getStockPosition() <tixapi/getStockPosition>
|
||||
getStockMaxShares() <tixapi/getStockMaxShares>
|
||||
getStockPurchaseCost() <tixapi/getStockPurchaseCost>
|
||||
getStockSaleGain() <tixapi/getStockSaleGain>
|
||||
buyStock() <tixapi/buyStock>
|
||||
sellStock() <tixapi/sellStock>
|
||||
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
|
||||
:RAM cost: 2 GB
|
||||
|
||||
Returns the price of a stock, given its symbol (NOT the company name). The symbol is a sequence
|
||||
of two to four capital letters.
|
||||
Given a stock's symbol, returns the 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).
|
||||
|
||||
.. 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::
|
||||
|
||||
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:
|
||||
`
|
||||
v0.46.3
|
||||
* Added a new Augmentation: The Shadow's Simulacrum
|
||||
* Improved tab autocompletion feature in Terminal so that it works better with directories
|
||||
* Bug Fix: Tech vendor location UI now properly refreshed when purchasing a TOR router
|
||||
* Bug Fix: Fixed UI issue with faction donations
|
||||
* Bug Fix: The money statistics & breakdown should now properly track money earned from Hacknet Server (hashes -> money)
|
||||
* Bug Fix: Fixed issue with changing input in 'Minimum Path Sum in a Triangle' coding contract problem
|
||||
* Fixed several typos in various places
|
||||
v0.47.0
|
||||
* Stock Market changes:
|
||||
** Implemented spread. Stock's now have bid and ask prices at which transactions occur
|
||||
** Large transactions will now influence a stock's price.
|
||||
** This "influencing" can take effect in the middle of a transaction
|
||||
** See documentation for more details on these changes
|
||||
** Added getStockAskPrice(), getStockBidPrice() Netscript functions to the TIX API
|
||||
** 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,
|
||||
cancelOrder
|
||||
} from "./StockMarket/StockMarket";
|
||||
import {
|
||||
getBuyTransactionCost,
|
||||
getSellTransactionGain,
|
||||
} from "./StockMarket/StockMarketHelpers";
|
||||
import { OrderTypes } from "./StockMarket/data/OrderTypes";
|
||||
import { PositionTypes } from "./StockMarket/data/PositionTypes";
|
||||
import { StockSymbols } from "./StockMarket/data/StockSymbols";
|
||||
@ -280,6 +284,29 @@ function NetscriptFunctions(workerScript) {
|
||||
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.
|
||||
* 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);
|
||||
}
|
||||
updateDynamicRam("getStockSymbols", CONSTANTS.ScriptGetStockRamCost);
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use getStockSymbols()");
|
||||
}
|
||||
checkTixApiAccess("getStockSymbols");
|
||||
return Object.values(StockSymbols);
|
||||
},
|
||||
getStockPrice : function(symbol) {
|
||||
@ -1595,23 +1620,37 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("getStockPrice", CONSTANTS.ScriptGetStockRamCost);
|
||||
}
|
||||
updateDynamicRam("getStockPrice", CONSTANTS.ScriptGetStockRamCost);
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use getStockPrice()");
|
||||
checkTixApiAccess("getStockPrice");
|
||||
const stock = getStockFromSymbol(symbol, "getStockPrice");
|
||||
|
||||
return stock.price;
|
||||
},
|
||||
getStockAskPrice : function(symbol) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("getStockAskPrice", CONSTANTS.ScriptGetStockRamCost);
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into getStockPrice()");
|
||||
updateDynamicRam("getStockAskPrice", CONSTANTS.ScriptGetStockRamCost);
|
||||
checkTixApiAccess("getStockAskPrice");
|
||||
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) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("getStockPosition", CONSTANTS.ScriptGetStockRamCost);
|
||||
}
|
||||
updateDynamicRam("getStockPosition", CONSTANTS.ScriptGetStockRamCost);
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use getStockPosition()");
|
||||
}
|
||||
checkTixApiAccess("getStockPosition");
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into getStockPosition()");
|
||||
@ -1623,29 +1662,66 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("getStockMaxShares", CONSTANTS.ScriptGetStockRamCost);
|
||||
}
|
||||
updateDynamicRam("getStockMaxShares", CONSTANTS.ScriptGetStockRamCost);
|
||||
|
||||
if (!Player.hasTixApiAccess) {
|
||||
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()");
|
||||
}
|
||||
checkTixApiAccess("getStockMaxShares");
|
||||
const stock = getStockFromSymbol(symbol, "getStockMaxShares");
|
||||
|
||||
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) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("buyStock", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
}
|
||||
updateDynamicRam("buyStock", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use buyStock()");
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into buyStock()");
|
||||
}
|
||||
checkTixApiAccess("buyStock");
|
||||
const stock = getStockFromSymbol(symbol, "buyStock");
|
||||
const res = buyStock(stock, shares, workerScript);
|
||||
|
||||
return res ? stock.price : 0;
|
||||
@ -1655,77 +1731,57 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("sellStock", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
}
|
||||
updateDynamicRam("sellStock", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use sellStock()");
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into sellStock()");
|
||||
}
|
||||
|
||||
checkTixApiAccess("sellStock");
|
||||
const stock = getStockFromSymbol(symbol, "sellStock");
|
||||
const res = sellStock(stock, shares, workerScript);
|
||||
|
||||
return res ? stock.price : 0;
|
||||
},
|
||||
shortStock(symbol, shares) {
|
||||
shortStock : function(symbol, shares) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("shortStock", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
}
|
||||
updateDynamicRam("shortStock", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use shortStock()");
|
||||
}
|
||||
checkTixApiAccess("shortStock");
|
||||
if (Player.bitNodeN !== 8) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into shortStock()");
|
||||
}
|
||||
const stock = getStockFromSymbol(symbol, "shortStock");
|
||||
const res = shortStock(stock, shares, workerScript);
|
||||
|
||||
return res ? stock.price : 0;
|
||||
},
|
||||
sellShort(symbol, shares) {
|
||||
sellShort : function(symbol, shares) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("sellShort", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
}
|
||||
updateDynamicRam("sellShort", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use sellShort()");
|
||||
}
|
||||
checkTixApiAccess("sellShort");
|
||||
if (Player.bitNodeN !== 8) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into sellShort()");
|
||||
}
|
||||
const stock = getStockFromSymbol(symbol, "sellShort");
|
||||
const res = sellShort(stock, shares, workerScript);
|
||||
|
||||
return res ? stock.price : 0;
|
||||
},
|
||||
placeOrder(symbol, shares, price, type, pos) {
|
||||
placeOrder : function(symbol, shares, price, type, pos) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("placeOrder", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
}
|
||||
updateDynamicRam("placeOrder", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use placeOrder()");
|
||||
}
|
||||
checkTixApiAccess("placeOrder");
|
||||
if (Player.bitNodeN !== 8) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into placeOrder()");
|
||||
}
|
||||
const stock = getStockFromSymbol(symbol, "placeOrder");
|
||||
|
||||
var orderType, orderPos;
|
||||
type = type.toLowerCase();
|
||||
if (type.includes("limit") && type.includes("buy")) {
|
||||
@ -1751,23 +1807,18 @@ function NetscriptFunctions(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) {
|
||||
return updateStaticRam("cancelOrder", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
}
|
||||
updateDynamicRam("cancelOrder", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use cancelOrder()");
|
||||
}
|
||||
checkTixApiAccess("cancelOrder");
|
||||
if (Player.bitNodeN !== 8) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into cancelOrder()");
|
||||
}
|
||||
const stock = getStockFrom(symbol, "cancelOrder");
|
||||
if (isNaN(shares) || isNaN(price)) {
|
||||
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) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have 4S Market Data TIX API Access! Cannot use getStockVolatility()");
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into getStockVolatility()");
|
||||
}
|
||||
const stock = getStockFromSymbol(symbol, "getStockVolatility");
|
||||
|
||||
return stock.mv / 100; // Convert from percentage to decimal
|
||||
},
|
||||
getStockForecast : function(symbol) {
|
||||
@ -1858,10 +1907,8 @@ function NetscriptFunctions(workerScript) {
|
||||
if (!Player.has4SDataTixApi) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have 4S Market Data TIX API Access! Cannot use getStockForecast()");
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into getStockForecast()");
|
||||
}
|
||||
const stock = getStockFromSymbol(symbol, "getStockForecast");
|
||||
|
||||
var forecast = 50;
|
||||
stock.b ? forecast += stock.otlkMag : forecast -= stock.otlkMag;
|
||||
return forecast / 100; // Convert from percentage to decimal
|
||||
@ -1871,10 +1918,7 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("purchase4SMarketData", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
}
|
||||
updateDynamicRam("purchase4SMarketData", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use purchase4SMarketData()");
|
||||
}
|
||||
checkTixApiAccess("purchase4SMarketData");
|
||||
|
||||
if (Player.has4SData) {
|
||||
if (workerScript.shouldLog("purchase4SMarketData")) {
|
||||
@ -1902,10 +1946,7 @@ function NetscriptFunctions(workerScript) {
|
||||
return updateStaticRam("purchase4SMarketDataTixApi", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
}
|
||||
updateDynamicRam("purchase4SMarketDataTixApi", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use purchase4SMarketDataTixApi()");
|
||||
}
|
||||
checkTixApiAccess("purchase4SMarketDataTixApi");
|
||||
|
||||
if (Player.has4SDataTixApi) {
|
||||
if (workerScript.shouldLog("purchase4SMarketDataTixApi")) {
|
||||
|
@ -182,7 +182,7 @@ export class Stock {
|
||||
this.totalShares = Math.round(totalSharesUnrounded / 1e5) * 1e5;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 1,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 10e3,
|
||||
min: 5e3,
|
||||
max: 30e3,
|
||||
min: 10e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.AevumECorp],
|
||||
},
|
||||
@ -59,8 +59,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 1,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 10e3,
|
||||
min: 5e3,
|
||||
max: 30e3,
|
||||
min: 10e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.Sector12MegaCorp],
|
||||
},
|
||||
@ -85,8 +85,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 1,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 10e3,
|
||||
min: 5e3,
|
||||
max: 30e3,
|
||||
min: 10e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.Sector12BladeIndustries],
|
||||
},
|
||||
@ -111,8 +111,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 1,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 10e3,
|
||||
min: 5e3,
|
||||
max: 30e3,
|
||||
min: 10e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.AevumClarkeIncorporated],
|
||||
},
|
||||
@ -137,8 +137,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 1,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 10e3,
|
||||
min: 5e3,
|
||||
max: 30e3,
|
||||
min: 10e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.VolhavenOmniTekIncorporated],
|
||||
},
|
||||
@ -163,8 +163,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 1,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 10e3,
|
||||
min: 5e3,
|
||||
max: 30e3,
|
||||
min: 10e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.Sector12FourSigma],
|
||||
},
|
||||
@ -189,8 +189,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 1,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 10e3,
|
||||
min: 5e3,
|
||||
max: 30e3,
|
||||
min: 10e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.ChongqingKuaiGongInternational],
|
||||
},
|
||||
@ -215,8 +215,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 1,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 10e3,
|
||||
min: 5e3,
|
||||
max: 30e3,
|
||||
min: 10e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.AevumFulcrumTechnologies],
|
||||
},
|
||||
@ -241,8 +241,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 2,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 12e3,
|
||||
min: 6e3,
|
||||
max: 36e3,
|
||||
min: 12e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.IshimaStormTechnologies],
|
||||
},
|
||||
@ -267,8 +267,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 2,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 12e3,
|
||||
min: 6e3,
|
||||
max: 36e3,
|
||||
min: 12e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.NewTokyoDefComm],
|
||||
},
|
||||
@ -293,8 +293,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 2,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 12e3,
|
||||
min: 6e3,
|
||||
max: 36e3,
|
||||
min: 12e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.VolhavenHeliosLabs],
|
||||
},
|
||||
@ -319,8 +319,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 2,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 12e3,
|
||||
min: 6e3,
|
||||
max: 36e3,
|
||||
min: 12e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.NewTokyoVitaLife],
|
||||
},
|
||||
@ -345,8 +345,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 3,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 12e3,
|
||||
min: 6e3,
|
||||
max: 36e3,
|
||||
min: 12e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.Sector12IcarusMicrosystems],
|
||||
},
|
||||
@ -371,8 +371,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 2,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 12e3,
|
||||
min: 6e3,
|
||||
max: 36e3,
|
||||
min: 12e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.Sector12UniversalEnergy],
|
||||
},
|
||||
@ -397,8 +397,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 3,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 14e3,
|
||||
min: 7e3,
|
||||
max: 42e3,
|
||||
min: 14e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.AevumAeroCorp],
|
||||
},
|
||||
@ -423,8 +423,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 4,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 14e3,
|
||||
min: 7e3,
|
||||
max: 42e3,
|
||||
min: 14e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.VolhavenOmniaCybersystems],
|
||||
},
|
||||
@ -449,8 +449,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 4,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 14e3,
|
||||
min: 7e3,
|
||||
max: 42e3,
|
||||
min: 14e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.ChongqingSolarisSpaceSystems],
|
||||
},
|
||||
@ -475,8 +475,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 4,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 14e3,
|
||||
min: 7e3,
|
||||
max: 42e3,
|
||||
min: 14e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.NewTokyoGlobalPharmaceuticals],
|
||||
},
|
||||
@ -501,8 +501,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 4,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 14e3,
|
||||
min: 7e3,
|
||||
max: 42e3,
|
||||
min: 14e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.IshimaNovaMedical],
|
||||
},
|
||||
@ -527,8 +527,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 5,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 6e3,
|
||||
min: 2e3,
|
||||
max: 18e3,
|
||||
min: 4e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.AevumWatchdogSecurity],
|
||||
},
|
||||
@ -553,8 +553,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 5,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 12e3,
|
||||
min: 6e3,
|
||||
max: 36e3,
|
||||
min: 12e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.VolhavenLexoCorp],
|
||||
},
|
||||
@ -579,8 +579,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 3,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 20e3,
|
||||
min: 10e3,
|
||||
max: 42e3,
|
||||
min: 20e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.AevumRhoConstruction],
|
||||
},
|
||||
@ -605,8 +605,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 5,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 10e3,
|
||||
min: 5e3,
|
||||
max: 30e3,
|
||||
min: 10e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.Sector12AlphaEnterprises],
|
||||
},
|
||||
@ -631,8 +631,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 5,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 10e3,
|
||||
min: 5e3,
|
||||
max: 30e3,
|
||||
min: 10e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.VolhavenSysCoreSecurities],
|
||||
},
|
||||
@ -657,8 +657,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 4,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 15e3,
|
||||
min: 10e3,
|
||||
max: 42e3,
|
||||
min: 20e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.VolhavenCompuTek],
|
||||
},
|
||||
@ -683,8 +683,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 5,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 6e3,
|
||||
min: 3e3,
|
||||
max: 18e3,
|
||||
min: 6e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.AevumNetLinkTechnologies],
|
||||
},
|
||||
@ -709,8 +709,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 4,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 10e3,
|
||||
min: 5e3,
|
||||
max: 30e3,
|
||||
min: 10e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.IshimaOmegaSoftware],
|
||||
},
|
||||
@ -735,8 +735,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 6,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 20e3,
|
||||
min: 10e3,
|
||||
max: 60e3,
|
||||
min: 20e3,
|
||||
},
|
||||
symbol: StockSymbols[LocationName.Sector12FoodNStuff],
|
||||
},
|
||||
@ -761,8 +761,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 6,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 8e3,
|
||||
min: 4e3,
|
||||
max: 28e3,
|
||||
min: 8e3,
|
||||
},
|
||||
symbol: StockSymbols["Sigma Cosmetics"],
|
||||
},
|
||||
@ -787,8 +787,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 6,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 7e3,
|
||||
min: 3e3,
|
||||
max: 21e3,
|
||||
min: 6e3,
|
||||
},
|
||||
symbol: StockSymbols["Joes Guns"],
|
||||
},
|
||||
@ -813,8 +813,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 5,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 8e3,
|
||||
min: 4e3,
|
||||
max: 24e3,
|
||||
min: 8e3,
|
||||
},
|
||||
symbol: StockSymbols["Catalyst Ventures"],
|
||||
},
|
||||
@ -839,8 +839,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 3,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 25e3,
|
||||
min: 15e3,
|
||||
max: 72e3,
|
||||
min: 30e3,
|
||||
},
|
||||
symbol: StockSymbols["Microdyne Technologies"],
|
||||
},
|
||||
@ -865,8 +865,8 @@ export const InitStockMetadata: IConstructorParams[] = [
|
||||
min: 2,
|
||||
},
|
||||
shareTxForMovement: {
|
||||
max: 25e3,
|
||||
min: 15e3,
|
||||
max: 72e3,
|
||||
min: 30e3,
|
||||
},
|
||||
symbol: StockSymbols["Titan Laboratories"],
|
||||
},
|
||||
|
@ -39,16 +39,6 @@ export class InfoAndPurchases extends React.Component<IProps, any> {
|
||||
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() {
|
||||
dialogBoxCreate(
|
||||
"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 qty: number = this.getQuantity();
|
||||
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 ""; }
|
||||
|
||||
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;
|
||||
if (causesMovement) {
|
||||
@ -130,10 +132,22 @@ export class StockTicker extends React.Component<IProps, IState> {
|
||||
const stock = this.props.stock;
|
||||
const qty: number = this.getQuantity();
|
||||
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 ""; }
|
||||
|
||||
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;
|
||||
if (causesMovement) {
|
||||
@ -264,7 +278,7 @@ export class StockTicker extends React.Component<IProps, IState> {
|
||||
handlePositionTypeChange(e: React.ChangeEvent<HTMLSelectElement>) {
|
||||
const val = e.target.value;
|
||||
|
||||
if (val === "Short") {
|
||||
if (val === PositionTypes.Short) {
|
||||
this.setState({
|
||||
position: PositionTypes.Short,
|
||||
});
|
||||
@ -369,19 +383,19 @@ export class StockTicker extends React.Component<IProps, IState> {
|
||||
panelContent={
|
||||
<div>
|
||||
<input
|
||||
className={"stock-market-input"}
|
||||
className="stock-market-input"
|
||||
onChange={this.handleQuantityChange}
|
||||
placeholder={"Quantity (Shares)"}
|
||||
placeholder="Quantity (Shares)"
|
||||
value={this.state.qty}
|
||||
/>
|
||||
<select className={"stock-market-input dropdown"} onChange={this.handlePositionTypeChange} value={this.state.position}>
|
||||
<option value={"Long"}>Long</option>
|
||||
<select className="stock-market-input dropdown" onChange={this.handlePositionTypeChange} value={this.state.position}>
|
||||
<option value={PositionTypes.Long}>Long</option>
|
||||
{
|
||||
this.hasShortAccess() &&
|
||||
<option value={"Short"}>Short</option>
|
||||
<option value={PositionTypes.Short}>Short</option>
|
||||
}
|
||||
</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>
|
||||
{
|
||||
this.hasOrderAccess() &&
|
||||
@ -402,7 +416,7 @@ export class StockTicker extends React.Component<IProps, IState> {
|
||||
<p className="stock-market-price-movement-warning">
|
||||
WARNING: Buying/Selling {numeralWrapper.formatBigNumber(qty)} shares will affect
|
||||
the stock's price. This applies during the transaction itself as well. See Investopedia
|
||||
for more details.
|
||||
for more details.
|
||||
</p>
|
||||
}
|
||||
<StockTickerPositionText p={this.props.p} stock={this.props.stock} />
|
||||
|
@ -32,7 +32,7 @@ export class StockTickerPositionText extends React.Component<IProps, any> {
|
||||
return (
|
||||
<div>
|
||||
<h3 className={"tooltip"}>
|
||||
Short Position:
|
||||
Long Position:
|
||||
<span className={"tooltiptext"}>
|
||||
Shares in the long position will increase in value if the price
|
||||
of the corresponding stock increases
|
||||
|
Loading…
Reference in New Issue
Block a user