paint-brush
অ্যালগরিদমিক জাদুকর: বৈদেশিক মুদ্রায় গ্রাফ থিওরি শোষণদ্বারা@optiklab
1,163 পড়া
1,163 পড়া

অ্যালগরিদমিক জাদুকর: বৈদেশিক মুদ্রায় গ্রাফ থিওরি শোষণ

দ্বারা Anton Yarkov22m2023/10/28
Read on Terminal Reader

অতিদীর্ঘ; পড়তে

আমার পূর্ববর্তী প্রচেষ্টা অনুসরণ করে, লাভজনক মুদ্রা বিনিময়ের উপায় খুঁজতে আমি গ্রাফ এবং গ্রাফ ট্রাভার্সাল অ্যালগরিদম নিয়ে খেলা চালিয়ে যাচ্ছি।
featured image - অ্যালগরিদমিক জাদুকর: বৈদেশিক মুদ্রায় গ্রাফ থিওরি শোষণ
Anton Yarkov HackerNoon profile picture

আপনি যদি ফিনটেক স্টার্টআপ শিল্পের সাথে পরিচিত হন, আপনি হয়তো লন্ডন, যুক্তরাজ্যে অবস্থিত একটি সুপরিচিত ফিনটেক জায়ান্ট Revolut-এর কথা শুনে থাকবেন। 2015 সালে প্রতিষ্ঠিত, Revolut যথেষ্ট বিনিয়োগ অর্জন করেছে এবং অনেক ইউরোপীয় নাগরিককে ব্যাঙ্কিং পরিষেবা প্রদান করে যুক্তরাজ্যের দ্রুততম বর্ধনশীল স্টার্টআপগুলির মধ্যে একটি হয়ে উঠেছে।


যদিও ব্যাঙ্কিং অপারেশনগুলি প্রায়শই রহস্যের মধ্যে আবৃত থাকে যখন তারা কীভাবে রাজস্ব তৈরি করে, 2020 এবং 2021 সালের জন্য রেভলুট সম্পর্কে কিছু মূল পরিসংখ্যান তাদের আয়ের উত্সগুলির উপর কিছু আলোকপাত করেছে:


Revolut আয় বিবৃতি


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


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


কারেন্সি আর্বিট্রেজ হল একটি ট্রেডিং কৌশল যেখানে একজন কারেন্সি ট্রেডার একাধিক ট্রেডের মাধ্যমে একটি নির্দিষ্ট কারেন্সি পেয়ারের জন্য ব্রোকারদের দেওয়া বিভিন্ন স্প্রেড লাভ করে।


এটি স্পষ্টভাবে টাস্কে উল্লেখ করা হয়েছিল যে অ্যালগরিদমের ভিত্তি গ্রাফ তত্ত্বের মূলে থাকা আবশ্যক।


FX বেসিক

এফএক্স, বা ফরেন এক্সচেঞ্জ, বিশ্ব বাণিজ্যে একটি মুখ্য ভূমিকা পালন করে, যা আমাদের আন্তঃসংযুক্ত বিশ্বের কার্যকারিতার উপর ভিত্তি করে। এটা স্পষ্ট যে FX ব্যাঙ্কগুলিকে কিছু ধনী প্রতিষ্ঠানে পরিণত করার ক্ষেত্রেও যথেষ্ট ভূমিকা পালন করে।


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


এফএক্স (ফরেন এক্সচেঞ্জ) এর ক্ষেত্রে, আমরা সবসময় যুগল মুদ্রার সাথে কাজ করি, যেমন EUR/USD। বেশিরভাগ ক্ষেত্রে, এই এক্সচেঞ্জগুলি দ্বিমুখী হয় (যেমন, EUR/USD এবং USD/EUR), এবং বিনিময় হারের মান প্রতিটি দিকে আলাদা হয়।


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


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


আরবিট্রেজ নিশ্চিত বাজি হল জোড়ার একটি সেট যা বৃত্তাকার পদ্ধতিতে ব্যবহার করা হবে। আরও পড়ুন


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


নিশ্চিত বাজির দৈর্ঘ্য এমন জোড়ার সংখ্যা বোঝায় যা সম্ভাব্য সালিসি সুযোগের একটি সেট গঠন করে।


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

