ডেটা-চালিত প্রযুক্তির মাধ্যমে জোড়া বিনিময়

লেখক:ভাল, তৈরিঃ 2019-08-21 13:50:23, আপডেটঃ 2023-10-19 21:01:31

img

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

মৌলিক নীতি

假设你有一对投资标的X和Y具有一些潜在的关联,例如两家公司生产相同的产品,如百事可乐和可口可乐。你希望这两者的价格比率或基差(也称为差价)随时间的变化而保持不变。然而,由于临时供需变化,如一个投资标的的大买/卖订单,对其中一家公司的重要新闻的反应等,这两对之间的价差可能会不时出现分歧。在这种情况下,一只投资标的向上移动而另一只投资标的相对于彼此向下移动。如果你希望这种分歧随着时间的推移恢复正常,你就可以发现交易机会(或套利机会)。此种套利机会在数字货币市场或者国内商品期货市场比比皆是,比如BTC与避险资产的关系;期货中豆粕,豆油与大豆品种之间的关系.

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

সুতরাং, প্যারেড ট্রেডিং একটি বাজার নিরপেক্ষ ট্রেডিং কৌশল যা ব্যবসায়ীদের প্রায় কোনও বাজার অবস্থার থেকে লাভবান হতে দেয়ঃ উত্থান, পতন বা অনুভূমিক সমন্বয়।

ব্যাখ্যাঃ দুটি অনুমিত বিনিয়োগের মানদণ্ড

  • ইনভেন্টর ক্যাভিটাইজেশন প্ল্যাটফর্মে আমাদের গবেষণা পরিবেশ তৈরি করুন

প্রথমত, কাজটি সুচারুভাবে চালানোর জন্য আমাদের গবেষণা পরিবেশ তৈরি করতে হবে, যা আমরা এই নিবন্ধে ইনভেন্টর কুইন্টিফাইং প্ল্যাটফর্ম ব্যবহার করেছি।FMZ.COMএই প্ল্যাটফর্মের জন্য একটি সহজ এবং দ্রুত এপিআই ইন্টারফেস এবং একটি সম্পূর্ণ ডকার সিস্টেম প্যাকেজ করার জন্য মূলত একটি গবেষণা পরিবেশ তৈরি করা হয়েছিল।

এই ডকার সিস্টেমটি ইনভেন্টর কোয়ালিফাইং প্ল্যাটফর্মের অফিসিয়াল নামের মধ্যে হোস্ট সিস্টেম নামে পরিচিত।

আমি আমার পূর্ববর্তী নিবন্ধে লিখেছি কিভাবে হোস্ট এবং বট স্থাপন করতে হয়ঃhttps://www.fmz.com/bbs-topic/4140

যারা তাদের নিজস্ব ক্লাউড সার্ভার স্থাপনার জন্য হোস্ট কিনতে চান তাদের জন্য এই নিবন্ধটি পড়ুনঃhttps://www.fmz.com/bbs-topic/2848

একটি ভাল ক্লাউড সার্ভিস এবং হোস্ট সিস্টেম সফলভাবে স্থাপন করার পরে, আমরা এখন পাইথনের বৃহত্তম টেম্পলেট ইনস্টল করতে যাচ্ছিঃ আনাকন্ডা।

এই প্রবন্ধে প্রয়োজনীয় সকল প্রাসঙ্গিক প্রোগ্রামিং পরিবেশ (অনির্ভরতা পুস্তিকা, সংস্করণ ব্যবস্থাপনা ইত্যাদি) বাস্তবায়নের জন্য সবচেয়ে সহজ উপায় হল Anaconda ব্যবহার করা। এটি একটি প্যাকেজড পাইথন ডেটা সায়েন্স ইকোসিস্টেম এবং একটি নির্ভরতা পুস্তিকা ম্যানেজার।

Anaconda ইনস্টল করার জন্য, Anaconda এর অফিসিয়াল গাইড দেখুনঃhttps://www.anaconda.com/distribution/

本文还将用到numpy和pandas这两个目前在Python科学计算方面十分流行且重要的库.

উপরের মৌলিক কাজগুলি আমার আগের নিবন্ধে উল্লেখ করা যেতে পারে, যেখানে আমি Anaconda পরিবেশ এবং numpy এবং pandas উভয় লাইব্রেরী সেট আপ করার বিষয়ে বিস্তারিতভাবে আলোচনা করেছিঃhttps://www.fmz.com/digest-topic/4169

পরবর্তী, আসুন আমরা কোড ব্যবহার করে একটি "দুটি অনুমিত বিনিয়োগের টার্মিনাল" বাস্তবায়ন করি।

import numpy as np
import pandas as pd

import statsmodels
from statsmodels.tsa.stattools import coint
# just set the seed for the random number generator
np.random.seed(107)

import matplotlib.pyplot as plt

ঠিক আছে, আমরা পাইথন এর খুব বিখ্যাত ম্যাটপ্লটলিব নামক গ্রাফ লাইব্রেরী ব্যবহার করব।

