量化交易Python數據分析

基於python的量化交易分析

採用:

1. N日擇時策略+ATR風險控制

# N日擇時策略+ATR
def Nbreakstrategy(self,data,  N1, N2, n_win, n_loss):
    # N1天內最高價
    global start
    data['N1_high'] = data.High.rolling(window=N1).max()
    data['N1_high'] = data.N1_high.shift(1)
    max_val = data.Close.expanding().max()
    data['N1_high'].fillna(value=max_val, inplace=True)

    # N2天內最低價
    data['N2_low'] = data.Low.rolling(window=N2).min()
    data['N2_low'] = data.N2_low.shift(1)
    min_val = data.Close.expanding().min()
    data['N2_low'].fillna(value=min_val, inplace=True)


    # ATR止盈止損判斷
    buy_price = 0
    for k_index, today in data.iterrows():
        tick = round(today.Close * 0.01, 2)
        # 買入
        if (today.Close - tick) > today.N1_high:
            print('N day buy: {} {}'.format(k_index,today.Close))
            buy_price = today.Close
            data.loc[k_index, 'signal'] = 1
        # 止損,收盤價少於買入價,賣出
        elif (buy_price != 0) and (buy_price > today.Close + tick) and ((buy_price - today.Close - tick) > n_loss * today.atr14):
            #print('stop loss: {} {} {}'.format(k_index, today.Close, buy_price))
            data.loc[k_index, 'signal'] = 0
            buy_price = 0
        # 止盈:收盤價多於買入價,賣出
        elif (buy_price != 0) and (buy_price < today.Close - tick) and ((today.Close - buy_price + tick) > n_win * today.atr14):
            #print('stop win: {} {} {}'.format(k_index, today.Close, buy_price))
            data.loc[k_index, 'signal'] = 0
            buy_price = 0
        elif today.Close + tick < today.N2_low:
            #print('N day sell: {} {}'.format(k_index, today.Close))
            data.loc[k_index, 'signal'] = 0
            buy_price = 0
        else:
            pass

    # 買入 / 賣出信號list
    data['signal'].fillna(method='ffill', inplace = True)
    data['signal'] = data.signal.shift(1)
    data['signal'].fillna(method='bfill', inplace=True)

    for k_index, today in data.iterrows():
        # 買入/賣出 執行
        if today.signal == 1 and self.hold_state == 0: # 買入
            start = data.index.get_loc(k_index) # 區間開始日期
            self.hold_state = -1
            self.stock_num = int(self.init_money / today.Close) # 資金轉化爲股票
            # 倉位管理
            self.send_order(code=self.stock_code, amount=int(self.init_money * 0.01 / today.atr14),
                            price=today.Close, order_type='buy')
            self.init_money = 0

            self.graph_trade.annotate('買入',xy=(k_index,data.Close.asof(k_index)),
                                      xytext=(k_index,data.Close.asof(k_index)+2),
                                      arrowprops=dict(facecolor='r',shrink=0.1),
                                      horizontalalignment='left',verticalalignment='top')
        elif today.signal == 0 and self.hold_state == -1: # 賣出
            end = data.index.get_loc(k_index)
            # 手續費:印花稅1‰,手續費5元
            profit = self.stock_num * today.Close
            fee = profit * 0.0001 - 5
            self.init_money = round((profit - fee),1) # 股票轉化爲資金
            self.hold_state = 0
            self.market_value = 0
            # 倉位管理
            self.send_order(code=self.stock_code, amount=self.hold_available(code = "600410.SS"), price=today.Close, order_type='sell')

            if data.Close[end] < data.Close[start]:
                # 賠錢,綠色
                self.graph_trade.fill_between(data.index[start:end],0,
                                              data.Close[start:end],color='green',alpha=0.8)
            else:
                # 賺錢 紅色
                self.graph_trade.fill_between(data.index[start:end], 0,
                                              data.Close[start:end], color='red', alpha=0.8)

            self.graph_trade.annotate('賣出',xy=(k_index,data.Close.asof(k_index)),
                                      xytext=(k_index+datetime.timedelta(days=5),
                                              data.Close.asof(k_index)+2),
                                      arrowprops=dict(facecolor='g',shrink=0.1),
                                      horizontalalignment='left',verticalalignment='top')

        latest_val = self.latest_assets(today.Close)
        data.loc[k_index, 'total_position'] = latest_val
        if self.hold_state == -1: # 持股狀態
            self.market_value = int(self.stock_num * today.Close)
            data.loc[k_index, 'total'] = self.market_value
        else: # 空倉
            data.loc[k_index, 'total'] = self.init_money
    print('total value is {}'.format(data['total'][-1]))
    self.resultanalysis(data)
    return data['total'][-1] # 每次返回