ব্যবহারিক লাভজনক ব্যবসায়, একাধিক ধাপে বিভিন্ন বিনিময় প্ল্যাটফর্মে বিভিন্ন মুদ্রার মাধ্যমে রূপান্তর জড়িত থাকতে পারে। অন্য কথায়, আরবিট্রেজ সার্কেল বেশ বিস্তৃত হতে পারে।


আরবিট্রেজ সার্কেলে একটি মুদ্রা অর্জন করা, অন্য প্ল্যাটফর্মে স্থানান্তর করা, অন্যান্য মুদ্রার বিনিময় পরিচালনা করা এবং শেষ পর্যন্ত আসল মুদ্রায় ফিরে আসা অন্তর্ভুক্ত।


এক বা একাধিক মধ্যবর্তী মুদ্রার মাধ্যমে দুটি মুদ্রার মধ্যে বিনিময় হার এই মধ্যবর্তী লেনদেনের বিনিময় হারের গুণফল হিসাবে গণনা করা হয়।


একটি উদাহরণ

উদাহরণ স্বরূপ, আসুন কল্পনা করি আমরা ইউএস ডলারের জন্য সুইস ফ্রাঙ্ক কিনতে চাই, তারপরে ফ্রাঙ্কগুলিকে জাপানি ইয়েনের সাথে বিনিময় করতে চাই এবং তারপরে আবার ইউএস ডলারে ইয়েন বিক্রি করতে চাই। শরত্কালে, 2023, আমাদের নিম্নলিখিত বিনিময় হার রয়েছে:


  1. আমরা 1 USD এর জন্য 0.91 CHF (সুইস ফ্রাঙ্ক) কিনতে পারি।

  2. আমরা 1 CHF এর জন্য 163.16 জাপানি ইয়েন কিনতে পারি।

  3. আমরা 0.0067 USD 1 জাপানি ইয়েন কিনতে পারি।


আসুন এটি একটি টেবিলের সাথে উপস্থাপন করা যাক:

 1 USD | 1 CHF | 1 YEN 0.91 CHF | 163.16 YEN | 0.0067 USD ----------------|-------------------|-------------- 1.098901099 | 0.006128953 | 149.2537313


এখন, আমাদের সেই মানগুলির একটি পণ্য খুঁজে বের করতে হবে। লেনদেনের একটি ক্রম লাভজনক হয়ে ওঠে যখন এই পণ্যটি একটির চেয়ে কম মূল্য দেয় :

 1.098901099 * 0.006128953 * 149.2537313 = 1.005240803


আমরা দেখতে পাচ্ছি যে ফলাফলটি একটির চেয়ে বড়, তাই মনে হচ্ছে আমরা আমাদের অর্থের 0.05% হারিয়েছি। কিন্তু ঠিক কতজন? আমরা এটিকে এভাবে সাজাতে পারি:

 0.91 CHF * 163.16 (YEN per 1 CHF) * 0.0067 (USD per 1 YEN) = 0.99478652 US Dollars


তাই, শুরুতে 1 ইউএস ডলার বিক্রি করার পর আমরা 0.994 পেয়েছি - শেষ পর্যন্ত 1 ইউএস ডলারের কম।


সহজ ভাষায়, আরবিট্রেজ সাইকেল লাভজনক হয় যখন একই মুদ্রার এক ইউনিটের কম জন্য মুদ্রার এক ইউনিট পাওয়া যায়।


ধরা যাক আমরা 0.91 CHF এর পরিবর্তে প্রাথমিক লেনদেনে প্রতি 1 US ডলারে 0.92 CHF নেওয়ার সুযোগ পেয়েছি:

 1 USD | 1 CHF | 1 YEN 0.92 CHF | 163.16 YEN | 0.0067 USD ----------------|-------------------|-------------- 1.086956522 | 0.006128953 | 149.2537313


একটি পণ্য 1 এর কম হবে:

 1.086956522 * 0.006128953 * 149.2537313 = 0.994314272


যার অর্থ, প্রকৃত মুদ্রায় এটি আমাদের 1 ইউএস ডলারের বেশি দেবে:

 0.92 CHF * 163.16 (YEN per 1 CHF) * 0.0067 (USD per 1 YEN) = 1.00571824 US Dollars


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