আসুন আমরা একটি অনুমিত বিনিয়োগের মানদণ্ডের এক্স উৎপন্ন করি, এবং এর দৈনিক রিটার্নকে একটি স্বাভাবিক বন্টনের মাধ্যমে মডেল করি। তারপর আমরা দৈনিক x-এর মান পাওয়ার জন্য সংযোজন করি।

# Generate daily returns
Xreturns = np.random.normal(0, 1, 100) 
# sum them and shift all the prices up
X = pd.Series(np.cumsum(
    Xreturns), name='X') 
    + 50
X.plot(figsize=(15,7))
plt.show()

img

একটি বিনিয়োগের ট্যাগের এক্স, একটি স্বাভাবিক বন্টনের মাধ্যমে তার দৈনিক রিটার্ন ম্যাপিং সিমুলেট করে

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

noise = np.random.normal(0, 1, 100)
Y = X + 5 + noise
Y.name = 'Y'
pd.concat([X, Y], axis=1).plot(figsize=(15,7))
plt.show()

img

সমন্বিত বিনিয়োগের জন্য এক্স এবং ওয়াই

সমন্বয়

协整非常类似于相关性,意味着两个数据系列之间的比率将在平均值附近变化.Y和X这两个系列遵循以下内容:

Y = X + e

যেখানে ই - ধ্রুবক অনুপাত এবং ই - শব্দ।

দুইটি সময়সূচির মধ্যে ব্যবসায়িক জোড়ার জন্য, এই অনুপাতটি অবশ্যই সময়ের সাথে সাথে প্রত্যাশিত মানগুলিতে সম্মিলিত হবে, অর্থাৎ তারা সমন্বিত হওয়া উচিত। আমরা উপরে যে সময়সূচী তৈরি করেছি তা সমন্বিত। আমরা এখন এর মধ্যে একটি অনুপাত আঁকব যাতে আমরা এটি দেখতে পারি।

(Y/X).plot(figsize=(15,7)) 
plt.axhline((Y/X).mean(), color='red', linestyle='--') 
plt.xlabel('Time')
plt.legend(['Price Ratio', 'Mean'])
plt.show()

img

দুটি সমন্বিত বিনিয়োগের মানের দামের মধ্যে অনুপাত এবং গড়

সমন্বয় পরীক্ষা

statmodels.tsa.stattools ব্যবহার করে এটি পরীক্ষা করার একটি সহজ উপায় আছে। আমরা একটি খুব কম p-value দেখতে পাবো কারণ আমরা কৃত্রিমভাবে যতটা সম্ভব সমন্বিত দুটি ডাটা সারি তৈরি করেছি।

# compute the p-value of the cointegration test
# will inform us as to whether the ratio between the 2 timeseries is stationary
# around its mean
score, pvalue, _ = coint(X,Y)
print pvalue

ফলাফলঃ 1.81864477307e-17

নোটঃ প্রাসঙ্গিকতা এবং সমন্বয়

সম্পর্কিত এবং সমন্বয়, যদিও তাত্ত্বিকভাবে অনুরূপ, কিন্তু একই নয়। আসুন সম্পর্কিত কিন্তু সমন্বয়হীন ডেটা সিরিজের উদাহরণ দেখি এবং এর বিপরীতে। প্রথমে আসুন আমরা সবেমাত্র উত্পন্ন সিরিজের সম্পর্ক পরীক্ষা করি।

X.corr(Y)

ফলাফলঃ 0.951

যেমনটি আমরা আশা করতাম, এটি খুব বেশি। কিন্তু দুটি সম্পর্কিত কিন্তু অসঙ্গতিপূর্ণ সারি সম্পর্কে কী? একটি সহজ উদাহরণ হল দুটি বিচ্যুত ডেটা সারি।

ret1 = np.random.normal(1, 1, 100)
ret2 = np.random.normal(2, 1, 100)

s1 = pd.Series( np.cumsum(ret1), name='X')
s2 = pd.Series( np.cumsum(ret2), name='Y')

pd.concat([s1, s2], axis=1 ).plot(figsize=(15,7))
plt.show()
print 'Correlation: ' + str(X_diverging.corr(Y_diverging))
score, pvalue, _ = coint(X_diverging,Y_diverging)
print 'Cointegration test p-value: ' + str(pvalue)

img

দুটি সংশ্লিষ্ট সিরিজ (এখনও একত্রিত হয়নি)

সংশ্লিষ্ট গুণকঃ ০.৯৯৮ সমন্বয় পরীক্ষার পি-ভ্যালুঃ 0.258

কোন সম্পর্কহীন সমন্বয়ের একটি সহজ উদাহরণ হল অর্গানাল ডিস্ট্রিবিউশন সিকোয়েন্স এবং বর্গ তরঙ্গ।

Y2 = pd.Series(np.random.normal(0, 1, 800), name='Y2') + 20
Y3 = Y2.copy()
Y3[0:100] = 30
Y3[100:200] = 10
Y3[200:300] = 30
Y3[300:400] = 10
Y3[400:500] = 30
Y3[500:600] = 10
Y3[600:700] = 30
Y3[700:800] = 10
Y2.plot(figsize=(15,7))
Y3.plot()
plt.ylim([0, 40])
plt.show()
# correlation is nearly zero
print 'Correlation: ' + str(Y2.corr(Y3))
score, pvalue, _ = coint(Y2,Y3)
print 'Cointegration test p-value: ' + str(pvalue)

