秩序ある排列の多空の均衡権益戦略を実現

作者: リン・ハーン優しさ作成日:2019年8月24日 10:05:53 更新日:2023年10月19日 21:06:54

img

この記事の記事へのトラックバック (0)https://www.fmz.com/digest-topic/4187取引戦略の組み合わせについて説明し,データと数学分析を使用して取引戦略を作成し,自動化する方法を示しました.

多空均衡利害戦略は,バスケット取引指標に適用される配列取引戦略の自然な延長である.特に,デジタル通貨市場や商品先物市場などの多様な相互関連取引市場に適用される.

基本原則

多空平衡利害戦略は,多空と空空の両方を同時に行う.配列取引のように,どの投資標標が安価で,どの投資標が高価かを決定する.異なるのは,多空平衡利害戦略は,どの投資標が比較的安価か高価かを決定するために,すべての投資標を1つの選択のプールに並べる.そして,多空先のnの投資標の順位に基づいて,等価で空底のnの投資標の"多空の総額=ポジションの総額"を決定する.

配列取引は市場中立の戦略であると言ったのを覚えていますか? 多空均衡権益戦略も同様です. 多頭と空頭ポジションの等価は,戦略が市場中立性を維持することを保証します. この戦略は,統計的に安定しています. 投資標籤をランク付けして,複数のポジションを保持することで,あなたのランキングモデルに一度のリスクではなく,複数の投資を行うことができます. あなたは純粋にあなたのランキングプログラムの品質のみを賭けています.

ランキングとは何か?

ランキングスケジュールとは,各投資指標が予想されるパフォーマンスに基づいて優先順位を付けられるモデルである.その要因は,価値因子,技術指標,価格モデル,または上記のすべての要素の組み合わせである.例えば,動力指標を使用して,一連のトレンドを追跡する投資指標をランクインすることができます.最も動力のある投資指標が引き続き良好なパフォーマンスを示し,最も高いランクを獲得すると予想される.動力最小の投資は,最低のパフォーマンス,最低の収益率を持つ.

この戦略の成功は,ほぼ完全に使用されたランキング方式によって成り立っています.つまり,あなたのランキング方式は,高性能投資指標と低性能投資指標を分離し,多空投資指標の戦略の収益性をより良く実現します.したがって,ランキング方式を策定することは非常に重要です.

ランキングの仕組みは?

一旦ランキングを決定したら,明らかに利益を得たいのです.私たちは,同じ金額を投資して,多くのランキング先の投資株と,ランキング下部の投資株を空くします.これは,戦略がランキングの質に比例してしか儲からないことを保証し",市場中立"になります.

すべての投資指標mをランク付けしていると仮定し,nドル投資があり,合計2p (m>2p) のポジションを保持したいとします. ランク1の投資指標が最悪な見通しである場合,ランク1の投資指標mの見通しが最もよいでしょう:

  • 2pの$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2の$2は$2の$2の$2の$2です

  • 投資指数を m-p,...,m のような位置に並べて,n/2pドル以上の投資指数をします.

**注意: **価格跳びによる投資指標の価格が常にn/2pを均等に分割しないため,そして特定の投資指標を整数で購入しなければならないため,いくつかの不正確なアルゴリズムがあるため,アルゴリズムはこの数字にできるだけ近づくべきです.n = 100000とp = 500を実行する戦略については,以下のように見ることができます.

n/2p = 100000/1000 = 100

これは100以上の価格のスコア (例えば商品先物市場) で大きな問題になります. なぜなら,スコア価格のポジションを開くことができないからです (デジタル通貨市場には問題はありません).

仮説の例を見てみましょう.

  • 発明者の定量化プラットフォームで私たちの研究環境を構築します

まず,作業が順調に進むためには,私たちは研究環境を構築する必要があります.FMZ.COMこの研究環境は,このプラットフォームの便利なAPIと完全なDockerシステムをパッケージ化するために開発された.

発明者による量化プラットフォームの公式名称では,このDockerシステムはホストシステムと呼ばれています.

管理者やロボットの配備については,私の前の記事を参照してください.https://www.fmz.com/bbs-topic/4140

クラウドサーバーの展開管理者を購入したい人は,この記事を参照してください:https://www.fmz.com/bbs-topic/2848

Pythonの最大級の神社である Anaconda をインストールします. これは,Python の最大級の神社である Anaconda をインストールします.

