बैकटेस्टिंग प्रयोजनों के लिए निरंतर वायदा अनुबंध

लेखक:अच्छाई, बनाया गयाः 2019-03-18 10:48:28, अद्यतन किया गयाः

वायदा अनुबंधों का संक्षिप्त अवलोकन

फ्यूचर्स एक प्रकार का अनुबंध है जो भविष्य में एक निर्दिष्ट तिथि पर एक अंतर्निहित संपत्ति की मात्रा की खरीद या बिक्री के लिए दो पक्षों के बीच तैयार किया जाता है। इस तारीख को डिलीवरी या समाप्ति के रूप में जाना जाता है। जब यह तारीख पहुंच जाती है तो खरीदार को भौतिक अंतर्निहित (या नकदी समकक्ष) को विक्रेता को अनुबंध गठन की तारीख पर सहमत मूल्य के लिए वितरित करना चाहिए।

फ्यूचर्स का उपयोग अक्सर कृषि या औद्योगिक वस्तुओं की कीमतों को कवर करने के लिए किया जाता था, लेकिन फ्यूचर्स अनुबंध किसी भी मूर्त या अमूर्त आधार पर बनाया जा सकता है जैसे स्टॉक सूचकांक, विदेशी मुद्रा मूल्यों की ब्याज दरें।

विभिन्न एक्सचेंजों में फ्यूचर्स अनुबंधों के लिए उपयोग किए जाने वाले सभी प्रतीक कोडों की विस्तृत सूची सीएसआई डेटा साइटः फ्यूचर्स फैक्टशीट पर पाई जा सकती है।

वायदा अनुबंध और इक्विटी स्वामित्व के बीच मुख्य अंतर यह है कि वायदा अनुबंध में समाप्ति तिथि के आधार पर उपलब्धता की एक सीमित खिड़की होती है। किसी भी एक क्षण में एक ही अंतर्निहित पर विभिन्न प्रकार के वायदा अनुबंध होंगे, जिनमें समाप्ति की विभिन्न तिथियां हैं। निकटतम समाप्ति तिथि के साथ अनुबंध को निकटतम अनुबंध के रूप में जाना जाता है। मात्रात्मक व्यापारियों के रूप में हमारी समस्या यह है कि किसी भी समय में हमारे पास कई अनुबंधों का विकल्प है जिनके साथ व्यापार करना है। इस प्रकार हम इक्विटी या विदेशी मुद्रा के मामले में एक निरंतर धारा के बजाय समय श्रृंखलाओं के एक ओवरलैप सेट से निपट रहे हैं।

इस लेख का उद्देश्य बहु श्रृंखलाओं के इस सेट से अनुबंधों के निरंतर प्रवाह के निर्माण के लिए विभिन्न दृष्टिकोणों की रूपरेखा तैयार करना और प्रत्येक तकनीक से जुड़े व्यापारों को उजागर करना है।

निरंतर वायदा अनुबंध बनाना

विभिन्न डिलीवरी के साथ अंतर्निहित अनुबंधों से एक निरंतर अनुबंध उत्पन्न करने की कोशिश करने में मुख्य कठिनाई यह है कि अनुबंध अक्सर एक ही कीमतों पर व्यापार नहीं करते हैं। इस प्रकार ऐसी स्थितियां उत्पन्न होती हैं जहां वे एक से दूसरे तक एक चिकनी स्प्लिट प्रदान नहीं करते हैं। यह कॉन्टेंगो और बैकवर्डेशन प्रभावों के कारण है। इस समस्या से निपटने के लिए विभिन्न दृष्टिकोण हैं, जिन पर हम अब चर्चा करते हैं।

सामान्य दृष्टिकोण

दुर्भाग्य से वित्तीय उद्योग में वायदा अनुबंधों को एक साथ जोड़ने के लिए कोई एकल मानक विधि नहीं है। अंततः चुनी गई विधि अनुबंधों को नियोजित करने वाली रणनीति और निष्पादन की विधि पर बहुत निर्भर करेगी। इस तथ्य के बावजूद कि कोई एकल विधि मौजूद नहीं है, कुछ सामान्य दृष्टिकोण हैंः

बैक/फॉरवर्ड (पनामा) समायोजन

यह विधि प्रत्येक अनुबंध को स्थानांतरित करके कई अनुबंधों में अंतर को कम करती है ताकि व्यक्तिगत वितरण आसन्न अनुबंधों के साथ सुचारू रूप से जुड़ सकें। इस प्रकार समाप्ति पर पिछले अनुबंधों के बीच खुला / बंद मेल खाता है।

