股票账户模拟生成器,股票交割单生成器,证券持仓收益曲线图

简介: 完整的股票模拟系统包含账户管理、交易记录和可视化分析三大模块,使用纯JavaScript实现

下载地址:https://www.pan38.com/share.php?code=JCnzE 提取密码:7789

完整的股票模拟系统包含账户管理、交易记录和可视化分析三大模块,使用纯JavaScript实现。核心功能包括模拟股票价格波动、买卖交易、生成交割单和绘制收益曲线图。代码采用面向对象设计,各模块职责分明,可通过扩展实现更复杂的金融分析功能。

class StockAccountSimulator {
constructor(initialBalance = 100000) {
this.balance = initialBalance;
this.portfolio = {};
this.transactionHistory = [];
this.stockData = this.generateMockStockData();
}

generateMockStockData() {
const stocks = ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'TSLA', 'NVDA', 'META', 'BABA', 'JD', 'NIO'];
return stocks.reduce((acc, symbol) => {
acc[symbol] = {
currentPrice: Math.random() 500 + 50,
volatility: Math.random()
0.3 + 0.1,
dividendYield: Math.random() * 0.03
};
return acc;
}, {});
}

updateStockPrices() {
Object.keys(this.stockData).forEach(symbol => {
const stock = this.stockData[symbol];
const change = (Math.random() 2 - 1) stock.volatility;
stock.currentPrice *= (1 + change);
stock.currentPrice = Math.max(10, stock.currentPrice);
});
}

buyStock(symbol, quantity) {
if (!this.stockData[symbol]) throw new Error('Invalid stock symbol');
const price = this.stockData[symbol].currentPrice;
const cost = price * quantity;

if (cost > this.balance) throw new Error('Insufficient funds');

this.balance -= cost;
this.portfolio[symbol] = (this.portfolio[symbol] || 0) + quantity;

this.transactionHistory.push({
  type: 'BUY',
  symbol,
  quantity,
  price,
  timestamp: new Date(),
  remainingBalance: this.balance
});

return { success: true, newBalance: this.balance };

}

sellStock(symbol, quantity) {
if (!this.portfolio[symbol] || this.portfolio[symbol] < quantity) {
throw new Error('Not enough shares to sell');
}

const price = this.stockData[symbol].currentPrice;
const proceeds = price * quantity;

this.balance += proceeds;
this.portfolio[symbol] -= quantity;
if (this.portfolio[symbol] === 0) delete this.portfolio[symbol];

this.transactionHistory.push({
  type: 'SELL',
  symbol,
  quantity,
  price,
  timestamp: new Date(),
  remainingBalance: this.balance
});

return { success: true, newBalance: this.balance };

}

generateTradeConfirmation(transactionId) {
const transaction = this.transactionHistory[transactionId];
if (!transaction) throw new Error('Invalid transaction ID');

return `
  TRADE CONFIRMATION #${transactionId}
  ----------------------------
  Type: ${transaction.type}
  Symbol: ${transaction.symbol}
  Quantity: ${transaction.quantity}
  Price: $${transaction.price.toFixed(2)}
      Amount: $${(transaction.price * transaction.quantity).toFixed(2)}
  Date: ${transaction.timestamp.toLocaleString()}
  Remaining Balance: $${transaction.remainingBalance.toFixed(2)}
    `;
  }
}


 TradeLedgerGenerator {
  constructor(simulator) {
    this.simulator = simulator;
  }

  generateDailyLedger(date = new Date()) {
    const dateStr = date.toISOString().split('T')[0];
    const dailyTrades = this.simulator.transactionHistory.filter(
      t => t.timestamp.toISOString().split('T')[0] === dateStr
    );
    
    if (dailyTrades.length === 0) return 'No trades on this date';
    
    let ledger = `DAILY TRADE LEDGER - ${dateStr}\n`;
    ledger += '='.repeat(50) + '\n';
    
    dailyTrades.forEach((trade, idx) => {
      ledger += `Trade #${idx + 1}\n`;
      ledger += `  Type: ${trade.type.padEnd(6)} `;
      ledger += `Symbol: ${trade.symbol.padEnd(6)} `;
      ledger += `Qty: ${trade.quantity.toString().padEnd(6)} `;
      ledger += `Price: $${trade.price.toFixed(2).padEnd(8)} `;
  ledger += `Amount: $${(trade.price * trade.quantity).toFixed(2)}\n`;
    });
    
    const totalBuy = dailyTrades
      .filter(t => t.type === 'BUY')
      .reduce((sum, t) => sum + t.price * t.quantity, 0);
    
    const totalSell = dailyTrades
      .filter(t => t.type === 'SELL')
      .reduce((sum, t) => sum + t.price * t.quantity, 0);
    
    ledger += '\nSUMMARY:\n';
    ledger += `  Total Buy: $${totalBuy.toFixed(2)}\n`;
ledger += `  Total Sell: $${totalSell.toFixed(2)}\n`;
    ledger += `  Net Change: $${(totalSell - totalBuy).toFixed(2)}\n`;
ledger += '='.repeat(50);

return ledger;

}

generatePortfolioStatement() {
let statement = PORTFOLIO STATEMENT - ${new Date().toLocaleDateString()}\n;
statement += '='.repeat(50) + '\n';

let totalValue = 0;
Object.keys(this.simulator.portfolio).forEach(symbol => {
  const quantity = this.simulator.portfolio[symbol];
  const price = this.simulator.stockData[symbol].currentPrice;
  const value = price * quantity;
  totalValue += value;

  statement += `${symbol.padEnd(6)}: `;
  statement += `${quantity.toString().padEnd(6)} shares @ `;
  statement += `$${price.toFixed(2).padEnd(8)} = `;
      statement += `$${value.toFixed(2)}\n`;
});

statement += '\nSUMMARY:\n';
statement += `  Cash Balance: $${this.simulator.balance.toFixed(2)}\n`;
    statement += `  Stock Value: $${totalValue.toFixed(2)}\n`;
statement += `  Total Assets: $${(this.simulator.balance + totalValue).toFixed(2)}\n`;
    statement += '='.repeat(50);
    
    return statement;
  }
}



