[TOC]

سٹاک مارکیٹ کے ملٹی فیکٹر ماڈل کے بارے میں متعدد تحقیقی رپورٹس موجود ہیں جن میں بھرپور تھیوری اور پریکٹس موجود ہے۔ ڈیجیٹل کرنسی مارکیٹ فیکٹر ریسرچ کے لیے کافی ہے، قطع نظر کرنسیوں کی تعداد، کل مارکیٹ ویلیو، لین دین کا حجم، ڈیریویٹو مارکیٹ وغیرہ۔ یہ مضمون بنیادی طور پر مقداری حکمت عملیوں کے ابتدائی افراد کے لیے ہے اور اس میں پیچیدہ ریاضیاتی اصول اور شماریاتی تجزیہ شامل نہیں ہوگا۔ فیوچر مارکیٹ کو ڈیٹا سورس کے طور پر، فیکٹر انڈیکیٹرز کی تشخیص کو آسان بنانے کے لیے ایک سادہ فیکٹر ریسرچ فریم ورک بنایا گیا ہے۔
ایک عامل کو ایک اشارے کے طور پر دیکھا جا سکتا ہے اور فیکٹرز مسلسل تبدیل ہوتے ہیں اور عام طور پر، عوامل سرمایہ کاری کی منطق کی نمائندگی کرتے ہیں۔
مثال کے طور پر، اختتامی قیمت کا عنصر اس مفروضے پر مبنی ہوتا ہے کہ اسٹاک کی قیمتیں جتنی زیادہ ہوں گی، مستقبل میں ریٹرن اتنا ہی زیادہ ہوگا (یا اس عنصر کی بنیاد پر پورٹ فولیو بنانا دراصل ایک سرمایہ کاری ہے۔ اعلی قیمت والے اسٹاک خریدنے کے لیے باقاعدگی سے گھومنے والی پوزیشنوں کا ماڈل/حکمت عملی۔ عام طور پر، عوامل جو مسلسل اضافی واپسی پیدا کر سکتے ہیں اکثر الفا کہلاتے ہیں۔ مثال کے طور پر، مارکیٹ کیپٹلائزیشن کے عوامل اور رفتار کے عوامل کو اکیڈمیا اور سرمایہ کاری برادری نے موثر عوامل ہونے کی تصدیق کی ہے۔
چاہے وہ سٹاک مارکیٹ ہو یا ڈیجیٹل کرنسی مارکیٹ، یہ ایک پیچیدہ نظام ہے، کوئی بھی عنصر مستقبل کے منافع کی پوری طرح سے پیشین گوئی نہیں کر سکتا، لیکن اس میں ایک خاص حد تک پیشین گوئی ہے۔ مؤثر الفا (سرمایہ کاری کا ماڈل) آہستہ آہستہ غیر موثر ہو جاتا ہے کیونکہ زیادہ فنڈز لگائے جاتے ہیں۔ لیکن یہ عمل مارکیٹ میں دوسرے ماڈلز پیدا کرے گا، نئے الفا کو جنم دے گا۔ مارکیٹ کیپٹلائزیشن فیکٹر کبھی A-حصص کی مارکیٹ میں ایک بہت ہی موثر حکمت عملی تھی، بس سب سے کم مارکیٹ کیپٹلائزیشن کے ساتھ 10 اسٹاک خریدیں اور انہیں 2007 سے لے کر 10 سالہ بیک ٹیسٹ سے 400 گنا زیادہ فائدہ ہوگا۔ مجموعی مارکیٹ سے زیادہ. تاہم، 2017 میں بلیو چپ اسٹاک مارکیٹ نے چھوٹے مارکیٹ کیپٹلائزیشن فیکٹر کے غیر موثر ہونے کی عکاسی کی، جبکہ ویلیو فیکٹر اس کی بجائے مقبول ہوا۔ اس لیے الفا کی تصدیق اور استعمال کے درمیان مسلسل توازن اور تجربہ کرنا ضروری ہے۔
ہم جن عوامل کی تلاش کرتے ہیں وہ حکمت عملی کے قیام کی بنیاد ہیں متعدد غیر متعلقہ موثر عوامل کو ملا کر بہتر حکمت عملی بنائی جا سکتی ہے۔
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
ابھی تک، 2022 کے آغاز سے لے کر موجودہ وقت تک Binance USDT دائمی مستقبل کا فی گھنٹہ K-line ڈیٹا 150 کرنسیوں سے تجاوز کر چکا ہے۔ جیسا کہ پہلے ذکر کیا گیا ہے، فیکٹر ماڈل کرنسی کے انتخاب کا ماڈل ہے جو صرف ایک مخصوص کرنسی کے بجائے تمام کرنسیوں کو نشانہ بناتا ہے۔ K-line ڈیٹا میں ڈیٹا شامل ہوتا ہے جیسے کہ اونچی اوپننگ اور کم بند ہونے والی قیمتیں، تجارتی حجم، لین دین کی تعداد، فعال خریداری والیوم وغیرہ۔ یہ ڈیٹا یقینی طور پر تمام عوامل کا ذریعہ نہیں ہیں، جیسے کہ امریکی اسٹاک انڈیکس، شرح سود میں اضافے کی توقعات۔ ، منافع، آن چین ڈیٹا، سوشل میڈیا توجہ، وغیرہ۔ کم مقبول ڈیٹا کے ذرائع بھی مؤثر الفا کو ظاہر کر سکتے ہیں، لیکن بنیادی حجم اور قیمت کا ڈیٹا بھی کافی ہے۔
## 当前交易对
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)
Out:
['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))
Out:
153
#获取任意周期K线的函数
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)
Out:
Index(['time', 'open', 'high', 'low', 'close', 'amount', 'end_time', 'volume',
'count', 'buy_amount', 'buy_volume', 'null'],
dtype='object')
ہم ابتدائی طور پر 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')
مارکیٹ انڈیکس کی کارکردگی کو دیکھتے ہوئے اسے کافی تاریک کہا جا سکتا ہے، سال کے آغاز سے اب تک اس میں 60 فیصد کی کمی واقع ہوئی ہے۔
df_norm = df_close/df_close.fillna(method='bfill').iloc[0] #归一化
df_norm.mean(axis=1).plot(figsize=(15,6),grid=True);
#最终指数收益图

