Sumber daya yang dimuat... Pemuatan...

Model Faktor Mata Uang Digital

Penulis:FMZ~Lydia, Dibuat: 2022-10-24 17:37:50, Diperbarui: 2023-09-15 20:59:38

img

Kerangka model faktor

Laporan penelitian tentang model multi-faktor pasar saham sangat besar, dengan teori dan praktik yang kaya. Tidak peduli jumlah mata uang, nilai pasar total, volume perdagangan, pasar derivatif, dll. di pasar mata uang digital, cukup untuk melakukan penelitian faktor. Makalah ini terutama untuk pemula strategi kuantitatif, dan tidak akan melibatkan prinsip-prinsip matematika yang kompleks dan analisis statistik.

Faktor dapat dianggap sebagai indikator dan ekspresi dapat ditulis. Faktor berubah terus-menerus, mencerminkan informasi pendapatan masa depan. Secara umum, faktor mewakili logika investasi.

Sebagai contoh, asumsi di balik faktor harga penutupan adalah bahwa harga saham dapat memprediksi pendapatan di masa depan, dan semakin tinggi harga saham, semakin tinggi pendapatan di masa depan akan (atau mungkin lebih rendah).

Baik pasar saham maupun pasar mata uang digital adalah sistem yang kompleks. Tidak ada faktor yang dapat sepenuhnya memprediksi keuntungan di masa depan, tetapi mereka masih memiliki prediktabilitas tertentu. Alpha yang efektif (mode investasi) secara bertahap akan menjadi tidak sah dengan masukan modal yang lebih banyak. Namun, proses ini akan menghasilkan model lain di pasar, sehingga melahirkan alpha baru. Faktor nilai pasar digunakan untuk menjadi strategi yang sangat efektif di pasar saham A. Cukup membeli 10 saham dengan nilai pasar terendah, dan menyesuaikan mereka sekali sehari. Sejak tahun 2007, backtest 10 tahun akan menghasilkan lebih dari 400 kali keuntungan, jauh melampaui keseluruhan pasar. Namun, pasar saham kuda putih pada tahun 2017 mencerminkan kegagalan faktor nilai pasar kecil, dan faktor nilai menjadi populer. Oleh karena itu, kita perlu terus-menerus memverifikasi dan mencoba menggunakan keseimbangan alfa.

Faktor-faktor yang dicari adalah dasar untuk menetapkan strategi. Strategi yang lebih baik dapat dibangun dengan menggabungkan beberapa faktor efektif yang tidak terkait.

import requests
from datetime import date,datetime
import time
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import requests, zipfile, io
%matplotlib inline

Sumber Data

Hingga saat ini, data garis K per jam Binance USDT perpetual futures dari awal 2022 hingga sekarang telah melebihi 150 mata uang. Seperti yang telah kami sebutkan sebelumnya, model faktor adalah model pemilihan mata uang, yang berorientasi pada semua mata uang daripada mata uang tertentu. Data garis K mencakup harga tinggi pembukaan dan harga rendah penutupan, volume perdagangan, jumlah transaksi, volume pembelian pemegang dan data lainnya. Data ini tentu saja bukan sumber semua faktor, seperti indeks saham AS, harapan kenaikan suku bunga, profitabilitas, data pada rantai, popularitas media sosial, dan sebagainya. Sumber data yang tidak biasa juga dapat menemukan alpha yang efektif, tetapi volume harga dasar juga cukup.

## Current trading pair
Info = requests.get('https://fapi.binance.com/fapi/v1/exchangeInfo')
symbols = [s['symbol'] for s in Info.json()['symbols']]
symbols = list(filter(lambda x: x[-4:] == 'USDT', [s.split('_')[0] for s in symbols]))
print(symbols)

Di luar:

['BTCUSDT', 'ETHUSDT', 'BCHUSDT', 'XRPUSDT', 'EOSUSDT', 'LTCUSDT', 'TRXUSDT', 'ETCUSDT', 'LINKUSDT',
'XLMUSDT', 'ADAUSDT', 'XMRUSDT', 'DASHUSDT', 'ZECUSDT', 'XTZUSDT', 'BNBUSDT', 'ATOMUSDT', 'ONTUSDT',
'IOTAUSDT', 'BATUSDT', 'VETUSDT', 'NEOUSDT', 'QTUMUSDT', 'IOSTUSDT', 'THETAUSDT', 'ALGOUSDT', 'ZILUSDT',
'KNCUSDT', 'ZRXUSDT', 'COMPUSDT', 'OMGUSDT', 'DOGEUSDT', 'SXPUSDT', 'KAVAUSDT', 'BANDUSDT', 'RLCUSDT',
'WAVESUSDT', 'MKRUSDT', 'SNXUSDT', 'DOTUSDT', 'DEFIUSDT', 'YFIUSDT', 'BALUSDT', 'CRVUSDT', 'TRBUSDT',
'RUNEUSDT', 'SUSHIUSDT', 'SRMUSDT', 'EGLDUSDT', 'SOLUSDT', 'ICXUSDT', 'STORJUSDT', 'BLZUSDT', 'UNIUSDT',
'AVAXUSDT', 'FTMUSDT', 'HNTUSDT', 'ENJUSDT', 'FLMUSDT', 'TOMOUSDT', 'RENUSDT', 'KSMUSDT', 'NEARUSDT',
'AAVEUSDT', 'FILUSDT', 'RSRUSDT', 'LRCUSDT', 'MATICUSDT', 'OCEANUSDT', 'CVCUSDT', 'BELUSDT', 'CTKUSDT',
'AXSUSDT', 'ALPHAUSDT', 'ZENUSDT', 'SKLUSDT', 'GRTUSDT', '1INCHUSDT', 'CHZUSDT', 'SANDUSDT', 'ANKRUSDT',
'BTSUSDT', 'LITUSDT', 'UNFIUSDT', 'REEFUSDT', 'RVNUSDT', 'SFPUSDT', 'XEMUSDT', 'BTCSTUSDT', 'COTIUSDT',
'CHRUSDT', 'MANAUSDT', 'ALICEUSDT', 'HBARUSDT', 'ONEUSDT', 'LINAUSDT', 'STMXUSDT', 'DENTUSDT', 'CELRUSDT',
'HOTUSDT', 'MTLUSDT', 'OGNUSDT', 'NKNUSDT', 'SCUSDT', 'DGBUSDT', '1000SHIBUSDT', 'ICPUSDT', 'BAKEUSDT',
'GTCUSDT', 'BTCDOMUSDT', 'TLMUSDT', 'IOTXUSDT', 'AUDIOUSDT', 'RAYUSDT', 'C98USDT', 'MASKUSDT', 'ATAUSDT',
'DYDXUSDT', '1000XECUSDT', 'GALAUSDT', 'CELOUSDT', 'ARUSDT', 'KLAYUSDT', 'ARPAUSDT', 'CTSIUSDT', 'LPTUSDT',
'ENSUSDT', 'PEOPLEUSDT', 'ANTUSDT', 'ROSEUSDT', 'DUSKUSDT', 'FLOWUSDT', 'IMXUSDT', 'API3USDT', 'GMTUSDT',
'APEUSDT', 'BNXUSDT', 'WOOUSDT', 'FTTUSDT', 'JASMYUSDT', 'DARUSDT', 'GALUSDT', 'OPUSDT', 'BTCUSDT',
'ETHUSDT', 'INJUSDT', 'STGUSDT', 'FOOTBALLUSDT', 'SPELLUSDT', '1000LUNCUSDT', 'LUNA2USDT', 'LDOUSDT',
'CVXUSDT']

print(len(symbols))

Di luar:

153

#Function to obtain any period of K-line
def GetKlines(symbol='BTCUSDT',start='2020-8-10',end='2021-8-10',period='1h',base='fapi',v = 'v1'):
    Klines = []
    start_time = int(time.mktime(datetime.strptime(start, "%Y-%m-%d").timetuple()))*1000 + 8*60*60*1000
    end_time =  min(int(time.mktime(datetime.strptime(end, "%Y-%m-%d").timetuple()))*1000 + 8*60*60*1000,time.time()*1000)
    intervel_map = {'m':60*1000,'h':60*60*1000,'d':24*60*60*1000}
    while start_time < end_time:
        mid_time = start_time+1000*int(period[:-1])*intervel_map[period[-1]]
        url = 'https://'+base+'.binance.com/'+base+'/'+v+'/klines?symbol=%s&interval=%s&startTime=%s&endTime=%s&limit=1000'%(symbol,period,start_time,mid_time)
        res = requests.get(url)
        res_list = res.json()
        if type(res_list) == list and len(res_list) > 0:
            start_time = res_list[-1][0]+int(period[:-1])*intervel_map[period[-1]]
            Klines += res_list
        if type(res_list) == list and len(res_list) == 0:
            start_time = start_time+1000*int(period[:-1])*intervel_map[period[-1]]
        if mid_time >= end_time:
            break
    df = pd.DataFrame(Klines,columns=['time','open','high','low','close','amount','end_time','volume','count','buy_amount','buy_volume','null']).astype('float')
    df.index = pd.to_datetime(df.time,unit='ms')
    return df
