2017-08-30 19:44:29 +02:00
|
|
|
import {CONSTANTS} from "./Constants.js";
|
|
|
|
import {Engine} from "./engine.js";
|
|
|
|
import {Locations} from "./Location.js";
|
|
|
|
import {Player} from "./Player.js";
|
|
|
|
|
|
|
|
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
|
|
|
import {clearEventListeners, getRandomInt} from "../utils/HelperFunctions.js";
|
|
|
|
import {Reviver} from "../utils/JSONReviver.js";
|
|
|
|
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
/* StockMarket.js */
|
|
|
|
function Stock(name, symbol, mv, b, otlkMag, initPrice=10000) {
|
|
|
|
this.symbol = symbol;
|
|
|
|
this.name = name;
|
|
|
|
this.price = initPrice;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
this.playerShares = 0;
|
|
|
|
this.playerAvgPx = 0;
|
|
|
|
this.mv = mv;
|
|
|
|
this.b = b;
|
|
|
|
this.otlkMag = otlkMag;
|
|
|
|
}
|
|
|
|
|
2017-08-30 19:44:29 +02:00
|
|
|
Stock.prototype.toJSON = function() {
|
|
|
|
return Generic_toJSON("Stock", this);
|
|
|
|
}
|
2017-07-03 21:42:11 +02:00
|
|
|
|
2017-08-30 19:44:29 +02:00
|
|
|
Stock.fromJSON = function(value) {
|
|
|
|
return Generic_fromJSON(Stock, value.data);
|
|
|
|
}
|
|
|
|
|
|
|
|
Reviver.constructors.Stock = Stock;
|
|
|
|
|
|
|
|
let StockMarket = {} //Full name to stock object
|
|
|
|
let StockSymbols = {} //Full name to symbol
|
|
|
|
let SymbolToStockMap = {}; //Symbol to Stock object
|
|
|
|
|
|
|
|
function loadStockMarket(saveString) {
|
|
|
|
if (saveString === "") {
|
|
|
|
StockMarket = {};
|
|
|
|
} else {
|
|
|
|
StockMarket = JSON.parse(saveString, Reviver);
|
|
|
|
}
|
|
|
|
}
|
2017-07-03 21:42:11 +02:00
|
|
|
|
|
|
|
function initStockSymbols() {
|
|
|
|
//Stocks for companies at which you can work
|
|
|
|
StockSymbols[Locations.AevumECorp] = "ECP";
|
|
|
|
StockSymbols[Locations.Sector12MegaCorp] = "MGCP";
|
|
|
|
StockSymbols[Locations.Sector12BladeIndustries] = "BLD";
|
|
|
|
StockSymbols[Locations.AevumClarkeIncorporated] = "CLRK";
|
|
|
|
StockSymbols[Locations.VolhavenOmniTekIncorporated] = "OMTK";
|
|
|
|
StockSymbols[Locations.Sector12FourSigma] = "FSIG";
|
|
|
|
StockSymbols[Locations.ChongqingKuaiGongInternational] = "KGI";
|
|
|
|
StockSymbols[Locations.AevumFulcrumTechnologies] = "FLCM";
|
|
|
|
StockSymbols[Locations.IshimaStormTechnologies] = "STM";
|
|
|
|
StockSymbols[Locations.NewTokyoDefComm] = "DCOMM";
|
|
|
|
StockSymbols[Locations.VolhavenHeliosLabs] = "HLS";
|
|
|
|
StockSymbols[Locations.NewTokyoVitaLife] = "VITA";
|
|
|
|
StockSymbols[Locations.Sector12IcarusMicrosystems] = "ICRS";
|
|
|
|
StockSymbols[Locations.Sector12UniversalEnergy] = "UNV";
|
|
|
|
StockSymbols[Locations.AevumAeroCorp] = "AERO";
|
|
|
|
StockSymbols[Locations.VolhavenOmniaCybersystems] = "OMN";
|
|
|
|
StockSymbols[Locations.ChongqingSolarisSpaceSystems] = "SLRS";
|
|
|
|
StockSymbols[Locations.NewTokyoGlobalPharmaceuticals] = "GPH";
|
|
|
|
StockSymbols[Locations.IshimaNovaMedical] = "NVMD";
|
|
|
|
StockSymbols[Locations.AevumWatchdogSecurity] = "WDS";
|
|
|
|
StockSymbols[Locations.VolhavenLexoCorp] = "LXO";
|
|
|
|
StockSymbols[Locations.AevumRhoConstruction] = "RHOC";
|
|
|
|
StockSymbols[Locations.Sector12AlphaEnterprises] = "APHE";
|
|
|
|
StockSymbols[Locations.VolhavenSysCoreSecurities] = "SYSC";
|
|
|
|
StockSymbols[Locations.VolhavenCompuTek] = "CTK";
|
|
|
|
StockSymbols[Locations.AevumNetLinkTechnologies] = "NTLK";
|
|
|
|
StockSymbols[Locations.IshimaOmegaSoftware] = "OMGA";
|
|
|
|
StockSymbols[Locations.Sector12FoodNStuff] = "FNS";
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
//Stocks for other companies
|
|
|
|
StockSymbols["Sigma Cosmetics"] = "SGC";
|
|
|
|
StockSymbols["Joes Guns"] = "JGN";
|
|
|
|
StockSymbols["Catalyst Ventures"] = "CTYS";
|
|
|
|
StockSymbols["Taiyang Digital"] = "TAI";
|
|
|
|
StockSymbols["Microdyne Technologies"] = "MDYN";
|
|
|
|
StockSymbols["Titan Laboratories"] = "TITN";
|
|
|
|
}
|
|
|
|
|
|
|
|
function initStockMarket() {
|
2017-07-22 00:54:55 +02:00
|
|
|
for (var stk in StockMarket) {
|
|
|
|
if (StockMarket.hasOwnProperty(stk)) {
|
|
|
|
delete StockMarket[stk];
|
|
|
|
}
|
|
|
|
}
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var ecorp = Locations.AevumECorp;
|
2017-07-06 00:33:46 +02:00
|
|
|
var ecorpStk = new Stock(ecorp, StockSymbols[ecorp], 0.5, true, 16, getRandomInt(20000, 25000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[ecorp] = ecorpStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var megacorp = Locations.Sector12MegaCorp;
|
2017-07-06 00:33:46 +02:00
|
|
|
var megacorpStk = new Stock(megacorp, StockSymbols[megacorp], 0.5, true, 16, getRandomInt(25000, 33000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[megacorp] = megacorpStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var blade = Locations.Sector12BladeIndustries;
|
2017-07-06 00:33:46 +02:00
|
|
|
var bladeStk = new Stock(blade, StockSymbols[blade], 0.75, true, 13, getRandomInt(15000, 22000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[blade] = bladeStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var clarke = Locations.AevumClarkeIncorporated;
|
2017-07-06 00:33:46 +02:00
|
|
|
var clarkeStk = new Stock(clarke, StockSymbols[clarke], 0.7, true, 12, getRandomInt(15000, 20000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[clarke] = clarkeStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var omnitek = Locations.VolhavenOmniTekIncorporated;
|
2017-07-06 00:33:46 +02:00
|
|
|
var omnitekStk = new Stock(omnitek, StockSymbols[omnitek], 0.65, true, 12, getRandomInt(35000, 40000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[omnitek] = omnitekStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var foursigma = Locations.Sector12FourSigma;
|
2017-07-06 00:33:46 +02:00
|
|
|
var foursigmaStk = new Stock(foursigma, StockSymbols[foursigma], 1.1, true, 18, getRandomInt(60000, 70000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[foursigma] = foursigmaStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var kuaigong = Locations.ChongqingKuaiGongInternational;
|
2017-07-06 00:33:46 +02:00
|
|
|
var kuaigongStk = new Stock(kuaigong, StockSymbols[kuaigong], 0.8, true, 10, getRandomInt(20000, 24000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[kuaigong] = kuaigongStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var fulcrum = Locations.AevumFulcrumTechnologies;
|
2017-07-06 00:33:46 +02:00
|
|
|
var fulcrumStk = new Stock(fulcrum, StockSymbols[fulcrum], 1.25, true, 17, getRandomInt(30000, 35000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[fulcrum] = fulcrumStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var storm = Locations.IshimaStormTechnologies;
|
2017-07-06 00:33:46 +02:00
|
|
|
var stormStk = new Stock(storm, StockSymbols[storm], 0.85, true, 7, getRandomInt(21000, 24000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[storm] = stormStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var defcomm = Locations.NewTokyoDefComm;
|
2017-07-06 00:33:46 +02:00
|
|
|
var defcommStk = new Stock(defcomm, StockSymbols[defcomm], 0.65, true, 10, getRandomInt(10000, 15000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[defcomm] = defcommStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var helios = Locations.VolhavenHeliosLabs;
|
2017-07-06 00:33:46 +02:00
|
|
|
var heliosStk = new Stock(helios, StockSymbols[helios], 0.6, true, 9, getRandomInt(12000, 16000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[helios] = heliosStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var vitalife = Locations.NewTokyoVitaLife;
|
2017-07-06 00:33:46 +02:00
|
|
|
var vitalifeStk = new Stock(vitalife, StockSymbols[vitalife], 0.75, true, 7, getRandomInt(10000, 12000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[vitalife] = vitalifeStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var icarus = Locations.Sector12IcarusMicrosystems;
|
2017-07-06 00:33:46 +02:00
|
|
|
var icarusStk = new Stock(icarus, StockSymbols[icarus], 0.65, true, 7.5, getRandomInt(16000, 20000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[icarus] = icarusStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var universalenergy = Locations.Sector12UniversalEnergy;
|
2017-07-06 00:33:46 +02:00
|
|
|
var universalenergyStk = new Stock(universalenergy, StockSymbols[universalenergy], 0.55, true, 10, getRandomInt(20000, 25000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[universalenergy] = universalenergyStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var aerocorp = Locations.AevumAeroCorp;
|
2017-07-06 00:33:46 +02:00
|
|
|
var aerocorpStk = new Stock(aerocorp, StockSymbols[aerocorp], 0.6, true, 6, getRandomInt(10000, 15000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[aerocorp] = aerocorpStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var omnia = Locations.VolhavenOmniaCybersystems;
|
|
|
|
var omniaStk = new Stock(omnia, StockSymbols[omnia], 0.7, true, 4.5, getRandomInt(9000, 12000));
|
|
|
|
StockMarket[omnia] = omniaStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var solaris = Locations.ChongqingSolarisSpaceSystems;
|
2017-07-06 00:33:46 +02:00
|
|
|
var solarisStk = new Stock(solaris, StockSymbols[solaris], 0.75, true, 8.5, getRandomInt(18000, 24000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[solaris] = solarisStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var globalpharm = Locations.NewTokyoGlobalPharmaceuticals;
|
2017-07-06 00:33:46 +02:00
|
|
|
var globalpharmStk = new Stock(globalpharm, StockSymbols[globalpharm], 0.6, true, 10.5, getRandomInt(18000, 24000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[globalpharm] = globalpharmStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var nova = Locations.IshimaNovaMedical;
|
2017-07-06 00:33:46 +02:00
|
|
|
var novaStk = new Stock(nova, StockSymbols[nova], 0.75, true, 5, getRandomInt(18000, 24000));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[nova] = novaStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var watchdog = Locations.AevumWatchdogSecurity;
|
2017-07-06 00:33:46 +02:00
|
|
|
var watchdogStk = new Stock(watchdog, StockSymbols[watchdog], 1, true, 1.5, getRandomInt(5000, 7500));
|
2017-07-03 21:42:11 +02:00
|
|
|
StockMarket[watchdog] = watchdogStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var lexocorp = Locations.VolhavenLexoCorp;
|
|
|
|
var lexocorpStk = new Stock(lexocorp, StockSymbols[lexocorp], 1.25, true, 3, getRandomInt(5000, 7500));
|
|
|
|
StockMarket[lexocorp] = lexocorpStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var rho = Locations.AevumRhoConstruction;
|
|
|
|
var rhoStk = new Stock(rho, StockSymbols[rho], 0.6, true, 1, getRandomInt(3000, 6000));
|
|
|
|
StockMarket[rho] = rhoStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var alpha = Locations.Sector12AlphaEnterprises;
|
|
|
|
var alphaStk = new Stock(alpha, StockSymbols[alpha], 1.05, true, 2, getRandomInt(5000, 7500));
|
|
|
|
StockMarket[alpha] = alphaStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var syscore = Locations.VolhavenSysCoreSecurities;
|
|
|
|
var syscoreStk = new Stock(syscore, StockSymbols[syscore], 1.25, true, 0, getRandomInt(4000, 7000))
|
|
|
|
StockMarket[syscore] = syscoreStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var computek = Locations.VolhavenCompuTek;
|
|
|
|
var computekStk = new Stock(computek, StockSymbols[computek], 0.9, true, 0, getRandomInt(2000, 5000));
|
|
|
|
StockMarket[computek] = computekStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var netlink = Locations.AevumNetLinkTechnologies;
|
|
|
|
var netlinkStk = new Stock(netlink, StockSymbols[netlink], 1, true, 1, getRandomInt(2000, 4000));
|
|
|
|
StockMarket[netlink] = netlinkStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var omega = Locations.IshimaOmegaSoftware;
|
|
|
|
var omegaStk = new Stock(omega, StockSymbols[omega], 1, true, 0.5, getRandomInt(3000, 6000));
|
|
|
|
StockMarket[omega] = omegaStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var fns = Locations.Sector12FoodNStuff;
|
|
|
|
var fnsStk = new Stock(fns, StockSymbols[fns], 0.75, false, 1, getRandomInt(1000, 4000));
|
|
|
|
StockMarket[fns] = fnsStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var sigmacosm = "Sigma Cosmetics";
|
|
|
|
var sigmacosmStk = new Stock(sigmacosm, StockSymbols[sigmacosm], 0.9, true, 0, getRandomInt(2000, 3000));
|
|
|
|
StockMarket[sigmacosm] = sigmacosmStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var joesguns = "Joes Guns";
|
|
|
|
var joesgunsStk = new Stock(joesguns, StockSymbols[joesguns], 1, true, 1, getRandomInt(500, 1000));
|
|
|
|
StockMarket[joesguns] = joesgunsStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var catalyst = "Catalyst Ventures";
|
|
|
|
var catalystStk = new Stock(catalyst, StockSymbols[catalyst], 1.25, true, 0, getRandomInt(1000, 1500));
|
|
|
|
StockMarket[catalyst] = catalystStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var microdyne = "Microdyne Technologies";
|
|
|
|
var microdyneStk = new Stock(microdyne, StockSymbols[microdyne], 0.75, true, 8, getRandomInt(20000, 25000));
|
|
|
|
StockMarket[microdyne] = microdyneStk;
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var titanlabs = "Titan Laboratories";
|
|
|
|
var titanlabsStk = new Stock(titanlabs, StockSymbols[titanlabs], 0.6, true, 11, getRandomInt(15000, 20000));
|
|
|
|
StockMarket[titanlabs] = titanlabsStk;
|
|
|
|
}
|
|
|
|
|
|
|
|
function initSymbolToStockMap() {
|
|
|
|
for (var name in StockSymbols) {
|
|
|
|
if (StockSymbols.hasOwnProperty(name)) {
|
|
|
|
var stock = StockMarket[name];
|
|
|
|
if (stock == null) {
|
|
|
|
console.log("ERROR finding stock");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
var symbol = StockSymbols[name];
|
|
|
|
SymbolToStockMap[symbol] = stock;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-13 18:54:29 +02:00
|
|
|
function stockMarketCycle() {
|
|
|
|
console.log("Cycling the Stock Market");
|
|
|
|
for (var name in StockMarket) {
|
|
|
|
if (StockMarket.hasOwnProperty(name)) {
|
|
|
|
var stock = StockMarket[name];
|
2017-07-22 00:54:55 +02:00
|
|
|
var thresh = 0.62;
|
|
|
|
if (stock.b) {thresh = 0.38;}
|
|
|
|
if (Math.random() < thresh) {
|
|
|
|
stock.b = !stock.b;
|
|
|
|
}
|
2017-07-13 18:54:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
//Returns true if successful, false otherwise
|
|
|
|
function buyStock(stock, shares) {
|
2017-07-04 04:39:15 +02:00
|
|
|
if (shares == 0) {return false;}
|
2017-07-13 18:54:29 +02:00
|
|
|
if (stock == null || shares < 0 || isNaN(shares)) {
|
2017-07-03 21:42:11 +02:00
|
|
|
dialogBoxCreate("Failed to buy stock. This may be a bug, contact developer");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
shares = Math.round(shares);
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var totalPrice = stock.price * shares;
|
2017-07-29 18:25:40 +02:00
|
|
|
if (Player.money.lt(totalPrice + CONSTANTS.StockMarketCommission)) {
|
|
|
|
dialogBoxCreate("You do not have enough money to purchase this. You need $" +
|
2017-07-03 21:42:11 +02:00
|
|
|
formatNumber(totalPrice + CONSTANTS.StockMarketCommission, 2).toString() + ".");
|
|
|
|
return false;
|
|
|
|
}
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var origTotal = stock.playerShares * stock.playerAvgPx;
|
|
|
|
Player.loseMoney(totalPrice + CONSTANTS.StockMarketCommission);
|
|
|
|
var newTotal = origTotal + totalPrice;
|
2017-07-29 18:25:40 +02:00
|
|
|
stock.playerShares += shares;
|
2017-07-03 21:42:11 +02:00
|
|
|
stock.playerAvgPx = newTotal / stock.playerShares;
|
|
|
|
updateStockPlayerPosition(stock);
|
2017-07-29 18:25:40 +02:00
|
|
|
dialogBoxCreate("Bought " + formatNumber(shares, 0) + " shares of " + stock.symbol + " at $" +
|
|
|
|
formatNumber(stock.price, 2) + " per share. You also paid $" +
|
2017-07-03 21:42:11 +02:00
|
|
|
formatNumber(CONSTANTS.StockMarketCommission, 2) + " in commission fees.");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Returns true if successful and false otherwise
|
|
|
|
function sellStock(stock, shares) {
|
2017-07-04 04:39:15 +02:00
|
|
|
if (shares == 0) {return false;}
|
2017-07-13 18:54:29 +02:00
|
|
|
if (stock == null || shares < 0 || isNaN(shares)) {
|
2017-07-03 21:42:11 +02:00
|
|
|
dialogBoxCreate("Failed to sell stock. This may be a bug, contact developer");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (shares > stock.playerShares) {shares = stock.playerShares;}
|
2017-07-04 05:16:41 +02:00
|
|
|
if (shares == 0) {return false;}
|
2017-07-03 21:42:11 +02:00
|
|
|
var gains = stock.price * shares - CONSTANTS.StockMarketCommission;
|
|
|
|
Player.gainMoney(gains);
|
|
|
|
stock.playerShares -= shares;
|
|
|
|
if (stock.playerShares == 0) {
|
|
|
|
stock.playerAvgPx = 0;
|
|
|
|
}
|
|
|
|
updateStockPlayerPosition(stock);
|
2017-07-29 18:25:40 +02:00
|
|
|
dialogBoxCreate("Sold " + formatNumber(shares, 0) + " shares of " + stock.symbol + " at $" +
|
|
|
|
formatNumber(stock.price, 2) + " per share. After commissions, you gained " +
|
2017-07-03 21:42:11 +02:00
|
|
|
"a total of $" + formatNumber(gains, 2));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateStockPrices() {
|
|
|
|
var v = Math.random();
|
|
|
|
for (var name in StockMarket) {
|
|
|
|
if (StockMarket.hasOwnProperty(name)) {
|
|
|
|
var stock = StockMarket[name];
|
|
|
|
var av = (v * stock.mv) / 100;
|
|
|
|
if (isNaN(av)) {av = .02;}
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var chc = 50;
|
|
|
|
if (stock.b) {
|
|
|
|
chc = (chc + stock.otlkMag)/100;
|
|
|
|
if (isNaN(chc)) {chc = 0.5;}
|
|
|
|
} else {
|
|
|
|
chc = (chc - stock.otlkMag)/100;
|
|
|
|
if (isNaN(chc)) {chc = 0.5;}
|
|
|
|
}
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var c = Math.random();
|
|
|
|
if (c < chc) {
|
|
|
|
stock.price *= (1 + av);
|
|
|
|
if (Engine.currentPage == Engine.Page.StockMarket) {
|
|
|
|
updateStockTicker(stock, true);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
stock.price /= (1 + av);
|
|
|
|
if (Engine.currentPage == Engine.Page.StockMarket) {
|
2017-07-29 18:25:40 +02:00
|
|
|
updateStockTicker(stock, false);
|
2017-07-03 21:42:11 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var otlkMagChange = stock.otlkMag * av;
|
|
|
|
if (stock.otlkMag <= 0.1) {
|
|
|
|
otlkMagChange = 1;
|
|
|
|
}
|
|
|
|
if (c < 0.5) {
|
|
|
|
stock.otlkMag += otlkMagChange;
|
|
|
|
} else {
|
|
|
|
stock.otlkMag -= otlkMagChange;
|
|
|
|
}
|
|
|
|
if (stock.otlkMag < 0) {
|
|
|
|
stock.otlkMag *= -1;
|
|
|
|
stock.b = !stock.b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var stockMarketContentCreated = false;
|
|
|
|
function displayStockMarketContent() {
|
|
|
|
if (Player.hasWseAccount == null) {Player.hasWseAccount = false;}
|
|
|
|
if (Player.hasTixApiAccess == null) {Player.hasTixApiAccess = false;}
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-13 18:54:29 +02:00
|
|
|
//Purchase WSE Account button
|
2017-07-03 21:42:11 +02:00
|
|
|
var wseAccountButton = clearEventListeners("stock-market-buy-account");
|
2017-07-13 18:54:29 +02:00
|
|
|
wseAccountButton.innerText = "Buy WSE Account - $" + formatNumber(CONSTANTS.WSEAccountCost, 2).toString();
|
2017-07-29 18:25:40 +02:00
|
|
|
if (!Player.hasWseAccount && Player.money.gte(CONSTANTS.WSEAccountCost)) {
|
2017-07-03 21:42:11 +02:00
|
|
|
wseAccountButton.setAttribute("class", "a-link-button");
|
|
|
|
} else {
|
|
|
|
wseAccountButton.setAttribute("class", "a-link-button-inactive");
|
|
|
|
}
|
|
|
|
wseAccountButton.addEventListener("click", function() {
|
|
|
|
Player.hasWseAccount = true;
|
|
|
|
initStockMarket();
|
2017-07-22 00:54:55 +02:00
|
|
|
initSymbolToStockMap();
|
2017-07-03 21:42:11 +02:00
|
|
|
Player.loseMoney(CONSTANTS.WSEAccountCost);
|
|
|
|
displayStockMarketContent();
|
|
|
|
return false;
|
|
|
|
});
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-13 18:54:29 +02:00
|
|
|
//Purchase TIX API Access account
|
|
|
|
var tixApiAccessButton = clearEventListeners("stock-market-buy-tix-api");
|
2017-07-29 18:25:40 +02:00
|
|
|
tixApiAccessButton.innerText = "Buy Trade Information eXchange (TIX) API Access - $" +
|
2017-07-13 18:54:29 +02:00
|
|
|
formatNumber(CONSTANTS.TIXAPICost, 2).toString();
|
2017-07-29 18:25:40 +02:00
|
|
|
if (!Player.hasTixApiAccess && Player.money.gte(CONSTANTS.TIXAPICost)) {
|
2017-07-13 18:54:29 +02:00
|
|
|
tixApiAccessButton.setAttribute("class", "a-link-button");
|
|
|
|
} else {
|
|
|
|
tixApiAccessButton.setAttribute("class", "a-link-button-inactive");
|
|
|
|
}
|
|
|
|
tixApiAccessButton.addEventListener("click", function() {
|
|
|
|
Player.hasTixApiAccess = true;
|
|
|
|
Player.loseMoney(CONSTANTS.TIXAPICost);
|
|
|
|
displayStockMarketContent();
|
|
|
|
return false;
|
|
|
|
});
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var stockList = document.getElementById("stock-market-list");
|
|
|
|
if (stockList == null) {return;}
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
if (!Player.hasWseAccount) {
|
|
|
|
stockMarketContentCreated = false;
|
|
|
|
while (stockList.firstChild) {
|
|
|
|
stockList.removeChild(stockList.firstChild);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
if (!stockMarketContentCreated && Player.hasWseAccount) {
|
|
|
|
console.log("Creating Stock Market UI");
|
2017-07-05 06:02:19 +02:00
|
|
|
document.getElementById("stock-market-commission").innerHTML =
|
2017-07-29 18:25:40 +02:00
|
|
|
"Commission Fees: Every transaction you make has a $" +
|
|
|
|
formatNumber(CONSTANTS.StockMarketCommission, 2) + " commission fee.<br><br>" +
|
|
|
|
"WARNING: When you reset after installing Augmentations, the Stock Market is reset. " +
|
|
|
|
"This means all your positions are lost, so make sure to sell your stocks before installing " +
|
2017-07-03 21:42:11 +02:00
|
|
|
"Augmentations!";
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var hdrLi = document.createElement("li");
|
|
|
|
var hdrName = document.createElement("p");
|
|
|
|
var hdrSym = document.createElement("p");
|
|
|
|
var hdrPrice = document.createElement("p");
|
|
|
|
var hdrQty = document.createElement("p");
|
|
|
|
var hdrBuySell = document.createElement("p")
|
|
|
|
var hdrAvgPrice = document.createElement("p");
|
|
|
|
var hdrShares = document.createElement("p");
|
|
|
|
var hdrReturn = document.createElement("p");
|
|
|
|
hdrName.style.display = "inline-block";
|
|
|
|
hdrName.innerText = "Stock Name";
|
|
|
|
hdrName.style.width = "8%";
|
|
|
|
hdrSym.style.display = "inline-block";
|
|
|
|
hdrSym.innerText = "Symbol";
|
|
|
|
hdrSym.style.width = "4%";
|
|
|
|
hdrPrice.style.display = "inline-block";
|
|
|
|
hdrPrice.innerText = "Price";
|
|
|
|
hdrPrice.style.width = "8%";
|
|
|
|
hdrQty.style.display = "inline-block";
|
|
|
|
hdrQty.innerText = "Quantity";
|
|
|
|
hdrQty.style.width = "3%";
|
|
|
|
hdrBuySell.style.display = "inline-block";
|
|
|
|
hdrBuySell.innerText = "Buy/Sell";
|
|
|
|
hdrBuySell.style.width = "5%";
|
|
|
|
hdrAvgPrice.style.display = "inline-block";
|
|
|
|
hdrAvgPrice.innerText = "Avg price of owned shares";
|
|
|
|
hdrAvgPrice.style.width = "7.5%";
|
|
|
|
hdrShares.style.display = "inline-block";
|
|
|
|
hdrShares.innerText = "Shares owned";
|
|
|
|
hdrShares.style.width = "4%";
|
|
|
|
hdrReturn.style.display = "inline-block";
|
|
|
|
hdrReturn.innerText = "Total Return";
|
|
|
|
hdrReturn.style.width = "6%";
|
|
|
|
hdrLi.appendChild(hdrName);
|
|
|
|
hdrLi.appendChild(hdrSym);
|
|
|
|
hdrLi.appendChild(hdrPrice);
|
|
|
|
hdrLi.appendChild(hdrQty);
|
|
|
|
hdrLi.appendChild(hdrBuySell);
|
|
|
|
hdrLi.appendChild(hdrAvgPrice);
|
|
|
|
hdrLi.appendChild(hdrShares);
|
|
|
|
hdrLi.appendChild(hdrReturn);
|
|
|
|
stockList.appendChild(hdrLi);
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
for (var name in StockMarket) {
|
|
|
|
if (StockMarket.hasOwnProperty(name)) {
|
|
|
|
(function() {
|
|
|
|
var stock = StockMarket[name];
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var li = document.createElement("li");
|
|
|
|
var stkName = document.createElement("p");
|
|
|
|
var stkSym = document.createElement("p");
|
|
|
|
var stkPrice = document.createElement("p");
|
|
|
|
var qtyInput = document.createElement("input");
|
|
|
|
var buyButton = document.createElement("span");
|
|
|
|
var sellButton = document.createElement("span");
|
|
|
|
var avgPriceTxt = document.createElement("p");
|
|
|
|
var sharesTxt = document.createElement("p");
|
|
|
|
var returnTxt = document.createElement("p");
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var tickerId = "stock-market-ticker-" + stock.symbol;
|
|
|
|
stkName.setAttribute("id", tickerId + "-name");
|
|
|
|
stkSym.setAttribute("id", tickerId + "-sym");
|
|
|
|
stkPrice.setAttribute("id", tickerId + "-price");
|
|
|
|
stkName.style.display = "inline-block";
|
|
|
|
stkName.style.width = "8%";
|
|
|
|
stkSym.style.display = "inline-block";
|
|
|
|
stkSym.style.width = "4%";
|
|
|
|
stkPrice.style.display = "inline-block";
|
|
|
|
stkPrice.style.width = "9%";
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
li.setAttribute("display", "inline-block");
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
qtyInput.setAttribute("type", "text");
|
|
|
|
qtyInput.setAttribute("id", tickerId + "-qty-input");
|
|
|
|
qtyInput.setAttribute("class", "stock-market-qty-input");
|
2017-07-29 18:25:40 +02:00
|
|
|
qtyInput.setAttribute("onkeydown", "return ( event.ctrlKey || event.altKey " +
|
|
|
|
" || (47<event.keyCode && event.keyCode<58 && event.shiftKey==false) " +
|
|
|
|
" || (95<event.keyCode && event.keyCode<106) " +
|
|
|
|
" || (event.keyCode==8) || (event.keyCode==9) " +
|
2017-07-04 05:16:41 +02:00
|
|
|
" || (event.keyCode>34 && event.keyCode<40) " +
|
|
|
|
" || (event.keyCode==46) )");
|
2017-07-03 21:42:11 +02:00
|
|
|
qtyInput.style.width = "3%";
|
|
|
|
qtyInput.style.display = "inline-block";
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
buyButton.innerHTML = "Buy";
|
|
|
|
buyButton.setAttribute("class", "stock-market-buy-sell-button");
|
|
|
|
buyButton.style.width = "3%";
|
|
|
|
buyButton.style.display = "inline-block";
|
|
|
|
buyButton.addEventListener("click", function() {
|
|
|
|
var shares = document.getElementById(tickerId + "-qty-input").value;
|
|
|
|
shares = Number(shares);
|
|
|
|
if (isNaN(shares)) {return false;}
|
|
|
|
buyStock(stock, shares);
|
|
|
|
});
|
|
|
|
sellButton.innerHTML = "Sell";
|
|
|
|
sellButton.setAttribute("class", "stock-market-buy-sell-button");
|
|
|
|
sellButton.style.width = "3%";
|
|
|
|
sellButton.style.display = "inline-block";
|
|
|
|
sellButton.addEventListener("click", function() {
|
|
|
|
var shares = document.getElementById(tickerId + "-qty-input").value;
|
|
|
|
shares = Number(shares);
|
|
|
|
if (isNaN(shares)) {return false;}
|
|
|
|
sellStock(stock, shares);
|
|
|
|
});
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
avgPriceTxt.setAttribute("id", tickerId + "-avgprice");
|
|
|
|
avgPriceTxt.style.display = "inline-block";
|
|
|
|
avgPriceTxt.style.width = "8%";
|
|
|
|
avgPriceTxt.style.color = "white";
|
|
|
|
sharesTxt.setAttribute("id", tickerId + "-shares");
|
|
|
|
sharesTxt.style.display = "inline-block";
|
|
|
|
sharesTxt.style.width = "4%";
|
|
|
|
sharesTxt.style.color = "white";
|
|
|
|
returnTxt.setAttribute("id", tickerId + "-return");
|
|
|
|
returnTxt.style.display = "inline-block";
|
|
|
|
returnTxt.style.width = "6%";
|
|
|
|
returnTxt.style.color = "white";
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
li.appendChild(stkName);
|
|
|
|
li.appendChild(stkSym);
|
|
|
|
li.appendChild(stkPrice);
|
|
|
|
li.appendChild(qtyInput);
|
|
|
|
li.appendChild(buyButton);
|
|
|
|
li.appendChild(sellButton);
|
|
|
|
li.appendChild(avgPriceTxt);
|
|
|
|
li.appendChild(sharesTxt);
|
|
|
|
li.appendChild(returnTxt);
|
|
|
|
stockList.appendChild(li);
|
|
|
|
}()); //Immediate invocation
|
|
|
|
}//End if
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
}
|
|
|
|
stockMarketContentCreated = true;
|
|
|
|
}
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-05 18:49:01 +02:00
|
|
|
if (Player.hasWseAccount) {
|
|
|
|
for (var name in StockMarket) {
|
|
|
|
if (StockMarket.hasOwnProperty(name)) {
|
|
|
|
var stock = StockMarket[name];
|
|
|
|
updateStockTicker(stock, true);
|
|
|
|
updateStockPlayerPosition(stock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-07-03 21:42:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//'increase' argument is a boolean indicating whether the price increased or decreased
|
|
|
|
function updateStockTicker(stock, increase) {
|
|
|
|
var tickerId = "stock-market-ticker-" + stock.symbol;
|
2017-08-30 19:44:29 +02:00
|
|
|
let stkName = document.getElementById(tickerId + "-name");
|
|
|
|
let stkSym = document.getElementById(tickerId + "-sym");
|
|
|
|
let stkPrice = document.getElementById(tickerId + "-price");
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
if (stkName == null || stkSym == null || stkPrice == null) {
|
|
|
|
console.log("ERROR, couldn't find elements with tickerId " + tickerId);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
stkName.innerText = stock.name;
|
|
|
|
stkSym.innerText = stock.symbol;
|
|
|
|
stkPrice.innerText = "$" + formatNumber(stock.price, 2).toString();
|
2017-07-29 18:25:40 +02:00
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
var returnTxt = document.getElementById(tickerId + "-return");
|
|
|
|
var totalCost = stock.playerShares * stock.playerAvgPx;
|
|
|
|
var gains = (stock.price - stock.playerAvgPx) * stock.playerShares;
|
|
|
|
var percentageGains = gains / totalCost;
|
|
|
|
if (totalCost > 0) {
|
2017-07-29 18:25:40 +02:00
|
|
|
returnTxt.innerText = "$" + formatNumber(gains, 2) + " (" +
|
2017-07-03 21:42:11 +02:00
|
|
|
formatNumber(percentageGains * 100, 2) + "%)";
|
|
|
|
} else {
|
|
|
|
returnTxt.innerText = "N/A";
|
|
|
|
}
|
2017-07-29 18:25:40 +02:00
|
|
|
|
|
|
|
|
2017-07-03 21:42:11 +02:00
|
|
|
if (increase) {
|
|
|
|
stkName.style.color = "#66ff33";
|
|
|
|
stkSym.style.color = "#66ff33";
|
|
|
|
stkPrice.style.color = "#66ff33";
|
|
|
|
} else {
|
|
|
|
stkName.style.color = "red";
|
|
|
|
stkSym.style.color = "red";
|
|
|
|
stkPrice.style.color = "red";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateStockPlayerPosition(stock) {
|
|
|
|
var tickerId = "stock-market-ticker-" + stock.symbol;
|
|
|
|
var avgPriceTxt = document.getElementById(tickerId + "-avgprice");
|
|
|
|
var sharesTxt = document.getElementById(tickerId + "-shares");
|
|
|
|
if (avgPriceTxt == null || sharesTxt == null) {
|
2017-07-29 18:25:40 +02:00
|
|
|
dialogBoxCreate("Could not find element for player positions for stock " +
|
2017-07-03 21:42:11 +02:00
|
|
|
stock.symbol + ". This is a bug please contact developer");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
avgPriceTxt.innerText = "$" + formatNumber(stock.playerAvgPx, 2);
|
|
|
|
sharesTxt.innerText = stock.playerShares.toString();
|
2017-07-29 18:25:40 +02:00
|
|
|
}
|
2017-08-30 19:44:29 +02:00
|
|
|
|
|
|
|
export {StockMarket, StockSymbols, SymbolToStockMap, initStockSymbols,
|
|
|
|
initStockMarket, initSymbolToStockMap, stockMarketCycle, buyStock,
|
|
|
|
sellStock, updateStockPrices, displayStockMarketContent,
|
|
|
|
updateStockTicker, updateStockPlayerPosition, loadStockMarket};
|