img

প্রাসঙ্গিকতাঃ 0.007546 সমন্বয় পরীক্ষার পি-ভ্যালুঃ ০.০

এই প্যাকেজটি একটি সম্পূর্ণ নতুন প্যাকেজ তৈরি করেছে, যা একটি সম্পূর্ণ নতুন প্যাকেজ তৈরি করেছে।

কিভাবে একটি সমন্বয় লেনদেন করা হয়?

যেহেতু দুটি সমন্বিত সময় ক্রম (যেমন উপরে X এবং Y) একে অপরের সাথে সামঞ্জস্যপূর্ণ এবং একে অপরের থেকে বিচ্যুত, তাই কখনও কখনও উচ্চ এবং নিম্ন ক্যাফিয়ারের পরিস্থিতি দেখা দেয়। আমরা একটি বিনিয়োগের ট্যাগ কিনতে এবং অন্যটি বিক্রি করে একটি সমন্বিত লেনদেন করি। সুতরাং যদি দুটি বিনিয়োগের ট্যাগ একসাথে পড়ে বা একসাথে উঠে যায় তবে আমরা অর্থ উপার্জন বা হারাতে পারি না, অর্থাৎ আমরা বাজারের নিরপেক্ষ।

উপরের Y = X + e এর মধ্যে X এবং Y-এর দিকে ফিরে, অনুপাত (Y / X) এর গড় মানের বিন্দুর চারপাশে সরে যায়, আমরা গড় মানের রিটার্নের অনুপাতের মাধ্যমে অর্থ উপার্জন করি। এটি করার জন্য, আমরা X এবং Y এর মধ্যে খুব দূরে অবস্থার দিকে নজর রাখি, অর্থাৎ থ্রেশহোল্ড খুব বেশি বা খুব কমঃ

  • বহু-অংশীদারিত্বঃ এটি যখন অনুপাতটি খুব ছোট হয় এবং আমরা এটি বড় হওয়ার প্রত্যাশা করি। উপরের উদাহরণে, আমরা বহু Y করে এবং খালি X করে ট্রেডিং শুরু করি।

  • শূন্যতার হারঃ এটি যখন হারটি খুব বড় হয় এবং আমরা এটিকে ঘন্টার পর ঘন্টা পরিবর্তন করার আশা করি। উপরের উদাহরণে, আমরা শূন্যতা Y এবং X এর সাথে একটি ট্রেডিং শুরু করি।

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

যদি আমরা এক্স এবং ওয়াই ট্রেডিং ইন্ডিকেটরগুলিকে একে অপরের তুলনায় সরিয়ে নিই, তাহলে আমরা লাভ বা ক্ষতি করব।

ডেটা ব্যবহার করে অনুরূপ ট্রেড আইকন অনুসন্ধান করুন

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

একাধিক তুলনা বিচ্যুতিএটি এমন একটি পরিস্থিতিতে বোঝায় যেখানে অনেকগুলি পরীক্ষা চালানোর সময় ভুলভাবে গুরুত্বপূর্ণ পি-ভ্যালু উত্পন্ন করার সম্ভাবনা বৃদ্ধি পায়, কারণ আমাদের অনেকগুলি পরীক্ষা চালাতে হবে। যদি আপনি র্যান্ডম ডেটাতে 100 টি পরীক্ষা করেন তবে আমরা 0.05 এর চেয়ে কম 5 টি পি-ভ্যালু দেখতে পাব। যদি আপনি n টি লেনদেনের তুলনা করতে চান তবে আপনি n ণ -1 / 2 তুলনা করবেন এবং আপনি অনেকগুলি ভুল পি-ভ্যালু দেখতে পাবেন, যা আপনার পরীক্ষার নমুনা বাড়ার সাথে সাথে বৃদ্ধি পাবে। এই পরিস্থিতি এড়াতে, কয়েকটি লেনদেনের কয়েকটি জোড়া বেছে নিন যার জন্য আপনি নিশ্চিত হতে পারেন যে তারা সম্ভবত সহযোগিতা করতে পারে এবং তাদের পৃথকভাবে পরীক্ষা করুন। এটি ব্যাপকভাবে হ্রাস পাবে।একাধিক তুলনা বিচ্যুতি

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

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

def find_cointegrated_pairs(data):
    n = data.shape[1]
    score_matrix = np.zeros((n, n))
    pvalue_matrix = np.ones((n, n))
    keys = data.keys()
    pairs = []
    for i in range(n):
        for j in range(i+1, n):
            S1 = data[keys[i]]
            S2 = data[keys[j]]
            result = coint(S1, S2)
            score = result[0]
            pvalue = result[1]
            score_matrix[i, j] = score
            pvalue_matrix[i, j] = pvalue
            if pvalue < 0.02:
                pairs.append((keys[i], keys[j]))
    return score_matrix, pvalue_matrix, pairs

