0
ফোকাস
78
অনুসারী

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

তৈরি: 2019-08-21 13:50:23, আপডেট করা হয়েছে: 2024-12-19 00:20:12
comments   2
hits   3246

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

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

মৌলিক নীতি

ধরুন আপনার কাছে একজোড়া বিনিয়োগের টার্গেট X এবং Y রয়েছে যার কিছু সম্ভাব্য পারস্পরিক সম্পর্ক রয়েছে, উদাহরণস্বরূপ, দুটি কোম্পানি একই পণ্য তৈরি করে, যেমন পেপসি-কোলা এবং কোকা-কোলা৷ আপনি দুটির মধ্যে মূল্য অনুপাত বা ভিত্তি (যাকে স্প্রেডও বলা হয়) সময়ের সাথে স্থির থাকতে চান। যাইহোক, অস্থায়ী সরবরাহ এবং চাহিদা পরিবর্তনের কারণে সময়ে সময়ে এই দুটি জোড়ার মধ্যে ছড়িয়ে পড়তে পারে, যেমন একটি বিনিয়োগ লক্ষ্যের জন্য বড় ক্রয়/বিক্রয় আদেশ, কোম্পানিগুলির একটি সম্পর্কে গুরুত্বপূর্ণ খবরের প্রতিক্রিয়া ইত্যাদি। এই ক্ষেত্রে, একটি বিনিয়োগ ঊর্ধ্বমুখী হয় যখন অন্যটি একে অপরের সাপেক্ষে নিম্নগামী হয়। আপনি যদি সময়ের সাথে সাথে এই ভিন্নতা স্বাভাবিক হওয়ার আশা করেন, তাহলে আপনি ট্রেডিং সুযোগ (বা সালিসি সুযোগ) চিহ্নিত করতে পারেন। ডিজিটাল মুদ্রার বাজার বা দেশীয় পণ্যের ফিউচার মার্কেটে এই ধরনের সালিশের সুযোগ রয়েছে, যেমন বিটিসি এবং নিরাপদ আশ্রয়ের সম্পদের মধ্যে সম্পর্ক;

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

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

ধারণাটি ব্যাখ্যা করা: দুটি অনুমানমূলক বিনিয়োগ লক্ষ্য

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

প্রথমত, সুষ্ঠুভাবে কাজ করার জন্য, আমাদের গবেষণার পরিবেশ তৈরি করতে হবে। এই প্রবন্ধে, আমরা গবেষণার পরিবেশ তৈরি করতে Inventor Quantitative Platform (FMZ.COM) ব্যবহার করব, মূলত যাতে আমরা সুবিধাজনক এবং দ্রুত API ব্যবহার করতে পারি। এই প্ল্যাটফর্মের ইন্টারফেস এবং এনক্যাপসুলেশন পরে। সম্পূর্ণ ডকার সিস্টেম।

উদ্ভাবক কোয়ান্টিফিকেশন প্ল্যাটফর্মের অফিসিয়াল নামে, এই ডকার সিস্টেমটিকে হোস্ট সিস্টেম বলা হয়।

কিভাবে হোস্ট এবং রোবট স্থাপন করতে হয়, অনুগ্রহ করে আমার আগের নিবন্ধটি পড়ুন: https://www.fmz.com/bbs-topic/4140

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

ক্লাউড কম্পিউটিং পরিষেবা এবং হোস্ট সিস্টেম সফলভাবে স্থাপন করার পরে, পরবর্তী, আমাদের পাইথনের বৃহত্তম শিল্পকর্মটি ইনস্টল করতে হবে: অ্যানাকোন্ডা

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

অ্যানাকোন্ডার ইনস্টলেশন পদ্ধতির জন্য, অনুগ্রহ করে অ্যানাকোন্ডার অফিসিয়াল গাইডটি দেখুন: https://www.anaconda.com/distribution/

এই প্রবন্ধে পাইথন বৈজ্ঞানিক কম্পিউটিংয়ে দুটি অত্যন্ত জনপ্রিয় এবং গুরুত্বপূর্ণ লাইব্রেরি, নম্পি এবং পান্ডাসও ব্যবহার করা হবে।

উপরের মৌলিক কাজের জন্য, আপনি আমার পূর্ববর্তী নিবন্ধটিও উল্লেখ করতে পারেন, যেটিতে অ্যানাকোন্ডা পরিবেশ এবং নম্পি এবং পান্ডাগুলির দুটি লাইব্রেরি কীভাবে সেট আপ করতে হয় তার একটি ভূমিকা রয়েছে, দয়া করে দেখুন: 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

হ্যাঁ, আমরা matplotlibও ব্যবহার করব, পাইথনের একটি খুব বিখ্যাত চার্টিং লাইব্রেরি

