如何在回測中獲得最終的百分比回報?
我正在學習如何使用 Pandas 在 Python 中進行回測。我正在學習如何使用移動平均交叉。我已經產生了買入或賣出的信號。但我不確定從那裡去哪裡?假設我擁有
$100,000
最終百分比回報的初始資本我意識到這是一個非常基本的問題,但我似乎還無法解決這個問題。
這就是我到目前為止所擁有的。
import datetime import pandas as pd from pandas_datareader import data, wb import numpy as np import Quandl import matplotlib.pylab as pylab %matplotlib inline start_date = datetime.datetime(2009,1,1) end_date = datetime.datetime(2014,1,1) amzn = data.DataReader("AMZN", "yahoo", start_date, end_date) def generate_signals(self): # Create DataFrame and initialise signal series to zero signals = pd.DataFrame(index=amzn.index) signals['signal'] = 0 # Create the short/long simple moving averages signals['short_mavg'] = pd.rolling_mean(amzn['Adj Close'], 40, min_periods=1) signals['long_mavg'] = pd.rolling_mean(amzn['Adj Close'], 100, min_periods=1) # When the short SMA exceeds the long SMA, set the ‘signals’ Series to 1 (else 0) signals['signal'][40:] = np.where(signals['short_mavg'][40:] > signals['long_mavg'][100:], 1, 0) # Take the difference of the signals in order to generate actual trading orders signals['positions'] = signals['signal'].diff() return signals
我從https://s3.amazonaws.com/quantstart/media/powerpoint/an-introduction-to-backtesting.pdf獲取了程式碼
這
Portfolio
部分不適合我,所以我試圖弄清楚在實際回測中應該發生什麼。
**注意:**假設你是一個初學者,試圖了解整個過程如何在高層次上運作,我絕對可以提出一些建議(如果我解釋錯了,如果下面的解釋是,我深表歉意不是你所追求的)。
如果您正在嘗試學習一些基本的回測基礎知識,而 QuantStart 是一個了不起的教育資源,我可能會建議在課程之外編寫一個類似的信號生成函式
Portfolio
(所以沒有self
函式參數),只是為了讓您了解交易的方式邏輯有效。您引用的展示文稿採用了一種更加嚴格的物件導向的方法來處理整個事情,對於剛剛學習基礎知識的人來說,這可能不會在上下文中點擊。接下來,我認為值得一提的是你要確保你的信號滯後。不這樣做是一個常見的回測陷阱,可以人為地產生良好的結果。
一旦你在每個時間步都有一個給定的信號,你就可以計算一些回報。假設您的信號是 1 表示做多,-1 表示做空,0 表示退出市場。然後您可以計算價格差異並乘以您的信號,這樣如果您的信號為 1,價格上漲將是有利的,如果您的信號為 -1,價格下跌將是有利的。假設每筆交易只有 1 股,該乘法步驟將在任何給定日期產生總(即美元金額)損益。
一旦你有了每日損益的向量,你就可以進行累積求和(
cumsum
函式)來產生一個總的執行損益向量,你可以將你的初始投資組合淨值 100,000 美元添加到該向量中。一旦你完成了所有這些,你就可以開始做一些回報計算了。這是一個類似於您上面的程式碼的小範例,它在 Portfolio 類之外工作,用於進行非常簡單直接的回測。
import pandas as pd from pandas.io.data import DataReader import numpy as np ticker = 'amzn' px = DataReader(ticker, 'yahoo') def generate_signals(px): signals = pd.DataFrame(index=px.index) signals['signal'] = 0 short_ma = pd.rolling_mean(px['Adj Close'], 40, min_periods=1) long_ma = pd.rolling_mean(px['Adj Close'], 100, min_periods=1) signals['signal'] = np.where(short_ma > long_ma, 1, 0) return signals['signal'].shift(1) # remember to lag your signals :) px['Signals'] = generate_signals(px) px['Daily P&L'] = px['Adj Close'].diff() * px['Signals'] px['Total P&L'] = px['Daily P&L'].cumsum() print px