本文に必要なすべての関連するプログラム環境 (依存庫,バージョン管理など) を実現するには,最も簡単な方法はAnacondaです.これはパッケージ化されたPythonデータサイエンスのエコシステムであり,依存庫管理者です.

アナコンダのインストール方法については,Anacondaの公式ガイドを参照してください.https://www.anaconda.com/distribution/

本文还将用到numpy和pandas这两个目前在Python科学计算方面十分流行且重要的库.

上記の基礎作業は, Anaconda 環境とnumpyとpandasの2つのライブラリをどのように設定するかについての私の前の記事にも参照できます.https://www.fmz.com/digest-topic/4169

ランダムな投資指標とランダムな因子を生成し,それらをランク付けします. 将来の収益が実際にこれらの因子値に依存していると仮定しましょう.

import numpy as np
import statsmodels.api as sm
import scipy.stats as stats
import scipy
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
## PROBLEM SETUP ##
# Generate stocks and a random factor value for them
stock_names = ['stock ' + str(x) for x in range(10000)]
current_factor_values = np.random.normal(0, 1, 10000)
# Generate future returns for these are dependent on our factor values
future_returns = current_factor_values + np.random.normal(0, 1, 10000)
# Put both the factor values and returns into one dataframe
data = pd.DataFrame(index = stock_names, columns=['Factor Value','Returns'])
data['Factor Value'] = current_factor_values
data['Returns'] = future_returns
# Take a look
data.head(10)

img

現在,因数値と収益性があるので,投資指標を因数値でランク付けすると,多頭と空頭がどうなるか見ることができます.

# Rank stocks
ranked_data = data.sort_values('Factor Value')
# Compute the returns of each basket with a basket size 500, so total (10000/500) baskets
number_of_baskets = int(10000/500)
basket_returns = np.zeros(number_of_baskets)
for i in range(number_of_baskets):
    start = i * 500
    end = i * 500 + 500 
    basket_returns[i] = ranked_data[start:end]['Returns'].mean()
# Plot the returns of each basket
plt.figure(figsize=(15,7))
plt.bar(range(number_of_baskets), basket_returns)
plt.ylabel('Returns')
plt.xlabel('Basket')
plt.legend(['Returns of Each Basket'])
plt.show()

img

この戦略の報酬は,バケット投資指標のプールの中で,一番多くランクインし,10番目で空いていることです.

basket_returns[number_of_baskets-1] - basket_returns[0]

答えは4.172でした.

ランキングモデルに金を注ぎ,低業績投資と高業績投資を区別できるようにします.

この記事の後半では,ランキング戦略の評価について説明します. ランキングベースの利息設定の利点は,市場混乱の影響を受けないが,それを利用できるということです.

リアルな世界の例を考えてみましょう.

S&P500の32の株のデータをダウンロードし,それらをランクインしようとしました.

from backtester.dataSource.yahoo_data_source import YahooStockDataSource
from datetime import datetime
startDateStr = '2010/01/01'
endDateStr = '2017/12/31'
cachedFolderName = '/Users/chandinijain/Auquan/yahooData/'
dataSetId = 'testLongShortTrading'
instrumentIds = ['ABT','AKS','AMGN','AMD','AXP','BK','BSX',
                'CMCSA','CVS','DIS','EA','EOG','GLW','HAL',
                'HD','LOW','KO','LLY','MCD','MET','NEM',
                'PEP','PG','M','SWN','T','TGT',
                'TWX','TXN','USB','VZ','WFC']
ds = YahooStockDataSource(cachedFolderName=cachedFolderName,
                            dataSetId=dataSetId,
                            instrumentIds=instrumentIds,
                            startDateStr=startDateStr,
                            endDateStr=endDateStr,
                            event='history')
price = 'adjClose'

標準的な運動量指標でランクインしましょう.

## Define normalized momentum
def momentum(dataDf, period):
    return dataDf.sub(dataDf.shift(period), fill_value=0) / dataDf.iloc[-1]
## Load relevant prices in a dataframe
data = ds.getBookDataByFeature()[‘Adj Close’]
#Let's load momentum score and returns into separate dataframes
index = data.index
mscores = pd.DataFrame(index=index,columns=assetList)
mscores = momentum(data, 30)
returns = pd.DataFrame(index=index,columns=assetList)
day = 30

今度は,私たちの株の行動を分析し,私たちの株が市場において,私たちが選んだランキング因子の中でどのように機能するか見てみましょう.

分析データ

株式の行動