দ্রষ্টব্যঃ আমরা ডেটাতে বাজার বেঞ্চমার্ক (SPX) অন্তর্ভুক্ত করেছি - বাজারটি অনেকগুলি ট্রেড ইন্ডিকেটরকে চালিত করে, সাধারণত আপনি দুটি দৃশ্যত সহযোগী ট্রেড ইন্ডিকেটর খুঁজে পেতে পারেন; কিন্তু আসলে তারা একে অপরের সাথে সহযোগী নয়, বরং বাজারের সাথে সহযোগী। এটিকে মিশ্র ভেরিয়েবল বলা হয়। আপনি যে কোনও সম্পর্কের মধ্যে বাজার অংশগ্রহণ পরীক্ষা করে দেখতে পারেন তা গুরুত্বপূর্ণ।

from backtester.dataSource.yahoo_data_source import YahooStockDataSource
from datetime import datetime
startDateStr = '2007/12/01'
endDateStr = '2017/12/01'
cachedFolderName = 'yahooData/'
dataSetId = 'testPairsTrading'
instrumentIds = ['SPY','AAPL','ADBE','SYMC','EBAY','MSFT','QCOM',
                 'HPQ','JNPR','AMD','IBM']
ds = YahooStockDataSource(cachedFolderName=cachedFolderName,
                            dataSetId=dataSetId,
                            instrumentIds=instrumentIds,
                            startDateStr=startDateStr,
                            endDateStr=endDateStr,
                            event='history')
data = ds.getBookDataByFeature()['Adj Close']
data.head(3)

img

এখন আসুন আমরা আমাদের পদ্ধতি ব্যবহার করে সমন্বিত লেনদেনের জোড়া খুঁজে বের করার চেষ্টা করি।

# Heatmap to show the p-values of the cointegration test
# between each pair of stocks
scores, pvalues, pairs = find_cointegrated_pairs(data)
import seaborn
m = [0,0.2,0.4,0.6,0.8,1]
seaborn.heatmap(pvalues, xticklabels=instrumentIds, 
                yticklabels=instrumentIds, cmap=’RdYlGn_r’, 
                mask = (pvalues >= 0.98))
plt.show()
print pairs
[('ADBE', 'MSFT')]

img

এটা মনে হয় যে ADBE এবং MSFT ক্যালোরিগুলি একসাথে কাজ করছে। আসুন এটির দামটি দেখুন যাতে এটি সত্যই অর্থপূর্ণ হয়।

S1 = data['ADBE']
S2 = data['MSFT']
score, pvalue, _ = coint(S1, S2)
print(pvalue)
ratios = S1 / S2
ratios.plot()
plt.axhline(ratios.mean())
plt.legend([' Ratio'])
plt.show()

img

২০০৮-২০১৭ MSFT এবং ADBE এর মধ্যে মূল্য অনুপাতের চিত্র

এই অনুপাতটি সত্যিই একটি স্থিতিশীল গড়ের মতো দেখায়। পরম অনুপাতগুলি পরিসংখ্যানগতভাবে খুব বেশি দরকারী নয়। এটিকে z-পয়েন্ট হিসাবে বিবেচনা করে আমাদের সংকেতগুলিকে মানসম্মত করে তোলা আরও সহায়ক। Z-পয়েন্টটি সংজ্ঞায়িত করা হয়েছেঃ

Z স্কোর (মান) = (মান গড়) / স্ট্যান্ডার্ড ডিভিয়েশন

সতর্কতা

বাস্তবে, আমরা সাধারণত ডাটাতে কিছু এক্সটেনশন করার চেষ্টা করি, তবে এই তথ্যগুলি যদি স্বাভাবিকভাবে বিতরণ করা হয় তবে। তবে, অনেক আর্থিক তথ্যই স্বাভাবিকভাবে বিতরণ করা হয় না, তাই আমাদের খুব সতর্ক থাকতে হবে যে আমরা যখন পরিসংখ্যান তৈরি করি তখন কেবলমাত্র স্বাভাবিকতা বা কোনও নির্দিষ্ট বিতরণকে অনুমান না করি। অনুপাতের সত্যিকারের বিতরণগুলি একটি মোটা শেষ প্রভাব ফেলতে পারে, এবং যেসব তথ্য চূড়ান্ত দিকে ঝুঁকছে সেগুলি আমাদের মডেলগুলিকে বিভ্রান্ত করে এবং বিশাল ক্ষতির দিকে পরিচালিত করে।

def zscore(series):
    return (series - series.mean()) / np.std(series)
zscore(ratios).plot()
plt.axhline(zscore(ratios).mean())
plt.axhline(1.0, color=’red’)
plt.axhline(-1.0, color=’green’)
plt.show()

img

MSFT এবং ADBE এর মধ্যে Z মূল্যের অনুপাত 2008 - 2017

