پانڈوں کے ساتھ پیتھون میں ایک چلتی اوسط کراس اوور کا بیک ٹیسٹنگ

مصنف:نیکی, تخلیق: 2019-03-27 15:11:40, تازہ کاری:

اس مضمون میں ہم ایک اصل حکمت عملی پر تحقیق کرنے کے لئے متعارف کرایا مشینری کا استعمال کریں گے، یعنی AAPL پر چلتی اوسط کراس اوور.

چلتی اوسط کراس اوور حکمت عملی

چلتی اوسط کراس اوور تکنیک ایک انتہائی مشہور آسان رفتار کی حکمت عملی ہے۔ اسے اکثر مقداری تجارت کے لئے ہیلو ورلڈ مثال سمجھا جاتا ہے۔

یہاں بیان کردہ حکمت عملی صرف لمبی ہے۔ ایک خاص ٹائم سیریز کے دو الگ الگ سادہ چلتی اوسط فلٹر بنائے جاتے ہیں ، مختلف نظرثانی کے ادوار کے ساتھ۔ اثاثہ خریدنے کے لئے سگنل اس وقت ہوتے ہیں جب مختصر نظرثانی کی چلتی اوسط لمبی نظرثانی کی چلتی اوسط سے تجاوز کرتی ہے۔ اگر طویل اوسط بعد میں مختصر اوسط سے تجاوز کرتا ہے تو ، اثاثہ واپس فروخت کیا جاتا ہے۔ یہ حکمت عملی اچھی طرح کام کرتی ہے جب ایک ٹائم سیریز مضبوط رجحان کی مدت میں داخل ہوتی ہے اور پھر آہستہ آہستہ رجحان کو تبدیل کرتی ہے۔

اس مثال کے لئے ، میں نے ایپل ، انکارپوریٹڈ (اے اے پی ایل) کو وقت کی سیریز کے طور پر منتخب کیا ہے ، جس میں 100 دن کی مختصر نظر اور 400 دن کی لمبی نظر ہے۔ یہ زپ لائن الگورتھمک ٹریڈنگ لائبریری کے ذریعہ فراہم کردہ مثال ہے۔ لہذا اگر ہم اپنا بیک ٹیسٹر لاگو کرنا چاہتے ہیں تو ہمیں اس بات کو یقینی بنانا ہوگا کہ یہ زپ لائن میں نتائج سے ملتا ہے ، توثیق کے بنیادی ذرائع کے طور پر۔

نفاذ

اس بات کو یقینی بنائیں کہ یہاں پچھلے ٹیوٹوریل پر عمل کریں ، جس میں بیان کیا گیا ہے کہ بیک ٹیسٹر کے لئے ابتدائی آبجیکٹ درجہ بندی کی تعمیر کیسے کی جاتی ہے ، ورنہ نیچے کا کوڈ کام نہیں کرے گا۔ اس خاص نفاذ کے لئے میں نے مندرجہ ذیل لائبریریوں کا استعمال کیا ہے:

  • پائیتھون - 2.7.3
  • NumPy - 1.8.0
  • پانڈا - 0.12.0
  • میٹپلوٹلیب - 1.1.0

ma_cross.py کے نفاذ کی ضرورت ہوتی ہےbacktest.pyپچھلے سبق سے. پہلا قدم ضروری ماڈیولز اور اشیاء درآمد کرنا ہے:

# ma_cross.py

import datetime
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from pandas.io.data import DataReader
from backtest import Strategy, Portfolio

پچھلے ٹیوٹوریل میں جیسا کہ ہم منتقل اوسطCrossStrategy پیدا کرنے کے لئے حکمت عملی خلاصہ بیس کلاس subclass کرنے جا رہے ہیں، AAPL کے چلتی اوسط ایک دوسرے کے اوپر عبور جب سگنل پیدا کرنے کے لئے کس طرح پر تمام تفصیلات پر مشتمل ہے.

آبجیکٹ کو کام کرنے کے لئے ایک مختصر_ونڈو اور ایک لمبی_ونڈو کی ضرورت ہے۔ اقدار کو بالترتیب 100 دن اور 400 دن کے ڈیفالٹ پر ترتیب دیا گیا ہے ، جو زپ لائن کی مرکزی مثال میں استعمال ہونے والے پیرامیٹرز ہیں۔

حرکت پذیر اوسطوں کو اے اے پی ایل اسٹاک کی باروں پر پینڈاس رولنگ_میڈین فنکشن کا استعمال کرتے ہوئے تخلیق کیا جاتا ہے۔ ایک بار جب انفرادی حرکت پذیر اوسط تیار ہوجاتے ہیں تو ، سگنل سیریز اس وقت پیدا کی جاتی ہے جب مختصر حرکت پذیر اوسط لمبی حرکت پذیر اوسط سے بڑا ہوتا ہے تو کالم 1.0 کے برابر ہوتا ہے ، یا دوسری صورت میں 0.0۔ اس سے تجارتی سگنل کی نمائندگی کرنے کے لئے پوزیشن آرڈرز تیار کیے جاسکتے ہیں۔