class PerformanceChart {
  constructor(simulator) {
    this.simulator = simulator;
    this.historicalData = [];
    this.recordDailySnapshot();
  }

  recordDailySnapshot() {
    const snapshot = {
      date: new Date(),
      cash: this.simulator.balance,
      holdings: {},
      totalValue: this.simulator.balance
    };
    
    Object.keys(this.simulator.portfolio).forEach(symbol => {
      const quantity = this.simulator.portfolio[symbol];
      const price = this.simulator.stockData[symbol].currentPrice;
      const value = price * quantity;
      snapshot.holdings[symbol] = value;
      snapshot.totalValue += value;
    });
    
    this.historicalData.push(snapshot);
    return snapshot;
  }

  generatePerformanceChart(days = 30) {
    const recentData = this.historicalData.slice(-days);
    if (recentData.length < 2) return 'Not enough data to generate chart';
    
    const dates = recentData.map(d => d.date.toLocaleDateString());
    const values = recentData.map(d => d.totalValue);
    const baseValue = values[0];
    const percentages = values.map(v => ((v - baseValue) / baseValue * 100).toFixed(2));
    
    let chart = 'PORTFOLIO PERFORMANCE CHART\n';
    chart += 'Date       '.padEnd(12) + 'Value      '.padEnd(12) + 'Change %  '.padEnd(12) + 'Chart\n';
    chart += '-'.repeat(60) + '\n';
    
    const maxValue = Math.max(...values);
    const minValue = Math.min(...values);
    const valueRange = maxValue - minValue;
    
    recentData.forEach((data, idx) => {
      const value = values[idx];
      const pct = percentages[idx];
      const position = Math.round(((value - minValue) / valueRange) * 20);
      
      chart += `${dates[idx].padEnd(12)}`;
      chart += `$${value.toFixed(2).padEnd(12)}`;
  chart += `${pct}%`.padEnd(12);
  chart += '|' + ' '.repeat(position) + '●' + ' '.repeat(20 - position) + '|\n';
});

chart += '-'.repeat(60) + '\n';
chart += `Starting Value: $${baseValue.toFixed(2)}\n`;
    chart += `Current Value: $${values[values.length - 1].toFixed(2)}\n`;
chart += `Total Return: ${percentages[percentages.length - 1]}%\n`;

return chart;

}

generateStockAllocationChart() {
const latest = this.historicalData[this.historicalData.length - 1];
if (!latest || Object.keys(latest.holdings).length === 0) {
return 'No stock holdings to display';
}

const total = latest.totalValue - latest.cash;
let chart = 'STOCK ALLOCATION CHART\n';
chart += '='.repeat(50) + '\n';

Object.keys(latest.holdings)
  .sort((a, b) => latest.holdings[b] - latest.holdings[a])
  .forEach(symbol => {
    const value = latest.holdings[symbol];
    const pct = (value / total * 100).toFixed(1);
    const bars = '■'.repeat(Math.round(pct / 2));

    chart += `${symbol.padEnd(6)}: `;
    chart += `${pct}% `.padEnd(6);
    chart += `${bars}\n`;
  });

chart += '='.repeat(50) + '\n';
chart += `Total Stock Value: $${total.toFixed(2)}\n`;
    chart += `Cash: $${latest.cash.toFixed(2)}\n`;
chart += `Total Portfolio: $${latest.totalValue.toFixed(2)}\n`;

return chart;

}
}

