diff --git a/app/intent/classifier.py b/app/intent/classifier.py index 3502b65..6a3c827 100644 --- a/app/intent/classifier.py +++ b/app/intent/classifier.py @@ -14,12 +14,14 @@ logger = logging.getLogger(__name__) Intent = Literal["codebase", "general", "clarification"] -INTENT_PROMPT = """Classify this user message into one category: -- "codebase": Questions about trading system code, architecture, files, methods, execution, strategies, exchanges, risk management, order handling, or technical implementation -- "general": Greetings, meta-questions, off-topic ("How are you?", "What can you do?", "Hello") -- "clarification": Follow-ups that rely on conversation context, not new retrieval ("Tell me more", "What did you mean?", "Can you explain that?") +INTENT_PROMPT = """You are classifying questions for a Tyndale trading system documentation assistant. -IMPORTANT: If the user is asking about specific code, files, classes, methods, or system behavior, classify as "codebase". +Classify this user message into one category: +- "codebase": ANY question about trading, strategies, exchanges, orders, positions, risk, execution, hedging, market making, P&L, or how the system works. Also includes questions with "our", "the system", "this", or references to specific functionality. +- "general": ONLY greetings or completely off-topic questions ("How are you?", "What's the weather?", "Hello") +- "clarification": Follow-ups that reference previous answers ("Tell me more", "What did you mean?", "Can you explain that?") + +DEFAULT TO "codebase" if uncertain. This is a trading system assistant - assume trading questions are about the codebase. Respond with ONLY the category name, nothing else.""" @@ -75,7 +77,7 @@ class IntentClassifier: # Validate intent if raw_intent in ("codebase", "general", "clarification"): - logger.debug(f"Classified intent: {raw_intent}") + logger.info(f"Intent classified: '{message[:50]}...' -> {raw_intent}") return raw_intent # Default to codebase for ambiguous cases (safer for RAG) diff --git a/artifacts/execution/live.yaml b/artifacts/execution/live.yaml index e69de29..ca1d088 100644 --- a/artifacts/execution/live.yaml +++ b/artifacts/execution/live.yaml @@ -0,0 +1,69 @@ +source_file: ./live.py +schema_version: v1.1 + +factual_summary: > + Provides the runtime framework for executing a market making strategy + in either paper or live trading modes. Responsible for initializing + exchanges, loading symbol universes, configuring execution components, + processing real-time market data, and coordinating the continuous + operation of the trading system. + +methods: + main() -> None: + description: > + Asynchronous entry point that orchestrates system initialization, + strategy and trader setup, exchange connectivity, optional logging + and metrics configuration, and continuous processing of incoming + market data events. + +interpretive_summary: > + Acts as the top-level execution driver for the trading system, wiring + together strategy logic, execution components, and exchange data feeds + into a single long-running process. Designed to support both simulated + and live trading environments while enabling observability and + operational control during runtime. + +invariants: + - Trading mode must be explicitly selected before execution begins. + - Exchanges must be initialized prior to processing market data. + - Strategy and trader instances must be fully constructed before + entering the main processing loop. + - Market data processing must run continuously until the process + terminates. + - Logging and metrics configuration must not interfere with execution. + +tags: + domain: + - market_data + - strategy_execution + - order_execution + - exchange_integration + + trading_function: + - data_ingest + - entry_logic + - exit_logic + + strategy_layer: + - execution + + system_layer: + - worker + + intent: + - orchestration + - isolation + - safety + + data_type: + - signals + - orders + - exchanges + + risk: + - latency + - data_corruption + - capital_loss + + maturity: + - production \ No newline at end of file diff --git a/artifacts/execution/trader.yaml b/artifacts/execution/trader.yaml index f3465e7..754c438 100644 --- a/artifacts/execution/trader.yaml +++ b/artifacts/execution/trader.yaml @@ -9,94 +9,94 @@ factual_summary: > backtesting modes. methods: - _getBracket(exch: str, sym: str) -> List[]: + "_getBracket(exch: str, sym: str) -> List[]": description: > Retrieves the current bid and ask information for a given symbol on a specified exchange using maintained order book state. - startBidding(exch: str, sym: str, ts: float, entryPrice: float or None) -> None: - description: > - Used in the Strat class to update the entry price of a symbol on a particular exchange. Logic for updating the - entry price is contained there. + "startBidding(exch: str, sym: str, ts: float, entryPrice: float or None) -> None": + description: > + Used in the Strat class to update the entry price of a symbol on a particular exchange. Logic for updating the + entry price is contained there. - stopBidding(exch: str, sym: str, ts: float) -> None: - description: > - Halts the bidding by removing the order from the limitBuy dictionary. + "stopBidding(exch: str, sym: str, ts: float) -> None": + description: > + Halts the bidding by removing the order from the limitBuy dictionary. - updateBracket(exch: str, sym: str, bidQuote: float, askQuote: float) -> None: - description: > - Updates the bracketed strings in our brackets dictionary. + "updateBracket(exch: str, sym: str, bidQuote: float, askQuote: float) -> None": + description: > + Updates the bracketed strings in our brackets dictionary. - startOffering(exch: str, sym: str, ts: float, entryPrice: float or None) -> None: - description: > - Executes the trades when we are going short. + "startOffering(exch: str, sym: str, ts: float, entryPrice: float or None) -> None": + description: > + Executes the trades when we are going short. - stopOffering(exch: str, sym: str, ts: float) -> None: - description: > - Stops the short position. + "stopOffering(exch: str, sym: str, ts: float) -> None": + description: > + Stops the short position. - logIntradayPnl(val: float) -> None: - description: > - Updates the value of our account to our pnl database + "logIntradayPnl(val: float) -> None": + description: > + Updates the value of our account to our pnl database - fpnl() -> None: + "fpnl() -> None": description: > Returns a list of floating profit and loss summaries - posCounts() -> dict: + "posCounts() -> dict": description: > Returns a python dictionary of the total positions we have on each exchange. - logFee(fee: float) -> None: + "logFee(fee: float) -> None": description: > Updates our fees in our database - posValueAtExchOld(exch: str, sym: str) -> int: + "posValueAtExchOld(exch: str, sym: str) -> int": description: > Calculates the values of the long and short positions. - fpnlnotional() -> int: + "fpnlnotional() -> int": description: > - This method calculates the profit/loss (P&L) based on the notional value of long and short positions for each - unique symbol across different exchanges. It computes the average price of long positions, sums the notional + This method calculates the profit/loss (P&L) based on the notional value of long and short positions for each + unique symbol across different exchanges. It computes the average price of long positions, sums the notional values of both long and short positions, and then uses these to compute the P&L. - fillLong(exch: str, sym: str, price: float, quan: float, ts: int, tag: str, feeType: str) -> None: + "fillLong(exch: str, sym: str, price: float, quan: float, ts: int, tag: str, feeType: str) -> None": description: > - The fillLong method handles the process of filling a buy order for a specified asset on an exchange. It updates - the trader's position with the new quantity and calculates the average price if necessary. If there was a short - position, it also calculates the profit/loss from buying back some or all of the shorted amount. Additionally, + The fillLong method handles the process of filling a buy order for a specified asset on an exchange. It updates + the trader's position with the new quantity and calculates the average price if necessary. If there was a short + position, it also calculates the profit/loss from buying back some or all of the shorted amount. Additionally, it logs the trade, applies fees, and ensures data integrity by asserting non-negative values. - fillShort(exch: str, sym: str, price: float, quan: float, ts: int, tag: str, feeType: str) -> None: + "fillShort(exch: str, sym: str, price: float, quan: float, ts: int, tag: str, feeType: str) -> None": description: > - The fillShort method handles the process of filling a sell order for a specified asset on an exchange. It updates - the trader's position with the new quantity and calculates the average price if necessary. If there was a long - position, it also calculates the profit/loss from selling some or all of the held amount. Additionally, it logs + The fillShort method handles the process of filling a sell order for a specified asset on an exchange. It updates + the trader's position with the new quantity and calculates the average price if necessary. If there was a long + position, it also calculates the profit/loss from selling some or all of the held amount. Additionally, it logs the trade, applies fees, and ensures data integrity by asserting non-negative values. - hedgeLong(exch: str, sym: str, price: float, quan: float, ts: int, force: bool) -> Exchange: + "hedgeLong(exch: str, sym: str, price: float, quan: float, ts: int, force: bool) -> Exchange": description: > - The hedgeLong method finds an appropriate exchange to hedge a long position by executing a corresponding sell - order. It iterates over possible exchanges, calculates adjusted bid prices based on offsets, and selects the - highest bid price for execution. If no suitable exchange is found without forcing, it forces hedging. The method - ensures that the hedge does not exceed maximum allowed positions and logs relevant information throughout the + The hedgeLong method finds an appropriate exchange to hedge a long position by executing a corresponding sell + order. It iterates over possible exchanges, calculates adjusted bid prices based on offsets, and selects the + highest bid price for execution. If no suitable exchange is found without forcing, it forces hedging. The method + ensures that the hedge does not exceed maximum allowed positions and logs relevant information throughout the process. - hedgeShort(exch: str, sym: str, price: float, quan: float, ts: int, force: bool) -> Exchange: + "hedgeShort(exch: str, sym: str, price: float, quan: float, ts: int, force: bool) -> Exchange": description: > - The hedgeShort method finds an appropriate exchange to hedge a short position by executing a corresponding buy - order. It iterates over possible exchanges, calculates adjusted ask prices based on offsets, and selects the - lowest ask price for execution. If no suitable exchange is found without forcing, it forces hedging. The method - ensures that the hedge does not exceed maximum allowed positions and logs relevant information throughout the + The hedgeShort method finds an appropriate exchange to hedge a short position by executing a corresponding buy + order. It iterates over possible exchanges, calculates adjusted ask prices based on offsets, and selects the + lowest ask price for execution. If no suitable exchange is found without forcing, it forces hedging. The method + ensures that the hedge does not exceed maximum allowed positions and logs relevant information throughout the process. - processTrade(exch: str, sym: str, price: float, tradeDir: list) -> None: + "processTrade(exch: str, sym: str, price: float, tradeDir: list) -> None": description: > - The first half of the processTrade method handles the scenario where a market sell order results in hitting a - limit buy order. It processes the fill, hedges the position, and logs various portfolio and holdings-related - details. The second half of the processTrade method handles the scenario where a market buy order results in - hitting a limit sell order. It processes the fill, hedges the position, and logs various portfolio and + The first half of the processTrade method handles the scenario where a market sell order results in hitting a + limit buy order. It processes the fill, hedges the position, and logs various portfolio and holdings-related + details. The second half of the processTrade method handles the scenario where a market buy order results in + hitting a limit sell order. It processes the fill, hedges the position, and logs various portfolio and holdings-related details. diff --git a/artifacts/strategies/strat.yaml b/artifacts/strategies/strat.yaml index 0c3b94c..b20458f 100644 --- a/artifacts/strategies/strat.yaml +++ b/artifacts/strategies/strat.yaml @@ -9,38 +9,38 @@ factual_summary: > runtime strategy state used for order placement and monitoring. methods: - registerExchange(exch: str, exchInst: Exchange) -> None: + "registerExchange(exch: str, exchInst: Exchange) -> None": description: > Registers an exchange instance under a named key for use by the strategy during execution. - setMinQty(exch: str, qtyMap: dict) -> None: + "setMinQty(exch: str, qtyMap: dict) -> None": description: > Updates minimum and maximum trade quantity constraints for a given exchange using a provided quantity mapping. - printFloating(ts: float) -> None: + "printFloating(ts: float) -> None": description: > Emits a formatted runtime summary of strategy activity for logging and monitoring purposes. - bestEdgeBid(exch: str, sym: str) -> List[bool, float, bool, str, float]: + "bestEdgeBid(exch: str, sym: str) -> List[bool, float, bool, str, float]": description: > - This method is designed to determine whether and where a bid should be placed based on several factors - related to market conditions and strategy rules. Its primary goal of is to calculate the optimal bid price for a - given symbol on a specific exchange, taking into account market positions, hedging strategies, trading limits, - price precision, and fee structures. Returns a collection of decision outputs including bid eligibility status, + This method is designed to determine whether and where a bid should be placed based on several factors + related to market conditions and strategy rules. Its primary goal of is to calculate the optimal bid price for a + given symbol on a specific exchange, taking into account market positions, hedging strategies, trading limits, + price precision, and fee structures. Returns a collection of decision outputs including bid eligibility status, relative pricing divergence, long-position participation, selected hedge exchange, and the computed bid price. - bestEdgeOffer(exch: str, sym: str) -> list: + "bestEdgeOffer(exch: str, sym: str) -> list": description: > - The primary goal of bestEdgeOffer is to calculate the optimal offer (ask) price for a given symbol on a specific - exchange, considering market positions, hedging strategies, trading limits, price precision, fee structures. + The primary goal of bestEdgeOffer is to calculate the optimal offer (ask) price for a given symbol on a specific + exchange, considering market positions, hedging strategies, trading limits, price precision, fee structures. Returns almost identical items as bestEdgeBid, but on the other side of the order book - updateTob(exch: str, sym: str, tob: dict, ts: float, force: bool) -> None: + "updateTob(exch: str, sym: str, tob: dict, ts: float, force: bool) -> None": description: > - The primary goal of the updateTob function is to update the top of the order book for quick access to perform + The primary goal of the updateTob function is to update the top of the order book for quick access to perform market making operations (bidding and selling) using the highest bid and lowest ask prices. interpretive_summary: >