moriakaice / bitburner

Collection of scripts for https://danielyxie.github.io/bitburner/
ISC License
117 stars 144 forks source link

Update to v1.0.0 #9

Closed hydroflame closed 2 years ago

Belelusat commented 2 years ago

Allows functionality on 1.1.0 as well.

lapryx commented 2 years ago

it seems to multiply the hack, weaken and grow times by 1000, in my game i removed the * 1000 multiplier

Ahriman-8819 commented 2 years ago

it seems to multiply the hack, weaken and grow times by 1000, in my game i removed the * 1000 multiplier

According to https://bitburner.readthedocs.io/en/latest/v1.0.0_migration.html getHack(-Grow/-Weaken)Time "will return milliseconds instead of seconds."

archraziel commented 2 years ago

Is this supposed to take hours?

mainHack.ns: [08:42:51] Starting mainHack.ns mainHack.ns: [08:42:51] Selected phantasy for a target. Planning to grow the server. Will wake up around 11:33:53 mainHack.ns: [08:42:51] Stock values: baseSecurity: 20; minSecurity: 7; maxMoney: $600,000,000 mainHack.ns: [08:42:51] Current values: security: 7; money: $24,000,000 mainHack.ns: [08:42:51] Time to: hack: 18:42:45; grow: 11:52:48; weaken: 02:51:01 mainHack.ns: [08:42:51] Delays: 08:07:45 for hacks, 14:57:57 for grows mainHack.ns: [08:42:51] Cycles ratio: 259 grow cycles; 23 weaken cycles

Belelusat commented 2 years ago

Is this supposed to take hours?

mainHack.ns: [08:42:51] Starting mainHack.ns mainHack.ns: [08:42:51] Selected phantasy for a target. Planning to grow the server. Will wake up around 11:33:53 mainHack.ns: [08:42:51] Stock values: baseSecurity: 20; minSecurity: 7; maxMoney: $600,000,000 mainHack.ns: [08:42:51] Current values: security: 7; money: $24,000,000 mainHack.ns: [08:42:51] Time to: hack: 18:42:45; grow: 11:52:48; weaken: 02:51:01 mainHack.ns: [08:42:51] Delays: 08:07:45 for hacks, 14:57:57 for grows mainHack.ns: [08:42:51] Cycles ratio: 259 grow cycles; 23 weaken cycles

Note: I am still a novice, but I will share what I have found. if you edit mainHack.ns around line 180 you will find: const hackTime = ns.getHackTime(bestTarget) 1000 const growTime = ns.getGrowTime(bestTarget) 1000 const weakenTime = ns.getWeakenTime(bestTarget) * 1000

rreplace the " 1000" with " 1" or just remove that section in each of those lines. This is what lapryx was referencing to I believe. Even if it isn't I have had the script behave much better after that change.

Ahriman-8819 commented 2 years ago

Note: I am still a novice, but I will share what I have found. if you edit mainHack.ns around line 180 you will find: const hackTime = ns.getHackTime(bestTarget) 1000 const growTime = ns.getGrowTime(bestTarget) 1000 const weakenTime = ns.getWeakenTime(bestTarget) * 1000

rreplace the " 1000" with " 1" or just remove that section in each of those lines. This is what lapryx was referencing to I believe. Even if it isn't I have had the script behave much better after that change.

also in const growDelay = Math.max(0, weakenTime - growTime - 15 1000) const hackDelay = Math.max(0, growTime + growDelay - hackTime - 15 1000) a few lines below.

archraziel commented 2 years ago

Is this supposed to take hours? mainHack.ns: [08:42:51] Starting mainHack.ns mainHack.ns: [08:42:51] Selected phantasy for a target. Planning to grow the server. Will wake up around 11:33:53 mainHack.ns: [08:42:51] Stock values: baseSecurity: 20; minSecurity: 7; maxMoney: $600,000,000 mainHack.ns: [08:42:51] Current values: security: 7; money: $24,000,000 mainHack.ns: [08:42:51] Time to: hack: 18:42:45; grow: 11:52:48; weaken: 02:51:01 mainHack.ns: [08:42:51] Delays: 08:07:45 for hacks, 14:57:57 for grows mainHack.ns: [08:42:51] Cycles ratio: 259 grow cycles; 23 weaken cycles

Note: I am still a novice, but I will share what I have found. if you edit mainHack.ns around line 180 you will find: const hackTime = ns.getHackTime(bestTarget) 1000 const growTime = ns.getGrowTime(bestTarget) 1000 const weakenTime = ns.getWeakenTime(bestTarget) * 1000

rreplace the " 1000" with " 1" or just remove that section in each of those lines. This is what lapryx was referencing to I believe. Even if it isn't I have had the script behave much better after that change.

Thanks. I was trying to remove all the 1000 and see if it stills works xD

After removing the * 1000 it seems it behaves better