আসুন একটি অনুমানমূলক বিনিয়োগ X তৈরি করি এবং একটি সাধারণ বিতরণ সিমুলেশনের মাধ্যমে এর দৈনিক আয়ের পরিকল্পনা করি। তারপরে আমরা দৈনিক 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()

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

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

এখন আমরা যে 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()

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

কো-ইন্টিগ্রেটেড বিনিয়োগ লক্ষ্য X এবং Y

সমন্বয়

সমন্বিতকরণটি পারস্পরিক সম্পর্কের সাথে খুব সাদৃশ্যপূর্ণ এবং এর অর্থ হল দুটি ডেটা সিরিজের অনুপাত গড়ের চারপাশে পরিবর্তিত হবে: দুটি সিরিজ Y এবং X নিম্নলিখিতগুলি অনুসরণ করে:

Y = ⍺ X + e

যেখানে ⍺ হল ধ্রুবক অনুপাত এবং 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()

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

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

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

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

# 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)

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

দুটি সম্পর্কিত সিরিজ (যৌথভাবে সমন্বিত নয়)

সহগ সহগ: ০.৯৯৮ সমন্বিতকরণ পরীক্ষা পি-মান: 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)

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

পারস্পরিক সম্পর্ক: 0.007546 সমন্বিতকরণ পরীক্ষা পি-মান: 0.0

পারস্পরিক সম্পর্ক খুবই কম, কিন্তু p-মান নিখুঁত সমন্বয় দেখায়!

পেয়ার ট্রেডিং কিভাবে করবেন?

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

Y তে X এবং Y তে ফিরে যাওয়া = ⍺ যখন এটি Y থেকে অনেক দূরে থাকে, অর্থাৎ, ⍺ মানটি খুব বেশি বা খুব কম:

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

  • সংক্ষিপ্ত অনুপাত: এটি তখন হয় যখন অনুপাত ⍺ বড় হয় এবং আমরা আশা করি এটি ছোট হবে। উপরের উদাহরণে, আমরা সংক্ষিপ্ত Y এবং দীর্ঘ X গিয়ে একটি অবস্থান খুলি।

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

সম্পদ X এবং Y একে অপরের সাপেক্ষে স্থানান্তরিত হওয়ার সাথে সাথে, আমরা অর্থ উপার্জন করি বা অর্থ হারাতে পারি।

একইভাবে আচরণ করে এমন ট্রেডিং লক্ষ্যমাত্রা খুঁজে পেতে ডেটা ব্যবহার করুন

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

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

তাই আসুন কিছু ট্রেড খুঁজে বের করার চেষ্টা করি যা S&P 500-এ ইউ.এস. লার্জ-ক্যাপ টেকনোলজির স্টকগুলিকে একই রকম বাজারের অংশে কাজ করে এবং এর দাম থাকে। আমরা ট্রেড করা বস্তুর তালিকা স্ক্যান করি এবং সমস্ত জোড়ার মধ্যে সমন্বিতকরণের জন্য পরীক্ষা করি।

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

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)

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

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

# 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')]

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

দেখে মনে হচ্ছে ‘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()

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

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

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

Z Score (Value) = (Value — Mean) / Standard Deviation

সতর্ক করা

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

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()

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

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

গড়ের চারপাশে চলমান অনুপাতটি পর্যবেক্ষণ করা এখন সহজ, তবে কখনও কখনও গড় থেকে বড় বিচ্যুতি দেখা সহজ হয় এবং আমরা এটির সুবিধা নিতে পারি।

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

  • নির্ভরযোগ্য ডেটা সংগ্রহ করুন এবং ডেটা পরিষ্কার করুন

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

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

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

সৌভাগ্যবশত, আমাদের জন্য উপরের চারটি দিক সম্পূর্ণ করার জন্য উদ্ভাবক কোয়ান্টিফিকেশন প্ল্যাটফর্ম রয়েছে সম্প্রসারণ

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

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

চলুন শুরু করা যাক:

ধাপ 1: আপনার প্রশ্ন সেট আপ করুন

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

Y = Ratio is buy (1) or sell (-1)

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

মনে রাখবেন যে আমাদের অনুপাতের প্রকৃত মূল্য, এমনকি অনুপাতের প্রকৃত মূল্য (যদিও আমরা পারি), অনুপাতের পরবর্তী দিকটি অনুমান করতে হবে না

ধাপ 2: নির্ভরযোগ্য এবং সঠিক তথ্য সংগ্রহ করুন

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

আমরা Yahoo Finance ব্যবহার করে গত 10 বছরে ট্রেডিং দিনগুলিতে নিম্নলিখিত ডেটা পেয়েছি (প্রায় 2500 ডেটা পয়েন্ট): খোলা মূল্য, বন্ধ মূল্য, উচ্চ মূল্য, কম মূল্য এবং ভলিউম।

