Model Faktor Mata Wang Digital

Penulis:Lydia, Dicipta: 2022-10-24 17:37:50, Dikemas kini: 2023-09-15 20:59:38

img

Kerangka model faktor

Laporan penyelidikan mengenai model multi-faktor pasaran saham adalah besar, dengan teori dan amalan yang kaya. Tidak kira jumlah mata wang, nilai pasaran keseluruhan, jumlah dagangan, pasaran derivatif, dan lain-lain di pasaran mata wang digital, cukup untuk menjalankan penyelidikan faktor. Kertas ini terutamanya untuk pemula strategi kuantitatif, dan tidak akan melibatkan prinsip matematik yang kompleks dan analisis statistik. Ia akan menggunakan pasaran masa depan kekal Binance sebagai sumber data untuk membina kerangka kerja yang mudah untuk penyelidikan faktor, yang mudah untuk menilai penunjuk faktor.

Faktor boleh dianggap sebagai penunjuk dan ungkapan boleh ditulis. Faktor sentiasa berubah, mencerminkan maklumat pendapatan masa depan. Secara amnya, faktor mewakili logika pelaburan.

Sebagai contoh, andaian di sebalik faktor harga penutupan adalah bahawa harga saham dapat meramalkan pendapatan masa depan, dan semakin tinggi harga saham, semakin tinggi pendapatan masa depan akan menjadi (atau mungkin lebih rendah). Sebenarnya, membina portfolio berdasarkan faktor ini adalah model / strategi pelaburan untuk membeli saham dengan harga tinggi dalam pusingan biasa. Secara umum, faktor-faktor yang dapat terus menjana keuntungan berlebihan juga dipanggil Alpha. Sebagai contoh, faktor nilai pasaran dan faktor momentum telah disahkan sebagai faktor yang pernah berkesan oleh alam akademik dan komuniti pelaburan.

Kedua-dua pasaran saham dan pasaran mata wang digital adalah sistem yang kompleks. Tidak ada faktor yang dapat meramalkan sepenuhnya keuntungan masa depan, tetapi mereka masih mempunyai jangkaan tertentu. Alfa yang berkesan (modus pelaburan) secara beransur-ansur akan menjadi tidak sah dengan lebih banyak input modal. Walau bagaimanapun, proses ini akan menghasilkan model lain di pasaran, sehingga melahirkan alfa baru. Faktor nilai pasaran digunakan untuk menjadi strategi yang sangat berkesan di pasaran saham A. Hanya membeli 10 saham dengan nilai pasaran terendah, dan menyesuaikan mereka sekali sehari. Sejak tahun 2007, 10 tahun belakang akan menghasilkan lebih daripada 400 kali keuntungan, jauh melebihi keseluruhan pasaran. Walau bagaimanapun, pasaran saham kuda putih pada tahun 2017 mencerminkan kegagalan faktor nilai pasaran kecil, dan faktor nilai menjadi popular. Oleh itu, kita perlu sentiasa memeriksa keseimbangan dan cuba menggunakan alfa.

Faktor-faktor yang dicari adalah asas untuk menetapkan strategi. Strategi yang lebih baik boleh dibina dengan menggabungkan beberapa faktor berkesan yang tidak berkaitan.

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

Sehingga kini, data garis K setiap jam niaga hadapan kekal Binance USDT dari awal tahun 2022 sehingga kini telah melebihi 150 mata wang. Seperti yang telah kita nyatakan sebelumnya, model faktor adalah model pemilihan mata wang, yang berorientasikan kepada semua mata wang dan bukan mata wang tertentu. Data garis K termasuk harga tinggi pembukaan dan harga rendah penutupan, jumlah dagangan, jumlah urus niaga, jumlah pembelian yang mengambil dan data lain. Data ini pastinya bukan sumber semua faktor, seperti indeks saham AS, jangkaan kenaikan kadar faedah, keuntungan, data pada rantaian, populariti media sosial dan sebagainya. Sumber data yang tidak biasa juga mungkin mencari alpha yang berkesan, tetapi jumlah harga asas juga mencukupi.