সুতরাং, 3টি আরবিট্রেজ পেয়ারের আরবিট্রেজ সার্কেলে লাভ বা ক্ষতি পরীক্ষা করার সূত্রটি দেখতে এইরকম হবে:

 USD/CHF * CHF/YEN * YEN/USD < 1.0

গ্রাফ উপস্থাপনা

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


সুতরাং, ম্যাট্রিক্সে দুটি জোড়া বিনিময়কে এভাবে উপস্থাপন করা সোজা:

 EUR USD 1 1 EUR 1 1 USD


জড়িত জোড়ার সংখ্যার উপর নির্ভর করে, আমাদের ম্যাট্রিক্স প্রসারিত হতে পারে:

 EUR USD YEN CHF 1 1 1 1 EUR 1 1 1 1 USD 1 1 1 1 YEN 1 1 1 1 CHF


ফলস্বরূপ, আমাদের টেবিলটি যথেষ্ট বড় হয়ে উঠতে পারে, এমনকি মাত্র দুটি মুদ্রার জন্য, যদি আমরা আরও বিনিময় প্ল্যাটফর্ম এবং সংস্থানগুলিকে বিবেচনা করি।


প্রকৃত কারেন্সি আর্বিট্রেজ সমস্যা সমাধানের জন্য, একটি সম্পূর্ণ গ্রাফ যা মুদ্রার উদ্ধৃতিগুলির জন্য সমস্ত সম্পর্ককে অন্তর্ভুক্ত করে প্রায়শই ব্যবহার করা হয়। একটি তিন-মুদ্রা বিনিময় টেবিল নিম্নরূপ প্রদর্শিত হতে পারে:

 USD CHF YEN { 1.0, 1.10, 0.0067 } USD { 0.91, 1.0, 0.0061 } CHF { 148.84, 163.16, 1.0 } YEN


মেমরিতে আমাদের মুদ্রা জোড়া উপস্থাপন করার জন্য আমরা একটি সাধারণ গ্রাফ ডেটা কাঠামো নিয়োগ করতে পারি:

 class GraphNode { public: string Name; }; class Graph { public: vector<vector<double>> Matrix; vector<GraphNode> Nodes; };


এখন, আমাদের শুধুমাত্র এই গ্রাফটি কীভাবে অতিক্রম করা যায় তা খুঁজে বের করতে হবে এবং সবচেয়ে লাভজনক বৃত্তটি খুঁজে বের করতে হবে। কিন্তু এখনও একটি সমস্যা আছে ...

গণিত আবার আমাদের বাঁচায়

ক্লাসিক্যাল গ্রাফ অ্যালগরিদমগুলি প্রান্তের দৈর্ঘ্যের পণ্যের সাথে কাজ করার জন্য উপযুক্ত নয় কারণ তারা এই দৈর্ঘ্যের সমষ্টি হিসাবে সংজ্ঞায়িত পথগুলি খুঁজে বের করার জন্য ডিজাইন করা হয়েছে (যেকোন সুপরিচিত ক্লাসিক পাথ-ফাইন্ডিং অ্যালগরিদম BFS, DFS, Dijkstra বা এমনকি এর বাস্তবায়ন দেখুন এ-স্টার )।


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


লগারিদম


এই সমীকরণের ডানদিকে, পছন্দসই সংখ্যাটি একের চেয়ে কম, ইঙ্গিত করে যে এই সংখ্যাটির লগারিদম অবশ্যই শূন্যের কম হতে হবে:

 LogE(USD/CHF) * LogE(CHF/YEN) * LogE(YEN/USD) < 0.0


এই সহজ গাণিতিক কৌশলটি আমাদেরকে একের চেয়ে কম প্রান্তের দৈর্ঘ্যের পণ্য সহ একটি চক্র অনুসন্ধান করা থেকে এমন একটি চক্রের সন্ধানে স্থানান্তরিত করতে দেয় যেখানে প্রান্তের দৈর্ঘ্যের যোগফল শূন্যের চেয়ে কম

আমাদের ম্যাট্রিক্স মানগুলি একটি LogE(x) এ রূপান্তরিত হয়েছে এবং বিন্দুর পরে 2টি সংখ্যা দিয়ে বৃত্তাকার হয়েছে, এখন দেখতে এইরকম:

 USD CHF YEN { 0.0, 0.1, -5.01 } USD { -0.09, 0.0, -5.1 } CHF { 5.0, 5.09, 0.0 } YEN