複製代碼

2. 蒙特卡洛優化算法優化策略輸入參數

# 使用蒙特卡洛方法挑選出最優的N1,N2,止盈,止損點
# 25,5,2.3,0.7
def montcarlo(self,data, n):
    n1_min, n1_max = 10, 30
    n2_min, n2_max = 5, 15
    win_min, win_max = 1.5, 3
    loss_min, loss_max = 0.5, 1.2

    ma_ls = []
    profit_ls = []

    # 每次隨機生成一組N1,N2,止盈,止損倍數,循環N日擇時策略並把每次執行策略的最終資產存入數組
    # 最終獲得n次執行後,獲得最大資產的一組隨機數,做爲最優策略的輸入參數
    for i in range(0, n+1):
        n1 = int(random.uniform(n1_min,n1_max))
        n2 = int(random.uniform(n2_min, n2_max))
        win = round(random.uniform(win_min, win_max),1)
        loss = round(random.uniform(loss_min, loss_max),1)
        ma_ls.append([n1,n2,win,loss])
        # 策略代碼
        trade = QuantAnalysis()
        profit_ls.append(trade.Nbreakstrategy(data, n1, n2, win, loss))


    profit_max = max(profit_ls)
    ma_max = ma_ls[profit_ls.index(profit_max)]
    print("maximize the profit is %s and correspond parametes are %s " % (profit_max, ma_max))
    return ma_ls
複製代碼

3. 基於ATR的倉位管理

# 倉位管理
self.send_order(code=self.stock_code, amount=int(self.init_money * 0.01 / today.atr14),price=today.Close, order_type='buy')
self.send_order(code=self.stock_code, amount=self.hold_available(code = "600410.SS"), price=today.Close, order_type='sell')            
複製代碼

4. 滑點收盤價的1%

在每一次買入賣出,止盈止損的過程當中加入滑點值,讓結果沒那麼‘完美’,更符合實際的狀況。
複製代碼

5. 印花稅 1‰,手續費5元

在賣出時將印花稅,手續費加入
profit = self.stock_num * today.Close
fee = profit * 0.0001 - 5
複製代碼

6. 結果生成圖像:

a. 買賣區間圖
    b. 基準收益/策略收益對比圖
    c. 總資產圖(無策略的總資產+N日擇時策略下的總資產+倉位管理的總資產+最大總資產)
    
    無倉位管理,無手續費,通過蒙特卡洛篩選出最優N日擇時策略後的執行結果圖
複製代碼

增長倉位管理,增長手續費後的結果圖,能夠對比看出倉位管理的優點,總資產比不實施倉位管理要高了不少
複製代碼

從圖中能夠看出當買入點較高時,股票開始下跌,策略可以及時止損,本次策略使用的止損點爲0.7,賣出時可以較好的獲利,止盈點爲2.3。
    
    採用量化分析的方式,能夠對一隻股票的交易歷史有一個很好的分析,經過模擬策略來進行買賣,檢驗本身策略的好壞,可是有個疑問,怎麼樣可以經過策略來決定當下要是否要買這支股票呢?複製代碼
相關文章
相關標籤/搜索