Personal tools

Programming performance/Yasuo Common Lisp

From HaskellWiki

Jump to: navigation, search
#|
CL-USER> (lisp-implementation-type)
"Clozure Common Lisp"
CL-USER> (lisp-implementation-version)
"Version 1.6-r14468M  (DarwinX8664)"
CL-USER> (run)
1950-01-04 closing=16.85 change%=1.1404594 cash=10000 assets=NIL
1950-01-05 closing=16.93 change%=0.47477698 cash=10000 assets=NIL
...
2007-03-01 closing=1403.17 change%=-0.25944346 cash=12389.992 assets=(#S(PURCHASE :AMOUNT 0.9840075 :ORIGINAL-PRICE 1399.04))
2007-03-02 closing=1387.17 change%=-1.1402752 cash=12389.992 assets=(#S(PURCHASE :AMOUNT 0.9840075 :ORIGINAL-PRICE 1399.04))
13754.978 (#S(PURCHASE :AMOUNT 0.9840075 :ORIGINAL-PRICE 1399.04))
NIL
CL-USER> 
|#
 
(defun read-gspc ()
  (with-open-file (s "gspc.txt" :direction :input)
    (do ((result)
	 (line (read-line s nil)
	       (read-line s nil)))
	((null line) result)
      (unless (eql (char (string-left-trim #(#\Space #\Tab) line) 0) #\#)
	(push line result)))))
 
(defun date (record)
  (subseq record 0 (position #\Space record)))
 
(defun closing-cost (record)
  (read-from-string (subseq record (1+ (position #\Space record :from-end t)))))
 
(defun percent-change (old-price new-price)
  (* 100 (/ (- new-price old-price) old-price)))
 
(defstruct purchase amount original-price)
 
;; - Whenever the closing cost is down 3% or more from the previous closing cost, buy shares with 10% of current cash.
;; - Whenever the closing cost is up 6% or more from the original purchase price, sell back the full amount of stock purchased at that price.
;; - Sell off any remaining assets after the last day.
 
(defun run ()
  (let ((assets)
	(cash 10000)
	(records (read-gspc)))
    (map nil #'(lambda (day-1-record day-2-record)
		 (let* ((cost1 (closing-cost day-1-record))
			(cost2 (closing-cost day-2-record))
			(change (percent-change cost1 cost2)))
		   ;; buy
		   (when (<= change -3)
		     (let ((cost (* cash 1/10)))
		       (decf cash cost)
		       (push (make-purchase :amount (/ cost cost2) :original-price cost2) assets)
		       (format t "buy ~S~%" (car assets))))
		   ;; sell
		   (labels ((high-enough (asset)
			      (let ((change (percent-change (purchase-original-price asset) cost2)))
				(>= change 6))))
		     (dolist (asset (remove-if-not #'high-enough assets))
		       (incf cash (* (purchase-amount asset) cost2))
		       (format t "sell ~S change%=~A~%" asset (percent-change (purchase-original-price asset) cost2)))
		     (setf assets (remove-if #'high-enough assets)))
		   ;; display
		   (format t "~A closing=~A change%=~A cash=~A assets=~S~%" (date day-2-record) (closing-cost day-2-record) change cash assets)))
	 records
	 (cdr records))
 
    ;; sell remaining assets
    (dolist (asset assets)
      (incf cash (* (purchase-amount asset) (closing-cost (car (last records))))))
    ;; display
    (format t "~A ~S~%" cash assets)))