رجعت کا طریقہ اگلی مدت کی واپسی کی شرح کو منحصر متغیر کے طور پر لیا جاتا ہے، جس عنصر کی جانچ کی جاتی ہے اسے آزاد متغیر کے طور پر لیا جاتا ہے، اور رجعت سے حاصل کردہ عدد فیکٹر کی واپسی کی شرح ہے۔ رجعت کی مساوات کو بنانے کے بعد، ہم عام طور پر عددی t قدر کے مطلق اوسط کا حوالہ دیتے ہیں، عددی t قدر کی 2 سے زیادہ کی مطلق قدر کی ترتیب کا تناسب، سالانہ عنصر کی واپسی، سالانہ عنصر کی واپسی کا اتار چڑھاؤ، کا تیز تناسب عنصر کی واپسی اور دیگر پیرامیٹرز کی تاثیر اور اتار چڑھاؤ۔ آپ ایک ہی وقت میں متعدد عوامل کو واپس لے سکتے ہیں، تفصیلات کے لیے بارا دستاویزات سے رجوع کریں۔
آئی سی، آئی آر اور دیگر اشارے نام نہاد IC فیکٹر اور اگلی مدت کی واپسی کی شرح کے درمیان ارتباط کا گتانک ہے جو عام طور پر عام طور پر فیکٹر کی درجہ بندی اور اگلی مدت کے ریٹ آف سٹاک کے درمیان ارتباط کا گتانک ہے۔ IR عام طور پر IC ترتیب/IC ترتیب کے معیاری انحراف کا اوسط ہوتا ہے۔
درجہ بندی رجعت یہ مضمون اس طریقہ کو استعمال کرے گا، جس کا مقصد جانچے جانے والے عوامل کو ترتیب دینا، گروپ بیک ٹیسٹنگ کے لیے کرنسیوں کو N گروپس میں تقسیم کرنا، اور پوزیشنز کو ایڈجسٹ کرنے کے لیے ایک مقررہ مدت کا استعمال کرنا ہے۔ اگر صورت حال مثالی ہے تو، کرنسیوں کے N گروپوں کی پیداوار اچھی یک جہتی ظاہر کرے گی، یکجہتی طور پر بڑھ رہی ہے یا کم ہوتی ہے، اور ہر گروپ کے درمیان پیداوار کا فرق بڑا ہوگا۔ ایسے عوامل بہتر امتیازی سلوک میں جھلکتے ہیں۔ اگر پہلے گروپ کی واپسی سب سے زیادہ ہے اور آخری گروپ کی سب سے کم واپسی ہے، تو پہلے گروپ پر لمبا اور آخری گروپ پر مختصر واپسی کی شرح تیز تناسب کا ایک حوالہ اشارہ ہے۔
عوامل کے مطابق، منتخب کرنسیوں کو 3 گروپوں میں تقسیم کیا جاتا ہے چھوٹے سے بڑے کے حساب سے کرنسیوں کے ہر گروپ میں تقریبا 1⁄3 ہوتا ہے، ہر گروپ کا تناسب جتنا چھوٹا ہوتا ہے۔ پیداوار، لیکن اس کا مطلب یہ بھی ہے کہ ہر کرنسی کے لیے مختص کیے گئے فنڈز نسبتاً زیادہ ہیں اگر ہر ایک 1x لیوریجڈ ہیں، اور پہلے اور آخری گروپوں میں بالترتیب 10 کرنسی ہیں، تو ہر ایک کا حساب 10% ہے۔ مختصر اضافہ، اگر سرمایہ کاری کی رقم میں 2 گنا اضافہ ہوتا ہے، تو ریٹیسمنٹ 20% ہو جائے گا، اسی طرح، اگر گروپوں کی تعداد 50 ہے، تو واپسی 4% ہو گی۔ کرنسیوں کو متنوع بنانے سے کالے ہنس کے خطرے کو کم کیا جا سکتا ہے۔ پہلے گروپ پر لمبا (سب سے چھوٹی فیکٹر ویلیو کے ساتھ) اور تیسرے گروپ پر مختصر۔ اگر فیکٹر جتنا بڑا ہے، ریٹرن اتنا ہی زیادہ ہے، تو آپ لمبی اور چھوٹی پوزیشنوں کو ریورس کر سکتے ہیں یا فیکٹر کو منفی یا الٹا بنا سکتے ہیں۔
عام طور پر کسی عنصر کی پیشین گوئی کی طاقت کا اندازہ حتمی بیک ٹیسٹ ریٹرن اور تیز تناسب کی بنیاد پر لگایا جا سکتا ہے۔ اس کے علاوہ، اس بات کا حوالہ دینا بھی ضروری ہے کہ آیا عنصر کا اظہار سادہ ہے، گروپ بندی کے سائز کے لیے غیر حساس، پوزیشن ایڈجسٹمنٹ وقفہ کے لیے غیر حساس، بیک ٹیسٹ کے ابتدائی وقت کے لیے غیر حساس، وغیرہ۔
پوزیشن ایڈجسٹمنٹ کی فریکوئنسی کے بارے میں، اسٹاک مارکیٹ میں اکثر 5 دن، 10 دن اور ایک ماہ کا چکر ہوتا ہے، لیکن ڈیجیٹل کرنسی مارکیٹ کے لیے ایسا چکر بلاشبہ بہت طویل ہوتا ہے، اور حقیقی مارکیٹ میں مارکیٹ کے حالات پر نظر رکھی جاتی ہے۔ حقیقی وقت، اس لیے کسی مخصوص سائیکل پر قائم رہنا مشکل ہے، اس لیے پوزیشنز کو دوبارہ ایڈجسٹ کرنے کی ضرورت نہیں ہے، لہذا حقیقی ٹریڈنگ میں ہم پوزیشنز کو حقیقی وقت میں یا مختصر وقت میں ایڈجسٹ کرتے ہیں۔
پوزیشن کو بند کرنے کے طریقہ کے بارے میں، روایتی طریقہ کے مطابق، آپ پوزیشن کو بند کر سکتے ہیں اگر وہ اگلی ترتیب کے دوران گروپ میں نہیں ہے۔ تاہم، ریئل ٹائم پوزیشن ایڈجسٹمنٹ کی صورت میں، کچھ کرنسیاں تقسیم کرنے والی لائن پر ہوسکتی ہیں، اور پوزیشنز آگے پیچھے بند ہوسکتی ہیں۔ لہذا، یہ حکمت عملی گروپ بندی میں تبدیلیوں اور پوزیشنوں کو بند کرنے کا انتظار کرنے کا طریقہ اپناتی ہے جب مخالف سمت میں پوزیشنیں کھولنا ضروری ہوتا ہے، مثال کے طور پر، اگر آپ پہلے گروپ میں طویل ہوتے ہیں، جب لانگ پوزیشن میں کرنسی کو تقسیم کیا جاتا ہے۔ تیسرے گروپ، آپ پوزیشن کو بند کر سکتے ہیں اور مختصر جا سکتے ہیں. اگر آپ ایک مقررہ مدت پر پوزیشنیں بند کرتے ہیں، جیسے کہ ہر دن یا ہر 8 گھنٹے، تو آپ گروپ میں شامل کیے بغیر بھی پوزیشنیں بند کر سکتے ہیں۔ آپ مزید کوشش کر سکتے ہیں۔
#回测引擎
class Exchange:
def __init__(self, trade_symbols, fee=0.0004, initial_balance=10000):
self.initial_balance = initial_balance #初始的资产
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 #扣除手续费
self.account['USDT']['fee'] += price*amount*self.fee
self.account[symbol]['fee'] += price*amount*self.fee
if cover_amount > 0: #先平仓
self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount #利润
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): #对资产进行更新
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)
#测试因子的函数
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)
حجم کا عنصر: کم حجم والے سکوں پر صرف لمبا جانا اور زیادہ والیوم والے سکوں پر مختصر کرنا بہت اچھی کارکردگی کا مظاہرہ کرتا ہے، جو ظاہر کرتا ہے کہ مقبول سکوں کے گرنے کا زیادہ امکان ہے۔
لین دین کی قیمت کا عنصر: لمبی کم قیمت والی کرنسیاں، مختصر زیادہ قیمت والی کرنسیاں، اثر اوسط ہے۔
لین دین کے عنصر کی تعداد: کارکردگی حجم سے بہت ملتی جلتی ہے۔ یہ ظاہر ہے کہ حجم کے عنصر اور لین دین کے عنصر کے درمیان باہمی تعلق بہت زیادہ ہے، درحقیقت مختلف کرنسیوں میں ان کے درمیان اوسط ارتباط 0.97 ہے، جس سے ظاہر ہوتا ہے کہ یہ دونوں عوامل بہت مماثل ہیں۔ اکاؤنٹ میں
3h رفتار کا عنصر: (df_close - df_close.shift(3))/df_close.shift(3)۔ یعنی فیکٹر کا 3 گھنٹے کا اضافہ یہ ظاہر کرتا ہے کہ 3 گھنٹے کا اضافہ واضح ریگریشن کی خصوصیت رکھتا ہے، یعنی اگلی مدت میں یہ اضافہ گرنے کا زیادہ امکان ہے۔ مجموعی کارکردگی اچھی ہے، لیکن پل بیک اور دوغلے پن کے طویل ادوار بھی ہیں۔
24 گھنٹہ مومنٹم فیکٹر: 24 گھنٹے ری بیلنسنگ سائیکل کے نتائج بہت اچھے ہیں، جس میں 3 گھنٹے کی رفتار کی طرح واپسی اور ایک چھوٹا ڈرا ڈاؤن ہے۔
ٹرن اوور کی تبدیلی کا عنصر: df_volume.rolling(24).mean() / df_volume.rolling(96).mean()، جو کہ حالیہ تین دنوں کے ٹرن اوور کا تناسب ہے۔ ہر 8 گھنٹے میں ایڈجسٹ کیا جاتا ہے. بیک ٹیسٹ کے نتائج نسبتاً اچھے ہیں اور ریٹیسمنٹ نسبتاً کم ہے، جو ظاہر کرتا ہے کہ فعال تجارتی حجم والے اسٹاک کے گرنے کا امکان زیادہ ہے۔
ٹرانزیکشن نمبر کی تبدیلی کا عنصر: df_count.rolling(24).mean() / df_count.rolling(96).mean()، جو کہ آخری دن کی ٹرانزیکشنز کی تعداد اور پچھلے تین دنوں میں ٹرانزیکشنز کی تعداد کا تناسب ہے۔ پوزیشن ہر 8 گھنٹے میں ایڈجسٹ کی جاتی ہے۔ بیک ٹیسٹ کے نتائج نسبتاً اچھے ہیں اور ریٹیسمنٹ نسبتاً کم ہے، جو ظاہر کرتا ہے کہ جیسے جیسے لین دین کی تعداد بڑھتی ہے، مارکیٹ زیادہ فعال طور پر گرتی ہے۔
واحد لین دین کی قدر میں تبدیلی کا عنصر: -(df_volume.rolling(24).mean()/df_count.rolling(24).mean())/(df_volume.rolling(24).mean()/df_count.rolling(96).mean()) جو کہ حالیہ ترین دن کی لین دین کی قیمت اور حالیہ تین دنوں کی لین دین کی قیمت کا تناسب ہے، اور پوزیشن ہر 8 گھنٹے بعد ایڈجسٹ کی جاتی ہے۔ یہ عنصر حجم کے عنصر کے ساتھ بھی بہت زیادہ منسلک ہے۔
فعال لین دین کے تناسب میں تبدیلی کا عنصر: df_buy_ratio.rolling(24).mean()/df_buy_ratio.rolling(96).mean()، یعنی، لین دین کے آخری دن کے کل لین دین کے حجم سے فعال خرید کے حجم کا تناسب گزشتہ تین دنوں میں قدر، ہر 8 گھنٹے پوزیشن کو ایڈجسٹ کریں. یہ عنصر اچھی کارکردگی کا مظاہرہ کرتا ہے اور حجم کے عنصر سے بہت کم تعلق رکھتا ہے۔
اتار چڑھاؤ کا عنصر: (df_close/df_open).rolling(24).std()، جس کا ایک خاص اثر ہوتا ہے جب کم اتار چڑھاؤ والی کرنسیوں پر طویل چلتے ہیں۔
تجارتی حجم اور اختتامی قیمت کے درمیان ارتباط کا عنصر: df_close.rolling(96).corr(df_volume)، آخری 4 دنوں میں اختتامی قیمت اور تجارتی حجم کے درمیان ارتباط کا عنصر، مجموعی کارکردگی اچھی ہے۔
یہاں صرف مقدار اور قیمت پر مبنی کچھ عوامل درج ہیں، حقیقت میں، فیکٹر فارمولوں کا مجموعہ بہت پیچیدہ ہوسکتا ہے اور اس میں واضح منطق نہیں ہوسکتی ہے۔ آپ مشہور ALPHA101 فیکٹر تعمیراتی طریقہ کا حوالہ دے سکتے ہیں: https://github.com/STHSF/alpha101۔
#成交量
factor_volume = df_volume
factor_volume_res = Test(factor_volume, symbols, period=4)
factor_volume_res.total.plot(figsize=(15,6),grid=True);

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

