均值迴歸策略在A股ETF市場獲利的可能性

王君敕發表於2024-09-25

如何在股票市場獲利

曾經有人告訴我一個在股票市場賺錢的秘訣,只要掌握這個秘訣,賺錢就像撿錢一樣容易。他說:這個秘訣其實很簡單,就是在股票價格低的時候買入,在價格高的時候賣出。

嘖嘖,不愧是秘訣,明明是句廢話,但又挑不出毛病。

問題是,如何判斷價格是低還是高?我知道你想說:價值。低於價值就是低,高於價值就是高。但是,如何估算出它的價值?我知道現在估值方法一大堆,公式指標漫天飛,但是任何公式任何指標都是參考都不能直接用。而當你無法準確估算價值時,其他的都無從談起。至於股神的“價值投資”,你說它是藝術也好,說它是玄學也罷,都不是我等凡人能搞明白的。

既然是凡人,那就要用凡人的方法。如果公式太複雜讓人摸不著頭腦,如果指標太多讓人無所適從,那就都不用,我們就簡單粗暴地求平均值。當然,也不能隨便什麼股票拿過來就求平均值,我們得挑,挑那種上下波動的股票,不要一路跌,也不要一路漲(我知道你可能青睞這種股票,但是這種股票不適合均值迴歸)。用統計學中的術語就是平穩,我們目標就是要尋找那種價格在時間序列上表現平穩的股票。

我們找到價格平穩的股票之後,還要弄清楚,它是多長時間從低點到高點然後又回到高點,就是週期。有兩個原因:1.我們要把週期太長的拋棄,你也不想等5年掙1%吧。2.我們儘量在一個週期內完成一次買賣操作,不要錯過週期,它一年低點到高點波動10次,你就買賣一次,那就有點辜負人家的好意了。

接下來,我們就需要解決這兩個問題:平穩性和週期。

平穩性測試

我打算使用ETF的資料來測試,因為ETF關聯的是一籃子股票,和單隻股票相比應該更平穩,更符合我們的意圖。(至於,自己挑選多隻股票,以不同權重組合起來以達到平穩,那是另外一個問題了,以後有機會再議)所有的資料都透過akshare來獲取,你可以訪問akshare的官方網站獲取更多資訊。

使用Dickey-Fuller(迪基-富勒)檢驗判斷股票價格序列的平穩性。至於迪基-富勒檢測的原理,你可以自行搜尋,也可以看我在這篇關於迪基-富勒檢驗1整理的一些概念。

我們先把A股所有ETF查出來,然後逐一檢測。檢測的時候僅獲取2023年1月1日以後的資料,使用的是收盤價。

import akshare as ak
import pandas as pd 
from statsmodels.tsa.stattools import adfuller
from datetime import datetime

def adf_test(hist_data):
    results=adfuller(hist_data, maxlag=None, regression='c', autolag='AIC')
    # print('ADF Statistic: %f' % results[0])  
    # print('p-value: %f' % results[1])  
    # print('Critical Values:')  
    # for key, value in results[4].items():  
    #     print('\t%s: %.3f' % (key, value))  
    if results[1] > 0.05:
        # print("時間序列是非平穩的,p-value > 0.05")
        return False
    else:
        # print("時間序列是平穩的,p-value <= 0.05")
        return True
    
def process_row(row):
    # print(row)
    hist_data = ak.fund_etf_hist_sina(symbol=row['程式碼'])
    if 'date' not in hist_data.columns:
        print('date not in clolumns 程式碼:%s 名稱:%s ' % (row['程式碼'],row['名稱']))
        print(hist_data)
        return None
    hist_data.set_index('date',inplace=True)
    y=hist_data.loc[hist_data.index >= datetime.strptime('2023-01-01','%Y-%m-%d').date(), 'close']
    # print(y)
    if len(hist_data) < 15:
        # print('程式碼:%s 名稱:%s ' % (row['程式碼'],row['名稱']))
        # print(f"Data length: {len(y)}")
        return None
    if adf_test(y):
         print('程式碼:%s 名稱:%s 時間序列adf測試結果是平穩的' % (row['程式碼'],row['名稱']))
         return row['程式碼'],row['名稱']
    else:
        return None
