吳晉安
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invitee
    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Versions and GitHub Sync Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
Invitee
Publish Note

Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

Your note will be visible on your profile and discoverable by anyone.
Your note is now live.
This note is visible on your profile and discoverable online.
Everyone on the web can find and read all notes of this public team.
See published notes
Unpublish note
Please check the box to agree to the Community Guidelines.
View profile
Engagement control
Commenting
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
  • Everyone
Suggest edit
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
Emoji Reply
Enable
Import from Dropbox Google Drive Gist Clipboard
   owned this note    owned this note      
Published Linked with GitHub
Subscribed
  • Any changes
    Be notified of any changes
  • Mention me
    Be notified of mention me
  • Unsubscribe
Subscribe
# Day1 量化交易簡介:資料取得、儲存 超晚才開局的我要開始寫文章啦,做了十幾年的交易,量化交易也做一段時間了,近期想說都沒有人寫量化交易在雲端服務系統上的應用,所以我就來補一下坑。本篇教學主要會著重在**量化交易數據分析**跟**GCP**兩大區塊。量化交易的領域中有很多數據分析上的盲點,需要考量很多假設才有辦法下手,總之我們先開始,後面大家再看我慢慢講來~ 這篇文章是以我從交易者轉職為資料科學家的角度來規劃的教學,主要使用的語言是Python。文章開頭會假設讀者已經有能力建立一個小的、基本的應用程式,並且已經爬取了一部分的數據(關於爬蟲太多人寫了,我就不獻醜了)。 以下是本次內容的目錄,請大家笑納~ 1. 量化交易簡介 - 資料取得 * 爬蟲簡述(包含爬取目標) * 購買 - 資料儲存 * SQLite(爬蟲儲存) * BigQuery(分析方便、運算速度快) - 小試身手 * 簡單建立幾個技術指標 --- # 量化交易簡介 量化交易的目的是為了讓我們進行交易時,可以不用長期盯盤,減輕交易過程的負擔。同時量化交易也因為有進行過數據分析,因此對於自己交易的信心會更加強烈,有所依據。當初我開始進行量化交易就是為了要讓生活可以真的是在生活,而不是受迫於交易過程的壓力。 量化交易分成以下幾個步驟: 1. 資料取得 2. 策略擬定 3. 回測績效 4. 建立下單環境 5. 下單交易 本篇是第一天的文章,我們先輕鬆一點從資料取得開始。 ## 資料取得 資料取得有很多方式,其中最簡單的方式就是直接到政府的[資料開放平台](https://data.gov.tw/dataset/11549)下載,缺點是可能會因為你忘記下載而導致資料缺漏。更好的方式是藉由購買以及爬蟲。 首先我們先說說爬蟲怎麼做吧! ### 爬蟲 目標先定為爬取[資料開放平台](https://data.gov.tw/dataset/11549)。 首先開啟瀏覽器,點選**開發人員**選項, ![](https://hackmd.io/_uploads/Hy1uqOT02.png) 使用左上角的**選取網頁中的元素即可檢查**, ![](https://hackmd.io/_uploads/rJ869u6Rn.png) 將滑鼠移動到下載按鈕,觀察下載按鈕的HTML構造 ![](https://hackmd.io/_uploads/Bkfeju6R3.png) 會發現該下載按鈕是藉由前端語言觸發並非URL,這時候懶惰的我就會立刻改採用動態爬蟲。 [動態爬蟲](https://hackmd.io/i8ChA3_7Te6ihLr6L3eIaw?view#%E8%A8%BB%EF%BC%9A)會以瀏覽器的測試驅動器執行,他會模擬使用者操作瀏覽器的方式,進行點按等動作。請注意近期Chrome的驅動器有改版,因此網路上大多教學文會失效。 首先我們先處理環境: 這裡使用的是 Python 10 ,pip更新至2023年9月最新的版本 第一步,我們先安裝 python 套件 selenium ``` pip install selenium ``` 接下來我們安裝驅動器,請到官方網站詳細閱讀一下(最近更新的時候沒看清楚就坑了一小時): https://chromedriver.chromium.org/downloads https://googlechromelabs.github.io/chrome-for-testing/ 撰寫一下程式碼: ```python= # 導入 selenium 套件 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service import time # 定義目標 URL URL = "https://data.gov.tw/dataset/11549" # 設定瀏覽器選項 options = Options() options.add_argument("--disable-notifications") # 指定 Chrome 驅動程式的路徑 driverpath = r"chromedriver.exe" service = Service(driverpath) # 啟動瀏覽器驅動程式 driver = webdriver.Chrome(service=service, options=options) driver.get(URL) # 如果網頁有某些元素需要等待加載,可以使用 WebDriverWait 方法, # 這個方法會等待元素出現才會與之互動以避免元素還沒出現就意圖互動帶來的錯誤 # 下方程式碼如果10秒都沒有出現會報錯 try: # 使用適當的定位方法,例如 By.ID, By.CLASS_NAME 等 # 注意 class 名稱中的空格需轉換成 "." element = WebDriverWait(driver, 10).until( EC.presence_of_element_located( (By.CLASS_NAME, "el-button.download-button.el-button--primary.el-button--mini.is-plain")) ) element.click() finally: # 等待 10 秒讓他下載 time.sleep(10) # 請記得關閉瀏覽器避免占用資源 driver.quit() ``` 爬取到的資料就可以放入資料庫儲存,以等待我們後續的處理。 (結果我還是寫了爬蟲XD) ### 註: - 靜態爬蟲: 靜態爬蟲主要用於獲取靜態網頁的內容,這些網頁的內容在原始碼中是固定的,並不依賴於任何用戶交互或JavaScript腳本執行。 - 動態爬蟲: 動態爬蟲用於獲取動態網頁的內容,這些網頁的內容通常由JavaScript腳本在用戶的瀏覽器中執行後渲染出來。 | 類型 | 優點 | 缺點 | |------|------|------| | 靜態爬蟲 | 1. 簡單、快速。 2. 不需要執行JavaScript。 3. 使用的資源較少。 | 1. 無法獲取基於JavaScript渲染的內容。 2. 有時可能會遇到反爬策略。 | | 動態爬蟲 | 1. 可以獲取JavaScript渲染的內容。 2. 更適合現代的Web應用。 | 1. 比靜態爬蟲更為複雜。 2. 需要的資源和時間較多。 3. 有時需要模擬用戶交互。 | ### 購買 購買的方式相對就簡單很多,市面上有很多購買的途徑。 我推薦由CMoney的法人決策系統取得資料,資料面相相當全面,並且有很方便的導出方式(他們的客服無微不至~)。 [CMoney 投資決策系統「網路版」](http://www.cmoney.com.tw/cmweb/upmain/shopping/default.aspx) ## 資料儲存 取得資料後我們就需要將資料儲存起來,這裡提供兩種方式,分別是SQLite以及BigQuery,兩者差別如下: - SQLite: - 輕便:只需要簡單安裝,不需要理會資料庫複雜的設定。 - 操作簡單:直接使用程式連接就可以操作。 - 便攜:只要把資料庫檔案 .db 檔,丟到隨身碟,資料庫就可以跟著走。 - BigQuery: - 功能強大:不論運算速度或是空間都相當大。 - 輕便:只需要登入google,不需要理會資料庫複雜的設定。 我們的計畫是,利用Python把資料先輸入到SQLite作為資料表的中繼站,而後我們可以將資料輸入BigQuery。因為爬下來的資料可能很髒,所以可以藉由SQLite進行約束、資料整理,並且能批量上傳數據以減少上傳次數。 ### SQLite >[SQLite](https://zh.wikipedia.org/zh-tw/SQLite)是遵守ACID的關聯式資料庫管理系統,它包含在一個相對小的C程式庫中。與許多其它資料庫管理系統不同,SQLite不是一個客戶端/伺服器結構的資料庫引擎,而是被整合在使用者程式中。 SQLite是什麼呢?想像一下你有一個玩具盒。這個玩具盒非常特別,因為不僅可以放玩具,還可以快速找到你想要的玩具,記錄玩具的名字,甚至可以記錄哪些玩具是一組的。這個玩具盒就像是SQLite。 那麼,SQLite的優勢是什麼呢? **輕巧簡單**:SQLite就像那個小巧的玩具盒,不需要特別的架子或工具就可以使用。在電腦上,它不需要特別的安裝或設定,只需要一個小小的檔案就可以運作。 **隨身攜帶**:想像一下,如果你今天到朋友家玩,你可以把整個玩具盒帶去,而不只是帶一些玩具。SQLite的資料庫是一個單一的檔案,所以你可以很容易地把它帶到其他地方,或分享給朋友。 **不需要特別的照顧**:有些玩具盒可能需要特別的鎖或密碼才能打開。但是SQLite很簡單,不需要特別的管理或維護。 要安裝SQLite很簡單,先到[這個網站](https://www.sqlite.org/download.html)下載程式安裝就可以在python中直接使用。 我們先來寫一下將資料寫入SQLite的程式碼~ ```python= # 匯入必要的函式庫 import pandas as pd import sqlite3 def save_csv_to_sqlite(file_path, db_path): """ 從CSV檔案中讀取資料並儲存到SQLite資料庫。 參數: - file_path: CSV檔案的路徑。 - db_path: 要儲存SQLite資料庫的路徑。 """ # 從CSV檔案中載入資料到pandas DataFrame df = pd.read_csv(file_path, encoding='utf-8') # 將原始的欄位名稱映射到其英文名稱 column_mapping = { "證券代號": "stock_code", "證券名稱": "stock_name", "成交股數": "transaction_volume", "成交金額": "transaction_amount", "開盤價": "opening_price", "最高價": "highest_price", "最低價": "lowest_price", "收盤價": "closing_price", "漲跌價差": "price_difference", "成交筆數": "transaction_count" } # 根據映射更改DataFrame的欄位名稱 df.rename(columns=column_mapping, inplace=True) # 與SQLite資料庫建立連線 with sqlite3.connect(db_path) as conn: # 將DataFrame的資料儲存到SQLite資料庫中,命名為'stock_data'的表格 # 如果已存在同名的表格,則會被替換 df.to_sql("stock_data", conn, if_exists="replace", index=False) # 使用指定的路徑呼叫函數 file_path = "/mnt/data/STOCK_DAY_ALL_20230912.csv" database_path = "/mnt/data/stock_data.sqlite" save_csv_to_sqlite(file_path, database_path) ``` 讀取資料到SQLite的方法如下: ```python= def read_from_sqlite(db_path, table_name): """ 使用pandas從SQLite資料庫中讀取資料。 參數: - db_path: SQLite資料庫的路徑。 - table_name: 要讀取的資料表名稱。 返回: - DataFrame: 包含資料表內容的pandas DataFrame。 """ # 與SQLite資料庫建立連線 with sqlite3.connect(db_path) as conn: # 使用pandas從資料庫中讀取資料 df = pd.read_sql(f"SELECT * FROM {table_name}", conn) return df # 使用指定的路徑和表名呼叫函數 database_path = "/mnt/data/stock_data.sqlite" table_name = "stock_data" data = read_from_sqlite(database_path, table_name) print(data.head()) ``` ### BigQuery 首先python要安裝套件,就裝一下吧~ ``` pip install --upgrade google-cloud-bigquery ``` BigQuery有很多連線方式(好像有四種),[官網推薦的是以下這種]:(https://cloud.google.com/bigquery/docs/reference/libraries?hl=zh-cn#client-libraries-install-python) ```python= from google.cloud import bigquery # 建構一個BigQuery客戶端物件。 client = bigquery.Client() query = """SELECT * FROM `trade-397602.stock_pool.stock_pool` LIMIT 1000 """ query_job = client.query(query) # 發起一個API請求。 print("查詢的資料:") for row in query_job: # 透過欄位名稱或索引來訪問行值。 print("pool_id={}, stock_id={}".format(row['pool_id'], row["stock_id"])) ``` 目前我們先連上就好,之後會再詳細講解如何運用BigQuery進行分析。 ## 建立幾個技術指標吧 寫到這裡也有點累了(竟然已經6600字!?)。先來簡單練練手,做為今天練習的結束吧~ 我們會使用到TAlib這個套件,但是這個套件比較麻煩不能用pip處理 1. 首先進入[此網站](https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib) ![](https://hackmd.io/_uploads/rJBs_ipC3.png) 2. 選擇自己電腦的環境: cp310是 python 3.10 版,不要選錯歐~ ![](https://hackmd.io/_uploads/r1j1YipRn.png) 3. 進入命令提示字元cmd輸入以下指令: ``` cd 你下載檔案的路徑 ``` 4. 安裝他~~ ``` pip install TA_Lib-0.4.24-cp310-cp310-win_amd64.whl ``` ## TALib建立簡單的KD指標 為了方便,接下來都以[這份資料](https://drive.google.com/file/d/1jj84N0yYdhIDxDEcQEK8AzxPkol2iKr5/view?usp=sharing)作分析。 我們讀取之後可以發現資料主要由以下欄位構成: 股票代號、股票名稱、日期、開盤價、收盤價、最高價、最低價、成交量 因為技術指標一次只需要計算一檔標的(股票),所以我們限制query在(台泥1101TT)上 ``` import talib as ta import pandas as pd import numpy as np df = pd.read_csv('transformed_data.csv') print(df) slowk, slowd = ta.STOCH(df.query('股票代號 == 1101')['最高價'], df.query('股票代號 == 1101')['最低價'], df.query('股票代號 == 1101')['收盤價'], fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, slowd_matype=0) print(slowd) ``` 今天先講到這裡~ 明天我們來談談機器學習的標註如何做在股票市場上。

