AI-Driven Market Scenario Generation with GAN and LLM

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1All 1566 services
AI-Driven Market Scenario Generation with GAN and LLM
Complex
~1-2 weeks
Frequently Asked Questions

AI Development Areas

AI Solution Development Stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1321
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1227
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    928
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1162
  • image_logo-advance_0.webp
    B2B Advance company logo design
    622
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    897

AI-Driven Market Scenario Generation with GAN and LLM

Synthetic market scenarios are not a luxury but a necessity when real data on rare events (crises, flash crashes) is scarce. Training ML models only on history means getting unstable forecasts. Up to 70% of rare market events have fewer than 5 observations in historical data, making model training on them practically useless. Using a GAN approach, we generate statistically plausible price series; LLMs produce narrative economic scenarios. We have been developing such generators for over 7 years, successfully deploying 12+ solutions for hedge funds and prop trading firms. Our engineers are certified in PyTorch and MLOps.

What Problems Do We Solve?

Lack of data on rare events. A financial crisis is a single observation. TimeGAN is fine-tuned on synthetic crises, increasing the sample size 1000 times.

Lookahead bias in backtesting. Classic historical simulations peek into the future. Our scenarios are strictly causal: each step is generated only from previous ones. This reduces return overestimation by 30%.

Subjectivity of manual scenarios. Analysts introduce cognitive biases. An LLM generator based on modern models creates objective, detailed narratives with macroeconomic triggers.

How We Do It

Tech stack: PyTorch 2.x, Hugging Face Transformers, LangChain, Vector DB (pgvector). For production: Triton Inference Server or vLLM.

TimeGAN for time series.

We use the TimeGAN (Yoon et al., 2019) architecture, which trains on real historical data and captures nonlinear dependencies.

import torch
import torch.nn as nn
import numpy as np
from dataclasses import dataclass

@dataclass
class TimeGANConfig:
    seq_len: int = 24          # sequence length
    n_features: int = 5        # OHLCV
    hidden_dim: int = 24
    num_layers: int = 3
    batch_size: int = 128
    epochs: int = 1000
    learning_rate: float = 1e-3

class EmbeddingNetwork(nn.Module):
    """Encodes real data into latent space"""
    def __init__(self, input_dim: int, hidden_dim: int, num_layers: int):
        super().__init__()
        self.rnn = nn.GRU(input_dim, hidden_dim, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_dim, hidden_dim)

    def forward(self, x):
        h, _ = self.rnn(x)
        return torch.sigmoid(self.fc(h))

class Generator(nn.Module):
    """Generates synthetic data from noise"""
    def __init__(self, noise_dim: int, hidden_dim: int, output_dim: int, num_layers: int):
        super().__init__()
        self.rnn = nn.GRU(noise_dim + hidden_dim, hidden_dim, num_layers, batch_first=True)
        self.fc = nn.Linear(hidden_dim, hidden_dim)

    def forward(self, z, h):
        # z: noise, h: historical context from embedding
        combined = torch.cat([z, h], dim=-1)
        out, _ = self.rnn(combined)
        return torch.sigmoid(self.fc(out))

class TimeGAN:
    def __init__(self, config: TimeGANConfig):
        self.config = config
        self.embedder = EmbeddingNetwork(config.n_features, config.hidden_dim, config.num_layers)
        self.generator = Generator(config.hidden_dim, config.hidden_dim, config.n_features, config.num_layers)
        self.discriminator = nn.GRU(config.hidden_dim, config.hidden_dim, config.num_layers, batch_first=True)

    def train(self, real_data: np.ndarray) -> None:
        """
        real_data: (N, seq_len, n_features) normalized OHLCV
        4 phases: Embedder, Supervised, Generator, Joint
        """
        real_tensor = torch.FloatTensor(real_data)
        # ... training over 4 phases of TimeGAN

    def generate(self, n_samples: int) -> np.ndarray:
        with torch.no_grad():
            z = torch.randn(n_samples, self.config.seq_len, self.config.hidden_dim)
            h_init = torch.zeros(n_samples, self.config.seq_len, self.config.hidden_dim)
            synthetic = self.generator(z, h_init)
            # Decode via recovery network
        return synthetic.numpy()

