> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ngnmarket.com/llms.txt
> Use this file to discover all available pages before exploring further.

# YTD Performers

> Retrieve the best or worst performing NGX stocks year-to-date, with start price, current price, and percentage return.

The YTD performers endpoint ranks NGX-listed stocks by their year-to-date return, calculated from the first available trading day of the year through to the most recent session.

You can request the best performers, the worst performers, or both together. Each entry includes the year-start price and date, the current closing price, and the total percentage return for the year so far. Historical years are also supported via the `year` parameter, making this endpoint useful for annual reviews as well as live tracking.

For example, to pull the 20 worst performers of 2025:

<CodeGroup>
  ```bash curl theme={null}
  curl "https://api.ngnmarket.com/v1/market/ytd-performers?type=worst&year=2025&limit=20" \
    -H "Authorization: Bearer ngm_live_YOUR_KEY"
  ```

  ```javascript JavaScript theme={null}
  const url = new URL('https://api.ngnmarket.com/v1/market/ytd-performers');
  url.searchParams.set('type', 'worst');
  url.searchParams.set('year', '2025');
  url.searchParams.set('limit', '20');

  const res = await fetch(url, {
    headers: { Authorization: 'Bearer ngm_live_YOUR_KEY' },
  });
  const { data } = await res.json();
  ```

  ```python Python theme={null}
  import requests

  res = requests.get(
      'https://api.ngnmarket.com/v1/market/ytd-performers',
      params={'type': 'worst', 'year': 2025, 'limit': 20},
      headers={'Authorization': 'Bearer ngm_live_YOUR_KEY'},
  )
  data = res.json()['data']
  ```
</CodeGroup>


## OpenAPI

