spb/vquant Public MIT
VibeQuant — AI-powered institutional-grade financial intelligence platform.
TypeScript 84.3%
Python 11.7%
JavaScript 1.6%
CSS 1.5%
HTML 0.7%
1/*2 * =============================================================================3 * VibeQuant (vquant) — AI-Powered Financial Intelligence Platform4 * -----------------------------------------------------------------------------5 * File: client/src/components/chat/monte-carlo-results.tsx6 *7 * Author: Simon-Pierre Boucher8 * Contact: contact@spboucher.ai9 * Website: https://www.spboucher.ai10 * Demo: https://www.vquant.ai11 * License: MIT (see LICENSE)12 *13 * Copyright © 2026 Simon-Pierre Boucher. All rights reserved.14 * =============================================================================15 */1617import { motion } from "framer-motion";18import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";19import { TrendingUp, Code2, BarChart3, DollarSign } from "lucide-react";20import { Badge } from "@/components/ui/badge";21import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";2223interface MonteCarloResultsProps {24 pythonCode?: string;25 results?: {26 success: boolean;27 parameters?: {28 num_simulations: number;29 time_horizon: number;30 initial_investment: number;31 mean_return: number;32 std_return: number;33 };34 statistics?: {35 mean_final_value: number;36 median_final_value: number;37 std_final_value: number;38 min_final_value: number;39 max_final_value: number;40 percentile_5: number;41 percentile_25: number;42 percentile_75: number;43 percentile_95: number;44 probability_of_profit: number;45 };46 };47}4849export function MonteCarloResults({ pythonCode, results }: MonteCarloResultsProps) {50 if (!pythonCode && !results) return null;5152 const formatCurrency = (value: number) => {53 return new Intl.NumberFormat('fr-FR', {54 style: 'currency',55 currency: 'USD',56 minimumFractionDigits: 2,57 maximumFractionDigits: 258 }).format(value);59 };6061 const formatPercent = (value: number) => {62 return `${value.toFixed(2)}%`;63 };6465 return (66 <motion.div67 initial={{ opacity: 0, y: 8 }}68 animate={{ opacity: 1, y: 0 }}69 transition={{ duration: 0.3 }}70 className="w-full max-w-5xl mx-auto"71 data-testid="monte-carlo-results"72 >73 <Card className="border-primary/20 shadow-lg">74 <CardHeader className="gap-2">75 <div className="flex items-center gap-2">76 <BarChart3 className="w-5 h-5 text-primary" />77 <CardTitle className="text-xl">Simulation Monte Carlo</CardTitle>78 </div>79 <p className="text-sm text-muted-foreground">80 Analyse de risque et projection des rendements futurs81 </p>82 </CardHeader>83 <CardContent>84 <Tabs defaultValue="results" className="w-full">85 <TabsList className="grid w-full grid-cols-2 mb-4" data-testid="tabs-monte-carlo">86 <TabsTrigger value="results" data-testid="tab-results">87 <TrendingUp className="w-4 h-4 mr-2" />88 Résultats89 </TabsTrigger>90 <TabsTrigger value="code" data-testid="tab-code">91 <Code2 className="w-4 h-4 mr-2" />92 Code Python93 </TabsTrigger>94 </TabsList>9596 <TabsContent value="results" data-testid="content-results">97 {results?.success && results.statistics && results.parameters ? (98 <div className="space-y-6">99 {/* Parameters */}100 <div className="bg-muted/30 rounded-lg p-4 space-y-2">101 <h3 className="font-semibold text-sm text-muted-foreground mb-3">Paramètres de simulation</h3>102 <div className="grid grid-cols-2 md:grid-cols-4 gap-3">103 <div className="space-y-1" data-testid="param-simulations">104 <p className="text-xs text-muted-foreground">Simulations</p>105 <p className="text-sm font-medium">{results.parameters.num_simulations.toLocaleString()}</p>106 </div>107 <div className="space-y-1" data-testid="param-horizon">108 <p className="text-xs text-muted-foreground">Horizon (jours)</p>109 <p className="text-sm font-medium">{results.parameters.time_horizon}</p>110 </div>111 <div className="space-y-1" data-testid="param-investment">112 <p className="text-xs text-muted-foreground">Investissement initial</p>113 <p className="text-sm font-medium">{formatCurrency(results.parameters.initial_investment)}</p>114 </div>115 <div className="space-y-1" data-testid="param-volatility">116 <p className="text-xs text-muted-foreground">Volatilité</p>117 <p className="text-sm font-medium">{formatPercent(results.parameters.std_return * 100)}</p>118 </div>119 </div>120 </div>121122 {/* Key Statistics */}123 <div className="grid grid-cols-1 md:grid-cols-3 gap-4">124 <Card data-testid="stat-mean">125 <CardContent className="pt-6">126 <div className="flex items-center gap-2 mb-2">127 <DollarSign className="w-4 h-4 text-primary" />128 <p className="text-sm text-muted-foreground">Valeur moyenne</p>129 </div>130 <p className="text-2xl font-bold">{formatCurrency(results.statistics.mean_final_value)}</p>131 </CardContent>132 </Card>133 134 <Card data-testid="stat-median">135 <CardContent className="pt-6">136 <div className="flex items-center gap-2 mb-2">137 <DollarSign className="w-4 h-4 text-primary" />138 <p className="text-sm text-muted-foreground">Valeur médiane</p>139 </div>140 <p className="text-2xl font-bold">{formatCurrency(results.statistics.median_final_value)}</p>141 </CardContent>142 </Card>143144 <Card data-testid="stat-profit-prob">145 <CardContent className="pt-6">146 <div className="flex items-center gap-2 mb-2">147 <TrendingUp className="w-4 h-4 text-primary" />148 <p className="text-sm text-muted-foreground">Probabilité de profit</p>149 </div>150 <p className="text-2xl font-bold">{formatPercent(results.statistics.probability_of_profit)}</p>151 </CardContent>152 </Card>153 </div>154155 {/* Percentiles */}156 <div className="bg-muted/30 rounded-lg p-4 space-y-3">157 <h3 className="font-semibold text-sm text-muted-foreground mb-3">Distribution des résultats</h3>158 <div className="space-y-2">159 <div className="flex justify-between items-center" data-testid="percentile-5">160 <span className="text-sm text-muted-foreground">5e percentile (pire scénario probable)</span>161 <Badge variant="outline">{formatCurrency(results.statistics.percentile_5)}</Badge>162 </div>163 <div className="flex justify-between items-center" data-testid="percentile-25">164 <span className="text-sm text-muted-foreground">25e percentile</span>165 <Badge variant="outline">{formatCurrency(results.statistics.percentile_25)}</Badge>166 </div>167 <div className="flex justify-between items-center" data-testid="percentile-75">168 <span className="text-sm text-muted-foreground">75e percentile</span>169 <Badge variant="outline">{formatCurrency(results.statistics.percentile_75)}</Badge>170 </div>171 <div className="flex justify-between items-center" data-testid="percentile-95">172 <span className="text-sm text-muted-foreground">95e percentile (meilleur scénario probable)</span>173 <Badge variant="outline">{formatCurrency(results.statistics.percentile_95)}</Badge>174 </div>175 </div>176 </div>177178 {/* Range */}179 <div className="bg-muted/30 rounded-lg p-4">180 <h3 className="font-semibold text-sm text-muted-foreground mb-3">Plage de résultats</h3>181 <div className="flex justify-between items-center">182 <div className="text-center" data-testid="min-value">183 <p className="text-xs text-muted-foreground mb-1">Minimum</p>184 <p className="text-sm font-medium">{formatCurrency(results.statistics.min_final_value)}</p>185 </div>186 <div className="flex-1 mx-4">187 <div className="h-2 bg-gradient-to-r from-red-500 via-yellow-500 to-green-500 rounded-full" />188 </div>189 <div className="text-center" data-testid="max-value">190 <p className="text-xs text-muted-foreground mb-1">Maximum</p>191 <p className="text-sm font-medium">{formatCurrency(results.statistics.max_final_value)}</p>192 </div>193 </div>194 </div>195 </div>196 ) : (197 <div className="text-center py-8 text-muted-foreground">198 Aucun résultat disponible199 </div>200 )}201 </TabsContent>202203 <TabsContent value="code" data-testid="content-code">204 {pythonCode ? (205 <div className="relative">206 <div className="absolute top-2 right-2 z-10">207 <Badge variant="outline" className="text-xs">208 Python209 </Badge>210 </div>211 <pre className="bg-muted p-4 rounded-lg overflow-x-auto text-sm font-mono" data-testid="python-code-block">212 <code className="text-foreground">{pythonCode}</code>213 </pre>214 </div>215 ) : (216 <div className="text-center py-8 text-muted-foreground">217 Aucun code disponible218 </div>219 )}220 </TabsContent>221 </Tabs>222 </CardContent>223 </Card>224 </motion.div>225 );226}227