এখন আমরা সহজেই দেখতে পাচ্ছি যে হারগুলি গড়ের কাছাকাছি চলেছে, কিন্তু মাঝে মাঝে গড়ের সাথে বড় পার্থক্য দেখা দেয়, আমরা এটি ব্যবহার করতে পারি।

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

  • নির্ভরযোগ্য তথ্য সংগ্রহ এবং পরিচ্ছন্নতা

  • লেনদেনের সংকেত / যুক্তি সনাক্ত করার জন্য ডেটা থেকে বৈশিষ্ট্য তৈরি করুন

  • ফাংশনগুলি হ'ল চলমান গড় বা দামের ডেটা, প্রাসঙ্গিকতা বা আরও জটিল সংকেতগুলির অনুপাত - নতুন বৈশিষ্ট্য তৈরি করতে এগুলি একত্রিত করুন

  • এই বৈশিষ্ট্যগুলি ব্যবহার করে ট্রেডিং সিগন্যাল তৈরি করা হয়, অর্থাৎ কোন সিগন্যালগুলি কিনতে, বিক্রি করতে বা খালি অবস্থানের প্রত্যাশা করে

সৌভাগ্যবশত, আমাদের কাছে উদ্ভাবকদের জন্য একটি পরিমাণগত প্ল্যাটফর্ম রয়েছে।fmz.comআমরা এই চারটি বিষয়ে কাজ করেছি, যা কৌশল বিকাশকারীদের জন্য একটি বড় গসপেল, এবং আমরা কৌশলগত যুক্তির নকশা এবং কার্যকারিতা সম্প্রসারণে আমাদের শক্তি এবং সময় ব্যয় করতে পারি।

ইনভেন্টর কোয়ালিটি প্ল্যাটফর্মে, বিভিন্ন মূলধারার এক্সচেঞ্জের ইন্টারফেসগুলি প্যাকেজ করা আছে, আমাদের যা করতে হবে তা হ'ল এই এপিআইগুলিকে কল করা, এবং অবশিষ্টটি হ'ল তলদেশের বাস্তবায়ন যুক্তি, যা ইতিমধ্যে পেশাদার দলগুলি এটিকে ভালভাবে পরিশোধন করেছে।

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

আসুন শুরু করা যাকঃ

প্রথম ধাপঃ আপনার সমস্যা নির্ধারণ করুন

এখানে, আমরা একটি সংকেত তৈরি করার চেষ্টা করছি যা আমাদের বলে যে পরবর্তী মুহুর্তে এই হারটি কেনা বা বিক্রি হবে, অর্থাৎ আমাদের পূর্বাভাস ভেরিয়েবল Y:

Y = অনুপাত হল কিনুন (1) বা বিক্রি করুন (-1) ।