## 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)

Keluar:

['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))

Keluar:

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)

Keluar:

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

Data yang kita minati: harga penutupan, harga pembukaan, jumlah dagangan, bilangan urus niaga, dan peratusan pembelian mengambil diambil dari data K-line terlebih dahulu. Berdasarkan data ini, faktor yang diperlukan diproses.

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')

Prestasi keseluruhan indeks pasaran adalah suram, jatuh sebanyak 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 kesahihan faktor

  • Kaedah regresi Hasil tempoh berikutnya adalah pembolehubah bergantung, dan faktor yang perlu diuji adalah pembolehubah bebas. Gabungan yang diperoleh dengan regresi juga merupakan hasil faktor. Selepas persamaan regresi dibina, kesahihan dan volatiliti faktor umumnya dilihat dengan merujuk kepada nilai purata mutlak nilai p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p p

  • IC, IR dan penunjuk lain Yang dipanggil IC adalah pekali korelasi antara faktor dan kadar pulangan tempoh seterusnya. Sekarang, RANK_ IC juga digunakan secara amnya, ia adalah pekali korelasi antara kedudukan faktor dan kadar pulangan saham seterusnya. IR biasanya adalah nilai purata urutan IC / penyimpangan standard urutan IC.

  • Kaedah regresi stratifikasi Dalam kertas ini, kita akan menggunakan kaedah ini, iaitu menyusun mata wang mengikut faktor yang akan diuji, membahagikannya kepada N kumpulan untuk backtesting kumpulan, dan menggunakan tempoh tetap untuk penyesuaian kedudukan. Jika keadaan ideal, kadar pulangan mata wang Kumpulan N akan menunjukkan monoton yang baik, meningkat atau menurun secara monoton, dan jurang pendapatan setiap kumpulan adalah besar. Faktor-faktor tersebut tercermin dalam diskriminasi yang baik. Jika kumpulan pertama mempunyai keuntungan tertinggi dan kumpulan terakhir mempunyai keuntungan terendah, maka pergi panjang dalam kumpulan pertama dan pergi pendek dalam kumpulan terakhir untuk mendapatkan hasil akhir, yang merupakan penunjuk rujukan nisbah Sharp.

Operasi backtest sebenar

Mata wang yang akan dipilih dibahagikan kepada 3 kumpulan berdasarkan kedudukan faktor dari yang terkecil ke yang terbesar. Setiap kumpulan mata wang menyumbang kira-kira 1/3 daripada jumlah keseluruhan. Jika faktor berkesan, semakin kecil bilangan mata dalam setiap kumpulan, semakin tinggi kadar pulangan akan menjadi, tetapi ia juga bermakna bahawa setiap mata wang mempunyai lebih banyak dana yang diperuntukkan. Jika kedudukan panjang dan pendek adalah leverage ganda masing-masing, dan kumpulan pertama dan kumpulan terakhir adalah 10 mata wang masing-masing, maka satu mata wang menyumbang 10% daripada jumlah keseluruhan. Jika mata wang yang pendek adalah dua kali ganda, maka 20% ditarik balik; Jika jumlah kumpulan adalah 50, maka 4% akan ditarik balik. Mata wang mempelbagaikan boleh mengurangkan risiko angsa hitam. pergi panjang kumpulan pertama (nilai faktor minimum), pergi ke kumpulan ketiga.

Secara amnya, keupayaan ramalan faktor boleh dinilai kira-kira mengikut kadar pulangan dan nisbah Sharpe dari backtest akhir. Di samping itu, ia juga perlu merujuk kepada sama ada ungkapan faktor adalah mudah, sensitif kepada saiz pengelompokan, sensitif kepada selang pelarasan kedudukan, dan sensitif kepada masa awal backtest.

