類別 class 讓程式維護擴展更簡單!

立即訂閱電子報,掌握最新資訊!

    電子郵件

    有興趣的主題
    量化交易金融知識台灣股市國內期貨海外期貨虛擬貨幣

    有興趣的量化交易軟體/平台
    不清楚MultiChartsTradingViewPythonXQMT4MT5

    還有什麼詢問的?

    好富投 1920x400
    好富投 978x258

    點我了解更多資訊


    一、類別與物件的概念

    Python 理財的初學者隨著程式越寫越多,應該會越來越常碰到幾種情況:

    「啊!這個之前寫過,複製貼過來好了」這時候通常第一個會想到要使用的是定義 def 函數,來解決重複使用同一段程式碼的狀況。對 def 不熟的讀者可以先看之前的文章:函式 def 把重複的動作包裝起來!

    然後隨著 def 越來越多、程式越來越複雜,「物件導向」的開發方式是一種常見的做法,在 Python 主軸就是圍繞在 class 類別和物件的概念了!

    「物件」是什麼呢?舉個最簡單的例子,我們在模擬或是回測的時候要假設一個虛擬的帳戶。這個帳戶就像「存摺」一樣,保存了每筆買賣和轉帳紀錄,如果要計算某段期間的損益,從存摺中查看就能算出來。

    在這個情況,定義一個帳戶的類別似乎是個不錯的主意!因為,如果你正在模擬把兩支策略運行在各自的帳戶,但又想要綜合檢驗投資成效,只要用類別 class 定義「存摺」的範本,然後用這個範本創造兩本「存摺物件」,就可以讓整個程式的邏輯變得更清晰易懂。

    於是,我們接下來就用這個例子來做 class 的解說吧!

    Py 101209161710
    Py 101209161711

    二、Class 入門

    這個例子裡,我們定義了一個 class 叫做 Account。

    class Account:
        def __init__(self, balance: float = 0.0, password: str = ""):
            self.balance = balance
            self.position = {}
            self.__password = password
            
            self.log = []
    
        def deposit(self, amount: float):
            self.balance += amount
            self.__save_log({"type":"deposit","amount":amount})
        def withdraw(self, amount: float):
            if self.balance >= amount:
                self.balance -= amount
                self.__save_log({"type":"withdraw","amount":amount})
            else:
                print("balance insufficient!")
        def check_password(self, pw):
            return True if pw == self.__password else False
    
        def __save_log(self, log):
            self.log.append(log)

    首先是 def __init__ 的部分,這是在我們創造這個 class 的物件時,會直接運行的函數,概念上是在初始化這個物件。而後接續的括弧是創造物件時必須傳入的參數。程式碼撰寫方式如下:

    def__init__(self, 變數名稱: 預設資料型態 = 預設值, …)

    依照上面的例子,我們希望在 Account 物件被創造時,要傳入初始的帳戶餘額 balance,資料型態為 float 浮點數、預設值為 0,以及傳入初始的帳戶密碼 password,資料型態為 str 字串、預設值為 “” 空字串。

    在 __init__ 初始化函數內,我們把剛剛傳入的帳戶餘額和密碼存成物件的屬性,因此可以看到變數前面加了 self.,表示我們定義了這個「帳戶」的範本,它必須有這幾個屬性。除此之外,我們還定義了一個屬性叫做 position,就像證券存摺一樣,它也管理著你的股票部位,初始值為空的字典,表示帳戶裡沒有股票持倉。

    眼尖的讀者應該有一個疑惑,為什麼我要把密碼定義成 self.__password 呢?在 Python 這叫做 private 私有術性。簡單來說,從外部無法直接取用這個屬性。(其實在 Python 這有破解方法,這裡先不提)。無法直接取用是什麼意思呢?這裡舉個例子:

    # 首先,創造一個物件 account(開一個帳戶)
    # 初始存入 10000 元,並設密碼為 example
    account = Account(10000, “example”)
    
    # 如果想創造另一個帳戶,依樣畫葫蘆就行了
    account2 = Account(100, “example_2) 
    
    print(account.balance) # 印出結果 10000
    print(account.__password) 
    # 出現錯誤 AttributeError: 'Account' object has no attribute '__password'

    那要如何取用呢?要透過像範例裡的 check_password 函數一樣,從內部取用。所以,這時候如果我輸入以下程式碼是沒問題的!

    account.check_password("example") # 回傳值為 True

    另外,能夠舉一反三的同學,應該能看出,def __save_log 也帶著私有屬性!所以我不能從外部寫入帳戶紀錄 log,只能在存款(deposit 函數)和提款(withdraw 函數)時,從內部調用它。(當然這不包括破解私有屬性的情況)

    實例方法 instance method:以 self 為開頭,傳入物件

    上面這些函數,都是最典型、最常用的實例方法,傳入參數第一個為 self,在創造物件後,透過物件自己去呼叫。舉例來說,我們要存入 100 元的話,應該這麼寫:

    account = Account(10000, “example”) # 創造物件 
    account account.deposit(100) # 存入 100 元,呼叫時只需傳入 self 之後的參數

    靜態方法 staticmethod:大家都能取用的方法

    另外,之前收到讀者訊問說,如果我想讓人人都能調用 class 裡面的 def,用 class 來管理,要怎麼寫?

    Python 能夠實現這個情境,不過有一些小撇步要注意!我們接續著前面的例子做說明。假設我們把下面這個函數「取得系統維護時間」也定義在上面的 class Account 之中:

        @staticmethod
        def get_maintenance_time():
            return "Sunday 4:00 ~ 5:00 AM"

    這時候,無論是用物件呼叫,還是不先實例化,直接用類別取用,都是沒問題的!程式碼如下:

    # 以物件呼叫
    account = Account(10000, “example) # 創造物件 account
    print(account.get_maintenance_time()) # 印出結果: "Sunday 4:00 ~ 5:00 AM"
    
    # 直接取用(注意 Account 是 class 名稱,開頭變成大寫了!)
    print(Account.get_maintenance_time()) # 一樣能印出結果: "Sunday 4:00 ~ 5:00 AM"

    class 入門先講到這邊,撰寫 Python 理財會用到的 class 並不會太深,若有需要,後續我們再補充吧!

      電子郵件

      有興趣的主題
      量化交易金融知識台灣股市國內期貨海外期貨虛擬貨幣

      有興趣的量化交易軟體/平台
      不清楚MultiChartsTradingViewPythonXQMT4MT5

      還有什麼詢問的?


      量化通粉絲社群,一起討論程式交易!

      加入LINE社群量化交易討論群」無壓力討論與分享!

      加入臉書社團「程式交易 Taiwan」即時獲取實用的資源!

      QP66
      QP66

      具備逾十年交易經驗,研究交易資產橫跨股票、債券、外匯、原物料,以及加密貨幣。現為量化避險基金交易員,亦曾任職於資金規模逾百億的避險基金,以及在區塊鏈企業擔任顧問一職。

      擅長從宏觀至微觀,由淺入深挖掘交易機會,並運用Python實現全自動化的投資組合管理。

      文章: 24

      發佈留言

      發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *