পাইথনের সাথে ইভেন্ট-চালিত ব্যাকটেস্টিং - অংশ VII

লেখক:ভাল, তৈরিঃ 2019-03-26 10:52:49, আপডেটঃ

ইভেন্ট চালিত ব্যাকটেস্টার সিরিজের শেষ নিবন্ধে আমরা একটি মৌলিক এক্সিকিউশনহ্যান্ডলার শ্রেণিবিন্যাস বিবেচনা করেছি। এই নিবন্ধে আমরা পোর্টফোলিও অবজেক্টে পূর্বে নির্মিত ইক্যুইটি বক্ররেখা ডেটাফ্রেম ব্যবহার করে ব্যাকটেস্টের পরে কৌশলটির পারফরম্যান্স কীভাবে মূল্যায়ন করা যায় তা নিয়ে আলোচনা করতে যাচ্ছি।

পারফরম্যান্স মেট্রিক্স

শার্প রেসিও সম্পর্কে আমরা একটি পূর্ববর্তী নিবন্ধে আলোচনা করেছি। সেই নিবন্ধে আমি উল্লেখ করেছি যে (বার্ষিক) শার্প রেসিও গণনা করা হয়ঃimg

যেখানে Ra হ'ল ইকুইটি কার্ভের রিটার্ন স্ট্রিম এবং Rb হ'ল একটি রেফারেন্স মার্ক, যেমন একটি উপযুক্ত সুদের হার বা ইকুইটি সূচক।

সর্বাধিক ড্রডাউন এবং ড্রডাউন সময়কাল হল দুটি অতিরিক্ত পরিমাপ যা বিনিয়োগকারীরা প্রায়ই একটি পোর্টফোলিওতে ঝুঁকি মূল্যায়ন করতে ব্যবহার করে। প্রথম পরিমাণটি একটি ইক্যুইটি বক্ররেখার পারফরম্যান্সের সর্বোচ্চ পিক-টু-ড্রপ হ্রাস হিসাবে সংজ্ঞায়িত করা হয়, যখন দ্বিতীয়টি ট্রেডিং সময়ের সংখ্যা হিসাবে সংজ্ঞায়িত করা হয় যা এটি ঘটে।

এই নিবন্ধে আমরা পাইথন ভিত্তিক ইভেন্ট-ড্রিভেন ব্যাকটেস্টিং স্যুট ব্যবহারের জন্য পোর্টফোলিও পারফরম্যান্সের পরিমাপ হিসাবে শার্প অনুপাত, সর্বাধিক ড্রডাউন এবং ড্রডাউন সময়কাল বাস্তবায়ন করব।

পাইথন বাস্তবায়ন

প্রথম কাজ হল একটি নতুন ফাইল তৈরি করাperformance.py, যা শার্প অনুপাত এবং ড্রাউনডাউন তথ্য গণনা করার জন্য ফাংশন সংরক্ষণ করে। আমাদের বেশিরভাগ গণনা-ভারী ক্লাসের মতো আমাদের NumPy এবং পান্ডা আমদানি করতে হবেঃ

# performance.py

import numpy as np
import pandas as pd

লক্ষ্য করুন যে শার্প রেসিও হ'ল ঝুঁকি থেকে পুরষ্কারের পরিমাপ (আসলে এটি অনেকের মধ্যে একটি) । এটির একটি মাত্র পরামিতি রয়েছে, যা বার্ষিক মান পর্যন্ত স্কেল করার সময় সামঞ্জস্য করার সময় সময়ের সংখ্যা।

সাধারণত এই মানটি 252 এ সেট করা হয়, যা মার্কিন যুক্তরাষ্ট্রে প্রতি বছর ট্রেডিং দিনের সংখ্যা। যাইহোক, যদি আপনার কৌশলটি ঘন্টার মধ্যে ট্রেড করে তবে আপনাকে এটি সঠিকভাবে বার্ষিকীকরণের জন্য শার্পকে সামঞ্জস্য করতে হবে। সুতরাং আপনাকে 2526.5=1638 এ সময়কাল সেট করতে হবে, যা এক বছরের মধ্যে মার্কিন যুক্তরাষ্ট্রের ট্রেডিং ঘন্টা সংখ্যা। যদি আপনি মিনিট ভিত্তিতে ট্রেড করেন তবে এই ফ্যাক্টরটি 2526.560=98280 এ সেট করতে হবে।

create_sharpe_ratio ফাংশনটি রিটার্নস নামে একটি পান্ডা সিরিজ অবজেক্টে কাজ করে এবং কেবলমাত্র সময়ের শতাংশ রিটার্ন এবং সময়ের শতাংশ রিটার্ন স্ট্যান্ডার্ড ডিভিয়েশনগুলির মধ্যম এবং সময়ের ফ্যাক্টর দ্বারা স্কেল করা অনুপাত গণনা করেঃ

# performance.py

def create_sharpe_ratio(returns, periods=252):
    """
    Create the Sharpe ratio for the strategy, based on a 
    benchmark of zero (i.e. no risk-free rate information).

    Parameters:
    returns - A pandas Series representing period percentage returns.
    periods - Daily (252), Hourly (252*6.5), Minutely(252*6.5*60) etc.
    """
    return np.sqrt(periods) * (np.mean(returns)) / np.std(returns)

যদিও শার্প রেসিও বৈশিষ্ট্যযুক্ত যে কত ঝুঁকি (অসেট পাথ স্ট্যান্ডার্ড ডিভিয়েশন দ্বারা সংজ্ঞায়িত) রিটার্নের একক প্রতি গ্রহণ করা হচ্ছে, drawdown একটি ইক্যুইটি বক্ররেখা বরাবর বৃহত্তম পিক-টু-ট্রপ ড্রপ হিসাবে সংজ্ঞায়িত করা হয়।

নিচের create_drawdowns ফাংশনটি প্রকৃতপক্ষে সর্বাধিক ড্রডাউন এবং সর্বাধিক ড্রডাউন সময়কাল উভয়ই প্রদান করে। প্রথমটি উপরে উল্লিখিত বৃহত্তম পিক-টু-ট্রপ ড্রপ, যখন দ্বিতীয়টি এই ড্রপটি ঘটে এমন সময়ের সংখ্যা হিসাবে সংজ্ঞায়িত করা হয়।

ড্রাউনডাউন সময়কালের ব্যাখ্যাতে কিছু সূক্ষ্মতা প্রয়োজন কারণ এটি ট্রেডিংয়ের সময়কাল গণনা করে এবং তাই এটি সরাসরি days এর মতো সময় একক হিসাবে অনুবাদ করা যায় না।

ফাংশনটি দুটি পান্ডা সিরিজ অবজেক্ট তৈরি করে শুরু হয় যা প্রতিটি ট্রেডিং bar এ ড্রডাউন এবং সময়কাল উপস্থাপন করে। তারপরে বর্তমান উচ্চ জল চিহ্ন (এইচডাব্লুএম) নির্ধারণ করে নির্ধারিত হয় যে ইক্যুইটি বক্ররেখাটি পূর্ববর্তী সমস্ত শীর্ষ অতিক্রম করে কিনা।

ড্রডাউন তখন কেবলমাত্র বর্তমান এইচডাব্লুএম এবং ইক্যুইটি বক্ররেখার মধ্যে পার্থক্য। যদি এই মানটি নেতিবাচক হয় তবে পরবর্তী এইচডাব্লুএম পৌঁছানো পর্যন্ত এটি ঘটে এমন প্রতিটি বারের জন্য সময়কাল বাড়ানো হয়। ফাংশনটি কেবলমাত্র দুটি সিরিজের প্রতিটি সর্বাধিক ফেরত দেয়ঃ

# performance.py

def create_drawdowns(equity_curve):
    """
    Calculate the largest peak-to-trough drawdown of the PnL curve
    as well as the duration of the drawdown. Requires that the 
    pnl_returns is a pandas Series.

    Parameters:
    pnl - A pandas Series representing period percentage returns.

    Returns:
    drawdown, duration - Highest peak-to-trough drawdown and duration.
    """

    # Calculate the cumulative returns curve 
    # and set up the High Water Mark
    # Then create the drawdown and duration series
    hwm = [0]
    eq_idx = equity_curve.index
    drawdown = pd.Series(index = eq_idx)
    duration = pd.Series(index = eq_idx)

    # Loop over the index range
    for t in range(1, len(eq_idx)):
        cur_hwm = max(hwm[t-1], equity_curve[t])
        hwm.append(cur_hwm)
        drawdown[t]= hwm[t] - equity_curve[t]
        duration[t]= 0 if drawdown[t] == 0 else duration[t-1] + 1
    return drawdown.max(), duration.max()

এই পারফরম্যান্স পরিমাপগুলি ব্যবহার করার জন্য আমাদের ব্যাকটেস্টের পরে তাদের গণনা করার উপায় দরকার, অর্থাৎ যখন একটি উপযুক্ত ইক্যুইটি বক্ররেখা উপলব্ধ থাকে!

আমরা একটি নির্দিষ্ট বস্তুর শ্রেণীবিন্যাস সঙ্গে গণনা সংযুক্ত করতে হবে। যেহেতু কর্মক্ষমতা পরিমাপ একটি পোর্টফোলিও ভিত্তিতে গণনা করা হয়, এটা কার্যকারিতা গণনা একটি পদ্ধতি পোর্টফোলিও শ্রেণী শ্রেণীবিন্যাস যে আমরা এই নিবন্ধে আলোচনা সংযুক্ত করা যুক্তিযুক্ত।

প্রথম কাজ হচ্ছে নিজেকে খুলে দেওয়াportfolio.pyযেমনটি পূর্ববর্তী নিবন্ধে আলোচনা করা হয়েছে এবং পারফরম্যান্স ফাংশন আমদানি করুনঃ

# portfolio.py

..  # Other imports

from performance import create_sharpe_ratio, create_drawdowns

যেহেতু পোর্টফোলিও একটি বিমূর্ত বেস ক্লাস, তাই আমরা এর একটি উদ্ভূত ক্লাসের সাথে একটি পদ্ধতি সংযুক্ত করতে চাই, যা এই ক্ষেত্রে NaivePortfolio হবে। অতএব আমরা একটি পদ্ধতি তৈরি করব যা output_summary_stats নামে পরিচিত যা পোর্টফোলিও ইক্যুইটি বক্ররেখার উপর কাজ করবে শার্প এবং ড্রডাউন তথ্য তৈরি করতে।

পদ্ধতিটি সহজ। এটি কেবলমাত্র দুটি কর্মক্ষমতা পরিমাপ ব্যবহার করে এবং এগুলিকে সরাসরি ইক্যুইটি কার্ভ ডেটাফ্রেমে প্রয়োগ করে, ফর্ম্যাট-বান্ধব পদ্ধতিতে টুপলগুলির একটি তালিকা হিসাবে পরিসংখ্যানগুলি আউটপুট করেঃ

# portfolio.py

..
..

class NaivePortfolio(object):

    ..
    ..

    def output_summary_stats(self):
        """
        Creates a list of summary statistics for the portfolio such
        as Sharpe Ratio and drawdown information.
        """
        total_return = self.equity_curve['equity_curve'][-1]
        returns = self.equity_curve['returns']
        pnl = self.equity_curve['equity_curve']

        sharpe_ratio = create_sharpe_ratio(returns)
        max_dd, dd_duration = create_drawdowns(pnl)

        stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)),
                 ("Sharpe Ratio", "%0.2f" % sharpe_ratio),
                 ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)),
                 ("Drawdown Duration", "%d" % dd_duration)]
        return stats

স্পষ্টতই এটি একটি পোর্টফোলিওর জন্য একটি খুব সহজ পারফরম্যান্স বিশ্লেষণ। এটি ট্রেড-স্তরের বিশ্লেষণ বা ঝুঁকি / পুরষ্কারের অন্যান্য পরিমাপ বিবেচনা করে না। তবে এটি আরও পদ্ধতি যুক্ত করে প্রসারিত করা সহজ।performance.pyএবং তারপর প্রয়োজনীয় হিসাবে output_summary_stat মধ্যে তাদের অন্তর্ভুক্ত।


আরো