Import from clipboard

Paste your markdown or webpage here...

Advanced permission required

Your current role can only read. Ask the system administrator to acquire write and comment permission.

This team is disabled

Sorry, this team is disabled. You can't edit this note.

This note is locked

Sorry, only owner can edit this note.

Reach the limit

Sorry, you've reached the max length this note can be.
Please reduce the content or divide it to more notes, thank you!

Import from Gist

Import from Snippet

or

Export to Snippet

Are you sure?

Do you really want to delete this note?
All users will lose their connection.

Create a note from template

Create a note from template

Oops...
This template has been removed or transferred.
Upgrade
All
  • All
  • Team
No template.

Create a template

Upgrade

Delete template

Do you really want to delete this template?
Turn this template into a regular note and keep its content, versions, and comments.

This page need refresh

You have an incompatible client version.
Refresh to update.
New version available!
See releases notes here
Refresh to enjoy new features.
Your user state has changed.
Refresh to load new user state.

Sign in

Forgot password

or

By clicking below, you agree to our terms of service.

Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
Wallet ( )
Connect another wallet

New to HackMD? Sign up

Help

  • English
  • 中文
  • Français
  • Deutsch
  • 日本語
  • Español
  • Català
  • Ελληνικά
  • Português
  • italiano
  • Türkçe
  • Русский
  • Nederlands
  • hrvatski jezik
  • język polski
  • Українська
  • हिन्दी
  • svenska
  • Esperanto
  • dansk

