量化交易 實戰之迴歸法選股 part 2

專注的阿熊發表於2021-03-29

# 可以自己 import 我們平臺支援的第三方 python 模組,比如 pandas numpy 等。

import numpy as np

import pandas as pd

from sklearn.linear_model import LinearRegression

# 在這個方法中編寫任何的初始化邏輯。 context 物件將會在你的演算法策略的任何方法之間做傳遞。

def init(context):

    # 初始化股票因子權重

    context.weights = np.array([0.04549957, 0.01249463, -0.02397849, 0.06077185, -0.00195205, -0.00892116, -0.04641399, -0.05644752, -0.08393869])

    # 定義股票池數量

    context.stocknum = 20

    # 定時每月執行函式

    scheduler.run_monthly(regression_select, tradingday=1)

def regression_select(context, bar_dict):

    """ 迴歸預測選股邏輯 """

    # 獲取滬深 300

    context.hs300 = index_components("000300.XSHG")

    # 1. 查詢因子

    q = query(

        fundamentals.eod_derivative_indicator.pe_ratio,

        fundamentals.eod_derivative_indicator.pb_ratio,

        fundamentals.eod_derivative_indicator.market_cap,

        fundamentals.financial_indicator.ev,

        fundamentals.financial_indicator.return_on_asset_net_profit,

        fundamentals.financial_indicator.du_return_on_equity,

        fundamentals.financial_indicator.earnings_per_share,

        fundamentals.income_statement.revenue,

        fundamentals.income_statement.total_expense

        ).filter(

            fundamentals.stockcode.in_(context.hs300)

        )

    fund = get_fundamentals(q)

    context.factors_data = fund.T

    # 2. 資料預處理

    process_data(context)

    # 3. 根據每月預測下月的收益率

    select_stocklist(context)

    # 4. 調倉

    reblance(context)

def process_data(context):

    """ 刪除空值 , 去極值 , 標準化 , 因子的市值中性化 """

    # 刪除空值

    context.factors_data = context.factors_data.dropna()

    # 市值因子不進行去極值 , 標準化處理

    market_cap_factor = context.factors_data["market_cap"]

    # 去極值化 , U 型你換對每個因子進行處理

    for name in context.factors_data.columns:

        context.factors_data[name] = mad(context.factors_data[name])

        context.factors_data[name] = stand(context.factors_data[name])

        # 對因子 ( 除了市值因子 ) 中性化處理

        if name == "market_cap":

            continue

        # 建立迴歸方程 , 市值中性化

        lr = LinearRegression()

        x = market_cap_factor.values

        y = context.factors_data[name]

        # x: 要求二維 , y: 要求一維

        lr.fit(x.reshape(-1, 1), y)

        y_predict = lr.predict(x.reshape(-1, 1))

        # 得出誤差進行替換原有因子值

        context.factors_data[name] = y - y_predict

def select_stocklist(context):

    """ 迴歸計算預測得出收益率結果 , 篩選收益率高的股票 """

    # 特徵值是 : context.factors_Date (300, 9) 係數 : 因子權重

    # 進行矩陣運算外匯跟單gendan5.com  (300, 9) * (9, 1) = (300, 1)

    stock_return = np.dot(context.factors_data.values, context.weights)

    logger.info(stock_return)

    # 賦值給因子資料 , 注意都是預設對應的股票程式碼和收益率

    context.factors_data["stock_return"] = stock_return

    # 進行收益率排序

    ordered = context.factors_data.sort_values(by="stock_return", ascending=False)

    # 加入股票池

    context.stock_list = ordered.index[:context.stocknum]

def reblance(context):

    # ---------------- 賣出 ----------------

# 遍歷股票池

    for stock in context.portfolio.positions.keys():

        # 判斷是否還在股票池

        if stock not in context.stock_list:

            # 如果不在 , 賣出

            order_target_percent(stock, 0)

    # ---------------- 買入 -----------------

# 買入的百分比

    weight = 1.0 / len(context.stock_list)

    # 遍歷股票池

    for stock in context.stock_list:

        # 等比例買入

        order_target_percent(stock, weight)

# before_trading 此函式會在每天策略交易開始前被呼叫,當天只會被呼叫一次

def before_trading(context):

    pass

# 你選擇的證券的資料更新將會觸發此段邏輯,例如日或分鐘歷史資料切片或者是實時資料切片更新

def handle_bar(context, bar_dict):

    # 開始編寫你的主要的演算法邏輯

    pass

# after_trading 函式會在每天交易結束後被呼叫,當天只會被呼叫一次

def after_trading(context):

    pass

def mad(factor):

    """3 倍中位數去極值 """

    # 求出因子值的中位數

    median = np.median(factor)

    # 求出因子值與中位數的差值 , 進行絕對值

    mad = np.median(abs(factor - median))

    # 定義幾倍的中位數上下限

    high = median + (3 * 1.4826 * mad)

    low = median - (3 * 1.4826 * mad)

    # 替換上下限

    factor = np.where(factor > high, high, factor)

    factor = np.where(factor < low, low, factor)

    return factor

def stand(factor):

    """ 資料標準化 """

    mean = factor.mean()

    std = factor.std()

    return (factor - mean) / std

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946337/viewspace-2765536/,如需轉載,請註明出處,否則將追究法律責任。

相關文章