पनामा पद्धति के साथ मुख्य समस्या में एक प्रवृत्ति पूर्वाग्रह की शुरूआत शामिल है, जो कीमतों में एक बड़ा बहाव पेश करेगा। इससे पर्याप्त ऐतिहासिक अनुबंधों के लिए नकारात्मक डेटा हो सकता है। इसके अलावा मूल्यों में पूर्ण बदलाव के कारण सापेक्ष मूल्य अंतर का नुकसान होता है। इसका मतलब है कि रिटर्न की गणना करना जटिल है (या बस सादा गलत है) ।

आनुपातिक समायोजन

आनुपातिकता समायोजन दृष्टिकोण इक्विटी में स्टॉक स्प्लिट्स को संभालने के समायोजन पद्धति के समान है। लगातार अनुबंधों में पूर्ण बदलाव करने के बजाय, पुराने निपटान (बंद) मूल्य के अनुपात का उपयोग ऐतिहासिक अनुबंधों की कीमतों को आनुपातिक रूप से समायोजित करने के लिए किया जाता है। यह प्रतिशत रिटर्न की गणना के व्यवधान के बिना निरंतर प्रवाह की अनुमति देता है।

आनुपातिक समायोजन के साथ मुख्य मुद्दा यह है कि सही संकेत को निष्पादित करने के लिए पूर्ण मूल्य स्तर पर निर्भर किसी भी ट्रेडिंग रणनीतियों को भी इसी तरह से समायोजित किया जाना होगा। यह एक समस्याग्रस्त और त्रुटि-प्रवण प्रक्रिया है। इस प्रकार इस प्रकार की निरंतर धारा अक्सर केवल संक्षिप्त सांख्यिकीय विश्लेषण के लिए उपयोगी होती है, प्रत्यक्ष बैकटेस्टिंग अनुसंधान के विपरीत।

रोलओवर/परप्युटेट सीरीज

इस दृष्टिकोण का सार यह है कि प्रत्येक अनुबंध के बीच सुचारू संक्रमण सुनिश्चित करने के लिए प्रत्येक अनुबंध के लिए कई दिनों में एक रैखिक रूप से भारित अनुपात लेते हुए लगातार अनुबंधों का एक निरंतर अनुबंध बनाया जाए।

उदाहरण के लिए पांच स्मूलिंग दिनों पर विचार करें। दिन 1, P1 पर कीमत दूर अनुबंध मूल्य (F1) के 80% और निकट अनुबंध मूल्य (N1) के 20% के बराबर है। इसी तरह, दिन 2 पर कीमत P2=0.6×F2+0.4×N2 है। दिन 5 तक हमारे पास P5=0.0×F5+1.0×N5=N5 है और अनुबंध तब केवल निकट मूल्य की निरंतरता बन जाता है। इस प्रकार पांच दिनों के बाद अनुबंध सुचारू रूप से दूर से निकट में संक्रमण होता है।

रोलओवर पद्धति की समस्या यह है कि इसके लिए पांचों दिनों में ट्रेडिंग की आवश्यकता होती है, जिससे लेनदेन की लागत बढ़ सकती है।

इस समस्या के लिए अन्य कम आम दृष्टिकोण हैं लेकिन हम यहां उनसे बचेंगे।

पायथन और पांडा में रोल-रिटर्न गठन

शेष लेख में अनंत श्रृंखला पद्धति को लागू करने पर ध्यान केंद्रित किया जाएगा क्योंकि यह बैकटेस्टिंग के लिए सबसे उपयुक्त है। यह रणनीति पाइपलाइन अनुसंधान करने का एक उपयोगी तरीका है।

हम एक निरंतर मूल्य श्रृंखला उत्पन्न करने के लिए डब्ल्यूटीआई कच्चे तेल निकट और दूर वायदा अनुबंध (प्रतीक सीएल) को एक साथ सिलाई करने जा रहे हैं। लेखन के समय (जनवरी 2014) में, निकट अनुबंध सीएलएफ2014 (जनवरी) है और दूर अनुबंध सीएलजी2014 (फरवरी) है।

वायदा डेटा डाउनलोड करने के लिए मैंने Quandl प्लगइन का उपयोग किया है. अपने सिस्टम पर सही पायथन आभासी वातावरण सेट करना सुनिश्चित करें और टर्मिनल में निम्न टाइप करके Quandl पैकेज स्थापित करें:

import datetime
import numpy as np
import pandas as pd
import Quandl

मुख्य कार्य फ्यूचर्स_रोलओवर_वेट्स फ़ंक्शन में किया जाता है। इसके लिए एक प्रारंभ तिथि (नज़दीकी अनुबंध की पहली तिथि), अनुबंध निपटान तिथियों (समाप्ति तिथि), अनुबंधों के प्रतीकों और अनुबंध को रोल करने के लिए दिनों की संख्या (डिफ़ॉल्ट रूप से पांच तक) की आवश्यकता होती है। नीचे दी गई टिप्पणियों में कोड की व्याख्या की गई हैः