# ma_cross.py

class MovingAverageCrossStrategy(Strategy):
    """    
    Requires:
    symbol - A stock symbol on which to form a strategy on.
    bars - A DataFrame of bars for the above symbol.
    short_window - Lookback period for short moving average.
    long_window - Lookback period for long moving average."""

    def __init__(self, symbol, bars, short_window=100, long_window=400):
        self.symbol = symbol
        self.bars = bars

        self.short_window = short_window
        self.long_window = long_window

    def generate_signals(self):
        """Returns the DataFrame of symbols containing the signals
        to go long, short or hold (1, -1 or 0)."""
        signals = pd.DataFrame(index=self.bars.index)
        signals['signal'] = 0.0

        # Create the set of short and long simple moving averages over the 
        # respective periods
        signals['short_mavg'] = pd.rolling_mean(bars['Close'], self.short_window, min_periods=1)
        signals['long_mavg'] = pd.rolling_mean(bars['Close'], self.long_window, min_periods=1)

        # Create a 'signal' (invested or not invested) when the short moving average crosses the long
        # moving average, but only for the period greater than the shortest moving average window
        signals['signal'][self.short_window:] = np.where(signals['short_mavg'][self.short_window:] 
            > signals['long_mavg'][self.short_window:], 1.0, 0.0)   

        # Take the difference of the signals in order to generate actual trading orders
        signals['positions'] = signals['signal'].diff()   

        return signals

مارکیٹ آن کلوز پورٹ فولیو پورٹ فولیو سے ذیلی درجہ بندی ہے، جو میں پایا جاتا ہےbacktest.pyیہ پچھلے ٹیوٹوریل میں بیان کردہ نفاذ کے ساتھ تقریبا identical یکساں ہے ، اس استثناء کے ساتھ کہ اب تجارتیں اوپن ٹو اوپن کی بجائے کلوز ٹو کلوز کی بنیاد پر کی جاتی ہیں۔ پورٹ فولیو آبجیکٹ کی وضاحت کے بارے میں تفصیلات کے لئے ، پچھلے ٹیوٹوریل کو دیکھیں۔ میں نے کوڈ کو مکمل ہونے اور اس ٹیوٹوریل کو خود مختار رکھنے کے لئے چھوڑ دیا ہے:

# ma_cross.py

class MarketOnClosePortfolio(Portfolio):
    """Encapsulates the notion of a portfolio of positions based
    on a set of signals as provided by a Strategy.

    Requires:
    symbol - A stock symbol which forms the basis of the portfolio.
    bars - A DataFrame of bars for a symbol set.
    signals - A pandas DataFrame of signals (1, 0, -1) for each symbol.
    initial_capital - The amount in cash at the start of the portfolio."""

    def __init__(self, symbol, bars, signals, initial_capital=100000.0):
        self.symbol = symbol        
        self.bars = bars
        self.signals = signals
        self.initial_capital = float(initial_capital)
        self.positions = self.generate_positions()
        
    def generate_positions(self):
        positions = pd.DataFrame(index=signals.index).fillna(0.0)
        positions[self.symbol] = 100*signals['signal']   # This strategy buys 100 shares
        return positions
                    
    def backtest_portfolio(self):
        portfolio = self.positions*self.bars['Close']
        pos_diff = self.positions.diff()

        portfolio['holdings'] = (self.positions*self.bars['Close']).sum(axis=1)
        portfolio['cash'] = self.initial_capital - (pos_diff*self.bars['Close']).sum(axis=1).cumsum()

        portfolio['total'] = portfolio['cash'] + portfolio['holdings']
        portfolio['returns'] = portfolio['total'].pct_change()
        return portfolio

اب جب کہ چلتی اوسط کراس اسٹریٹیجی اور مارکیٹ آن کلوز پورٹ فولیو کلاسوں کی وضاحت کی گئی ہے ،اہمتمام افعال کو ایک ساتھ جوڑنے کے لئے فنکشن کو بلایا جائے گا۔ اس کے علاوہ حکمت عملی کی کارکردگی کا جائزہ ایکویٹی وکر کے ایک پلاٹ کے ذریعے لیا جائے گا۔

پانڈا ڈیٹا ریڈر آبجیکٹ 1 جنوری 1990 سے 1 جنوری 2002 تک کی مدت کے لئے اے اے پی ایل اسٹاک کی او ایچ ایل سی وی قیمتوں کو ڈاؤن لوڈ کرتا ہے۔ اس وقت صرف طویل سگنل پیدا کرنے کے لئے سگنل ڈیٹا فریم بنائے جاتے ہیں۔ اس کے بعد پورٹ فولیو کو 100،000 امریکی ڈالر کے ابتدائی سرمایہ بیس کے ساتھ تیار کیا جاتا ہے اور منافع کا حساب ایکویٹی وکر پر کیا جاتا ہے۔