選択したバスケットの株が,私たちのランキングモデルでどのように表現しているか見てみましょう. そのため,すべての株の1週間の長期回帰を計算しましょう. そして,それぞれの株の1週間前の回帰と,前30日の動向との関連を見ることができます. 傾向を追っていると陽性で関連している株は,平均的な回帰を示しています.

# Calculate Forward returns
forward_return_day = 5
returns = data.shift(-forward_return_day)/data -1
returns.dropna(inplace = True)
# Calculate correlations between momentum and returns
correlations = pd.DataFrame(index = returns.columns, columns = [‘Scores’, ‘pvalues’])
mscores = mscores[mscores.index.isin(returns.index)]
for i in correlations.index:
    score, pvalue = stats.spearmanr(mscores[i], returns[i])
    correlations[‘pvalues’].loc[i] = pvalue
    correlations[‘Scores’].loc[i] = score
correlations.dropna(inplace = True)
correlations.sort_values(‘Scores’, inplace=True)
l = correlations.index.size
plt.figure(figsize=(15,7))
plt.bar(range(1,1+l),correlations[‘Scores’])
plt.xlabel(‘Stocks’)
plt.xlim((1, l+1))
plt.xticks(range(1,1+l), correlations.index)
plt.legend([‘Correlation over All Data’])
plt.ylabel(‘Correlation between %s day Momentum Scores and %s-day forward returns by Stock’%(day,forward_return_day));
plt.show()

img

(明らかに,我々の選択した宇宙は,このように機能している) これは私たちに,もし株が動力分析で高い順位を上げているなら,来週は悪くなると予想すべきだと教えてくれます.

動力分析のスコア順位と利益の関連性

次に,私たちは,私たちのランキングスコアと市場全体の前向きな収益の関係,つまり,期待される収益率の予測が,私たちのランキング因子との関係,より高い関連度が,より悪い相対的な収益を予測するか,それともその逆か,を見なければなりません.

このために,すべての株の30日間の動力と1週間の長期的収益との日々の関連性を計算した.

correl_scores = pd.DataFrame(index = returns.index.intersection(mscores.index), columns = [‘Scores’, ‘pvalues’])
for i in correl_scores.index:
    score, pvalue = stats.spearmanr(mscores.loc[i], returns.loc[i])
    correl_scores[‘pvalues’].loc[i] = pvalue
    correl_scores[‘Scores’].loc[i] = score
correl_scores.dropna(inplace = True)
l = correl_scores.index.size
plt.figure(figsize=(15,7))
plt.bar(range(1,1+l),correl_scores[‘Scores’])
plt.hlines(np.mean(correl_scores[‘Scores’]), 1,l+1, colors=’r’, linestyles=’dashed’)
plt.xlabel(‘Day’)
plt.xlim((1, l+1))
plt.legend([‘Mean Correlation over All Data’, ‘Daily Rank Correlation’])
plt.ylabel(‘Rank correlation between %s day Momentum Scores and %s-day forward returns’%(day,forward_return_day));
plt.show()

img

日々の相関性は非常に騒々しく,しかし非常に微妙な表現である (これは予想される,すべての株が均等な回帰をすると言ったからです).また,1ヶ月前の平均的な月間相関性を見てみましょう.

monthly_mean_correl =correl_scores['Scores'].astype(float).resample('M').mean()
plt.figure(figsize=(15,7))
plt.bar(range(1,len(monthly_mean_correl)+1), monthly_mean_correl)
plt.hlines(np.mean(monthly_mean_correl), 1,len(monthly_mean_correl)+1, colors='r', linestyles='dashed')
plt.xlabel('Month')
plt.xlim((1, len(monthly_mean_correl)+1))
plt.legend(['Mean Correlation over All Data', 'Monthly Rank Correlation'])
plt.ylabel('Rank correlation between %s day Momentum Scores and %s-day forward returns'%(day,forward_return_day));
plt.show()

img

平均的な関連性は再び少しマイナスに見えますが,毎月大きく変化します.

平均的な株回帰率

順位から取れた1つの株の回報を計算しました. もしすべての株を順位に並べてnnグループに分けると,それぞれのグループ平均回報は?

最初のステップは,毎月与えられたバスケットごとに平均回報とランキング因数を与える関数を作成することです.

def compute_basket_returns(factor, forward_returns, number_of_baskets, index):
data = pd.concat([factor.loc[index],forward_returns.loc[index]], axis=1)
    # Rank the equities on the factor values
    data.columns = ['Factor Value', 'Forward Returns']
    data.sort_values('Factor Value', inplace=True)
    # How many equities per basket
    equities_per_basket = np.floor(len(data.index) / number_of_baskets)
