LuxAlgo MCP
What this MCP does
Provides trading and technical-analysis reference content, market edge statistics, prop-firm challenge analysis, and trade-journal management.
Tools
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'category': {'type': 'string', 'description': 'Narrow to one category (the result lists all categories)'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['preset', 'symbol', 'context'], 'properties': {'preset': {'type': 'string', 'minLength': 1, 'description': "Preset id, e.g. 'gap-fill' â\x80\x94 see edge_presets"}, 'symbol': {'type': 'string', 'minLength': 1, 'description': "Hosted symbol, e.g. 'BTCUSDT' â\x80\x94 see edge_symbols"}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['accountId', 'fills', 'context'], 'properties': {'fills': {'type': 'array', 'items': {'type': 'object', 'required': ['symbol', 'side', 'quantity', 'price', 'executedAt'], 'properties': {'fee': {'type': 'number', 'minimum': 0, 'description': 'Commission and fees for this fill, in the account currency. Default 0.'}, 'side': {'enum': ['buy', 'sell'], 'type': 'string'}, 'price': {'type': 'number', 'minimum': 0, 'description': 'Fill price per unit.'}, 'symbol': {'type': 'string', 'maxLength': 30, 'minLength': 1, 'description': "Ticker as the user names it, e.g. 'AAPL', 'ES', 'BTCUSDT'."}, 'quantity': {'type': 'number', 'description': 'Units, shares or contracts filled â\x80\x94 always positive; `side` carries the direction.', 'exclusiveMinimum': 0}, 'assetClass': {'enum': ['equity', 'option', 'futures', 'forex', 'crypto', 'cfd', 'other'], 'type': 'string'}, 'executedAt': {'type': 'string', 'minLength': 1, 'description': "When the fill happened â\x80\x94 ISO 8601 with a UTC offset, e.g. '2026-09-08T13:35:00-04:00'. Order among fills follows this."}}}, 'maxItems': 100, 'minItems': 1, 'description': 'The fills, in any order.'}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'accountId': {'type': 'string', 'minLength': 1, 'description': 'A `manual` or `import` account id from journal_list_accounts.'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'to': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Inclusive end day (YYYY-MM-DD, journal timezone). Overrides `range`.'}, 'from': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Inclusive start day (YYYY-MM-DD, journal timezone). Overrides `range`.'}, 'range': {'enum': ['today', '7d', '30d', '90d', '365d', 'ytd', 'all'], 'type': 'string', 'description': 'Named window ending today in the journal timezone. Ignored when from/to are given.'}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'accounts': {'type': 'array', 'items': {'type': 'string', 'minLength': 1}, 'maxItems': 50, 'minItems': 1, 'description': 'Journal account ids to scope to (from journal_list_accounts). Omit for every account, archived ones included. Unknown ids are rejected.'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'month': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}$', 'description': 'Month as YYYY-MM. Default: the current month in the journal timezone.'}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'accounts': {'type': 'array', 'items': {'type': 'string', 'minLength': 1}, 'maxItems': 50, 'minItems': 1, 'description': 'Journal account ids to scope to (from journal_list_accounts). Omit for every account, archived ones included. Unknown ids are rejected.'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['date', 'context'], 'properties': {'date': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'The day, YYYY-MM-DD in the journal timezone.'}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'accounts': {'type': 'array', 'items': {'type': 'string', 'minLength': 1}, 'maxItems': 50, 'minItems': 1, 'description': 'Journal account ids to scope to (from journal_list_accounts). Omit for every account, archived ones included. Unknown ids are rejected.'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['key', 'context'], 'properties': {'key': {'type': 'string', 'minLength': 1, 'description': "The trade's `key` exactly as returned by journal_list_trades, journal_get_day, journal_search_notes or journal_add_trade. Never construct one."}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'accounts': {'type': 'array', 'items': {'type': 'string', 'minLength': 1}, 'maxItems': 50, 'minItems': 1, 'description': 'Journal account ids to scope to (from journal_list_accounts). Omit for every account, archived ones included. Unknown ids are rejected.'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'to': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Inclusive end day (YYYY-MM-DD, journal timezone). Overrides `range`.'}, 'tag': {'type': 'string', 'maxLength': 40, 'minLength': 1, 'description': 'Trades carrying exactly this tag (see journal_list_tags).'}, 'from': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Inclusive start day (YYYY-MM-DD, journal timezone). Overrides `range`.'}, 'sort': {'enum': ['openedAt', 'closedAt', 'netPnl', 'grossPnl', 'durationMs', 'quantity', 'symbol', 'rating'], 'type': 'string', 'description': 'Field to order by; default openedAt. Trades without a value for it come last in either order.'}, 'limit': {'type': 'integer', 'maximum': 100, 'minimum': 1, 'description': 'Page size, default 25.'}, 'order': {'enum': ['asc', 'desc'], 'type': 'string', 'description': 'Default desc (largest / latest first); symbol defaults to asc (Aâ\x86\x92Z).'}, 'cursor': {'type': 'string', 'minLength': 1, 'description': '`nextCursor` from the previous page; keep every other argument identical.'}, 'status': {'enum': ['open', 'win', 'loss', 'breakeven'], 'type': 'string'}, 'symbol': {'type': 'string', 'maxLength': 30, 'minLength': 1, 'description': "One symbol, e.g. 'AAPL' (case-insensitive)."}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'accounts': {'type': 'array', 'items': {'type': 'string', 'minLength': 1}, 'maxItems': 50, 'minItems': 1, 'description': 'Journal account ids to scope to (from journal_list_accounts). Omit for every account, archived ones included. Unknown ids are rejected.'}, 'direction': {'enum': ['long', 'short'], 'type': 'string'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'to': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Inclusive end day (YYYY-MM-DD, journal timezone). Overrides `range`.'}, 'from': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Inclusive start day (YYYY-MM-DD, journal timezone). Overrides `range`.'}, 'range': {'enum': ['today', '7d', '30d', '90d', '365d', 'ytd', 'all'], 'type': 'string', 'description': 'Named window ending today in the journal timezone. Ignored when from/to are given.'}, 'compare': {'type': 'boolean', 'description': 'Also compute the equal-length window immediately before this one.'}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'accounts': {'type': 'array', 'items': {'type': 'string', 'minLength': 1}, 'maxItems': 50, 'minItems': 1, 'description': 'Journal account ids to scope to (from journal_list_accounts). Omit for every account, archived ones included. Unknown ids are rejected.'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'q': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': 'Substring to look for in note text, case-insensitive.'}, 'to': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Inclusive end day (YYYY-MM-DD, journal timezone). Overrides `range`.'}, 'from': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Inclusive start day (YYYY-MM-DD, journal timezone). Overrides `range`.'}, 'limit': {'type': 'integer', 'maximum': 100, 'minimum': 1, 'description': 'Page size, default 25.'}, 'cursor': {'type': 'string', 'minLength': 1, 'description': '`nextCursor` from the previous page; keep every other argument identical.'}, 'symbol': {'type': 'string', 'maxLength': 30, 'minLength': 1}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'accounts': {'type': 'array', 'items': {'type': 'string', 'minLength': 1}, 'maxItems': 50, 'minItems': 1, 'description': 'Journal account ids to scope to (from journal_list_accounts). Omit for every account, archived ones included. Unknown ids are rejected.'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['noteId', 'context'], 'properties': {'body': {'type': 'string', 'maxLength': 50000, 'minLength': 1, 'description': 'The full new text.'}, 'date': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'Move the note to this day, YYYY-MM-DD in the journal timezone.'}, 'noteId': {'type': 'string', 'minLength': 1, 'description': "The note's `id`."}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['key', 'context'], 'properties': {'key': {'type': 'string', 'minLength': 1, 'description': "The trade's `key` exactly as returned by journal_list_trades, journal_get_day, journal_search_notes or journal_add_trade. Never construct one."}, 'tags': {'anyOf': [{'type': 'array', 'items': {'type': 'string', 'maxLength': 40, 'minLength': 1}, 'maxItems': 20, 'description': 'Replace the whole tag list; null clears it. Not with addTags/removeTags.'}, {'type': 'null'}]}, 'notes': {'anyOf': [{'type': 'string', 'maxLength': 20000}, {'type': 'null'}], 'description': "Replaces the trade's note text; null clears it."}, 'rating': {'anyOf': [{'type': 'integer', 'maximum': 5, 'minimum': 1}, {'type': 'null'}], 'description': 'Execution quality 1â\x80\x935; null clears it.'}, 'addTags': {'type': 'array', 'items': {'type': 'string', 'maxLength': 40, 'minLength': 1}, 'maxItems': 20, 'description': 'Tags to add (existing ones are kept; case-insensitive duplicates are ignored).'}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'mistakes': {'anyOf': [{'type': 'array', 'items': {'type': 'string', 'maxLength': 80, 'minLength': 1}, 'maxItems': 20, 'description': 'Replace the whole mistakes list; null clears it. Not with addMistakes/removeMistakes.'}, {'type': 'null'}]}, 'reviewed': {'type': 'boolean', 'description': 'Mark the trade reviewed (true) or not (false).'}, 'stopLoss': {'type': ['number', 'null'], 'description': 'Planned stop price; null clears it.'}, 'playbookId': {'anyOf': [{'type': 'string', 'maxLength': 100}, {'type': 'null'}], 'description': 'Playbook / setup name this trade followed; null clears it.'}, 'removeTags': {'type': 'array', 'items': {'type': 'string', 'maxLength': 40, 'minLength': 1}, 'maxItems': 20, 'description': 'Tags to remove (case-insensitive).'}, 'addMistakes': {'type': 'array', 'items': {'type': 'string', 'maxLength': 80, 'minLength': 1}, 'maxItems': 20, 'description': 'Mistakes to add.'}, 'profitTarget': {'type': ['number', 'null'], 'description': 'Planned target price; null clears it.'}, 'removeMistakes': {'type': 'array', 'items': {'type': 'string', 'maxLength': 80, 'minLength': 1}, 'maxItems': 20, 'description': 'Mistakes to remove (case-insensitive).'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['date', 'body', 'context'], 'properties': {'body': {'type': 'string', 'maxLength': 50000, 'minLength': 1, 'description': 'The note text (plain text or markdown).'}, 'date': {'type': 'string', 'pattern': '^\\d{4}-\\d{2}-\\d{2}$', 'description': 'The day the note belongs to, YYYY-MM-DD in the journal timezone.'}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['slug', 'context'], 'properties': {'slug': {'type': 'string', 'minLength': 1, 'description': "Exact concept slug, e.g. 'rsi' or 'order-blocks' â\x80\x94 from search or list results"}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['key', 'context'], 'properties': {'key': {'enum': ['trend', 'momentum', 'volatility', 'volume-orderflow', 'market-structure', 'smc-ict', 'wyckoff', 'elliott-harmonics', 'patterns', 'levels', 'statistics', 'machine-learning', 'time-seasonality', 'sentiment-breadth', 'risk-exits', 'meta-composition', 'validation'], 'type': 'string', 'description': "Family key, e.g. 'smc-ict'"}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['slug', 'context'], 'properties': {'slug': {'type': 'string', 'minLength': 1, 'description': "Indicator slug, e.g. 'tri-star'"}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['slug', 'context'], 'properties': {'slug': {'type': 'string', 'minLength': 1, 'description': 'Indicator slug'}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'page': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Default 0'}, 'family': {'enum': ['trend', 'momentum', 'volatility', 'volume-orderflow', 'market-structure', 'smc-ict', 'wyckoff', 'elliott-harmonics', 'patterns', 'levels', 'statistics', 'machine-learning', 'time-seasonality', 'sentiment-breadth', 'risk-exits', 'meta-composition', 'validation'], 'type': 'string'}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'page_size': {'type': 'integer', 'maximum': 200, 'minimum': 1, 'description': 'Default 50'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'page': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Default 0'}, 'sort': {'enum': ['name', 'date', 'family'], 'type': 'string', 'description': 'Default: date'}, 'tags': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Tag ids (from library_list_tags); an indicator must carry every tag'}, 'text': {'type': 'string', 'description': 'Server-side text filter'}, 'tier': {'enum': ['essential', 'premium', 'ultimate', 'ultra'], 'type': 'string', 'description': 'Only indicators included in this LuxAlgo plan tier'}, 'family': {'enum': ['trend', 'momentum', 'volatility', 'volume-orderflow', 'market-structure', 'smc-ict', 'wyckoff', 'elliott-harmonics', 'patterns', 'levels', 'statistics', 'machine-learning', 'time-seasonality', 'sentiment-breadth', 'risk-exits', 'meta-composition', 'validation'], 'type': 'string'}, 'concept': {'type': 'string', 'description': "Concept slug â\x80\x94 only indicators linked to this concept, e.g. 'rsi'"}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'platform': {'type': 'string', 'description': "Trading platform the indicator supports, e.g. 'metatrader'"}, 'direction': {'enum': ['asc', 'desc'], 'type': 'string'}, 'page_size': {'type': 'integer', 'maximum': 100, 'minimum': 1, 'description': 'Default 24'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['query', 'context'], 'properties': {'type': {'enum': ['all', 'concepts', 'indicators'], 'type': 'string', 'description': "Limit to 'concepts' (explanations) or 'indicators' (implementations); default all"}, 'limit': {'type': 'integer', 'maximum': 50, 'minimum': 1, 'description': 'Max results (default 10)'}, 'query': {'type': 'string', 'minLength': 1, 'description': "A concept, indicator name, alias, or topic â\x80\x94 e.g. 'order blocks', 'mean reversion', 'stochastics'"}, 'family': {'enum': ['trend', 'momentum', 'volatility', 'volume-orderflow', 'market-structure', 'smc-ict', 'wyckoff', 'elliott-harmonics', 'patterns', 'levels', 'statistics', 'machine-learning', 'time-seasonality', 'sentiment-breadth', 'risk-exits', 'meta-composition', 'validation'], 'type': 'string', 'description': 'Narrow to one concept family'}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['firmId', 'challengeId', 'context'], 'properties': {'firmId': {'type': 'string', 'minLength': 1, 'description': "Directory firm id or firm name from propfirms_list_simulatable, e.g. 'ftmo'."}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'challengeId': {'type': 'string', 'minLength': 1, 'description': 'Directory challenge id from propfirms_list_simulatable.'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['challenges', 'winRate', 'avgWinR', 'tradesPerDay', 'riskValue', 'context'], 'properties': {'seed': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991}, {'type': 'string'}], 'description': 'RNG seed (integer or string). Default 42. Same inputs + seed reproduce byte-identical results - include the seed when reporting so users can reproduce the numbers.'}, 'paths': {'type': 'integer', 'maximum': 100000, 'minimum': 100, 'description': 'Monte Carlo paths (independent simulated trader journeys). Default 10,000 (well under a second); capped at 100,000 per tool call. Confidence intervals shrink roughly with the square root of paths.'}, 'avgWinR': {'type': 'number', 'description': 'Average winning trade in R-multiples, i.e. multiples of the amount risked per trade (1.5 = winners average 1.5x the risk).', 'exclusiveMinimum': 0}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'winRate': {'type': 'number', 'maximum': 1, 'minimum': 0, 'description': 'Probability a trade is a winner, as a FRACTION in [0, 1] (0.55 = 55% winners) - NOT percent units. The most impactful input: traders routinely overestimate it by a few points, which can flip EV negative, so prefer measured stats over self-reported ones.'}, 'winStdR': {'type': 'number', 'minimum': 0, 'description': 'Standard deviation of winner sizes in R (0 = every winner is exactly avgWinR). Default 0. Adding spread makes streak damage more realistic.'}, 'avgLossR': {'type': 'number', 'description': 'Average losing trade in R, as a POSITIVE number. Default 1 (losers lose exactly the risked amount, i.e. stops are honored). Raise above 1 to model slippage or blown stops.', 'exclusiveMinimum': 0}, 'lossStdR': {'type': 'number', 'minimum': 0, 'description': 'Standard deviation of loser sizes in R (0 = every loser is exactly avgLossR). Default 0.'}, 'riskMode': {'enum': ['percent-of-balance', 'percent-of-initial', 'fixed-amount'], 'type': 'string', 'description': "How riskValue is interpreted. 'percent-of-balance' (default): risk compounds with the current balance. 'percent-of-initial': constant currency risk derived from the initial account size - how most prop traders size, since loss limits are fixed in currency. 'fixed-amount': explicit currency risked per 1R."}, 'riskValue': {'type': 'number', 'description': "Risk per trade - the value of 1R. PERCENT UNITS for percent modes (0.5 = 0.5% risked per trade; a typical prop range is 0.25-2), or a currency amount for 'fixed-amount'. NOT a fraction.", 'exclusiveMinimum': 0}, 'attemptCap': {'type': 'integer', 'maximum': 1000, 'minimum': 1, 'description': 'Maximum challenge attempts per path before that path gives up. Default 25. Journey statistics (expected attempts/cost, P(funded)) are censored at this cap.'}, 'challenges': {'type': 'array', 'items': {'type': 'object', 'properties': {'spec': {'type': 'object', 'required': ['challengeId', 'name', 'accountSize', 'steps', 'dailyLoss', 'maxLoss', 'fees', 'funded'], 'properties': {'fees': {'type': 'object', 'required': ['price'], 'properties': {'price': {'type': 'number', 'minimum': 0, 'description': "Challenge price in account currency. Under 'monthly' billing: price per month."}, 'billing': {'enum': ['one-time', 'monthly'], 'type': 'string', 'description': "'one-time' (default): the price buys one attempt; failed attempts are re-bought or reset. 'monthly': recurring subscription while evaluating (common for futures firms)."}, 'resetFee': {'anyOf': [{'type': 'number', 'minimum': 0}, {'type': 'null'}], 'description': 'Discounted fee to reset a failed attempt. null (default) = no reset offer: a failed one-time attempt costs full price again; a failed monthly attempt rides on the subscription.'}, 'activationFee': {'type': 'number', 'minimum': 0, 'description': 'One-time fee charged when the funded account is activated. Default 0.'}, 'refundableOnPass': {'type': 'boolean', 'description': 'Whether the one-time challenge fee is refunded once funded (credited back in cost/EV). Default false.'}}, 'description': 'Fees - everything that goes into expected total cost.', 'additionalProperties': {}}, 'name': {'type': 'string', 'minLength': 1, 'description': "Display name, e.g. '100K 2-Step'."}, 'steps': {'type': 'array', 'items': {'type': 'object', 'properties': {'maxDays': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'exclusiveMinimum': 0}, {'type': 'null'}], 'description': 'Trading-day limit for the step; null (the default) = unlimited time.'}, 'maxLoss': {'type': 'object', 'required': ['mode'], 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Max loss in PERCENT UNITS of the initial account size (10 = 10%). Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'mode': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized', 'trailing-locks-at-initial'], 'type': 'string', 'description': "How the max-loss floor behaves - the single most consequential rule difference between firms. 'static-initial': floor fixed at initial balance minus the limit; never moves (classic CFD two-step). 'trailing-realized-eod': floor ratchets up with end-of-day balance highs; intraday highs do not move it. 'trailing-intraday-unrealized': floor trails the peak unrealized equity intraday and never stops trailing (futures-style; the most-miscalculated rule in the industry: it cuts pass probability dramatically). 'trailing-locks-at-initial': trails intraday peak equity until the floor reaches the initial balance, then freezes (common futures variant). Locking is also composable: locksAtInitial adds the same lock to an EOD trail, and lockOffsetAmount shifts the lock level to initial balance + that amount (e.g. 100 models 'stops trailing $100 above the start')."}, 'amount': {'type': 'number', 'description': 'Max loss as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'locksAtInitial': {'type': 'boolean', 'description': "For trailing modes: once the trailing floor climbs up to the initial balance (plus lockOffsetAmount), it locks there and stops trailing. Default false. 'trailing-locks-at-initial' locks by definition; set this to add the same lock to 'trailing-realized-eod' (e.g. an EOD trail that stops at the starting balance)."}, 'lockOffsetAmount': {'type': 'number', 'minimum': 0, 'description': "Currency offset of the lock level: the floor locks at initial balance + this amount, modeling rules like 'the trailing threshold stops $100 above the start'. Default 0. Only meaningful when the rule locks (mode 'trailing-locks-at-initial' or locksAtInitial=true)."}}, 'description': 'Per-step override of the challenge-level max loss rule. Omit to inherit.', 'additionalProperties': {}}, 'dailyLoss': {'anyOf': [{'type': 'object', 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Daily loss limit in PERCENT UNITS (5 = 5%); what it is a percent OF is set by limitBasis. Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'basis': {'enum': ['prior-day-balance', 'prior-day-equity'], 'type': 'string', 'description': "Anchor today's loss is measured from: prior day's closing balance or closing equity (they differ only with overnight positions). Default 'prior-day-balance'."}, 'amount': {'type': 'number', 'description': 'Daily loss limit as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'evaluation': {'enum': ['intraday', 'end-of-day'], 'type': 'string', 'description': "'intraday': fails the moment equity touches the daily floor. 'end-of-day': only the close is checked. Default 'intraday'."}, 'limitBasis': {'enum': ['initial-balance', 'anchor'], 'type': 'string', 'description': "What a percentage limit is a percent OF. 'initial-balance': a fixed currency allowance (always e.g. 5% of the starting account). 'anchor': recomputed daily from the day's anchor. Default 'initial-balance'."}, 'includesOpenPnl': {'type': 'boolean', 'description': 'Whether floating (unrealized) P&L counts toward the daily loss, i.e. breach can happen intra-position. Default true.'}}, 'description': 'Daily loss rule: the daily floor is anchor minus limit, reset at each trading-day boundary. Exactly one of pct/amount must be set.', 'additionalProperties': {}}, {'type': 'null'}], 'description': 'Per-step override of the challenge-level daily loss rule. Omit to inherit; null = no daily loss rule in this step.'}, 'consistency': {'anyOf': [{'type': 'object', 'required': ['maxBestDayProfitPct'], 'properties': {'maxBestDayProfitPct': {'type': 'number', 'maximum': 100, 'description': "Maximum share of the step's total profit the best single day may contribute, in PERCENT UNITS (40 = the best day may be at most 40% of total profit).", 'exclusiveMinimum': 0}}, 'additionalProperties': {}}, {'type': 'null'}], 'description': "Consistency rule - SIMULATED (engine v1), not just flagged: one outsized day effectively raises the target (total profit must reach best day / pct), and the simulated trader keeps trading - rationally stopping days early when that helps - until the best-day share complies (see flag 'consistency-stop-rule'). null or omitted = no consistency rule."}, 'minTradingDays': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Minimum days with at least one trade before the step can be passed. Default 0.'}, 'profitTargetPct': {'type': 'number', 'description': 'Profit target in PERCENT UNITS of the initial account size (8 = 8%). Exactly one of profitTargetPct/profitTargetAmount.', 'exclusiveMinimum': 0}, 'profitTargetAmount': {'type': 'number', 'description': 'Profit target as a fixed currency amount (alternative to profitTargetPct).', 'exclusiveMinimum': 0}}, 'description': 'One evaluation step. Each step starts on a fresh account at the initial balance.', 'additionalProperties': {}}, 'minItems': 1, 'description': 'Evaluation steps in order. Passing the last step means funded.'}, 'funded': {'type': 'object', 'required': ['profitSplitPct', 'payoutFrequency'], 'properties': {'notes': {'type': 'string', 'description': 'Free-text funded-stage details that are not simulated.'}, 'maxLoss': {'type': 'object', 'required': ['mode'], 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Max loss in PERCENT UNITS of the initial account size (10 = 10%). Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'mode': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized', 'trailing-locks-at-initial'], 'type': 'string', 'description': "How the max-loss floor behaves - the single most consequential rule difference between firms. 'static-initial': floor fixed at initial balance minus the limit; never moves (classic CFD two-step). 'trailing-realized-eod': floor ratchets up with end-of-day balance highs; intraday highs do not move it. 'trailing-intraday-unrealized': floor trails the peak unrealized equity intraday and never stops trailing (futures-style; the most-miscalculated rule in the industry: it cuts pass probability dramatically). 'trailing-locks-at-initial': trails intraday peak equity until the floor reaches the initial balance, then freezes (common futures variant). Locking is also composable: locksAtInitial adds the same lock to an EOD trail, and lockOffsetAmount shifts the lock level to initial balance + that amount (e.g. 100 models 'stops trailing $100 above the start')."}, 'amount': {'type': 'number', 'description': 'Max loss as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'locksAtInitial': {'type': 'boolean', 'description': "For trailing modes: once the trailing floor climbs up to the initial balance (plus lockOffsetAmount), it locks there and stops trailing. Default false. 'trailing-locks-at-initial' locks by definition; set this to add the same lock to 'trailing-realized-eod' (e.g. an EOD trail that stops at the starting balance)."}, 'lockOffsetAmount': {'type': 'number', 'minimum': 0, 'description': "Currency offset of the lock level: the floor locks at initial balance + this amount, modeling rules like 'the trailing threshold stops $100 above the start'. Default 0. Only meaningful when the rule locks (mode 'trailing-locks-at-initial' or locksAtInitial=true)."}}, 'description': 'Funded-account override of the max loss rule. Omit to inherit.', 'additionalProperties': {}}, 'dailyLoss': {'anyOf': [{'type': 'object', 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Daily loss limit in PERCENT UNITS (5 = 5%); what it is a percent OF is set by limitBasis. Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'basis': {'enum': ['prior-day-balance', 'prior-day-equity'], 'type': 'string', 'description': "Anchor today's loss is measured from: prior day's closing balance or closing equity (they differ only with overnight positions). Default 'prior-day-balance'."}, 'amount': {'type': 'number', 'description': 'Daily loss limit as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'evaluation': {'enum': ['intraday', 'end-of-day'], 'type': 'string', 'description': "'intraday': fails the moment equity touches the daily floor. 'end-of-day': only the close is checked. Default 'intraday'."}, 'limitBasis': {'enum': ['initial-balance', 'anchor'], 'type': 'string', 'description': "What a percentage limit is a percent OF. 'initial-balance': a fixed currency allowance (always e.g. 5% of the starting account). 'anchor': recomputed daily from the day's anchor. Default 'initial-balance'."}, 'includesOpenPnl': {'type': 'boolean', 'description': 'Whether floating (unrealized) P&L counts toward the daily loss, i.e. breach can happen intra-position. Default true.'}}, 'description': 'Daily loss rule: the daily floor is anchor minus limit, reset at each trading-day boundary. Exactly one of pct/amount must be set.', 'additionalProperties': {}}, {'type': 'null'}], 'description': 'Funded-account override of the daily loss rule. Omit to inherit; null = none.'}, 'payoutRules': {'type': 'object', 'properties': {'bufferAmount': {'type': 'number', 'minimum': 0, 'description': 'Profit buffer that must remain in the account; only profit above it is withdrawable. Default 0.'}, 'minWinningDays': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Winning days required in a payout window before a payout can be requested. Default 0.'}, 'maxPayoutAmount': {'type': 'number', 'description': 'Absolute currency cap per payout request. Omit for no fixed cap.', 'exclusiveMinimum': 0}, 'winningDayMinProfit': {'type': 'number', 'minimum': 0, 'description': 'Minimum profit for a day to count as a winning day. Default 0 (any positive day).'}, 'maxPayoutPctOfProfit': {'type': 'number', 'maximum': 100, 'description': 'Cap on each payout in PERCENT UNITS of accrued profit (50 = at most half the profit per request). Omit for no percentage cap.', 'exclusiveMinimum': 0}, 'consistencyMaxBestDayPct': {'type': 'number', 'maximum': 100, 'description': "Funded consistency gate in PERCENT UNITS: the best day may contribute at most this share of the payout window's profit. Evaluated per window (see flag 'funded-consistency-window-approximated').", 'exclusiveMinimum': 0}}, 'description': "Payout gating - SIMULATED (engine v1), not just flagged: a payout happens only when these conditions are met, and on each eligible payout day the trader withdraws the maximum the rules allow (profit above the buffer, under the caps, never below the loss floor); balances and loss floors carry across payouts (see flag 'funded-withdrawal-model'). Omit for ungated payouts.", 'additionalProperties': {}}, 'profitSplitPct': {'type': 'number', 'maximum': 100, 'minimum': 0, 'description': "Trader's share of funded profits in PERCENT UNITS (80 = 80%)."}, 'payoutFrequency': {'enum': ['weekly', 'biweekly', 'monthly', 'on-demand'], 'type': 'string', 'description': 'How often funded profits can be withdrawn.'}, 'firstPayoutMinDays': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Minimum days on the funded account before the first payout. Default 0.'}}, 'description': 'Funded-stage terms used for the payout/EV simulation.', 'additionalProperties': {}}, 'maxLoss': {'type': 'object', 'required': ['mode'], 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Max loss in PERCENT UNITS of the initial account size (10 = 10%). Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'mode': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized', 'trailing-locks-at-initial'], 'type': 'string', 'description': "How the max-loss floor behaves - the single most consequential rule difference between firms. 'static-initial': floor fixed at initial balance minus the limit; never moves (classic CFD two-step). 'trailing-realized-eod': floor ratchets up with end-of-day balance highs; intraday highs do not move it. 'trailing-intraday-unrealized': floor trails the peak unrealized equity intraday and never stops trailing (futures-style; the most-miscalculated rule in the industry: it cuts pass probability dramatically). 'trailing-locks-at-initial': trails intraday peak equity until the floor reaches the initial balance, then freezes (common futures variant). Locking is also composable: locksAtInitial adds the same lock to an EOD trail, and lockOffsetAmount shifts the lock level to initial balance + that amount (e.g. 100 models 'stops trailing $100 above the start')."}, 'amount': {'type': 'number', 'description': 'Max loss as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'locksAtInitial': {'type': 'boolean', 'description': "For trailing modes: once the trailing floor climbs up to the initial balance (plus lockOffsetAmount), it locks there and stops trailing. Default false. 'trailing-locks-at-initial' locks by definition; set this to add the same lock to 'trailing-realized-eod' (e.g. an EOD trail that stops at the starting balance)."}, 'lockOffsetAmount': {'type': 'number', 'minimum': 0, 'description': "Currency offset of the lock level: the floor locks at initial balance + this amount, modeling rules like 'the trailing threshold stops $100 above the start'. Default 0. Only meaningful when the rule locks (mode 'trailing-locks-at-initial' or locksAtInitial=true)."}}, 'description': 'Challenge-level max loss rule applied to every step unless a step overrides it. Required.', 'additionalProperties': {}}, 'sources': {'type': 'array', 'items': {'type': 'object', 'required': ['url', 'lastVerified'], 'properties': {'url': {'type': 'string', 'description': 'Public page documenting the rule.'}, 'note': {'type': 'string'}, 'lastVerified': {'type': 'string', 'description': 'ISO date the rules were last checked against that page.'}}, 'additionalProperties': {}}, 'description': 'Public citations. Optional for inline specs; dataset entries always carry them.'}, 'currency': {'type': 'string', 'description': 'ISO currency code all amounts are denominated in. Default USD.'}, 'dailyLoss': {'anyOf': [{'type': 'object', 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Daily loss limit in PERCENT UNITS (5 = 5%); what it is a percent OF is set by limitBasis. Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'basis': {'enum': ['prior-day-balance', 'prior-day-equity'], 'type': 'string', 'description': "Anchor today's loss is measured from: prior day's closing balance or closing equity (they differ only with overnight positions). Default 'prior-day-balance'."}, 'amount': {'type': 'number', 'description': 'Daily loss limit as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'evaluation': {'enum': ['intraday', 'end-of-day'], 'type': 'string', 'description': "'intraday': fails the moment equity touches the daily floor. 'end-of-day': only the close is checked. Default 'intraday'."}, 'limitBasis': {'enum': ['initial-balance', 'anchor'], 'type': 'string', 'description': "What a percentage limit is a percent OF. 'initial-balance': a fixed currency allowance (always e.g. 5% of the starting account). 'anchor': recomputed daily from the day's anchor. Default 'initial-balance'."}, 'includesOpenPnl': {'type': 'boolean', 'description': 'Whether floating (unrealized) P&L counts toward the daily loss, i.e. breach can happen intra-position. Default true.'}}, 'description': 'Daily loss rule: the daily floor is anchor minus limit, reset at each trading-day boundary. Exactly one of pct/amount must be set.', 'additionalProperties': {}}, {'type': 'null'}], 'description': 'Challenge-level daily loss rule applied to every step unless a step overrides it. null = no daily loss rule. This field is required (pass null explicitly for none).'}, 'accountSize': {'type': 'number', 'description': 'Initial account balance in account currency.', 'exclusiveMinimum': 0}, 'challengeId': {'type': 'string', 'minLength': 1, 'description': "Stable kebab-case id for this ruleset, e.g. '100k-2step'."}, 'constraints': {'type': 'object', 'description': 'Informational trading constraints (maxLeverage, newsTrading, weekendHolding, ...). Recorded and flagged, never simulated.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'productType': {'enum': ['futures', 'cfd', 'equities'], 'type': 'string', 'description': "Instrument class the challenge is traded on: 'futures', 'cfd' (forex/CFD), or 'equities'."}, 'flagsNotSimulated': {'type': 'array', 'items': {'type': 'string'}, 'description': "Honesty channel: ids of rules this entry has that the engine does not simulate (e.g. 'scaling-plan', 'soft-daily-lockout'). Surfaced in every result's assumption flags. Consistency rules and payout gating do NOT belong here - the engine simulates them."}}, 'description': "Inline challenge ruleset, for challenges not in the directory or for what-if rule edits. Mutually exclusive with firmId/challengeId. Identify the challenge EITHER by directory reference (firmId + challengeId, discovered via propfirms_list_simulatable; firmId accepts the directory id or the firm's name) OR by a full inline `spec` object - the exact shape propfirms_challenge_rules returns, so you can fetch a directory entry, change one rule, and re-simulate to model rule variations. Provide exactly one of the two forms; providing both or neither is an error. Directory references need network access; inline specs are fully offline.", 'additionalProperties': {}}, 'firmId': {'type': 'string', 'minLength': 1, 'description': "Directory firm id or firm name (e.g. 'ftmo' or 'FTMO'); discover with propfirms_list_simulatable. Must be paired with challengeId. Mutually exclusive with `spec`."}, 'challengeId': {'type': 'string', 'minLength': 1, 'description': 'Directory challenge id; discover with propfirms_list_simulatable. Must be paired with firmId. Mutually exclusive with `spec`.'}}, 'description': 'One challenge: either firmId + challengeId (dataset) or an inline spec.'}, 'maxItems': 12, 'minItems': 1, 'description': 'The challenges to simulate this trader across (1-12 entries; 2+ for a meaningful comparison). Mix dataset references and inline specs freely.'}, 'tradesPerDay': {'type': 'number', 'description': 'Average trades per simulated trading day. More trades per day means more ways to hit the daily loss limit within a single day.', 'exclusiveMinimum': 0}, 'simulateFunded': {'type': 'boolean', 'description': 'Whether to simulate the funded stage (payouts, blowup risk) after passing. Default true - EV is only meaningful with it on; set false to study the evaluation alone.'}, 'fundedHorizonDays': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Funded-stage horizon in trading days for the payout/EV simulation. Default 90 (about 4 calendar months). EV scales with this choice - state it when reporting EV.'}, 'tradesPerDayModel': {'enum': ['fixed', 'poisson'], 'type': 'string', 'description': "'fixed' (default): the same count every day. 'poisson': daily count drawn Poisson(tradesPerDay); days can then have zero trades, which do not count as trading days."}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['propfirmId', 'context'], 'properties': {'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'propfirmId': {'type': 'string', 'minLength': 1, 'description': "Public firm slug, e.g. 'ftmo'"}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'productType': {'enum': ['futures', 'cfd'], 'type': 'string', 'description': 'Optional filter to one instrument class. Omit to list every firm.'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['winRate', 'avgWinR', 'tradesPerDay', 'context'], 'properties': {'max': {'type': 'number', 'description': 'Grid end, same units as min. Default 3 (= 3% per trade for percent modes).', 'exclusiveMinimum': 0}, 'min': {'type': 'number', 'description': "Grid start, in the risk units of riskMode (percent units for percent modes, currency for 'fixed-amount'). Default 0.1 (= 0.1% per trade for percent modes).", 'exclusiveMinimum': 0}, 'seed': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991}, {'type': 'string'}], 'description': 'RNG seed (integer or string). Default 42. Same inputs + seed reproduce byte-identical results - include the seed when reporting so users can reproduce the numbers.'}, 'spec': {'type': 'object', 'required': ['challengeId', 'name', 'accountSize', 'steps', 'dailyLoss', 'maxLoss', 'fees', 'funded'], 'properties': {'fees': {'type': 'object', 'required': ['price'], 'properties': {'price': {'type': 'number', 'minimum': 0, 'description': "Challenge price in account currency. Under 'monthly' billing: price per month."}, 'billing': {'enum': ['one-time', 'monthly'], 'type': 'string', 'description': "'one-time' (default): the price buys one attempt; failed attempts are re-bought or reset. 'monthly': recurring subscription while evaluating (common for futures firms)."}, 'resetFee': {'anyOf': [{'type': 'number', 'minimum': 0}, {'type': 'null'}], 'description': 'Discounted fee to reset a failed attempt. null (default) = no reset offer: a failed one-time attempt costs full price again; a failed monthly attempt rides on the subscription.'}, 'activationFee': {'type': 'number', 'minimum': 0, 'description': 'One-time fee charged when the funded account is activated. Default 0.'}, 'refundableOnPass': {'type': 'boolean', 'description': 'Whether the one-time challenge fee is refunded once funded (credited back in cost/EV). Default false.'}}, 'description': 'Fees - everything that goes into expected total cost.', 'additionalProperties': {}}, 'name': {'type': 'string', 'minLength': 1, 'description': "Display name, e.g. '100K 2-Step'."}, 'steps': {'type': 'array', 'items': {'type': 'object', 'properties': {'maxDays': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'exclusiveMinimum': 0}, {'type': 'null'}], 'description': 'Trading-day limit for the step; null (the default) = unlimited time.'}, 'maxLoss': {'type': 'object', 'required': ['mode'], 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Max loss in PERCENT UNITS of the initial account size (10 = 10%). Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'mode': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized', 'trailing-locks-at-initial'], 'type': 'string', 'description': "How the max-loss floor behaves - the single most consequential rule difference between firms. 'static-initial': floor fixed at initial balance minus the limit; never moves (classic CFD two-step). 'trailing-realized-eod': floor ratchets up with end-of-day balance highs; intraday highs do not move it. 'trailing-intraday-unrealized': floor trails the peak unrealized equity intraday and never stops trailing (futures-style; the most-miscalculated rule in the industry: it cuts pass probability dramatically). 'trailing-locks-at-initial': trails intraday peak equity until the floor reaches the initial balance, then freezes (common futures variant). Locking is also composable: locksAtInitial adds the same lock to an EOD trail, and lockOffsetAmount shifts the lock level to initial balance + that amount (e.g. 100 models 'stops trailing $100 above the start')."}, 'amount': {'type': 'number', 'description': 'Max loss as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'locksAtInitial': {'type': 'boolean', 'description': "For trailing modes: once the trailing floor climbs up to the initial balance (plus lockOffsetAmount), it locks there and stops trailing. Default false. 'trailing-locks-at-initial' locks by definition; set this to add the same lock to 'trailing-realized-eod' (e.g. an EOD trail that stops at the starting balance)."}, 'lockOffsetAmount': {'type': 'number', 'minimum': 0, 'description': "Currency offset of the lock level: the floor locks at initial balance + this amount, modeling rules like 'the trailing threshold stops $100 above the start'. Default 0. Only meaningful when the rule locks (mode 'trailing-locks-at-initial' or locksAtInitial=true)."}}, 'description': 'Per-step override of the challenge-level max loss rule. Omit to inherit.', 'additionalProperties': {}}, 'dailyLoss': {'anyOf': [{'type': 'object', 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Daily loss limit in PERCENT UNITS (5 = 5%); what it is a percent OF is set by limitBasis. Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'basis': {'enum': ['prior-day-balance', 'prior-day-equity'], 'type': 'string', 'description': "Anchor today's loss is measured from: prior day's closing balance or closing equity (they differ only with overnight positions). Default 'prior-day-balance'."}, 'amount': {'type': 'number', 'description': 'Daily loss limit as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'evaluation': {'enum': ['intraday', 'end-of-day'], 'type': 'string', 'description': "'intraday': fails the moment equity touches the daily floor. 'end-of-day': only the close is checked. Default 'intraday'."}, 'limitBasis': {'enum': ['initial-balance', 'anchor'], 'type': 'string', 'description': "What a percentage limit is a percent OF. 'initial-balance': a fixed currency allowance (always e.g. 5% of the starting account). 'anchor': recomputed daily from the day's anchor. Default 'initial-balance'."}, 'includesOpenPnl': {'type': 'boolean', 'description': 'Whether floating (unrealized) P&L counts toward the daily loss, i.e. breach can happen intra-position. Default true.'}}, 'description': 'Daily loss rule: the daily floor is anchor minus limit, reset at each trading-day boundary. Exactly one of pct/amount must be set.', 'additionalProperties': {}}, {'type': 'null'}], 'description': 'Per-step override of the challenge-level daily loss rule. Omit to inherit; null = no daily loss rule in this step.'}, 'consistency': {'anyOf': [{'type': 'object', 'required': ['maxBestDayProfitPct'], 'properties': {'maxBestDayProfitPct': {'type': 'number', 'maximum': 100, 'description': "Maximum share of the step's total profit the best single day may contribute, in PERCENT UNITS (40 = the best day may be at most 40% of total profit).", 'exclusiveMinimum': 0}}, 'additionalProperties': {}}, {'type': 'null'}], 'description': "Consistency rule - SIMULATED (engine v1), not just flagged: one outsized day effectively raises the target (total profit must reach best day / pct), and the simulated trader keeps trading - rationally stopping days early when that helps - until the best-day share complies (see flag 'consistency-stop-rule'). null or omitted = no consistency rule."}, 'minTradingDays': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Minimum days with at least one trade before the step can be passed. Default 0.'}, 'profitTargetPct': {'type': 'number', 'description': 'Profit target in PERCENT UNITS of the initial account size (8 = 8%). Exactly one of profitTargetPct/profitTargetAmount.', 'exclusiveMinimum': 0}, 'profitTargetAmount': {'type': 'number', 'description': 'Profit target as a fixed currency amount (alternative to profitTargetPct).', 'exclusiveMinimum': 0}}, 'description': 'One evaluation step. Each step starts on a fresh account at the initial balance.', 'additionalProperties': {}}, 'minItems': 1, 'description': 'Evaluation steps in order. Passing the last step means funded.'}, 'funded': {'type': 'object', 'required': ['profitSplitPct', 'payoutFrequency'], 'properties': {'notes': {'type': 'string', 'description': 'Free-text funded-stage details that are not simulated.'}, 'maxLoss': {'type': 'object', 'required': ['mode'], 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Max loss in PERCENT UNITS of the initial account size (10 = 10%). Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'mode': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized', 'trailing-locks-at-initial'], 'type': 'string', 'description': "How the max-loss floor behaves - the single most consequential rule difference between firms. 'static-initial': floor fixed at initial balance minus the limit; never moves (classic CFD two-step). 'trailing-realized-eod': floor ratchets up with end-of-day balance highs; intraday highs do not move it. 'trailing-intraday-unrealized': floor trails the peak unrealized equity intraday and never stops trailing (futures-style; the most-miscalculated rule in the industry: it cuts pass probability dramatically). 'trailing-locks-at-initial': trails intraday peak equity until the floor reaches the initial balance, then freezes (common futures variant). Locking is also composable: locksAtInitial adds the same lock to an EOD trail, and lockOffsetAmount shifts the lock level to initial balance + that amount (e.g. 100 models 'stops trailing $100 above the start')."}, 'amount': {'type': 'number', 'description': 'Max loss as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'locksAtInitial': {'type': 'boolean', 'description': "For trailing modes: once the trailing floor climbs up to the initial balance (plus lockOffsetAmount), it locks there and stops trailing. Default false. 'trailing-locks-at-initial' locks by definition; set this to add the same lock to 'trailing-realized-eod' (e.g. an EOD trail that stops at the starting balance)."}, 'lockOffsetAmount': {'type': 'number', 'minimum': 0, 'description': "Currency offset of the lock level: the floor locks at initial balance + this amount, modeling rules like 'the trailing threshold stops $100 above the start'. Default 0. Only meaningful when the rule locks (mode 'trailing-locks-at-initial' or locksAtInitial=true)."}}, 'description': 'Funded-account override of the max loss rule. Omit to inherit.', 'additionalProperties': {}}, 'dailyLoss': {'anyOf': [{'type': 'object', 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Daily loss limit in PERCENT UNITS (5 = 5%); what it is a percent OF is set by limitBasis. Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'basis': {'enum': ['prior-day-balance', 'prior-day-equity'], 'type': 'string', 'description': "Anchor today's loss is measured from: prior day's closing balance or closing equity (they differ only with overnight positions). Default 'prior-day-balance'."}, 'amount': {'type': 'number', 'description': 'Daily loss limit as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'evaluation': {'enum': ['intraday', 'end-of-day'], 'type': 'string', 'description': "'intraday': fails the moment equity touches the daily floor. 'end-of-day': only the close is checked. Default 'intraday'."}, 'limitBasis': {'enum': ['initial-balance', 'anchor'], 'type': 'string', 'description': "What a percentage limit is a percent OF. 'initial-balance': a fixed currency allowance (always e.g. 5% of the starting account). 'anchor': recomputed daily from the day's anchor. Default 'initial-balance'."}, 'includesOpenPnl': {'type': 'boolean', 'description': 'Whether floating (unrealized) P&L counts toward the daily loss, i.e. breach can happen intra-position. Default true.'}}, 'description': 'Daily loss rule: the daily floor is anchor minus limit, reset at each trading-day boundary. Exactly one of pct/amount must be set.', 'additionalProperties': {}}, {'type': 'null'}], 'description': 'Funded-account override of the daily loss rule. Omit to inherit; null = none.'}, 'payoutRules': {'type': 'object', 'properties': {'bufferAmount': {'type': 'number', 'minimum': 0, 'description': 'Profit buffer that must remain in the account; only profit above it is withdrawable. Default 0.'}, 'minWinningDays': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Winning days required in a payout window before a payout can be requested. Default 0.'}, 'maxPayoutAmount': {'type': 'number', 'description': 'Absolute currency cap per payout request. Omit for no fixed cap.', 'exclusiveMinimum': 0}, 'winningDayMinProfit': {'type': 'number', 'minimum': 0, 'description': 'Minimum profit for a day to count as a winning day. Default 0 (any positive day).'}, 'maxPayoutPctOfProfit': {'type': 'number', 'maximum': 100, 'description': 'Cap on each payout in PERCENT UNITS of accrued profit (50 = at most half the profit per request). Omit for no percentage cap.', 'exclusiveMinimum': 0}, 'consistencyMaxBestDayPct': {'type': 'number', 'maximum': 100, 'description': "Funded consistency gate in PERCENT UNITS: the best day may contribute at most this share of the payout window's profit. Evaluated per window (see flag 'funded-consistency-window-approximated').", 'exclusiveMinimum': 0}}, 'description': "Payout gating - SIMULATED (engine v1), not just flagged: a payout happens only when these conditions are met, and on each eligible payout day the trader withdraws the maximum the rules allow (profit above the buffer, under the caps, never below the loss floor); balances and loss floors carry across payouts (see flag 'funded-withdrawal-model'). Omit for ungated payouts.", 'additionalProperties': {}}, 'profitSplitPct': {'type': 'number', 'maximum': 100, 'minimum': 0, 'description': "Trader's share of funded profits in PERCENT UNITS (80 = 80%)."}, 'payoutFrequency': {'enum': ['weekly', 'biweekly', 'monthly', 'on-demand'], 'type': 'string', 'description': 'How often funded profits can be withdrawn.'}, 'firstPayoutMinDays': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Minimum days on the funded account before the first payout. Default 0.'}}, 'description': 'Funded-stage terms used for the payout/EV simulation.', 'additionalProperties': {}}, 'maxLoss': {'type': 'object', 'required': ['mode'], 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Max loss in PERCENT UNITS of the initial account size (10 = 10%). Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'mode': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized', 'trailing-locks-at-initial'], 'type': 'string', 'description': "How the max-loss floor behaves - the single most consequential rule difference between firms. 'static-initial': floor fixed at initial balance minus the limit; never moves (classic CFD two-step). 'trailing-realized-eod': floor ratchets up with end-of-day balance highs; intraday highs do not move it. 'trailing-intraday-unrealized': floor trails the peak unrealized equity intraday and never stops trailing (futures-style; the most-miscalculated rule in the industry: it cuts pass probability dramatically). 'trailing-locks-at-initial': trails intraday peak equity until the floor reaches the initial balance, then freezes (common futures variant). Locking is also composable: locksAtInitial adds the same lock to an EOD trail, and lockOffsetAmount shifts the lock level to initial balance + that amount (e.g. 100 models 'stops trailing $100 above the start')."}, 'amount': {'type': 'number', 'description': 'Max loss as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'locksAtInitial': {'type': 'boolean', 'description': "For trailing modes: once the trailing floor climbs up to the initial balance (plus lockOffsetAmount), it locks there and stops trailing. Default false. 'trailing-locks-at-initial' locks by definition; set this to add the same lock to 'trailing-realized-eod' (e.g. an EOD trail that stops at the starting balance)."}, 'lockOffsetAmount': {'type': 'number', 'minimum': 0, 'description': "Currency offset of the lock level: the floor locks at initial balance + this amount, modeling rules like 'the trailing threshold stops $100 above the start'. Default 0. Only meaningful when the rule locks (mode 'trailing-locks-at-initial' or locksAtInitial=true)."}}, 'description': 'Challenge-level max loss rule applied to every step unless a step overrides it. Required.', 'additionalProperties': {}}, 'sources': {'type': 'array', 'items': {'type': 'object', 'required': ['url', 'lastVerified'], 'properties': {'url': {'type': 'string', 'description': 'Public page documenting the rule.'}, 'note': {'type': 'string'}, 'lastVerified': {'type': 'string', 'description': 'ISO date the rules were last checked against that page.'}}, 'additionalProperties': {}}, 'description': 'Public citations. Optional for inline specs; dataset entries always carry them.'}, 'currency': {'type': 'string', 'description': 'ISO currency code all amounts are denominated in. Default USD.'}, 'dailyLoss': {'anyOf': [{'type': 'object', 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Daily loss limit in PERCENT UNITS (5 = 5%); what it is a percent OF is set by limitBasis. Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'basis': {'enum': ['prior-day-balance', 'prior-day-equity'], 'type': 'string', 'description': "Anchor today's loss is measured from: prior day's closing balance or closing equity (they differ only with overnight positions). Default 'prior-day-balance'."}, 'amount': {'type': 'number', 'description': 'Daily loss limit as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'evaluation': {'enum': ['intraday', 'end-of-day'], 'type': 'string', 'description': "'intraday': fails the moment equity touches the daily floor. 'end-of-day': only the close is checked. Default 'intraday'."}, 'limitBasis': {'enum': ['initial-balance', 'anchor'], 'type': 'string', 'description': "What a percentage limit is a percent OF. 'initial-balance': a fixed currency allowance (always e.g. 5% of the starting account). 'anchor': recomputed daily from the day's anchor. Default 'initial-balance'."}, 'includesOpenPnl': {'type': 'boolean', 'description': 'Whether floating (unrealized) P&L counts toward the daily loss, i.e. breach can happen intra-position. Default true.'}}, 'description': 'Daily loss rule: the daily floor is anchor minus limit, reset at each trading-day boundary. Exactly one of pct/amount must be set.', 'additionalProperties': {}}, {'type': 'null'}], 'description': 'Challenge-level daily loss rule applied to every step unless a step overrides it. null = no daily loss rule. This field is required (pass null explicitly for none).'}, 'accountSize': {'type': 'number', 'description': 'Initial account balance in account currency.', 'exclusiveMinimum': 0}, 'challengeId': {'type': 'string', 'minLength': 1, 'description': "Stable kebab-case id for this ruleset, e.g. '100k-2step'."}, 'constraints': {'type': 'object', 'description': 'Informational trading constraints (maxLeverage, newsTrading, weekendHolding, ...). Recorded and flagged, never simulated.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'productType': {'enum': ['futures', 'cfd', 'equities'], 'type': 'string', 'description': "Instrument class the challenge is traded on: 'futures', 'cfd' (forex/CFD), or 'equities'."}, 'flagsNotSimulated': {'type': 'array', 'items': {'type': 'string'}, 'description': "Honesty channel: ids of rules this entry has that the engine does not simulate (e.g. 'scaling-plan', 'soft-daily-lockout'). Surfaced in every result's assumption flags. Consistency rules and payout gating do NOT belong here - the engine simulates them."}}, 'description': "Inline challenge ruleset, for challenges not in the directory or for what-if rule edits. Mutually exclusive with firmId/challengeId. Identify the challenge EITHER by directory reference (firmId + challengeId, discovered via propfirms_list_simulatable; firmId accepts the directory id or the firm's name) OR by a full inline `spec` object - the exact shape propfirms_challenge_rules returns, so you can fetch a directory entry, change one rule, and re-simulate to model rule variations. Provide exactly one of the two forms; providing both or neither is an error. Directory references need network access; inline specs are fully offline.", 'additionalProperties': {}}, 'step': {'type': 'number', 'description': 'Grid step, same units. Default 0.1. The sweep runs one full simulation per grid point, so (max - min) / step + 1 simulations in total - keep the grid coarse or paths low for a first pass.', 'exclusiveMinimum': 0}, 'paths': {'type': 'integer', 'maximum': 100000, 'minimum': 100, 'description': 'Monte Carlo paths (independent simulated trader journeys). Default 10,000 (well under a second); capped at 100,000 per tool call. Confidence intervals shrink roughly with the square root of paths.'}, 'firmId': {'type': 'string', 'minLength': 1, 'description': "Directory firm id or firm name (e.g. 'ftmo' or 'FTMO'); discover with propfirms_list_simulatable. Must be paired with challengeId. Mutually exclusive with `spec`."}, 'avgWinR': {'type': 'number', 'description': 'Average winning trade in R-multiples, i.e. multiples of the amount risked per trade (1.5 = winners average 1.5x the risk).', 'exclusiveMinimum': 0}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'winRate': {'type': 'number', 'maximum': 1, 'minimum': 0, 'description': 'Probability a trade is a winner, as a FRACTION in [0, 1] (0.55 = 55% winners) - NOT percent units. The most impactful input: traders routinely overestimate it by a few points, which can flip EV negative, so prefer measured stats over self-reported ones.'}, 'winStdR': {'type': 'number', 'minimum': 0, 'description': 'Standard deviation of winner sizes in R (0 = every winner is exactly avgWinR). Default 0. Adding spread makes streak damage more realistic.'}, 'avgLossR': {'type': 'number', 'description': 'Average losing trade in R, as a POSITIVE number. Default 1 (losers lose exactly the risked amount, i.e. stops are honored). Raise above 1 to model slippage or blown stops.', 'exclusiveMinimum': 0}, 'lossStdR': {'type': 'number', 'minimum': 0, 'description': 'Standard deviation of loser sizes in R (0 = every loser is exactly avgLossR). Default 0.'}, 'riskMode': {'enum': ['percent-of-balance', 'percent-of-initial', 'fixed-amount'], 'type': 'string', 'description': "How riskValue is interpreted. 'percent-of-balance' (default): risk compounds with the current balance. 'percent-of-initial': constant currency risk derived from the initial account size - how most prop traders size, since loss limits are fixed in currency. 'fixed-amount': explicit currency risked per 1R."}, 'attemptCap': {'type': 'integer', 'maximum': 1000, 'minimum': 1, 'description': 'Maximum challenge attempts per path before that path gives up. Default 25. Journey statistics (expected attempts/cost, P(funded)) are censored at this cap.'}, 'challengeId': {'type': 'string', 'minLength': 1, 'description': 'Directory challenge id; discover with propfirms_list_simulatable. Must be paired with firmId. Mutually exclusive with `spec`.'}, 'tradesPerDay': {'type': 'number', 'description': 'Average trades per simulated trading day. More trades per day means more ways to hit the daily loss limit within a single day.', 'exclusiveMinimum': 0}, 'simulateFunded': {'type': 'boolean', 'description': 'Whether to simulate the funded stage (payouts, blowup risk) after passing. Default true - EV is only meaningful with it on; set false to study the evaluation alone.'}, 'fundedHorizonDays': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Funded-stage horizon in trading days for the payout/EV simulation. Default 90 (about 4 calendar months). EV scales with this choice - state it when reporting EV.'}, 'tradesPerDayModel': {'enum': ['fixed', 'poisson'], 'type': 'string', 'description': "'fixed' (default): the same count every day. 'poisson': daily count drawn Poisson(tradesPerDay); days can then have zero trades, which do not count as trading days."}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['firmId', 'context'], 'properties': {'firmId': {'type': 'string', 'minLength': 1, 'description': "Directory firm id (propfirmId, e.g. 'ftmo') or firm name â\x80\x94 from propfirms_list_simulatable."}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'challengeId': {'type': 'string', 'minLength': 1, 'description': 'One challenge id. Omit to compute every simulatable challenge the firm has.'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'sort': {'enum': ['name', 'yearFounded', 'reviewsTrustPilotScore', 'reviewsTrustPilotCount'], 'type': 'string', 'description': 'Sort key (default name)'}, 'text': {'type': 'string', 'description': "Case-insensitive search over firm name and slug, e.g. 'ftmo'"}, 'steps': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'Exact evaluation step count (1 = instant/funded, 2 = two-step, â\x80¦)'}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'include': {'type': 'array', 'items': {'enum': ['challenges', 'offers', 'overview'], 'type': 'string'}, 'description': 'Extra payloads to nest on each firm (only children matching the filters are returned)'}, 'offerId': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Public offer ids'}, 'currency': {'type': 'array', 'items': {'type': 'string'}, 'description': "Account currencies, e.g. ['usd', 'eur']"}, 'interval': {'type': 'array', 'items': {'type': 'string'}, 'description': "Challenge fee intervals, e.g. 'one-time', 'monthly'"}, 'priceMax': {'type': 'number', 'description': 'Maximum challenge fee (inclusive)'}, 'priceMin': {'type': 'number', 'description': 'Minimum challenge fee (inclusive)'}, 'stepsMax': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'Maximum step count (ignored when steps is set)'}, 'stepsMin': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'Minimum step count (ignored when steps is set)'}, 'direction': {'enum': ['asc', 'desc'], 'type': 'string', 'description': 'Sort direction; each sort key has a sensible default'}, 'offerText': {'type': 'string', 'description': 'Case-insensitive search over promo code and offer descriptions'}, 'pageIndex': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': '0-based page index (default 0)'}, 'promoCode': {'type': 'string', 'description': 'Case-insensitive substring of the promo code'}, 'isFeatured': {'type': 'boolean', 'description': 'Only featured offers when true'}, 'maxLossMax': {'type': 'number', 'description': 'Upper bound on the overall-loss limit magnitude'}, 'propfirmId': {'type': 'array', 'items': {'type': 'string'}, 'description': "Public firm slugs, e.g. ['ftmo']"}, 'autoTrading': {'type': 'boolean', 'description': 'Whether automated trading (EAs/bots) is allowed'}, 'availableIn': {'type': 'array', 'items': {'type': 'string'}, 'description': "Country names the firm must NOT restrict, e.g. ['United States']"}, 'challengeId': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Public challenge ids'}, 'copyTrading': {'type': 'boolean', 'description': 'Whether copy trading is allowed'}, 'countryIso2': {'type': 'array', 'items': {'type': 'string'}, 'description': "ISO-2 headquarters countries, e.g. ['GB', 'US']"}, 'discountMax': {'type': 'number', 'description': 'Maximum discount value'}, 'discountMin': {'type': 'number', 'description': 'Minimum discount value'}, 'maxLossMode': {'type': 'array', 'items': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized'], 'type': 'string'}, 'description': 'Drawdown modes; challenges without a captured mode never match'}, 'newsTrading': {'type': 'boolean', 'description': 'Whether news trading is allowed'}, 'dailyLossMax': {'type': 'number', 'description': 'Upper bound on the daily-loss limit magnitude (smaller = stricter)'}, 'pageQuantity': {'type': 'integer', 'maximum': 100, 'minimum': 1, 'description': 'Page size (default 50, max 100)'}, 'productTypes': {'type': 'array', 'items': {'type': 'string'}, 'description': "Product types the firm must offer at least one of, e.g. 'CFD', 'Futures'"}, 'challengeName': {'type': 'string', 'description': 'Case-insensitive substring of the challenge name'}, 'payoutMethods': {'type': 'array', 'items': {'type': 'string'}, 'description': "Payout methods the firm must offer at least one of, e.g. 'Bank Transfer', 'Crypto'"}, 'accountSizeMax': {'type': 'number', 'description': 'Maximum account size (inclusive)'}, 'accountSizeMin': {'type': 'number', 'description': 'Minimum account size (inclusive)'}, 'hasActiveOffer': {'type': 'boolean', 'description': 'When true, the firm must currently have a live (active, unexpired) offer'}, 'includeExpired': {'type': 'boolean', 'description': 'When true, ended offers are not hidden (default false)'}, 'maxLeverageMin': {'type': 'number', 'description': 'Minimum max leverage'}, 'maxYearFounded': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'Inclusive maximum year founded'}, 'minYearFounded': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'Inclusive minimum year founded'}, 'paymentMethods': {'type': 'array', 'items': {'type': 'string'}, 'description': "Payment methods the firm must accept at least one of, e.g. 'Crypto', 'PayPal'"}, 'profitSplitMin': {'type': 'number', 'description': 'Minimum trader profit-split percent'}, 'weekendHolding': {'type': 'boolean', 'description': 'Whether holding over the weekend is allowed'}, 'includeInactive': {'type': 'boolean', 'description': 'When true, inactive offers are not hidden (default false)'}, 'isFeeRefundable': {'type': 'boolean', 'description': 'Whether the challenge fee is refundable'}, 'overnightHolding': {'type': 'boolean', 'description': 'Whether holding overnight is allowed'}, 'stoplossRequired': {'type': 'boolean', 'description': 'Whether a stop loss is required'}, 'tradingPlatforms': {'type': 'array', 'items': {'type': 'string'}, 'description': "Platforms the firm must offer at least one of, e.g. 'MT5', 'cTrader', 'TradingView'"}, 'discountIsPercent': {'type': 'boolean', 'description': 'true for percent discounts, false for absolute amounts'}, 'minTradingDaysMax': {'type': 'number', 'description': 'Maximum required minimum trading days (finds less-strict challenges)'}, 'tradedMarketTypes': {'type': 'array', 'items': {'type': 'string'}, 'description': "Markets the firm must offer at least one of, e.g. 'forex', 'indices', 'commodities'"}, 'isPreferredPartner': {'type': 'boolean', 'description': 'Only LuxAlgo preferred-partner firms when true'}, 'minTrustPilotCount': {'type': 'number', 'description': 'Minimum Trustpilot review count'}, 'minTrustPilotScore': {'type': 'number', 'description': 'Minimum Trustpilot score'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'sort': {'enum': ['challengeName', 'accountSize', 'price', 'steps', 'profitSplitPercent'], 'type': 'string', 'description': 'Sort key (default accountSize descending)'}, 'text': {'type': 'string', 'description': 'Case-insensitive search over challenge name and firm name/slug'}, 'steps': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'Exact evaluation step count (1 = instant/funded, 2 = two-step, â\x80¦)'}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'include': {'type': 'array', 'items': {'enum': ['offers'], 'type': 'string'}, 'description': "Pass ['offers'] to attach live offers that apply to each challenge"}, 'interval': {'type': 'array', 'items': {'type': 'string'}, 'description': "Challenge fee intervals, e.g. 'one-time', 'monthly'"}, 'priceMax': {'type': 'number', 'description': 'Maximum challenge fee (inclusive)'}, 'priceMin': {'type': 'number', 'description': 'Minimum challenge fee (inclusive)'}, 'stepsMax': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'Maximum step count (ignored when steps is set)'}, 'stepsMin': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991, 'description': 'Minimum step count (ignored when steps is set)'}, 'direction': {'enum': ['asc', 'desc'], 'type': 'string', 'description': 'Sort direction; each sort key has a sensible default'}, 'pageIndex': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': '0-based page index (default 0)'}, 'maxLossMax': {'type': 'number', 'description': 'Upper bound on the overall-loss limit magnitude'}, 'propfirmId': {'type': 'array', 'items': {'type': 'string'}, 'description': "Public firm slugs, e.g. ['ftmo']"}, 'autoTrading': {'type': 'boolean', 'description': 'Whether automated trading (EAs/bots) is allowed'}, 'availableIn': {'type': 'array', 'items': {'type': 'string'}, 'description': "Country names the firm must NOT restrict, e.g. ['United States']"}, 'challengeId': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Public challenge ids'}, 'copyTrading': {'type': 'boolean', 'description': 'Whether copy trading is allowed'}, 'maxLossMode': {'type': 'array', 'items': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized'], 'type': 'string'}, 'description': 'Drawdown modes; challenges without a captured mode never match'}, 'newsTrading': {'type': 'boolean', 'description': 'Whether news trading is allowed'}, 'dailyLossMax': {'type': 'number', 'description': 'Upper bound on the daily-loss limit magnitude (smaller = stricter)'}, 'pageQuantity': {'type': 'integer', 'maximum': 100, 'minimum': 1, 'description': 'Page size (default 50, max 100)'}, 'productTypes': {'type': 'array', 'items': {'type': 'string'}, 'description': "Product types the firm must offer at least one of, e.g. 'CFD', 'Futures'"}, 'challengeName': {'type': 'string', 'description': 'Case-insensitive substring of the challenge name'}, 'accountSizeMax': {'type': 'number', 'description': 'Maximum account size (inclusive)'}, 'accountSizeMin': {'type': 'number', 'description': 'Minimum account size (inclusive)'}, 'maxLeverageMin': {'type': 'number', 'description': 'Minimum max leverage'}, 'profitSplitMin': {'type': 'number', 'description': 'Minimum trader profit-split percent'}, 'weekendHolding': {'type': 'boolean', 'description': 'Whether holding over the weekend is allowed'}, 'isFeeRefundable': {'type': 'boolean', 'description': 'Whether the challenge fee is refundable'}, 'overnightHolding': {'type': 'boolean', 'description': 'Whether holding overnight is allowed'}, 'stoplossRequired': {'type': 'boolean', 'description': 'Whether a stop loss is required'}, 'tradingPlatforms': {'type': 'array', 'items': {'type': 'string'}, 'description': "Platforms the firm must offer at least one of, e.g. 'MT5', 'cTrader', 'TradingView'"}, 'minTradingDaysMax': {'type': 'number', 'description': 'Maximum required minimum trading days (finds less-strict challenges)'}, 'tradedMarketTypes': {'type': 'array', 'items': {'type': 'string'}, 'description': "Markets the firm must offer at least one of, e.g. 'forex', 'indices', 'commodities'"}, 'isPreferredPartner': {'type': 'boolean', 'description': 'Only LuxAlgo preferred-partner firms when true'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'sort': {'enum': ['discountValue', 'endsAt', 'promoCode'], 'type': 'string', 'description': 'Sort key (default: featured first, then discount)'}, 'text': {'type': 'string', 'description': 'Case-insensitive search over promo code, descriptions, and firm name/slug'}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'offerId': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Public offer ids'}, 'isActive': {'type': 'boolean', 'description': 'Defaults to live offers only; pass false to look at inactive offers'}, 'direction': {'enum': ['asc', 'desc'], 'type': 'string', 'description': 'Sort direction; each sort key has a sensible default'}, 'offerText': {'type': 'string', 'description': 'Case-insensitive search over promo code and offer descriptions'}, 'pageIndex': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': '0-based page index (default 0)'}, 'promoCode': {'type': 'string', 'description': 'Case-insensitive substring of the promo code'}, 'isFeatured': {'type': 'boolean', 'description': 'Only featured offers when true'}, 'propfirmId': {'type': 'array', 'items': {'type': 'string'}, 'description': "Public firm slugs, e.g. ['ftmo']"}, 'challengeId': {'type': 'array', 'items': {'type': 'string'}, 'description': "Public challenge ids; an offer matches when it applies to at least one (all-challenges offers match that firm's challenges)"}, 'discountMax': {'type': 'number', 'description': 'Maximum discount value'}, 'discountMin': {'type': 'number', 'description': 'Minimum discount value'}, 'pageQuantity': {'type': 'integer', 'maximum': 100, 'minimum': 1, 'description': 'Page size (default 50, max 100)'}, 'includeExpired': {'type': 'boolean', 'description': 'When true, ended offers are not hidden (default false)'}, 'includeInactive': {'type': 'boolean', 'description': 'When true, inactive offers are not hidden (default false)'}, 'discountIsPercent': {'type': 'boolean', 'description': 'true for percent discounts, false for absolute amounts'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['winRate', 'avgWinR', 'tradesPerDay', 'riskValue', 'context'], 'properties': {'seed': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991}, {'type': 'string'}], 'description': 'RNG seed (integer or string). Default 42. Same inputs + seed reproduce byte-identical results - include the seed when reporting so users can reproduce the numbers.'}, 'spec': {'type': 'object', 'required': ['challengeId', 'name', 'accountSize', 'steps', 'dailyLoss', 'maxLoss', 'fees', 'funded'], 'properties': {'fees': {'type': 'object', 'required': ['price'], 'properties': {'price': {'type': 'number', 'minimum': 0, 'description': "Challenge price in account currency. Under 'monthly' billing: price per month."}, 'billing': {'enum': ['one-time', 'monthly'], 'type': 'string', 'description': "'one-time' (default): the price buys one attempt; failed attempts are re-bought or reset. 'monthly': recurring subscription while evaluating (common for futures firms)."}, 'resetFee': {'anyOf': [{'type': 'number', 'minimum': 0}, {'type': 'null'}], 'description': 'Discounted fee to reset a failed attempt. null (default) = no reset offer: a failed one-time attempt costs full price again; a failed monthly attempt rides on the subscription.'}, 'activationFee': {'type': 'number', 'minimum': 0, 'description': 'One-time fee charged when the funded account is activated. Default 0.'}, 'refundableOnPass': {'type': 'boolean', 'description': 'Whether the one-time challenge fee is refunded once funded (credited back in cost/EV). Default false.'}}, 'description': 'Fees - everything that goes into expected total cost.', 'additionalProperties': {}}, 'name': {'type': 'string', 'minLength': 1, 'description': "Display name, e.g. '100K 2-Step'."}, 'steps': {'type': 'array', 'items': {'type': 'object', 'properties': {'maxDays': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'exclusiveMinimum': 0}, {'type': 'null'}], 'description': 'Trading-day limit for the step; null (the default) = unlimited time.'}, 'maxLoss': {'type': 'object', 'required': ['mode'], 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Max loss in PERCENT UNITS of the initial account size (10 = 10%). Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'mode': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized', 'trailing-locks-at-initial'], 'type': 'string', 'description': "How the max-loss floor behaves - the single most consequential rule difference between firms. 'static-initial': floor fixed at initial balance minus the limit; never moves (classic CFD two-step). 'trailing-realized-eod': floor ratchets up with end-of-day balance highs; intraday highs do not move it. 'trailing-intraday-unrealized': floor trails the peak unrealized equity intraday and never stops trailing (futures-style; the most-miscalculated rule in the industry: it cuts pass probability dramatically). 'trailing-locks-at-initial': trails intraday peak equity until the floor reaches the initial balance, then freezes (common futures variant). Locking is also composable: locksAtInitial adds the same lock to an EOD trail, and lockOffsetAmount shifts the lock level to initial balance + that amount (e.g. 100 models 'stops trailing $100 above the start')."}, 'amount': {'type': 'number', 'description': 'Max loss as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'locksAtInitial': {'type': 'boolean', 'description': "For trailing modes: once the trailing floor climbs up to the initial balance (plus lockOffsetAmount), it locks there and stops trailing. Default false. 'trailing-locks-at-initial' locks by definition; set this to add the same lock to 'trailing-realized-eod' (e.g. an EOD trail that stops at the starting balance)."}, 'lockOffsetAmount': {'type': 'number', 'minimum': 0, 'description': "Currency offset of the lock level: the floor locks at initial balance + this amount, modeling rules like 'the trailing threshold stops $100 above the start'. Default 0. Only meaningful when the rule locks (mode 'trailing-locks-at-initial' or locksAtInitial=true)."}}, 'description': 'Per-step override of the challenge-level max loss rule. Omit to inherit.', 'additionalProperties': {}}, 'dailyLoss': {'anyOf': [{'type': 'object', 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Daily loss limit in PERCENT UNITS (5 = 5%); what it is a percent OF is set by limitBasis. Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'basis': {'enum': ['prior-day-balance', 'prior-day-equity'], 'type': 'string', 'description': "Anchor today's loss is measured from: prior day's closing balance or closing equity (they differ only with overnight positions). Default 'prior-day-balance'."}, 'amount': {'type': 'number', 'description': 'Daily loss limit as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'evaluation': {'enum': ['intraday', 'end-of-day'], 'type': 'string', 'description': "'intraday': fails the moment equity touches the daily floor. 'end-of-day': only the close is checked. Default 'intraday'."}, 'limitBasis': {'enum': ['initial-balance', 'anchor'], 'type': 'string', 'description': "What a percentage limit is a percent OF. 'initial-balance': a fixed currency allowance (always e.g. 5% of the starting account). 'anchor': recomputed daily from the day's anchor. Default 'initial-balance'."}, 'includesOpenPnl': {'type': 'boolean', 'description': 'Whether floating (unrealized) P&L counts toward the daily loss, i.e. breach can happen intra-position. Default true.'}}, 'description': 'Daily loss rule: the daily floor is anchor minus limit, reset at each trading-day boundary. Exactly one of pct/amount must be set.', 'additionalProperties': {}}, {'type': 'null'}], 'description': 'Per-step override of the challenge-level daily loss rule. Omit to inherit; null = no daily loss rule in this step.'}, 'consistency': {'anyOf': [{'type': 'object', 'required': ['maxBestDayProfitPct'], 'properties': {'maxBestDayProfitPct': {'type': 'number', 'maximum': 100, 'description': "Maximum share of the step's total profit the best single day may contribute, in PERCENT UNITS (40 = the best day may be at most 40% of total profit).", 'exclusiveMinimum': 0}}, 'additionalProperties': {}}, {'type': 'null'}], 'description': "Consistency rule - SIMULATED (engine v1), not just flagged: one outsized day effectively raises the target (total profit must reach best day / pct), and the simulated trader keeps trading - rationally stopping days early when that helps - until the best-day share complies (see flag 'consistency-stop-rule'). null or omitted = no consistency rule."}, 'minTradingDays': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Minimum days with at least one trade before the step can be passed. Default 0.'}, 'profitTargetPct': {'type': 'number', 'description': 'Profit target in PERCENT UNITS of the initial account size (8 = 8%). Exactly one of profitTargetPct/profitTargetAmount.', 'exclusiveMinimum': 0}, 'profitTargetAmount': {'type': 'number', 'description': 'Profit target as a fixed currency amount (alternative to profitTargetPct).', 'exclusiveMinimum': 0}}, 'description': 'One evaluation step. Each step starts on a fresh account at the initial balance.', 'additionalProperties': {}}, 'minItems': 1, 'description': 'Evaluation steps in order. Passing the last step means funded.'}, 'funded': {'type': 'object', 'required': ['profitSplitPct', 'payoutFrequency'], 'properties': {'notes': {'type': 'string', 'description': 'Free-text funded-stage details that are not simulated.'}, 'maxLoss': {'type': 'object', 'required': ['mode'], 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Max loss in PERCENT UNITS of the initial account size (10 = 10%). Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'mode': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized', 'trailing-locks-at-initial'], 'type': 'string', 'description': "How the max-loss floor behaves - the single most consequential rule difference between firms. 'static-initial': floor fixed at initial balance minus the limit; never moves (classic CFD two-step). 'trailing-realized-eod': floor ratchets up with end-of-day balance highs; intraday highs do not move it. 'trailing-intraday-unrealized': floor trails the peak unrealized equity intraday and never stops trailing (futures-style; the most-miscalculated rule in the industry: it cuts pass probability dramatically). 'trailing-locks-at-initial': trails intraday peak equity until the floor reaches the initial balance, then freezes (common futures variant). Locking is also composable: locksAtInitial adds the same lock to an EOD trail, and lockOffsetAmount shifts the lock level to initial balance + that amount (e.g. 100 models 'stops trailing $100 above the start')."}, 'amount': {'type': 'number', 'description': 'Max loss as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'locksAtInitial': {'type': 'boolean', 'description': "For trailing modes: once the trailing floor climbs up to the initial balance (plus lockOffsetAmount), it locks there and stops trailing. Default false. 'trailing-locks-at-initial' locks by definition; set this to add the same lock to 'trailing-realized-eod' (e.g. an EOD trail that stops at the starting balance)."}, 'lockOffsetAmount': {'type': 'number', 'minimum': 0, 'description': "Currency offset of the lock level: the floor locks at initial balance + this amount, modeling rules like 'the trailing threshold stops $100 above the start'. Default 0. Only meaningful when the rule locks (mode 'trailing-locks-at-initial' or locksAtInitial=true)."}}, 'description': 'Funded-account override of the max loss rule. Omit to inherit.', 'additionalProperties': {}}, 'dailyLoss': {'anyOf': [{'type': 'object', 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Daily loss limit in PERCENT UNITS (5 = 5%); what it is a percent OF is set by limitBasis. Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'basis': {'enum': ['prior-day-balance', 'prior-day-equity'], 'type': 'string', 'description': "Anchor today's loss is measured from: prior day's closing balance or closing equity (they differ only with overnight positions). Default 'prior-day-balance'."}, 'amount': {'type': 'number', 'description': 'Daily loss limit as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'evaluation': {'enum': ['intraday', 'end-of-day'], 'type': 'string', 'description': "'intraday': fails the moment equity touches the daily floor. 'end-of-day': only the close is checked. Default 'intraday'."}, 'limitBasis': {'enum': ['initial-balance', 'anchor'], 'type': 'string', 'description': "What a percentage limit is a percent OF. 'initial-balance': a fixed currency allowance (always e.g. 5% of the starting account). 'anchor': recomputed daily from the day's anchor. Default 'initial-balance'."}, 'includesOpenPnl': {'type': 'boolean', 'description': 'Whether floating (unrealized) P&L counts toward the daily loss, i.e. breach can happen intra-position. Default true.'}}, 'description': 'Daily loss rule: the daily floor is anchor minus limit, reset at each trading-day boundary. Exactly one of pct/amount must be set.', 'additionalProperties': {}}, {'type': 'null'}], 'description': 'Funded-account override of the daily loss rule. Omit to inherit; null = none.'}, 'payoutRules': {'type': 'object', 'properties': {'bufferAmount': {'type': 'number', 'minimum': 0, 'description': 'Profit buffer that must remain in the account; only profit above it is withdrawable. Default 0.'}, 'minWinningDays': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Winning days required in a payout window before a payout can be requested. Default 0.'}, 'maxPayoutAmount': {'type': 'number', 'description': 'Absolute currency cap per payout request. Omit for no fixed cap.', 'exclusiveMinimum': 0}, 'winningDayMinProfit': {'type': 'number', 'minimum': 0, 'description': 'Minimum profit for a day to count as a winning day. Default 0 (any positive day).'}, 'maxPayoutPctOfProfit': {'type': 'number', 'maximum': 100, 'description': 'Cap on each payout in PERCENT UNITS of accrued profit (50 = at most half the profit per request). Omit for no percentage cap.', 'exclusiveMinimum': 0}, 'consistencyMaxBestDayPct': {'type': 'number', 'maximum': 100, 'description': "Funded consistency gate in PERCENT UNITS: the best day may contribute at most this share of the payout window's profit. Evaluated per window (see flag 'funded-consistency-window-approximated').", 'exclusiveMinimum': 0}}, 'description': "Payout gating - SIMULATED (engine v1), not just flagged: a payout happens only when these conditions are met, and on each eligible payout day the trader withdraws the maximum the rules allow (profit above the buffer, under the caps, never below the loss floor); balances and loss floors carry across payouts (see flag 'funded-withdrawal-model'). Omit for ungated payouts.", 'additionalProperties': {}}, 'profitSplitPct': {'type': 'number', 'maximum': 100, 'minimum': 0, 'description': "Trader's share of funded profits in PERCENT UNITS (80 = 80%)."}, 'payoutFrequency': {'enum': ['weekly', 'biweekly', 'monthly', 'on-demand'], 'type': 'string', 'description': 'How often funded profits can be withdrawn.'}, 'firstPayoutMinDays': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Minimum days on the funded account before the first payout. Default 0.'}}, 'description': 'Funded-stage terms used for the payout/EV simulation.', 'additionalProperties': {}}, 'maxLoss': {'type': 'object', 'required': ['mode'], 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Max loss in PERCENT UNITS of the initial account size (10 = 10%). Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'mode': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized', 'trailing-locks-at-initial'], 'type': 'string', 'description': "How the max-loss floor behaves - the single most consequential rule difference between firms. 'static-initial': floor fixed at initial balance minus the limit; never moves (classic CFD two-step). 'trailing-realized-eod': floor ratchets up with end-of-day balance highs; intraday highs do not move it. 'trailing-intraday-unrealized': floor trails the peak unrealized equity intraday and never stops trailing (futures-style; the most-miscalculated rule in the industry: it cuts pass probability dramatically). 'trailing-locks-at-initial': trails intraday peak equity until the floor reaches the initial balance, then freezes (common futures variant). Locking is also composable: locksAtInitial adds the same lock to an EOD trail, and lockOffsetAmount shifts the lock level to initial balance + that amount (e.g. 100 models 'stops trailing $100 above the start')."}, 'amount': {'type': 'number', 'description': 'Max loss as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'locksAtInitial': {'type': 'boolean', 'description': "For trailing modes: once the trailing floor climbs up to the initial balance (plus lockOffsetAmount), it locks there and stops trailing. Default false. 'trailing-locks-at-initial' locks by definition; set this to add the same lock to 'trailing-realized-eod' (e.g. an EOD trail that stops at the starting balance)."}, 'lockOffsetAmount': {'type': 'number', 'minimum': 0, 'description': "Currency offset of the lock level: the floor locks at initial balance + this amount, modeling rules like 'the trailing threshold stops $100 above the start'. Default 0. Only meaningful when the rule locks (mode 'trailing-locks-at-initial' or locksAtInitial=true)."}}, 'description': 'Challenge-level max loss rule applied to every step unless a step overrides it. Required.', 'additionalProperties': {}}, 'sources': {'type': 'array', 'items': {'type': 'object', 'required': ['url', 'lastVerified'], 'properties': {'url': {'type': 'string', 'description': 'Public page documenting the rule.'}, 'note': {'type': 'string'}, 'lastVerified': {'type': 'string', 'description': 'ISO date the rules were last checked against that page.'}}, 'additionalProperties': {}}, 'description': 'Public citations. Optional for inline specs; dataset entries always carry them.'}, 'currency': {'type': 'string', 'description': 'ISO currency code all amounts are denominated in. Default USD.'}, 'dailyLoss': {'anyOf': [{'type': 'object', 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Daily loss limit in PERCENT UNITS (5 = 5%); what it is a percent OF is set by limitBasis. Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'basis': {'enum': ['prior-day-balance', 'prior-day-equity'], 'type': 'string', 'description': "Anchor today's loss is measured from: prior day's closing balance or closing equity (they differ only with overnight positions). Default 'prior-day-balance'."}, 'amount': {'type': 'number', 'description': 'Daily loss limit as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'evaluation': {'enum': ['intraday', 'end-of-day'], 'type': 'string', 'description': "'intraday': fails the moment equity touches the daily floor. 'end-of-day': only the close is checked. Default 'intraday'."}, 'limitBasis': {'enum': ['initial-balance', 'anchor'], 'type': 'string', 'description': "What a percentage limit is a percent OF. 'initial-balance': a fixed currency allowance (always e.g. 5% of the starting account). 'anchor': recomputed daily from the day's anchor. Default 'initial-balance'."}, 'includesOpenPnl': {'type': 'boolean', 'description': 'Whether floating (unrealized) P&L counts toward the daily loss, i.e. breach can happen intra-position. Default true.'}}, 'description': 'Daily loss rule: the daily floor is anchor minus limit, reset at each trading-day boundary. Exactly one of pct/amount must be set.', 'additionalProperties': {}}, {'type': 'null'}], 'description': 'Challenge-level daily loss rule applied to every step unless a step overrides it. null = no daily loss rule. This field is required (pass null explicitly for none).'}, 'accountSize': {'type': 'number', 'description': 'Initial account balance in account currency.', 'exclusiveMinimum': 0}, 'challengeId': {'type': 'string', 'minLength': 1, 'description': "Stable kebab-case id for this ruleset, e.g. '100k-2step'."}, 'constraints': {'type': 'object', 'description': 'Informational trading constraints (maxLeverage, newsTrading, weekendHolding, ...). Recorded and flagged, never simulated.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'productType': {'enum': ['futures', 'cfd', 'equities'], 'type': 'string', 'description': "Instrument class the challenge is traded on: 'futures', 'cfd' (forex/CFD), or 'equities'."}, 'flagsNotSimulated': {'type': 'array', 'items': {'type': 'string'}, 'description': "Honesty channel: ids of rules this entry has that the engine does not simulate (e.g. 'scaling-plan', 'soft-daily-lockout'). Surfaced in every result's assumption flags. Consistency rules and payout gating do NOT belong here - the engine simulates them."}}, 'description': "Inline challenge ruleset, for challenges not in the directory or for what-if rule edits. Mutually exclusive with firmId/challengeId. Identify the challenge EITHER by directory reference (firmId + challengeId, discovered via propfirms_list_simulatable; firmId accepts the directory id or the firm's name) OR by a full inline `spec` object - the exact shape propfirms_challenge_rules returns, so you can fetch a directory entry, change one rule, and re-simulate to model rule variations. Provide exactly one of the two forms; providing both or neither is an error. Directory references need network access; inline specs are fully offline.", 'additionalProperties': {}}, 'paths': {'type': 'integer', 'maximum': 100000, 'minimum': 100, 'description': 'Monte Carlo paths (independent simulated trader journeys). Default 10,000 (well under a second); capped at 100,000 per tool call. Confidence intervals shrink roughly with the square root of paths.'}, 'firmId': {'type': 'string', 'minLength': 1, 'description': "Directory firm id or firm name (e.g. 'ftmo' or 'FTMO'); discover with propfirms_list_simulatable. Must be paired with challengeId. Mutually exclusive with `spec`."}, 'avgWinR': {'type': 'number', 'description': 'Average winning trade in R-multiples, i.e. multiples of the amount risked per trade (1.5 = winners average 1.5x the risk).', 'exclusiveMinimum': 0}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'winRate': {'type': 'number', 'maximum': 1, 'minimum': 0, 'description': 'Probability a trade is a winner, as a FRACTION in [0, 1] (0.55 = 55% winners) - NOT percent units. The most impactful input: traders routinely overestimate it by a few points, which can flip EV negative, so prefer measured stats over self-reported ones.'}, 'winStdR': {'type': 'number', 'minimum': 0, 'description': 'Standard deviation of winner sizes in R (0 = every winner is exactly avgWinR). Default 0. Adding spread makes streak damage more realistic.'}, 'avgLossR': {'type': 'number', 'description': 'Average losing trade in R, as a POSITIVE number. Default 1 (losers lose exactly the risked amount, i.e. stops are honored). Raise above 1 to model slippage or blown stops.', 'exclusiveMinimum': 0}, 'lossStdR': {'type': 'number', 'minimum': 0, 'description': 'Standard deviation of loser sizes in R (0 = every loser is exactly avgLossR). Default 0.'}, 'riskMode': {'enum': ['percent-of-balance', 'percent-of-initial', 'fixed-amount'], 'type': 'string', 'description': "How riskValue is interpreted. 'percent-of-balance' (default): risk compounds with the current balance. 'percent-of-initial': constant currency risk derived from the initial account size - how most prop traders size, since loss limits are fixed in currency. 'fixed-amount': explicit currency risked per 1R."}, 'riskValue': {'type': 'number', 'description': "Risk per trade - the value of 1R. PERCENT UNITS for percent modes (0.5 = 0.5% risked per trade; a typical prop range is 0.25-2), or a currency amount for 'fixed-amount'. NOT a fraction.", 'exclusiveMinimum': 0}, 'attemptCap': {'type': 'integer', 'maximum': 1000, 'minimum': 1, 'description': 'Maximum challenge attempts per path before that path gives up. Default 25. Journey statistics (expected attempts/cost, P(funded)) are censored at this cap.'}, 'challengeId': {'type': 'string', 'minLength': 1, 'description': 'Directory challenge id; discover with propfirms_list_simulatable. Must be paired with firmId. Mutually exclusive with `spec`.'}, 'tradesPerDay': {'type': 'number', 'description': 'Average trades per simulated trading day. More trades per day means more ways to hit the daily loss limit within a single day.', 'exclusiveMinimum': 0}, 'simulateFunded': {'type': 'boolean', 'description': 'Whether to simulate the funded stage (payouts, blowup risk) after passing. Default true - EV is only meaningful with it on; set false to study the evaluation alone.'}, 'fundedHorizonDays': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Funded-stage horizon in trading days for the payout/EV simulation. Default 90 (about 4 calendar months). EV scales with this choice - state it when reporting EV.'}, 'includeHistograms': {'type': 'boolean', 'description': 'Include histogram arrays (attempts, cost, net, drawdown) in the result. Default FALSE for this tool to keep responses compact; summary quantiles (p05...p95) are always included.'}, 'tradesPerDayModel': {'enum': ['fixed', 'poisson'], 'type': 'string', 'description': "'fixed' (default): the same count every day. 'poisson': daily count drawn Poisson(tradesPerDay); days can then have zero trades, which do not count as trading days."}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['riskValue', 'context'], 'properties': {'seed': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991}, {'type': 'string'}], 'description': 'RNG seed (integer or string). Default 42. Same inputs + seed reproduce byte-identical results - include the seed when reporting so users can reproduce the numbers.'}, 'spec': {'type': 'object', 'required': ['challengeId', 'name', 'accountSize', 'steps', 'dailyLoss', 'maxLoss', 'fees', 'funded'], 'properties': {'fees': {'type': 'object', 'required': ['price'], 'properties': {'price': {'type': 'number', 'minimum': 0, 'description': "Challenge price in account currency. Under 'monthly' billing: price per month."}, 'billing': {'enum': ['one-time', 'monthly'], 'type': 'string', 'description': "'one-time' (default): the price buys one attempt; failed attempts are re-bought or reset. 'monthly': recurring subscription while evaluating (common for futures firms)."}, 'resetFee': {'anyOf': [{'type': 'number', 'minimum': 0}, {'type': 'null'}], 'description': 'Discounted fee to reset a failed attempt. null (default) = no reset offer: a failed one-time attempt costs full price again; a failed monthly attempt rides on the subscription.'}, 'activationFee': {'type': 'number', 'minimum': 0, 'description': 'One-time fee charged when the funded account is activated. Default 0.'}, 'refundableOnPass': {'type': 'boolean', 'description': 'Whether the one-time challenge fee is refunded once funded (credited back in cost/EV). Default false.'}}, 'description': 'Fees - everything that goes into expected total cost.', 'additionalProperties': {}}, 'name': {'type': 'string', 'minLength': 1, 'description': "Display name, e.g. '100K 2-Step'."}, 'steps': {'type': 'array', 'items': {'type': 'object', 'properties': {'maxDays': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'exclusiveMinimum': 0}, {'type': 'null'}], 'description': 'Trading-day limit for the step; null (the default) = unlimited time.'}, 'maxLoss': {'type': 'object', 'required': ['mode'], 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Max loss in PERCENT UNITS of the initial account size (10 = 10%). Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'mode': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized', 'trailing-locks-at-initial'], 'type': 'string', 'description': "How the max-loss floor behaves - the single most consequential rule difference between firms. 'static-initial': floor fixed at initial balance minus the limit; never moves (classic CFD two-step). 'trailing-realized-eod': floor ratchets up with end-of-day balance highs; intraday highs do not move it. 'trailing-intraday-unrealized': floor trails the peak unrealized equity intraday and never stops trailing (futures-style; the most-miscalculated rule in the industry: it cuts pass probability dramatically). 'trailing-locks-at-initial': trails intraday peak equity until the floor reaches the initial balance, then freezes (common futures variant). Locking is also composable: locksAtInitial adds the same lock to an EOD trail, and lockOffsetAmount shifts the lock level to initial balance + that amount (e.g. 100 models 'stops trailing $100 above the start')."}, 'amount': {'type': 'number', 'description': 'Max loss as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'locksAtInitial': {'type': 'boolean', 'description': "For trailing modes: once the trailing floor climbs up to the initial balance (plus lockOffsetAmount), it locks there and stops trailing. Default false. 'trailing-locks-at-initial' locks by definition; set this to add the same lock to 'trailing-realized-eod' (e.g. an EOD trail that stops at the starting balance)."}, 'lockOffsetAmount': {'type': 'number', 'minimum': 0, 'description': "Currency offset of the lock level: the floor locks at initial balance + this amount, modeling rules like 'the trailing threshold stops $100 above the start'. Default 0. Only meaningful when the rule locks (mode 'trailing-locks-at-initial' or locksAtInitial=true)."}}, 'description': 'Per-step override of the challenge-level max loss rule. Omit to inherit.', 'additionalProperties': {}}, 'dailyLoss': {'anyOf': [{'type': 'object', 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Daily loss limit in PERCENT UNITS (5 = 5%); what it is a percent OF is set by limitBasis. Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'basis': {'enum': ['prior-day-balance', 'prior-day-equity'], 'type': 'string', 'description': "Anchor today's loss is measured from: prior day's closing balance or closing equity (they differ only with overnight positions). Default 'prior-day-balance'."}, 'amount': {'type': 'number', 'description': 'Daily loss limit as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'evaluation': {'enum': ['intraday', 'end-of-day'], 'type': 'string', 'description': "'intraday': fails the moment equity touches the daily floor. 'end-of-day': only the close is checked. Default 'intraday'."}, 'limitBasis': {'enum': ['initial-balance', 'anchor'], 'type': 'string', 'description': "What a percentage limit is a percent OF. 'initial-balance': a fixed currency allowance (always e.g. 5% of the starting account). 'anchor': recomputed daily from the day's anchor. Default 'initial-balance'."}, 'includesOpenPnl': {'type': 'boolean', 'description': 'Whether floating (unrealized) P&L counts toward the daily loss, i.e. breach can happen intra-position. Default true.'}}, 'description': 'Daily loss rule: the daily floor is anchor minus limit, reset at each trading-day boundary. Exactly one of pct/amount must be set.', 'additionalProperties': {}}, {'type': 'null'}], 'description': 'Per-step override of the challenge-level daily loss rule. Omit to inherit; null = no daily loss rule in this step.'}, 'consistency': {'anyOf': [{'type': 'object', 'required': ['maxBestDayProfitPct'], 'properties': {'maxBestDayProfitPct': {'type': 'number', 'maximum': 100, 'description': "Maximum share of the step's total profit the best single day may contribute, in PERCENT UNITS (40 = the best day may be at most 40% of total profit).", 'exclusiveMinimum': 0}}, 'additionalProperties': {}}, {'type': 'null'}], 'description': "Consistency rule - SIMULATED (engine v1), not just flagged: one outsized day effectively raises the target (total profit must reach best day / pct), and the simulated trader keeps trading - rationally stopping days early when that helps - until the best-day share complies (see flag 'consistency-stop-rule'). null or omitted = no consistency rule."}, 'minTradingDays': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Minimum days with at least one trade before the step can be passed. Default 0.'}, 'profitTargetPct': {'type': 'number', 'description': 'Profit target in PERCENT UNITS of the initial account size (8 = 8%). Exactly one of profitTargetPct/profitTargetAmount.', 'exclusiveMinimum': 0}, 'profitTargetAmount': {'type': 'number', 'description': 'Profit target as a fixed currency amount (alternative to profitTargetPct).', 'exclusiveMinimum': 0}}, 'description': 'One evaluation step. Each step starts on a fresh account at the initial balance.', 'additionalProperties': {}}, 'minItems': 1, 'description': 'Evaluation steps in order. Passing the last step means funded.'}, 'funded': {'type': 'object', 'required': ['profitSplitPct', 'payoutFrequency'], 'properties': {'notes': {'type': 'string', 'description': 'Free-text funded-stage details that are not simulated.'}, 'maxLoss': {'type': 'object', 'required': ['mode'], 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Max loss in PERCENT UNITS of the initial account size (10 = 10%). Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'mode': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized', 'trailing-locks-at-initial'], 'type': 'string', 'description': "How the max-loss floor behaves - the single most consequential rule difference between firms. 'static-initial': floor fixed at initial balance minus the limit; never moves (classic CFD two-step). 'trailing-realized-eod': floor ratchets up with end-of-day balance highs; intraday highs do not move it. 'trailing-intraday-unrealized': floor trails the peak unrealized equity intraday and never stops trailing (futures-style; the most-miscalculated rule in the industry: it cuts pass probability dramatically). 'trailing-locks-at-initial': trails intraday peak equity until the floor reaches the initial balance, then freezes (common futures variant). Locking is also composable: locksAtInitial adds the same lock to an EOD trail, and lockOffsetAmount shifts the lock level to initial balance + that amount (e.g. 100 models 'stops trailing $100 above the start')."}, 'amount': {'type': 'number', 'description': 'Max loss as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'locksAtInitial': {'type': 'boolean', 'description': "For trailing modes: once the trailing floor climbs up to the initial balance (plus lockOffsetAmount), it locks there and stops trailing. Default false. 'trailing-locks-at-initial' locks by definition; set this to add the same lock to 'trailing-realized-eod' (e.g. an EOD trail that stops at the starting balance)."}, 'lockOffsetAmount': {'type': 'number', 'minimum': 0, 'description': "Currency offset of the lock level: the floor locks at initial balance + this amount, modeling rules like 'the trailing threshold stops $100 above the start'. Default 0. Only meaningful when the rule locks (mode 'trailing-locks-at-initial' or locksAtInitial=true)."}}, 'description': 'Funded-account override of the max loss rule. Omit to inherit.', 'additionalProperties': {}}, 'dailyLoss': {'anyOf': [{'type': 'object', 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Daily loss limit in PERCENT UNITS (5 = 5%); what it is a percent OF is set by limitBasis. Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'basis': {'enum': ['prior-day-balance', 'prior-day-equity'], 'type': 'string', 'description': "Anchor today's loss is measured from: prior day's closing balance or closing equity (they differ only with overnight positions). Default 'prior-day-balance'."}, 'amount': {'type': 'number', 'description': 'Daily loss limit as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'evaluation': {'enum': ['intraday', 'end-of-day'], 'type': 'string', 'description': "'intraday': fails the moment equity touches the daily floor. 'end-of-day': only the close is checked. Default 'intraday'."}, 'limitBasis': {'enum': ['initial-balance', 'anchor'], 'type': 'string', 'description': "What a percentage limit is a percent OF. 'initial-balance': a fixed currency allowance (always e.g. 5% of the starting account). 'anchor': recomputed daily from the day's anchor. Default 'initial-balance'."}, 'includesOpenPnl': {'type': 'boolean', 'description': 'Whether floating (unrealized) P&L counts toward the daily loss, i.e. breach can happen intra-position. Default true.'}}, 'description': 'Daily loss rule: the daily floor is anchor minus limit, reset at each trading-day boundary. Exactly one of pct/amount must be set.', 'additionalProperties': {}}, {'type': 'null'}], 'description': 'Funded-account override of the daily loss rule. Omit to inherit; null = none.'}, 'payoutRules': {'type': 'object', 'properties': {'bufferAmount': {'type': 'number', 'minimum': 0, 'description': 'Profit buffer that must remain in the account; only profit above it is withdrawable. Default 0.'}, 'minWinningDays': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Winning days required in a payout window before a payout can be requested. Default 0.'}, 'maxPayoutAmount': {'type': 'number', 'description': 'Absolute currency cap per payout request. Omit for no fixed cap.', 'exclusiveMinimum': 0}, 'winningDayMinProfit': {'type': 'number', 'minimum': 0, 'description': 'Minimum profit for a day to count as a winning day. Default 0 (any positive day).'}, 'maxPayoutPctOfProfit': {'type': 'number', 'maximum': 100, 'description': 'Cap on each payout in PERCENT UNITS of accrued profit (50 = at most half the profit per request). Omit for no percentage cap.', 'exclusiveMinimum': 0}, 'consistencyMaxBestDayPct': {'type': 'number', 'maximum': 100, 'description': "Funded consistency gate in PERCENT UNITS: the best day may contribute at most this share of the payout window's profit. Evaluated per window (see flag 'funded-consistency-window-approximated').", 'exclusiveMinimum': 0}}, 'description': "Payout gating - SIMULATED (engine v1), not just flagged: a payout happens only when these conditions are met, and on each eligible payout day the trader withdraws the maximum the rules allow (profit above the buffer, under the caps, never below the loss floor); balances and loss floors carry across payouts (see flag 'funded-withdrawal-model'). Omit for ungated payouts.", 'additionalProperties': {}}, 'profitSplitPct': {'type': 'number', 'maximum': 100, 'minimum': 0, 'description': "Trader's share of funded profits in PERCENT UNITS (80 = 80%)."}, 'payoutFrequency': {'enum': ['weekly', 'biweekly', 'monthly', 'on-demand'], 'type': 'string', 'description': 'How often funded profits can be withdrawn.'}, 'firstPayoutMinDays': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Minimum days on the funded account before the first payout. Default 0.'}}, 'description': 'Funded-stage terms used for the payout/EV simulation.', 'additionalProperties': {}}, 'maxLoss': {'type': 'object', 'required': ['mode'], 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Max loss in PERCENT UNITS of the initial account size (10 = 10%). Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'mode': {'enum': ['static-initial', 'trailing-realized-eod', 'trailing-intraday-unrealized', 'trailing-locks-at-initial'], 'type': 'string', 'description': "How the max-loss floor behaves - the single most consequential rule difference between firms. 'static-initial': floor fixed at initial balance minus the limit; never moves (classic CFD two-step). 'trailing-realized-eod': floor ratchets up with end-of-day balance highs; intraday highs do not move it. 'trailing-intraday-unrealized': floor trails the peak unrealized equity intraday and never stops trailing (futures-style; the most-miscalculated rule in the industry: it cuts pass probability dramatically). 'trailing-locks-at-initial': trails intraday peak equity until the floor reaches the initial balance, then freezes (common futures variant). Locking is also composable: locksAtInitial adds the same lock to an EOD trail, and lockOffsetAmount shifts the lock level to initial balance + that amount (e.g. 100 models 'stops trailing $100 above the start')."}, 'amount': {'type': 'number', 'description': 'Max loss as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'locksAtInitial': {'type': 'boolean', 'description': "For trailing modes: once the trailing floor climbs up to the initial balance (plus lockOffsetAmount), it locks there and stops trailing. Default false. 'trailing-locks-at-initial' locks by definition; set this to add the same lock to 'trailing-realized-eod' (e.g. an EOD trail that stops at the starting balance)."}, 'lockOffsetAmount': {'type': 'number', 'minimum': 0, 'description': "Currency offset of the lock level: the floor locks at initial balance + this amount, modeling rules like 'the trailing threshold stops $100 above the start'. Default 0. Only meaningful when the rule locks (mode 'trailing-locks-at-initial' or locksAtInitial=true)."}}, 'description': 'Challenge-level max loss rule applied to every step unless a step overrides it. Required.', 'additionalProperties': {}}, 'sources': {'type': 'array', 'items': {'type': 'object', 'required': ['url', 'lastVerified'], 'properties': {'url': {'type': 'string', 'description': 'Public page documenting the rule.'}, 'note': {'type': 'string'}, 'lastVerified': {'type': 'string', 'description': 'ISO date the rules were last checked against that page.'}}, 'additionalProperties': {}}, 'description': 'Public citations. Optional for inline specs; dataset entries always carry them.'}, 'currency': {'type': 'string', 'description': 'ISO currency code all amounts are denominated in. Default USD.'}, 'dailyLoss': {'anyOf': [{'type': 'object', 'properties': {'pct': {'type': 'number', 'maximum': 100, 'description': 'Daily loss limit in PERCENT UNITS (5 = 5%); what it is a percent OF is set by limitBasis. Exactly one of pct/amount.', 'exclusiveMinimum': 0}, 'basis': {'enum': ['prior-day-balance', 'prior-day-equity'], 'type': 'string', 'description': "Anchor today's loss is measured from: prior day's closing balance or closing equity (they differ only with overnight positions). Default 'prior-day-balance'."}, 'amount': {'type': 'number', 'description': 'Daily loss limit as a fixed currency amount (alternative to pct).', 'exclusiveMinimum': 0}, 'evaluation': {'enum': ['intraday', 'end-of-day'], 'type': 'string', 'description': "'intraday': fails the moment equity touches the daily floor. 'end-of-day': only the close is checked. Default 'intraday'."}, 'limitBasis': {'enum': ['initial-balance', 'anchor'], 'type': 'string', 'description': "What a percentage limit is a percent OF. 'initial-balance': a fixed currency allowance (always e.g. 5% of the starting account). 'anchor': recomputed daily from the day's anchor. Default 'initial-balance'."}, 'includesOpenPnl': {'type': 'boolean', 'description': 'Whether floating (unrealized) P&L counts toward the daily loss, i.e. breach can happen intra-position. Default true.'}}, 'description': 'Daily loss rule: the daily floor is anchor minus limit, reset at each trading-day boundary. Exactly one of pct/amount must be set.', 'additionalProperties': {}}, {'type': 'null'}], 'description': 'Challenge-level daily loss rule applied to every step unless a step overrides it. null = no daily loss rule. This field is required (pass null explicitly for none).'}, 'accountSize': {'type': 'number', 'description': 'Initial account balance in account currency.', 'exclusiveMinimum': 0}, 'challengeId': {'type': 'string', 'minLength': 1, 'description': "Stable kebab-case id for this ruleset, e.g. '100k-2step'."}, 'constraints': {'type': 'object', 'description': 'Informational trading constraints (maxLeverage, newsTrading, weekendHolding, ...). Recorded and flagged, never simulated.', 'propertyNames': {'type': 'string'}, 'additionalProperties': {}}, 'productType': {'enum': ['futures', 'cfd', 'equities'], 'type': 'string', 'description': "Instrument class the challenge is traded on: 'futures', 'cfd' (forex/CFD), or 'equities'."}, 'flagsNotSimulated': {'type': 'array', 'items': {'type': 'string'}, 'description': "Honesty channel: ids of rules this entry has that the engine does not simulate (e.g. 'scaling-plan', 'soft-daily-lockout'). Surfaced in every result's assumption flags. Consistency rules and payout gating do NOT belong here - the engine simulates them."}}, 'description': "Inline challenge ruleset, for challenges not in the directory or for what-if rule edits. Mutually exclusive with firmId/challengeId. Identify the challenge EITHER by directory reference (firmId + challengeId, discovered via propfirms_list_simulatable; firmId accepts the directory id or the firm's name) OR by a full inline `spec` object - the exact shape propfirms_challenge_rules returns, so you can fetch a directory entry, change one rule, and re-simulate to model rule variations. Provide exactly one of the two forms; providing both or neither is an error. Directory references need network access; inline specs are fully offline.", 'additionalProperties': {}}, 'paths': {'type': 'integer', 'maximum': 100000, 'minimum': 100, 'description': 'Monte Carlo paths (independent simulated trader journeys). Default 10,000 (well under a second); capped at 100,000 per tool call. Confidence intervals shrink roughly with the square root of paths.'}, 'firmId': {'type': 'string', 'minLength': 1, 'description': "Directory firm id or firm name (e.g. 'ftmo' or 'FTMO'); discover with propfirms_list_simulatable. Must be paired with challengeId. Mutually exclusive with `spec`."}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'rSeries': {'type': 'array', 'items': {'type': 'number'}, 'minItems': 10, 'description': "The trader's real trades as R-multiples in chronological order: each trade's P&L divided by the amount risked on it (+1.8 = won 1.8x risk, -1 = lost exactly the risk, -1.4 = stop slipped 40%). At least 10 trades; 100+ strongly recommended - short series make the simulation overconfident in the sample. Mutually exclusive with rSeriesText, tradeLogText, and tradeLogTexts."}, 'riskMode': {'enum': ['percent-of-balance', 'percent-of-initial', 'fixed-amount'], 'type': 'string', 'description': "How riskValue is interpreted. 'percent-of-balance' (default): risk compounds with the current balance. 'percent-of-initial': constant currency risk derived from the initial account size - how most prop traders size, since loss limits are fixed in currency. 'fixed-amount': explicit currency risked per 1R."}, 'riskValue': {'type': 'number', 'description': "Risk per trade - the value of 1R. PERCENT UNITS for percent modes (0.5 = 0.5% risked per trade; a typical prop range is 0.25-2), or a currency amount for 'fixed-amount'. NOT a fraction.", 'exclusiveMinimum': 0}, 'attemptCap': {'type': 'integer', 'maximum': 1000, 'minimum': 1, 'description': 'Maximum challenge attempts per path before that path gives up. Default 25. Journey statistics (expected attempts/cost, P(funded)) are censored at this cap.'}, 'importRisk': {'type': 'string', 'description': 'Risk per trade for imports that carry P&L but no risk data (e.g. TradingView, MT5 deals, broker JSON, ThinkOrSwim): cash risked per trade ("25") or a percent of entry value ("1%"). Applies to tradeLogText/tradeLogTexts only, is labeled rSource inferred, and is never applied silently: without it such files are refused with needs-risk.'}, 'newsFilter': {'type': 'object', 'properties': {'impacts': {'type': 'array', 'items': {'enum': ['low', 'medium', 'high'], 'type': 'string'}, 'minItems': 1, 'description': "Impact levels to avoid. Default ['high']. The built-in recurring calendar carries high- and medium-impact templates only; 'low' matches nothing unless customEventTimes supplies the events."}, 'currencies': {'type': 'array', 'items': {'enum': ['USD', 'EUR', 'GBP', 'JPY', 'AUD', 'CAD', 'CHF', 'NZD'], 'type': 'string'}, 'minItems': 1, 'description': 'Currencies whose events are avoided. Default: all eight built-in currencies (USD, EUR, GBP, JPY, AUD, CAD, CHF, NZD).'}, 'preMinutes': {'type': 'number', 'maximum': 1440, 'minimum': 0, 'description': 'Minutes avoided BEFORE each event. Default 30.'}, 'postMinutes': {'type': 'number', 'maximum': 1440, 'minimum': 0, 'description': 'Minutes avoided AFTER each event. Default 30.'}, 'customEventTimes': {'type': 'array', 'items': {'type': 'number'}, 'description': 'Exact extra event times as epoch MILLISECONDS UTC, merged into the calendar as high-impact events. Use these for releases the recurring templates do not cover.'}}, 'description': "What-if comparison: what are my odds if I do not OPEN trades around scheduled news? Requires a timestamped input (tradeLogText or tradeLogTexts). The simulation runs TWICE with the same seed and options, once on the full history and once with every trade opened inside [event - preMinutes, event + postMinutes] removed; trades opened earlier but held through an event are only counted, not removed. The returned SimResult is the news-AVOIDED scenario; structuredContent.newsComparison carries both scenarios' headline numbers, the excluded-trade count, and a calendar caveat that MUST be relayed to the user (the calendar is a recurring-template approximation of scheduled releases, not a historical feed)."}, 'challengeId': {'type': 'string', 'minLength': 1, 'description': 'Directory challenge id; discover with propfirms_list_simulatable. Must be paired with firmId. Mutually exclusive with `spec`.'}, 'rSeriesText': {'type': 'string', 'minLength': 1, 'description': 'The same series as pasted text: a JSON array, CSV, or whitespace/newline separated numbers, with an optional \'R\' suffix per value (e.g. "1.8R, -1R, 0.4, 2.1"). Parsed with the library\'s parseRSeries; unparseable tokens are reported back. Mutually exclusive with rSeries, tradeLogText, and tradeLogTexts.'}, 'tradeLogText': {'type': 'string', 'minLength': 1, 'description': 'The trader\'s trades as one pasted TIMESTAMPED log instead of a bare series. Accepted formats, auto-detected: the generic CSV template (header: open time,close time,symbol,direction,quantity,entry price,exit price,stop loss,pnl,fees,r), plain timestamped CSV/TSV logs (open time + R columns), real platform exports: TradingView strategy-tester list of trades (both generations), MT4/MT5 account statements (CSV or pasted HTML), MT5 deals tables, and ThinkOrSwim account statements, plus broker trade-history JSON in the @luxalgo/broker-sdk shape (a bare fills array, {"trades": [...]}, or one snapshot account; fills replay FIFO into round trips with price-based P&L, disclosed). Timestamps WITHOUT an explicit offset are read as UTC. Files that carry P&L but no risk information need importRisk to become R-multiples; ambiguous rule readings are refused with diagnostics rather than guessed, and skipped rows are reported as warnings. Timestamps unlock two things a bare series cannot do: tradesPerDay is derived from the log when not given, and newsFilter can compare odds with and without trading around news. Mutually exclusive with rSeries, rSeriesText, and tradeLogTexts.'}, 'tradesPerDay': {'type': 'number', 'description': "Average trades per simulated trading day. REQUIRED with rSeries/rSeriesText, which carry no timestamps. Optional with tradeLogText/tradeLogTexts: when omitted it is derived from the log's own timestamps (trades divided by distinct UTC trading days) and the output says so. More trades per day means more ways to hit the daily loss limit within a single day.", 'exclusiveMinimum': 0}, 'tradeLogTexts': {'type': 'array', 'items': {'type': 'string', 'minLength': 1}, 'maxItems': 5, 'minItems': 2, 'description': 'PORTFOLIO MODE: 2 to 5 timestamped trade logs (same format as tradeLogText), one per strategy or account. They are merged into one chronological series and the combined account is simulated, which preserves cross-strategy loss clustering (exactly what daily and max loss limits punish). Overlap across the histories is ALWAYS analyzed and attached as structuredContent.portfolioOverlap with an audit-risk verdict; see the attached structuredContent.portfolioOverlap analysis for the methodology. Mutually exclusive with rSeries, rSeriesText, and tradeLogText.'}, 'simulateFunded': {'type': 'boolean', 'description': 'Whether to simulate the funded stage (payouts, blowup risk) after passing. Default true - EV is only meaningful with it on; set false to study the evaluation alone.'}, 'blockMeanLength': {'type': 'number', 'description': "Mean block length of the stationary bootstrap (geometrically distributed blocks). Default 5 trades. 1 = i.i.d. resampling (destroys streaks - only for comparison); raise toward 10 if the trader's edge comes and goes in long regimes.", 'exclusiveMinimum': 0}, 'fundedHorizonDays': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Funded-stage horizon in trading days for the payout/EV simulation. Default 90 (about 4 calendar months). EV scales with this choice - state it when reporting EV.'}, 'includeHistograms': {'type': 'boolean', 'description': 'Include histogram arrays (attempts, cost, net, drawdown) in the result. Default FALSE for this tool to keep responses compact; summary quantiles (p05...p95) are always included.'}, 'tradesPerDayModel': {'enum': ['fixed', 'poisson'], 'type': 'string', 'description': "'fixed' (default): the same count every day. 'poisson': daily count drawn Poisson(tradesPerDay); days can then have zero trades, which do not count as trading days."}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['tradesPerDay', 'riskValue', 'context'], 'properties': {'firm': {'type': 'string', 'minLength': 1, 'description': "Restrict to one firm by propfirmId or name (e.g. 'ftmo')."}, 'seed': {'anyOf': [{'type': 'integer', 'maximum': 9007199254740991, 'minimum': -9007199254740991}, {'type': 'string'}], 'description': 'RNG seed (integer or string). Default 42. Same inputs + seed reproduce byte-identical results â\x80\x94 include the seed when reporting so users can reproduce the numbers.'}, 'paths': {'type': 'integer', 'maximum': 20000, 'minimum': 100, 'description': 'Monte Carlo paths PER CHALLENGE. Default 5,000 here (one full simulation runs per challenge in scope, so this tool costs number-of-challenges times one simulation); raise it to tighten confidence intervals on a narrowed scope.'}, 'avgWinR': {'type': 'number', 'description': 'Average winning trade in R-multiples, i.e. multiples of the amount risked per trade (1.5 = winners average 1.5x the risk).', 'exclusiveMinimum': 0}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'rSeries': {'type': 'array', 'items': {'type': 'number'}, 'minItems': 10, 'description': "The strategy's real trades as R-multiples in chronological order (P&L divided by amount risked; +1.8 = won 1.8x risk, -1 = lost the risk). At least 10 trades, 100+ recommended. When given, the screen uses the stationary block bootstrap (streaks preserved) instead of winRate/avgWinR."}, 'winRate': {'type': 'number', 'maximum': 1, 'minimum': 0, 'description': 'Probability a trade is a winner, as a FRACTION in [0, 1] (0.55 = 55% winners) â\x80\x94 NOT percent units. The most impactful input: traders routinely overestimate it by a few points, which can flip EV negative, so prefer measured stats over self-reported ones.'}, 'winStdR': {'type': 'number', 'minimum': 0, 'description': 'Standard deviation of winner sizes in R (0 = every winner is exactly avgWinR). Default 0. Adding spread makes streak damage more realistic.'}, 'avgLossR': {'type': 'number', 'description': 'Average losing trade in R, as a POSITIVE number. Default 1 (losers lose exactly the risked amount, i.e. stops are honored). Raise above 1 to model slippage or blown stops.', 'exclusiveMinimum': 0}, 'lossStdR': {'type': 'number', 'minimum': 0, 'description': 'Standard deviation of loser sizes in R (0 = every loser is exactly avgLossR). Default 0.'}, 'priceMax': {'type': 'number', 'description': 'Only challenges costing at most this.', 'exclusiveMinimum': 0}, 'riskMode': {'enum': ['percent-of-balance', 'percent-of-initial', 'fixed-amount'], 'type': 'string', 'description': "How riskValue is interpreted. 'percent-of-balance' (default): risk compounds with the current balance. 'percent-of-initial': constant currency risk derived from the initial account size â\x80\x94 how most prop traders size, since loss limits are fixed in currency. 'fixed-amount': explicit currency risked per 1R."}, 'riskValue': {'type': 'number', 'description': "Risk per trade â\x80\x94 the value of 1R. PERCENT UNITS for percent modes (0.5 = 0.5% risked per trade; a typical prop range is 0.25-2), or a currency amount for 'fixed-amount'. NOT a fraction.", 'exclusiveMinimum': 0}, 'attemptCap': {'type': 'integer', 'maximum': 1000, 'minimum': 1, 'description': 'Maximum challenge attempts per path before that path gives up. Default 25. Journey statistics (expected attempts/cost, P(funded)) are censored at this cap.'}, 'productType': {'enum': ['futures', 'cfd'], 'type': 'string', 'description': 'Restrict the screen to one instrument class.'}, 'rSeriesText': {'type': 'string', 'minLength': 1, 'description': "The same series as pasted text (JSON, CSV, or whitespace separated, optional 'R' suffix). Mutually exclusive with rSeries."}, 'tradesPerDay': {'type': 'number', 'description': 'Average trades per simulated trading day. More trades per day means more ways to hit the daily loss limit within a single day.', 'exclusiveMinimum': 0}, 'accountSizeMax': {'type': 'number', 'description': 'Only challenges with at most this account size.', 'exclusiveMinimum': 0}, 'accountSizeMin': {'type': 'number', 'description': 'Only challenges with at least this account size.', 'exclusiveMinimum': 0}, 'simulateFunded': {'type': 'boolean', 'description': 'Whether to simulate the funded stage (payouts, blowup risk) after passing. Default true â\x80\x94 EV is only meaningful with it on; set false to study the evaluation alone.'}, 'blockMeanLength': {'type': 'number', 'description': 'Bootstrap mean block length in trades. Default 5. Only used with rSeries/rSeriesText.', 'exclusiveMinimum': 0}, 'fundedHorizonDays': {'type': 'integer', 'maximum': 2000, 'minimum': 1, 'description': 'Funded-stage horizon in trading days for the payout/EV simulation. Default 90 (about 4 calendar months). EV scales with this choice â\x80\x94 state it when reporting EV.'}, 'minPassPerAttempt': {'type': 'number', 'maximum': 1, 'minimum': 0, 'description': 'The pass bar as a FRACTION in [0, 1]: a challenge counts as passing when the simulated per-attempt pass probability is at least this. Default 0.5. State the bar when relaying results.'}, 'requirePositiveEv': {'type': 'boolean', 'description': 'Additionally require expected value (payouts minus all fees over the funded horizon) above zero. Default false.'}, 'tradesPerDayModel': {'enum': ['fixed', 'poisson'], 'type': 'string', 'description': "'fixed' (default): the same count every day. 'poisson': daily count drawn Poisson(tradesPerDay); days can then have zero trades, which do not count as trading days."}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['context'], 'properties': {'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'dataset': {'enum': ['congress-trades', 'insider-transactions', 'thirteenf-holdings', 'gov-contracts', 'gov-grants', 'lobbying-filings', 'short-volume', 'committee-assignments', 'patents', 'clinical-trials', 'fda-approvals', 'cot-reports', 'wiki-pageviews', 'bills', 'fec-candidates', 'fec-contributions', 'congress-hearings', 'fed-communications'], 'type': 'string', 'description': 'One dataset for the detailed view; omit to list all'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['dataset', 'context'], 'properties': {'sort': {'enum': ['newest', 'oldest'], 'type': 'string', 'description': 'Order by event date (default newest)'}, 'text': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': "Case-insensitive substring over the dataset's name/title fields (member, insider, issuer, recipient, registrant and client, sponsor, assignee, bill title, â\x80¦); see textPaths in trackers_datasets"}, 'limit': {'type': 'integer', 'maximum': 100, 'minimum': 1, 'description': 'Rows to return (default 25, max 100)'}, 'where': {'type': 'object', 'description': 'Exact field matches by dot path, e.g. {"side":"buy"}, {"member.state":"CA"}, {"code":"P"}, {"formType":"4"}; string comparisons are case-insensitive, arrays match when any element does', 'propertyNames': {'type': 'string'}, 'additionalProperties': {'type': ['string', 'number', 'boolean']}}, 'offset': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Rows to skip, for paging (default 0)'}, 'ticker': {'type': 'string', 'maxLength': 12, 'minLength': 1, 'description': "Trading symbol, case-insensitive (e.g. 'NVDA'); matches the dataset's ticker field(s). Only datasets flagged tickerSearchable carry tickers."}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'dataset': {'enum': ['congress-trades', 'insider-transactions', 'thirteenf-holdings', 'gov-contracts', 'gov-grants', 'lobbying-filings', 'short-volume', 'committee-assignments', 'patents', 'clinical-trials', 'fda-approvals', 'cot-reports', 'wiki-pageviews', 'bills', 'fec-candidates', 'fec-contributions', 'congress-hearings', 'fed-communications'], 'type': 'string', 'description': 'Dataset id, from trackers_datasets'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['dataset', 'context'], 'properties': {'sort': {'enum': ['newest', 'oldest'], 'type': 'string', 'description': 'Order by event date (default newest)'}, 'text': {'type': 'string', 'maxLength': 200, 'minLength': 1, 'description': "Case-insensitive substring over the dataset's name/title fields (member, insider, issuer, recipient, registrant and client, sponsor, assignee, bill title, â\x80¦); see textPaths in trackers_datasets"}, 'limit': {'type': 'integer', 'maximum': 100, 'minimum': 1, 'description': 'Rows to return (default 25, max 100)'}, 'since': {'type': 'string', 'pattern': '^\\d{4}(-\\d{2}(-\\d{2})?)?$', 'description': 'Earliest event date (YYYY-MM-DD, YYYY-MM or YYYY), inclusive'}, 'until': {'type': 'string', 'pattern': '^\\d{4}(-\\d{2}(-\\d{2})?)?$', 'description': 'Latest event date, inclusive'}, 'where': {'type': 'object', 'description': 'Exact field matches by dot path, e.g. {"side":"buy"}, {"member.state":"CA"}, {"code":"P"}, {"formType":"4"}; string comparisons are case-insensitive, arrays match when any element does', 'propertyNames': {'type': 'string'}, 'additionalProperties': {'type': ['string', 'number', 'boolean']}}, 'years': {'type': 'array', 'items': {'type': 'integer', 'maximum': 2100, 'minimum': 1900}, 'maxItems': 8, 'description': 'Event years to read (max 8); default is the newest year with data. Prefer one year at a time for deep-history datasets.'}, 'offset': {'type': 'integer', 'maximum': 9007199254740991, 'minimum': 0, 'description': 'Rows to skip, for paging (default 0)'}, 'ticker': {'type': 'string', 'maxLength': 12, 'minLength': 1, 'description': "Trading symbol, case-insensitive (e.g. 'NVDA'); matches the dataset's ticker field(s). Only datasets flagged tickerSearchable carry tickers."}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}, 'dataset': {'enum': ['congress-trades', 'insider-transactions', 'thirteenf-holdings', 'gov-contracts', 'gov-grants', 'lobbying-filings', 'short-volume', 'committee-assignments', 'patents', 'clinical-trials', 'fda-approvals', 'cot-reports', 'wiki-pageviews', 'bills', 'fec-candidates', 'fec-contributions', 'congress-hearings', 'fed-communications'], 'type': 'string', 'description': 'Dataset id, from trackers_datasets'}}}
Input schema
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['ticker', 'context'], 'properties': {'year': {'type': 'integer', 'maximum': 2100, 'minimum': 1900, 'description': 'Event year to read (default: the current year)'}, 'limit': {'type': 'integer', 'maximum': 25, 'minimum': 1, 'description': 'Newest rows to include per dataset (default 5)'}, 'ticker': {'type': 'string', 'maxLength': 12, 'minLength': 1, 'description': "Trading symbol, e.g. 'NVDA'"}, 'context': {'type': 'string', 'description': 'Explain in 15-25 words, in third person, why this tool is called and how it supports the user\'s goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as "a user", "the customer", or "an account". Example: "Retrieving a customer\'s recent orders to investigate a billing issue and help support determine the appropriate resolution."'}}}
Recent tool changes
Similar MCP servers
Canon (wallstreet.wiki)
Searches a finance reference canon, explains regulatory thresholds and formulas, computes validated finance metrics, and produces…
Halal or Not
Provides Islamic-law assessments for food, medicine, financial products, crypto, stocks, funds, and everyday practices across fou…
Hemrock MCP
Provides financial modeling calculations for cap tables, exit waterfalls, and venture fund economics, along with modeling concept…
vorausgedacht.at
Provides precious-metal prices and historical analysis, material-value calculations, educational reference content, public-domain…
archive
Queries a source-traced archive of Lunenburg town and school budgets, meetings, staffing, elections, ledgers, and annual reports.
ITIN Finance
Provides verified information, guides, lender directories, and eligibility answers for US loans, credit, and cards using an ITIN.
FINLY Mortgage Knowledge
Provides sourced Israeli mortgage knowledge and performs limited hypothetical loan, payment, LTV, and PTI calculations.
MyKIFRS
Searches and retrieves Korean accounting standards, audit and ESG standards, and related official accounting Q&A documents.