def futures_rollover_weights(start_date, expiry_dates, contracts, rollover_days=5):
    """This constructs a pandas DataFrame that contains weights (between 0.0 and 1.0)
    of contract positions to hold in order to carry out a rollover of rollover_days
    prior to the expiration of the earliest contract. The matrix can then be
    'multiplied' with another DataFrame containing the settle prices of each
    contract in order to produce a continuous time series futures contract."""

    # Construct a sequence of dates beginning from the earliest contract start
    # date to the end date of the final contract
    dates = pd.date_range(start_date, expiry_dates[-1], freq='B')

    # Create the 'roll weights' DataFrame that will store the multipliers for
    # each contract (between 0.0 and 1.0)
    roll_weights = pd.DataFrame(np.zeros((len(dates), len(contracts))),
                                index=dates, columns=contracts)
    prev_date = roll_weights.index[0]

    # Loop through each contract and create the specific weightings for
    # each contract depending upon the settlement date and rollover_days
    for i, (item, ex_date) in enumerate(expiry_dates.iteritems()):
        if i < len(expiry_dates) - 1:
            roll_weights.ix[prev_date:ex_date - pd.offsets.BDay(), item] = 1
            roll_rng = pd.date_range(end=ex_date - pd.offsets.BDay(),
                                     periods=rollover_days + 1, freq='B')

            # Create a sequence of roll weights (i.e. [0.0,0.2,...,0.8,1.0]
            # and use these to adjust the weightings of each future
            decay_weights = np.linspace(0, 1, rollover_days + 1)
            roll_weights.ix[roll_rng, item] = 1 - decay_weights
            roll_weights.ix[roll_rng, expiry_dates.index[i+1]] = decay_weights
        else:
            roll_weights.ix[prev_date:, item] = 1
        prev_date = ex_date
    return roll_weights

अब जब भारन मैट्रिक्स का उत्पादन किया गया है, तो इसे व्यक्तिगत समय श्रृंखलाओं पर लागू करना संभव है। मुख्य कार्य निकट और दूर के अनुबंधों को डाउनलोड करता है, दोनों के लिए एक एकल डेटाफ्रेम बनाता है, रोलओवर भारन मैट्रिक्स का निर्माण करता है और फिर अंत में दोनों कीमतों की एक निरंतर श्रृंखला का उत्पादन करता है, जो उचित रूप से भारित हैः

if __name__ == "__main__":
    # Download the current Front and Back (near and far) futures contracts
    # for WTI Crude, traded on NYMEX, from Quandl.com. You will need to 
    # adjust the contracts to reflect your current near/far contracts 
    # depending upon the point at which you read this!
    wti_near = Quandl.get("OFDP/FUTURE_CLF2014")
    wti_far = Quandl.get("OFDP/FUTURE_CLG2014")
    wti = pd.DataFrame({'CLF2014': wti_near['Settle'],
                        'CLG2014': wti_far['Settle']}, index=wti_far.index)

    # Create the dictionary of expiry dates for each contract
    expiry_dates = pd.Series({'CLF2014': datetime.datetime(2013, 12, 19),
                              'CLG2014': datetime.datetime(2014, 2, 21)}).order()

    # Obtain the rollover weighting matrix/DataFrame
    weights = futures_rollover_weights(wti_near.index[0], expiry_dates, wti.columns)

    # Construct the continuous future of the WTI CL contracts
    wti_cts = (wti * weights).sum(1).dropna()

    # Output the merged series of contract settle prices
    wti_cts.tail(60)

आउटपुट निम्नानुसार है:

2013-10-14 102.230 2013-10-15 101.240 2013-10-16 102,330 2013-10-17 100.620 2013-10-18 100.990 2013-10-21 99.760 2013-10-22 98.470 2013-10-23 97.000 2013-10-24 97.240 2013-10-25 97.950 ... ... 2013-12-24 99.220 2013-12-26 99.550 2013-12-27 100.320 2013-12-30 99.290 2013-12-31 98.420 2014-01-02 95.440 2014-01-03 93.960 2014-01-06 93.430 2014-01-07 93.670 2014-01-08 92.330 लंबाईः 60, dप्रकारः फ्लोट64

यह देखा जा सकता है कि श्रृंखला अब दोनों अनुबंधों में निरंतर है। अगला कदम आपकी बैकटेस्टिंग आवश्यकताओं के आधार पर विभिन्न वर्षों में कई डिलीवरी के लिए इसे पूरा करना है।


अधिक