basket_returns = np.zeros(number_of_baskets)
# Compute the returns of each basket
    for i in range(number_of_baskets):
        start = i * equities_per_basket
        if i == number_of_baskets - 1:
            # Handle having a few extra in the last basket when our number of equities doesn't divide well
            end = len(data.index) - 1
        else:
            end = i * equities_per_basket + equities_per_basket
        # Actually compute the mean returns for each basket
        #s = data.index.iloc[start]
        #e = data.index.iloc[end]
        basket_returns[i] = data.iloc[int(start):int(end)]['Forward Returns'].mean()
        
    return basket_returns

このスコアに基づいて,株をランク付けするときに,それぞれのバスケットの平均回報を計算します.これは,長い時間間の関係を理解できるようにするべきです.

number_of_baskets = 8
mean_basket_returns = np.zeros(number_of_baskets)
resampled_scores = mscores.astype(float).resample('2D').last()
resampled_prices = data.astype(float).resample('2D').last()
resampled_scores.dropna(inplace=True)
resampled_prices.dropna(inplace=True)
forward_returns = resampled_prices.shift(-1)/resampled_prices -1
forward_returns.dropna(inplace = True)
for m in forward_returns.index.intersection(resampled_scores.index):
    basket_returns = compute_basket_returns(resampled_scores, forward_returns, number_of_baskets, m)
    mean_basket_returns += basket_returns
mean_basket_returns /= l    
print(mean_basket_returns)
# Plot the returns of each basket
plt.figure(figsize=(15,7))
plt.bar(range(number_of_baskets), mean_basket_returns)
plt.ylabel('Returns')
plt.xlabel('Basket')
plt.legend(['Returns of Each Basket'])
plt.show()

img

高い成績と低い成績を区別できるようだった.

利子差 (基差) の一致性

もちろん,これらは平均的な関係である.この関係がどの程度一致しているか,そして私たちが取引をする気になるかどうかを理解するために,我々は時間の経過とともにそれに対する見方や態度を変えなければならない.次に,その前の2年間の月間利子率 (基数) を見ていきます.我々はより多くの変化を見ることができ,この動力分数が取引可能かどうかを決定するためにさらなる分析を行うことができます.

total_months = mscores.resample('M').last().index
months_to_plot = 24
monthly_index = total_months[:months_to_plot+1]
mean_basket_returns = np.zeros(number_of_baskets)
strategy_returns = pd.Series(index = monthly_index)
f, axarr = plt.subplots(1+int(monthly_index.size/6), 6,figsize=(18, 15))
for month in range(1, monthly_index.size):
    temp_returns = forward_returns.loc[monthly_index[month-1]:monthly_index[month]]
    temp_scores = resampled_scores.loc[monthly_index[month-1]:monthly_index[month]]
    for m in temp_returns.index.intersection(temp_scores.index):
        basket_returns = compute_basket_returns(temp_scores, temp_returns, number_of_baskets, m)
        mean_basket_returns += basket_returns
    
    strategy_returns[monthly_index[month-1]] = mean_basket_returns[ number_of_baskets-1] - mean_basket_returns[0]
    
    mean_basket_returns /= temp_returns.index.intersection(temp_scores.index).size
    
    r = int(np.floor((month-1) / 6))
    c = (month-1) % 6
    axarr[r, c].bar(range(number_of_baskets), mean_basket_returns)
    axarr[r, c].xaxis.set_visible(False)
    axarr[r, c].set_title('Month ' + str(month))
plt.show()

img

plt.figure(figsize=(15,7))
plt.plot(strategy_returns)
plt.ylabel(‘Returns’)
plt.xlabel(‘Month’)
plt.plot(strategy_returns.cumsum())
plt.legend([‘Monthly Strategy Returns’,’Cumulative Strategy Returns’])
plt.show()

img

最後に,最後のバスケットを追加し,毎月最初のバスケットを空にして,返金を見てみましょう (各証券の資本配分が等しく仮定します)

total_return = strategy_returns.sum()
ann_return = 100*((1 + total_return)**(12.0 /float(strategy_returns.index.size))-1)
print('Annual Returns: %.2f%%'%ann_return)

年間収益率:5.03%

我々は,非常に弱いランキングシステムがあり,高パフォーマンス株と低パフォーマンス株をわずかに区別していることに気づきました. さらに,このランキングシステムは一貫性がないし,月ごとに大きく変化しています.