Mengenai kekerapan penyesuaian kedudukan, pasaran saham biasanya mempunyai tempoh 5 hari, 10 hari dan satu bulan. Walau bagaimanapun, untuk pasaran mata wang digital, tempoh sedemikian tidak diragukan lagi terlalu lama, dan pasaran dalam bot sebenar dipantau dalam masa nyata. Tidak perlu berpegang pada tempoh tertentu untuk menyesuaikan kedudukan lagi. Oleh itu, dalam bot sebenar, kita menyesuaikan kedudukan dalam masa nyata atau dalam jangka masa yang singkat.

Dalam kes ini, strategi ini menggunakan kaedah untuk menunggu perubahan kumpulan, dan kemudian menutup kedudukan apabila kedudukan di arah yang bertentangan perlu dibuka. Sebagai contoh, kumpulan pertama pergi lama. Apabila mata wang dalam status posisi panjang dibahagikan kepada kumpulan ketiga, kemudian menutup kedudukan dan pergi pendek. Jika kedudukan ditutup dalam tempoh tetap, seperti setiap hari atau setiap 8 jam, anda juga boleh menutup kedudukan tanpa berada dalam kumpulan. Cuba sebanyak yang anda boleh.

#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)

Ujian faktor mudah

Faktor jumlah dagangan: Mata wang panjang mudah dengan jumlah dagangan yang rendah dan mata wang pendek dengan jumlah dagangan yang tinggi, yang berprestasi sangat baik, menunjukkan bahawa mata wang popular cenderung menurun.

Faktor harga dagangan: kesan mata wang yang panjang dengan harga yang rendah dan mata wang yang pendek dengan harga yang tinggi adalah sama-sama biasa.

Faktor bilangan transaksi: Prestasi sangat serupa dengan jumlah transaksi. Adalah jelas bahawa korelasi antara faktor jumlah transaksi dan faktor bilangan transaksi sangat tinggi. Malah, korelasi purata antara mereka dalam mata wang yang berbeza telah mencapai 0.97, menunjukkan bahawa kedua-dua faktor sangat serupa. Faktor ini perlu diambil kira ketika mensintesis beberapa faktor.

Faktor momentum 3h: (df_close - df_close. shift (3)) /df_ close. shift(3). iaitu, kenaikan faktor selama 3 jam. Hasil backtest menunjukkan bahawa kenaikan 3 jam mempunyai ciri regresi yang jelas, iaitu, kenaikan lebih mudah jatuh kemudian. Kinerja keseluruhan OK, tetapi juga terdapat tempoh pengunduran dan osilasi yang panjang.

Faktor momentum 24 jam: hasil tempoh pelarasan kedudukan 24 jam adalah baik, hasilnya serupa dengan momentum 3 jam, dan menarik balik lebih kecil.

