2019-04-28 02:43:38 +02:00
import { Order } from "./Order" ;
2019-04-23 10:48:15 +02:00
import { Stock } from "./Stock" ;
2019-04-28 04:20:51 +02:00
import {
getBuyTransactionCost ,
getSellTransactionGain ,
processBuyTransactionPriceMovement ,
processSellTransactionPriceMovement
} from "./StockMarketHelpers" ;
2019-04-23 10:48:15 +02:00
import {
getStockMarket4SDataCost ,
getStockMarket4STixApiCost
} from "./StockMarketCosts" ;
import { InitStockMetadata } from "./data/InitStockMetadata" ;
2019-04-28 02:43:38 +02:00
import { OrderTypes } from "./data/OrderTypes" ;
import { PositionTypes } from "./data/PositionTypes" ;
2019-04-23 10:48:15 +02:00
import { StockSymbols } from "./data/StockSymbols" ;
import { StockMarketRoot } from "./ui/Root" ;
import { CONSTANTS } from "../Constants" ;
import { WorkerScript } from "../NetscriptWorker" ;
import { Player } from "../Player" ;
import { Page , routing } from ".././ui/navigationTracking" ;
import { numeralWrapper } from ".././ui/numeralFormat" ;
import { dialogBoxCreate } from "../../utils/DialogBox" ;
import { Reviver } from "../../utils/JSONReviver" ;
import React from "react" ;
2019-04-28 02:43:38 +02:00
import ReactDOM from "react-dom" ;
2019-04-23 10:48:15 +02:00
export function placeOrder ( stock , shares , price , type , position , workerScript = null ) {
var tixApi = ( workerScript instanceof WorkerScript ) ;
var order = new Order ( stock , shares , price , type , position ) ;
if ( isNaN ( shares ) || isNaN ( price ) ) {
if ( tixApi ) {
workerScript . scriptRef . log ( "ERROR: Invalid numeric value provided for either 'shares' or 'price' argument" ) ;
} else {
dialogBoxCreate ( "ERROR: Invalid numeric value provided for either 'shares' or 'price' argument" ) ;
}
return false ;
}
if ( StockMarket [ "Orders" ] == null ) {
const orders = { } ;
for ( const name in StockMarket ) {
if ( StockMarket . hasOwnProperty ( name ) ) {
const stk = StockMarket [ name ] ;
if ( ! ( stk instanceof Stock ) ) { continue ; }
orders [ stk . symbol ] = [ ] ;
}
}
StockMarket [ "Orders" ] = orders ;
}
StockMarket [ "Orders" ] [ stock . symbol ] . push ( order ) ;
//Process to see if it should be executed immediately
processOrders ( order . stock , order . type , order . pos ) ;
displayStockMarketContent ( ) ;
return true ;
}
// Returns true if successfully cancels an order, false otherwise
export function cancelOrder ( params , workerScript = null ) {
var tixApi = ( workerScript instanceof WorkerScript ) ;
if ( StockMarket [ "Orders" ] == null ) { return false ; }
if ( params . order && params . order instanceof Order ) {
var order = params . order ;
2019-04-28 02:43:38 +02:00
// An 'Order' object is passed in
2019-04-23 10:48:15 +02:00
var stockOrders = StockMarket [ "Orders" ] [ order . stock . symbol ] ;
for ( var i = 0 ; i < stockOrders . length ; ++ i ) {
if ( order == stockOrders [ i ] ) {
stockOrders . splice ( i , 1 ) ;
displayStockMarketContent ( ) ;
return true ;
}
}
return false ;
} else if ( params . stock && params . shares && params . price && params . type &&
params . pos && params . stock instanceof Stock ) {
2019-04-28 02:43:38 +02:00
// Order properties are passed in. Need to look for the order
2019-04-23 10:48:15 +02:00
var stockOrders = StockMarket [ "Orders" ] [ params . stock . symbol ] ;
var orderTxt = params . stock . symbol + " - " + params . shares + " @ " +
numeralWrapper . format ( params . price , '$0.000a' ) ;
for ( var i = 0 ; i < stockOrders . length ; ++ i ) {
var order = stockOrders [ i ] ;
if ( params . shares === order . shares &&
params . price === order . price &&
params . type === order . type &&
params . pos === order . pos ) {
stockOrders . splice ( i , 1 ) ;
displayStockMarketContent ( ) ;
if ( tixApi ) {
workerScript . scriptRef . log ( "Successfully cancelled order: " + orderTxt ) ;
}
return true ;
}
}
if ( tixApi ) {
workerScript . scriptRef . log ( "Failed to cancel order: " + orderTxt ) ;
}
return false ;
}
return false ;
}
function executeOrder ( order ) {
var stock = order . stock ;
var orderBook = StockMarket [ "Orders" ] ;
var stockOrders = orderBook [ stock . symbol ] ;
var res = true ;
console . log ( "Executing the following order:" ) ;
console . log ( order ) ;
switch ( order . type ) {
case OrderTypes . LimitBuy :
case OrderTypes . StopBuy :
if ( order . pos === PositionTypes . Long ) {
res = buyStock ( order . stock , order . shares ) && res ;
} else if ( order . pos === PositionTypes . Short ) {
res = shortStock ( order . stock , order . shares ) && res ;
}
break ;
case OrderTypes . LimitSell :
case OrderTypes . StopSell :
if ( order . pos === PositionTypes . Long ) {
res = sellStock ( order . stock , order . shares ) && res ;
} else if ( order . pos === PositionTypes . Short ) {
res = sellShort ( order . stock , order . shares ) && res ;
}
break ;
}
if ( res ) {
2019-04-28 02:43:38 +02:00
// Remove order from order book
2019-04-23 10:48:15 +02:00
for ( var i = 0 ; i < stockOrders . length ; ++ i ) {
if ( order == stockOrders [ i ] ) {
stockOrders . splice ( i , 1 ) ;
displayStockMarketContent ( ) ;
return ;
}
}
console . log ( "ERROR: Could not find the following Order in Order Book: " ) ;
console . log ( order ) ;
} else {
console . log ( "Order failed to execute" ) ;
}
}
export let StockMarket = { } ; // Maps full stock name -> Stock object
export let SymbolToStockMap = { } ; // Maps symbol -> Stock object
export function loadStockMarket ( saveString ) {
if ( saveString === "" ) {
StockMarket = { } ;
} else {
StockMarket = JSON . parse ( saveString , Reviver ) ;
}
}
export function initStockMarket ( ) {
for ( const stk in StockMarket ) {
if ( StockMarket . hasOwnProperty ( stk ) ) {
delete StockMarket [ stk ] ;
}
}
for ( const metadata of InitStockMetadata ) {
const name = metadata . name ;
StockMarket [ name ] = new Stock ( metadata ) ;
}
const orders = { } ;
for ( const name in StockMarket ) {
if ( StockMarket . hasOwnProperty ( name ) ) {
const stock = StockMarket [ name ] ;
if ( ! ( stock instanceof Stock ) ) { continue ; }
orders [ stock . symbol ] = [ ] ;
}
}
StockMarket [ "Orders" ] = orders ;
StockMarket . storedCycles = 0 ;
StockMarket . lastUpdate = 0 ;
}
export function initSymbolToStockMap ( ) {
for ( const name in StockSymbols ) {
if ( StockSymbols . hasOwnProperty ( name ) ) {
const stock = StockMarket [ name ] ;
if ( stock == null ) {
console . error ( ` Could not find Stock for ${ name } ` ) ;
continue ;
}
const symbol = StockSymbols [ name ] ;
SymbolToStockMap [ symbol ] = stock ;
}
}
}
export 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 ) {
stock . b = ! stock . b ;
}
}
}
}
/ * *
* Attempt to buy a stock in the long position
* @ param { Stock } stock - Stock to buy
* @ param { number } shares - Number of shares to buy
* @ param { WorkerScript } workerScript - If this is being called through Netscript
* @ returns { boolean } - true if successful , false otherwise
* /
export function buyStock ( stock , shares , workerScript = null ) {
const tixApi = ( workerScript instanceof WorkerScript ) ;
// Validate arguments
shares = Math . round ( shares ) ;
if ( shares == 0 || shares < 0 ) { return false ; }
if ( stock == null || isNaN ( shares ) ) {
if ( tixApi ) {
workerScript . log ( ` ERROR: buyStock() failed due to invalid arguments ` ) ;
} else {
dialogBoxCreate ( "Failed to buy stock. This may be a bug, contact developer" ) ;
}
return false ;
}
// Does player have enough money?
2019-04-28 04:20:51 +02:00
const totalPrice = getBuyTransactionCost ( stock , shares , PositionTypes . Long ) ;
if ( Player . money . lt ( totalPrice ) ) {
2019-04-23 10:48:15 +02:00
if ( tixApi ) {
workerScript . log ( ` ERROR: buyStock() failed because you do not have enough money to purchase this potiion. You need ${ numeralWrapper . formatMoney ( totalPrice + CONSTANTS . StockMarketCommission ) } ` ) ;
} else {
dialogBoxCreate ( ` You do not have enough money to purchase this. You need ${ numeralWrapper . formatMoney ( totalPrice + CONSTANTS . StockMarketCommission ) } ` ) ;
}
return false ;
}
// Would this purchase exceed the maximum number of shares?
if ( shares + stock . playerShares + stock . playerShortShares > stock . maxShares ) {
if ( tixApi ) {
workerScript . log ( ` ERROR: buyStock() failed because purchasing this many shares would exceed ${ stock . symbol } 's maximum number of shares ` ) ;
} else {
dialogBoxCreate ( ` You cannot purchase this many shares. ${ stock . symbol } has a maximum of ${ numeralWrapper . formatBigNumber ( stock . maxShares ) } shares. ` ) ;
}
return false ;
}
const origTotal = stock . playerShares * stock . playerAvgPx ;
2019-04-28 04:20:51 +02:00
Player . loseMoney ( totalPrice ) ;
2019-04-23 10:48:15 +02:00
const newTotal = origTotal + totalPrice ;
stock . playerShares = Math . round ( stock . playerShares + shares ) ;
stock . playerAvgPx = newTotal / stock . playerShares ;
2019-04-28 04:20:51 +02:00
processBuyTransactionPriceMovement ( stock , shares , PositionTypes . Long ) ;
2019-04-23 10:48:15 +02:00
displayStockMarketContent ( ) ;
2019-04-28 04:20:51 +02:00
const resultTxt = ` Bought ${ numeralWrapper . format ( shares , '0,0' ) } shares of ${ stock . symbol } for ${ numeralWrapper . formatMoney ( totalPrice ) } . ` +
` Paid ${ numeralWrapper . formatMoney ( CONSTANTS . StockMarketCommission ) } in commission fees. `
2019-04-23 10:48:15 +02:00
if ( tixApi ) {
2019-04-28 04:20:51 +02:00
if ( workerScript . shouldLog ( "buyStock" ) ) { workerScript . log ( resultTxt ) ; }
2019-04-23 10:48:15 +02:00
} else {
2019-04-28 04:20:51 +02:00
dialogBoxCreate ( resultTxt ) ;
2019-04-23 10:48:15 +02:00
}
return true ;
}
/ * *
* Attempt to sell a stock in the long position
* @ param { Stock } stock - Stock to sell
* @ param { number } shares - Number of shares to sell
* @ param { WorkerScript } workerScript - If this is being called through Netscript
* returns { boolean } - true if successfully sells given number of shares OR MAX owned , false otherwise
* /
export function sellStock ( stock , shares , workerScript = null ) {
const tixApi = ( workerScript instanceof WorkerScript ) ;
// Sanitize/Validate arguments
if ( stock == null || shares < 0 || isNaN ( shares ) ) {
if ( tixApi ) {
workerScript . log ( ` ERROR: sellStock() failed due to invalid arguments ` ) ;
} else {
dialogBoxCreate ( "Failed to sell stock. This is probably due to an invalid quantity. Otherwise, this may be a bug, contact developer" ) ;
}
return false ;
}
shares = Math . round ( shares ) ;
if ( shares > stock . playerShares ) { shares = stock . playerShares ; }
if ( shares === 0 ) { return false ; }
2019-04-28 04:20:51 +02:00
const gains = getSellTransactionGain ( stock , shares , PositionTypes . Long ) ;
let netProfit = gains - ( stock . playerAvgPx * shares ) ;
2019-04-23 10:48:15 +02:00
if ( isNaN ( netProfit ) ) { netProfit = 0 ; }
Player . gainMoney ( gains ) ;
Player . recordMoneySource ( netProfit , "stock" ) ;
if ( tixApi ) {
workerScript . scriptRef . onlineMoneyMade += netProfit ;
Player . scriptProdSinceLastAug += netProfit ;
}
stock . playerShares = Math . round ( stock . playerShares - shares ) ;
if ( stock . playerShares === 0 ) {
stock . playerAvgPx = 0 ;
}
2019-04-28 04:20:51 +02:00
processSellTransactionPriceMovement ( stock , shares , PositionTypes . Long ) ;
2019-04-23 10:48:15 +02:00
displayStockMarketContent ( ) ;
2019-04-28 04:20:51 +02:00
const resultTxt = ` Sold ${ numeralWrapper . format ( shares , '0,0' ) } shares of ${ stock . symbol } . ` +
` After commissions, you gained a total of ${ numeralWrapper . formatMoney ( gains ) } . ` ;
2019-04-23 10:48:15 +02:00
if ( tixApi ) {
2019-04-28 04:20:51 +02:00
if ( workerScript . shouldLog ( "sellStock" ) ) { workerScript . log ( resultTxt ) ; }
2019-04-23 10:48:15 +02:00
} else {
2019-04-28 04:20:51 +02:00
dialogBoxCreate ( resultTxt ) ;
2019-04-23 10:48:15 +02:00
}
return true ;
}
/ * *
* Attempt to buy a stock in the short position
* @ param { Stock } stock - Stock to sell
* @ param { number } shares - Number of shares to short
* @ param { WorkerScript } workerScript - If this is being called through Netscript
* @ returns { boolean } - true if successful , false otherwise
* /
export function shortStock ( stock , shares , workerScript = null ) {
const tixApi = ( workerScript instanceof WorkerScript ) ;
// Validate arguments
shares = Math . round ( shares ) ;
if ( shares === 0 || shares < 0 ) { return false ; }
if ( stock == null || isNaN ( shares ) ) {
if ( tixApi ) {
workerScript . log ( "ERROR: shortStock() failed because of invalid arguments." ) ;
} else {
dialogBoxCreate ( "Failed to initiate a short position in a stock. This is probably " +
"due to an invalid quantity. Otherwise, this may be a bug, so contact developer" ) ;
}
return false ;
}
// Does the player have enough money?
2019-04-28 04:20:51 +02:00
const totalPrice = getBuyTransactionCost ( stock , shares , PositionTypes . Short ) ;
2019-04-23 10:48:15 +02:00
if ( Player . money . lt ( totalPrice + CONSTANTS . StockMarketCommission ) ) {
if ( tixApi ) {
workerScript . log ( "ERROR: shortStock() failed because you do not have enough " +
"money to purchase this short position. You need " +
numeralWrapper . formatMoney ( totalPrice + CONSTANTS . StockMarketCommission ) ) ;
} else {
dialogBoxCreate ( "You do not have enough money to purchase this short position. You need " +
numeralWrapper . formatMoney ( totalPrice + CONSTANTS . StockMarketCommission ) ) ;
}
return false ;
}
// Would this purchase exceed the maximum number of shares?
if ( shares + stock . playerShares + stock . playerShortShares > stock . maxShares ) {
if ( tixApi ) {
workerScript . log ( ` ERROR: shortStock() failed because purchasing this many short shares would exceed ${ stock . symbol } 's maximum number of shares. ` ) ;
} else {
dialogBoxCreate ( ` You cannot purchase this many shares. ${ stock . symbol } has a maximum of ${ stock . maxShares } shares. ` ) ;
}
return false ;
}
const origTotal = stock . playerShortShares * stock . playerAvgShortPx ;
Player . loseMoney ( totalPrice + CONSTANTS . StockMarketCommission ) ;
const newTotal = origTotal + totalPrice ;
stock . playerShortShares = Math . round ( stock . playerShortShares + shares ) ;
stock . playerAvgShortPx = newTotal / stock . playerShortShares ;
2019-04-28 04:20:51 +02:00
processBuyTransactionPriceMovement ( stock , shares , PositionTypes . Short ) ;
2019-04-23 10:48:15 +02:00
displayStockMarketContent ( ) ;
2019-04-28 04:20:51 +02:00
const resultTxt = ` Bought a short position of ${ numeralWrapper . format ( shares , '0,0' ) } shares of ${ stock . symbol } ` +
` for ${ numeralWrapper . formatMoney ( totalPrice ) } . Paid ${ numeralWrapper . formatMoney ( CONSTANTS . StockMarketCommission ) } ` +
` in commission fees. ` ;
2019-04-23 10:48:15 +02:00
if ( tixApi ) {
2019-04-28 04:20:51 +02:00
if ( workerScript . shouldLog ( "shortStock" ) ) { workerScript . log ( resultTxt ) ; }
2019-04-23 10:48:15 +02:00
} else {
2019-04-28 04:20:51 +02:00
dialogBoxCreate ( resultTxt ) ;
2019-04-23 10:48:15 +02:00
}
return true ;
}
/ * *
* Attempt to sell a stock in the short position
* @ param { Stock } stock - Stock to sell
* @ param { number } shares - Number of shares to sell
* @ param { WorkerScript } workerScript - If this is being called through Netscript
* @ returns { boolean } true if successfully sells given amount OR max owned , false otherwise
* /
export function sellShort ( stock , shares , workerScript = null ) {
const tixApi = ( workerScript instanceof WorkerScript ) ;
if ( stock == null || isNaN ( shares ) || shares < 0 ) {
if ( tixApi ) {
workerScript . log ( "ERROR: sellShort() failed because of invalid arguments." ) ;
} else {
dialogBoxCreate ( "Failed to sell a short position in a stock. This is probably " +
"due to an invalid quantity. Otherwise, this may be a bug, so contact developer" ) ;
}
return false ;
}
shares = Math . round ( shares ) ;
if ( shares > stock . playerShortShares ) { shares = stock . playerShortShares ; }
if ( shares === 0 ) { return false ; }
const origCost = shares * stock . playerAvgShortPx ;
2019-04-28 04:20:51 +02:00
const totalGain = getSellTransactionGain ( stock , shares , PositionTypes . Short ) ;
if ( totalGain == null || isNaN ( totalGain ) || origCost == null ) {
if ( tixApi ) {
workerScript . log ( ` Failed to sell short position in a stock. This is probably either due to invalid arguments, or a bug ` ) ;
} else {
dialogBoxCreate ( ` Failed to sell short position in a stock. This is probably either due to invalid arguments, or a bug ` ) ;
}
return false ;
}
let profit = totalGain - origCost ;
2019-04-23 10:48:15 +02:00
if ( isNaN ( profit ) ) { profit = 0 ; }
2019-04-28 04:20:51 +02:00
Player . gainMoney ( totalGain ) ;
2019-04-23 10:48:15 +02:00
Player . recordMoneySource ( profit , "stock" ) ;
if ( tixApi ) {
workerScript . scriptRef . onlineMoneyMade += profit ;
Player . scriptProdSinceLastAug += profit ;
}
stock . playerShortShares = Math . round ( stock . playerShortShares - shares ) ;
if ( stock . playerShortShares === 0 ) {
stock . playerAvgShortPx = 0 ;
}
2019-04-28 04:20:51 +02:00
processSellTransactionPriceMovement ( stock , shares , PositionTypes . Short ) ;
2019-04-23 10:48:15 +02:00
displayStockMarketContent ( ) ;
2019-04-28 04:20:51 +02:00
const resultTxt = ` Sold your short position of ${ numeralWrapper . format ( shares , '0,0' ) } shares of ${ stock . symbol } . ` +
` After commissions, you gained a total of ${ numeralWrapper . formatMoney ( totalGain ) } ` ;
2019-04-23 10:48:15 +02:00
if ( tixApi ) {
2019-04-28 04:20:51 +02:00
if ( workerScript . shouldLog ( "sellShort" ) ) { workerScript . log ( resultTxt ) ; }
2019-04-23 10:48:15 +02:00
} else {
2019-04-28 04:20:51 +02:00
dialogBoxCreate ( resultTxt ) ;
2019-04-23 10:48:15 +02:00
}
return true ;
}
export function processStockPrices ( numCycles = 1 ) {
if ( StockMarket . storedCycles == null || isNaN ( StockMarket . storedCycles ) ) { StockMarket . storedCycles = 0 ; }
StockMarket . storedCycles += numCycles ;
// Stock Prices updated every 6 seconds on average. But if there are stored
// cycles they update 50% faster, so every 4 seconds
const msPerStockUpdate = 6 e3 ;
const cyclesPerStockUpdate = msPerStockUpdate / CONSTANTS . MilliPerCycle ;
if ( StockMarket . storedCycles < cyclesPerStockUpdate ) { return ; }
const timeNow = new Date ( ) . getTime ( ) ;
if ( timeNow - StockMarket . lastUpdate < 4 e3 ) { return ; }
StockMarket . lastUpdate = timeNow ;
StockMarket . storedCycles -= cyclesPerStockUpdate ;
var v = Math . random ( ) ;
for ( var name in StockMarket ) {
if ( StockMarket . hasOwnProperty ( name ) ) {
var stock = StockMarket [ name ] ;
if ( ! ( stock instanceof Stock ) ) { continue ; }
var av = ( v * stock . mv ) / 100 ;
if ( isNaN ( av ) ) { av = .02 ; }
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 ; }
}
if ( stock . price >= stock . cap ) {
chc = 0.1 ; // "Soft Limit" on stock price. It could still go up but its unlikely
stock . b = false ;
}
var c = Math . random ( ) ;
if ( c < chc ) {
stock . price *= ( 1 + av ) ;
processOrders ( stock , OrderTypes . LimitBuy , PositionTypes . Short ) ;
processOrders ( stock , OrderTypes . LimitSell , PositionTypes . Long ) ;
processOrders ( stock , OrderTypes . StopBuy , PositionTypes . Long ) ;
processOrders ( stock , OrderTypes . StopSell , PositionTypes . Short ) ;
} else {
stock . price /= ( 1 + av ) ;
processOrders ( stock , OrderTypes . LimitBuy , PositionTypes . Long ) ;
processOrders ( stock , OrderTypes . LimitSell , PositionTypes . Short ) ;
processOrders ( stock , OrderTypes . StopBuy , PositionTypes . Short ) ;
processOrders ( stock , OrderTypes . StopSell , PositionTypes . Long ) ;
}
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 > 50 ) { stock . otlkMag = 50 ; } // Cap so the "forecast" is between 0 and 100
if ( stock . otlkMag < 0 ) {
stock . otlkMag *= - 1 ;
stock . b = ! stock . b ;
}
}
}
2019-04-28 02:43:38 +02:00
displayStockMarketContent ( ) ;
2019-04-23 10:48:15 +02:00
}
//Checks and triggers any orders for the specified stock
function processOrders ( stock , orderType , posType ) {
var orderBook = StockMarket [ "Orders" ] ;
if ( orderBook == null ) {
var orders = { } ;
for ( var name in StockMarket ) {
if ( StockMarket . hasOwnProperty ( name ) ) {
var stock = StockMarket [ name ] ;
if ( ! ( stock instanceof Stock ) ) { continue ; }
orders [ stock . symbol ] = [ ] ;
}
}
StockMarket [ "Orders" ] = orders ;
return ; //Newly created, so no orders to process
}
var stockOrders = orderBook [ stock . symbol ] ;
if ( stockOrders == null || ! ( stockOrders . constructor === Array ) ) {
console . log ( "ERROR: Invalid Order book for " + stock . symbol + " in processOrders()" ) ;
stockOrders = [ ] ;
return ;
}
for ( var i = 0 ; i < stockOrders . length ; ++ i ) {
var order = stockOrders [ i ] ;
if ( order . type === orderType && order . pos === posType ) {
switch ( order . type ) {
case OrderTypes . LimitBuy :
if ( order . pos === PositionTypes . Long && stock . price <= order . price ) {
executeOrder /*66*/ ( order ) ;
} else if ( order . pos === PositionTypes . Short && stock . price >= order . price ) {
executeOrder /*66*/ ( order ) ;
}
break ;
case OrderTypes . LimitSell :
if ( order . pos === PositionTypes . Long && stock . price >= order . price ) {
executeOrder /*66*/ ( order ) ;
} else if ( order . pos === PositionTypes . Short && stock . price <= order . price ) {
executeOrder /*66*/ ( order ) ;
}
break ;
case OrderTypes . StopBuy :
if ( order . pos === PositionTypes . Long && stock . price >= order . price ) {
executeOrder /*66*/ ( order ) ;
} else if ( order . pos === PositionTypes . Short && stock . price <= order . price ) {
executeOrder /*66*/ ( order ) ;
}
break ;
case OrderTypes . StopSell :
if ( order . pos === PositionTypes . Long && stock . price <= order . price ) {
executeOrder /*66*/ ( order ) ;
} else if ( order . pos === PositionTypes . Short && stock . price >= order . price ) {
executeOrder /*66*/ ( order ) ;
}
break ;
default :
console . log ( "Invalid order type: " + order . type ) ;
return ;
}
}
}
}
let stockMarketContainer = null ;
function setStockMarketContainer ( ) {
stockMarketContainer = document . getElementById ( "stock-market-container" ) ;
document . removeEventListener ( "DOMContentLoaded" , setStockMarketContainer ) ;
}
document . addEventListener ( "DOMContentLoaded" , setStockMarketContainer ) ;
function initStockMarketFnForReact ( ) {
initStockMarket ( ) ;
initSymbolToStockMap ( ) ;
}
export function displayStockMarketContent ( ) {
if ( ! routing . isOn ( Page . StockMarket ) ) {
return ;
}
if ( stockMarketContainer instanceof HTMLElement ) {
ReactDOM . render (
< StockMarketRoot
buyStockLong = { buyStock }
buyStockShort = { shortStock }
cancelOrder = { cancelOrder }
initStockMarket = { initStockMarketFnForReact }
p = { Player }
placeOrder = { placeOrder }
sellStockLong = { sellStock }
sellStockShort = { sellShort }
stockMarket = { StockMarket }
/ > ,
stockMarketContainer
)
}
}