# 獲取所有ETF基金資訊
fund_etf_category_sina_df = ak.fund_etf_category_sina(symbol="ETF基金")
# 對所有基金做DF測試
results = fund_etf_category_sina_df.apply(process_row,axis=1).dropna()
p_results = [r for r in results if r is not None]
results_df = pd.DataFrame(p_results, columns=['程式碼', '名稱'])
print(results_df)
# 將結果儲存到csv
results_df.to_csv('datas/eft_fund_stationary_results.csv', index=False)
程式碼:sz159939 名稱:資訊科技ETF 時間序列adf測試結果是平穩的
程式碼:sz159933 名稱:國投金融地產ETF 時間序列adf測試結果是平穩的
程式碼:sz159811 名稱:5G50ETF 時間序列adf測試結果是平穩的
程式碼:sz159607 名稱:中概網際網路ETF 時間序列adf測試結果是平穩的
程式碼:sz159605 名稱:中概互聯ETF 時間序列adf測試結果是平穩的
程式碼:sz159587 名稱:糧食50ETF 時間序列adf測試結果是平穩的
程式碼:sz159579 名稱:深主機板50ETF華安 時間序列adf測試結果是平穩的
程式碼:sz159570 名稱:港股通創新藥ETF 時間序列adf測試結果是平穩的
程式碼:sz159569 名稱:港股紅利低波ETF 時間序列adf測試結果是平穩的
程式碼:sz159567 名稱:港股創新藥ETF 時間序列adf測試結果是平穩的
程式碼:sz159557 名稱:恆生醫療指數ETF 時間序列adf測試結果是平穩的
程式碼:sz159552 名稱:中證2000增強ETF 時間序列adf測試結果是平穩的
程式碼:sz159545 名稱:恆生紅利低波ETF 時間序列adf測試結果是平穩的
程式碼:sz159507 名稱:電信ETF 時間序列adf測試結果是平穩的
程式碼:sz159331 名稱:紅利港股ETF 時間序列adf測試結果是平穩的
程式碼:sz159330 名稱:滬深300ETF基金 時間序列adf測試結果是平穩的
程式碼:sz159329 名稱:沙特ETF 時間序列adf測試結果是平穩的
程式碼:sz159005 名稱:匯添富快錢ETF 時間序列adf測試結果是平穩的
程式碼:sz159003 名稱:招商快線ETF 時間序列adf測試結果是平穩的
程式碼:sz159001 名稱:貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh563180 名稱:高股息ETF 時間序列adf測試結果是平穩的
程式碼:sh520830 名稱:沙特ETF 時間序列adf測試結果是平穩的
程式碼:sh516110 名稱:汽車ETF 時間序列adf測試結果是平穩的
程式碼:sh512640 名稱:金融地產ETF基金 時間序列adf測試結果是平穩的
程式碼:sh512160 名稱:MSCI中國A股ETF 時間序列adf測試結果是平穩的
程式碼:sh511990 名稱:華寶添益ETF 時間序列adf測試結果是平穩的
程式碼:sh511980 名稱:現金添富ETF 時間序列adf測試結果是平穩的
程式碼:sh511970 名稱:國壽貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh511960 名稱:嘉實快線ETF 時間序列adf測試結果是平穩的
程式碼:sh511950 名稱:添利貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh511930 名稱:國聯日盈貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh511920 名稱:廣發貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh511910 名稱:融通貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh511900 名稱:富國貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh511860 名稱:保證金貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh511850 名稱:財富寶ETF 時間序列adf測試結果是平穩的
程式碼:sh511830 名稱:華泰貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh511820 名稱:鵬華添利ETF 時間序列adf測試結果是平穩的
程式碼:sh511810 名稱:理財金貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh511800 名稱:易方達貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh511770 名稱:金鷹增益貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh511700 名稱:場內貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh511690 名稱:交易貨幣ETF 時間序列adf測試結果是平穩的
程式碼:sh511670 名稱:華泰天天金ETF 時間序列adf測試結果是平穩的
程式碼:sh511660 名稱:貨幣ETF建信添益 時間序列adf測試結果是平穩的
程式碼:sh511650 名稱:華夏快線ETF 時間序列adf測試結果是平穩的
程式碼:sh511620 名稱:貨幣基金ETF 時間序列adf測試結果是平穩的
程式碼:sh511600 名稱:貨幣ETF 時間序列adf測試結果是平穩的
          程式碼           名稱
0   sz159939      資訊科技ETF
1   sz159933    國投金融地產ETF
2   sz159811      5G50ETF
3   sz159607     中概網際網路ETF
4   sz159605      中概互聯ETF
5   sz159587      糧食50ETF
6   sz159579   深主機板50ETF華安
7   sz159570    港股通創新藥ETF
8   sz159569    港股紅利低波ETF
9   sz159567     港股創新藥ETF
10  sz159557    恆生醫療指數ETF
11  sz159552  中證2000增強ETF
12  sz159545    恆生紅利低波ETF
13  sz159507        電信ETF
14  sz159331      紅利港股ETF
15  sz159330   滬深300ETF基金
16  sz159329        沙特ETF
17  sz159005     匯添富快錢ETF
18  sz159003      招商快線ETF
19  sz159001        貨幣ETF
20  sh563180       高股息ETF
21  sh520830        沙特ETF
22  sh516110        汽車ETF
23  sh512640    金融地產ETF基金
24  sh512160  MSCI中國A股ETF
25  sh511990      華寶添益ETF
26  sh511980      現金添富ETF
27  sh511970      國壽貨幣ETF
28  sh511960      嘉實快線ETF
29  sh511950      添利貨幣ETF
30  sh511930    國聯日盈貨幣ETF
31  sh511920      廣發貨幣ETF
32  sh511910      融通貨幣ETF
33  sh511900      富國貨幣ETF
34  sh511860     保證金貨幣ETF
35  sh511850       財富寶ETF
36  sh511830      華泰貨幣ETF
37  sh511820      鵬華添利ETF
38  sh511810     理財金貨幣ETF
39  sh511800     易方達貨幣ETF
40  sh511770    金鷹增益貨幣ETF
41  sh511700      場內貨幣ETF
42  sh511690      交易貨幣ETF
43  sh511670     華泰天天金ETF
44  sh511660    貨幣ETF建信添益
45  sh511650      華夏快線ETF
46  sh511620      貨幣基金ETF
47  sh511600        貨幣ETF

半衰期

下面的程式碼中,半衰期是透過對時間序列資料進行自迴歸分析(AR模型)得到的,這篇關於迪基-富勒檢驗的文章中也整理了一些概念。至於,為什麼,我無法解釋。如果你能解釋,請給我留言。

import statsmodels.api as sm
import numpy as np

def get_halflife(y):
    ylag = y.shift() #建立一個滯後變數
    # print(ylag)
    deltay = y - ylag #計算收盤價的差分
    # print(deltay)
    deltay = deltay[1:] #刪除第一個NaN值
    # print(deltay)

    # print(ylag[1:])
    X=sm.add_constant(ylag[1:]) # 為滯後變數新增常數項
    # print(X)
    model=sm.OLS(deltay, X) #建立一個線性迴歸模型
    res=model.fit() #擬合模型
    halflife=-np.log(2)/res.params.iloc[1] #計算半衰期
    print('halflife:',halflife)
    return halflife

stationary_df = pd.read_csv('datas/eft_fund_stationary_results.csv')

# 遍歷每一行
for index, row in stationary_df.iterrows():
    print(f"Row index: {index}, Values: {row['程式碼']}, {row['名稱']}")
    fund_etf_hist_sina_df = ak.fund_etf_hist_sina(symbol=row['程式碼'])
    # print(fund_etf_hist_sina_df)
    fund_etf_hist_sina_df.set_index('date',inplace=True)
    y=fund_etf_hist_sina_df.loc[fund_etf_hist_sina_df.index >= datetime.strptime('2022-01-01','%Y-%m-%d').date(), 'close']
    halflife = get_halflife(y)
    if halflife is not None:
        stationary_df.loc[index, '半衰期'] = halflife
        stationary_df.loc[index, '最高價'] = y.max()
        stationary_df.loc[index, '最低價'] = y.min()
    # print(stationary_df)
    
stationary_df.to_csv('datas/eft_fund_stationary_halflife.csv', index=False)
Row index: 0, Values: sz159939, 資訊科技ETF
halflife: 92.34305228118055
Row index: 1, Values: sz159933, 國投金融地產ETF
halflife: 20.68724512575711
Row index: 2, Values: sz159811, 5G50ETF
halflife: 26.37190816021413
Row index: 3, Values: sz159607, 中概網際網路ETF
halflife: 17.28790422641463
Row index: 4, Values: sz159605, 中概互聯ETF
halflife: 17.06493212981132
Row index: 5, Values: sz159587, 糧食50ETF
halflife: 2.949089109871738
Row index: 6, Values: sz159579, 深主機板50ETF華安
halflife: 2.813338527596978
Row index: 7, Values: sz159570, 港股通創新藥ETF
halflife: 6.72602477892452
Row index: 8, Values: sz159569, 港股紅利低波ETF
halflife: 6.982621873502573
Row index: 9, Values: sz159567, 港股創新藥ETF
halflife: 5.551490912970278
Row index: 10, Values: sz159557, 恆生醫療指數ETF
halflife: 3.886180626825971
Row index: 11, Values: sz159552, 中證2000增強ETF
halflife: 1.6623555515355546
Row index: 12, Values: sz159545, 恆生紅利低波ETF
halflife: 9.563267261024693
Row index: 13, Values: sz159507, 電信ETF
halflife: 15.354744585135212
Row index: 14, Values: sz159331, 紅利港股ETF
halflife: 5.127745146257745
Row index: 15, Values: sz159330, 滬深300ETF基金
halflife: 6.224023324277483
Row index: 16, Values: sz159329, 沙特ETF
halflife: 4.358172512022778
Row index: 17, Values: sz159005, 匯添富快錢ETF
halflife: 0.6930003555249722
Row index: 18, Values: sz159003, 招商快線ETF
halflife: 1.4086066553569159
Row index: 19, Values: sz159001, 貨幣ETF
halflife: 0.7891527486212535
Row index: 20, Values: sh563180, 高股息ETF
halflife: 16.960359750665614
Row index: 21, Values: sh520830, 沙特ETF
halflife: 3.7269403800137626
Row index: 22, Values: sh516110, 汽車ETF
halflife: 23.956386651978036
Row index: 23, Values: sh512640, 金融地產ETF基金
halflife: 21.492512923053198
Row index: 24, Values: sh512160, MSCI中國A股ETF
halflife: 106.42494264934585
Row index: 25, Values: sh511990, 華寶添益ETF
halflife: 1.0355531761823507
Row index: 26, Values: sh511980, 現金添富ETF
halflife: 0.8344262170791367
Row index: 27, Values: sh511970, 國壽貨幣ETF
halflife: 0.729031882259672
Row index: 28, Values: sh511960, 嘉實快線ETF
halflife: 2.4253386106330748
Row index: 29, Values: sh511950, 添利貨幣ETF
halflife: 1.1395445691593764
Row index: 30, Values: sh511930, 國聯日盈貨幣ETF
halflife: 0.7663723096457301
Row index: 31, Values: sh511920, 廣發貨幣ETF
halflife: 0.9131814944393649
Row index: 32, Values: sh511910, 融通貨幣ETF
halflife: 0.7700386811412008
Row index: 33, Values: sh511900, 富國貨幣ETF
halflife: 0.9199089818384839
Row index: 34, Values: sh511860, 保證金貨幣ETF
halflife: 0.7353234140098629
Row index: 35, Values: sh511850, 財富寶ETF
halflife: 1.7391021847980375
Row index: 36, Values: sh511830, 華泰貨幣ETF
halflife: 0.7853783252242303
Row index: 37, Values: sh511820, 鵬華添利ETF
halflife: 0.6984652914285889
Row index: 38, Values: sh511810, 理財金貨幣ETF
halflife: 1.1692529552911715
Row index: 39, Values: sh511800, 易方達貨幣ETF
halflife: 0.8153931709406015
Row index: 40, Values: sh511770, 金鷹增益貨幣ETF
halflife: 0.7606485418287927
Row index: 41, Values: sh511700, 場內貨幣ETF
halflife: 0.8159305221884142
Row index: 42, Values: sh511690, 交易貨幣ETF
halflife: 0.8158787320359637
Row index: 43, Values: sh511670, 華泰天天金ETF
halflife: 1.4621583710852248
Row index: 44, Values: sh511660, 貨幣ETF建信添益
halflife: 0.9027364815815827
Row index: 45, Values: sh511650, 華夏快線ETF
halflife: 0.7742258733578317
Row index: 46, Values: sh511620, 貨幣基金ETF
halflife: 0.7385332559142509
Row index: 47, Values: sh511600, 貨幣ETF
halflife: 0.714136626739289

我們進一步篩選一下,把半衰期太長(大於30)和太短(小於5)的拋棄。

target_df = pd.read_csv('datas/eft_fund_stationary_halflife.csv')

filtered_df = target_df[(target_df['半衰期'] > 5) & (target_df['半衰期'] < 30)].copy()

filtered_df.loc[:, '最大漲幅'] = (filtered_df['最高價'] - filtered_df['最低價']) / filtered_df['最低價']
# 按最大漲幅降序排序
sorted_df = filtered_df.sort_values(by='最大漲幅', ascending=False)
# pd.set_option('display.max_rows', 100)  # 設定最多顯示100行
# 列印結果
print(sorted_df)
          程式碼          名稱        半衰期    最高價    最低價      最大漲幅
3   sz159607    中概網際網路ETF  17.287904  0.960  0.545  0.761468
4   sz159605     中概互聯ETF  17.064932  0.957  0.545  0.755963
2   sz159811     5G50ETF  26.371908  1.281  0.771  0.661479
22  sh516110       汽車ETF  23.956387  1.312  0.828  0.584541
13  sz159507       電信ETF  15.354745  1.024  0.736  0.391304
23  sh512640   金融地產ETF基金  21.492513  2.110  1.564  0.349105
9   sz159567    港股創新藥ETF   5.551491  1.004  0.754  0.331565
1   sz159933   國投金融地產ETF  20.687245  2.526  1.900  0.329474
7   sz159570   港股通創新藥ETF   6.726025  0.923  0.753  0.225764
12  sz159545   恆生紅利低波ETF   9.563267  1.132  0.977  0.158649
20  sh563180      高股息ETF  16.960360  1.036  0.933  0.110397
14  sz159331     紅利港股ETF   5.127745  1.011  0.924  0.094156
8   sz159569   港股紅利低波ETF   6.982622  1.016  0.939  0.082002
15  sz159330  滬深300ETF基金   6.224023  1.002  0.951  0.053628

上面對漲幅進行了排序,中概網際網路ETF漲幅最大,我們來把資料拉出來驗證一下

etf_df = ak.fund_etf_hist_sina(symbol='sz159607')
etf_df.set_index('date',inplace=True)
close_data=etf_df.loc[etf_df.index >= datetime.strptime('2023-01-01','%Y-%m-%d').date(), 'close'].to_frame()
# close_data.plot(figsize=(12, 6))
close_data['MA17'] = close_data.rolling(window=17).mean().ffill()
close_data.plot(y=['close', 'MA17'], figsize=(12, 6))

這個曲線看起來還可以,應該能掙到錢吧。用backtrader回測下試試。

from datetime import datetime
import backtrader as bt
import pandas as pd

class SimpleMovingAverage(bt.Strategy):
    """
    主策略程式
    """
    params = (("maperiod", 17),)  # 全域性設定交易策略的引數

    def __init__(self):
        """
        初始化函式
        """
        self.data_close = self.datas[0].close  # 指定價格序列
        # 初始化交易指令、買賣價格和手續費
        self.order = None
        self.buy_price = None
        self.buy_comm = None
        # 新增移動均線指標
        self.sma = bt.indicators.SimpleMovingAverage(
            self.datas[0], period=self.params.maperiod
        )
    
    def log(self, txt, dt=None):
        dt = dt or self.datas[0].datetime.date(0)
        print('%s, %s' % (dt.isoformat(), txt))

    def next(self):
        """
        執行邏輯
        """
        if self.order:  # 檢查是否有指令等待執行,
            return
        if self.data_close[0] > self.sma[0]:# 執行賣出條件判斷:收盤價格高於日均線
            if self.position: # 檢查是否持倉
                self.order = self.sell(size=20000)
        if self.data_close[0] < self.sma[0]: # 執行買入條件判斷:收盤價格跌破日均線
            self.order = self.buy(size=20000)
    
    def notify_order(self, order):
        if order.status in [order.Submitted, order.Accepted]:
            return
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log('BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                        (order.executed.price,
                        order.executed.value,
                        order.executed.comm))
                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
            elif order.issell():
                self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                         (order.executed.price,
                          order.executed.value,
                          order.executed.comm))
            self.bar_executed = len(self)
        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Order Canceled/Margin/Rejected')
        self.order = None

def get_data_byakshare(code,start_date,end_date):
    fund_etf_hist_sina_df = ak.fund_etf_hist_sina(symbol=code)
    df=fund_etf_hist_sina_df.loc[(fund_etf_hist_sina_df['date'] >= start_date) & (fund_etf_hist_sina_df['date'] <= end_date)]
    # print(df)
    df.columns = ['trade_date', 'open', 'high', 'low', 'close','volume']
    # df.loc[:, 'trade_date'] = pd.to_datetime(df['trade_date'])
    df.set_index('trade_date', inplace=True)
    df.index = pd.to_datetime(df.index)
    # df.ffill()

    return df
cerebro = bt.Cerebro()

cerebro.addstrategy(SimpleMovingAverage)
start_date = datetime(2024, 3, 1)  # 回測開始時間
end_date = datetime(2024, 9, 1)  # 回測結束時間
stock_code = "sz159607"

data = get_data_byakshare(stock_code,start_date.date(),end_date.date())
datafeed = bt.feeds.PandasData(dataname=data,
                                fromdate=start_date,
                                todate=end_date)
cerebro.adddata(datafeed,name=stock_code)

cerebro.broker.setcash(100000.0)
# cerebro.addsizer(bt.sizers.FixedSize, stake=10)
cerebro.broker.setcommission(commission=0.002)

print('組合初始值: %.2f' % cerebro.broker.getvalue())

result=cerebro.run()

print('組合終結值: %.2f' % cerebro.broker.getvalue())
# cerebro.plot()
組合初始值: 100000.00
2024-04-16, BUY EXECUTED, Price: 0.71, Cost: 14300.00, Comm 28.60
2024-04-17, BUY EXECUTED, Price: 0.71, Cost: 14220.00, Comm 28.44
2024-04-18, BUY EXECUTED, Price: 0.71, Cost: 14120.00, Comm 28.24
2024-04-19, BUY EXECUTED, Price: 0.70, Cost: 14020.00, Comm 28.04
2024-04-22, BUY EXECUTED, Price: 0.71, Cost: 14140.00, Comm 28.28
2024-04-23, BUY EXECUTED, Price: 0.73, Cost: 14680.00, Comm 29.36
2024-04-24, SELL EXECUTED, Price: 0.76, Cost: 14246.67, Comm 30.36
2024-04-25, SELL EXECUTED, Price: 0.77, Cost: 14246.67, Comm 30.80
2024-04-26, SELL EXECUTED, Price: 0.77, Cost: 14246.67, Comm 30.96
2024-04-29, SELL EXECUTED, Price: 0.80, Cost: 14246.67, Comm 31.92
2024-04-30, SELL EXECUTED, Price: 0.80, Cost: 14246.67, Comm 31.80
2024-05-06, SELL EXECUTED, Price: 0.84, Cost: 14246.67, Comm 33.44
2024-05-27, BUY EXECUTED, Price: 0.84, Cost: 16800.00, Comm 33.60
2024-05-28, SELL EXECUTED, Price: 0.85, Cost: 16800.00, Comm 33.96
2024-05-29, BUY EXECUTED, Price: 0.84, Cost: 16760.00, Comm 33.52
2024-05-30, BUY EXECUTED, Price: 0.82, Cost: 16440.00, Comm 32.88
2024-05-31, BUY EXECUTED, Price: 0.83, Cost: 16580.00, Comm 33.16
2024-06-03, BUY EXECUTED, Price: 0.82, Cost: 16360.00, Comm 32.72
2024-06-04, BUY EXECUTED, Price: 0.82, Cost: 16380.00, Comm 32.76
2024-06-05, BUY EXECUTED, Price: 0.83, Cost: 16520.00, Comm 33.04
2024-06-06, Order Canceled/Margin/Rejected
2024-06-07, Order Canceled/Margin/Rejected
2024-06-11, Order Canceled/Margin/Rejected
2024-06-12, Order Canceled/Margin/Rejected
2024-06-13, Order Canceled/Margin/Rejected
2024-06-14, Order Canceled/Margin/Rejected
2024-06-17, Order Canceled/Margin/Rejected
2024-06-18, Order Canceled/Margin/Rejected
2024-06-19, Order Canceled/Margin/Rejected
2024-06-20, SELL EXECUTED, Price: 0.84, Cost: 16506.67, Comm 33.48
2024-06-21, SELL EXECUTED, Price: 0.82, Cost: 16506.67, Comm 32.76
2024-06-24, BUY EXECUTED, Price: 0.80, Cost: 16040.00, Comm 32.08
2024-06-25, BUY EXECUTED, Price: 0.80, Cost: 16080.00, Comm 32.16
2024-06-26, Order Canceled/Margin/Rejected
2024-06-27, Order Canceled/Margin/Rejected
2024-06-28, Order Canceled/Margin/Rejected
2024-07-01, Order Canceled/Margin/Rejected
2024-07-02, Order Canceled/Margin/Rejected
2024-07-03, Order Canceled/Margin/Rejected
2024-07-04, Order Canceled/Margin/Rejected
2024-07-05, Order Canceled/Margin/Rejected
2024-07-08, Order Canceled/Margin/Rejected
2024-07-09, Order Canceled/Margin/Rejected
2024-07-10, Order Canceled/Margin/Rejected
2024-07-11, Order Canceled/Margin/Rejected
2024-07-12, SELL EXECUTED, Price: 0.82, Cost: 16357.78, Comm 32.68
2024-07-15, SELL EXECUTED, Price: 0.82, Cost: 16357.78, Comm 32.88
2024-07-16, SELL EXECUTED, Price: 0.80, Cost: 16357.78, Comm 32.04
2024-07-17, SELL EXECUTED, Price: 0.80, Cost: 16357.78, Comm 31.88
2024-07-18, SELL EXECUTED, Price: 0.79, Cost: 16357.78, Comm 31.48
2024-07-19, BUY EXECUTED, Price: 0.79, Cost: 15700.00, Comm 31.40
2024-07-22, BUY EXECUTED, Price: 0.78, Cost: 15560.00, Comm 31.12
2024-07-23, BUY EXECUTED, Price: 0.80, Cost: 15900.00, Comm 31.80
2024-07-24, BUY EXECUTED, Price: 0.78, Cost: 15620.00, Comm 31.24
2024-07-25, BUY EXECUTED, Price: 0.77, Cost: 15360.00, Comm 30.72
2024-07-26, Order Canceled/Margin/Rejected
2024-07-29, Order Canceled/Margin/Rejected
2024-07-30, Order Canceled/Margin/Rejected
2024-07-31, Order Canceled/Margin/Rejected
2024-08-01, Order Canceled/Margin/Rejected
2024-08-02, Order Canceled/Margin/Rejected
2024-08-05, Order Canceled/Margin/Rejected
2024-08-06, Order Canceled/Margin/Rejected
2024-08-07, Order Canceled/Margin/Rejected
2024-08-08, Order Canceled/Margin/Rejected
2024-08-09, Order Canceled/Margin/Rejected
2024-08-12, SELL EXECUTED, Price: 0.77, Cost: 15749.63, Comm 30.80
2024-08-13, SELL EXECUTED, Price: 0.78, Cost: 15749.63, Comm 31.00
2024-08-14, SELL EXECUTED, Price: 0.78, Cost: 15749.63, Comm 31.16
2024-08-15, SELL EXECUTED, Price: 0.76, Cost: 15749.63, Comm 30.48
2024-08-16, SELL EXECUTED, Price: 0.78, Cost: 15749.63, Comm 31.04
2024-08-19, SELL EXECUTED, Price: 0.80, Cost: 15749.63, Comm 31.88
2024-08-28, BUY EXECUTED, Price: 0.74, Cost: 14860.00, Comm 29.72
2024-08-29, BUY EXECUTED, Price: 0.72, Cost: 14440.00, Comm 28.88
2024-08-30, BUY EXECUTED, Price: 0.74, Cost: 14740.00, Comm 29.48
組合終結值: 106851.96

3月1號到9月1號,10W的本金,折騰半年掙了6851,收益率6.8%,嘖嘖。怎麼說呢,好像還真有點賺頭…(其實,每次下單量對收益也有影響,我調整了幾次,發現20000可能是收益最高的了,真實交易的時候是不會給我這種調整的機會的...還有,這策略每天都要操作,要玩起來可能還真的全職,但交易太頻繁成本也高,佣金都要3000塊了,交易成本佔收益一半,還是慎重吧...)

上面的方法大都出自《演算法交易》這本書。

剛看完這書的時候,我意氣風發,都準備辭職在家全職炒股了。現在再看,半年掙6千...唉,還是算了,安心搬磚吧。

----------------------------------------------------------------------

Footnotes

  1. https://wangxuan.me/doushuai/posts/2024-08-20-Things-About-Dickey-Fuller.html

相關文章