start_date = '2022-1-1'
end_date = '2022-09-14'
period = '1h'
df_dict = {}
for symbol in symbols:
    df_s = GetKlines(symbol=symbol,start=start_date,end=end_date,period=period,base='fapi',v='v1')
    if not df_s.empty:
        df_dict[symbol] = df_s
symbols = list(df_dict.keys())
print(df_s.columns)

Di luar:

Index(['time', 'open', 'high', 'low', 'close', 'amount', 'end_time', 'volume',
       'count', 'buy_amount', 'buy_volume', 'null'],
      dtype='object')

Data yang kami minati: harga penutupan, harga pembukaan, volume perdagangan, jumlah transaksi, dan proporsi pembelian yang diambil terlebih dahulu diekstrak dari data K-line.

df_close = pd.DataFrame(index=pd.date_range(start=start_date, end=end_date, freq=period),columns=df_dict.keys())
df_open = pd.DataFrame(index=pd.date_range(start=start_date, end=end_date, freq=period),columns=df_dict.keys())
df_volume = pd.DataFrame(index=pd.date_range(start=start_date, end=end_date, freq=period),columns=df_dict.keys())
df_buy_ratio = pd.DataFrame(index=pd.date_range(start=start_date, end=end_date, freq=period),columns=df_dict.keys())
df_count = pd.DataFrame(index=pd.date_range(start=start_date, end=end_date, freq=period),columns=df_dict.keys())
for symbol in df_dict.keys():
    df_s = df_dict[symbol]
    df_close[symbol] = df_s.close
    df_open[symbol] = df_s.open
    df_volume[symbol] = df_s.volume
    df_count[symbol] = df_s['count']
    df_buy_ratio[symbol] = df_s.buy_amount/df_s.amount
df_close = df_close.dropna(how='all')
df_open = df_open.dropna(how='all')
df_volume = df_volume.dropna(how='all')
df_count = df_count.dropna(how='all')
df_buy_ratio = df_buy_ratio.dropna(how='all')

Kinerja indeks pasar secara keseluruhan suram, turun 60% dari awal tahun hingga hari-hari terakhir.

df_norm = df_close/df_close.fillna(method='bfill').iloc[0] #normalization
df_norm.mean(axis=1).plot(figsize=(15,6),grid=True);
#Final index profit chart

img

Penghakiman validitas faktor

  • Metode regresi Hasil dari periode berikutnya adalah variabel dependen, dan faktor yang akan diuji adalah variabel independen. Koefisien yang diperoleh dengan regresi juga merupakan hasil dari faktor. Setelah persamaan regresi dibangun, validitas dan volatilitas faktor umumnya dilihat dengan mengacu pada nilai rata-rata mutlak nilai koefisien t, proporsi urutan nilai absolut nilai koefisien t lebih besar dari 2, pengembalian faktor tahunan, volatilitas keuntungan faktor tahunan, dan rasio Sharpe dari keuntungan faktor. Beberapa faktor dapat regresi sekaligus. Silakan lihat dokumen barra untuk rincian.

  • IC, IR dan indikator lainnya Sekarang, RANK_ IC juga digunakan secara umum, ini adalah koefisien korelasi antara peringkat faktor dan tingkat pengembalian saham berikutnya. IR umumnya adalah nilai rata-rata urutan IC / standar deviasi urutan IC.

  • Metode regresi stratifikasi Dalam makalah ini, kita akan menggunakan metode ini, yaitu mengurutkan mata uang sesuai dengan faktor yang akan diuji, membagi mereka menjadi N kelompok untuk backtesting kelompok, dan menggunakan periode tetap untuk penyesuaian posisi. Jika situasinya ideal, tingkat pengembalian mata uang Grup N akan menunjukkan monotonitas yang baik, meningkat atau menurun secara monoton, dan kesenjangan pendapatan setiap kelompok besar. Faktor-faktor tersebut tercermin dalam diskriminasi yang baik. Jika kelompok pertama memiliki keuntungan tertinggi dan kelompok terakhir memiliki keuntungan terendah, maka pergi panjang di kelompok pertama dan pergi pendek di kelompok terakhir untuk mendapatkan hasil akhir, yang merupakan indikator referensi rasio Sharp.