ধাপ 3: ডেটা বিভক্ত করুন

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

  • Training 7 years ~ 70%

  • Test ~ 3 years 30%

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

আদর্শভাবে আমাদেরও একটি বৈধতা সেট করা উচিত, তবে আমরা আপাতত তা করব না।

ধাপ 4: ফিচার ইঞ্জিনিয়ারিং

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

আমরা নিম্নলিখিত ফাংশন ব্যবহার করি:

  • 60-দিনের মুভিং এভারেজ রেশিও: রোলিং এভারেজের একটি পরিমাপ

  • 5-দিনের চলমান গড় অনুপাত: গড় বর্তমান মানের একটি পরিমাপ

  • 60-দিনের আদর্শ বিচ্যুতি

  • 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()

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

৬০ দিন এবং ৫ দিন এমএ মূল্য অনুপাত

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()

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

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

ঘূর্ণায়মান গড়ের জেড-স্কোর সত্যিই অনুপাতের গড়-প্রত্যাবর্তন প্রকৃতি বের করে!

ধাপ 5: মডেল নির্বাচন

একটি খুব সাধারণ মডেল দিয়ে শুরু করা যাক। জেড-স্কোর চার্টের দিকে তাকালে, আমরা দেখতে পাচ্ছি যে যখনই জেড-স্কোর খুব বেশি বা খুব কম হয় তখন এটি পিছিয়ে যায়। খুব বেশি এবং খুব কম সংজ্ঞায়িত করতে আমাদের থ্রেশহোল্ড হিসাবে +1/-1 ব্যবহার করা যাক, তারপর আমরা ট্রেডিং সংকেত তৈরি করতে নিম্নলিখিত মডেলটি ব্যবহার করতে পারি:

  • যখন z -1.0 এর নিচে থাকে, অনুপাতটি বাই(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()

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

বিড এবং আস্ক প্রাইস রেশিও সিগন্যাল

সংকেতটি যুক্তিসঙ্গত বলে মনে হয়, আমরা অনুপাতটি বিক্রি করি যখন এটি বেশি বা বৃদ্ধি পায় (লাল বিন্দু) এবং যখন এটি কম (সবুজ বিন্দু) এবং হ্রাস পায় তখন ফেরত কিনব। আমাদের বাণিজ্যের প্রকৃত অন্তর্নিহিত জন্য এর অর্থ কী? দেখা যাক

# 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()

ডেটা-চালিত প্রযুক্তির উপর ভিত্তি করে পেয়ার ট্রেডিং

এমএসএফটি এবং এডিবিই স্টক ক্রয় এবং বিক্রির সংকেত

লক্ষ্য করুন কিভাবে আমরা কখনও কখনও “শর্ট লেগ”, কখনও “লং লেগ” এবং কখনও কখনও উভয়েই অর্থ উপার্জন করি।

আমরা প্রশিক্ষণ তথ্য থেকে সংকেত সঙ্গে সন্তুষ্ট. চলুন দেখি এই সিগন্যালটি কি ধরনের লাভ জেনারেট করতে পারে। আমরা কেনার জন্য 1 অনুপাতের একটি সাধারণ ব্যাকটেস্টার তৈরি করতে পারি (1টি ADBE স্টক কিনুন এবং অনুপাত x MSFT স্টক বিক্রি করুন) এবং অনুপাত কম হলে 1 অনুপাত বিক্রি করতে পারি (1টি 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)

ফলাফল হল: 1783.375

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

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

এখন, আসুন এই মডেলটিকে অগ্রসর করি, যা আমাদের নিয়ে আসে

ধাপ 7: পরীক্ষার ডেটা ব্যাকটেস্ট করুন

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

নীতিটি ব্যাখ্যা করার জন্য, এই নিবন্ধটি ব্যবহারিক প্রয়োগগুলিতে, পাঠকদের সময় বাঁচানোর পাশাপাশি, ত্রুটি সহনশীলতার হার উন্নত করার জন্য সুপারিশ করা হয়।

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

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

ফলাফল হল: 5262.868

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

অতিরিক্ত ফিটিং এড়িয়ে চলুন

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

আমাদের মডেলে, আমরা রোলিং প্যারামিটার অনুমান ব্যবহার করি এবং তাদের দ্বারা সময় উইন্ডোর দৈর্ঘ্য অপ্টিমাইজ করতে চাই। আমরা সব সম্ভাবনা, যুক্তিসঙ্গত সময় উইন্ডো দৈর্ঘ্য, এবং আমাদের মডেল সবচেয়ে ভাল পারফর্ম করে তার উপর ভিত্তি করে সময় দৈর্ঘ্য নির্বাচন করার সিদ্ধান্ত নিতে পারি। নীচে আমরা প্রশিক্ষণ ডেটার 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)

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