এখন এই সমস্যাটি ক্লাসিক্যাল গ্রাফ অ্যালগরিদম ব্যবহার করে আরও সমাধানযোগ্য হয়ে উঠেছে। আমাদের যা প্রয়োজন তা হল বিনিময়ের সবচেয়ে লাভজনক পথের সন্ধানে গ্রাফটি অতিক্রম করা।

গ্রাফ অ্যালগরিদম

প্রতিটি অ্যালগরিদমের সীমাবদ্ধতা রয়েছে। আমি আমার আগের নিবন্ধে তাদের কিছু উল্লেখ করেছি।

আমরা এখানে ক্লাসিক্যাল BFS, DFS বা এমনকি Dijkstra প্রয়োগ করতে পারি না কারণ আমাদের গ্রাফে ঋণাত্মক ওজন থাকতে পারে, যা গ্রাফ অতিক্রম করার সময় নেতিবাচক চক্রের দিকে নিয়ে যেতে পারে। নেতিবাচক চক্রগুলি অ্যালগরিদমের জন্য একটি চ্যালেঞ্জ তৈরি করে কারণ এটি ক্রমাগত প্রতিটি পুনরাবৃত্তিতে আরও ভাল সমাধান খুঁজে পায়।


এই সমস্যাটি সমাধান করার জন্য, বেলম্যান-ফোর্ড অ্যালগরিদম কেবল পুনরাবৃত্তির সংখ্যা সীমিত করে। এটি একটি চক্রে গ্রাফের প্রতিটি প্রান্ত অতিক্রম করে এবং V-1 বারের বেশি নয় (যেখানে V নোডের সংখ্যা) সমস্ত প্রান্তের জন্য শিথিলতা প্রয়োগ করে।


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


যদিও এই অ্যালগরিদমটি তাত্ত্বিকভাবে সহজবোধ্য (এবং আপনি এটি সম্পর্কে বিলিয়ন ভিডিওগুলি খুঁজে পেতে পারেন), আমাদের প্রয়োজনের জন্য ব্যবহারিক বাস্তবায়নের জন্য কিছু প্রচেষ্টা প্রয়োজন৷ এর মধ্যে খনন করা যাক.

বেলম্যান-ফোর্ড অ্যালগরিদম বাস্তবায়ন

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


অ্যালগরিদমের একটি মসৃণ ভূমিকার জন্য, আসুন এমন একটি গ্রাফ ব্যবহার করি যাতে নেতিবাচক চক্র নেই:

 graph.Nodes.push_back({ "USD" }); graph.Nodes.push_back({ "CHF" }); graph.Nodes.push_back({ "YEN" }); graph.Nodes.push_back({ "GBP" }); graph.Nodes.push_back({ "CNY" }); graph.Nodes.push_back({ "EUR" }); // Define exchange rates for pairs of currencies below // USD CHF YEN GBP CNY EUR graph.Matrix = { { 0.0, 0.41, INF, INF, INF, 0.29 }, // USD { INF, 0.0, 0.51, INF, 0.32, INF }, // CHF { INF, INF, 0.0, 0.50, INF, INF }, // YEN { 0.45, INF, INF, 0.0, INF, -0.38 }, // GBP { INF, INF, 0.32, 0.36, 0.0, INF }, // CNY { INF, -0.29, INF, INF, 0.21, 0.0 } }; // EUR


