mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-18 21:53:50 +01:00
Merge pull request #438 from danielyxie/stock-market-update
Stock market update
This commit is contained in:
commit
c8158e1d19
@ -552,6 +552,17 @@
|
||||
#stock-market-container {
|
||||
position: fixed;
|
||||
padding: 6px;
|
||||
p {
|
||||
font-size: $defaultFontSize * 0.8125;
|
||||
}
|
||||
a {
|
||||
font-size: $defaultFontSize * 0.875;
|
||||
}
|
||||
h2 {
|
||||
margin-top:10px;
|
||||
margin-left:10px;
|
||||
display:block;
|
||||
}
|
||||
}
|
||||
|
||||
#stock-market-container p {
|
||||
@ -564,6 +575,11 @@
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
#stock-market-watchlist-filter {
|
||||
width:50%;
|
||||
margin-left:10px;
|
||||
}
|
||||
|
||||
.stock-market-input {
|
||||
display: inline-block;
|
||||
padding: 4px;
|
||||
|
@ -310,11 +310,23 @@ a:visited {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.help-tip:hover {
|
||||
.help-tip-big {
|
||||
content: '?';
|
||||
padding: 3px;
|
||||
margin-left: 3px;
|
||||
color: #fff;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 8px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.help-tip:hover,
|
||||
.help-tip-big:hover {
|
||||
background-color: #888;
|
||||
}
|
||||
|
||||
.help-tip:active {
|
||||
.help-tip:active,
|
||||
.help-tip-big:active {
|
||||
@include boxShadow(inset 0 1px 4px rgba(0, 0, 0, 0.6));
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,9 @@ getActionEstimatedSuccessChance
|
||||
:param string type: Type of action. See :ref:`bladeburner_action_types`
|
||||
:param string name: Name of action. Must be an exact match
|
||||
|
||||
Returns the estimated success chance for the specified action
|
||||
Returns the estimated success chance for the specified action. This chance
|
||||
is returned as a decimal value, NOT a percentage (e.g. if you have an estimated
|
||||
success chance of 80%, then this function will return 0.80, NOT 80).
|
||||
|
||||
getActionCountRemaining
|
||||
-----------------------
|
||||
|
@ -172,3 +172,38 @@ cancelOrder
|
||||
Cancels an oustanding Limit or Stop order on the stock market.
|
||||
|
||||
The ability to use limit and stop orders is **not** immediately available to the player and must be unlocked later on in the game.
|
||||
|
||||
getStockVolatility
|
||||
------------------
|
||||
|
||||
.. js:function:: getStockVolatility(sym)
|
||||
|
||||
:param string sym: Symbol of stock
|
||||
|
||||
Returns the volatility of the specified stock.
|
||||
|
||||
Volatility represents the maximum percentage by which a stock's price can
|
||||
change every tick. The volatility is returned as a decimal value, NOT
|
||||
a percentage (e.g. if a stock has a volatility of 3%, then this function will
|
||||
return 0.03, NOT 3).
|
||||
|
||||
In order to use this function, you must first purchase access to the Four Sigma (4S)
|
||||
Market Data TIX API.
|
||||
|
||||
getStockForecast
|
||||
----------------
|
||||
|
||||
.. js:function:: getStockForecast(sym)
|
||||
|
||||
:param string sym: Symbol of stock
|
||||
|
||||
Returns the probability that the specified stock's price will increase
|
||||
(as opposed to decrease) during the next tick.
|
||||
|
||||
The probability is returned as a decimal value, NOT a percentage (e.g. if a
|
||||
stock has a 60% chance of increasing, then this function will return 0.6,
|
||||
NOT 60).
|
||||
|
||||
In other words, if this function returned 0.30 for a stock, then this means
|
||||
that the stock's price has a 30% chance of increasing and a 70% chance of
|
||||
decreasing during the next tick.
|
||||
|
34
index.html
34
index.html
@ -679,22 +679,44 @@
|
||||
after you 'reset' by installing Augmentations.
|
||||
</p>
|
||||
<a id="stock-market-buy-account" class="a-link-button-inactive"> Buy WSE Account </a>
|
||||
<a id="stock-market-investopedia" class="a-link-button">Investopedia</a>
|
||||
|
||||
<h2> Trade Information eXchange (TIX) API </h2>
|
||||
<p>
|
||||
You can also purchase access to the World Stock Exchange's TIX API! TIX, short for
|
||||
Trade Information eXchange, is the communications protocol supported by the WSE.
|
||||
<br><br>
|
||||
Gaining access to the TIX API lets you write code to build automated trading
|
||||
systems. In other words, you can create your own algorithmic trading strategies!
|
||||
TIX, short for Trade Information eXchange, is the communications protocol supported by the WSE.
|
||||
Purchasing access to the TIX API lets you write code to create your own algorithmic/automated
|
||||
trading strategies.
|
||||
<br><br>
|
||||
If you purchase access to the TIX API, you will retain that access even after
|
||||
you 'reset' by installing Augmentations.
|
||||
</p>
|
||||
<a id="stock-market-buy-tix-api" class="a-link-button-inactive">Buy Trade Information eXchange (TIX) API Access</a>
|
||||
<a id="stock-market-investopedia" class="a-link-button">Investopedia</a>
|
||||
|
||||
<h2> Four Sigma (4S) Market Data Feed </h2>
|
||||
<p>
|
||||
Four Sigma's (4S) Market Data Feed provides information about stocks
|
||||
that will help your trading strategies.
|
||||
<br><br>
|
||||
If you purchase access to 4S Market Data and/or the 4S TIX API, you will
|
||||
retain that access even after you 'reset' by installing Augmentations.
|
||||
</p>
|
||||
|
||||
<a id="stock-market-buy-4s-data" class="a-link-button-inactive tooltip">
|
||||
Buy 4S Market Data Feed
|
||||
</a>
|
||||
<div class="help-tip-big" id="stock-market-4s-data-help-tip">?</div>
|
||||
|
||||
<a id="stock-market-buy-4s-tix-api" class="a-link-button-inactive tooltip">
|
||||
Buy 4S Market Data TIX API Access
|
||||
</a>
|
||||
|
||||
<p id="stock-market-commission"> </p>
|
||||
<a id="stock-market-mode" class="a-link-button tooltip"></a>
|
||||
<a id="stock-market-expand-tickers" class="a-link-button tooltip">Expand tickers</a>
|
||||
<a id="stock-market-collapse-tickers" class="a-link-button tooltip">Collapse tickers</a>
|
||||
<br><br>
|
||||
<input id="stock-market-watchlist-filter" type="text" placeholder="Filter Stocks by symbol (comma-separated list)"> </input>
|
||||
<a id="stock-market-watchlist-filter-update" class="a-link-button"> Update Watchlist </a>
|
||||
<ul id="stock-market-list" style="list-style:none;">
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -101,5 +101,5 @@
|
||||
"watch": "webpack --watch --mode production",
|
||||
"watch:dev": "webpack --watch --mode development"
|
||||
},
|
||||
"version": "0.35.1"
|
||||
"version": "0.40.2"
|
||||
}
|
||||
|
@ -115,6 +115,8 @@ let CONSTANTS = {
|
||||
//Stock market constants
|
||||
WSEAccountCost: 200e6,
|
||||
TIXAPICost: 5e9,
|
||||
MarketData4SCost: 1e9,
|
||||
MarketDataTixApi4SCost: 20e9,
|
||||
StockMarketCommission: 100e3,
|
||||
|
||||
//Hospital/Health
|
||||
@ -492,9 +494,9 @@ let CONSTANTS = {
|
||||
|
||||
LatestUpdate:
|
||||
"v0.40.2<br>" +
|
||||
"------------------------------<br>" +
|
||||
"* Bladeburner Changes:<br>" +
|
||||
"*** Added getSkillUpgradeCost() Netscript function to the API<br>" +
|
||||
"*** Added getBonusTime() Netscript function to the API<br>" +
|
||||
"*** Added getBonusTime(), getSkillUpgradeCost(), and getCity() Netscript functions to the API<br>" +
|
||||
"*** Buffed the effects of many Bladeburner Augmentations<br>" +
|
||||
"*** The Blade's Simulacrum Augmentation requires significantly less reputation but slightly more money<br>" +
|
||||
"*** Slightly increased the amount of successes needed for a Contract/Operation in order to increase its max level<br>" +
|
||||
@ -504,6 +506,12 @@ let CONSTANTS = {
|
||||
"*** The number (count) of Operations should now increase significantly faster<br>" +
|
||||
"*** There are now, on average, more Synthoid communities in a city<br>" +
|
||||
"*** If automation is enabled (the feature in Bladeburner console), then switching to another action such as working for a company will now disable the automation<br>" +
|
||||
"------------------------------<br>" +
|
||||
"* Stock Market Changes:<br>" +
|
||||
"***Added a watchlist filter feature to the UI that allows you to specify which stocks to show<br>" +
|
||||
"***Added the Four Sigma (4S) Market Data feed, which provides volatility and price forecast information about stocks<br>" +
|
||||
"***Added the 4S Market Data TIX API, which lets you access the aforementioned data through Netscript<br>" +
|
||||
"------------------------------<br>" +
|
||||
"* There is now a setting for enabling/disabling the popup that appears when you are hospitalized<br>" +
|
||||
"* Bug Fix: Stock market should now be correctly initialized in BitNode-8 (by Kline-)<br>" +
|
||||
"* Bug Fix: bladeburner.getCurrentAction() should now properly an 'Idle' object rather than null (by Kline-)<br>" +
|
||||
|
@ -1599,6 +1599,36 @@ function NetscriptFunctions(workerScript) {
|
||||
};
|
||||
return cancelOrder(params, workerScript);
|
||||
},
|
||||
getStockVolatility : function(symbol) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("getStockVolatility", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
}
|
||||
updateDynamicRam("getStockVolatility", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
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()");
|
||||
}
|
||||
return stock.mv / 100; //Convert from percentage to decimal
|
||||
},
|
||||
getStockForecast : function(symbol) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("getStockForecast", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
}
|
||||
updateDynamicRam("getStockForecast", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
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()");
|
||||
}
|
||||
var forecast = 50;
|
||||
stock.b ? forecast += stock.otlkMag : forecast -= stock.otlkMag;
|
||||
return forecast / 100; //Convert from percentage to decimal
|
||||
},
|
||||
getPurchasedServerLimit : function() {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("getPurchasedServerLimit", CONSTANTS.ScriptGetPurchasedServerLimit);
|
||||
@ -3744,6 +3774,21 @@ function NetscriptFunctions(workerScript) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "getCityChaos() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
|
||||
"at the Bladeburner division or because you do not have Source-File 7");
|
||||
},
|
||||
getCity : function() {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("getCity", CONSTANTS.ScriptBladeburnerApiBaseRamCost);
|
||||
}
|
||||
updateDynamicRam("getCity", CONSTANTS.ScriptBladeburnerApiBaseRamCost);
|
||||
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
|
||||
try {
|
||||
return Player.bladeburner.city;
|
||||
} catch(e) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Bladeburner.getCity() failed with exception: " + e);
|
||||
}
|
||||
}
|
||||
throw makeRuntimeRejectMsg(workerScript, "getCity() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
|
||||
"at the Bladeburner division or because you do not have Source-File 7");
|
||||
},
|
||||
switchCity : function(cityName) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("switchCity", CONSTANTS.ScriptBladeburnerApiBaseRamCost);
|
||||
|
@ -173,6 +173,8 @@ function PlayerObject() {
|
||||
//Stock Market
|
||||
this.hasWseAccount = false;
|
||||
this.hasTixApiAccess = false;
|
||||
this.has4SData = false;
|
||||
this.has4SDataTixApi = false;
|
||||
|
||||
//Gang
|
||||
this.gang = 0;
|
||||
|
@ -10,7 +10,11 @@ import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver";
|
||||
import {Page, routing} from "./ui/navigationTracking";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {exceptionAlert} from "../utils/helpers/exceptionAlert";
|
||||
import {getRandomInt} from "../utils/helpers/getRandomInt";
|
||||
import {KEY} from "../utils/helpers/keyCodes";
|
||||
import {createElement} from "../utils/uiHelpers/createElement";
|
||||
import {removeChildrenFromElement} from "../utils/uiHelpers/removeChildrenFromElement";
|
||||
import {removeElementById} from "../utils/uiHelpers/removeElementById";
|
||||
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
|
||||
@ -409,6 +413,7 @@ function stockMarketCycle() {
|
||||
for (var name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
var stock = StockMarket[name];
|
||||
if (!(stock instanceof Stock)) {continue;}
|
||||
var thresh = 0.6;
|
||||
if (stock.b) {thresh = 0.4;}
|
||||
if (Math.random() < thresh) {
|
||||
@ -693,20 +698,31 @@ var stockMarketContentCreated = false;
|
||||
var stockMarketPortfolioMode = false;
|
||||
var COMM = CONSTANTS.StockMarketCommission;
|
||||
function displayStockMarketContent() {
|
||||
if (Player.hasWseAccount == null) {Player.hasWseAccount = false;}
|
||||
if (Player.hasWseAccount == null) {Player.hasWseAccount = false;}
|
||||
if (Player.hasTixApiAccess == null) {Player.hasTixApiAccess = false;}
|
||||
if (Player.has4SData == null) {Player.has4SData = false;}
|
||||
if (Player.has4SDataTixApi == null) {Player.has4SDataTixApi = false;}
|
||||
|
||||
function stylePurchaseButton(btn, cost, flag, initMsg, purchasedMsg) {
|
||||
btn.innerText = initMsg;
|
||||
btn.classList.remove("a-link-button");
|
||||
btn.classList.remove("a-link-button-bought");
|
||||
btn.classList.remove("a-link-button-inactive");
|
||||
if (!flag && Player.money.gte(cost)) {
|
||||
btn.classList.add("a-link-button");
|
||||
} else if (flag) {
|
||||
btn.innerText = purchasedMsg;
|
||||
btn.classList.add("a-link-button-bought");
|
||||
} else {
|
||||
btn.classList.add("a-link-button-inactive");
|
||||
}
|
||||
}
|
||||
|
||||
//Purchase WSE Account button
|
||||
var wseAccountButton = clearEventListeners("stock-market-buy-account");
|
||||
wseAccountButton.innerText = "Buy WSE Account - " + numeral(CONSTANTS.WSEAccountCost).format('($0.000a)');
|
||||
if (!Player.hasWseAccount && Player.money.gte(CONSTANTS.WSEAccountCost)) {
|
||||
wseAccountButton.setAttribute("class", "a-link-button");
|
||||
} else if (Player.hasWseAccount){
|
||||
wseAccountButton.innerText = "WSE Account - Purchased";
|
||||
wseAccountButton.setAttribute("class", "a-link-button-bought");
|
||||
} else {
|
||||
wseAccountButton.setAttribute("class", "a-link-button-inactive");
|
||||
}
|
||||
stylePurchaseButton(wseAccountButton, CONSTANTS.WSEAccountCost, Player.hasWseAccount,
|
||||
"Buy WSE Account - " + numeral(CONSTANTS.WSEAccountCost).format('($0.000a)'),
|
||||
"WSE Account - Purchased");
|
||||
wseAccountButton.addEventListener("click", function() {
|
||||
Player.hasWseAccount = true;
|
||||
initStockMarket();
|
||||
@ -718,16 +734,9 @@ function displayStockMarketContent() {
|
||||
|
||||
//Purchase TIX API Access account
|
||||
var tixApiAccessButton = clearEventListeners("stock-market-buy-tix-api");
|
||||
tixApiAccessButton.innerText = "Buy Trade Information eXchange (TIX) API Access - " +
|
||||
numeral(CONSTANTS.TIXAPICost).format('($0.000a)');
|
||||
if (!Player.hasTixApiAccess && Player.money.gte(CONSTANTS.TIXAPICost)) {
|
||||
tixApiAccessButton.setAttribute("class", "a-link-button");
|
||||
} else if(Player.hasTixApiAccess) {
|
||||
tixApiAccessButton.innerText = "Trade Information eXchange (TIX) API Access - Purchased"
|
||||
tixApiAccessButton.setAttribute("class", "a-link-button-bought");
|
||||
} else {
|
||||
tixApiAccessButton.setAttribute("class", "a-link-button-inactive");
|
||||
}
|
||||
stylePurchaseButton(tixApiAccessButton, CONSTANTS.TIXAPICost, Player.hasTixApiAccess,
|
||||
"Buy Trade Information eXchange (TIX) API Access - " + numeral(CONSTANTS.TIXAPICost).format('($0.000a)'),
|
||||
"TIX API Access - Purchased");
|
||||
tixApiAccessButton.addEventListener("click", function() {
|
||||
Player.hasTixApiAccess = true;
|
||||
Player.loseMoney(CONSTANTS.TIXAPICost);
|
||||
@ -735,9 +744,76 @@ function displayStockMarketContent() {
|
||||
return false;
|
||||
});
|
||||
|
||||
//Purchase Four Sigma Market Data Feed
|
||||
var marketDataButton = clearEventListeners("stock-market-buy-4s-data");
|
||||
stylePurchaseButton(marketDataButton, CONSTANTS.MarketData4SCost, Player.has4SData,
|
||||
"Buy 4S Market Data Access - " + numeral(CONSTANTS.MarketData4SCost).format('($0.000a)'),
|
||||
"4S Market Data - Purchased");
|
||||
marketDataButton.addEventListener("click", function() {
|
||||
Player.has4SData = true;
|
||||
Player.loseMoney(CONSTANTS.MarketData4SCost);
|
||||
displayStockMarketContent();
|
||||
return false;
|
||||
});
|
||||
marketDataButton.appendChild(createElement("span", {
|
||||
class:"tooltiptext",
|
||||
innerText:"Lets you view additional pricing and volatility information about stocks"
|
||||
}));
|
||||
marketDataButton.style.marginRight = "2px"; //Adjusts following help tip to be slightly closer
|
||||
|
||||
//4S Market Data Help Tip
|
||||
var marketDataHelpTip = clearEventListeners("stock-market-4s-data-help-tip");
|
||||
marketDataHelpTip.style.marginTop = "10px";
|
||||
marketDataHelpTip.addEventListener("click", ()=>{
|
||||
dialogBoxCreate("Access to the 4S Market Data feed will display two additional pieces " +
|
||||
"of information about each stock: Price Forecast & Volatility<br><br>" +
|
||||
"Price Forecast indicates the probability the stock has of increasing or " +
|
||||
"decreasing. A '+' forecast means the stock has a higher chance of increasing " +
|
||||
"than decreasing, and a '-' means the opposite. The number of '+/-' symbols " +
|
||||
"is used to illustrate the magnitude of these probabilities. For example, " +
|
||||
"'+++' means that the stock has a significantly higher chance of increasing " +
|
||||
"than decreasing, while '+' means that the stock only has a slightly higher chance " +
|
||||
"of increasing than decreasing.<br><br>" +
|
||||
"Volatility represents the maximum percentage by which a stock's price " +
|
||||
"can change every tick (a tick occurs every few seconds while the game " +
|
||||
"is running).<br><br>" +
|
||||
"A stock's price forecast can change over time. This is also affected by volatility. " +
|
||||
"The more volatile a stock is, the more its price forecast will change.");
|
||||
return false;
|
||||
});
|
||||
|
||||
//Purchase Four Sigma Market Data TIX API (Requires TIX API Access)
|
||||
var marketDataTixButton = clearEventListeners("stock-market-buy-4s-tix-api");
|
||||
stylePurchaseButton(marketDataTixButton, CONSTANTS.MarketDataTixApi4SCost, Player.has4SDataTixApi,
|
||||
"Buy 4S Market Data TIX API Access - " + numeral(CONSTANTS.MarketDataTixApi4SCost).format('($0.000a)'),
|
||||
"4S Market Data TIX API - Purchased");
|
||||
if (Player.hasTixApiAccess) {
|
||||
marketDataTixButton.addEventListener("click", function() {
|
||||
Player.has4SDataTixApi = true;
|
||||
Player.loseMoney(CONSTANTS.MarketDataTixApi4SCost);
|
||||
displayStockMarketContent();
|
||||
return false;
|
||||
});
|
||||
marketDataTixButton.appendChild(createElement("span", {
|
||||
class:"tooltiptext",
|
||||
innerText:"Lets you access 4S Market Data through Netscript"
|
||||
}));
|
||||
} else {
|
||||
marketDataTixButton.classList.remove("a-link-button");
|
||||
marketDataTixButton.classList.remove("a-link-button-bought");
|
||||
marketDataTixButton.classList.remove("a-link-button-inactive");
|
||||
marketDataTixButton.classList.add("a-link-button-inactive");
|
||||
marketDataTixButton.appendChild(createElement("span", {
|
||||
class:"tooltiptext",
|
||||
innerText:"Requires TIX API Access"
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
var stockList = document.getElementById("stock-market-list");
|
||||
if (stockList == null) {return;}
|
||||
|
||||
//If Player doesn't have account, clear stocks UI and return
|
||||
if (!Player.hasWseAccount) {
|
||||
stockMarketContentCreated = false;
|
||||
while (stockList.firstChild) {
|
||||
@ -834,14 +910,32 @@ function displayStockMarketContent() {
|
||||
});
|
||||
}
|
||||
|
||||
for (var name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
var stock = StockMarket[name];
|
||||
if (!(stock instanceof Stock)) {continue;} //orders property is an array
|
||||
createStockTicker(stock);
|
||||
//Watchlish filter
|
||||
var watchlistFilter = clearEventListeners("stock-market-watchlist-filter");
|
||||
var watchlistUpdateBtn = clearEventListeners("stock-market-watchlist-filter-update");
|
||||
if (watchlistFilter && watchlistUpdateBtn) {
|
||||
//Initialize value in watchlist
|
||||
if (StockMarket.watchlistFilter) {
|
||||
watchlistFilter.value = StockMarket.watchlistFilter; //Remove whitespace
|
||||
}
|
||||
watchlistUpdateBtn.addEventListener("click", ()=> {
|
||||
let filterValue = watchlistFilter.value.toString();
|
||||
StockMarket.watchlistFilter = filterValue.replace(/\s/g, '');
|
||||
if (stockMarketPortfolioMode) {
|
||||
switchToPortfolioMode();
|
||||
} else {
|
||||
switchToDisplayAllMode();
|
||||
}
|
||||
});
|
||||
watchlistFilter.addEventListener("keyup", (e)=>{
|
||||
e.preventDefault();
|
||||
if (e.keyCode === KEY.ENTER) {watchlistUpdateBtn.click();}
|
||||
})
|
||||
} else {
|
||||
console.warn("Stock Market Watchlist DOM elements could not be found");
|
||||
}
|
||||
setStockTickerClickHandlers(); //Clicking headers opens/closes panels
|
||||
|
||||
createAllStockTickers();
|
||||
stockMarketContentCreated = true;
|
||||
}
|
||||
|
||||
@ -849,8 +943,10 @@ function displayStockMarketContent() {
|
||||
for (var name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
var stock = StockMarket[name];
|
||||
updateStockTicker(stock, null);
|
||||
updateStockOrderList(stock);
|
||||
if (stock instanceof Stock) {
|
||||
updateStockTicker(stock, null);
|
||||
updateStockOrderList(stock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -859,17 +955,34 @@ function displayStockMarketContent() {
|
||||
//Displays only stocks you have position/order in
|
||||
function switchToPortfolioMode() {
|
||||
stockMarketPortfolioMode = true;
|
||||
var stockList = document.getElementById("stock-market-list");
|
||||
if (stockList == null) {return;}
|
||||
var modeBtn = clearEventListeners("stock-market-mode");
|
||||
if (modeBtn) {
|
||||
modeBtn.innerHTML = "Switch to 'All stocks' Mode" +
|
||||
"<span class='tooltiptext'>Displays all stocks on the WSE</span>";
|
||||
modeBtn.addEventListener("click", switchToDisplayAllMode);
|
||||
}
|
||||
while(stockList.firstChild) {stockList.removeChild(stockList.firstChild);}
|
||||
createAllStockTickers();
|
||||
}
|
||||
|
||||
//Displays all stocks
|
||||
function switchToDisplayAllMode() {
|
||||
stockMarketPortfolioMode = false;
|
||||
var modeBtn = clearEventListeners("stock-market-mode");
|
||||
if (modeBtn) {
|
||||
modeBtn.innerHTML = "Switch to 'Portfolio' Mode" +
|
||||
"<span class='tooltiptext'>Displays only the stocks for which you have shares or orders</span>";
|
||||
modeBtn.addEventListener("click", switchToPortfolioMode);
|
||||
}
|
||||
createAllStockTickers();
|
||||
}
|
||||
|
||||
function createAllStockTickers() {
|
||||
var stockList = document.getElementById("stock-market-list");
|
||||
if (stockList == null) {
|
||||
exceptionAlert("Error creating Stock Tickers UI. DOM element with ID 'stock-market-list' could not be found");
|
||||
}
|
||||
removeChildrenFromElement(stockList);
|
||||
|
||||
//Get Order book (create it if it hasn't been created)
|
||||
var orderBook = StockMarket["Orders"];
|
||||
if (orderBook == null) {
|
||||
var orders = {};
|
||||
@ -881,41 +994,30 @@ function switchToPortfolioMode() {
|
||||
}
|
||||
}
|
||||
StockMarket["Orders"] = orders;
|
||||
orderBook = StockMarket["Orders"];
|
||||
}
|
||||
|
||||
let watchlist = null;
|
||||
if (StockMarket.watchlistFilter != null && StockMarket.watchlistFilter !== "") {
|
||||
let filter = StockMarket.watchlistFilter.replace(/\s/g, '');
|
||||
watchlist = filter.split(",");
|
||||
}
|
||||
|
||||
for (var name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
var stock = StockMarket[name];
|
||||
if (!(stock instanceof Stock)) {continue;} //orders property is an array
|
||||
var stockOrders = orderBook[stock.symbol];
|
||||
if (stock.playerShares === 0 && stock.playerShortShares === 0 &&
|
||||
stockOrders.length === 0) {continue;}
|
||||
createStockTicker(stock);
|
||||
}
|
||||
}
|
||||
setStockTickerClickHandlers();
|
||||
}
|
||||
if (watchlist && !watchlist.includes(stock.symbol)) {continue;} //Watchlist filtering
|
||||
|
||||
//Displays all stocks
|
||||
function switchToDisplayAllMode() {
|
||||
stockMarketPortfolioMode = false;
|
||||
var stockList = document.getElementById("stock-market-list");
|
||||
if (stockList == null) {return;}
|
||||
var modeBtn = clearEventListeners("stock-market-mode");
|
||||
if (modeBtn) {
|
||||
modeBtn.innerHTML = "Switch to 'Portfolio' Mode" +
|
||||
"<span class='tooltiptext'>Displays only the stocks for which you have shares or orders</span>";
|
||||
modeBtn.addEventListener("click", switchToPortfolioMode);
|
||||
}
|
||||
while(stockList.firstChild) {stockList.removeChild(stockList.firstChild);}
|
||||
for (var name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
var stock = StockMarket[name];
|
||||
if (!(stock instanceof Stock)) {continue;} //orders property is an array
|
||||
let stockOrders = orderBook[stock.symbol];
|
||||
if (stockMarketPortfolioMode) {
|
||||
if (stock.playerShares === 0 && stock.playerShortShares === 0 &&
|
||||
stockOrders.length === 0) {continue;}
|
||||
}
|
||||
createStockTicker(stock);
|
||||
}
|
||||
}
|
||||
setStockTickerClickHandlers();
|
||||
setStockTickerClickHandlers(); //Clicking headers opens/closes panels
|
||||
}
|
||||
|
||||
function createStockTicker(stock) {
|
||||
@ -1196,10 +1298,25 @@ function updateStockTicker(stock, increase) {
|
||||
var hdr = document.getElementById(tickerId + "-hdr");
|
||||
|
||||
if (hdr == null) {
|
||||
if (!stockMarketPortfolioMode) {console.log("ERROR: Couldn't find ticker element for stock: " + stock.symbol);}
|
||||
if (!stockMarketPortfolioMode) {
|
||||
let watchlist = StockMarket.watchlistFilter;
|
||||
if (watchlist !== "" && watchlist.includes(stock.symbol)) {
|
||||
console.log("ERROR: Couldn't find ticker element for stock: " + stock.symbol);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
hdr.innerHTML = stock.name + " - " + stock.symbol + " - " + numeral(stock.price).format('($0.000a)');
|
||||
let hdrText = stock.name + " (" + stock.symbol + ") - " + numeral(stock.price).format('($0.000a)');
|
||||
if (Player.has4SData) {
|
||||
hdrText += " - Volatility: " + numeral(stock.mv).format('0,0.00') + "%" +
|
||||
" - Price Forecast: ";
|
||||
if (stock.b) {
|
||||
hdrText += "+".repeat(Math.floor(stock.otlkMag/10) + 1);
|
||||
} else {
|
||||
hdrText += "-".repeat(Math.floor(stock.otlkMag/10) + 1);
|
||||
}
|
||||
}
|
||||
hdr.innerText = hdrText;
|
||||
if (increase != null) {
|
||||
increase ? hdr.style.color = "#66ff33" : hdr.style.color = "red";
|
||||
}
|
||||
@ -1280,7 +1397,13 @@ function updateStockOrderList(stock) {
|
||||
var tickerId = "stock-market-ticker-" + stock.symbol;
|
||||
var orderList = document.getElementById(tickerId + "-order-list");
|
||||
if (orderList == null) {
|
||||
if (!stockMarketPortfolioMode) {console.log("ERROR: Could not find order list for " + stock.symbol);}
|
||||
//Log only if its a valid error
|
||||
if (!stockMarketPortfolioMode) {
|
||||
let watchlist = StockMarket.watchlistFilter;
|
||||
if (watchlist !== "" && watchlist.includes(stock.symbol)) {
|
||||
console.log("ERROR: Could not find order list for " + stock.symbol);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user