সংখ্যা দিয়েই শুরু করি, কারণ যুক্তিটা পুরোপুরি সেখানেই। বড় কোনো perp ভেন্যুতে taker হিসেবে একটি রাউন্ড-ট্রিপ ট্রেডে কমিশন লাগে নোশনালের প্রায় 0.10%। ভিড় জমা long অবস্থানে ফান্ডিং আপনার বিপক্ষে বছরে 10-30% পর্যন্ত যেতে পারে। অর্ডার বুকের সেরা দরের গভীরতার তুলনায় বড় কোনো মার্কেট অর্ডারে স্প্রেডের পাশাপাশি square-root-law অনুযায়ী প্রাইস ইমপ্যাক্টও লাগে। আর ব্যাকটেস্টে যদি গতকালের ডেটার আজকের সংশোধিত সংস্করণ পড়া হয়, তাহলে বছরে কয়েক শতাংশের এমন এক এজ পাওয়া যায়, যার অস্তিত্ব কখনোই ছিল না।
সবচেয়ে চমকে দেওয়া সংখ্যাটি প্রথমটি। পরিমাণটা বড় বলে নয়—ট্রেডের সংখ্যা বাড়লে এর প্রভাব কী হয়, সেটাই আসল। সবাই বলে, “ফি ধরতে হবে,” তারপর এমন কৌশল পরীক্ষা করে যা দিনে 40টি ট্রেড করে। প্রতি রাউন্ড ট্রিপে 0.10% খরচ হলে, 40টি ট্রেডে খরচ দাঁড়ায় দিনে নোশনালের 4%। কোনো mid-cap perp-এর সিগন্যালই সেই খরচ পেরোতে পারে না। কৌশলটি লাভজনক হওয়ার ধারেকাছেও ছিল না, অথচ ফি বাদ দেওয়া ব্যাকটেস্ট একে দারুণ বলে দেখিয়েছিল।
ফি হলো বাছাইয়ের মানদণ্ড, মুনাফা কমানোর খাঁড়া নয়
বেশিরভাগের ধারণা, ফি মুনাফার রেখাটাকে একটু নিচে নামায়: রেখার আকৃতি একই থাকে, শুধু লাভ কমে। ধারণাটা ভুল। ফি হলো ট্রেডের ঘনত্ব বাছাইয়ের মানদণ্ড। এগুলো কোনো এজের উচ্চ-ফ্রিকোয়েন্সির রূপকে পুরোপুরি মুছে দেয়, অথচ ধীরগতির রূপে প্রায় কোনো প্রভাবই ফেলে না। আমাদের পাইপলাইনে প্রতিটি ভেন্যুর প্রকৃত maker/taker ফি-তালিকা প্রয়োগ শুরু করার পর যেসব কৌশল বাদ পড়েছিল, সেগুলো খারাপ ধারণা ছিল না—ভালো ধারণাগুলোই অতিরিক্ত ঘন ঘন ট্রেড করছিল। সমাধান সাধারণত আরও ভালো সিগন্যাল নয়, বরং দীর্ঘতর টাইমফ্রেম। এখন নোশনালের 0.15%-এর কম গড় ট্রেড-রিটার্ন আছে, এমন যেকোনো কৌশল আমরা বাদ দিই; কারণ দুই দিকের খরচ কাটার পর চক্রবৃদ্ধি করার মতো আর কিছু থাকে না।
ফান্ডিং হলো অবস্থানের ওপর ধারাবাহিক কর
Perpetual futures-এ প্রতি ঘণ্টায় বা প্রতি 8 ঘণ্টায় ফান্ডিং পরিশোধ হয়; এটা এলোমেলো নয়—মোমেন্টাম সিস্টেম যে ট্রেডগুলো করতে চায়, তার সঙ্গেই কাঠামোগতভাবে সম্পর্কিত। সবাই long হলে ফান্ডিং পজিটিভ থাকে, আর আপনার long মোমেন্টাম অবস্থানের জন্য তা দিতে হয়। ফান্ডিং জমার হিসাব ছাড়া ব্যাকটেস্টে perp-এ ট্রেন্ড-ফলোয়িং কৌশল নিয়মিতই বাস্তবের চেয়ে ভালো দেখায়। বিব্রতকরভাবে বিষয়টা আমরা নিজেরাই শিখেছি—ফান্ডিং থেকে মুনাফা তোলার জন্য তৈরি পুরো একগুচ্ছ কৌশল ইঞ্জিন থেকে ফান্ডিংয়ের আয় হিসাব না করায় স্বয়ংক্রিয়ভাবে বাদ পড়েছিল। সিগন্যাল ঠিক ছিল। হিসাবটাই অসম্পূর্ণ ছিল।
অর্ডারের আকারের বর্গমূল অনুপাতে ইমপ্যাক্ট বাড়ে
বার-ভিত্তিক ব্যাকটেস্টের ভদ্রস্থ কল্পনাটি হলো, অর্ডার ক্লোজিং প্রাইসে পূরণ হয়। ছোট অর্ডারের ক্ষেত্রে এটা মোটামুটি সত্যি। কিন্তু বড় অর্ডারে স্বীকৃত মডেল অনুযায়ী, ভলিউমের তুলনায় অর্ডারের আকারের বর্গমূল অনুপাতে ইমপ্যাক্ট বাড়ে, আর তা আর ফিরে আসে না। প্রতিটি fill এবং ইকুইটি কার্ভেই আমরা sqrt-law অনুযায়ী ইমপ্যাক্টের হিসাব রাখি। এর প্রভাব সবচেয়ে বেশি ঠিক সেই জায়গাতেই, যেখানে তা মানতে সবচেয়ে অসুবিধা: ধারণক্ষমতা। কোনো কৌশল $50k-এ সত্যিই লাভজনক, কিন্তু $5M-এ কাঠামোগতভাবে অলাভজনক হতে পারে; সীমাটা কোথায়, তা শুধু ইমপ্যাক্টের হিসাব রাখা কার্ভেই দেখা যায়।
ডেটার ভেতরেই ভবিষ্যৎ-তথ্য লুকিয়ে থাকে, কোডে নয়
কেউ if tomorrow_close > today_close: buy() লেখে না। ডেটা জোড়ার প্রক্রিয়াতেই ভবিষ্যৎ-তথ্য চুপিসারে ঢুকে পড়ে: খবরের sentiment-এর টাইমস্ট্যাম্প প্রকাশের সময় অনুযায়ী দেওয়া হয়, ডেটা গ্রহণের সময় অনুযায়ী নয়; ফান্ডিং রেট যুক্ত হয় যে সময়কালকে তা প্রযোজ্য সেই সময়ের সঙ্গে, কখন জানা গিয়েছিল তার সঙ্গে নয়; ইতিহাসে “বর্তমান” প্রতীকের তালিকা প্রয়োগ করা হয় (survivorship bias); সংশোধিত অর্থনৈতিক পরিসংখ্যান দিয়ে বাজারে তখন প্রকাশিত সংখ্যাটি প্রতিস্থাপন করা হয়। আমাদের নিয়ম হলো, সবকিছুতেই point-in-time ডেটা: প্রতিটি সহায়ক সিরিজের টাইমস্ট্যাম্প থাকে কখন আমরা সেটি জানতে পারতাম সেই সময় অনুযায়ী, আর ব্যাকটেস্টে পড়া যায় কেবল সেই ন্যানোসেকেন্ডে যা বিদ্যমান ছিল।
ব্যাকটেস্টের সার্থকতা কার্ভ ঊর্ধ্বমুখী কি না, তা দিয়ে বোঝা যায় না। একই কোডে একই সিগন্যাল দিয়ে লাইভে চালালে একই ট্রেড হয় কি না, সেটাই আসল—আর তা জানতে হলে প্রতিদিন, চিরকাল, যাচাই করে যেতে হয়।
শেষ বাক্যটি কোনো স্লোগান নয়, বাস্তব প্রক্রিয়া। প্রতিদিন paper-traded প্রতিটি কৌশলের সময়সীমা আমরা ব্যাকটেস্ট ইঞ্জিনে আবার চালাই, তারপর একে একে ট্রেডগুলো মিলিয়ে দেখি। paper ট্রেড আর পুনরায় চালানো ফল না মিললে, কোনো একটির হিসাব ভুল—আর সাধারণত কারণটা হয় খরচ, নয়তো টাইমস্ট্যাম্প। উপরের 4টি খরচের খাতই প্রথমে আমাদের ভুল পথে নিয়েছিল।
← সব পোস্ট


