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

লেখক:ভাল, তৈরিঃ 2019-03-25 14:24:46, আপডেটঃ

ইভেন্ট-চালিত ব্যাকটেস্টিং বাস্তবায়নের আলোচনায় ইতোমধ্যে ইভেন্ট-লুপ, ইভেন্ট ক্লাসের শ্রেণীবিন্যাস এবং ডেটা হ্যান্ডলিং উপাদান বিবেচনা করা হয়েছে। এই নিবন্ধে একটি কৌশল শ্রেণীর শ্রেণীবিন্যাস রূপরেখা করা হবে। কৌশল বস্তুগুলি বাজারের তথ্য ইনপুট হিসাবে নেয় এবং আউটপুট হিসাবে ট্রেডিং সিগন্যাল ইভেন্টগুলি উত্পাদন করে।

একটি কৌশল অবজেক্ট একটি পোর্টফোলিও অবজেক্টের জন্য উপদেশমূলক সংকেত উত্পন্ন করে এমন বাজার তথ্যের সমস্ত গণনাকে ক্যাপসুল করে। ইভেন্ট-চালিত ব্যাকটেস্টার বিকাশের এই পর্যায়ে কোনও সূচক বা ফিল্টারের ধারণা নেই, যেমন প্রযুক্তিগত ট্রেডিংয়ে পাওয়া যায়। এগুলিও একটি শ্রেণী শ্রেণী তৈরির জন্য ভাল প্রার্থী তবে এই নিবন্ধের আওতার বাইরে।

কৌশল শ্রেণীবিন্যাসটি তুলনামূলকভাবে সহজ কারণ এটি একটি বিমূর্ত বেস ক্লাস নিয়ে গঠিত যা SignalEvent অবজেক্ট তৈরির জন্য একটি একক খাঁটি ভার্চুয়াল পদ্ধতি রয়েছে। কৌশল শ্রেণীবিন্যাস তৈরি করতে NumPy, pandas, Queue অবজেক্ট, বিমূর্ত বেস ক্লাস সরঞ্জাম এবং SignalEvent আমদানি করা প্রয়োজনঃ

# strategy.py

import datetime
import numpy as np
import pandas as pd
import Queue

থেকে abc আমদানি ABCMeta, বিমূর্ত পদ্ধতি

ইভেন্ট আমদানি থেকে SignalEvent কৌশল বিমূর্ত বেস ক্লাস কেবলমাত্র একটি খাঁটি ভার্চুয়াল গণনা_সিগন্যাল পদ্ধতি সংজ্ঞায়িত করে। উদ্ভূত ক্লাসগুলিতে এটি বাজার ডেটা আপডেটের উপর ভিত্তি করে সিগন্যাল ইভেন্ট অবজেক্টগুলির উত্পাদন পরিচালনা করতে ব্যবহৃত হয়ঃ

# strategy.py

class Strategy(object):
    """
    Strategy is an abstract base class providing an interface for
    all subsequent (inherited) strategy handling objects.

    The goal of a (derived) Strategy object is to generate Signal
    objects for particular symbols based on the inputs of Bars 
    (OLHCVI) generated by a DataHandler object.

    This is designed to work both with historic and live data as
    the Strategy object is agnostic to the data source,
    since it obtains the bar tuples from a queue object.
    """

    __metaclass__ = ABCMeta

    @abstractmethod
    def calculate_signals(self):
        """
        Provides the mechanisms to calculate the list of signals.
        """
        raise NotImplementedError("Should implement calculate_signals()")

কৌশল এবিসি এর সংজ্ঞা সহজ। কৌশল অবজেক্টকে উপবিভাগ করার আমাদের প্রথম উদাহরণটি BuyAndHoldStrategy শ্রেণি তৈরি করতে একটি কিনুন এবং ধরে রাখার কৌশল ব্যবহার করে। এটি কেবল একটি নির্দিষ্ট তারিখে একটি নির্দিষ্ট সিকিউরিটিতে দীর্ঘ যায় এবং এটিকে পোর্টফোলিওর মধ্যে রাখে। সুতরাং প্রতি সিকিউরিটি প্রতি কেবলমাত্র একটি সংকেত উত্পন্ন হয়।

নির্মাতা (সূচনা) বার বাজার ডেটা হ্যান্ডলার এবং ইভেন্ট ইভেন্ট সারি বস্তু প্রয়োজনঃ

# strategy.py

class BuyAndHoldStrategy(Strategy):
    """
    This is an extremely simple strategy that goes LONG all of the 
    symbols as soon as a bar is received. It will never exit a position.

    It is primarily used as a testing mechanism for the Strategy class
    as well as a benchmark upon which to compare other strategies.
    """

    def __init__(self, bars, events):
        """
        Initialises the buy and hold strategy.

        Parameters:
        bars - The DataHandler object that provides bar information
        events - The Event Queue object.
        """
        self.bars = bars
        self.symbol_list = self.bars.symbol_list
        self.events = events

        # Once buy & hold signal is given, these are set to True
        self.bought = self._calculate_initial_bought()

ক্রয় এবং হোল্ড স্ট্র্যাটেজি শুরু করার সময়, ক্রয়কৃত অভিধান সদস্যের প্রতিটি প্রতীকের জন্য একটি সেট কী রয়েছে যা সমস্ত মিথ্যাতে সেট করা আছে। একবার সম্পদটি longed হয়ে গেলে এটি সত্যে সেট করা হয়। মূলত এটি কৌশলটিকে জানতে দেয় যে এটি বাজারে কিনাঃ

# strategy.py

    def _calculate_initial_bought(self):
        """
        Adds keys to the bought dictionary for all symbols
        and sets them to False.
        """
        bought = {}
        for s in self.symbol_list:
            bought[s] = False
        return bought

calculate_signals বিশুদ্ধ ভার্চুয়াল পদ্ধতিটি এই শ্রেণীতে বাস্তবায়িত হয়। পদ্ধতিটি প্রতীক তালিকার সমস্ত চিহ্নের উপর লুপ করে এবং বার ডেটা হ্যান্ডলার থেকে সর্বশেষ বারটি পুনরুদ্ধার করে। এটি তারপরে পরীক্ষা করে যে সেই প্রতীকটি bought হয়েছে কিনা (যেমন আমরা এই প্রতীকটির জন্য বাজারে আছি কিনা) এবং যদি না হয় তবে একটি একক SignalEvent অবজেক্ট তৈরি করে। এটি তারপরে ইভেন্টের সারিতে স্থাপন করা হয় এবং কেনা অভিধানটি এই নির্দিষ্ট প্রতীক কীটির জন্য সত্য হিসাবে সঠিকভাবে আপডেট করা হয়ঃ

# strategy.py

    def calculate_signals(self, event):
        """
        For "Buy and Hold" we generate a single signal per symbol
        and then no additional signals. This means we are 
        constantly long the market from the date of strategy
        initialisation.

        Parameters
        event - A MarketEvent object. 
        """
        if event.type == 'MARKET':
            for s in self.symbol_list:
                bars = self.bars.get_latest_bars(s, N=1)
                if bars is not None and bars != []:
                    if self.bought[s] == False:
                        # (Symbol, Datetime, Type = LONG, SHORT or EXIT)
                        signal = SignalEvent(bars[0][0], bars[0][1], 'LONG')
                        self.events.put(signal)
                        self.bought[s] = True

এটি স্পষ্টতই একটি সহজ কৌশল তবে এটি ইভেন্ট-চালিত কৌশল শ্রেণিবিন্যাসের প্রকৃতি প্রদর্শন করতে যথেষ্ট। পরবর্তী নিবন্ধগুলিতে আমরা জোড়া বাণিজ্যের মতো আরও পরিশীলিত কৌশলগুলি বিবেচনা করব। পরবর্তী নিবন্ধে আমরা কীভাবে একটি পোর্টফোলিও শ্রেণিবিন্যাস তৈরি করব তা বিবেচনা করব যা লাভ এবং ক্ষতির সাথে আমাদের অবস্থানগুলি ট্র্যাক করে ( পিএনএল) ।


আরো