Operasi backtest yang sebenarnya

Koin yang akan dipilih dibagi menjadi 3 kelompok berdasarkan peringkat faktor dari yang terkecil ke yang terbesar. Setiap kelompok mata uang menyumbang sekitar 1/3 dari total. Jika suatu faktor efektif, semakin kecil jumlah poin di setiap kelompok, semakin tinggi tingkat pengembalian, tetapi juga berarti bahwa setiap mata uang memiliki dana yang relatif lebih banyak dialokasikan. Jika posisi panjang dan pendek masing-masing leverage ganda, dan kelompok pertama dan kelompok terakhir masing-masing 10 mata uang, maka satu mata uang menyumbang 10% dari total. Jika mata uang yang disingkat dua kali lipat, maka 20% ditarik; Jika jumlah kelompok adalah 50, maka 4% akan ditarik. Mendiversifikasi mata uang dapat mengurangi risiko angsa hitam. Pergi panjang kelompok pertama (faktor nilai minimum), pergi ke kelompok ketiga. Semakin besar faktornya, dan jumlah pendapatan yang lebih tinggi, Anda hanya dapat mengubah faktor dan posisi pendek atau panjang menjadi pendapatan negatif atau reciprocal.

Secara umum, kemampuan prediksi faktor dapat dievaluasi secara kasar berdasarkan tingkat pengembalian dan rasio Sharpe dari backtest akhir. Selain itu, juga perlu merujuk pada apakah ekspresi faktor sederhana, sensitif terhadap ukuran pengelompokan, sensitif terhadap interval penyesuaian posisi, dan sensitif terhadap waktu awal backtest.

Dalam hal frekuensi penyesuaian posisi, pasar saham biasanya memiliki periode 5 hari, 10 hari dan satu bulan. Namun, untuk pasar mata uang digital, periode seperti itu tidak diragukan lagi terlalu lama, dan pasar di bot nyata dipantau secara real time. Tidak perlu berpegang pada periode tertentu untuk menyesuaikan posisi lagi. Oleh karena itu, di bot nyata, kita menyesuaikan posisi secara real time atau dalam waktu singkat.

Strategi ini menggunakan metode untuk menunggu perubahan pengelompokan, dan kemudian menutup posisi ketika posisi di arah yang berlawanan perlu dibuka. Misalnya, kelompok pertama pergi panjang. Ketika mata uang dalam status posisi panjang dibagi menjadi kelompok ketiga, maka tutup posisi dan pergi pendek. Jika posisi ditutup dalam periode tetap, seperti setiap hari atau setiap 8 jam, Anda juga dapat menutup posisi tanpa berada dalam kelompok. Cobalah sebanyak yang Anda bisa.

