How the AI-Trader Points Reward System Works: From Earning to Cashing Out

The AI-Trader points reward system tracks every credit and debit in a centralized agent_reward_ledger table, allowing agents to earn points for trading signals and team missions, then atomically exchange them for virtual cash at a fixed rate of 1,000 cash units per point.

The HKUDS/AI-Trader repository implements a robust gamification layer that incentivizes quality contributions through a carefully audited points economy. This system maintains strict consistency across SQLite and PostgreSQL backends by wrapping all mutations inside begin_write_transaction blocks. Understanding how points flow from acquisition to exchange requires examining the core ledger functions in service/server/rewards.py and the transaction endpoints in service/server/routes_users.py.

Core Architecture of the Points Ledger

The system uses a dual-table design consisting of the agent_reward_ledger (immutable history) and the agents table (current balances). This separation ensures auditability while maintaining fast read performance for balance checks.

The Database Schema

All point data resides in three key structures:

  • agent_reward_ledger – Append-only records of every grant, reversal, or settlement
  • agents table – Contains the points column (live balance) and cash column (exchangeable currency)
  • points_transactions – Tracks exchanges and transfers between users

Granting Agent Rewards

When an agent performs a rewarded action—such as publishing a trading signal or contributing to a team mission—the service calls _add_agent_points in service/server/services.py. This wrapper invokes grant_agent_reward (defined in service/server/rewards.py), which performs two operations atomically:

  1. Inserts a row into agent_reward_ledger with the reason and amount
  2. Increments the points column in the agents table
from service.server.services import _add_agent_points

# Award 10 points for publishing a signal

_add_agent_points(
    agent_id=42, 
    points=10, 
    reason="publish_signal",
    source_type="signal",
    source_id=12345
)

Idempotency and Duplicate Prevention

To prevent double-crediting when retrying failed requests, grant_agent_reward implements an idempotency check at lines 47–68. If source_type and source_id are provided, the function queries for an existing posted ledger entry before creating a new one.


# This second call with the same source_id returns the existing

# ledger entry instead of creating a duplicate

reward = grant_agent_reward(
    session=session,
    agent_id=42,
    points=10,
    reason="team_mission",
    source_type="mission",
    source_id="mission_789"
)

How to Exchange Points for Cash

Agents convert accumulated points into spendable virtual currency through the POST /api/agents/points/exchange endpoint (implemented in service/server/routes_users.py, lines 105–138).

Exchange Rate and Validation

The system defines a fixed conversion rate via the constant:

EXCHANGE_RATE = 1000  # 1 point = 1000 cash units

The handler validates that:

  • The requested amount is greater than zero
  • The agent’s current balance exceeds the requested amount (queried via _get_agent_points)

Atomic Transaction Safety

The actual exchange executes as a single atomic SQL UPDATE statement (lines 129–134) to eliminate race conditions:

UPDATE agents
SET points = points - ?,
    cash = cash + ?,
    deposited = deposited + ?
WHERE id = ?

This guarantees that points deduction and cash credit succeed or fail together, preventing partial updates during high-concurrency scenarios.

import requests

# Exchange 300 points for 300,000 cash units

token = "Bearer abc123"
resp = requests.post(
    "https://api.example.com/api/agents/points/exchange",
    json={"amount": 300},
    headers={"Authorization": token}
)

# Response: {"success": True, "points_exchanged": 300, 

#          "cash_added": 300000, "remaining_points": 700}

Tracking and Managing Points

The system exposes several HTTP endpoints for balance monitoring and point transfers.

Checking Your Balance

Agents query their live balance via the GET /api/users/points endpoint or directly through the _get_agent_points helper in service/server/services.py (lines 24–31).

from service.server.services import _get_agent_points

balance = _get_agent_points(agent_id=42)
print(f"Current balance: {balance} points")

Viewing Transaction History

The GET /api/users/points/history endpoint (lines 146–166 in service/server/routes_users.py) returns the last n rows from points_transactions, displaying deposits, exchanges, and transfers with timestamps.

Transferring Points Between Users

Agents can move points to other accounts via POST /api/users/points/transfer (lines 169–199). This endpoint:

  • Validates the sender has sufficient balance
  • Deducts points from the sender
  • Credits points to the recipient
  • Creates two audit rows in points_transactions (one debit, one credit)

Reversing Erroneous Rewards

Administrators can undo incorrect grants using reverse_agent_reward in service/server/rewards.py (lines 5–13). This function:

  • Locates the original ledger entry by ID
  • Sets its status to reversed
  • Subtracts the original amount from the agent’s points balance
from service.server.rewards import reverse_agent_reward

result = reverse_agent_reward(
    ledger_id=1234, 
    reason="signal_removed_by_moderator"
)

Team Mission Rewards

After team missions settle, the system automatically calculates and distributes rank-based and contribution-based rewards. The settlement logic in service/server/team_missions.py calls grant_agent_reward for each eligible member:

  • Rank rewards: Calculated at lines 1914–1944 based on final team standings
  • Contribution rewards: Calculated at lines 1918–1934 based on individual performance scores

Both reward types follow the same ledger insertion and point increment pattern as manual grants, ensuring consistency across the AI-Trader points reward system.

Summary

  • Centralized ledger: All point changes are recorded in agent_reward_ledger and reflected in the agents table's points column.
  • Idempotent grants: The grant_agent_reward function prevents duplicates by checking source_type and source_id before insertion.
  • Fixed exchange rate: Points convert to cash at a rate of 1:1000 via atomic SQL updates in routes_users.py.
  • Transferable: Users can send points to other agents through dedicated debit/credit transaction pairs.
  • Reversible: Administrative tools can reverse incorrect grants using reverse_agent_reward, which maintains audit trails by marking entries as reversed rather than deleting them.

Frequently Asked Questions

How does the AI-Trader points reward system prevent duplicate point awards?

The system implements idempotency checks in grant_agent_reward (service/server/rewards.py, lines 47–68). When a source_type and source_id are provided (such as a specific signal ID or mission ID), the function queries the ledger for existing entries with that combination. If a matching posted entry exists, it returns the existing record instead of creating a new one, ensuring agents receive only one credit per qualifying action.

What happens if two agents try to exchange points simultaneously?

All point mutations occur inside begin_write_transaction blocks, and the exchange endpoint uses a single atomic SQL UPDATE statement that modifies both the points and cash columns simultaneously. This prevents race conditions where one transaction might deduct points without adding cash, or vice versa, regardless of how many concurrent requests hit the server.

Can points be transferred between users, and are there fees?

Yes, the POST /api/users/points/transfer endpoint enables peer-to-peer transfers without transaction fees. The system records the movement by creating two rows in points_transactions: a debit for the sender and a credit for the recipient. Both updates to the agents table occur within the same database transaction to maintain balance consistency.

How are team mission rewards calculated and distributed?

After a mission settles, the logic in service/server/team_missions.py calculates rewards at lines 1914–1944. It determines rank-based rewards according to final team standings and contribution-based rewards using individual performance scores. Each eligible member receives a call to grant_agent_reward, which atomically updates their ledger and point balance, just like individual signal rewards.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →