diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/510300.SH.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/510300.SH.xlsx new file mode 100644 index 00000000..972f3d4a Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/510300.SH.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/AG.SHF.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/AG.SHF.xlsx new file mode 100644 index 00000000..f18d119d Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/AG.SHF.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/AL.SHF.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/AL.SHF.xlsx new file mode 100644 index 00000000..057d57f2 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/AL.SHF.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/AP.CZC.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/AP.CZC.xlsx new file mode 100644 index 00000000..eb42a6df Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/AP.CZC.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/AU.SHF.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/AU.SHF.xlsx new file mode 100644 index 00000000..30822666 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/AU.SHF.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/CF.CZC.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/CF.CZC.xlsx new file mode 100644 index 00000000..e5ea4169 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/CF.CZC.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/CU.SHF.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/CU.SHF.xlsx new file mode 100644 index 00000000..a8ea7b4b Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/CU.SHF.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/EC.INE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/EC.INE.xlsx new file mode 100644 index 00000000..619bc683 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/EC.INE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/FU.SHF.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/FU.SHF.xlsx new file mode 100644 index 00000000..8a0fcd11 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/FU.SHF.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/IC.CFE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/IC.CFE.xlsx new file mode 100644 index 00000000..9724cb3d Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/IC.CFE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/IF.CFE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/IF.CFE.xlsx new file mode 100644 index 00000000..cad40227 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/IF.CFE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/IH.CFE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/IH.CFE.xlsx new file mode 100644 index 00000000..200f3a7b Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/IH.CFE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/IM.CFE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/IM.CFE.xlsx new file mode 100644 index 00000000..01b89375 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/IM.CFE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/JD.DCE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/JD.DCE.xlsx new file mode 100644 index 00000000..e66f1b82 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/JD.DCE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/LC.GFE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/LC.GFE.xlsx new file mode 100644 index 00000000..f751ccc4 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/LC.GFE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/LH.DCE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/LH.DCE.xlsx new file mode 100644 index 00000000..47cda499 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/LH.DCE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/M.DCE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/M.DCE.xlsx new file mode 100644 index 00000000..5503cc79 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/M.DCE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/NI.SHF.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/NI.SHF.xlsx new file mode 100644 index 00000000..d59cd584 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/NI.SHF.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/NR.INE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/NR.INE.xlsx new file mode 100644 index 00000000..86fa9b1e Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/NR.INE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/OI.CZC.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/OI.CZC.xlsx new file mode 100644 index 00000000..b98c4b43 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/OI.CZC.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/P.DCE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/P.DCE.xlsx new file mode 100644 index 00000000..92fa4547 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/P.DCE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/RB.SHF.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/RB.SHF.xlsx new file mode 100644 index 00000000..3dbaf8f8 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/RB.SHF.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/RM.CZC.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/RM.CZC.xlsx new file mode 100644 index 00000000..6d497c22 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/RM.CZC.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SA.CZC.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SA.CZC.xlsx new file mode 100644 index 00000000..1c0ecf62 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SA.CZC.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SC.INE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SC.INE.xlsx new file mode 100644 index 00000000..2e36b210 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SC.INE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SH.CZC.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SH.CZC.xlsx new file mode 100644 index 00000000..b67ff509 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SH.CZC.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SN.SHF.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SN.SHF.xlsx new file mode 100644 index 00000000..d93f7264 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SN.SHF.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SP.SHF.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SP.SHF.xlsx new file mode 100644 index 00000000..f2a42684 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SP.SHF.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SR.CZC.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SR.CZC.xlsx new file mode 100644 index 00000000..4c45a93b Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/SR.CZC.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/T.CFE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/T.CFE.xlsx new file mode 100644 index 00000000..45932a99 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/T.CFE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/TA.CZC.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/TA.CZC.xlsx new file mode 100644 index 00000000..22210941 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/TA.CZC.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/TF.CFE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/TF.CFE.xlsx new file mode 100644 index 00000000..d04a6456 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/TF.CFE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/TL.CFE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/TL.CFE.xlsx new file mode 100644 index 00000000..a9ec88ca Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/TL.CFE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/TS.CFE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/TS.CFE.xlsx new file mode 100644 index 00000000..d467e765 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/TS.CFE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/UR.CZC.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/UR.CZC.xlsx new file mode 100644 index 00000000..324e90f6 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/UR.CZC.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/Y.DCE.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/Y.DCE.xlsx new file mode 100644 index 00000000..01fbe6a1 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/data/Y.DCE.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/divergence.py b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/divergence.py new file mode 100644 index 00000000..08004055 --- /dev/null +++ b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/divergence.py @@ -0,0 +1,162 @@ +import os +import numpy as np +import pandas as pd +from scipy.signal import argrelextrema + +def find_local_extrema(data, window, greater=True): + special_indices = [] + for i in range(window + 1, len(data)): + window_data = data[i-window-1:i] + if greater: + if data[i-1] == window_data.max() and data[i] < data[i-1]: + special_indices.append(i-1) + else: + if data[i-1] == window_data.min() and data[i] > data[i-1]: + special_indices.append(i-1) + + return np.array(special_indices) + +folder_path = 'data' +ans = [] +for file in os.listdir(folder_path): + if file.endswith('.xlsx'): + file_path = os.path.join(folder_path, file) + data = pd.read_excel(file_path) + data = data.iloc[:-2] + base_name, _ = os.path.splitext(file) + data = data.iloc[:-2] + + ema_short = data['收盘价(元)'].ewm(span=12, adjust=False).mean() + ema_long = data['收盘价(元)'].ewm(span=26, adjust=False).mean() + dif = ema_short - ema_long + dea = dif.ewm(span=9, adjust=False).mean() + macd_histogram = dif - dea + + data['DIF'] = dif + data['DEA'] = dea + data['MACD'] = macd_histogram + red_bar = np.where(macd_histogram > 0, macd_histogram, 0) + blue_bar = np.where(macd_histogram < 0, macd_histogram, 0) + + order = 15 + + # 找到股价和MACD的局部极大值和极小值索引 + price_max_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=True) + price_min_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=False) + macd_max_idx = find_local_extrema(data['MACD'], window=order, greater=True) + macd_min_idx = find_local_extrema(data['MACD'], window=order, greater=False) + + data['price_max'] = pd.Series(data['收盘价(元)'].iloc[price_max_idx].values, index=price_max_idx) + data['price_min'] = pd.Series(data['收盘价(元)'].iloc[price_min_idx].values, index=price_min_idx) + data['macd_max'] = pd.Series(data['MACD'].iloc[macd_max_idx].values, index=macd_max_idx) + data['macd_min'] = pd.Series(data['MACD'].iloc[macd_min_idx].values, index=macd_min_idx) + + # 初始化背离标识 + data['bull_divergence'] = False + data['bear_divergence'] = False + + for i in range(1, len(price_max_idx)): + current_idx = price_max_idx[i] + previous_idx = price_max_idx[i-1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + + for i in range(1, len(macd_max_idx)): + current_idx = macd_max_idx[i] + previous_idx = macd_max_idx[i-1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + + for i in range(1, len(price_min_idx)): + current_idx = price_min_idx[i] + previous_idx = price_min_idx[i-1] + + if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] > data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + + for i in range(1, len(macd_min_idx)): + current_idx = macd_min_idx[i] + previous_idx = macd_min_idx[i-1] + + if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] > data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + + initial_capital = 500000.0 + capital = initial_capital + stocks_held = 0 + portfolio_values = [] + + trades_tot = 0 + buy_price = 0 + trades = 0 + gains = [] + buy_queue = [] + for i in range(len(data) - 1): + if data['bear_divergence'][i] and capital >= data['收盘价(元)'][i]: + num_shares_to_buy = capital // data['收盘价(元)'].iloc[i] + buy_price += num_shares_to_buy * data['收盘价(元)'].iloc[i] + capital -= num_shares_to_buy * data['收盘价(元)'].iloc[i] + stocks_held += num_shares_to_buy + trades_tot += 1 + elif data['bull_divergence'][i] and stocks_held > 0: + num_shares_to_sell = stocks_held + sell_price = num_shares_to_sell * data['收盘价(元)'].iloc[i] + capital += sell_price + stocks_held = 0 + trades += 1 + trades_tot += 1 + gains.append(sell_price - buy_price) + buy_price = 0 + portfolio_value = capital + stocks_held * data['收盘价(元)'][i] + portfolio_values.append(portfolio_value) + + if stocks_held > 0: + num_shares_to_sell = stocks_held + capital += num_shares_to_sell * data['收盘价(元)'].iloc[len(data)-1] + stocks_held = 0 + trades += 1 + trades_tot += 1 + gains.append(sell_price - buy_price) + + portfolio_value = capital + stocks_held * data['收盘价(元)'][len(data)-1] + portfolio_values.append(portfolio_value) + + gains = np.array(gains) + profits = gains[gains > 0] + losses = gains[gains < 0] + + win_rate = len(profits) / trades if trades > 0 else 0 + avg_gain = np.mean(profits) if len(profits) > 0 else 0 + avg_loss = np.mean(losses) if len(losses) > 0 else 0 + odds_ratio = abs(avg_gain / avg_loss) if avg_loss != 0 else 0 + trade_frequency = trades_tot / len(data) if len(data) > 0 else 0 + + total_return = capital - initial_capital + annual_return = ((total_return / initial_capital) + 1) ** (252 / len(data)) - 1 + portfolio_values = np.array(portfolio_values) + + annual_risk_free_rate = 2.653 / 100 + daily_risk_free_rate = (1 + annual_risk_free_rate) ** (1/252) - 1 + returns = np.diff(portfolio_values) / portfolio_values[:-1] + adjusted_returns = returns - daily_risk_free_rate + sharpe_ratio = (np.mean(adjusted_returns) / np.std(adjusted_returns) * np.sqrt(len(data)) + if np.std(adjusted_returns) != 0 else 0) + max_drawdown = np.max(np.maximum.accumulate(portfolio_values) - portfolio_values) / np.max(portfolio_values) if np.max(portfolio_values) > 0 else 0 + + ans.append({ + "name": base_name, + "type": "dif", + "win_rate": win_rate, + "odds_ratio": odds_ratio, + "trade_frequency": trade_frequency, + "total_return": total_return, + "annual_return": annual_return, + "sharpe_ratio": sharpe_ratio, + "max_drawdown": max_drawdown, + }) +ansdf = pd.DataFrame(ans) + +file_path = "x3.xlsx" +ansdf.to_excel(file_path, index=False) diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/end2 mindspore.py b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/end2 mindspore.py new file mode 100644 index 00000000..b0ea758b --- /dev/null +++ b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/end2 mindspore.py @@ -0,0 +1,385 @@ +import os +import numpy as np +import pandas as pd +import pywt +import mindspore as ms +import mindspore.numpy as ms_np +from mindspore import ops, Tensor + + +def find_local_extrema(data, window, greater=True): + special_indices = [] + for i in range(window + 1, len(data)): + window_data = data[i - window - 1:i] + if greater: + if data[i - 1] == window_data.max() and data[i] < data[i - 1]: + special_indices.append(i - 1) + else: + if data[i - 1] == window_data.min() and data[i] > data[i - 1]: + special_indices.append(i - 1) + + return np.array(special_indices) + + +def genetic_algorithm(fitness_func, bounds, num_individuals, num_generations, crossover_rate, mutation_rate, + max_stagnant_generations, subset_data1): + num_variables = len(bounds) + low_bounds = ms_np.array([b[0] for b in bounds]) + high_bounds = ms_np.array([b[1] + 1 for b in bounds]) + + # 修复: 分维度生成随机整数后再堆叠 + low_bounds_np = low_bounds.asnumpy() + high_bounds_np = high_bounds.asnumpy() + temp_pop = [] + for i in range(num_variables): + col = ms_np.randint(int(low_bounds_np[i]), int(high_bounds_np[i]), (num_individuals,)) + temp_pop.append(col) + population = ops.stack(temp_pop, axis=1) + + elite_size = max(1, num_individuals // 10) + + def evaluate_population(pop): + pop_np = pop.asnumpy() + fitness_vals = [fitness_func(subset_data1, ind) for ind in pop_np] + return Tensor(fitness_vals, dtype=ms.float32) + + def select(population, fitness): + elite_indices = ops.argsort(fitness)[-elite_size:] + elite = ops.gather(population, elite_indices, 0) + max_fitness = ops.reduce_max(fitness) + max_fitness = ops.cast(max_fitness, ms.float32) + exp_values = ops.exp(fitness - max_fitness) + prob = exp_values / ops.reduce_sum(exp_values) + # 用 np.random.choice 替换 ms_np.random.choice + chosen_indices_np = np.random.choice(np.arange(num_individuals), size=num_individuals - elite_size, replace=True, p=prob.asnumpy()) + chosen_indices = Tensor(chosen_indices_np, dtype=ms.int32) + chosen = ops.gather(population, chosen_indices, 0) + return ops.concat((chosen, elite), 0) + + best_fitness_history = [] + stagnant_counter = 0 + for generation in range(num_generations): + fitness = evaluate_population(population) + best_index_tensor = ops.argmax(fitness) + best_index = int(best_index_tensor.asnumpy()) + max_fitness_tensor = ops.reduce_max(fitness) + max_fitness_val = float(max_fitness_tensor.asnumpy()) + best_fitness_history.append(max_fitness_val) + print(population[best_index]) + + if max_stagnant_generations: + if len(best_fitness_history) > 1 and (best_fitness_history[-1] - best_fitness_history[-2] < 1e-5): + stagnant_counter += 1 + else: + stagnant_counter = 0 + if stagnant_counter >= max_stagnant_generations: + print(f"Progress stagnant for {max_stagnant_generations} generations at generation {generation}") + break + + selected = select(population, fitness) + new_population = selected.copy() + + for i in range(0, num_individuals - elite_size, 2): + if ms_np.rand() < crossover_rate: + point = np.random.randint(1, num_variables) + seg1 = new_population[i, point:].copy() + new_population[i, point:] = new_population[i + 1, point:] + new_population[i + 1, point:] = seg1 + new_population[i] = mutate(new_population[i], mutation_rate, bounds) + new_population[i + 1] = mutate(new_population[i + 1], mutation_rate, bounds) + + population = new_population + print(f"Generation {generation}: Max Fitness = {max_fitness_tensor}") + + final_fitness = evaluate_population(population) + best_index = int(ops.argmax(final_fitness).asnumpy()) + return population[best_index].asnumpy(), float(ops.reduce_max(final_fitness).asnumpy()) + + +def mutate(individual, mutation_rate, bounds): + for i in range(len(bounds)): + if ms_np.rand() < mutation_rate: + individual[i] = ms_np.randint(bounds[i][0], bounds[i][1] + 1) + return individual + + +def fitness_function(data, individual): + x, y, z = individual + ema_short = data['收盘价(元)'].ewm(span=x, adjust=False).mean() + ema_long = data['收盘价(元)'].ewm(span=y, adjust=False).mean() + dif = ema_short - ema_long + dea = dif.ewm(span=z, adjust=False).mean() + macd_histogram = dif - dea + coeffs = pywt.wavedec(dif.values, 'coif5', level=4) + + approximation = coeffs[0] + + reconstructed_signal = pywt.waverec([approximation] + [np.zeros_like(coeff) for coeff in coeffs[1:]], 'coif5') + if len(reconstructed_signal) != len(dif): + reconstructed_signal = reconstructed_signal[:len(dif)] + reconstructed_dif = pd.Series(reconstructed_signal, index=dif.index) + + data['DIF'] = reconstructed_dif + data['DEA'] = dea + data['MACD'] = macd_histogram + + buy_signals = (data['DIF'] > data['MACD']) & (data['DIF'].shift(1) <= data['MACD'].shift(1)) + sell_signals = (data['DIF'] < data['MACD']) & (data['DIF'].shift(1) >= data['MACD'].shift(1)) + + order = 15 + + price_max_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=True) + price_min_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=False) + macd_max_idx = find_local_extrema(data['MACD'], window=order, greater=True) + macd_min_idx = find_local_extrema(data['MACD'], window=order, greater=False) + + data['price_max'] = pd.Series(data['收盘价(元)'].iloc[price_max_idx].values, index=price_max_idx) + data['price_min'] = pd.Series(data['收盘价(元)'].iloc[price_min_idx].values, index=price_min_idx) + data['macd_max'] = pd.Series(data['MACD'].iloc[macd_max_idx].values, index=macd_max_idx) + data['macd_min'] = pd.Series(data['MACD'].iloc[macd_min_idx].values, index=macd_min_idx) + + data['bull_divergence'] = False + data['bear_divergence'] = False + + for i in range(1, len(price_max_idx)): + current_idx = price_max_idx[i] + previous_idx = price_max_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + + for i in range(1, len(macd_max_idx)): + current_idx = macd_max_idx[i] + previous_idx = macd_max_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + + for i in range(1, len(price_min_idx)): + current_idx = price_min_idx[i] + previous_idx = price_min_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] > data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + + for i in range(1, len(macd_min_idx)): + current_idx = macd_min_idx[i] + previous_idx = macd_min_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] > \ + data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + + initial_capital = 500000.0 + capital = initial_capital + stocks_held = 0 + + buy_price = 0 + for i in range(len(data) - 1): + if (buy_signals.iloc[i] or data['bear_divergence'][i]) and capital > 0: + num_shares_to_buy = capital // data['收盘价(元)'].iloc[i] + buy_price += num_shares_to_buy * data['收盘价(元)'].iloc[i] + capital -= num_shares_to_buy * data['收盘价(元)'].iloc[i] + stocks_held += num_shares_to_buy + + elif (sell_signals.iloc[i] or data['bull_divergence'][i]) and stocks_held > 0: + num_shares_to_sell = stocks_held + sell_price = num_shares_to_sell * data['收盘价(元)'].iloc[i] + capital += sell_price + stocks_held = 0 + buy_price = 0 + + if stocks_held > 0: + num_shares_to_sell = stocks_held + capital += num_shares_to_sell * data['收盘价(元)'].iloc[len(data) - 1] + stocks_held = 0 + + total_return = capital - initial_capital + + return total_return + + +bounds = [(5, 20), (20, 50), (5, 25)] +NUM_INDIVIDUALS = 256 +NUM_GENERATIONS = 1024 +CROSSOVER_RATE = 0.95 +MUTATION_RATE = 0.05 + +folder_path = 'data' +ans = [] +for file in os.listdir(folder_path): + if file.endswith('.xlsx'): + file_path = os.path.join(folder_path, file) + data = pd.read_excel(file_path) + data = data.iloc[:-2] + base_name, _ = os.path.splitext(file) + + best_solution, max_fitness = genetic_algorithm(fitness_function, bounds, NUM_INDIVIDUALS, NUM_GENERATIONS, + CROSSOVER_RATE, MUTATION_RATE, 8, data) + print("Best Solution:", best_solution) + print("Max Fitness:", max_fitness) + + x, y, z = best_solution + + ema_short = data['收盘价(元)'].ewm(span=x, adjust=False).mean() + ema_long = data['收盘价(元)'].ewm(span=y, adjust=False).mean() + dif = ema_short - ema_long + dea = dif.ewm(span=z, adjust=False).mean() + macd_histogram = dif - dea + coeffs = pywt.wavedec(dif.values, 'coif5', level=4) + + approximation = coeffs[0] + + reconstructed_signal = pywt.waverec([approximation] + [np.zeros_like(coeff) for coeff in coeffs[1:]], 'coif5') + if len(reconstructed_signal) != len(dif): + reconstructed_signal = reconstructed_signal[:len(dif)] + reconstructed_dif = pd.Series(reconstructed_signal, index=dif.index) + + data['DIF'] = reconstructed_dif + data['DEA'] = dea + data['MACD'] = macd_histogram + + buy_signals = (data['DIF'] > data['MACD']) & (data['DIF'].shift(1) <= data['MACD'].shift(1)) + sell_signals = (data['DIF'] < data['MACD']) & (data['DIF'].shift(1) >= data['MACD'].shift(1)) + + order = 15 + + price_max_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=True) + price_min_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=False) + macd_max_idx = find_local_extrema(data['MACD'], window=order, greater=True) + macd_min_idx = find_local_extrema(data['MACD'], window=order, greater=False) + + data['price_max'] = pd.Series(data['收盘价(元)'].iloc[price_max_idx].values, index=price_max_idx) + data['price_min'] = pd.Series(data['收盘价(元)'].iloc[price_min_idx].values, index=price_min_idx) + data['macd_max'] = pd.Series(data['MACD'].iloc[macd_max_idx].values, index=macd_max_idx) + data['macd_min'] = pd.Series(data['MACD'].iloc[macd_min_idx].values, index=macd_min_idx) + + data['bull_divergence'] = False + data['bear_divergence'] = False + + for i in range(1, len(price_max_idx)): + current_idx = price_max_idx[i] + previous_idx = price_max_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + + for i in range(1, len(macd_max_idx)): + current_idx = macd_max_idx[i] + previous_idx = macd_max_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + + for i in range(1, len(price_min_idx)): + current_idx = price_min_idx[i] + previous_idx = price_min_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] > data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + + for i in range(1, len(macd_min_idx)): + current_idx = macd_min_idx[i] + previous_idx = macd_min_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] > data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + + initial_capital = 500000.0 + capital = initial_capital + stocks_held = 0 + portfolio_values = [] + + trades_tot = 0 + buy_price = 0 + trades = 0 + gains = [] + for i in range(len(data) - 1): + if (buy_signals.iloc[i] or data['bear_divergence'][i]) and capital > 0: + num_shares_to_buy = capital // data['收盘价(元)'].iloc[i] + buy_price += num_shares_to_buy * data['收盘价(元)'].iloc[i] + capital -= num_shares_to_buy * data['收盘价(元)'].iloc[i] + stocks_held += num_shares_to_buy + trades_tot += 1 + + elif (sell_signals.iloc[i] or data['bull_divergence'][i]) and stocks_held > 0: + num_shares_to_sell = stocks_held + sell_price = num_shares_to_sell * data['收盘价(元)'].iloc[i] + capital += sell_price + stocks_held = 0 + trades += 1 + trades_tot += 1 + gains.append(sell_price - buy_price) + buy_price = 0 + + portfolio_value = capital + stocks_held * data['收盘价(元)'][i] + portfolio_values.append(portfolio_value) + + if stocks_held > 0: + num_shares_to_sell = stocks_held + capital += num_shares_to_sell * data['收盘价(元)'].iloc[len(data) - 1] + stocks_held = 0 + trades += 1 + trades_tot += 1 + gains.append(sell_price - buy_price) + + portfolio_value = capital + stocks_held * data['收盘价(元)'][len(data) - 1] + portfolio_values.append(portfolio_value) + + gains = np.array(gains) + profits = gains[gains > 0] + losses = gains[gains < 0] + + win_rate = len(profits) / trades if trades > 0 else 0 + avg_gain = np.mean(profits) if len(profits) > 0 else 0 + avg_loss = np.mean(losses) if len(losses) > 0 else 0 + odds_ratio = abs(avg_gain / avg_loss) if avg_loss != 0 else 0 + trade_frequency = trades_tot / len(data) if len(data) > 0 else 0 + + total_return = capital - initial_capital + annual_return = ((total_return / initial_capital) + 1) ** (252 / len(data)) - 1 + portfolio_values = np.array(portfolio_values) + + annual_risk_free_rate = 2.653 / 100 + + daily_risk_free_rate = (1 + annual_risk_free_rate) ** (1 / 252) - 1 + returns = np.diff(portfolio_values) / portfolio_values[:-1] + adjusted_returns = returns - daily_risk_free_rate + sharpe_ratio = (np.mean(adjusted_returns) / np.std(adjusted_returns) * np.sqrt(len(data)) + if np.std(adjusted_returns) != 0 else 0) + max_drawdown = np.max(np.maximum.accumulate(portfolio_values) - portfolio_values) / np.max( + portfolio_values) if np.max(portfolio_values) > 0 else 0 + + print({ + "name": base_name, + "parameter": best_solution, + "win_rate": win_rate, + "odds_ratio": odds_ratio, + "trade_frequency": trade_frequency, + "total_return": total_return, + "annual_return": annual_return, + "sharpe_ratio": sharpe_ratio, + "max_drawdown": max_drawdown, + }) + ans.append({ + "name": base_name, + "parameter": best_solution, + "win_rate": win_rate, + "odds_ratio": odds_ratio, + "trade_frequency": trade_frequency, + "total_return": total_return, + "annual_return": annual_return, + "sharpe_ratio": sharpe_ratio, + "max_drawdown": max_drawdown, + }) +ansdf = pd.DataFrame(ans) + +file_path = "x4.xlsx" +ansdf.to_excel(file_path, index=False) \ No newline at end of file diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/end_1.py b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/end_1.py new file mode 100644 index 00000000..557796d7 --- /dev/null +++ b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/end_1.py @@ -0,0 +1,176 @@ +import os +import numpy as np +import pandas as pd +import matplotlib.pyplot as plt +import pywt + +def find_local_extrema(data, window, greater=True): + special_indices = [] + for i in range(window + 1, len(data)): + window_data = data[i-window-1:i] + if greater: + if data[i-1] == window_data.max() and data[i] < data[i-1]: + special_indices.append(i-1) + else: + if data[i-1] == window_data.min() and data[i] > data[i-1]: + special_indices.append(i-1) + + return np.array(special_indices) + +folder_path = 'data' +ans = [] +for file in os.listdir(folder_path): + if file.endswith('.xlsx'): + file_path = os.path.join(folder_path, file) + data = pd.read_excel(file_path) + + data = data.iloc[:-2] + + base_name, _ = os.path.splitext(file) + + ema_short = data['收盘价(元)'].ewm(span=12, adjust=False).mean() + ema_long = data['收盘价(元)'].ewm(span=26, adjust=False).mean() + dif = ema_short - ema_long + dea = dif.ewm(span=9, adjust=False).mean() + macd_histogram = dif - dea + coeffs = pywt.wavedec(dif.values, 'coif5', level=4) + + approximation = coeffs[0] + + reconstructed_signal = pywt.waverec([approximation] + [np.zeros_like(coeff) for coeff in coeffs[1:]], 'coif5') + if len(reconstructed_signal) != len(dif): + reconstructed_signal = reconstructed_signal[:len(dif)] + reconstructed_dif = pd.Series(reconstructed_signal, index=dif.index) + + data['DIF'] = reconstructed_dif + data['DEA'] = dea + data['MACD'] = macd_histogram + + buy_signals = (data['DIF'] > data['MACD']) & (data['DIF'].shift(1) <= data['MACD'].shift(1)) + sell_signals = (data['DIF'] < data['MACD']) & (data['DIF'].shift(1) >= data['MACD'].shift(1)) + + # 设置order参数 + order = 15 + + # 找到股价和MACD的局部极大值和极小值索引 + price_max_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=True) + price_min_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=False) + macd_max_idx = find_local_extrema(data['MACD'], window=order, greater=True) + macd_min_idx = find_local_extrema(data['MACD'], window=order, greater=False) + + # 创建极值点的Series + data['price_max'] = pd.Series(data['收盘价(元)'].iloc[price_max_idx].values, index=price_max_idx) + data['price_min'] = pd.Series(data['收盘价(元)'].iloc[price_min_idx].values, index=price_min_idx) + data['macd_max'] = pd.Series(data['MACD'].iloc[macd_max_idx].values, index=macd_max_idx) + data['macd_min'] = pd.Series(data['MACD'].iloc[macd_min_idx].values, index=macd_min_idx) + + # 初始化背离标识 + data['bull_divergence'] = False + data['bear_divergence'] = False + + for i in range(1, len(price_max_idx)): + current_idx = price_max_idx[i] + previous_idx = price_max_idx[i-1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + + for i in range(1, len(macd_max_idx)): + current_idx = macd_max_idx[i] + previous_idx = macd_max_idx[i-1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + + for i in range(1, len(price_min_idx)): + current_idx = price_min_idx[i] + previous_idx = price_min_idx[i-1] + + if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] > data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + + for i in range(1, len(macd_min_idx)): + current_idx = macd_min_idx[i] + previous_idx = macd_min_idx[i-1] + + if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] > data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + + initial_capital = 500000.0 + capital = initial_capital + stocks_held = 0 + portfolio_values = [] + + buy_price = 0 + trades = 0 + trades_tot = 0 + gains = [] + buy_queue = [] + for i in range(len(data) - 1): + if (buy_signals.iloc[i] or data['bear_divergence'][i]) and capital > 0: + num_shares_to_buy = capital // data['收盘价(元)'].iloc[i] + buy_price += num_shares_to_buy * data['收盘价(元)'].iloc[i] + capital -= num_shares_to_buy * data['收盘价(元)'].iloc[i] + stocks_held += num_shares_to_buy + trades_tot += 1 + + elif (sell_signals.iloc[i] or data['bull_divergence'][i]) and stocks_held > 0: + num_shares_to_sell = stocks_held + sell_price = num_shares_to_sell * data['收盘价(元)'].iloc[i] + capital += sell_price + stocks_held = 0 + trades += 1 + trades_tot += 1 + gains.append(sell_price - buy_price) + buy_price = 0 + + portfolio_value = capital + stocks_held * data['收盘价(元)'][i] + portfolio_values.append(portfolio_value) + + if stocks_held > 0: + num_shares_to_sell = stocks_held + capital += num_shares_to_sell * data['收盘价(元)'].iloc[len(data)-1] + stocks_held = 0 + trades += 1 + trades_tot += 1 + gains.append(sell_price - buy_price) + + portfolio_value = capital + stocks_held * data['收盘价(元)'][len(data)-1] + portfolio_values.append(portfolio_value) + + gains = np.array(gains) + profits = gains[gains > 0] + losses = gains[gains < 0] + + win_rate = len(profits) / trades if trades > 0 else 0 + avg_gain = np.mean(profits) if len(profits) > 0 else 0 + avg_loss = np.mean(losses) if len(losses) > 0 else 0 + odds_ratio = abs(avg_gain / avg_loss) if avg_loss != 0 else 0 + trade_frequency = trades_tot / len(data) if len(data) > 0 else 0 + + total_return = capital - initial_capital + annual_return = ((total_return / initial_capital) + 1) ** (252 / len(data)) - 1 + portfolio_values = np.array(portfolio_values) + + annual_risk_free_rate = 2.653 / 100 + daily_risk_free_rate = (1 + annual_risk_free_rate) ** (1/252) - 1 + returns = np.diff(portfolio_values) / portfolio_values[:-1] + adjusted_returns = returns - daily_risk_free_rate + sharpe_ratio = (np.mean(adjusted_returns) / np.std(adjusted_returns) * np.sqrt(len(data)) + if np.std(adjusted_returns) != 0 else 0) + max_drawdown = np.max(np.maximum.accumulate(portfolio_values) - portfolio_values) / np.max(portfolio_values) if np.max(portfolio_values) > 0 else 0 + + ans.append({ + "name": base_name, + "win_rate": win_rate, + "odds_ratio": odds_ratio, + "trade_frequency": trade_frequency, + "total_return": total_return, + "annual_return": annual_return, + "sharpe_ratio": sharpe_ratio, + "max_drawdown": max_drawdown, + }) +ansdf = pd.DataFrame(ans) + +file_path = "trading_strategies.xlsx" +ansdf.to_excel(file_path, index=False) \ No newline at end of file diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/end_2.py b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/end_2.py new file mode 100644 index 00000000..95984463 --- /dev/null +++ b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/end_2.py @@ -0,0 +1,367 @@ +import os +import numpy as np +import pandas as pd +import pywt + + +def find_local_extrema(data, window, greater=True): + special_indices = [] + for i in range(window + 1, len(data)): + window_data = data[i - window - 1:i] + if greater: + if data[i - 1] == window_data.max() and data[i] < data[i - 1]: + special_indices.append(i - 1) + else: + if data[i - 1] == window_data.min() and data[i] > data[i - 1]: + special_indices.append(i - 1) + + return np.array(special_indices) + + +def genetic_algorithm(fitness_func, bounds, num_individuals, num_generations, crossover_rate, mutation_rate, + max_stagnant_generations, subset_data1): + num_variables = len(bounds) + population = np.random.randint(low=[b[0] for b in bounds], high=[b[1] + 1 for b in bounds], + size=(num_individuals, num_variables)) + elite_size = max(1, num_individuals // 10) + + def evaluate_population(pop): + return np.array([fitness_func(subset_data1, ind) for ind in pop]) + + def select(population, fitness): + + elite_indices = np.argsort(fitness)[-elite_size:] + elite = population[elite_indices] + + max_fitness = np.max(fitness) + exp_values = np.exp(fitness - max_fitness) + probabilities = exp_values / exp_values.sum() + + chosen_indices = np.random.choice(num_individuals, size=num_individuals - elite_size, replace=True, + p=probabilities) + return np.concatenate((population[chosen_indices], elite)) + + best_fitness_history = [] + stagnant_counter = 0 + for generation in range(num_generations): + fitness = evaluate_population(population) + best_index = np.argmax(fitness) + max_fitness = fitness.max() + best_fitness_history.append(max_fitness) + print(population[best_index]) + + if max_stagnant_generations: + if len(best_fitness_history) > 1 and (best_fitness_history[-1] - best_fitness_history[-2] < 1e-5): + stagnant_counter += 1 + else: + stagnant_counter = 0 + if stagnant_counter >= max_stagnant_generations: + print(f"Progress stagnant for {max_stagnant_generations} generations at generation {generation}") + break + + selected = select(population, fitness) + new_population = selected.copy() + + for i in range(0, num_individuals - elite_size, 2): + if np.random.rand() < crossover_rate: + point = np.random.randint(1, num_variables) + new_population[i, point:], new_population[i + 1, point:] = new_population[i + 1, + point:], new_population[i, point:].copy() + new_population[i] = mutate(new_population[i], mutation_rate, bounds) + new_population[i + 1] = mutate(new_population[i + 1], mutation_rate, bounds) + + population = new_population + print(f"Generation {generation}: Max Fitness = {fitness.max()}") + + fitness = evaluate_population(population) + best_index = np.argmax(fitness) + return population[best_index], fitness.max() + + +def mutate(individual, mutation_rate, bounds): + for i in range(len(bounds)): + if np.random.rand() < mutation_rate: + individual[i] = np.random.randint(bounds[i][0], bounds[i][1] + 1) + return individual + + +def fitness_function(data, individual): + x, y, z = individual + ema_short = data['收盘价(元)'].ewm(span=x, adjust=False).mean() + ema_long = data['收盘价(元)'].ewm(span=y, adjust=False).mean() + dif = ema_short - ema_long + dea = dif.ewm(span=z, adjust=False).mean() + macd_histogram = dif - dea + coeffs = pywt.wavedec(dif.values, 'coif5', level=4) + + approximation = coeffs[0] + + reconstructed_signal = pywt.waverec([approximation] + [np.zeros_like(coeff) for coeff in coeffs[1:]], 'coif5') + if len(reconstructed_signal) != len(dif): + reconstructed_signal = reconstructed_signal[:len(dif)] + reconstructed_dif = pd.Series(reconstructed_signal, index=dif.index) + + data['DIF'] = reconstructed_dif + data['DEA'] = dea + data['MACD'] = macd_histogram + + buy_signals = (data['DIF'] > data['MACD']) & (data['DIF'].shift(1) <= data['MACD'].shift(1)) + sell_signals = (data['DIF'] < data['MACD']) & (data['DIF'].shift(1) >= data['MACD'].shift(1)) + + order = 15 + + price_max_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=True) + price_min_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=False) + macd_max_idx = find_local_extrema(data['MACD'], window=order, greater=True) + macd_min_idx = find_local_extrema(data['MACD'], window=order, greater=False) + + data['price_max'] = pd.Series(data['收盘价(元)'].iloc[price_max_idx].values, index=price_max_idx) + data['price_min'] = pd.Series(data['收盘价(元)'].iloc[price_min_idx].values, index=price_min_idx) + data['macd_max'] = pd.Series(data['MACD'].iloc[macd_max_idx].values, index=macd_max_idx) + data['macd_min'] = pd.Series(data['MACD'].iloc[macd_min_idx].values, index=macd_min_idx) + + data['bull_divergence'] = False + data['bear_divergence'] = False + + for i in range(1, len(price_max_idx)): + current_idx = price_max_idx[i] + previous_idx = price_max_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + + for i in range(1, len(macd_max_idx)): + current_idx = macd_max_idx[i] + previous_idx = macd_max_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + + for i in range(1, len(price_min_idx)): + current_idx = price_min_idx[i] + previous_idx = price_min_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] > data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + + for i in range(1, len(macd_min_idx)): + current_idx = macd_min_idx[i] + previous_idx = macd_min_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] > \ + data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + + initial_capital = 500000.0 + capital = initial_capital + stocks_held = 0 + + buy_price = 0 + for i in range(len(data) - 1): + if (buy_signals.iloc[i] or data['bear_divergence'][i]) and capital > 0: + num_shares_to_buy = capital // data['收盘价(元)'].iloc[i] + buy_price += num_shares_to_buy * data['收盘价(元)'].iloc[i] + capital -= num_shares_to_buy * data['收盘价(元)'].iloc[i] + stocks_held += num_shares_to_buy + + elif (sell_signals.iloc[i] or data['bull_divergence'][i]) and stocks_held > 0: + num_shares_to_sell = stocks_held + sell_price = num_shares_to_sell * data['收盘价(元)'].iloc[i] + capital += sell_price + stocks_held = 0 + buy_price = 0 + + if stocks_held > 0: + num_shares_to_sell = stocks_held + capital += num_shares_to_sell * data['收盘价(元)'].iloc[len(data) - 1] + stocks_held = 0 + + total_return = capital - initial_capital + + return total_return + + +bounds = [(5, 20), (20, 50), (5, 25)] +NUM_INDIVIDUALS = 256 +NUM_GENERATIONS = 1024 +CROSSOVER_RATE = 0.95 +MUTATION_RATE = 0.05 + +folder_path = 'data' +ans = [] +for file in os.listdir(folder_path): + if file.endswith('.xlsx'): + file_path = os.path.join(folder_path, file) + data = pd.read_excel(file_path) + data = data.iloc[:-2] + base_name, _ = os.path.splitext(file) + + best_solution, max_fitness = genetic_algorithm(fitness_function, bounds, NUM_INDIVIDUALS, NUM_GENERATIONS, + CROSSOVER_RATE, MUTATION_RATE, 8, data) + print("Best Solution:", best_solution) + print("Max Fitness:", max_fitness) + + x, y, z = best_solution + + ema_short = data['收盘价(元)'].ewm(span=x, adjust=False).mean() + ema_long = data['收盘价(元)'].ewm(span=y, adjust=False).mean() + dif = ema_short - ema_long + dea = dif.ewm(span=z, adjust=False).mean() + macd_histogram = dif - dea + coeffs = pywt.wavedec(dif.values, 'coif5', level=4) + + approximation = coeffs[0] + + reconstructed_signal = pywt.waverec([approximation] + [np.zeros_like(coeff) for coeff in coeffs[1:]], 'coif5') + if len(reconstructed_signal) != len(dif): + reconstructed_signal = reconstructed_signal[:len(dif)] + reconstructed_dif = pd.Series(reconstructed_signal, index=dif.index) + + data['DIF'] = reconstructed_dif + data['DEA'] = dea + data['MACD'] = macd_histogram + + buy_signals = (data['DIF'] > data['MACD']) & (data['DIF'].shift(1) <= data['MACD'].shift(1)) + sell_signals = (data['DIF'] < data['MACD']) & (data['DIF'].shift(1) >= data['MACD'].shift(1)) + + order = 15 + + price_max_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=True) + price_min_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=False) + macd_max_idx = find_local_extrema(data['MACD'], window=order, greater=True) + macd_min_idx = find_local_extrema(data['MACD'], window=order, greater=False) + + data['price_max'] = pd.Series(data['收盘价(元)'].iloc[price_max_idx].values, index=price_max_idx) + data['price_min'] = pd.Series(data['收盘价(元)'].iloc[price_min_idx].values, index=price_min_idx) + data['macd_max'] = pd.Series(data['MACD'].iloc[macd_max_idx].values, index=macd_max_idx) + data['macd_min'] = pd.Series(data['MACD'].iloc[macd_min_idx].values, index=macd_min_idx) + + data['bull_divergence'] = False + data['bear_divergence'] = False + + for i in range(1, len(price_max_idx)): + current_idx = price_max_idx[i] + previous_idx = price_max_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + + for i in range(1, len(macd_max_idx)): + current_idx = macd_max_idx[i] + previous_idx = macd_max_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + + for i in range(1, len(price_min_idx)): + current_idx = price_min_idx[i] + previous_idx = price_min_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] > data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + + for i in range(1, len(macd_min_idx)): + current_idx = macd_min_idx[i] + previous_idx = macd_min_idx[i - 1] + + if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[ + current_idx] > data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + + initial_capital = 500000.0 + capital = initial_capital + stocks_held = 0 + portfolio_values = [] + + trades_tot = 0 + buy_price = 0 + trades = 0 + gains = [] + for i in range(len(data) - 1): + if (buy_signals.iloc[i] or data['bear_divergence'][i]) and capital > 0: + num_shares_to_buy = capital // data['收盘价(元)'].iloc[i] + buy_price += num_shares_to_buy * data['收盘价(元)'].iloc[i] + capital -= num_shares_to_buy * data['收盘价(元)'].iloc[i] + stocks_held += num_shares_to_buy + trades_tot += 1 + + elif (sell_signals.iloc[i] or data['bull_divergence'][i]) and stocks_held > 0: + num_shares_to_sell = stocks_held + sell_price = num_shares_to_sell * data['收盘价(元)'].iloc[i] + capital += sell_price + stocks_held = 0 + trades += 1 + trades_tot += 1 + gains.append(sell_price - buy_price) + buy_price = 0 + + portfolio_value = capital + stocks_held * data['收盘价(元)'][i] + portfolio_values.append(portfolio_value) + + if stocks_held > 0: + num_shares_to_sell = stocks_held + capital += num_shares_to_sell * data['收盘价(元)'].iloc[len(data) - 1] + stocks_held = 0 + trades += 1 + trades_tot += 1 + gains.append(sell_price - buy_price) + + portfolio_value = capital + stocks_held * data['收盘价(元)'][len(data) - 1] + portfolio_values.append(portfolio_value) + + gains = np.array(gains) + profits = gains[gains > 0] + losses = gains[gains < 0] + + win_rate = len(profits) / trades if trades > 0 else 0 + avg_gain = np.mean(profits) if len(profits) > 0 else 0 + avg_loss = np.mean(losses) if len(losses) > 0 else 0 + odds_ratio = abs(avg_gain / avg_loss) if avg_loss != 0 else 0 + trade_frequency = trades_tot / len(data) if len(data) > 0 else 0 + + total_return = capital - initial_capital + annual_return = ((total_return / initial_capital) + 1) ** (252 / len(data)) - 1 + portfolio_values = np.array(portfolio_values) + + annual_risk_free_rate = 2.653 / 100 + + daily_risk_free_rate = (1 + annual_risk_free_rate) ** (1 / 252) - 1 + returns = np.diff(portfolio_values) / portfolio_values[:-1] + adjusted_returns = returns - daily_risk_free_rate + sharpe_ratio = (np.mean(adjusted_returns) / np.std(adjusted_returns) * np.sqrt(len(data)) + if np.std(adjusted_returns) != 0 else 0) + max_drawdown = np.max(np.maximum.accumulate(portfolio_values) - portfolio_values) / np.max( + portfolio_values) if np.max(portfolio_values) > 0 else 0 + + print({ + "name": base_name, + "parameter": best_solution, + "win_rate": win_rate, + "odds_ratio": odds_ratio, + "trade_frequency": trade_frequency, + "total_return": total_return, + "annual_return": annual_return, + "sharpe_ratio": sharpe_ratio, + "max_drawdown": max_drawdown, + }) + ans.append({ + "name": base_name, + "parameter": best_solution, + "win_rate": win_rate, + "odds_ratio": odds_ratio, + "trade_frequency": trade_frequency, + "total_return": total_return, + "annual_return": annual_return, + "sharpe_ratio": sharpe_ratio, + "max_drawdown": max_drawdown, + }) +ansdf = pd.DataFrame(ans) + +file_path = "x4.xlsx" +ansdf.to_excel(file_path, index=False) \ No newline at end of file diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/end_2_draw.py b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/end_2_draw.py new file mode 100644 index 00000000..d9f9894d --- /dev/null +++ b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/end_2_draw.py @@ -0,0 +1,195 @@ +import os +import numpy as np +import pandas as pd +import matplotlib.pyplot as plt +import pywt + +def find_local_extrema(data, window, greater=True): + special_indices = [] + for i in range(window + 1, len(data)): + window_data = data[i-window-1:i] + if greater: + if data[i-1] == window_data.max() and data[i] < data[i-1]: + special_indices.append(i-1) + else: + if data[i-1] == window_data.min() and data[i] > data[i-1]: + special_indices.append(i-1) + + return np.array(special_indices) + +file_path = './data/510300.SH.xlsx' +data = pd.read_excel(file_path) +data = data.iloc[:500] + +ema_short = data['收盘价(元)'].ewm(span=9, adjust=False).mean() +ema_long = data['收盘价(元)'].ewm(span=22, adjust=False).mean() +dif = ema_short - ema_long +dea = dif.ewm(span=25, adjust=False).mean() +macd_histogram = dif - dea +coeffs = pywt.wavedec(dif.values, 'coif5', level=4) + +approximation = coeffs[0] + +reconstructed_signal = pywt.waverec([approximation] + [np.zeros_like(coeff) for coeff in coeffs[1:]], 'coif5') +if len(reconstructed_signal) != len(dif): + reconstructed_signal = reconstructed_signal[:len(dif)] +reconstructed_dif = pd.Series(reconstructed_signal, index=dif.index) + +data['DIF'] = reconstructed_dif +data['DEA'] = dea +data['MACD'] = macd_histogram + +buy_signals = (data['DIF'] > data['MACD']) & (data['DIF'].shift(1) <= data['MACD'].shift(1)) +sell_signals = (data['DIF'] < data['MACD']) & (data['DIF'].shift(1) >= data['MACD'].shift(1)) + +order = 15 + +price_max_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=True) +price_min_idx = find_local_extrema(data['收盘价(元)'], window=order, greater=False) +macd_max_idx = find_local_extrema(data['MACD'], window=order, greater=True) +macd_min_idx = find_local_extrema(data['MACD'], window=order, greater=False) + +data['price_max'] = pd.Series(data['收盘价(元)'].iloc[price_max_idx].values, index=price_max_idx) +data['price_min'] = pd.Series(data['收盘价(元)'].iloc[price_min_idx].values, index=price_min_idx) +data['macd_max'] = pd.Series(data['MACD'].iloc[macd_max_idx].values, index=macd_max_idx) +data['macd_min'] = pd.Series(data['MACD'].iloc[macd_min_idx].values, index=macd_min_idx) + +data['bull_divergence'] = False +data['bear_divergence'] = False + +for i in range(1, len(price_max_idx)): + current_idx = price_max_idx[i] + previous_idx = price_max_idx[i-1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + +for i in range(1, len(macd_max_idx)): + current_idx = macd_max_idx[i] + previous_idx = macd_max_idx[i-1] + + if data['收盘价(元)'].iloc[current_idx] > data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] < data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bull_divergence'] = True + +for i in range(1, len(price_min_idx)): + current_idx = price_min_idx[i] + previous_idx = price_min_idx[i-1] + + if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] > data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + +for i in range(1, len(macd_min_idx)): + current_idx = macd_min_idx[i] + previous_idx = macd_min_idx[i-1] + +if data['收盘价(元)'].iloc[current_idx] < data['收盘价(元)'].iloc[previous_idx] and data['MACD'].iloc[current_idx] > data['MACD'].iloc[previous_idx]: + data.loc[current_idx, 'bear_divergence'] = True + +red_bar = np.where(macd_histogram > 0, macd_histogram, 0) +blue_bar = np.where(macd_histogram < 0, macd_histogram, 0) +fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10)) + +# 绘制牛背离点 +bull_divergence_points = data['日期'][data['bull_divergence']] +bull_divergence_prices = data['收盘价(元)'][data['bull_divergence']] +ax1.plot(bull_divergence_points, bull_divergence_prices, 'v', markersize=10, color='red', lw=0) + +# 绘制熊背离点 +bear_divergence_points = data['日期'][data['bear_divergence']] +bear_divergence_prices = data['收盘价(元)'][data['bear_divergence']] +ax1.plot(bear_divergence_points, bear_divergence_prices, '^', markersize=10, color='green', lw=0) + +ax1.plot(data['日期'], data['收盘价(元)'], label='Close Price', color='blue') +ax1.plot(data['日期'][buy_signals], data['收盘价(元)'][buy_signals], '^', markersize=10, color='green', lw=0, label='Buy Signal') +ax1.plot(data['日期'][sell_signals], data['收盘价(元)'][sell_signals], 'v', markersize=10, color='red', lw=0, label='Sell Signal') +ax1.set_title('9-22-25 Close Price and Trade Signals') +ax1.set_ylabel('Price') +ax1.legend() + +ax2.plot(data['日期'], data['DIF'], label='DIF') +ax2.plot(data['日期'], data['DEA'], label='DEA') +ax2.bar(data['日期'], red_bar, color="red") +ax2.bar(data['日期'], blue_bar, color="blue") +ax2.set_title('9-22-25 MACD Indicator') +ax2.set_ylabel('Value') +ax2.legend() + +plt.show() + + +initial_capital = 500000.0 +capital = initial_capital +stocks_held = 0 +portfolio_values = [] + +trades_tot = 0 +buy_price = 0 +trades = 0 +gains = [] +for i in range(len(data) - 1): + if (buy_signals.iloc[i] or data['bear_divergence'][i]) and capital > 0: + num_shares_to_buy = capital // data['收盘价(元)'].iloc[i] + buy_price += num_shares_to_buy * data['收盘价(元)'].iloc[i] + capital -= num_shares_to_buy * data['收盘价(元)'].iloc[i] + stocks_held += num_shares_to_buy + trades_tot += 1 + + elif (sell_signals.iloc[i] or data['bull_divergence'][i]) and stocks_held > 0: + num_shares_to_sell = stocks_held + sell_price = num_shares_to_sell * data['收盘价(元)'].iloc[i] + capital += sell_price + stocks_held = 0 + trades += 1 + trades_tot += 1 + gains.append(sell_price - buy_price) + buy_price = 0 + + portfolio_value = capital + stocks_held * data['收盘价(元)'][i] + portfolio_values.append(portfolio_value) + +if stocks_held > 0: + num_shares_to_sell = stocks_held + capital += num_shares_to_sell * data['收盘价(元)'].iloc[len(data)-1] + stocks_held = 0 + trades += 1 + trades_tot += 1 + gains.append(sell_price - buy_price) + +portfolio_value = capital + stocks_held * data['收盘价(元)'][len(data)-1] +portfolio_values.append(portfolio_value) + +gains = np.array(gains) +profits = gains[gains > 0] +losses = gains[gains < 0] + +win_rate = len(profits) / trades if trades > 0 else 0 +avg_gain = np.mean(profits) if len(profits) > 0 else 0 +avg_loss = np.mean(losses) if len(losses) > 0 else 0 +odds_ratio = abs(avg_gain / avg_loss) if avg_loss != 0 else 0 +trade_frequency = trades_tot / len(data) if len(data) > 0 else 0 + +total_return = capital - initial_capital +annual_return = ((total_return / initial_capital) + 1) ** (252 / len(data)) - 1 +portfolio_values = np.array(portfolio_values) + +# 假设的无风险年化回报率 +annual_risk_free_rate = 2.653 / 100 + +# 将年化无风险回报率转换为日无风险回报率 +daily_risk_free_rate = (1 + annual_risk_free_rate) ** (1/252) - 1 +returns = np.diff(portfolio_values) / portfolio_values[:-1] +adjusted_returns = returns - daily_risk_free_rate +sharpe_ratio = (np.mean(adjusted_returns) / np.std(adjusted_returns) * np.sqrt(len(data)) + if np.std(adjusted_returns) != 0 else 0) +max_drawdown = np.max(np.maximum.accumulate(portfolio_values) - portfolio_values) / np.max(portfolio_values) if np.max(portfolio_values) > 0 else 0 + +print({ + "name": "AL.SHF", + "win_rate": win_rate, + "odds_ratio": odds_ratio, + "trade_frequency": trade_frequency, + "total_return": total_return, + "annual_return": annual_return, + "sharpe_ratio": sharpe_ratio, + "max_drawdown": max_drawdown, +}) \ No newline at end of file diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/little_wave.py b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/little_wave.py new file mode 100644 index 00000000..38af00a9 --- /dev/null +++ b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/little_wave.py @@ -0,0 +1,122 @@ +import os +import numpy as np +import pywt +import pandas as pd +import matplotlib.pyplot as plt + +folder_path = 'data' +ans = [] +for file in os.listdir(folder_path): + if file.endswith('.xlsx'): + file_path = os.path.join(folder_path, file) + data = pd.read_excel(file_path) + data = data.iloc[:-2] + base_name, _ = os.path.splitext(file) + + ema_short = data['收盘价(元)'].ewm(span=12, adjust=False).mean() + ema_long = data['收盘价(元)'].ewm(span=26, adjust=False).mean() + dif = ema_short - ema_long + dea = dif.ewm(span=9, adjust=False).mean() + macd_histogram = dif - dea + + coeffs = pywt.wavedec(dif.values, 'coif5', level=4) + + approximation = coeffs[0] + + reconstructed_signal = pywt.waverec([approximation] + [np.zeros_like(coeff) for coeff in coeffs[1:]], 'coif5') + if len(reconstructed_signal) != len(dif): + reconstructed_signal = reconstructed_signal[:len(dif)] + + reconstructed_dif = pd.Series(reconstructed_signal, index=dif.index) + + data['DIF'] = reconstructed_dif + data['DEA'] = dea + data['MACD'] = macd_histogram + red_bar = np.where(macd_histogram > 0, macd_histogram, 0) + blue_bar = np.where(macd_histogram < 0, macd_histogram, 0) + + buy_signals = (data['DIF'] > data['MACD']) & (data['DIF'].shift(1) <= data['MACD'].shift(1)) + sell_signals = (data['DIF'] < data['MACD']) & (data['DIF'].shift(1) >= data['MACD'].shift(1)) + + initial_capital = 500000.0 + capital = initial_capital + stocks_held = 0 + portfolio_values = [] + + trades_tot = 0 + buy_price = 0 + trades = 0 + gains = [] + buy_queue = [] + for i in range(len(data) - 1): + if buy_signals.iloc[i] and capital > 0: + num_shares_to_buy = capital // data['收盘价(元)'].iloc[i] + buy_price += num_shares_to_buy * data['收盘价(元)'].iloc[i] + capital -= num_shares_to_buy * data['收盘价(元)'].iloc[i] + stocks_held += num_shares_to_buy + trades_tot += 1 + + elif sell_signals.iloc[i] and stocks_held > 0: + num_shares_to_sell = stocks_held + sell_price = num_shares_to_sell * data['收盘价(元)'].iloc[i] + capital += sell_price + stocks_held = 0 + trades += 1 + trades_tot += 1 + gains.append(sell_price - buy_price) + buy_price = 0 + + portfolio_value = capital + stocks_held * data['收盘价(元)'][i] + portfolio_values.append(portfolio_value) + + if stocks_held > 0: + num_shares_to_sell = stocks_held + capital += num_shares_to_sell * data['收盘价(元)'].iloc[len(data)-1] + stocks_held = 0 + trades += 1 + trades_tot += 1 + gains.append(sell_price - buy_price) + + portfolio_value = capital + stocks_held * data['收盘价(元)'][len(data)-1] + portfolio_values.append(portfolio_value) + + + gains = np.array(gains) + profits = gains[gains > 0] + losses = gains[gains < 0] + + win_rate = len(profits) / trades if trades > 0 else 0 + avg_gain = np.mean(profits) if len(profits) > 0 else 0 + avg_loss = np.mean(losses) if len(losses) > 0 else 0 + odds_ratio = abs(avg_gain / avg_loss) if avg_loss != 0 else 0 + trade_frequency = trades_tot / len(data) if len(data) > 0 else 0 + + total_return = capital - initial_capital + annual_return = ((total_return / initial_capital) + 1) ** (252 / len(data)) - 1 + portfolio_values = np.array(portfolio_values) + + annual_risk_free_rate = 2.653 / 100 + + daily_risk_free_rate = (1 + annual_risk_free_rate) ** (1/252) - 1 + returns = np.diff(portfolio_values) / portfolio_values[:-1] + adjusted_returns = returns - daily_risk_free_rate + sharpe_ratio = (np.mean(adjusted_returns) / np.std(adjusted_returns) * np.sqrt(len(data)) + if np.std(adjusted_returns) != 0 else 0) + max_drawdown = np.max(np.maximum.accumulate(portfolio_values) - portfolio_values) / np.max(portfolio_values) if np.max(portfolio_values) > 0 else 0 + + ans.append({ + "name": base_name, + "type": "reconstructed_dif", + "win_rate": win_rate, + "odds_ratio": odds_ratio, + "trade_frequency": trade_frequency, + "total_return": total_return, + "annual_return": annual_return, + "sharpe_ratio": sharpe_ratio, + "max_drawdown": max_drawdown, + }) + +ansdf = pd.DataFrame(ans) + +file_path = "x2.xlsx" +ansdf.to_excel(file_path, index=False) diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/raw_draw.py b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/raw_draw.py new file mode 100644 index 00000000..c4ad0b9c --- /dev/null +++ b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/raw_draw.py @@ -0,0 +1,43 @@ +import numpy as np +import pandas as pd + +file_path = './data/NR.INE.xlsx' +data = pd.read_excel(file_path) +data = data.iloc[:-2] + +import matplotlib.pyplot as plt + +ema_short = data['收盘价(元)'].ewm(span=12, adjust=False).mean() +ema_long = data['收盘价(元)'].ewm(span=26, adjust=False).mean() +dif = ema_short - ema_long +dea = dif.ewm(span=9, adjust=False).mean() +macd_histogram = dif - dea + +data['DIF'] = dif +data['DEA'] = dea +data['MACD'] = macd_histogram +red_bar = np.where(macd_histogram > 0, macd_histogram, 0) +blue_bar = np.where(macd_histogram < 0, macd_histogram, 0) + +buy_signals = (data['DIF'] > data['MACD']) & (data['DIF'].shift(1) <= data['MACD'].shift(1)) +sell_signals = (data['DIF'] < data['MACD']) & (data['DIF'].shift(1) >= data['MACD'].shift(1)) + + +fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10)) + +ax1.plot(data['日期'], data['收盘价(元)'], label='Close Price', color='blue') +ax1.plot(data['日期'][buy_signals], data['收盘价(元)'][buy_signals], '^', markersize=10, color='green', lw=0, label='Buy Signal') +ax1.plot(data['日期'][sell_signals], data['收盘价(元)'][sell_signals], 'v', markersize=10, color='red', lw=0, label='Sell Signal') +ax1.set_title('Close Price and Trade Signals') +ax1.set_ylabel('Price') +ax1.legend() + +ax2.plot(data['日期'], data['DIF'], label='DIF') +ax2.plot(data['日期'], data['DEA'], label='DEA') +ax2.bar(data['日期'], red_bar, color="red") +ax2.bar(data['日期'], blue_bar, color="blue") +ax2.set_title('MACD Indicator') +ax2.set_ylabel('Value') +ax2.legend() + +plt.show() diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/readme.md b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/readme.md new file mode 100644 index 00000000..6937ce04 --- /dev/null +++ b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/readme.md @@ -0,0 +1,341 @@ +# 项目名称:基于MACD指标的交易策略分析与回测 + +## 代码功能解释 +raw_draw.py 为MACD买入卖出图 +little_wave.py 为小波分析结果 +divergence.py 为背离分析结果 +end_1.py 为小波分析和背离分析 +end2_mindspore.py 为遗传算法测定买入点 +end_2_draw.py 为遗传算法测定买入点最终结果的画图程序 +trading_strategies.xlsx 为小波分析和背离分析的运行结果 +x1.xlsx 为原始策略交易量化指标 +x2.xlsx 为小波分析后交易量化指标 +x3.xlsx 为背离分析后交易量化指标 + +## 项目简介 +本项目旨在通过分析MACD指标(移动平均收敛散度)来构建一个简单的交易策略,并使用历史数据进行回测。项目结合了技术分析中的MACD指标、小波变换(Wavelet Transform)以及MindSpore框架,对股票价格数据进行分析,生成买卖信号,并计算策略的表现指标。 + +## 主要功能 +1. **数据加载与预处理**:从Excel文件中加载股票价格数据,并进行简单的预处理。 +2. **小波变换**:对DIF信号进行小波变换,提取近似信号以平滑数据。 +3. **MACD指标计算**:计算短期和长期的指数移动平均线(EMA),并生成MACD指标(DIF、DEA、MACD柱状图)。 +4. **买卖信号生成**:基于MACD指标生成买卖信号,并结合局部极值点检测技术识别牛市和熊市背离信号。 +5. **遗传算法计算个股最优参数**:在MindSpore计算框架的基础上加快遗传算法的计算速度得出个股最优的MACD相关参数,提高指标个股适应性。 +6. **策略回测**:根据生成的买卖信号进行回测,计算策略的收益率、胜率、夏普比率等关键指标。 +7. **可视化**:绘制股票价格、MACD指标、买卖信号以及背离信号的图表。 + +## 依赖库 +- `numpy` +- `pandas` +- `matplotlib` +- `pywt` +- `mindspore` + +**安装依赖库**: +确保已安装所需的Python库。可以通过以下命令安装: +```bash +pip install -r requirements.txt +``` + +## 文件结构 +- `data/510300.SH.xlsx`:包含股票价格数据的Excel文件。 +- `end2_mindspore.py`:主程序文件,包含数据加载、指标计算、信号生成、回测和可视化代码。 + +## 使用方法 +1. **准备数据**: + 将股票价格数据保存为Excel文件,并放置在`data/`目录下。文件应包含至少以下列: + - `日期`:日期列。 + - `收盘价(元)`:股票收盘价。 + +2. **运行代码**: + 运行`end2_mindspore.py`文件,程序将自动加载数据、计算指标、生成买卖信号并进行回测。最终结果将显示在图表中,并打印出策略的表现指标。 + + ```bash + python end2_mindspore.py + ``` + +3. **查看结果**: + - 图表将展示股票价格、MACD指标、买卖信号以及背离信号。 + - 控制台将输出策略的表现指标,包括胜率、总收益、年化收益、夏普比率等。 + +## 关键代码说明 +- **MACD指标计算**: + ```python + ema_short = data['收盘价(元)'].ewm(span=9, adjust=False).mean() + ema_long = data['收盘价(元)'].ewm(span=22, adjust=False).mean() + dif = ema_short - ema_long + dea = dif.ewm(span=25, adjust=False).mean() + macd_histogram = dif - dea + ``` + +- **小波变换**: + ```python + coeffs = pywt.wavedec(dif.asnumpy(), 'coif5', level=4) + approximation = coeffs[0] + reconstructed_signal = pywt.waverec([approximation] + [np.zeros_like(coeff) for coeff in coeffs[1:]], 'coif5') + ``` + +- **买卖信号生成**: + ```python + buy_signals = (data['DIF'] > data['MACD']) & (data['DIF'].shift(1) <= data['MACD'].shift(1)) + sell_signals = (data['DIF'] < data['MACD']) & (data['DIF'].shift(1) >= data['MACD'].shift(1)) + ``` + +- **遗传算法实现**: +在`end2_mindspore.py`中,我们使用MindSpore框架实现了遗传算法,用于优化MACD指标的参数,以找到最佳的买入点。以下是遗传算法的关键步骤: + +1. **种群初始化**: + - 根据参数范围初始化种群,生成随机的个体。 + +2. **适应度计算**: + - 计算每个个体的适应度值,即其对应参数下的交易策略的总收益。 + +3. **选择操作**: + - 采用精英保留策略和基于适应度的概率选择,保留优秀个体并选择下一代个体。 + +4. **交叉操作**: + - 随机选择交叉点,交换两个个体的部分基因。 + +5. **变异操作**: + - 以一定的概率随机改变个体的某个基因,增加种群的多样性。 + +6. **进化过程**: + - 每一代进行适应度评估、选择、交叉和变异操作,逐步进化种群,寻找最优解。 + +- **策略回测**: + ```python + for i in range(len(data) - 1): + if (buy_signals.iloc[i] or data['bear_divergence'][i]) and capital > 0: + # 买入逻辑 + elif (sell_signals.iloc[i] or data['bull_divergence'][i]) and stocks_held > 0: + # 卖出逻辑 + ``` + +## 输出结果 +- **图表**: + - 股票价格与买卖信号图。 + - MACD指标图,包含DIF、DEA以及MACD柱状图。 +- **策略表现指标**: + - 胜率(Win Rate) + - 盈亏比(Odds Ratio) + - 交易频率(Trade Frequency) + - 总收益(Total Return) + - 年化收益(Annual Return) + - 夏普比率(Sharpe Ratio) + - 最大回撤(Max Drawdown) + +## 注意事项 +- 本项目使用的数据为历史数据,回测结果仅供参考,实际交易中可能存在滑点、手续费等因素,需谨慎使用。 +- 代码中的参数(如EMA的周期、小波变换的类型等)可以根据实际需求进行调整。 + +## 未来改进 +- 增加更多的技术指标(如RSI、布林带等)来优化策略。 +- 引入机器学习模型来预测买卖信号。 +- 考虑交易成本、滑点等实际交易中的因素。 + +## 许可证 +本项目采用MIT许可证。详情请参阅LICENSE文件。 + +## **MindSpore 的核心功能** +在本项目中,MindSpore 主要用于以下两个部分: + +### 2.1 **数据转换为 MindSpore Tensor** +MindSpore 的核心数据结构是 `Tensor`,它类似于 NumPy 的 `ndarray`,但支持更高效的数值计算和自动微分。项目中通过 `ms.Tensor` 将 Pandas DataFrame 中的数据转换为 MindSpore Tensor。 + +```python +import mindspore as ms + +# 示例:将 Pandas Series 转换为 MindSpore Tensor +data_tensor = ms.Tensor(data.values) +``` + +- **输入**:Pandas Series 或 DataFrame 中的数据。 +- **输出**:MindSpore Tensor 格式的数据。 +- **作用**:将 MACD 指标(DIF、DEA、MACD 柱状图)以及股票价格数据转换为 MindSpore Tensor,以便后续计算。 + +### 2.2 **使用 MindSpore 进行数值计算** +在项目中,MindSpore 的 `mnp` 模块(MindSpore NumPy)被用于一些数值计算任务。例如,计算 MACD 指标中的红色和蓝色部分: + +```python +import mindspore.numpy as mnp + +red_bar = mnp.where(macd_histogram > 0, macd_histogram, 0) +blue_bar = mnp.where(macd_histogram < 0, macd_histogram, 0) +``` + +- **`mnp.where`**:类似于 NumPy 的 `np.where`,用于条件筛选。 +- **作用**:将 MACD 柱状图分为红色(正值)和蓝色(负值)两部分,便于后续可视化。 + +### 2.3 **遗传算法中的 MindSpore 应用** +在遗传算法的实现中,MindSpore 提供了强大的支持,主要体现在以下几个方面: + +#### 2.3.1 **种群初始化** +```python +low_bounds_np = low_bounds.asnumpy() +high_bounds_np = high_bounds.asnumpy() +temp_pop = [] +for i in range(num_variables): + col = ms_np.randint(int(low_bounds_np[i]), int(high_bounds_np[i]), (num_individuals,)) + temp_pop.append(col) +population = ops.stack(temp_pop, axis=1) +``` + +- **输入**:参数范围(`bounds`)。 +- **输出**:初始化的种群(`population`)。 +- **作用**:根据参数范围随机生成初始种群,为后续的遗传操作提供基础。 + +#### 2.3.2 **适应度计算** +```python +def evaluate_population(pop): + pop_np = pop.asnumpy() + fitness_vals = [fitness_func(subset_data1, ind) for ind in pop_np] + return Tensor(fitness_vals, dtype=ms.float32) +``` + +- **输入**:种群(`pop`)。 +- **输出**:每个个体的适应度值(`fitness_vals`)。 +- **作用**:计算每个个体的适应度值,即其对应参数下的交易策略的总收益。 + +#### 2.3.3 **选择操作** +```python +def select(population, fitness): + elite_indices = ops.argsort(fitness)[-elite_size:] + elite = ops.gather(population, elite_indices, 0) + max_fitness = ops.reduce_max(fitness) + exp_values = ops.exp(fitness - max_fitness) + prob = exp_values / ops.reduce_sum(exp_values) + chosen_indices_np = np.random.choice(np.arange(num_individuals), size=num_individuals - elite_size, replace=True, p=prob.asnumpy()) + chosen_indices = Tensor(chosen_indices_np, dtype=ms.int32) + chosen = ops.gather(population, chosen_indices, 0) + return ops.concat((chosen, elite), 0) +``` + +- **输入**:种群(`population`)和适应度值(`fitness`)。 +- **输出**:选择后的种群(`selected`)。 +- **作用**:采用精英保留策略和基于适应度的概率选择,保留优秀个体并选择下一代个体。 + +#### 2.3.4 **交叉操作** +```python +if ms_np.rand() < crossover_rate: + point = np.random.randint(1, num_variables) + seg1 = new_population[i, point:].copy() + new_population[i, point:] = new_population[i + 1, point:] + new_population[i + 1, point:] = seg1 +``` + +- **输入**:当前种群(`new_population`)。 +- **输出**:交叉后的种群。 +- **作用**:随机选择交叉点,交换两个个体的部分基因,增加种群的多样性。 + +#### 2.3.5 **变异操作** +```python +def mutate(individual, mutation_rate, bounds): + for i in range(len(bounds)): + if ms_np.rand() < mutation_rate: + individual[i] = ms_np.randint(bounds[i][0], bounds[i][1] + 1) + return individual +``` + +- **输入**:个体(`individual`)、变异率(`mutation_rate`)和参数范围(`bounds`)。 +- **输出**:变异后的个体。 +- **作用**:以一定的概率随机改变个体的某个基因,增加种群的多样性。 + +#### 2.3.6 **进化过程** +```python +for generation in range(num_generations): + fitness = evaluate_population(population) + best_index_tensor = ops.argmax(fitness) + best_index = int(best_index_tensor.asnumpy()) + max_fitness_tensor = ops.reduce_max(fitness) + max_fitness_val = float(max_fitness_tensor.asnumpy()) + best_fitness_history.append(max_fitness_val) + + if max_stagnant_generations: + if len(best_fitness_history) > 1 and (best_fitness_history[-1] - best_fitness_history[-2] < 1e-5): + stagnant_counter += 1 + else: + stagnant_counter = 0 + if stagnant_counter >= max_stagnant_generations: + print(f"Progress stagnant for {max_stagnant_generations} generations at generation {generation}") + break + + selected = select(population, fitness) + new_population = selected.copy() + + for i in range(0, num_individuals - elite_size, 2): + if ms_np.rand() < crossover_rate: + point = np.random.randint(1, num_variables) + seg1 = new_population[i, point:].copy() + new_population[i, point:] = new_population[i + 1, point:] + new_population[i + 1, point:] = seg1 + new_population[i] = mutate(new_population[i], mutation_rate, bounds) + new_population[i + 1] = mutate(new_population[i + 1], mutation_rate, bounds) + + population = new_population + print(f"Generation {generation}: Max Fitness = {max_fitness_tensor}") +``` + +- **输入**:初始种群(`population`)。 +- **输出**:进化后的最优个体(`best_solution`)和最大适应度值(`max_fitness`)。 +- **作用**:每一代进行适应度评估、选择、交叉和变异操作,逐步进化种群,寻找最优解。 + +--- + +## **MindSpore 的优势** +在本项目中使用 MindSpore 的主要优势包括: + +1. **高效计算**: + - MindSpore Tensor 支持高效的数值计算,尤其是在大规模数据集上表现优异。 + - 与 NumPy 相比,MindSpore 的计算速度更快,尤其是在 GPU 或 Ascend 硬件上。 + +2. **自动微分**: + - 虽然本项目未涉及深度学习模型,但 MindSpore 的自动微分功能为未来扩展(如引入神经网络模型)提供了便利。 + +3. **跨平台支持**: + - MindSpore 支持 CPU、GPU 和 Ascend 等多种硬件平台,便于在不同环境中运行代码。 + +--- + +## **MindSpore 的扩展性** +如果需要进一步扩展本项目,可以利用 MindSpore 的以下功能: + +1. **引入神经网络模型**: + - 使用 MindSpore 构建深度学习模型,预测股票价格或生成买卖信号。 + - 示例代码: + ```python + import mindspore.nn as nn + + class StockPredictionModel(nn.Cell): + def __init__(self): + super(StockPredictionModel, self).__init__() + self.fc1 = nn.Dense(10, 64) + self.fc2 = nn.Dense(64, 1) + + def construct(self, x): + x = self.fc1(x) + x = self.fc2(x) + return x + ``` + +2. **优化计算性能**: + - 使用 MindSpore 的图模式(Graph Mode)加速计算。 + - 示例代码: + ```python + ms.set_context(mode=ms.GRAPH_MODE, device_target="GPU") + ``` + +3. **分布式训练**: + - 如果需要处理更大规模的数据,可以使用 MindSpore 的分布式训练功能。 + +--- + +## **注意事项** +- **硬件支持**:确保运行环境支持 MindSpore(如安装正确版本的 CUDA 或 Ascend 驱动)。 +- **数据格式**:MindSpore Tensor 与 NumPy 数组可以互相转换,但需要注意数据类型的兼容性。 +- **性能调优**:对于大规模数据,建议使用 MindSpore 的图模式或 GPU 加速。 + +--- + +## **参考文档** +- [MindSpore 官方文档](https://www.mindspore.cn/docs) +- [MindSpore GitHub 仓库](https://github.com/mindspore-ai/mindspore) \ No newline at end of file diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/requirements.txt b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/requirements.txt new file mode 100644 index 00000000..2a7e0c1e --- /dev/null +++ b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/requirements.txt @@ -0,0 +1,6 @@ +matplotlib==3.8.0 +mindspore==2.4.10 +numpy==2.2.2 +pandas==2.2.3 +scipy==1.11.4 +~atplotlib==3.8.0 diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/trading_strategies.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/trading_strategies.xlsx new file mode 100644 index 00000000..aa95cfa2 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/trading_strategies.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/x1.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/x1.xlsx new file mode 100644 index 00000000..af849d4a Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/x1.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/x2.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/x2.xlsx new file mode 100644 index 00000000..2acde4ac Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/x2.xlsx differ diff --git a/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/x3.xlsx b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/x3.xlsx new file mode 100644 index 00000000..d680f914 Binary files /dev/null and b/research/arxiv_papers/Optimizing_MACD_Trading_Strategies_A_Dance_of_Finance_Wavelets_and_Genetics/x3.xlsx differ