NBLOG_20231030 PYTHON量化交易;第二部Back Testing,新的開篇
睽違了好長的一段發呆的時間;今天還是硬著頭皮把這個新篇章給他寫下去。沒誇張的,這段時間真的是大部分都在發呆。事實上到此時此刻,都還不確定最終會呈現怎麼樣的一個結果?因為這個新的章節,應該就是我們整個量化交易的重點所在。這裡走包含著交易策略的設計、之後的歷史回測、以及策略的成果評估。直白地說,目標就是盡量的去復刻出一個Python下的Multicharts出來。當然我們不可能去搞出一個完整的套裝軟體出來。但是自己也不希望,事後完成的許多小程式是零零散散的。於是就發呆了這麼長的一段時間;盡量的去想、、盡量的去想。
不過再怎麼盡量的去想,也能把想這個動作走到了盡頭。再不走出去,也沒有什麼方向可以想的;所以硬著頭皮就上了。就這樣大家先跟著我邊打邊想吧!哪天也許有了什麼石破天驚的新點子?也不排除把這章節再重新寫過一遍。
一開始的工作,便需要來處理一些交易訊號。這裡有一個很好玩的過程。當大家每每開始學習一個新的程式語言的時候,幾乎所有人所寫的第一段代碼都應該是在螢幕列印出“Hello Word !! ”對吧?這幾乎都成一個慣例了。但是在年紀漸長之後發現這一段程式碼,就好像是一段保佑之後學習之路一路平安的祝福咒語屢試不爽。跟我有同感的請舉右手。
其實在學習量化程式交易的路上,也有著相同的段子。幾乎每個人完成的第一個交易策略程式碼,幾乎都是倆條移動平均線的交叉策略。就像宿命一樣,逃也逃不過。但也幾乎所有的人心裡都明白一件事;應該不會有人傻到拿這套策略直接去上戰場交易。因為大夥心知肚明,這幾乎就是一場穩賠不賺的遊戲。所以學歸學、做歸做,之間沒有半毛錢關係。
大家以為在這個新的章節裡,我會整出不一樣的活嗎?錯了、我們的交易訊號還是要從這裡開始。
首先、我必須說;雙均線的交叉策略,事實上是可以獲利的;指的是它經過一些改良之後。但這不是我們這裡所要去討論的重點。從這裡出發的原因,除了它是一個非常好的基礎策略示範之外,我想把它整出一箇萬向接頭來。所以這篇文章,不只是你交易策略設計的Hello world;我想他為成為大家在交易上真正可以用上手的極端武器。可以幫我們解決許多交易訊號的問題。
在自己幾年前所出版的一本專門討論XQ程式設計的新書當中,我就與讀者們分享談到許多策略設計的心得與問題。其中一個我歸納的重點;是非常重要的,那就是交叉幾乎是所有交易策略訊號之靈魂。相信就算沒有100%,八成以上也會是個保守的估計。可以說交叉無所不在。
在自己提出的右側交易觀念中,左側幾乎就是一個不需要的存在。因為在那個接下墜飛刀的區域裡面,幾乎沒有存在著真正的獲利空間。更多的是一些風險的存在。而在右側的區間裡面,我們必須要去設定個成熟的水位。當然、他不可能是在右側存在的最低點。當這個設定的水位,被觸及的時候;便可以假設趨勢的反轉可能到來。交易者可以利用這個確認的訊號進場,亦即使用右側最低的價格跌破來執行止損。
交叉便是確認了這個水位的存在與動作。可能是一個收盤價突破3日最高價的結果、又或者是一個5天移動平均線穿越10日移動平均線的結果、也可能是RSI的數據穿越過50以上。但不論是使用什麼樣的技術分析工具,最終可以歸納出它就是一個短期的訊號,向上穿越過了一個長期的訊號位準。這個訊號的成立;事實上這也是符合葛蘭碧八大法則,當中的買進訊號定義其中之一。所以它不只是一個交叉點,也是一個確認的點。交易趨勢改變了的確認點。
誒,這篇文章當中。我們的。代碼舉例的一個5日對10日移動平均線的交叉策略。上面提過,這是一個最基礎的。入門教育策略。但事實上。跟花俏一點的信號也是如此的去確認。比如說關卡價位的交叉。又比如說。布林格通道。與上軌的交叉。不論前面的訊號設計是如何的複雜。最終我們都可以提存。精簡到。2個數字之間的關係。也就是判斷這2個數字是否。存在。交叉的問題。所以其實我們擁有了一套。交叉為主的交易策略。幾乎等同我們掌握了。絕大多數的。交易策略。精神。還是直接上程式碼來說明吧。
import yfinance as yf
import pandas as pd
import mplfinance as mpf
import matplotlib.pyplot as plt
%matplotlib notebook
# 下載AAPL兩年歷史股價
symbol = "AAPL"
data = yf.download(symbol, period="2y")
# 計算5日和10日均線
data["MA5"] = data["Close"].rolling(window=5).mean()
data["MA10"] = data["Close"].rolling(window=10).mean()
# 判斷5日向上穿越10日
data["Signal"] = (data["MA5"] > data["MA10"]).astype(int)
data["Position"] = data["Signal"].diff() # 遇到1時持有,遇到-1時賣出
# 提取買入和賣出信號的日期和價格
buy_signal = data[data["Position"] == 1][["Low"]]
sell_signal = data[data["Position"] == -1][["High"]]
# 將買入和賣出信號的資料框轉換為具有相同日期索引的資料框
buy_signal = buy_signal.reindex(index=data.index, fill_value=None)
sell_signal = sell_signal.reindex(index=data.index, fill_value=None)
# 繪製K線圖和均線
fig, axes = mpf.plot(
data,
type="candle",
addplot=[
mpf.make_addplot(data["MA5"]),
mpf.make_addplot(data["MA10"]),
mpf.make_addplot(buy_signal, type="scatter", color="green", marker="^"),
mpf.make_addplot(sell_signal, type="scatter", color="red", marker="v"),
],
title="AAPL Stock",
ylabel="Price",
figsize=(10, 6),
returnfig=True,
)
# 設置買入和賣出點的箭頭標識
ax = axes[0]
ax.legend(["MA5", "MA10", "Buy Signal", "Sell Signal"])
# 顯示圖表
plt.show()
新章節的第一篇。我們就先談到這裡。下次見。
留言
張貼留言