Advertisement
Guest User

bitburner basic stock script

a guest
Dec 28th, 2021
2,389
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //Requires access to the TIX API and the 4S Mkt Data API
  2. const THRESHOLD_CASH_GOAL = 0.4; // Fraction of cash to aim to keep in hand
  3. const THRESHOLD_CASH_LOW = 0.1; // Fraction of cash in hand sale back to goal threshold
  4.  
  5. // Probability stock will increase is a value between 0 and 1.
  6. const THRESHOLD_SELL = 0.5; // Probability we should start sell at if under.
  7. const THRESHOLD_BUY = 0.5; // Probability we should start buying at if over
  8.  
  9. const COMMISSION = 100000; //Buy or sell commission
  10. const REFRESH = 5200; // time to wait between stock price refreshes
  11.  
  12. /** @param {NS} ns **/
  13. export async function main(ns) {
  14.     let rollingProfit = 0;
  15.     if (ns.args[0] == "sellall") {
  16.         ns.tprint("selling all stocks");
  17.         const allStocks = refreshStocks(ns);
  18.         allStocks.filter((stk) => stk.shares > 0).forEach((stk) =>{
  19.             rollingProfit += sell(ns, stk, stk.shares, true);
  20.         });
  21.         ns.tprint(`made ~${format(rollingProfit)}`);
  22.         return;
  23.     }
  24.     //Initialise
  25.     ns.disableLog("ALL");
  26.     while (true) {
  27.         // get current stock info with highest return chance first.
  28.         const allStocks = refreshStocks(ns);
  29.         // get my stocks but sorted by weakest return chance
  30.         const myStocks = allStocks.filter((stock) => stock.shares > 0).sort(function (a, b) { return a.prob - b.prob });
  31.         const holdingPrice = allStocks.reduce((prev, stock) => prev += (stock.price * stock.shares), 0);
  32.         const boughtPrice = allStocks.reduce((prev, stock) => prev += (stock.avgBuyPrice * stock.shares), 0);
  33.         ns.print(`holding ${format(holdingPrice)} for current gain of ${format(holdingPrice - boughtPrice)}`);
  34.         let corpus = ns.getServerMoneyAvailable("home") + holdingPrice;
  35.         ns.print(`corpus ${format(corpus)}`);
  36.         ns.print(`actual profit: ${format(rollingProfit)}`);
  37.  
  38.         //Sell underperforming shares
  39.         myStocks.forEach((stock) => {
  40.             if (stock.prob < THRESHOLD_SELL) {
  41.                 rollingProfit += sell(ns, stock, stock.shares);
  42.                 corpus -= COMMISSION;
  43.             }
  44.         });
  45.  
  46.         // Sell shares if not enough cash in hand (start lowest return);
  47.         myStocks.forEach((stock) => {
  48.             const homeMoney = ns.getServerMoneyAvailable("home");
  49.             if (homeMoney < (THRESHOLD_CASH_LOW * corpus)) {
  50.                 ns.print(`need money, selling stocks`);
  51.                 let cashNeeded = (corpus * THRESHOLD_CASH_GOAL - homeMoney + COMMISSION);
  52.                 let numShares = Math.floor(cashNeeded / stock.price);
  53.                 rollingProfit += sell(ns, myStocks[i], numShares);
  54.                 corpus -= COMMISSION;
  55.             }
  56.         });
  57.  
  58.         //Buy shares with cash remaining in hand
  59.         let cashToSpend = ns.getServerMoneyAvailable("home") - (corpus * THRESHOLD_CASH_GOAL);
  60.         allStocks.filter((stock)=> (stock.prob > THRESHOLD_BUY && stock.remainingShares > 0)).forEach((stock)=>{
  61.             let numShares = Math.min(Math.floor((cashToSpend - COMMISSION) / stock.price), stock.remainingShares);
  62.             if (numShares > 0) {
  63.                 const spent = buy(ns, stock, numShares);
  64.                 cashToSpend -= spent;
  65.             }
  66.         });
  67.         await ns.sleep(REFRESH);
  68.     }
  69. }
  70.  
  71. /** @param {NS} ns **/
  72. function refreshStocks(ns) {
  73.     return ns.stock.getSymbols().map((sym)=> {
  74.         const position = ns.stock.getPosition(sym);
  75.         const price = ns.stock.getPrice(sym);
  76.         const shares = position[0];
  77.         const avgBuyPrice = position[1];
  78.         const prob = ns.stock.getForecast(sym);
  79.         const remainingShares = ns.stock.getMaxShares(sym) - shares;
  80.         return {
  81.             sym,
  82.             price,
  83.             shares,
  84.             avgBuyPrice,
  85.             prob,
  86.             remainingShares
  87.         };
  88.     }).sort(function (a, b) { return b.prob - a.prob });
  89. }
  90.  
  91. /** @param {NS} ns **/
  92. function buy(ns, stock, numShares) {
  93.     const price = ns.stock.buy(stock.sym, numShares);
  94.     ns.print(`Bought ${stock.sym} for ${format(numShares * stock.price)}`);
  95.     return price * numShares + COMMISSION;
  96. }
  97.  
  98. /** @param {NS} ns **/
  99. function sell(ns, stock, numShares, isSellAll) {
  100.     let profit = numShares * (stock.price - stock.avgBuyPrice) - 2 * COMMISSION;
  101.     if (!isSellAll) {
  102.         ns.print(`Sold ${stock.sym} for profit of ${format(profit)}`);
  103.     } else {
  104.         ns.tprint(`Sold ${stock.sym} for profit of ${format(profit)}`);
  105.     }
  106.     ns.stock.sell(stock.sym, numShares);
  107.     return profit;
  108. }
  109.  
  110. function format(num) {
  111.     let symbols = ["", "K", "M", "B", "T", "Qa", "Qi", "Sx", "Sp", "Oc"];
  112.     let i;
  113.     for (i = 0; (Math.abs(num) >= 1000) && (i < symbols.length); i++) {
  114.         num /= 1000;
  115.     }
  116.     return ((Math.sign(num) < 0) ? "-$" : "$") + Math.abs(num.toFixed(3)) + symbols[i];
  117. }
  118.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement