OS Trading Engine
Technical Documentation
Shared Package

Shared Package

The nexgent-open-source-trading-engine/shared package contains code shared between the backend and frontend packages. It ensures type safety and consistency across the entire monorepo.

Overview

ExportPurpose
TypesTypeScript interfaces for trading config, API responses
ValidatorsZod schemas for runtime validation
ConstantsTrading configuration defaults, DCA templates
UtilitiesStop loss calculators, formatting functions

The shared package has minimal dependencies (only Zod) to keep it lightweight and prevent dependency conflicts.


Package Structure

    • index.ts
      • trading-config.ts
      • agent-position.ts

  • Types

    Trading Configuration

    The core trading configuration types define how agents trade:

    // types/trading-config.ts
     
    /** Stop loss calculation mode */
    export type StopLossMode = 'fixed' | 'exponential' | 'zones' | 'custom';
     
    /** DCA calculation mode */
    export type DCAMode = 'aggressive' | 'moderate' | 'conservative' | 'custom';
     
    /** Complete agent trading configuration */
    export interface AgentTradingConfig {
      purchaseLimits: PurchaseLimits;
      signals: SignalConfig;
      stopLoss: StopLossConfig;
      positionCalculator: PositionCalculator;
      staleTrade: StaleTradeConfig;
      dca: DCAConfig;
    }

    Stop Loss Configuration

    export interface StopLossConfig {
      /** Whether stop loss is active */
      enabled: boolean;
      
      /** Default stop loss % (e.g., -32 = 32% loss from purchase) */
      defaultPercentage: number;
      
      /** Calculation mode: fixed, exponential, zones, or custom */
      mode: StopLossMode;
      
      /** Custom trailing levels (only used when mode === 'custom') */
      trailingLevels: TrailingLevel[];
    }
     
    export interface TrailingLevel {
      /** Price change % above purchase (e.g., 200 = 2x) */
      change: number;
      
      /** Stop loss % to keep (e.g., 90 = keep 90% of peak) */
      stopLoss: number;
    }

    DCA Configuration

    export interface DCAConfig {
      enabled: boolean;
      mode: DCAMode;
      levels: DCALevel[];
      maxDCACount: number;
      cooldownSeconds: number;
    }
     
    export interface DCALevel {
      /** Price drop % from average (e.g., -15 = 15% drop) */
      dropPercent: number;
      
      /** Amount to buy as % of position (e.g., 50 = buy 50% more) */
      buyPercent: number;
    }

    Position Configuration

    export interface PositionCalculator {
      solBalanceThresholds: {
        minimum: number;
        medium: number;
        large: number;
      };
      positionSizes: {
        small: PositionSizeRange;
        medium: PositionSizeRange;
        large: PositionSizeRange;
      };
      randomization: {
        enabled: boolean;
      };
    }
     
    export interface PositionSizeRange {
      min: number;
      max: number;
    }

    API Types

    API request/response types are organized by resource:

    // types/api/agents.ts
    export interface Agent {
      id: string;
      userId: string;
      name: string;
      tradingMode: 'simulation' | 'live';
      automatedTradingSimulation: boolean;
      automatedTradingLive: boolean;
      tradingConfig: AgentTradingConfig;
      createdAt: Date;
      updatedAt: Date;
    }
     
    // types/api/wallets.ts
    export interface Wallet {
      id: string;
      address: string;
      name: string | null;
      isAssigned: boolean;
      assignedAgentId: string | null;
    }
     
    // types/api/trading-signals.ts
    export interface TradingSignal {
      id: string;
      tokenAddress: string;
      tokenSymbol: string;
      signalType: 'BUY' | 'SELL';
      score: number;
      source: string;
      createdAt: Date;
    }

    Validators (Zod)

    Zod schemas provide runtime validation with TypeScript type inference.

    Agent Schemas

    // validators/agents.schema.ts
    import { z } from 'zod';
     
    export const CreateAgentSchema = z.object({
      name: z.string()
        .min(3, 'Name must be at least 3 characters')
        .max(50, 'Name must be less than 50 characters'),
      tradingMode: z.enum(['simulation', 'live']).default('simulation'),
    });
     
    export const UpdateAgentSchema = z.object({
      name: z.string().min(3).max(50).optional(),
      tradingMode: z.enum(['simulation', 'live']).optional(),
      automatedTradingSimulation: z.boolean().optional(),
      automatedTradingLive: z.boolean().optional(),
    });
     
    // Infer TypeScript types from schemas
    export type CreateAgentInput = z.infer<typeof CreateAgentSchema>;
    export type UpdateAgentInput = z.infer<typeof UpdateAgentSchema>;

    Wallet Schemas

    // validators/wallets.schema.ts
    import { z } from 'zod';
     
    export const AssignWalletSchema = z.object({
      walletAddress: z.string().min(32).max(44),
      agentId: z.string().uuid(),
    });
     
    export const DepositSchema = z.object({
      walletAddress: z.string(),
      agentId: z.string().uuid(),
      amount: z.number().positive(),
    });
     
    export const WithdrawSchema = z.object({
      walletAddress: z.string(),
      agentId: z.string().uuid(),
      amount: z.number().positive(),
    });

    Auth Schemas

    // validators/auth.schema.ts
    import { z } from 'zod';
     
    export const LoginSchema = z.object({
      email: z.string().email('Invalid email address'),
      password: z.string().min(8, 'Password must be at least 8 characters'),
    });
     
    export const RegisterSchema = z.object({
      email: z.string().email('Invalid email address'),
      password: z.string()
        .min(8, 'Password must be at least 8 characters')
        .regex(/[A-Z]/, 'Password must contain uppercase letter')
        .regex(/[0-9]/, 'Password must contain number'),
      confirmPassword: z.string(),
    }).refine((data) => data.password === data.confirmPassword, {
      message: 'Passwords do not match',
      path: ['confirmPassword'],
    });

    Usage Pattern

    // Backend: Validate request body
    import { CreateAgentSchema } from 'nexgent-open-source-trading-engine/shared';
     
    app.post('/api/v1/agents', async (req, res) => {
      const result = CreateAgentSchema.safeParse(req.body);
      
      if (!result.success) {
        return res.status(400).json({ errors: result.error.flatten() });
      }
      
      const agent = await createAgent(result.data);
      res.json(agent);
    });
     
    // Frontend: Form validation with React Hook Form
    import { zodResolver } from '@hookform/resolvers/zod';
    import { CreateAgentSchema } from 'nexgent-open-source-trading-engine/shared';
     
    const form = useForm({
      resolver: zodResolver(CreateAgentSchema),
    });

    Constants

    Trading Configuration Defaults

    // constants/trading-config-defaults.ts
     
    export const DEFAULT_TRADING_CONFIG: AgentTradingConfig = {
      purchaseLimits: {
        minimumAgentBalance: 0.5,
        maxPurchasePerToken: 2.0,
      },
      signals: {
        minScore: 4,
        blacklist: [],
        whitelist: [],
        whitelistEnabled: false,
      },
      stopLoss: {
        enabled: true,
        defaultPercentage: -32,
        mode: 'fixed',
        trailingLevels: [],
      },
      positionCalculator: {
        solBalanceThresholds: {
          minimum: 0.2,
          medium: 5,
          large: 10,
        },
        positionSizes: {
          small: { min: 0.1, max: 0.1 },
          medium: { min: 0.5, max: 1.0 },
          large: { min: 1.5, max: 2.0 },
        },
        randomization: { enabled: true },
      },
      staleTrade: {
        enabled: true,
        minHoldTimeMinutes: 60,
        minProfitPercent: 1,
        maxProfitPercent: 10,
      },
      dca: {
        enabled: false,
        mode: 'moderate',
        levels: [],
        maxDCACount: 3,
        cooldownSeconds: 30,
      },
    };

    DCA Templates

    // constants/dca-templates.ts
     
    export const DCA_TEMPLATES = {
      aggressive: [
        { dropPercent: -10, buyPercent: 25 },
        { dropPercent: -20, buyPercent: 35 },
        { dropPercent: -30, buyPercent: 50 },
        { dropPercent: -40, buyPercent: 75 },
      ],
      moderate: [
        { dropPercent: -15, buyPercent: 30 },
        { dropPercent: -30, buyPercent: 50 },
        { dropPercent: -45, buyPercent: 75 },
      ],
      conservative: [
        { dropPercent: -20, buyPercent: 40 },
        { dropPercent: -40, buyPercent: 60 },
      ],
    };

    Utilities

    Stop Loss Calculator

    Pure functions for calculating stop loss percentages across different modes:

    // utils/stop-loss-calculator.ts
     
    /**
     * Main entry point: Calculate stop loss based on config
     */
    export function calculateStopLossPercentage(
      priceChangePercent: number,
      config: StopLossConfig
    ): number {
      if (priceChangePercent < 0) {
        return config.defaultPercentage;
      }
      
      switch (config.mode) {
        case 'fixed':
          return calculateFixedStepperStopLoss(priceChangePercent, config.defaultPercentage);
        case 'exponential':
          return calculateExponentialStopLoss(priceChangePercent, config.defaultPercentage);
        case 'zones':
          return calculateZonesStopLoss(priceChangePercent, config.defaultPercentage);
        case 'custom':
          return calculateCustomStopLoss(priceChangePercent, config.trailingLevels) 
            ?? config.defaultPercentage;
        default:
          return config.defaultPercentage;
      }
    }

    Fixed Stepper Mode

    /**
     * Fixed Stepper: stopLoss = change - 10 (10% increments)
     * For gains below 20%, uses default percentage
     */
    export function calculateFixedStepperStopLoss(
      priceChangePercent: number,
      defaultPercentage: number = -32
    ): number {
      if (priceChangePercent < 20) {
        return defaultPercentage;
      }
      return Math.max(0, priceChangePercent - 10);
    }

    Exponential Mode

    /**
     * Exponential Decay: Loose at low levels, tight at high
     * Uses Gaussian function for natural pullback zone
     */
    export function calculateExponentialStopLoss(
      priceChangePercent: number,
      defaultPercentage: number = -32
    ): number {
      if (priceChangePercent <= 20) {
        return defaultPercentage;
      }
      
      const x = priceChangePercent - 20;
      
      // Base exponential growth
      const baseKeep = 1 - Math.exp(-x / (100 / 3.2));
      
      // Gaussian pullback modulation (creates dip at ~75%)
      const gaussianPullback = 0.12 * Math.exp(-Math.pow((x - 55) / 8, 2) / 2);
      
      let keepPercentage = Math.max(0, Math.min(0.90, baseKeep - gaussianPullback));
      
      // Acceleration after pullback zone
      if (x > 65) {
        const boost = 0.30 * (1 - Math.exp(-(x - 65) / 80));
        keepPercentage = Math.min(0.90, keepPercentage + boost);
      }
      
      return priceChangePercent * keepPercentage;
    }

    Zones Mode

    /**
     * Step-Based Zones: 5 distinct zones with different keep percentages
     */
    export function calculateZonesStopLoss(
      priceChangePercent: number,
      defaultPercentage: number = -32
    ): number {
      if (priceChangePercent < 20) return defaultPercentage;
      
      let keepPercentage: number;
      
      if (priceChangePercent <= 25) keepPercentage = 0.50;      // Zone 1
      else if (priceChangePercent <= 50) keepPercentage = 0.60; // Zone 2
      else if (priceChangePercent <= 100) keepPercentage = 0.70; // Zone 3
      else if (priceChangePercent <= 200) keepPercentage = 0.80; // Zone 4
      else keepPercentage = 0.85;                                // Zone 5
      
      return priceChangePercent * keepPercentage;
    }
    💡

    These calculator functions are pure (no side effects) and used by both the backend stop loss manager and frontend chart visualizations.


    Usage

    Backend Import

    import { 
      AgentTradingConfig,
      DEFAULT_TRADING_CONFIG,
      CreateAgentSchema,
      calculateStopLossPercentage,
    } from 'nexgent-open-source-trading-engine/shared';

    Frontend Import

    import { 
      type Agent,
      CreateAgentSchema,
      type CreateAgentInput,
      DCA_TEMPLATES,
    } from 'nexgent-open-source-trading-engine/shared';