#Backtest engine
class Exchange:
    
    def __init__(self, trade_symbols, fee=0.0004, initial_balance=10000):
        self.initial_balance = initial_balance #Initial assets
        self.fee = fee
        self.trade_symbols = trade_symbols
        self.account = {'USDT':{'realised_profit':0, 'unrealised_profit':0, 'total':initial_balance, 'fee':0, 'leverage':0, 'hold':0}}
        for symbol in trade_symbols:
            self.account[symbol] = {'amount':0, 'hold_price':0, 'value':0, 'price':0, 'realised_profit':0,'unrealised_profit':0,'fee':0}
            
    def Trade(self, symbol, direction, price, amount):
        
        cover_amount = 0 if direction*self.account[symbol]['amount'] >=0 else min(abs(self.account[symbol]['amount']), amount)
        open_amount = amount - cover_amount
        self.account['USDT']['realised_profit'] -= price*amount*self.fee #Net of fees
        self.account['USDT']['fee'] += price*amount*self.fee
        self.account[symbol]['fee'] += price*amount*self.fee

        if cover_amount > 0: #Close position first
            self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount  #Profits
            self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount
            
            self.account[symbol]['amount'] -= -direction*cover_amount
            self.account[symbol]['hold_price'] = 0 if self.account[symbol]['amount'] == 0 else self.account[symbol]['hold_price']
            
        if open_amount > 0:
            total_cost = self.account[symbol]['hold_price']*direction*self.account[symbol]['amount'] + price*open_amount
            total_amount = direction*self.account[symbol]['amount']+open_amount
            
            self.account[symbol]['hold_price'] = total_cost/total_amount
            self.account[symbol]['amount'] += direction*open_amount
                    
    
    def Buy(self, symbol, price, amount):
        self.Trade(symbol, 1, price, amount)
        
    def Sell(self, symbol, price, amount):
        self.Trade(symbol, -1, price, amount)
        
    def Update(self, close_price): #Update assets
        self.account['USDT']['unrealised_profit'] = 0
        self.account['USDT']['hold'] = 0
        for symbol in self.trade_symbols:
            if not np.isnan(close_price[symbol]):
                self.account[symbol]['unrealised_profit'] = (close_price[symbol] - self.account[symbol]['hold_price'])*self.account[symbol]['amount']
                self.account[symbol]['price'] = close_price[symbol]
                self.account[symbol]['value'] = abs(self.account[symbol]['amount'])*close_price[symbol]
                self.account['USDT']['hold'] += self.account[symbol]['value']
                self.account['USDT']['unrealised_profit'] += self.account[symbol]['unrealised_profit']
        self.account['USDT']['total'] = round(self.account['USDT']['realised_profit'] + self.initial_balance + self.account['USDT']['unrealised_profit'],6)
        self.account['USDT']['leverage'] = round(self.account['USDT']['hold']/self.account['USDT']['total'],3)

#Function of test factor
def Test(factor, symbols, period=1, N=40, value=300):
    e = Exchange(symbols, fee=0.0002, initial_balance=10000)
    res_list = []
    index_list = []
    factor = factor.dropna(how='all')
    for idx, row in factor.iterrows():
        if idx.hour % period == 0:
            buy_symbols =  row.sort_values().dropna()[0:N].index
            sell_symbols = row.sort_values().dropna()[-N:].index
            prices = df_close.loc[idx,]
            index_list.append(idx)
            for symbol in symbols:
                if symbol in buy_symbols and e.account[symbol]['amount'] <= 0:
                    e.Buy(symbol,prices[symbol],value/prices[symbol]-e.account[symbol]['amount'])
                if symbol in sell_symbols and e.account[symbol]['amount'] >= 0:
                    e.Sell(symbol,prices[symbol], value/prices[symbol]+e.account[symbol]['amount'])
            e.Update(prices)
            res_list.append([e.account['USDT']['total'],e.account['USDT']['hold']])
    return pd.DataFrame(data=res_list, columns=['total','hold'],index = index_list)

Tes faktor sederhana

Faktor volume perdagangan: Mata uang panjang sederhana dengan volume perdagangan rendah dan mata uang pendek dengan volume perdagangan tinggi, yang berkinerja sangat baik, menunjukkan bahwa mata uang populer cenderung menurun.

Faktor harga perdagangan: efek dari mata uang yang panjang dengan harga rendah dan mata uang yang pendek dengan harga tinggi keduanya biasa.

Faktor jumlah transaksi: Kinerja sangat mirip dengan volume transaksi. Jelas bahwa korelasi antara faktor volume transaksi dan faktor jumlah transaksi sangat tinggi. Bahkan, korelasi rata-rata antara keduanya dalam mata uang yang berbeda telah mencapai 0,97, yang menunjukkan bahwa kedua faktor ini sangat mirip. Faktor ini perlu dipertimbangkan ketika mensintesis beberapa faktor.

3h momentum factor: (df_close - df_close. shift (3)) /df_ close. shift(3). yaitu, kenaikan faktor 3 jam. Hasil backtest menunjukkan bahwa kenaikan 3 jam memiliki karakteristik regresi yang jelas, yaitu, kenaikan lebih mudah jatuh kemudian. Kinerja keseluruhan OK, tetapi juga ada periode penarikan dan osilasi yang panjang.

Faktor momentum 24 jam: hasil dari periode penyesuaian posisi 24 jam baik, hasilnya mirip dengan momentum 3 jam, dan penarikan lebih kecil.

Faktor perubahan volume transaksi: df_ volume.rolling(24).mean() /df_ volume. rolling (96). mean(), yaitu rasio volume transaksi pada hari terakhir terhadap volume transaksi dalam tiga hari terakhir. Posisi disesuaikan setiap 8 jam. Hasil backtesting bagus, dan penarikan juga relatif rendah, menunjukkan bahwa mereka dengan volume transaksi aktif lebih cenderung menurun.

