Advertisement
Guest User

trade.js

a guest
Nov 2nd, 2022
693
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.55 KB | Source Code | 0 0
  1. /** @param {NS} ns */
  2. let inHand = 0.25; // % of funds to keep in hand. Default 0.25
  3. let numCyclesToProject = 2; // Only buy stocks that are projected to increase for this amount of cycles. Recommended 2-5. Default 2
  4. let expectedRetentionLossToSell = -0.40; // Percent change between initial forecast and current forcast. ie if current forecast is 40% worse than initial, sell. Default -0.40
  5. let commission = 100000; // Current Buy/Sell Comission cost
  6.  
  7.  
  8. function pChange(ns, sym, oldNum, newNum){
  9. const diff = newNum < oldNum ? -(oldNum - newNum) : newNum - oldNum;
  10. let pdiff = diff / oldNum;
  11. ns.print(` ${sym}:\t| ${oldNum.toFixed(5)} -> ${newNum.toFixed(5)}\t| ${(pdiff*100).toFixed(3)}%`);
  12. return pdiff
  13. }
  14.  
  15. function format(num){
  16. let symbols = ["","K","M","B","T","Qa","Qi","Sx","Sp","Oc"];
  17. let i = 0;
  18. let neg = num < 0;
  19. if(neg) num = -num;
  20.  
  21. for(; (num >= 1000) && (i < symbols.length); i++) num /= 1000;
  22.  
  23. return ( (neg)?"-$":"$") + num.toFixed(3) + symbols[i];
  24. }
  25.  
  26. function getStocks(ns, stocks, myStocks){
  27. let corpus = ns.getServerMoneyAvailable("home");
  28. myStocks.length = 0;
  29. for(let i = 0; i < stocks.length; i++){
  30. let sym = stocks[i].sym;
  31. stocks[i].askPrice = ns.stock.getAskPrice(sym);
  32. stocks[i].bidPrice = ns.stock.getBidPrice(sym);
  33. stocks[i].shares = ns.stock.getPosition(sym)[0];
  34. stocks[i].buyPrice = ns.stock.getPosition(sym)[1];
  35. stocks[i].vol = ns.stock.getVolatility(sym);
  36. stocks[i].prob = 2* (ns.stock.getForecast(sym) - 0.5);
  37. stocks[i].expRet = stocks[i].vol * stocks[i].prob / 2;
  38. if (stocks[i].shares > 0){
  39. stocks[i].initExpRet ||= stocks[i].expRet;
  40. }else {
  41. stocks[i].initExpRet = null;
  42. }
  43.  
  44. corpus += stocks[i].askPrice * stocks[i].shares;
  45. if(stocks[i].shares > 0) myStocks.push(stocks[i]);
  46. }
  47. stocks.sort(function(a, b){return b.expRet - a.expRet});
  48. return corpus;
  49. }
  50.  
  51. async function buy(ns, stock, numShares) {
  52. const max = ns.stock.getMaxShares(stock.sym)
  53. numShares = max < numShares ? max : numShares;
  54.  
  55. await ns.stock.buyStock(stock.sym, numShares);
  56. ns.print(`Bought ${stock.sym} for ${format((numShares * stock.askPrice) + commission)}`);
  57. }
  58.  
  59. async function sell(ns, stock, numShares) {
  60. let profit = (numShares * (stock.bidPrice - stock.buyPrice)) - (2 * commission);
  61. await ns.stock.sellStock(stock.sym, numShares);
  62. ns.print(`Sold ${stock.sym} for profit of ${format(profit)}`);
  63. }
  64.  
  65.  
  66. export async function main(ns) {
  67. //Initialise
  68. ns.disableLog("ALL");
  69. let stocks = [...ns.stock.getSymbols().map(_sym => {return {sym: _sym}})];
  70. let myStocks = [];
  71. let corpus = 0;
  72.  
  73.  
  74. while (true) {
  75. corpus = getStocks(ns, stocks, myStocks);
  76.  
  77. //Symbol, Initial Return, Current Return, The % change between
  78. // the Initial Return and the Current Return.
  79. ns.print("Currently Owned Stocks:");
  80. ns.print(" SYM\t| InitReturn -> CurReturn | % change");
  81.  
  82. //Sell underperforming shares
  83. for (let i = 0; i < myStocks.length; i++) {
  84. if (pChange(ns, myStocks[i].sym, myStocks[i].initExpRet, myStocks[i].expRet) <= expectedRetentionLossToSell)
  85. await sell(ns, myStocks[i], myStocks[i].shares);
  86.  
  87. if (myStocks[i].expRet <= 0)
  88. await sell(ns, myStocks[i], myStocks[i].shares);
  89.  
  90. corpus -= commission;
  91. }
  92.  
  93. ns.print("----------------------------------------");
  94.  
  95. ns.print(" SYM\t| $ invested\t| $ profit");
  96. for (let i = 0; i < myStocks.length; i++) {
  97. ns.print(` ${myStocks[i].sym}:\t| ${format(myStocks[i].shares * myStocks[i].buyPrice)}\t| ${format((myStocks[i].shares * (myStocks[i].bidPrice - myStocks[i].buyPrice))- (2 * commission))}`);
  98. }
  99.  
  100.  
  101. ns.print("________________________________________");
  102.  
  103. //Buy shares with cash remaining in hand
  104. for (let stock of stocks) {
  105.  
  106. if (stock.shares > 0) continue;
  107. if (stock.expRet <= 0) continue;
  108. let cashToSpend = ns.getServerMoneyAvailable("home") - (inHand * corpus);
  109. let numShares = Math.floor((cashToSpend - commission) / stock.askPrice);
  110. if ((numShares * stock.expRet * stock.askPrice * numCyclesToProject) > (commission * 2))
  111. await buy(ns, stock, numShares);
  112. break;
  113. }
  114.  
  115. await ns.sleep(5 * 1000 * numCyclesToProject + 200);
  116. }
  117. }
Advertisement
Comments
  • Parkinwad
    2 years (edited)
    # text 0.89 KB | 0 0
    1. This is for long positions only.
    2. Changes made from original:
    3. line 31 was edited from "getPrice" to "getAskPrice"
    4. line 32 was added for sell side of transaction to be accurate
    5. line 44 was changed to .askPrice from .price
    6. line 56: changed .price to .askPrice and added commission to printout calculation.
    7. line 60: changed profit calculation to use the bidPrice since that is what is used when a stock is sold long, thereby making the printout calculation in line 62 accurate as well. Not sure if the commission portion of that line I added is accurate. Need to check the code again.
    8. line 97: changed ".price" to ".bidPrice" to properly show the profit if stock is sold during that cycle.
    9. line 109: changed ".price" to ".askPrice"
    10. line 110: changed to 2 * commission in order to take into account both purchase and sale commissions when deciding profits on a stock. Won't make much of a difference TBH.
Add Comment
Please, Sign In to add comment
Advertisement