Y ((t) = Sign ((Ratio ((t+1) Ratio ((t))

মনে রাখবেন, আমাদের প্রকৃত লেনদেনের মূল্যের পূর্বাভাস দেওয়ার প্রয়োজন নেই, এমনকি হারটির প্রকৃত মূল্যও নেই (যদিও আমরা পারি), কেবলমাত্র হারটির পরবর্তী দিকের পূর্বাভাস দেওয়ার প্রয়োজন রয়েছে।

দ্বিতীয় ধাপঃ নির্ভরযোগ্য এবং সঠিক তথ্য সংগ্রহ

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

আমরা গত ১০ বছরের (প্রায় ২৫০০ ডেটা পয়েন্ট) ট্রেডিং দিনের জন্য ইয়াহু ফিনান্সিয়াল ব্যবহার করে নিম্নলিখিত তথ্য সংগ্রহ করেছিঃ ওপেন, ক্লোজ, হাইক, লম এবং ট্রেডিং ভলিউম।

তৃতীয় ধাপঃ তথ্য বিভাজন

মডেলের নির্ভুলতা পরীক্ষা করার জন্য এই অত্যন্ত গুরুত্বপূর্ণ পদক্ষেপটি ভুলে যাবেন না। আমরা নিম্নলিখিত ডেটা ব্যবহার করে প্রশিক্ষণ / যাচাইকরণ / পরীক্ষার বিভাজন করছি।

  • প্রশিক্ষণ ৭ বছর ~ ৭০%

  • পরীক্ষা ~ ৩ বছর ৩০%

ratios = data['ADBE'] / data['MSFT']
print(len(ratios))
train = ratios[:1762]
test = ratios[1762:]

আদর্শভাবে, আমাদেরও একটি ভেরিফিকেশন সেট তৈরি করা উচিত, কিন্তু আমরা এই মুহুর্তে এটি করব না।

চতুর্থ ধাপঃ বৈশিষ্ট্য নির্মাণ

সম্পর্কিত ফাংশন কি হতে পারে? আমরা অনুপাতের পরিবর্তনের দিকটি পূর্বাভাস দিতে চাই। আমরা ইতিমধ্যে দেখেছি যে আমাদের দুটি ট্রেডিং ইঙ্গিতগুলি সমন্বিত, তাই এই অনুপাতটি প্রায়শই স্থানান্তরিত হয় এবং গড়ের দিকে ফিরে আসে। দেখে মনে হচ্ছে আমাদের বৈশিষ্ট্যটি হ'ল অনুপাতের গড়ের কিছু মেট্রিক, বর্তমান মান এবং গড়ের মধ্যে পার্থক্য আমাদের ট্রেডিং সংকেত তৈরি করতে পারে।

আমরা নিম্নলিখিত বৈশিষ্ট্যগুলি ব্যবহার করিঃ

  • ৬০ দিনের মুভিং এভারেজঃ রোলিং এভারেজের পরিমাপ

  • 5 দিনের চলমান গড় হারঃ গড়ের বর্তমান মানের পরিমাপ

  • ৬০ দিনের স্ট্যান্ডার্ড ডিফারেন্স

  • z স্কোরঃ ((5d MA - 60d MA) / 60d SD

ratios_mavg5 = train.rolling(window=5,
                               center=False).mean()
ratios_mavg60 = train.rolling(window=60,
                               center=False).mean()
std_60 = train.rolling(window=60,
                        center=False).std()
zscore_60_5 = (ratios_mavg5 - ratios_mavg60)/std_60
plt.figure(figsize=(15,7))
plt.plot(train.index, train.values)
plt.plot(ratios_mavg5.index, ratios_mavg5.values)
plt.plot(ratios_mavg60.index, ratios_mavg60.values)
plt.legend(['Ratio','5d Ratio MA', '60d Ratio MA'])
plt.ylabel('Ratio')
plt.show()

img

60d এবং 5d MA এর দামের অনুপাত

plt.figure(figsize=(15,7))
zscore_60_5.plot()
plt.axhline(0, color='black')
plt.axhline(1.0, color='red', linestyle='--')
plt.axhline(-1.0, color='green', linestyle='--')
plt.legend(['Rolling Ratio z-Score', 'Mean', '+1', '-1'])
plt.show()

img

60-5 Z স্কোর মূল্য অনুপাত

রোলিং গড়ের Z-পয়েন্টগুলি সত্যিই অনুপাতের গড়-গতির রিগ্রেশন প্রকৃতিকে প্রকাশ করে!

পঞ্চম ধাপঃ মডেল নির্বাচন

আসুন আমরা একটি খুব সহজ মডেল দিয়ে শুরু করি. z স্কোর চার্ট দেখুন, আমরা দেখতে পাচ্ছি যে z স্কোর খুব বেশি বা খুব কম হলে এটি ফিরে আসবে. আসুন আমরা + 1 / -1 ব্যবহার করি আমাদের থ্রেশহোল্ড হিসাবে খুব বেশি এবং খুব কম সংজ্ঞায়িত করতে, এবং তারপরে আমরা নিম্নলিখিত মডেলটি ব্যবহার করতে পারি ট্রেডিং সিগন্যাল তৈরি করতেঃ

  • যদি z -1 এর নিচে থাকে, তাহলে হারটি হল buy (-1), কারণ আমরা আশা করি z 0 এ ফিরে আসবে, তাই হার বাড়বে।

  • যখন z 1.0 এর চেয়ে বড় হয়, তখন রেটটি বিক্রি হয় (−1) কারণ আমরা আশা করি যে z 0 এ ফিরে আসবে, তাই রেটটি হ্রাস পায়

ষষ্ঠ ধাপঃ প্রশিক্ষণ, যাচাইকরণ এবং অপ্টিমাইজেশন

এবং শেষ পর্যন্ত, আসুন আমরা দেখি আমাদের মডেলের প্রকৃত তথ্যের উপর কী প্রভাব পড়ছে। আসুন আমরা দেখি এই সংকেতটি প্রকৃত অনুপাতের সাথে কিভাবে কাজ করে।

# Plot the ratios and buy and sell signals from z score
plt.figure(figsize=(15,7))
train[60:].plot()
buy = train.copy()
sell = train.copy()
buy[zscore_60_5>-1] = 0
sell[zscore_60_5<1] = 0
buy[60:].plot(color=’g’, linestyle=’None’, marker=’^’)
sell[60:].plot(color=’r’, linestyle=’None’, marker=’^’)
x1,x2,y1,y2 = plt.axis()
plt.axis((x1,x2,ratios.min(),ratios.max()))
plt.legend([‘Ratio’, ‘Buy Signal’, ‘Sell Signal’])
plt.show()

img

কিনুন এবং বিক্রয় হার সংকেত

এই সংকেতটি যুক্তিসঙ্গত বলে মনে হচ্ছে, আমরা যখন এটি উচ্চ বা বৃদ্ধি পায় তখন আমরা বিক্রি করি (লাল বিন্দু) এবং যখন এটি কম হয় (সবুজ বিন্দু) এবং হ্রাস পায় তখন আমরা আবার কিনে থাকি। এটি আমাদের ব্যবসায়ের প্রকৃত ট্রেডিং সূচকগুলির জন্য কী বোঝায়? আসুন দেখি।

# Plot the prices and buy and sell signals from z score
plt.figure(figsize=(18,9))
S1 = data['ADBE'].iloc[:1762]
S2 = data['MSFT'].iloc[:1762]
S1[60:].plot(color='b')
S2[60:].plot(color='c')
buyR = 0*S1.copy()
sellR = 0*S1.copy()
# When buying the ratio, buy S1 and sell S2
buyR[buy!=0] = S1[buy!=0]
sellR[buy!=0] = S2[buy!=0]
# When selling the ratio, sell S1 and buy S2 
buyR[sell!=0] = S2[sell!=0]
sellR[sell!=0] = S1[sell!=0]
buyR[60:].plot(color='g', linestyle='None', marker='^')
sellR[60:].plot(color='r', linestyle='None', marker='^')
x1,x2,y1,y2 = plt.axis()
plt.axis((x1,x2,min(S1.min(),S2.min()),max(S1.max(),S2.max())))
plt.legend(['ADBE','MSFT', 'Buy Signal', 'Sell Signal'])
plt.show()

img

MSFT এবং ADBE শেয়ার কেনার এবং বিক্রির জন্য সংকেত

দয়া করে নোট করুন যে আমরা কখনও কখনও "সংক্ষিপ্ত পায়ে" অর্থ উপার্জন করি, কখনও কখনও "দীর্ঘ পায়ে" অর্থ উপার্জন করি এবং কখনও কখনও উভয়ই।

আমরা ট্রেনিং ডেটার সংকেত নিয়ে সন্তুষ্ট। আসুন দেখি এই সংকেতটি কি ধরনের মুনাফা আনতে পারে। যখন হার কম হয়, আমরা একটি সহজ রিটার্ন তৈরি করতে পারি, ১টি হার কিনতে পারি (১টি ADBE শেয়ার কিনতে এবং বিক্রি করার হার x MSFT শেয়ার) এবং যখন এটি উচ্চ হয় তখন ১টি হার বিক্রি করতে পারি (১টি ADBE শেয়ার বিক্রি করতে এবং কিনতে হার x MSFT শেয়ার) এবং এই হারগুলির PnL লেনদেন গণনা করতে পারি।

# Trade using a simple strategy
def trade(S1, S2, window1, window2):
    
    # If window length is 0, algorithm doesn't make sense, so exit
    if (window1 == 0) or (window2 == 0):
        return 0
    
    # Compute rolling mean and rolling standard deviation
    ratios = S1/S2
    ma1 = ratios.rolling(window=window1,
                               center=False).mean()
    ma2 = ratios.rolling(window=window2,
                               center=False).mean()
    std = ratios.rolling(window=window2,
                        center=False).std()
    zscore = (ma1 - ma2)/std
    
    # Simulate trading
    # Start with no money and no positions
    money = 0
    countS1 = 0
    countS2 = 0
    for i in range(len(ratios)):
        # Sell short if the z-score is > 1
        if zscore[i] > 1:
            money += S1[i] - S2[i] * ratios[i]
            countS1 -= 1
            countS2 += ratios[i]
            print('Selling Ratio %s %s %s %s'%(money, ratios[i], countS1,countS2))
        # Buy long if the z-score is < 1
        elif zscore[i] < -1:
            money -= S1[i] - S2[i] * ratios[i]
            countS1 += 1
            countS2 -= ratios[i]
            print('Buying Ratio %s %s %s %s'%(money,ratios[i], countS1,countS2))
        # Clear positions if the z-score between -.5 and .5
        elif abs(zscore[i]) < 0.75:
            money += S1[i] * countS1 + S2[i] * countS2
            countS1 = 0
            countS2 = 0
            print('Exit pos %s %s %s %s'%(money,ratios[i], countS1,countS2))
            
            
    return money
trade(data['ADBE'].iloc[:1763], data['MSFT'].iloc[:1763], 60, 5)

ফলাফলঃ ১৭৮৩.৩৭৫

এখন, আমরা একটি চলমান গড় সময় উইন্ডো পরিবর্তন করে, ক্রয় / বিক্রয় এবং স্থিতিশীল অবস্থানের থ্রেশহোল্ড পরিবর্তন করে এবং যাচাইকরণ ডেটার পারফরম্যান্স উন্নতি পরীক্ষা করে আরও অনুকূল করতে পারি।

আমরা আরও জটিল মডেল যেমন লজিস্টিক রিগ্রেশন, এসভিএম ইত্যাদি চেষ্টা করতে পারি যাতে 1/-1 পূর্বাভাস দেওয়া যায়।

এখন, চলুন এই মডেলটি আরও এগিয়ে নিয়ে যাই, যা আমাদের এনেছে

সপ্তম ধাপঃ পরীক্ষার তথ্য পুনরায় পরীক্ষা করুন

এখানে আরও একটি উদ্ভাবক ক্যোটিফিকেশন প্ল্যাটফর্মের কথা উল্লেখ করা যেতে পারে, যা উচ্চ-পারফরম্যান্স QPS/TPS পুনঃনির্ধারণ ইঞ্জিন ব্যবহার করে, ঐতিহাসিক পরিবেশের সত্যিকারের পুনরাবৃত্তি করে, সাধারণ পরিমাণগত পুনঃনির্ধারণ ফাঁদগুলি দূর করে এবং কৌশলগত ত্রুটিগুলিকে সময়মত সনাক্ত করে, যা প্রকৃত বিনিয়োগের জন্য আরও ভাল সহায়তা করে।

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

রিটার্নিং খুবই সহজ, আমরা উপরের ফাংশনটি ব্যবহার করতে পারি পরীক্ষার তথ্যের PnL দেখতে।

trade(data[‘ADBE’].iloc[1762:], data[‘MSFT’].iloc[1762:], 60, 5)

ফলাফলঃ ৫২৬২,৮৬৮

এই মডেলটি খুব ভাল কাজ করেছে! এটি আমাদের প্রথম সহজ প্যারেড-টু-ট্রেড মডেল হয়ে উঠেছে।

অতিরিক্ত ফিটনেস এড়ানো

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

আমাদের মডেলের মধ্যে, আমরা ঘূর্ণন পরামিতিগুলি ব্যবহার করে পূর্বাভাস দিয়েছি এবং এর দ্বারা সময় উইন্ডোর দৈর্ঘ্যকে অনুকূলিত করতে চাই। আমরা সহজেই সমস্ত সম্ভাবনার পুনরাবৃত্তি, যুক্তিসঙ্গত সময় উইন্ডোর দৈর্ঘ্য এবং আমাদের মডেলের পারফরম্যান্সের উপর নির্ভর করে সর্বোত্তম সময় দৈর্ঘ্য নির্বাচন করার সিদ্ধান্ত নিতে পারি। নীচে আমরা একটি সহজ লুপ লিখেছি যা প্রশিক্ষণের তথ্যের উপর ভিত্তি করেpnl সময় উইন্ডোর দৈর্ঘ্যকে রেট দেয় এবং সর্বোত্তম লুপটি খুঁজে পায়।

# Find the window length 0-254 
# that gives the highest returns using this strategy
length_scores = [trade(data['ADBE'].iloc[:1762], 
                data['MSFT'].iloc[:1762], l, 5) 
                for l in range(255)]
best_length = np.argmax(length_scores)
print ('Best window length:', best_length)
('Best window length:', 40)

এখন আমরা পরীক্ষার ডেটাতে মডেলের পারফরম্যান্স পরীক্ষা করি এবং আমরা দেখতে পাই যে এই সময় উইন্ডোর দৈর্ঘ্যটি অনুকূল নয়! এটি কারণ আমাদের মূল পছন্দটি স্পষ্টতই নমুনা ডেটাতে অতিরিক্ত ফিট করে।

# Find the returns for test data
# using what we think is the best window length
length_scores2 = [trade(data['ADBE'].iloc[1762:], 
                  data['MSFT'].iloc[1762:],l,5) 
                  for l in range(255)]
print (best_length, 'day window:', length_scores2[best_length])
# Find the best window length based on this dataset, 
# and the returns using this window length
best_length2 = np.argmax(length_scores2)
print (best_length2, 'day window:', length_scores2[best_length2])
(40, 'day window:', 1252233.1395)
(15, 'day window:', 1449116.4522)

এটা স্পষ্ট যে আমাদের নমুনা তথ্য সবসময় ভবিষ্যতে ভাল ফলাফল দিতে পারে না. শুধু পরীক্ষার জন্য, আমাদের দুই ডেটাসেট থেকে গণনা দৈর্ঘ্য ভগ্নাংশ আঁকা যাক.

plt.figure(figsize=(15,7))
plt.plot(length_scores)
plt.plot(length_scores2)
plt.xlabel('Window length')
plt.ylabel('Score')
plt.legend(['Training', 'Test'])
plt.show()

img

আমরা দেখতে পাচ্ছি যে ২০-৫০ এর মধ্যে যেকোনো কিছু একটি সময় উইন্ডোর জন্য একটি ভাল বিকল্প।

অতিরিক্ত ফিটনেস এড়াতে, আমরা অর্থনৈতিক যুক্তি বা অ্যালগরিদমিক প্রকৃতি ব্যবহার করে সময় উইন্ডোর দৈর্ঘ্য নির্বাচন করতে পারি। আমরা কার্লম্যান ফিল্টার ব্যবহার করতে পারি, যা আমাদের দৈর্ঘ্য নির্দিষ্ট করার প্রয়োজন হয় না; এটি পরে অন্য একটি নিবন্ধে বর্ণনা করা হবে।

পরবর্তী পদক্ষেপ

এই নিবন্ধে আমরা ট্রেডিং কৌশল বিকাশের প্রক্রিয়াটি প্রদর্শন করার জন্য কিছু সহজ উপস্থাপনা প্রস্তাব করেছি।

  • হার্স্ট সূচক

  • অর্ণস্টাইন-উহেলেনবেক প্রক্রিয়া থেকে অনুমান করা গড় মানের রিগ্রেশন অর্ধেককালীন

  • কারম্যান ফিল্টার


সম্পর্কিত

আরো

bk_fundএই প্যাকেজটি পাওয়া যায়নি

bk_fundকোথায় ব্যাকটেস্টার ইনস্টল করা যায়.dataSource.yahoo_data_source