#成交笔数
factor_count = df_count
factor_count_res = Test(factor_count, symbols, period=8)
factor_count_res.total.plot(figsize=(15,6),grid=True);

print(df_count.corrwith(df_volume).mean())
0.9671246744996017
#3小时动量因子
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);

#24小时动量因子
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);

#成交量因子
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);

#成交笔数因子
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);

#因子相关性
print(factor_4.corrwith(factor_3).mean())
0.9707239580854841
#单笔成交价值因子
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);

print(factor_4.corrwith(factor_5).mean())
0.861206620552479
#主动成交比例因子
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);

print(factor_3.corrwith(factor_6).mean())
0.1534572192503726
#波动率因子
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);

#成交量和收盘价相关性因子
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);

نئے موثر عوامل کو مسلسل دریافت کرنا یقیناً حکمت عملی کی تعمیر کے عمل کا سب سے اہم حصہ ہے، لیکن ایک اچھے عنصر کی ترکیب کے طریقہ کار کے بغیر، ایک بہترین واحد الفا فیکٹر اپنا زیادہ سے زیادہ کردار ادا نہیں کر سکتا۔ عام کثیر عنصر ترکیب کے طریقوں میں شامل ہیں:
مساوی وزن کا طریقہ: نئے ترکیبی عوامل حاصل کرنے کے لیے تمام عوامل کو مساوی وزن کے ساتھ جوڑا جاتا ہے۔
تاریخی عنصر کی واپسی کا وزنی طریقہ: ترکیب کیے جانے والے تمام عوامل کو نئے ترکیبی عوامل حاصل کرنے کے لیے حالیہ عرصے میں تاریخی عنصر کی واپسی کے حسابی اوسط کے مطابق ایک ساتھ جوڑا جاتا ہے۔ یہ طریقہ ان عوامل کو زیادہ وزن دیتا ہے جو اچھی کارکردگی کا مظاہرہ کرتے ہیں۔
IC_IR وزنی طریقہ کو زیادہ سے زیادہ بنانا: تاریخ کے ایک عرصے کے دوران جامع عنصر کی اوسط IC قدر کو اگلے دور میں جامع عنصر کی IC قدر کے تخمینہ کے طور پر استعمال کیا جاتا ہے، اور تاریخی IC قدر کا ہم آہنگی میٹرکس تخمینہ کے طور پر استعمال کیا جاتا ہے۔ اگلے پیریڈ میں کمپوزٹ فیکٹر کی اتار چڑھاؤ IC کی متوقع قدر کے برابر ہے جسے IC کے معیاری انحراف سے تقسیم کیا جاتا ہے، اور مرکب عنصر IC_IR کو زیادہ سے زیادہ کرنے کے لیے بہترین وزن کا حل حاصل کیا جا سکتا ہے۔
پرنسپل اجزاء کا تجزیہ (PCA) طریقہ: PCA عام طور پر ڈیٹا کی جہت میں کمی کے لیے استعمال ہونے والا طریقہ ہے، عوامل کے درمیان ارتباط نسبتاً زیادہ ہو سکتا ہے، اور جہتی کمی کے بعد بنیادی اجزاء کو ترکیب شدہ عوامل کے طور پر استعمال کیا جاتا ہے۔
یہ مضمون دستی طور پر فیکٹر کی توثیق کے وزن کا حوالہ دے گا۔ اوپر بیان کردہ طریقہ کا حوالہ دے سکتے ہیں:ae933a8c-5a94-4d92-8f33-d92b70c36119.pdf
ایک عنصر کی جانچ کرتے وقت، ترتیب طے ہوتی ہے، لیکن کثیر عنصر کی ترکیب کے لیے مکمل طور پر مختلف ڈیٹا کو ایک ساتھ ضم کرنے کی ضرورت ہوتی ہے، اس لیے تمام عوامل کو معیاری بنانے کی ضرورت ہوتی ہے، اور عام طور پر انتہائی قدروں اور گمشدہ اقدار کو ہٹانے کی ضرورت ہوتی ہے۔ یہاں ہم ترکیب کے لیے df_volume\factor_1\factor_7\factor_6\factor_8 استعمال کرتے ہیں۔
#标准化函数,去除缺失值和极值,并且进行标准化处理
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);

یہ مضمون سنگل فیکٹر ٹیسٹ کا طریقہ متعارف کراتا ہے اور عام واحد عوامل کی جانچ کرتا ہے، اور ابتدائی طور پر ملٹی فیکٹر کی ترکیب کا طریقہ متعارف کرایا جاتا ہے، تاہم، مضمون میں بیان کردہ ہر نکتے کو گہرائی میں بڑھایا جا سکتا ہے۔ اس طرح کی حکمت عملی کی تحقیق کو الفا عوامل کی دریافت میں تبدیل کرنا ایک قابل عمل طریقہ ہے۔
اصل پتہ: https://www.fmz.com/robot/486605