mainHack.ns: [08:54:35] Selected phantasy for a target. Planning to grow the server. Will wake up around 08:59:04 mainHack.ns: [08:54:35] Stock values: baseSecurity: 20; minSecurity: 7; maxMoney: $600,000,000 mainHack.ns: [08:54:35] Current values: security: 7; money: $24,000,000 mainHack.ns: [08:54:35] Time to: hack: 00:01:07; grow: 00:03:35; weaken: 00:04:29 mainHack.ns: [08:54:35] Delays: 00:03:22 for hacks, 00:00:53 for grows mainHack.ns: [08:54:35] Cycles ratio: 259 grow cycles; 23 weaken cycles

archraziel commented 2 years ago

I fixed stockMarketer4S.ns. It requires bitnode 8 to run. does anyone have a stock script for starters?


let stockSymbols
let corpus
let underperformingShares
const commission = 100000

function localeHHMMSS(ms = 0) {
  if (!ms) {
    ms = new Date().getTime()
  }

  return new Date(ms).toLocaleTimeString()
}

function getMoney(ns) {
  return ns.getServerMoneyAvailable('home') - 5 * commission
}

function sellShorts(ns, stockSymbol) {
  const stockInfo = getStockInfo(ns, stockSymbol)
  const shortSellValue = ns.stock.sellShort(stockSymbol, stockInfo.sharesShort)

  if (shortSellValue) {
    corpus += stockInfo.sharesShort * (stockInfo.avgPriceShort - shortSellValue) - 2 * commission
    ns.print(
      `[${localeHHMMSS()}][${stockSymbol}] Sold ${stockInfo.sharesShort} shorts for ${ns.nFormat(shortSellValue, '$0.000a')}. Profit: ${ns.nFormat(
        stockInfo.sharesLong * (stockInfo.avgPriceShort - shortSellValue) - 2 * commission,
        '$0.000a'
      )}`
    )
  }
}

function sellLongs(ns, stockSymbol) {
  const stockInfo = getStockInfo(ns, stockSymbol)
  const longSellValue = ns.stock.sell(stockSymbol, stockInfo.sharesLong)

  if (longSellValue) {
    corpus += stockInfo.sharesLong * (longSellValue - stockInfo.avgPriceLong) - 2 * commission
    ns.print(
      `[${localeHHMMSS()}][${stockSymbol}] Sold ${stockInfo.sharesLong} longs for ${ns.nFormat(longSellValue, '$0.000a')}. Profit: ${ns.nFormat(
        stockInfo.sharesLong * (longSellValue - stockInfo.avgPriceLong) - 2 * commission,
        '$0.000a'
      )}`
    )
  }
}

// Only if not going to lose money
function sellUnderperforming(ns, stockSymbol) {
  const stockInfo = getStockInfo(ns, stockSymbol)

  if (stockInfo.sharesShort && stockInfo.sharesShort * (stockInfo.avgPriceShort - stockInfo.stockAskPrice) > 2 * commission) {
    sellShorts(ns, stockSymbol)
  }

  if (stockInfo.sharesLong && stockInfo.sharesLong * (stockInfo.stockBidPrice - stockInfo.avgPriceLong) > 2 * commission) {
    sellLongs(ns, stockSymbol)
  }
}

function sellWrongPosition(ns, stockSymbol) {
  const stockInfo = getStockInfo(ns, stockSymbol)

  // Sell shorts if going up
  if (stockInfo.position === 'Long' && stockInfo.sharesShort) {
    sellShorts(ns, stockSymbol)
  }

  // Sell longs if going down
  if (stockInfo.position === 'Short' && stockInfo.sharesLong) {
    sellLongs(ns, stockSymbol)
  }
}

function buyNewShares(ns, stockSymbol) {
  const stockInfo = getStockInfo(ns, stockSymbol)
  const minimumMoneyToInvest = 10 * commission

  if (!stockInfo.haveMaxShares && getMoney(ns) > minimumMoneyToInvest) {
    let maxSharesToBuy
    let sharesToBuy
    let buyValue
    let shareType

    if (stockInfo.position === 'Long') {
      maxSharesToBuy = stockInfo.maxShares - stockInfo.sharesLong
      sharesToBuy = Math.max(0, Math.min(maxSharesToBuy, Math.floor(getMoney(ns) / stockInfo.stockAskPrice)))
      if (sharesToBuy) {
        buyValue = ns.buyStock(stockSymbol, sharesToBuy)
      }
      shareType = 'longs'
    } else {
      maxSharesToBuy = stockInfo.maxShares - stockInfo.sharesShort
      sharesToBuy = Math.max(0, Math.min(maxSharesToBuy, Math.floor(getMoney(ns) / stockInfo.stockBidPrice)))
      if (sharesToBuy) {
        buyValue =ns.stock.short(stockSymbol, sharesToBuy)
      }
      shareType = 'shorts'
    }

    if (sharesToBuy) {
      const invested = ns.nFormat(buyValue * sharesToBuy, '$0.000a')
      ns.print(`[${localeHHMMSS()}][${stockSymbol}] Bought ${sharesToBuy} ${shareType} for ${ns.nFormat(buyValue, '$0.000a')} each. Invested: ${invested}`)
    }
  }
}

