(defclass agent () ((name :accessor name :initarg :name :initform nil :documentation "Human-readable name of the agent.") (security :accessor security :initarg :security :type keyword :documentation "Keyword symbol of the security being traded by the agent.") (market-hours :accessor market-hours :initarg :market-hours :initform (list (local-time:parse-timestring "09:30:00") (local-time:parse-timestring "15:45:00")) :documentation "Hours the market is open. Can be used in conjunction with the MARKET-CLOSED-P method to close out open positions or prevent trading during high volatility/low liquidity times.") (short-size :accessor unblock-short :initform -1) (long-size :accessor unblock-long :initform 1) (timestamps :accessor timestamps :initform nil :documentation "Reverse-chronological series of event timestamps seen by the agent.") (revalprices :accessor revalprices :initform nil :documentation "Reverse-chronological series of price events seen by the agent.") (orders :accessor orders :initform nil :documentation "Reverse-chronological series of orders issued by the agent.") (positions :accessor positions :initform nil :documentation "Reverse-chronological series of positions requested by the agent.") (pls :accessor pls :initform nil :documentation "Reverse-chronological series of profits/losses. Does not account for slippage.") (navs :initform nil :documentation "Reverse-chronological series of agent's clock-time Net Asset Value (NAV). Does not account for slippage.") (indicators :accessor indicators :initform nil :documentation "Reverse-chronological series of indicator values.") (fitnesses :accessor fitnesses :initform nil :documentation "Reverse-chronological series of trading strategy fitness calculations.") (trade-groups-cache :accessor trade-groups-cache :initform nil :type (or list nil) :documentation "Cached grouped trades (market entry to exit) in reverse-chronological order.") (unprocessed-trades :accessor unprocessed-trades :initform nil :documentation "New, unprocessed/grouped trades in reverse-chronological order.") (latest-trade-stats :initform nil :type (or 'trade-stats nil) :documentation "Cached version of the last computed trade stats.") (incoming-messages :accessor incoming-messages :initform nil :documentation "Set of messages from other agents. Used for inter-agent coordination.") (outgoing-messages :accessor outgoing-messages :initform nil :documentation "Set of messages to be passed to the other agents in the RECIPIENTS-LIST.") (recipients-list :accessor recipients-list :initarg :recipients-list :initform nil :documentation "Names of other agents that should receive outgoing messages.") (fitness-feedback-control :accessor fitness-feedback-control :initarg :fitness-feedback-control :initform nil))) ;;Here is a method that uses with-slots to for getting name and security from a agent (defmethod print-object ((a agent) stream) (with-slots (name security) a (print-unreadable-object (a stream :type t :identity t) (when (and (slot-boundp a 'name) name) (princ name stream)) (when (slot-boundp a 'security) (princ " " stream) (princ security stream))))) ;; Here is a method that gets orders from a agent without with-slots (defmethod cancel-order ((a agent) old-oid) (setf (orders a) (remove-if #`(equal (value %) old-oid) (orders a))))