آخری مرحلہ یہ ہے کہ دونوں اے اے پی ایل قیمتوں کا دو ہندسوں کا پلاٹ استعمال کریں ، جو چلتی اوسط اور خرید / فروخت کے اشارے کے ساتھ ساتھ ایکویٹی وکر کے ساتھ ساتھ اسی خرید / فروخت کے اشاروں کے ساتھ اوورلیپ کریں۔ پلاٹنگ کوڈ زپ لائن نفاذ کی مثال سے لیا گیا ہے (اور اس میں ترمیم کی گئی ہے) ۔

# ma_cross.py

if __name__ == "__main__":
    # Obtain daily bars of AAPL from Yahoo Finance for the period
    # 1st Jan 1990 to 1st Jan 2002 - This is an example from ZipLine
    symbol = 'AAPL'
    bars = DataReader(symbol, "yahoo", datetime.datetime(1990,1,1), datetime.datetime(2002,1,1))

    # Create a Moving Average Cross Strategy instance with a short moving
    # average window of 100 days and a long window of 400 days
    mac = MovingAverageCrossStrategy(symbol, bars, short_window=100, long_window=400)
    signals = mac.generate_signals()

    # Create a portfolio of AAPL, with $100,000 initial capital
    portfolio = MarketOnClosePortfolio(symbol, bars, signals, initial_capital=100000.0)
    returns = portfolio.backtest_portfolio()

    # Plot two charts to assess trades and equity curve
    fig = plt.figure()
    fig.patch.set_facecolor('white')     # Set the outer colour to white
    ax1 = fig.add_subplot(211,  ylabel='Price in $')
    
    # Plot the AAPL closing price overlaid with the moving averages
    bars['Close'].plot(ax=ax1, color='r', lw=2.)
    signals[['short_mavg', 'long_mavg']].plot(ax=ax1, lw=2.)

    # Plot the "buy" trades against AAPL
    ax1.plot(signals.ix[signals.positions == 1.0].index, 
             signals.short_mavg[signals.positions == 1.0],
             '^', markersize=10, color='m')

    # Plot the "sell" trades against AAPL
    ax1.plot(signals.ix[signals.positions == -1.0].index, 
             signals.short_mavg[signals.positions == -1.0],
             'v', markersize=10, color='k')

    # Plot the equity curve in dollars
    ax2 = fig.add_subplot(212, ylabel='Portfolio value in $')
    returns['total'].plot(ax=ax2, lw=2.)

    # Plot the "buy" and "sell" trades against the equity curve
    ax2.plot(returns.ix[signals.positions == 1.0].index, 
             returns.total[signals.positions == 1.0],
             '^', markersize=10, color='m')
    ax2.plot(returns.ix[signals.positions == -1.0].index, 
             returns.total[signals.positions == -1.0],
             'v', markersize=10, color='k')

    # Plot the figure
    fig.show()

کوڈ کا گرافک آؤٹ پٹ مندرجہ ذیل ہے۔ میں نے آئی پییٹون٪ پیسٹ کمانڈ کا استعمال کیا تاکہ اسے براہ راست آئی پییٹون کنسول میں ڈال دیا جائے جبکہ اوبنٹو میں ، تاکہ گرافک آؤٹ پٹ نظر میں رہے۔ گلابی اپ ٹکس اسٹاک خریدنے کی نمائندگی کرتے ہیں ، جبکہ سیاہ ڈاون ٹکس اسے واپس بیچنے کی نمائندگی کرتے ہیں:imgاے اے پی ایل چلتی اوسط کراس اوور کارکردگی 1990-01-01 سے 2002-01-01 تک

جیسا کہ دیکھا جاسکتا ہے کہ اسٹریٹجی نے اس عرصے میں پانچ گول ٹرپ تجارتوں کے ساتھ پیسہ کھویا ہے۔ یہ حیرت کی بات نہیں ہے کہ اس عرصے کے دوران اے اے پی ایل کا رویہ ، جو 1998 میں شروع ہونے والے نمایاں اضافے کے بعد تھوڑا سا نیچے کا رجحان تھا ، اس کے بعد 1998.

بعد کے مضامین میں ہم کارکردگی کا تجزیہ کرنے کے لئے ایک زیادہ نفیس ذریعہ بنائیں گے ، نیز یہ بیان کریں گے کہ انفرادی حرکت پذیر اوسط سگنلز کے بیک بیک ادوار کو کس طرح بہتر بنایا جائے۔


مزید