function getStockInfo(ns, stockSymbol) {
  const [sharesLong, avgPriceLong, sharesShort, avgPriceShort] = ns.stock.getPosition(stockSymbol);
  const volatility = ns.stock.getVolatility(stockSymbol)
  const probability = ns.stock.getForecast(stockSymbol) - 0.5
  const expectedReturn = Math.abs(volatility * probability)
  const maxShares = ns.stock.getMaxShares(stockSymbol)

  const haveAnyShares = sharesLong + sharesShort > 0
  const haveMaxShares = sharesLong + sharesShort === maxShares

  const stockAskPrice = ns.stock.getAskPrice(stockSymbol)
  const stockBidPrice = ns.stock.getBidPrice(stockSymbol)

  const position = probability >= 0 ? 'Long' : 'Short'

  return {
    stockSymbol,
    maxShares,
    haveAnyShares,
    haveMaxShares,
    sharesLong,
    avgPriceLong,
    stockAskPrice,
    sharesShort,
    avgPriceShort,
    stockBidPrice,
    volatility,
    probability,
    expectedReturn,
    position,
  }
}

export async function main(ns) {
  ns.disableLog('ALL')
  let tickCounter = 1

  stockSymbols = ns.stock.getSymbols();

  corpus = ns.getServerMoneyAvailable('home') - 1000000
  stockSymbols.forEach((stockSymbol) => {
    const stockInfo = getStockInfo(ns, stockSymbol)

    corpus += stockInfo.sharesLong * stockInfo.avgPriceLong + stockInfo.sharesShort * stockInfo.avgPriceShort
  })
  const startingCorpus = corpus

  while (true) {
    ns.clearLog()
    ns.print(`[${localeHHMMSS()}] Tick counter: ${tickCounter}, corpus: ${ns.nFormat(corpus, '$0.000a')}`)
    ns.print(`[${localeHHMMSS()}] Starting corpus: ${ns.nFormat(startingCorpus, '$0.000a')}`)

    stockSymbols.sort((a, b) => {
      const stockA = getStockInfo(ns, a)
      const stockB = getStockInfo(ns, b)

      if (stockB.expectedReturn === stockA.expectedReturn) {
        return Math.abs(stockB.probability) - Math.abs(stockA.probability)
      }

      return stockB.expectedReturn - stockA.expectedReturn
    })

    stockSymbols
      .filter((stockSymbol) => getStockInfo(ns, stockSymbol).haveAnyShares)
      .filter((stockSymbol, index) => stockSymbol !== stockSymbols[index])
      .forEach((stockSymbol) => sellUnderperforming(ns, stockSymbol))
    await ns.sleep(5)

    stockSymbols.forEach((stockSymbol) => sellWrongPosition(ns, stockSymbol))
    await ns.sleep(5)

    stockSymbols.forEach((stockSymbol) => buyNewShares(ns, stockSymbol))
    await ns.sleep(5)

    ns.print(`[${localeHHMMSS()}] After transactions: corpus: ${ns.nFormat(corpus, '$0.000a')}`)
    await ns.sleep(3500)
    tickCounter++
  }
}
lapryx commented 2 years ago

stockmaster4.ns is a Tix only based script as far as i know. It is not working in my game on steam tho as it doesn't recognize the TIX api functions.

archraziel commented 2 years ago

stockmaster4.ns is a Tix only based script as far as i know. It is not working in my game on steam tho as it doesn't recognize the TIX api functions.

Yea. TIX is not recognized. I used ns.stock. But ns.stock.short need bitnode 8

Hordeq commented 2 years ago

I fixed stockMarketer4S.ns. It requires bitnode 8 to run. does anyone have a stock script for starters?

Someone wrote an adequate one here: https://www.reddit.com/r/Bitburner/comments/qvqwkw/help_with_stock_market_script/

lapryx commented 2 years ago

stockmaster4.ns is a Tix only based script as far as i know. It is not working in my game on steam tho as it doesn't recognize the TIX api functions.

Yea. TIX is not recognized. I used ns.stock. But ns.stock.short need bitnode 8

it seems that the stock keyword has been moved from say ns.buyStock() to ns.stock.buy(), this is pretty easy to replace across a file. i modified the stock-marketer4s file to comment out all short related code, with this it works without the bitnode

BasTijs commented 2 years ago

Should there be *1000 at the top in line 9 and 10? I removed all 5 around line 180

lapryx commented 2 years ago

yes, the sleeptime is based in milliseconds aswell as the getXtime functions return the time in milliseconds. so this makes sure that the max weaken time is 30 min and the map is refreshed every 24 hours.

mazowo commented 2 years ago

also in const growDelay = Math.max(0, weakenTime - growTime - 15 1000) const hackDelay = Math.max(0, growTime + growDelay - hackTime - 15 1000) a few lines below.

This isn't quite correct. These two lines should keep the * 1000, as it simply multiplies the 15 seconds to 15000 milliseconds. Unlike the "getXTime" functions, this is just a static equation and didn't get changed by the game devs. It's to note, that both removing it and not removing it works, however, if you remove it you lose a tiny bit of efficiency. (15 seconds extra on each delay)

In summary, if you have an issue with your wake up times being astronomically high:

and you should be good to go.