Documents

Help & Tutorial

How to use Book mode

Slide Example

API Docs

Edit in VSCode

Install browser extension

Contacts

Feedback

Discord

Send us email

Resources

Releases

Pricing

Blog

Policy

Terms

Privacy

Cheatsheet

Syntax Example Reference
# Header Header 基本排版
- Unordered List
  • Unordered List
1. Ordered List
  1. Ordered List
- [ ] Todo List
  • Todo List
> Blockquote
Blockquote
**Bold font** Bold font
*Italics font* Italics font
~~Strikethrough~~ Strikethrough
19^th^ 19th
H~2~O H2O
++Inserted text++ Inserted text
==Marked text== Marked text
[link text](https:// "title") Link
![image alt](https:// "title") Image
`Code` Code 在筆記中貼入程式碼
```javascript
var i = 0;
```
var i = 0;
:smile: :smile: Emoji list
{%youtube youtube_id %} Externals
$L^aT_eX$ LaTeX
:::info
This is a alert area.
:::

This is a alert area.

Versions and GitHub Sync
Get Full History Access

  • Edit version name
  • Delete

revision author avatar     named on  

More Less

Note content is identical to the latest version.
Compare
    Choose a version
    No search result
    Version not found
Sign in to link this note to GitHub
Learn more
This note is not linked with GitHub
 

Feedback

Submission failed, please try again

Thanks for your support.

On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

Please give us some advice and help us improve HackMD.

 

Thanks for your feedback

Remove version name

Do you want to remove this version name and description?

Transfer ownership

Transfer to
    Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

      Link with GitHub

      Please authorize HackMD on GitHub
      • Please sign in to GitHub and install the HackMD app on your GitHub repo.
      • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
      Learn more  Sign in to GitHub

      Push the note to GitHub Push to GitHub Pull a file from GitHub

        Authorize again
       

      Choose which file to push to

      Select repo
      Refresh Authorize more repos
      Select branch
      Select file
      Select branch
      Choose version(s) to push
      • Save a new version and push
      • Choose from existing versions
      Include title and tags
      Available push count

      Pull from GitHub

       
      File from GitHub
      File from HackMD

      GitHub Link Settings

      File linked

      Linked by
      File path
      Last synced branch
      Available push count

      Danger Zone

      Unlink
      You will no longer receive notification when GitHub file changes after unlink.

      Syncing

      Push failed

      Push successfully