Faktor perubahan jumlah transaksi: df_ count.rolling(24).mean() /df_ count.rolling(96). mean (), yaitu rasio jumlah transaksi pada hari terakhir terhadap jumlah transaksi dalam tiga hari terakhir. Posisi disesuaikan setiap 8 jam. Hasil backtesting baik, dan penarikan juga relatif rendah, yang menunjukkan bahwa mereka dengan volume transaksi aktif lebih cenderung menurun.

Faktor perubahan nilai transaksi tunggal: - ((df_volume.rolling(24).mean()/df_count.rolling(24.mean())/(df_volume.rolling(24.mean()/df_count.rolling(96.mean()) , yaitu rasio nilai transaksi hari terakhir terhadap nilai transaksi tiga hari terakhir, dan posisi akan disesuaikan setiap 8 jam. Faktor ini juga sangat berkorelasi dengan faktor volume transaksi.

Faktor perubahan pengambil berdasarkan rasio transaksi: df_buy_ratio.rolling(24).mean() /df_buy_ratio.rolling(96).mean(), yaitu rasio pengambil berdasarkan volume terhadap total volume transaksi pada hari terakhir terhadap nilai transaksi dalam tiga hari terakhir, dan posisi akan disesuaikan setiap 8 jam. Faktor ini berkinerja cukup baik dan tidak memiliki korelasi dengan faktor volume transaksi.

Faktor volatilitas: (df_close/df_open).rolling(24).std(), pergi panjang mata uang dengan volatilitas rendah, itu memiliki efek tertentu.

Faktor korelasi antara volume transaksi dan harga penutupan: df_close.rolling ((96).corr ((df_volume), harga penutupan dalam empat hari terakhir memiliki faktor korelasi volume transaksi, yang secara keseluruhan berjalan dengan baik.

Faktor-faktor yang tercantum di sini didasarkan pada volume harga. Sebenarnya kombinasi rumus faktor bisa sangat kompleks tanpa logika yang jelas. Anda dapat merujuk metode konstruksi faktor ALPHA101 yang terkenal:https://github.com/STHSF/alpha101.

#transaction volume
factor_volume = df_volume
factor_volume_res = Test(factor_volume, symbols, period=4)
factor_volume_res.total.plot(figsize=(15,6),grid=True);

img

#transaction price
factor_close = df_close
factor_close_res = Test(factor_close, symbols, period=8)
factor_close_res.total.plot(figsize=(15,6),grid=True);

img

#transaction count
factor_count = df_count
factor_count_res = Test(factor_count, symbols, period=8)
factor_count_res.total.plot(figsize=(15,6),grid=True);

img

print(df_count.corrwith(df_volume).mean())

0.9671246744996017

#3h momentum factor
factor_1 =  (df_close - df_close.shift(3))/df_close.shift(3)
factor_1_res = Test(factor_1,symbols,period=1)
factor_1_res.total.plot(figsize=(15,6),grid=True);

img

#24h momentum factor
factor_2 =  (df_close - df_close.shift(24))/df_close.shift(24)
factor_2_res = Test(factor_2,symbols,period=24)
tamenxuanfactor_2_res.total.plot(figsize=(15,6),grid=True);

img

#factor of transaction volume
factor_3 = df_volume.rolling(24).mean()/df_volume.rolling(96).mean()
factor_3_res = Test(factor_3, symbols, period=8)
factor_3_res.total.plot(figsize=(15,6),grid=True);

img

#factor of transaction number
factor_4 = df_count.rolling(24).mean()/df_count.rolling(96).mean()
factor_4_res = Test(factor_4, symbols, period=8)
factor_4_res.total.plot(figsize=(15,6),grid=True);

img

#factor correlation
print(factor_4.corrwith(factor_3).mean())

0.9707239580854841

#single transaction value factor
factor_5 = -(df_volume.rolling(24).mean()/df_count.rolling(24).mean())/(df_volume.rolling(24).mean()/df_count.rolling(96).mean())
factor_5_res = Test(factor_5, symbols, period=8)
factor_5_res.total.plot(figsize=(15,6),grid=True);

img

print(factor_4.corrwith(factor_5).mean())

0.861206620552479

#proportion factor of taker by transaction
factor_6 = df_buy_ratio.rolling(24).mean()/df_buy_ratio.rolling(96).mean()
factor_6_res = Test(factor_6, symbols, period=4)
factor_6_res.total.plot(figsize=(15,6),grid=True);

img

print(factor_3.corrwith(factor_6).mean())

0.1534572192503726

#volatility factor
factor_7 = (df_close/df_open).rolling(24).std()
factor_7_res = Test(factor_7, symbols, period=2)
factor_7_res.total.plot(figsize=(15,6),grid=True);

img

#correlation factor between transaction volume and closing price
factor_8 = df_close.rolling(96).corr(df_volume)
factor_8_res = Test(factor_8, symbols, period=4)
factor_8_res.total.plot(figsize=(15,6),grid=True);

img

Sintesis multifaktor

Hal ini tentu bagian yang paling penting dari proses konstruksi strategi untuk menemukan faktor efektif baru terus-menerus, tetapi tanpa metode sintesis faktor yang baik, faktor alfa tunggal yang sangat baik tidak dapat memainkan peran maksimal.

Metode berat yang sama: semua faktor yang akan disintesis ditambahkan dengan berat yang sama untuk mendapatkan faktor baru setelah sintesis.

Metode pembobolan rasio pengembalian faktor historis: semua faktor yang akan dikombinasikan ditambahkan sesuai dengan rata-rata aritmatika rasio pengembalian faktor historis dalam periode terakhir sebagai bobot untuk mendapatkan faktor baru setelah sintesis. Faktor yang berkinerja baik dalam metode ini memiliki bobot yang lebih tinggi.

Memaksimalkan metode bobot IC_IR: nilai rata-rata IC dari faktor komposit selama periode sejarah digunakan sebagai estimasi nilai IC dari faktor komposit pada periode berikutnya, dan matriks kovariansi dari nilai IC historis digunakan sebagai estimasi volatilitas faktor komposit pada periode berikutnya. Menurut IC_IR sama dengan nilai yang diharapkan dari IC dibagi dengan standar deviasi dari IC untuk mendapatkan solusi bobot optimal dari faktor komposit maksimum IC_IR.

Analisis komponen utama (PCA): PCA adalah metode umum untuk pengurangan dimensi data, dan korelasi antara faktor mungkin tinggi.

Artikel ini akan merujuk pada penugasan validitas faktor secara manual.ae933a8c-5a94-4d92-8f33-d92b70c36119.pdf

Saat menguji faktor tunggal, pengurutannya tetap, tetapi sintesis multi faktor perlu menggabungkan data yang sama sekali berbeda, sehingga semua faktor perlu disatukan, dan nilai ekstrim dan nilai yang hilang perlu dihilangkan secara umum.

#standardize functions, remove missing values and extreme values, and standardize
def norm_factor(factor):
    factor = factor.dropna(how='all')
    factor_clip = factor.apply(lambda x:x.clip(x.quantile(0.2), x.quantile(0.8)),axis=1)
    factor_norm = factor_clip.add(-factor_clip.mean(axis=1),axis ='index').div(factor_clip.std(axis=1),axis ='index')
    return factor_norm


df_volume_norm = norm_factor(df_volume)
factor_1_norm = norm_factor(factor_1)
factor_6_norm = norm_factor(factor_6)
factor_7_norm = norm_factor(factor_7)
factor_8_norm = norm_factor(factor_8)
factor_total = 0.6*df_volume_norm + 0.4*factor_1_norm + 0.2*factor_6_norm + 0.3*factor_7_norm + 0.4*factor_8_norm
factor_total_res = Test(factor_total, symbols, period=8)
factor_total_res.total.plot(figsize=(15,6),grid=True);

img

Ringkasan

Artikel ini memperkenalkan metode pengujian faktor tunggal dan menguji faktor tunggal yang umum, dan awalnya memperkenalkan metode sintesis multi faktor. Namun, ada banyak konten penelitian multi faktor. Setiap poin yang disebutkan dalam makalah dapat dikembangkan lebih lanjut. Ini adalah cara yang layak untuk mengubah penelitian tentang berbagai strategi menjadi eksplorasi faktor alfa. Penggunaan metodologi faktor dapat sangat mempercepat verifikasi ide perdagangan, dan ada banyak bahan untuk referensi.

Robot asli dari:https://www.fmz.com/robot/486605


Berkaitan

Lebih banyak