একটি ট্রেডের মাঝপথে আমরা পেপার কৌশলটি রিস্টার্ট করেছিলাম, আর রিস্টার্টের আগে এটি যে অর্ডারের ক্রম তৈরি করেছিল, তার চেয়ে ভিন্ন ক্রম পেলাম। একই মার্কেট ডেটা, একই কৌশল সংস্করণ, একই অ্যাকাউন্ট ব্যালেন্স। সিগন্যালের হিসাব মিলে গিয়েছিল। কিন্তু পজিশন ও অপেক্ষমাণ অর্ডার সম্পর্কে কৌশলটির স্মৃতি মিলল না।
এক দিনের রিপ্লে কাজের মধ্যে আমরা এই অমিলের সূত্র খুঁজেছি। শিক্ষাটা সহজ: আপনার সফটওয়্যারের জন্য রিস্টার্টও একটি মার্কেট ইভেন্ট। কৌশলটি কীভাবে তার অবস্থা আবার গড়ে তোলে, তা পরীক্ষা না করলে পরিচ্ছন্ন ব্যাকটেস্ট এমন একটি পেপার সিস্টেমের ত্রুটি আড়াল করতে পারে, যা নিজের হাতে কী আছে তা ভুলে যায়।
09:10 — আমরা একটি সাদামাটা পজিশন বেছে নিলাম
পরীক্ষার কৌশলটি একটি লিকুইড পারপেচুয়াল কন্ট্রাক্টে ট্রেড করত: একটি ছোট মুভিং অ্যাভারেজ বড়টির ওপরে উঠলে লং এন্ট্রি, আর বিপরীত ক্রস হলে এক্সিট। আগে থেকেই একটি ছোট পজিশন খোলা এবং সেটি কমানোর জন্য একটি reduce-only লিমিট অর্ডার অপেক্ষমাণ রেখে আমরা রিপ্লে শুরু করেছিলাম। এতে পুনরুদ্ধারের সময় 2টি বিষয় আবার তৈরি করতে হয়েছিল: আমাদের কী ছিল এবং ভেন্যুকে আমরা ইতিমধ্যে কী করতে বলেছিলাম।
চেকপয়েন্টে অ্যাকাউন্টে 0.04 কন্ট্র্যাক্ট ছিল। অর্ডারটি 0.01-এর জন্য খোলা ছিল। কৌশলের প্রসেসটি মেমরিতে এই 2টি মান ক্যাশ করেছিল, কিন্তু স্টার্টআপের পথে শুধু পজিশনই আনা হয়েছিল। ক্যাশ করা অর্ডারটিকে সে বাতিল ধরে নিয়েছিল।
09:25 — প্রথম ডুপ্লিকেট অর্ডারটি দেখা দিল
রিস্টার্টের পর কৌশলটি বিদ্যমান লং পজিশনটি দেখল, সিগন্যালের লজিক চালাল এবং সেটি কমাতে আরও 0.01-এর একটি অর্ডার দিল। এখন পেপার ভেন্যুতে 2টি সক্রিয় অর্ডার ছিল। আলাদা করে দেখলে কোনোটিই খারাপ অর্ডার ছিল না। কিন্তু দুটিই পূরণ হলে একসঙ্গে নির্ধারিত পরিমাণের দ্বিগুণ বিক্রি হয়ে যেতে পারত।
শুরুতে আমরা সিগন্যাল লুপকে দোষ দিয়েছিলাম। লুপের দোষ ছিল না; স্ন্যাপশটটি অসম্পূর্ণ ছিল। কৌশলটি জিজ্ঞেস করেছিল, “আমার কী পজিশন আছে?” কিন্তু কখনো জিজ্ঞেস করেনি, “কোন অর্ডারগুলো এখনো কার্যকর আছে?”
| রিস্টার্টের পর অবস্থা | প্রসেসের ধারণা | অ্যাকাউন্টে যা ছিল |
|---|---|---|
| পজিশন | লং 0.04 | লং 0.04 |
| খোলা ট্রিম অর্ডার | কোনোটিই নেই | প্রতিটি 0.01-এর 2টি |
| একটি অর্ডার পূরণ হলে নির্ধারিত এক্সপোজার | লং 0.03 | লং 0.02 হতে পারে |
10:00 — পুনরুদ্ধার ঠিক করলাম, তারপর সময়ের একটি সূক্ষ্ম সমস্যা পেলাম
নতুন সিদ্ধান্ত নেওয়ার অনুমতি দেওয়ার আগে অ্যাকাউন্টের পজিশন ও খোলা অর্ডার থেকে অবস্থা পুনর্গঠনের জন্য আমরা স্টার্টআপ প্রক্রিয়াটি বদলালাম। এতে ডুপ্লিকেট অর্ডারটি আর হলো না। এরপর বিচ্ছিন্নতার পরিস্থিতিটিকে আরও জটিল করলাম: কৌশলটি অফলাইনে থাকা অবস্থায় একটি অর্ডার পূরণ হলো, আর পূরণের নোটিফিকেশনটি পুনঃসংযোগের পরে এল।
অ্যাকাউন্টের স্ন্যাপশটে পূরণটি ইতিমধ্যেই দেখা যাচ্ছিল। পরে আসা নোটিফিকেশনটি স্থানীয় পজিশন আবার কমিয়ে দিল। কয়েক সেকেন্ডের জন্য কৌশলটি ভাবল তার কাছে 0.02 কন্ট্র্যাক্ট আছে, অথচ অ্যাকাউন্টে ছিল 0.03। পরের রিব্যালান্সটি কাল্পনিক ঘাটতির ভিত্তিতে হওয়ার কথা ছিল।
আমরা পুনর্মিলনের নিয়ম যোগ করলাম: অ্যাকাউন্টের স্ন্যাপশটকে শুরুর অবস্থা ধরতে হবে, সেখানে প্রতিফলিত পূরণগুলো উপেক্ষা করতে ইভেন্ট আইডি ব্যবহার করতে হবে, আর প্রাথমিক সিঙ্ক শেষ না হওয়া পর্যন্ত অর্ডার পাঠানো যাবে না। নোটিফিকেশন দেরিতে আসতে পারে, কিংবা দুবারও আসতে পারে। পুনরুদ্ধার প্রক্রিয়াকে দুটো পরিস্থিতিই সামলাতে হবে।
13:40 — রিপ্লেতে একটি সূক্ষ্ম অমিল ধরা পড়ল
মূল রান এবং রিস্টার্ট করা রানে আমরা একই দামের গতিপথ রিপ্লে করলাম। চূড়ান্ত P&L তুলনা করলে সমস্যাটি চোখ এড়িয়ে যেত: বাজার ঘুরে যাওয়ার পর 2টি সংস্করণই একই পজিশনে শেষ হয়েছিল। অর্ডার ইভেন্ট তুলনা করতেই অমিলটি ধরা পড়ল।
প্রতিটি সিদ্ধান্তের সঙ্গে সেটি যে অবস্থা পড়েছিল, তা আমরা লগ করেছিলাম: পজিশন, খোলা অর্ডার, সর্বশেষ প্রক্রিয়াকৃত পূরণ আইডি, সিগন্যালের মান এবং কৌশলের সংস্করণ। ফলে প্রথম যে ইভেন্টে অমিল দেখা দিয়েছিল, তার কারণ জানা গেল। একটি রানে একটি কার্যকর অর্ডার দেখা গিয়েছিল; অন্যটিতে তালিকাটি ফাঁকা ছিল। পরে, এক রানে একটি পূরণ দুবার প্রয়োগ হয়েছিল।
শেষের ব্যালেন্স মিলে গেলেই যে আচরণও মিলেছে, তা প্রমাণ হয় না। সিদ্ধান্ত ও অর্ডারের ক্রম তুলনা করুন, বিশেষ করে পুনরুদ্ধারের সময়সীমার কাছাকাছি।
16:20 — পরের বার আমরা যা অন্যভাবে করব
অ্যাকাউন্টের অবস্থা কীভাবে বদলায়, তা যাচাই করার আগে আমরা দামের ডেটা রিপ্লে করতে অনেক বেশি সময় দিয়েছিলাম। পরের বার আগে ব্যর্থতার পরিস্থিতিগুলো তৈরি করব এবং মার্কেটের গতিপথ প্রায় সমতল রাখব। এতে সফটওয়্যারের ত্রুটিটি সহজে দেখা যাবে, আর অস্থির বাজারের ওঠানামায় কারণ নির্ণয় জটিল হবে না।
- পজিশন ও আংশিকভাবে পূরণ হওয়া অর্ডার থাকা অবস্থায় রিস্টার্ট করুন।
- অর্ডার পাঠানোর পর সংযোগ বিচ্ছিন্ন করুন, তারপর পূরণের নোটিফিকেশন আসার আগে আবার সংযোগ করুন।
- একই পূরণ ইভেন্ট দুবার পাঠিয়ে যাচাই করুন, অবস্থা যেন কেবল একবারই বদলায়।
- পজিশন ও খোলা অর্ডার—দুটিরই পুনর্মিলন না হওয়া পর্যন্ত নতুন অর্ডার আটকে রাখুন।
- বিরতিহীন এবং রিস্টার্ট করা রান জুড়ে সিদ্ধান্ত ও অর্ডারের লগ তুলনা করুন।
আমরা আরও শিখেছি, কৌশলের সংস্করণ ও ইভেন্ট লগের সঙ্গে পুনরুদ্ধারের একটি স্ন্যাপশটও সংরক্ষণ করতে হয়। এতে নির্দিষ্ট পুনঃসংযোগের ক্রম কারও মনে রাখার ওপর নির্ভর না করে কয়েক মিনিটেই ত্রুটিটি আবার ঘটানো সম্ভব হয়েছিল।
যে পেপার কৌশলটি কেবল তার প্রসেস চালু থাকলেই ঠিকমতো চলে, তার পূর্ণ মহড়া এখনো হয়নি। পজিশনের মাঝখানে সেটি রিস্টার্ট করুন, পূরণের নোটিফিকেশন দেরিতে আসতে দিন, তারপর এটি যে প্রতিটি অর্ডার পাঠায় তা খুঁটিয়ে দেখুন। উদ্দেশ্য হলো এটি কখনোই ব্যর্থ হয় না, তা প্রমাণ করা নয়। পেপার অ্যাকাউন্ট আপনাকে একই শিক্ষা আচমকা দেওয়ার আগেই এর পুনরুদ্ধার প্রক্রিয়াকে দৃশ্যমান করা।
← সব পোস্ট