````yaml GET /market/ytd-performers
openapi: 3.1.0
info:
  title: NGN Market API
  version: '1.0'
  description: >
    The NGN Market API provides programmatic access to Nigerian Exchange Group
    (NGX) market data, including equities, forex rates, company profiles,
    indices, bonds, and financial news.


    ## Base URL


    All endpoints are served from:


    ```

    https://api.ngnmarket.com/v1

    ```


    ## Authentication


    Every request requires a Bearer token in the `Authorization` header:


    ```

    Authorization: Bearer ngm_live_YOUR_KEY

    ```


    Generate and manage your API keys from the [developer
    dashboard](https://ngnmarket.com/developer).


    ## Plans & Quotas


    | Plan | Monthly Calls | Requests/min | Price |

    | :--- | ---: | ---: | :--- |

    | Free | 3,000 | 30 | Free |

    | Hobby | 10,000 | 60 | ₦15,000/mo |

    | Starter | 100,000 | 120 | ₦50,000/mo |

    | Growth | 500,000 | 200 | ₦200,000/mo |

    | Business | 2,000,000 | 300 | ₦700,000/mo |

    | Enterprise | Unlimited | Unlimited | Custom |


    Every response includes a `meta` object showing your current usage and
    remaining quota. Exceeding the per-minute rate limit returns `429
    RATE_LIMITED`. Exceeding the monthly quota returns `429 QUOTA_EXCEEDED`.


    ## Response Envelope


    All responses use a consistent JSON envelope:


    ```json

    {
      "success": true,
      "data": { ... },
      "meta": {
        "plan": "starter",
        "calls_used": 4821,
        "calls_remaining": 95179,
        "reset_at": "2026-05-01T00:00:00.000Z"
      }
    }

    ```
  contact:
    name: NGN Market Support
    email: support@ngnmarket.com
    url: https://ngnmarket.com
  license:
    name: Proprietary
servers:
  - url: https://api.ngnmarket.com/v1
    description: Production
security:
  - BearerAuth: []
tags:
  - name: Market
    description: >-
      Daily market snapshots, top trades, movers, market breadth, sectors, and
      YTD performers.
  - name: Companies
    description: >-
      Browse, search, and retrieve profiles, price charts, and financial
      statements for NGX-listed companies.
  - name: Forex
    description: Current and historical NGN exchange rates against major currencies.
  - name: Indices
    description: >-
      All NGX market indices, including list, detail with constituents, and
      historical chart data.
  - name: ETFs
    description: >-
      NGX-listed Exchange Traded Funds and ETPs — list, full fund detail, and
      historical daily price data.
  - name: Bonds
    description: >-
      NGX-listed bond instruments with issuer details, coupon rates, and
      maturity dates.
  - name: Disclosures
    description: >-
      Official corporate filings from NGX-listed companies (financial
      statements, AGM notices, board meetings, director dealings, earnings
      forecasts). Sourced from NGX Group and updated twice daily.
  - name: Blog
    description: >-
      Published NGN Market blog posts. List, search, and filter by category or
      company.
  - name: Dividends
    description: >-
      Market-wide NGX dividend calendar. Browse upcoming and recently paid
      dividends across all listed companies with optional search and pagination.
  - name: Account
    description: >-
      Quota status, 30-day request analytics, and paginated request logs for the
      authenticated user.
paths:
  /market/ytd-performers:
    get:
      tags:
        - Market
      summary: Year-to-date stock returns
      description: >
        Ranks NGX-listed stocks by their year-to-date return, from the first
        available trading day of the year through the most recent session.
        Request the best performers, worst performers, or both. Historical years
        are supported via the `year` parameter.


        **Plan required:** Growth
      operationId: getYTDPerformers
      parameters:
        - name: type
          in: query
          description: Performance direction to return. Defaults to `best`.
          required: false
          schema:
            type: string
            enum:
              - best
              - worst
            default: best
        - name: limit
          in: query
          description: Number of stocks to return. Maximum `30`.
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 30
            default: 10
        - name: year
          in: query
          description: >-
            Calendar year to evaluate (e.g. `2025`). Defaults to the current
            year. Provide a past year to query historical annual performance.
          required: false
          schema:
            type: integer
            example: 2026
      responses:
        '200':
          description: YTD performers retrieved successfully.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/SuccessEnvelope'
                  - type: object
                    properties:
                      data:
                        $ref: '#/components/schemas/YTDPerformers'
              examples:
                bestPerformers:
                  summary: Top 2 best YTD performers
                  value:
                    success: true
                    data:
                      type: best
                      year: 2026
                      is_past_year: false
                      year_start_date: '2026-01-02'
                      total: 2
                      data:
                        - symbol: OKOMUOIL
                          company_name: Okomu Oil Palm
                          sector: Agriculture
                          year_start_price: 275
                          year_start_date: '2026-01-02'
                          current_price: 400.7
                          end_date: '2026-04-17'
                          ytd_pct: 45.71
                        - symbol: DANGCEM
                          company_name: Dangote Cement
                          sector: Industrial Goods
                          year_start_price: 210
                          year_start_date: '2026-01-02'
                          current_price: 302.5
                          end_date: '2026-04-17'
                          ytd_pct: 44.05
                    meta:
                      plan: growth
                      calls_used: 212
                      calls_remaining: 499788
                      reset_at: '2026-05-01T00:00:00.000Z'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/PlanRequired'
        '429':
          $ref: '#/components/responses/QuotaExceeded'
        '500':
          $ref: '#/components/responses/ServerError'
components:
  schemas:
    SuccessEnvelope:
      type: object
      required:
        - success
      properties:
        success:
          type: boolean
          const: true
        meta:
          $ref: '#/components/schemas/Meta'
    YTDPerformers:
      type: object
      properties:
        type:
          type: string
          enum:
            - best
            - worst
        year:
          type: integer
        isPastYear:
          type: boolean
        yearStartDate:
          type: string
          format: date
        total:
          type: integer
        data:
          type: array
          items:
            type: object
            properties:
              symbol:
                type: string
              company_name:
                type: string
              sector:
                type: string
              year_start_price:
                type: number
              year_start_date:
                type: string
                format: date
              current_price:
                type: number
              end_date:
                type: string
                format: date
              ytd_pct:
                type: number
    Meta:
      type: object
      description: Quota and plan metadata included on every authenticated response.
      properties:
        plan:
          type: string
          description: Current plan name.
          enum:
            - free
            - starter
            - growth
            - business
            - enterprise
          example: starter
        calls_used:
          type: integer
          description: Total calls made this calendar month across all your keys.
          example: 4821
        calls_remaining:
          type: integer
          description: Calls remaining before your quota is exhausted.
          example: 95179
        reset_at:
          type: string
          format: date-time
          description: ISO 8601 UTC timestamp of your next quota reset (1st of next month).
          example: '2026-05-01T00:00:00.000Z'
    ErrorEnvelope:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          const: false
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Machine-readable error identifier.
              example: NOT_FOUND
            message:
              type: string
              description: Human-readable error description.
              example: Resource not found.
            required_plan:
              type: string
              description: _(PLAN_REQUIRED only)_ Minimum plan needed.
            current_plan:
              type: string
              description: _(PLAN_REQUIRED only)_ Your current plan.
  responses:
    Unauthorized:
      description: Missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            missingKey:
              summary: Missing Authorization header
              value:
                success: false
                error:
                  code: MISSING_API_KEY
                  message: 'Provide your API key via: Authorization: Bearer <key>'
            invalidKey:
              summary: Invalid or revoked key
              value:
                success: false
                error:
                  code: INVALID_API_KEY
                  message: API key not found or revoked.
    PlanRequired:
      description: Endpoint requires a higher plan.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            success: false
            error:
              code: PLAN_REQUIRED
              message: This endpoint requires a starter plan or higher.
              required_plan: starter
              current_plan: free
    QuotaExceeded:
      description: Monthly call limit reached.
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/ErrorEnvelope'
              - type: object
                properties:
                  meta:
                    $ref: '#/components/schemas/Meta'
          example:
            success: false
            error:
              code: QUOTA_EXCEEDED
              message: >-
                Monthly call limit of 100,000 reached. Resets on
                2026-05-01T00:00:00.000Z.
            meta:
              plan: starter
              calls_used: 100000
              calls_remaining: 0
              reset_at: '2026-05-01T00:00:00.000Z'
    ServerError:
      description: Unexpected server-side failure. Safe to retry with backoff.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            success: false
            error:
              code: SERVER_ERROR
              message: Something went wrong on our end. Please try again.
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: ngm_live_*
      description: >
        Pass your API key as a Bearer token: `Authorization: Bearer
        ngm_live_YOUR_KEY`.

        Generate keys at
        [ngnmarket.com/dashboard/developer](https://ngnmarket.com/developer).

````