নীচের কোড উদাহরণটি বেলম্যান-ফোর্ড অ্যালগরিদম ব্যবহার করে দুটি নোডের মধ্যে একটি পথ খুঁজে পায় যখন গ্রাফে নেতিবাচক চক্রের অভাব থাকে:

 vector<double> _shortestPath; vector<int> _previousVertex; void FindPath(Graph& graph, int start) { int verticesNumber = graph.Nodes.size(); _shortestPath.resize(verticesNumber, INF); _previousVertex.resize(verticesNumber, -1); _shortestPath[start] = 0; // For each vertex, apply relaxation for all the edges V - 1 times. for (int k = 0; k < verticesNumber - 1; k++) for (int from = 0; from < verticesNumber; from++) for (int to = 0; to < verticesNumber; to++) if (_shortestPath[to] > _shortestPath[from] + graph.Matrix[from][to]) { _shortestPath[to] = _shortestPath[from] + graph.Matrix[from][to]; _previousVertex[to] = from; } }


চাইনিজ ইউয়ানের জন্য এই কোডটি চালানো _previousVertex অ্যারে পূরণ করে এবং এর মতো ফলাফল দেয়:

 Path from 4 to 0 is : 4(CNY) 3(GBP) 0(USD) Path from 4 to 1 is : 4(CNY) 3(GBP) 5(EUR) 1(CHF) Path from 4 to 2 is : 4(CNY) 3(GBP) 5(EUR) 1(CHF) 2(YEN) Path from 4 to 3 is : 4(CNY) 3(GBP) Path from 4 to 4 is : 4(CNY) Path from 4 to 5 is : 4(CNY) 3(GBP) 5(EUR)


আপনি লক্ষ্য করতে পারেন, এটি CNY এবং অন্যান্য বিভিন্ন মুদ্রার মধ্যে সর্বোত্তম পথ চিহ্নিত করে।


এবং আবার, আমি শুধুমাত্র একটি সেরা খুঁজে বের করার উপর ফোকাস করব না, কারণ এটি তুলনামূলকভাবে সহজ কাজ এবং নিবন্ধের লক্ষ্য নয়।


উপরের বাস্তবায়ন আদর্শ ক্ষেত্রে ভাল কাজ করে কিন্তু নেতিবাচক চক্র ধারণকারী গ্রাফগুলির সাথে কাজ করার সময় কম পড়ে।

নেতিবাচক চক্র সনাক্তকরণ

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


পুনরাবৃত্তির সংখ্যা সর্বদা সুনির্দিষ্টভাবে V - 1-এ পৌঁছাতে হবে না। একটি সমাধান পাওয়া গেছে বলে মনে করা হয় যদি, (N+1)-ম চক্রে, N-তম চক্রের চেয়ে ভাল কোন পথ খুঁজে পাওয়া যায় না। সুতরাং, সামান্য অপ্টিমাইজেশনের জন্য জায়গা আছে।


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

 vector<double> _shortestPath; vector<int> _previousVertex; bool ContainsNegativeCycles(Graph& graph, int start) { int verticesNumber = graph.Nodes.size(); _shortestPath.resize(verticesNumber, INF); _previousVertex.resize(verticesNumber, -1); _shortestPath[start] = 0; // For each vertex, apply relaxation for all the edges V - 1 times. for (int k = 0; k < verticesNumber - 1; k++) { updated = false; for (int from = 0; from < verticesNumber; from++) { for (int to = 0; to < verticesNumber; to++) { if (_shortestPath[to] > _shortestPath[from] + graph.Matrix[from][to]) { _shortestPath[to] = _shortestPath[from] + graph.Matrix[from][to]; _previousVertex[to] = from; updated = true; } } } if (!updated) // No changes in paths, means we can finish earlier. break; } // Run one more relaxation step to detect which nodes are part of a negative cycle. if (updated) for (int from = 0; from < verticesNumber; from++) for (int to = 0; to < verticesNumber; to++) if (_shortestPath[to] > _shortestPath[from] + graph.Matrix[from][to]) // A negative cycle has occurred if we can find a better path beyond the optimal solution. return true; return false; }


এবং এখন আমরা একটি আরও জটিল গ্রাফ নিয়ে খেলি যা নেতিবাচক চক্র অন্তর্ভুক্ত করে:

 graph.Nodes.push_back({ "USD" }); // 1 (Index = 0) graph.Nodes.push_back({ "CHF" }); graph.Nodes.push_back({ "YEN" }); graph.Nodes.push_back({ "GBP" }); graph.Nodes.push_back({ "CNY" }); graph.Nodes.push_back({ "EUR" }); graph.Nodes.push_back({ "XXX" }); graph.Nodes.push_back({ "YYY" }); // 8 (Index = 7) // USD CHF YEN GBP CNY EUR XXX YYY graph.Matrix = { { 0.0, 1.0, INF, INF, INF, INF, INF, INF }, // USD { INF, 0.0, 1.0, INF, INF, 4.0, 4.0, INF }, // CHF { INF, INF, 0.0, INF, 1.0, INF, INF, INF }, // YEN { INF, INF, 1.0, 0.0, INF, INF, INF, INF }, // GBP { INF, INF, INF, -3.0, 0.0, INF, INF, INF }, // CNY { INF, INF, INF, INF, INF, 0.0, 5.0, 3.0 }, // EUR { INF, INF, INF, INF, INF, INF, 0.0, 4.0 }, // XXX { INF, INF, INF, INF, INF, INF, INF, 0.0 } }; // YYY


আমাদের প্রোগ্রামটি কেবল থামায় এবং একটি বার্তা প্রদর্শন করে:

 Graph contains negative cycle.


আমরা সমস্যাটি নির্দেশ করতে সক্ষম হয়েছি, তবে, আমাদের গ্রাফের সমস্যাযুক্ত অংশগুলির চারপাশে নেভিগেট করতে হবে।

নেতিবাচক চক্র এড়ানো

এটি সম্পন্ন করার জন্য, আমরা একটি ধ্রুবক মান, NEG_INF সহ নেতিবাচক চক্রের অংশগুলিকে চিহ্নিত করব:

 bool FindPathsAndNegativeCycles(Graph& graph, int start) { int verticesNumber = graph.Nodes.size(); _shortestPath.resize(verticesNumber, INF); _previousVertex.resize(verticesNumber, -1); _shortestPath[start] = 0; for (int k = 0; k < verticesNumber - 1; k++) for (int from = 0; from < verticesNumber; from++) for (int to = 0; to < verticesNumber; to++) { if (graph.Matrix[from][to] == INF) // Edge not exists { continue; } if (_shortestPath[to] > _shortestPath[from] + graph.Matrix[from][to]) { _shortestPath[to] = _shortestPath[from] + graph.Matrix[from][to]; _previousVertex[to] = from; } } bool negativeCycles = false; for (int k = 0; k < verticesNumber - 1; k++) for (int from = 0; from < verticesNumber; from++) for (int to = 0; to < verticesNumber; to++) { if (graph.Matrix[from][to] == INF) // Edge not exists { continue; } if (_shortestPath[to] > _shortestPath[from] + graph.Matrix[from][to]) { _shortestPath[to] = NEG_INF; _previousVertex[to] = -2; negativeCycles = true; } } return negativeCycles; }


এখন, যদি আমরা _shortestPath অ্যারেতে NEG_INF এর সম্মুখীন হই, তাহলে আমরা একটি বার্তা প্রদর্শন করতে পারি এবং অন্যান্য মুদ্রার জন্য সর্বোত্তম সমাধান সনাক্ত করার সময় সেই অংশটিকে এড়িয়ে যেতে পারি। উদাহরণস্বরূপ, নোড 0 (USD প্রতিনিধিত্ব করে):

 Graph contains negative cycle. Path from 0 to 0 is : 0(USD) Path from 0 to 1 is : 0(USD) 1(CHF) Path from 0 to 2 is : Infinite number of shortest paths (negative cycle). Path from 0 to 3 is : Infinite number of shortest paths (negative cycle). Path from 0 to 4 is : Infinite number of shortest paths (negative cycle). Path from 0 to 5 is : 0(USD) 1(CHF) 5(EUR) Path from 0 to 6 is : 0(USD) 1(CHF) 6(XXX) Path from 0 to 7 is : 0(USD) 1(CHF) 5(EUR) 7(YYY)


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

এমনকি সামান্য ওঠানামা ব্যাপার

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

 graph.Nodes.push_back({ "USD" }); // 1 (Index = 0) graph.Nodes.push_back({ "CHF" }); graph.Nodes.push_back({ "YEN" }); // 3 (Index = 2) // LogE(x) table: USD CHF YEN graph.Matrix = { { 0.0, 0.489, -0.402 }, // USD { -0.489, 0.0, -0.891 }, // CHF { 0.402, 0.89, 0.0 } }; // YEN from = 0; FindPathsAndNegativeCycles(graph, from);


ফলাফল:

 Graph contains negative cycle. Path from 0 to 0 is: Infinite number of shortest paths (negative cycle). Path from 0 to 1 is: Infinite number of shortest paths (negative cycle). Path from 0 to 2 is: Infinite number of shortest paths (negative cycle).


যাইহোক, এমনকি বিনিময় হারের সামান্য পরিবর্তন (অর্থাৎ, ম্যাট্রিক্সের সাথে সামঞ্জস্য) উল্লেখযোগ্য পার্থক্য সৃষ্টি করতে পারে:

 // LogE(x) table: USD CHF YEN graph.Matrix = { { 0.0, 0.490, -0.402 }, // USD { -0.489, 0.0, -0.891 }, // CHF { 0.403, 0.891, 0.0 } }; // YEN from = 0; FindPathsAndNegativeCycles(graph, from);


দেখুন, আমরা একটি লাভজনক চেইন খুঁজে পেয়েছি:

 Path from 0 to 0 is : 0(USD) Path from 0 to 1 is : 0(USD) 2(YEN) 1(CHF) Path from 0 to 2 is : 0(USD) 2(YEN)


আমরা এই ধারণাগুলিকে অনেক বড় গ্রাফে প্রয়োগ করতে পারি, একাধিক মুদ্রা জড়িত:

 graph.Nodes.push_back({ "USD" }); // 1 (Index = 0) graph.Nodes.push_back({ "CHF" }); graph.Nodes.push_back({ "YEN" }); graph.Nodes.push_back({ "GBP" }); graph.Nodes.push_back({ "CNY" }); // 5 (Index = 4) // LogE(x) table: USD CHF YEN GBP CNY graph.Matrix = { { 0.0, 0.490, -0.402, 0.7, 0.413 }, // USD { -0.489, 0.0, -0.891, 0.89, 0.360 }, // CHF { 0.403, 0.891, 0.0, 0.91, 0.581 }, // YEN { 0.340, 0.405, 0.607, 0.0, 0.72 }, // GBP { 0.403, 0.350, 0.571, 0.71, 0.0 } }; // CNY from = 0; runDetectNegativeCycles(graph, from);


ফলস্বরূপ, আমরা লাভ পেতে একাধিক প্রার্থী খুঁজে পেতে পারি:

 Path from 0 to 0 is : 0(USD) Path from 0 to 1 is : 0(USD) 2(YEN) 1(CHF) Path from 0 to 2 is : 0(USD) 2(YEN) Path from 0 to 3 is : 0(USD) 2(YEN) 3(GBP) Path from 0 to 4 is : 0(USD) 2(YEN) 4(CNY) 


স্ক্রুজ ম্যাকডাক


দুটি গুরুত্বপূর্ণ কারণ আছে, যদিও:

  1. সালিসি প্রক্রিয়া বাস্তবায়নে সময় একটি গুরুত্বপূর্ণ ফ্যাক্টর, প্রাথমিকভাবে মুদ্রার দামের দ্রুত ওঠানামার কারণে। ফলস্বরূপ, একটি নিশ্চিত বাজির জীবনকাল অত্যন্ত সংক্ষিপ্ত।

  2. প্ল্যাটফর্ম প্রতিটি লেনদেনের জন্য কমিশন ধার্য করে।


অতএব, নিশ্চিত বাজির দৈর্ঘ্য সীমিত করে অর্জিত সময় ব্যয় কমানো এবং কমিশন কমানো সর্বাগ্রে।


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


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


স্মার্ট চুক্তি ব্যবহার করে অটোমেশন

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


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


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


যদিও নিঃসন্দেহে প্রতিভাবান ব্যক্তি এবং দলগুলি এই ক্ষেত্র থেকে লাভবান হচ্ছে, সেখানে নিয়ন্ত্রক সংস্থাগুলিও রয়েছে যাতে বাজারের নিয়মগুলি বহাল থাকে তা নিশ্চিত করার চেষ্টা করা হয়।

কেন আমরা এই অনুসন্ধান করছি?

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


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


অসংখ্য বৈজ্ঞানিক কাগজপত্র বিশ্ব অর্থনীতিতে বিনিময় হারের অস্তিত্ব এবং নির্ণয় নিয়ে আলোচনা করে, কয়েকটি উল্লেখ করার জন্য:

এই কাগজপত্রগুলি বৈদেশিক এক্সচেঞ্জের কিছু মৌলিক প্রক্রিয়ার উপর আলোকপাত করে, যা এখনও বোঝা এবং একটি মডেলের মধ্যে মাপসই করা কঠিন।


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

সাথে থাকুন!

লিঙ্ক


এছাড়াও এখানে প্রকাশিত.