Faktor perubahan jumlah urus niaga: df_ volume.rolling ((24).mean() /df_ volume. rolling (96). mean(), iaitu nisbah jumlah urus niaga pada hari terakhir kepada jumlah urus niaga dalam tiga hari terakhir. Kedudukan disesuaikan setiap 8 jam. Hasil pengujian kembali adalah baik, dan pengeluaran juga agak rendah, menunjukkan bahawa mereka yang mempunyai jumlah urus niaga aktif lebih cenderung menurun.

Faktor perubahan nombor urus niaga: df_ count.rolling ((24).mean() /df_ count.rolling ((96). mean (), iaitu nisbah nombor urus niaga pada hari terakhir kepada nombor urus niaga dalam tiga hari terakhir. Kedudukan disesuaikan setiap 8 jam. Hasil pengujian kembali adalah baik, dan pengeluaran juga agak rendah, yang menunjukkan bahawa mereka yang mempunyai jumlah urus niaga 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()) , iaitu nisbah nilai transaksi hari terakhir kepada nilai transaksi tiga hari terakhir, dan kedudukan akan diselaraskan setiap 8 jam. Faktor ini juga sangat berkaitan dengan faktor jumlah transaksi.

Faktor perubahan pengambil mengikut nisbah urus niaga: df_buy_ratio.rolling(24).mean() /df_buy_ratio.rolling(96).mean(), iaitu nisbah pengambil mengikut jumlah kepada jumlah urus niaga pada hari terakhir kepada nilai urus niaga dalam tiga hari terakhir, dan kedudukan akan diselaraskan setiap 8 jam. Faktor ini berfungsi dengan cukup baik dan ia mempunyai korelasi yang sedikit dengan faktor jumlah urus niaga.

Faktor turun naik: (df_close/df_open).rolling ((24).std ((), pergi mata wang lama dengan turun naik yang rendah, ia mempunyai kesan tertentu.

Faktor korelasi antara jumlah urus niaga dan harga penutupan: df_close.rolling ((96).corr ((df_volume), harga penutupan dalam empat hari terakhir mempunyai faktor korelasi jumlah urus niaga, yang secara keseluruhan berjalan dengan baik.

Faktor-faktor yang disenaraikan di sini adalah berdasarkan jumlah harga. Malah, gabungan formula faktor boleh menjadi sangat kompleks tanpa logik yang jelas.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 pelbagai faktor

Ia pasti merupakan bahagian yang paling penting dalam proses pembinaan strategi untuk menemui faktor-faktor baru yang berkesan secara berterusan, tetapi tanpa kaedah sintesis faktor yang baik, faktor alfa tunggal yang sangat baik tidak dapat memainkan peranan maksimum.

Kaedah berat yang sama: semua faktor yang akan disintesis ditambahkan dengan berat yang sama untuk mendapatkan faktor baru selepas sintesis.

Kaedah berat kadar pulangan faktor sejarah: semua faktor yang akan digabungkan ditambahkan mengikut purata aritmetik kadar pulangan faktor sejarah dalam tempoh terakhir sebagai berat untuk mendapatkan faktor baru selepas sintesis. Faktor yang berprestasi baik dalam kaedah ini mempunyai berat yang lebih tinggi.

Memaksimumkan kaedah berat IC_IR: nilai IC purata faktor komposit dalam tempoh sejarah digunakan sebagai anggaran nilai IC faktor komposit dalam tempoh seterusnya, dan matriks kovariansi nilai IC sejarah digunakan sebagai anggaran volatiliti faktor komposit dalam tempoh seterusnya. Menurut IC_ IR adalah sama dengan nilai yang dijangkakan IC dibahagikan dengan penyimpangan piawai IC untuk mendapatkan penyelesaian berat optimum faktor komposit maksimum IC_ IR.

Analisis komponen utama (PCA): PCA adalah kaedah biasa untuk pengurangan dimensi data, dan korelasi antara faktor mungkin tinggi. Komponen utama selepas pengurangan dimensi digunakan sebagai faktor sintetik.

Kajian ini akan merujuk kepada penugasan kesahihan faktor secara manual.ae933a8c-5a94-4d92-8f33-d92b70c36119.pdf

Apabila menguji faktor tunggal, pemisahan tetap, tetapi sintesis pelbagai faktor perlu menggabungkan data yang sama sekali berbeza, jadi semua faktor perlu disatukan, dan nilai melampau dan nilai yang hilang perlu dikeluarkan secara amnya.

#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

Kajian ini memperkenalkan kaedah ujian faktor tunggal dan menguji faktor tunggal biasa, dan pada mulanya memperkenalkan kaedah sintesis faktor pelbagai. Walau bagaimanapun, terdapat banyak kandungan penyelidikan faktor pelbagai. Setiap titik yang disebutkan dalam kertas ini boleh dikembangkan lebih lanjut. Ia adalah cara yang layak untuk mengubah penyelidikan mengenai pelbagai strategi ke dalam penerokaan faktor alfa. Penggunaan metodologi faktor dapat mempercepatkan pengesahan idea perdagangan, dan terdapat banyak bahan untuk rujukan.

Bot sebenar dari:https://www.fmz.com/robot/486605


Berkaitan

Lebih lanjut