適切なランキング方法を見つけること

多空平衡利害関係戦略を実現するには,実際には排列方案を決定するだけでよい. その後は機械的な作業である. 一旦多空平衡利害関係戦略ができれば,さまざまな排列因子を交換し,他のものはほとんど変更する必要はありません. これは,すべてのコードを調整する心配なしに,あなたのアイデアをすぐに回転させる非常に便利な方法です.

ランキング方案は,ほぼすべてのモデルからも得られる.それは必ずしも価値に基づく因数モデルである必要はない.それは機械学習技術であり,収益を1ヶ月前に予測し,そのランキングに基づいてランク付けすることができる.

ランキングの選択と評価

ランキング方案は,多空の均衡権益戦略の長所であり,最も重要な要素である. 良いランキング方案を選ぶことは,体系的な作業であり,簡単な答えはない.

優れたスタート地点は,既存の既知の技術を選んで,より高い利益を得るために,それらを少し修正できるかどうか見ることです.

  • クローンと調整: よく議論されるものを選び,それを少し修正して優位性を得るかどうかを確認します. 通常,公開されたファクターは完全に市場から利益を得ているので,取引信号がなくなるでしょう. しかし,時には正しい方向にあなたを導きます.

  • 価格モデル将来の収益を予測するどんなモデルも,因数であり,あなたのバスケ取引指標をランク付けする潜在的可能性を持っています.あなたはどんな複雑な価格モデルでも採用してランキングに変換することができます.

  • 価格に基づく要因 (技術指標)価格ベースのファクタルは,今日お話ししたように,それぞれの利権の歴史的価格に関する情報を入手し,それを利用してファクタルの値を生成します.例として移動平均指標,動力指標,または波動率指標があります.

  • 逆転と動力注目すべきは,価格が一度一方向に動いていると仮定する要因がいくつかあり,その逆の要因もいくつかある.両者は異なる時間範囲と資産に関する有効なモデルであり,動力に基づいた行動か回帰に基づいた行動かを研究することが重要である.

  • 基本要素 (価値に基づく):これはPE,配当などの基本価値の組み合わせを使用する. 基本価値は,会社の現実世界事実に関連する情報を含んでおり,多くの点で価格よりも強力である.

最終的には,成長予測要因は軍拡競争であり,あなたは先を行くようにしています.要因は市場から切り取られ,使用寿命がありますので,あなたの要因がどれくらい衰退したか,そしてそれらを置き換えることができる新しい要因をどのように使用できるか,常に調べなければなりません.

他の考慮事項

  • 周波数を再バランスする

各ランキングシステムは少し異なる時間枠でリターンを予測する.価格ベースの平均値回帰は数日で予測可能であり,価値ベースの因数モデルでは数ヶ月で予測可能である.モデルが予測すべき時間枠を決定することは非常に重要であり,戦略を実行する前に統計的検証を行う.あなたはもちろん,リバランス周波数を最適化しようとし,過剰に適合することを望まないので,他の周波数よりもランダムに最適化することを必然的に見つけます.ランキングシステムの予測の時間枠を決定すると,モデルを最大限に活用するために,約その周波数でリバランスをしようとします.

  • 資本能力と取引コスト

各戦略には最小および最大の資本容量があり,最小の限界は通常取引コストによって決定される.

取引する株が多すぎると高い取引コストが生じる. 1000株を購入したいと仮定すると,リバランスするたびに数千ドルのコストが生じる. あなたの資本基盤は,取引コストがあなたの戦略がもたらす利益のほんの一部を占めるほど高くなければなりません. 例えば,あなたの資本が10万ドルで,あなたの戦略が月に1% (つまり1000ドル) を稼いでいる場合,これらの利益はすべて取引コストに占めるでしょう. あなたは何百万ドルの資本でその戦略を稼いでいる必要があります. 1,000株以上の利益.

最低の資産限界は,主に取引される株の数によって決まる.しかし,最大容量は非常に高く,多空均衡利得戦略は数百万ドルを取引し,優位性を失うことができない.これは,その戦略が比較的頻繁に再バランスされないためである.総資産数は,取引される株の数に加えて,各株のドル価値が非常に低く,あなたの取引量が市場に影響を与える心配する必要はない.あなたが1,000株を取引すると仮定して,それは100,000,000ドルである.あなたが毎月全ポートフォリオを再バランスすると,毎月1株がわずか100,000ドルになります.これはほとんどの取引証券にとって重要な市場シェアになるには不十分です.


関連性

もっと