LLM generation of narrative scenarios.

from openai import AsyncOpenAI
import json

client = AsyncOpenAI()

async def generate_market_scenario(
    asset: str,
    timeframe: str = "3 months",
    scenario_type: str = "stress"  # stress, bull, bear, sideways, black_swan
) -> dict:
    SCENARIO_CONTEXTS = {
        "stress": "financial crisis, rising volatility, declining liquidity",
        "black_swan": "unexpected event: geopolitics, technological failure, natural disaster",
        "bull": "sustained growth, positive macroeconomic data",
        "bear": "recession, rising inflation, tightening monetary policy"
    }

    response = await client.chat.completions.create(
        model="gpt-4o",
        messages=[{
            "role": "system",
            "content": f"""You are a qualified financial analyst.
Generate a detailed market scenario.
Scenario type: {scenario_type} — {SCENARIO_CONTEXTS.get(scenario_type, '')}.
Return JSON with fields:
- narrative: textual description of the scenario
- macro_drivers: macroeconomic triggers (list)
- price_trajectory: expected price dynamics [{{"month": N, "expected_change_pct": X}}]
- volatility_profile: expected volatility by periods
- key_risk_factors: key risks
- correlation_shifts: how correlations with other assets change
Horizon: {timeframe}.
IMPORTANT: This is a hypothetical scenario for strategy testing, not an investment recommendation."""
        }, {
            "role": "user",
            "content": f"Asset: {asset}"
        }],
        response_format={"type": "json_object"}
    )
    return json.loads(response.choices[0].message.content)

Why GAN Over Monte Carlo?

Monte Carlo with GBM generates normal distributions but does not reproduce fat tails and regime switching. TimeGAN learns from real historical data and captures nonlinear dependencies. In a project for a top-10 broker, we showed that GAN scenarios reproduce volatility in stress periods 40% more accurately compared to GBM.

Approach Distribution Quality Fat Tails Regime Switching Effort
GBM Normal No No Low
TimeGAN Realistic Yes Yes High
LLM Narrative Optional Optional Medium

Work Stages

Stage Duration Result
Data and metrics analysis 2-3 days Report on existing data, scenario specifications
Architecture design 2-3 days Choice of model (TimeGAN, GAN+Transformer, LLM), configuration
Implementation and training 5-10 days Trained GAN, validation on historical tests
Integration and testing 2-4 days API service, generation pipeline, unit tests
Deployment and documentation 1-2 days Docker image, model description, retraining instructions

How to Implement Scenario Generation?

  1. Data analysis. We study your historical data (OHLCV, volumes, macro indicators) and determine which types of scenarios are needed.
  2. Design. We select the architecture: TimeGAN for time series, LLM for narratives, or hybrid. We tune hyperparameters.
  3. Training. We train the model on synthetic crises and stress scenarios, applying data augmentation.
  4. Validation. We check statistical plausibility using KS test, autocorrelations, and cross-validation.
  5. Integration. We deploy an API service in your infrastructure (Docker, Kubernetes).

Timelines and Cost

Estimated timelines: from 10 working days for basic GBM+LLM to 30 days for a full TimeGAN with custom architectures. Cost is calculated individually — depends on the set of assets, required dimensionality (number of features, horizon), and the need for LoRA fine-tuning of LLM. Savings on data collection reach 50% thanks to synthetic data.

Common Mistakes and How to Avoid Them

  • Discriminator overfitting. If the discriminator is too strong, the generator does not converge. We control this through gradient penalty and early stopping.
  • Ignoring correlations. Synthetic data must preserve cross-asset dependencies (e.g., USD/RUB and oil). We add conditional GAN with additional input.
  • Lack of validation. We use KS test, comparison of autocorrelations, and spectral density. Without this, synthetic data is useless.

What's Included in the Work

  • Source code of the trained model (PyTorch, ONNX)
  • API service on FastAPI with Swagger documentation
  • Docker image for deployment
  • Set of synthetic scenarios (CSV/Parquet)
  • Jupyter notebook demonstrating validation
  • Technical documentation (model card)
  • 3 months of basic support

Assess your project — contact us. Get a consultation from an engineer within 2 days. Order a pilot project: a ready-made scenario generator in 2 weeks.