系统初始化
const simulator = new StockAccountSimulator(50000);
const ledger = new TradeLedgerGenerator(simulator);
const chart = new PerformanceChart(simulator);

// 模拟市场波动和交易
function simulateTrading(days = 30) {
for (let i = 0; i < days; i++) {
simulator.updateStockPrices();

// 随机买卖
const symbols = Object.keys(simulator.stockData);
const randomSymbol = symbols[Math.floor(Math.random() * symbols.length)];
const action = Math.random() > 0.5 ? 'BUY' : 'SELL';
const quantity = Math.floor(Math.random() * 10) + 1;

try {
  if (action === 'BUY') {
    simulator.buyStock(randomSymbol, quantity);
  } else {
    if (simulator.portfolio[randomSymbol]) {
      simulator.sellStock(randomSymbol, Math.min(quantity, simulator.portfolio[randomSymbol]));
    }
  }
} catch (e) {
  console.log(`Day ${i+1}: ${e.message}`);
}

chart.recordDailySnapshot();

}
}

// 执行模拟
simulateTrading(90);

// 输出结果
console.log('=== 最新投资组合 ===');
console.log(ledger.generatePortfolioStatement());

console.log('\n=== 最近30天表现 ===');
console.log(chart.generatePerformanceChart(30));

console.log('\n=== 股票配置 ===');
console.log(chart.generateStockAllocationChart());

console.log('\n=== 随机交易日交割单 ===');
const randomDay = new Date();
randomDay.setDate(randomDay.getDate() - Math.floor(Math.random() * 30));
console.log(ledger.generateDailyLedger(randomDay));

相关文章
|
8天前
|
人工智能 数据安全/隐私保护
抖音留痕脚本,快手小红书留痕工具,截流获客刷短视频软件
AutoJS脚本实现了完整的留痕功能,包含日志记录、定时截图、事件监听和模拟操作四大模块
|
8天前
|
人工智能 数据安全/隐私保护 C++
一键解除机器码工具,电脑机器码修改工具,永久修改机器码工具【c++】
有时候我们用一些工具的时候发现经常会被限制,尤其是AI编程工具,最喜欢限制人的机器码,但是我们又
|
8天前
|
Java 数据安全/隐私保护
快手小红书抖音留痕工具,自动留痕插件工具,java代码开源
这个框架包含三个核心模块:主操作类处理点赞评论、配置管理类和代理管理类。使用时需要配合
|
8天前
|
API 数据安全/隐私保护 C++
永久修改机器码工具, exe一机一码破解工具,软件机器码一键修改工具【c++代码】
程序实现了完整的机器码修改功能,包含进程查找、内存扫描、模式匹配和修改操作。代码使用
|
9天前
|
数据可视化 容器
股票假图一键生成器,股票账户模拟生成器,股票交割单生成器
这个代码示例展示了如何生成随机股票数据,但请注意实际应用中应使用真实数据源。如果您需要完
|
9天前
|
前端开发 数据安全/隐私保护
股票持仓截图生成器手机版, 股票持仓图生成器免费,交割单生成器制作工具
代码实现了一个完整的股票持仓截图生成器,包含数据模拟、表格绘制、汇总计算和水印添加功能。
|
9天前
|
前端开发 数据安全/隐私保护
股票交易截图生成器, 股票持仓图生成器免费, 股票交割单生成器手机版
实现了完整的股票持仓截图生成功能,包含随机数据生成、表格绘制、汇总统计和水印添加。使用时只
|
9天前
|
数据可视化 安全 JavaScript
股票假图一键生成器, 股票持仓图生成器免费, 股票虚拟仿真交易软件
本系统包含三大核心模块:假图生成器、持仓可视化工具和虚拟交易引擎。采用Python+Flask+Vue技术栈实现前后端分离架构。
|
8天前
|
算法 API Windows
一键解除机器码工具,永久修改机器码工具, 破解一机一注册码软件
这段代码实现了硬件信息获取和伪装功能,包含三个模块:硬件信息获取、伪装算法实现和主程序入口
|
云安全 安全 数据安全/隐私保护
阿里云成为全球唯一完成德国C5云安全基础附加标准审计云服务商 数据安全获“最严谨”标准认可
12月14日,德国联邦信息安全局宣布阿里云完成德国C5云安全(Cloud Computing Compliance Controls Catalog)标准评审。 这样,阿里云成为全球首家,也是唯一一家审计报告覆盖所有C5标准基础要求和附加要求的云服务提供商。
6191 0