Type/to search
2
Follow
484
Followers
মাল্টি-ফ্যাক্টর স্ট্র্যাটেজি শুধু বড় কোম্পানির একচেটিয়া নয়: স্বাধীন কোয়ান্টের গবেষণা কাঠামো
Discussions
Created 2026-03-27 15:05:12  Updated 2026-03-31 18:40:35
 0
 397

[টোক]

img

এক: কেন স্বয়ংক্রিয় ফ্যাক্টর মাইনিং প্রয়োজন

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

শুনতে সহজ মনে হলেও, যারা সত্যিই ফ্যাক্টর গবেষণা করেন, তারা জানেন এই কাজ কতটা কঠিন:

গভীর আর্থিক জ্ঞান এবং গাণিতিক পরিসংখ্যানের শক্তিশালী পটভূমি
প্রচুর পরিমাণ পরিষ্কার ঐতিহাসিক ডেটা
কঠোর ব্যাকটেস্টিং ফ্রেমওয়ার্ক

এছাড়াও একটি সমস্যার সম্মুখীন হতে হয় যা কখনও এড়ানো যায় না: ফ্যাক্টর ক্ষয়প্রাপ্ত হয়

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

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

img


দুই: সিস্টেমের সামগ্রিক আর্কিটেকচার

প্রথাগত ফ্যাক্টর মাইনিং প্রক্রিয়া হলো: গবেষক হাইপোথিসিস প্রস্তাব → কোড লেখা → ব্যাকটেস্ট চালানো → ফিল্টার করা → লাইভে যাওয়া → কয়েক মাস পর অকার্যকর দেখা → আবার শুরু। পুরো চক্রটি কয়েক সপ্তাহ বা কয়েক মাস সময় নিতে পারে।

এই সিস্টেম পুরো চক্রটিকে নির্দিষ্ট ব্যবধানে স্বয়ংক্রিয়ভাবে একবার সম্পাদনের জন্য সংকুচিত করে:

ধাপমডিউলব্যাখ্যা
Step 1লক্ষ্যবস্তু পুল সংগ্রহলেনদেনের পরিমাণ অনুযায়ী উচ্চ লিকুইডিটি সম্পন্ন পারপেচুয়াল কন্ট্রাক্ট নির্বাচন, বাজারের অবস্থা শনাক্তকরণ
Step 2ফ্যাক্টর পুল পরীক্ষাবর্তমান ফ্যাক্টরগুলোর স্বাস্থ্য বিশ্লেষণ, এই রাউন্ডের অনুসন্ধানের দিকনির্দেশ নির্ধারণ
Step 3AI দ্বারা ফ্যাক্টর জেনারেটসীমাবদ্ধতার কাঠামোর মধ্যে, AI কে নতুন মাত্রার প্রার্থী ফ্যাক্টর তৈরি করতে দেওয়া
Step 4IC যাচাইকরণঐতিহাসিক ডেটা প্লেব্যাকের মাধ্যমে তথ্য সহগ (IC) গণনা, অকার্যকর ফ্যাক্টর বাতিল করা
Step 5সম্পর্ক ফিল্টারিং ও শেষ স্থান বাদতথ্যগত ওভারল্যাপিং ফ্যাক্টর অপসারণ, ফ্যাক্টর পুলকে স্বল্প কিন্তু কার্যকর রাখা
Step 6সিগন্যাল সংশ্লেষণ ও অর্ডারওয়েটেড সংশ্লেষণ স্কোরিং, থ্রেশহোল্ড অতিক্রমকারী সিগন্যাল পজিশন অ্যাডজাস্টমেন্ট ট্রিগার করে

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


তিন: প্রতিটি মডিউলের বিস্তারিত ও মূল কোড

৩.১ লক্ষ্যবস্তু পুল সংগ্রহ

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

একই সময়ে BTC-র চার ঘণ্টার ক্যান্ডেলের অস্থিরতার ঐতিহাসিক পার্সেন্টাইল শনাক্ত করে, বাজারের সামগ্রিক অবস্থা নির্ধারণ করে (normal / high_vol / low_vol / volatile)। এই নির্ধারণ সরাসরি AI-র ফ্যাক্টর জেনারেশনের দিকনির্দেশনাকে প্রভাবিত করে।

javascript
// লেনদেনের পরিমাণ অনুযায়ী উচ্চ লিকুইডিটি সম্পন্ন লক্ষ্যবস্তু ফিল্টার করা const topN = $vars.topN || 150; const tickers = exchange.GetTickers(); const filtered = tickers .filter(t => t.Symbol.endsWith('USDT.swap')) .map(t => ({ symbol: t.Symbol, quoteVolume: t.Last * t.Volume })) .sort((a, b) => b.quoteVolume - a.quoteVolume) .slice(0, topN) .map(t => t.symbol); _G('afi_symbolPool', JSON.stringify(filtered)); // BTC-র অস্থিরতা পার্সেন্টাইল শনাক্ত করে বাজারের অবস্থা নির্ধারণ const btcR = exchange.GetRecords('BTC_USDT.swap', PERIOD_H4); const n = btcR.length; const returns20 = []; for (let i = n - 20; i < n; i++) returns20.push(Math.abs((btcR[i].Close - btcR[i-1].Close) / btcR[i-1].Close)); const avgVol = returns20.reduce((a, b) => a + b, 0) / returns20.length; // সম্পূর্ণ ঐতিহাসিক অস্থিরতার সাথে তুলনা করে পার্সেন্টাইল নির্ধারণ const allVols = []; for (let i = 1; i < n; i++) allVols.push(Math.abs((btcR[i].Close - btcR[i-1].Close) / btcR[i-1].Close)); allVols.sort((a, b) => a - b); let btcVolPercentile = allVols.findIndex(v => v >= avgVol) / allVols.length; let marketState = 'normal'; if (btcVolPercentile > 0.8) marketState = 'high_vol'; else if (btcVolPercentile < 0.3) marketState = 'low_vol'; _G('afi_marketState', marketState); _G('afi_btcVolPct', btcVolPercentile.toFixed(2));

৩.২ ফ্যাক্টর পুলের অবস্থা পরীক্ষা

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

javascript
const factorPool = JSON.parse(_G('afi_factorPool') || '[]'); const icHistory = JSON.parse(_G('afi_icHistory') || '{}'); const icDecayWindow = $vars.icDecayWindow || 48; // সাম্প্রতিক উইন্ডোর দৈর্ঘ্য const icDecayThreshold = $vars.icDecayThreshold || -0.01; // ক্ষয় সনাক্তকরণ থ্রেশহোল্ড const targetFactorCount = $vars.targetFactorCount || 10; const degradedFactors = []; for (const factor of factorPool) { const icArr = icHistory[factor.name] || []; if (icArr.length >= 20) { const window = Math.min(icArr.length, icDecayWindow); const recentAvg = icArr.slice(-window).reduce((a, b) => a + b, 0) / window; if (recentAvg < icDecayThreshold) degradedFactors.push({ name: factor.name, recentIC: recentAvg.toFixed(4), rationale: factor.rationale }); } } // গতিময়ভাবে এই রাউন্ডে কতটি নতুন ফ্যাক্টর অনুসন্ধান করতে হবে তা নির্ধারণ const explorationBuffer = $vars.explorationBuffer || 3; const explorationCount = Math.max( explorationBuffer, targetFactorCount - validCount + explorationBuffer ); const action = factorPool.length === 0 ? 'generate_initial' : 'iterate_factors';

৩.৩ প্রম্পট তৈরি করা, AI-কে ফ্যাক্টর আবিষ্কার করতে দেওয়া

AI একটি খোলামেলা কাজ পায় না, বরং একটি সীমাবদ্ধ কাঠামো পায়। প্রম্পটে অন্তর্ভুক্ত থাকে: বর্তমান বাজারের অবস্থা, ইতিমধ্যে বিদ্যমান ফ্যাক্টরের তালিকা (পুনরাবৃত্তি নিষিদ্ধ), সাম্প্রতিক ক্ষয়প্রাপ্ত ফ্যাক্টর (ক্ষুদ্র সমন্বয় নিষিদ্ধ), ইতিমধ্যে কভার করা মাত্রা, এখনও অনুসন্ধান না করা মাত্রা।

এইভাবে জেনারেট করা প্রার্থী ফ্যাক্টরগুলো সত্যিই নতুন দিকের দিকে প্রচেষ্টা, কোনো বিদ্যমান ফ্যাক্টরের প্যারামিটার পরিবর্তন করে পুনরায় চালানো নয়।

javascript
// পুনরাবৃত্তিমূলক প্যাটার্নের জন্য প্রম্পটের মূল অংশ const usedDimensions = factorPool .map(f => f.name + '(' + (f.rationale || '') + ')') .join(', ') || 'কোনো তথ্য নেই'; const validSummary = validFactors.map(f => { const arr = icHistory[f.name] || []; const avg = arr.length > 0 ? (arr.reduce((a,b) => a+b, 0) / arr.length).toFixed(4) : 'N/A'; const recent = arr.length >= 20 ? (arr.slice(-20).reduce((a,b) => a+b, 0) / 20).toFixed(4) : 'N/A'; return f.name + ': ঐতিহাসিক IC=' + avg + ' সাম্প্রতিক IC=' + recent + ' | যুক্তি: ' + f.rationale; }).join('\n') || 'কোনো তথ্য নেই'; const degradedSummary = degradedFactors.length > 0 ? degradedFactors.map(f => f.name + ': সাম্প্রতিক IC=' + f.recentIC + ' | মূল যুক্তি: ' + f.rationale ).join('\n') : 'এই রাউন্ডে কোনো ক্ষয়প্রাপ্ত ফ্যাক্টর নেই'; prompt += '【বর্তমান কার্যকর ফ্যাক্টর (ভেরিয়েন্ট তৈরি করার প্রয়োজন নেই)】\n' + validSummary + '\n\n'; prompt += '【সাম্প্রতিক ক্ষয়প্রাপ্ত ফ্যাক্টর (এই মাত্রাগুলোতে সূক্ষ্ম-টিউনিং নিষিদ্ধ)】\n' + degradedSummary + '\n\n'; prompt += '【কভার করা মাত্রা (পুনরাবৃত্তি নিষিদ্ধ)】\n' + usedDimensions + '\n\n'; prompt += '【এখনো অন্বেষণ করা হয়নি এমন মাত্রা (এখান থেকে অগ্রাধিকার নিন)】\n' + unusedSample + '\n\n'; prompt += explorationCount + ' টি সম্পূর্ণ নতুন দিকনির্দেশক ফ্যাক্টর তৈরি করুন:\n'; prompt += '1. অবশ্যই কভার করা মাত্রা থেকে সম্পূর্ণ ভিন্ন হতে হবে, ক্ষয়প্রাপ্ত ফ্যাক্টরগুলোর সূক্ষ্ম-টিউনিং নিষিদ্ধ\n'; prompt += '2. এখনো অন্বেষণ করা হয়নি এমন মাত্রা থেকে অগ্রাধিকার নিন\n'; prompt += '3. অ-রৈখিক কম্বিনেশন ফ্যাক্টর ডিজাইন করতে অগ্রাধিকার দিন\n'; prompt += '4. বর্তমান ' + marketState + ' মার্কেট অবস্থার জন্য ডিজাইন করুন\n';

AI-এর সিস্টেম প্রম্পটে ইনভেন্টর প্ল্যাটফর্মের সম্পূর্ণ TA ফাংশন স্পেসিফিকেশন, কোড ফরম্যাটের সীমাবদ্ধতা, ক্রিপ্টো মার্কেটের পূর্ব জ্ঞান এবং অন্বেষণযোগ্য সমস্ত ফ্যাক্টর মাত্রার তালিকা (সম্পূর্ণ বিষয়বস্তু কৌশল সোর্স কোডে রয়েছে) অন্তর্ভুক্ত রয়েছে। আউটপুট ফরম্যাট কঠোরভাবে খাঁটি JSON (মার্কডাউন র্যাপার ছাড়া):

json
{ "factors": [ { "name": "MomentumAcceleration", "rationale": "স্বল্পমেয়াদী মুভমেন্টাম অ্যাক্সিলারেশন, খুচরা বিনিয়োগকারীদের ট্রেন্ড অনুসরণের জড়তার ব্রেকিং পয়েন্ট ক্যাপচার", "code": "(records[n-1].Close - records[n-6].Close)/records[n-6].Close - (records[n-2].Close - records[n-7].Close)/(records[n-7].Close + 0.0001)", "direction": 1, "type": "exploration" } ] }

3.4 IC যাচাই: তথ্য কথা বলে, অন্তর্দৃষ্টি নয়

IC (তথ্য সহগ, Information Coefficient) পরিমাপ করে: ফ্যাক্টর দ্বারা গণনা করা ক্রস-সেকশন র্যাঙ্কিং এবং পরবর্তী ক্যান্ডেলস্টিকের প্রকৃত লাভ/ক্ষতির র্যাঙ্কিংয়ের মধ্যে সম্পর্ক কতটা উচ্চ। IC যত বেশি, ফ্যাক্টরের পূর্বাভাস তত বেশি নির্ভুল।

যাচাই পদ্ধতি হল ঐতিহাসিক রিপ্লে (ওয়াক-ফরোয়ার্ড): বিগত কয়েকশ ক্যান্ডেলস্টিক ব্যবহার করে, প্রতিটি সময় বিন্দুতে t, t-1 সময়ের ডেটা ব্যবহার করে ফ্যাক্টর মান গণনা করুন এবং t-তম ক্যান্ডেলস্টিকের লাভ/ক্ষতি পূর্বাভাস করুন। সময়ের ক্রম কঠোরভাবে সারিবদ্ধ, ফিউচার ফাংশন সম্পূর্ণরূপে প্রতিরোধ করা হয়েছে।

javascript
function calcRankICFull(code, symRecords, factorName) { const syms = Object.keys(symRecords); const icList = []; const minLen = 30; const allLengths = syms.map(s => symRecords[s].length); const minSymLen = Math.min(...allLengths); const testLen = Math.min(500, minSymLen - 1); for (let t = minLen; t < testLen; t++) { const fVals = [], nRets = []; for (const sym of syms) { const fullRecords = symRecords[sym]; // t-1 পিরিয়ডের ডেটা ব্যবহার করে ফ্যাক্টর গণনা (slice(0, t) এ t-তম ক্যান্ডেলস্টিক অন্তর্ভুক্ত নয়) const records = fullRecords.slice(0, t); const n = records.length; const v = (function() { return eval(code); })(); if (isNaN(v) || !isFinite(v)) continue; fVals.push({ sym, val: v }); // t-তম ক্যান্ডেলস্টিকের প্রকৃত রিটার্ন পূর্বাভাস nRets.push({ sym, ret: (fullRecords[t].Close - fullRecords[t-1].Close) / fullRecords[t-1].Close }); } if (fVals.length < 8) continue; // Rank IC (স্পিয়ারম্যান র্যাঙ্ক পারস্পরিক সম্পর্ক সহগ) গণনা করুন const fRank = {}, rRank = {}; [...fVals].sort((a,b) => a.val - b.val).forEach((x,i) => fRank[x.sym] = i); [...nRets].sort((a,b) => a.ret - b.ret).forEach((x,i) => rRank[x.sym] = i); const ss = fVals.map(x => x.sym); const fr = ss.map(s => fRank[s]); const rr = ss.map(s => rRank[s]); const n2 = ss.length; const fm = fr.reduce((a,b) => a+b, 0) / n2; const rm = rr.reduce((a,b) => a+b, 0) / n2; const num = fr.map((f,i) => (f-fm) * (rr[i]-rm)).reduce((a,b) => a+b, 0); const den = Math.sqrt( fr.map(f => (f-fm)**2).reduce((a,b) => a+b, 0) * rr.map(r => (r-rm)**2).reduce((a,b) => a+b, 0) ); if (den > 0) icList.push(num / den); } const avgIC = icList.length > 0 ? icList.reduce((a,b) => a+b, 0) / icList.length : 0; return { avgIC, icList }; }

IC থ্রেশহোল্ড ভেরিয়েবল $vars.icThreshold দ্বারা নিয়ন্ত্রিত, ডিফল্ট 0.02। এটি একটি অপেক্ষাকৃত শিথিল প্রবেশের সীমা, যা দ্রুত স্পষ্টভাবে অকার্যকর ফ্যাক্টরগুলি বাদ দেওয়ার জন্য উপযুক্ত; আরও কঠোর পরিসংখ্যানগত গুরুত্ব নিয়ন্ত্রণের প্রয়োজন হলে, প্রকৃত পরিস্থিতি অনুযায়ী এই মান বাড়ানো যেতে পারে। থ্রেশহোল্ড অতিক্রম করতে ব্যর্থ ফ্যাক্টরগুলি, তাদের যুক্তি যতই নিখুঁত হোক না কেন, সরাসরি বাদ দেওয়া হয়।


3.5 সম্পর্ক ফিল্টারিং এবং সর্বনিম্ন বাদ দেওয়া

IC যাচাই পাস করা ফ্যাক্টরগুলিকে আরও দুটি ধাপ অতিক্রম করতে হবে:

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

দ্বিতীয় ধাপ: সর্বনিম্ন বাদ দেওয়া। ফ্যাক্টর পুলের ক্ষমতার একটি উপরের সীমা রয়েছে। সীমা অতিক্রম করলে, কর্মক্ষমতা অনুসারে সাজান, সবচেয়ে খারাপটি বাদ দিন। সাম্প্রতিক IC ক্রমাগত হ্রাস পাচ্ছে এমন ফ্যাক্টরগুলি ঐতিহাসিক গড় IC-এর পরিবর্তে সাম্প্রতিক IC-এর ভিত্তিতে র্যাঙ্কিংয়ে অংশ নেয় এবং বড় চাপের সম্মুখীন হয়।

javascript
// 相关性过滤(保留 IC 最高的,丢弃高度相关的冗余因子) const corrThreshold = $vars.corrThreshold || 0.7; survivedFactors.sort((a, b) => b.icAvg - a.icAvg); // 先按 IC 降序排列 const decorrelatedFactors = []; for (const factor of survivedFactors) { let isRedundant = false; for (const selected of decorrelatedFactors) { const corr = Math.abs(calcCorrelation( factorScoresMap[factor.name], factorScoresMap[selected.name] )); if (corr > corrThreshold) { // 记录被吸收的相关因子(仪表板展示用) selected.corrGroup = (selected.corrGroup ? selected.corrGroup + ',' : '') + factor.name; isRedundant = true; break; } } if (!isRedundant) decorrelatedFactors.push({ ...factor, corrGroup: '' }); } // 末位淘汰:衰减因子用近期 IC 而非历史均值参与排名 const targetFactorCount = $vars.targetFactorCount || 10; decorrelatedFactors.sort((a, b) => { const scoreA = a.isDecaying ? a.recentIC : a.icAvg; const scoreB = b.isDecaying ? b.recentIC : b.icAvg; return scoreB - scoreA; }); const finalPool = decorrelatedFactors.slice(0, targetFactorCount); _G('afi_factorPool', JSON.stringify(finalPool));

নোট: সম্পর্ক নির্ণয় বর্তমান ক্রস-সেকশনের ফ্যাক্টর স্কোরের উপর ভিত্তি করে, নির্দিষ্ট মুহূর্তে মাঝে মাঝে ভুল বিচার হতে পারে। আরও নির্ভরযোগ্য পদ্ধতি হলো ঐতিহাসিক একাধিক ক্রস-সেকশনের গড় সম্পর্ক ব্যবহার করা, এটি পরবর্তী উন্নতির একটি দিক।


3.6 সংকেত সংশ্লেষণ ও পুনর্বিন্যাস কার্যকর

ফ্যাক্টর পুল স্থিতিশীল হওয়ার পর, সিস্টেম প্রতিটি লক্ষ্যের জন্য একটি সমন্বিত স্কোর গণনা করে: প্রতিটি ফ্যাক্টরের ক্রস-সেকশন মানকে Z-স্কোর মানকীকরণ করা হয়, তারপর নিজ নিজ সাম্প্রতিক IC অনুযায়ী ওজনযুক্তভাবে যুক্ত করা হয়—ভালো পারফর্ম করা ফ্যাক্টরের অংশ বেশি হয়, ঋণাত্মক সাম্প্রতিক IC-যুক্ত ফ্যাক্টরগুলির ওজন শূন্য করা হয়।

javascript
// 因子权重:近期 IC 加权(负 IC 因子权重置零) const weights = {}; let totalW = 0; for (const f of factorPool) { const arr = icHistory[f.name] || []; const recentArr = arr.slice(-48); const recentIC = recentArr.length > 0 ? recentArr.reduce((a,b) => a+b, 0) / recentArr.length : 0; const w = Math.max(0, recentIC); // 负 IC → 权重为 0 weights[f.name] = w; totalW += w; } if (totalW > 0) Object.keys(weights).forEach(k => weights[k] /= totalW); else factorPool.forEach(f => weights[f.name] = 1 / factorPool.length); // Z-score 标准化 function zscore(fname) { const vals = validSyms .map(s => ({ sym: s, val: rawMatrix[s][fname] })) .filter(x => x.val !== null); if (vals.length < 5) return {}; const mean = vals.reduce((a,b) => a + b.val, 0) / vals.length; const std = Math.sqrt(vals.reduce((a,b) => a + (b.val - mean)**2, 0) / vals.length); const r = {}; vals.forEach(x => r[x.sym] = std > 0 ? (x.val - mean) / std : 0); return r; } // 合成评分 const scores = {}; for (const sym of validSyms) { let score = 0; for (const f of factorPool) { const z = zscore(f.name)[sym]; if (z !== undefined) score += weights[f.name] * f.direction * z; } scores[sym] = score; } // 阈值过滤:信号模糊的直接跳过,不入场 const longShortN = $vars.longShortN || 5; const longThreshold = $vars.longThreshold || 0.3; const shortThreshold = $vars.shortThreshold || -0.3; const sorted = Object.keys(scores).sort((a,b) => scores[b] - scores[a]); const longList = sorted.filter(s => scores[s] >= longThreshold).slice(0, longShortN); const shortList = sorted.slice().reverse() .filter(s => scores[s] <= shortThreshold).slice(0, longShortN);

পুনর্বিন্যাস কার্যকর করার সময়, প্রথমে বর্তমান তালিকায় না থাকা পুরনো পজিশন বন্ধ করা হয়, তারপর অ্যাকাউন্ট ইকুইটি অনুযায়ী সমান অনুপাতে নতুন সংকেত খোলা হয়:

javascript
const positionRatio = $vars.positionRatio || 0.8; // 总权益使用比例 const maxLeverage = $vars.maxLeverage || 3; const account = exchange.GetAccount(); const equity = account.Equity || account.Balance; const perAmt = (equity * positionRatio) / (longList.length + shortList.length); // 平掉不在目标集合里的旧仓位 const targetSet = new Set([...longList, ...shortList]); for (const sym of Object.keys(currentHoldings)) { if (!targetSet.has(sym)) { const pos = currentHoldings[sym]; const isLong = pos.Type === PD_LONG || pos.Type === 0; exchange.CreateOrder(sym, isLong ? 'closebuy' : 'closesell', -1, Math.abs(pos.Amount)); // 清除止盈追踪状态 const cm = sym.match(/^(.+)_USDT/); if (cm) { _G(cm[1] + '_maxpnl', null); _G(cm[1] + '_trail', null); } } } // 开入新信号仓位(使用市价单,-1 表示市价) function openPos(sym, isLong) { exchange.SetMarginLevel(sym, maxLeverage); const market = allMarkets[sym]; const price = exchange.GetTicker(sym).Last; const ctVal = (market.CtVal && market.CtVal > 0) ? market.CtVal : 1; const amtPrec = market.AmountPrecision !== undefined ? market.AmountPrecision : 0; const minQty = (market.MinQty && market.MinQty > 0) ? market.MinQty : 1; const maxQty = (market.MaxQty && market.MaxQty > 0) ? market.MaxQty : 999999; let qty = _N(perAmt / price / ctVal, amtPrec); qty = Math.min(Math.max(qty, minQty), maxQty); exchange.CreateOrder(sym, isLong ? 'buy' : 'sell', -1, qty); }

৩.৭ পজিশন মনিটরিং: স্টপ লস / টেক প্রফিট / ডায়নামিক ট্রেইলিং স্টপ

দ্রুত ট্রিগার প্রতি সেকেন্ডে একবার চলে, রিয়েল-টাইমে সব পজিশনের ভাসমান লাভ-ক্ষতি পর্যবেক্ষণ করে এবং তিন ধরনের এক্সিট লজিক কার্যকর করে:

  • ফিক্সড স্টপ লস: ভাসমান ক্ষতি STOP_LOSS_PCT (ডিফল্ট ৫%) ছাড় করলে স্বয়ংক্রিয়ভাবে পজিশন বন্ধ হয়
  • ফিক্সড টেক প্রফিট: ভাসমান লাভ TAKE_PROFIT_PCT (ডিফল্ট ১০%) ছাড় করলে স্বয়ংক্রিয়ভাবে পজিশন বন্ধ হয়
  • ডায়নামিক ট্রেইলিং স্টপ: ভাসমান লাভ TRAIL_TRIGGER (৩%) এ পৌঁছালে সক্রিয় হয়, সর্বোচ্চ ভাসমান লাভের ভিত্তিতে রিট্রেসমেন্ট থ্রেশহোল্ড dynamically সামঞ্জস্য হয়
javascript
const STOP_LOSS_PCT = $vars.stopLossPct || 5; const TAKE_PROFIT_PCT = $vars.takeProfitPct || 10; const TRAIL_TRIGGER = 3; // 浮盈达到 3% 后启动移动止盈 // 动态回撤阈值:最高浮盈越高,允许的回撤空间越大 function getDynamicTrailDrawdown(maxPnl) { if (maxPnl >= 7) return 3; // 最高盈利 ≥7%,允许回撤 3% if (maxPnl >= 4) return 2; // 最高盈利 ≥4%,允许回撤 2% return 1.5; // 其他情况,回撤 1.5% } function monitorTPSL(positions, tickers) { for (const pos of (positions || [])) { if (Math.abs(pos.Amount) === 0) continue; const cm = pos.Symbol.match(/^(.+)_USDT/); if (!cm) continue; const coin = cm[1]; const ticker = tickers[coin + '_USDT.swap']; if (!ticker) continue; const isLong = pos.Type === PD_LONG || pos.Type === 0; const cur = ticker.Last; const ent = pos.Price; const amt = Math.abs(pos.Amount); const pnlPct = (cur - ent) * (isLong ? 1 : -1) / ent * 100; // 追踪最高浮盈 let maxPnl = _G(coin + '_maxpnl'); if (maxPnl === null) { maxPnl = pnlPct; _G(coin + '_maxpnl', maxPnl); } else if (pnlPct > maxPnl) { maxPnl = pnlPct; _G(coin + '_maxpnl', maxPnl); } // 启动移动止盈 if (!_G(coin + '_trail') && maxPnl >= TRAIL_TRIGGER) { _G(coin + '_trail', true); Log(coin + ' 启动移动止盈,浮盈: +' + pnlPct.toFixed(2) + '%'); } const trailDrawdown = getDynamicTrailDrawdown(maxPnl); let reason = null; if (_G(coin + '_trail') && (maxPnl - pnlPct) >= trailDrawdown) reason = '移动止盈(回撤 ' + (maxPnl - pnlPct).toFixed(2) + '%, 阈值 ' + trailDrawdown + '%)'; if (!reason && pnlPct <= -STOP_LOSS_PCT) reason = '止损(' + pnlPct.toFixed(2) + '%)'; if (!reason && pnlPct >= TAKE_PROFIT_PCT) reason = '止盈(' + pnlPct.toFixed(2) + '%)'; if (reason) { exchange.CreateOrder(pos.Symbol, isLong ? 'closebuy' : 'closesell', -1, amt); Log(coin, '触发', reason); _G(coin + '_maxpnl', null); _G(coin + '_trail', null); } } }

চতুর্থ: গুরুত্বপূর্ণ ডিজাইন সিদ্ধান্ত

৪.১ কেন Rank IC (Pearson IC নয়)

Rank IC মূল মানের পরিবর্তে র‌্যাঙ্ক ব্যবহার করে কোরিলেশন গণনা করে, ফলে ফ্যাক্টরের চরম মানের (আউটলায়ার) প্রতি স্বাভাবিকভাবেই রোবাস্ট। ক্রিপ্টোকারেন্সি বাজারে দাম বণ্টন ভারী লেজযুক্ত, Pearson IC সহজেই কয়েকটি চরম ক্যান্ডেলস্টিক দ্বারা বিকৃত হতে পারে, অন্যদিকে Rank IC অনেক বেশি স্থিতিশীল।

৪.২ টাইম সিরিজ কঠোরভাবে সারিবদ্ধ, ফিউচার ফাংশন এড়ানো

IC যাচাইকরণ এবং অনলাইন সিগন্যাল ক্যালকুলেশন উভয়েই t-1 পিরিয়ডের ফ্যাক্টর মান ব্যবহার করে t পিরিয়ডের রিটার্ন পূর্বাভাস দেয়: যাচাইকরণের সময়, recordsfullRecords.slice(0, t) পাঠানো হয়, যা ভবিষ্যত ডেটাকে শারীরিকভাবে কেটে ফেলে; AI তৈরি করা ফ্যাক্টর কোড যতই records[n] উল্লেখ করুক, তা কেবল t-1 পর্যন্ত ইতিহাস অ্যাক্সেস করে। অনলাইনে, শেষ ক্যান্ডেলস্টিক বাদ দিয়ে (slice(0, n-1)) ফ্যাক্টর মান গণনা করে পরের ক্যান্ডেলস্টিকের ওঠা-নামা পূর্বাভাস করা হয়। উভয়ের যুক্তি সম্পূর্ণ অভিন্ন, ফলে ভবিষ্যত ডেটা দেখা থেকে IC কৃত্রিমভাবে উন্নত হওয়া এড়ানো যায়।

৪.৩ সাম্প্রতিক IC ওয়েটেড, ওজন বাজারের সাথে স্ব-অভিযোজিত

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

৪.৪ ডুয়াল ট্রিগার আর্কিটেকচার

ফ্যাক্টর পুনরাবৃত্তি একটি ভারী গণনা কাজ (কে-লাইন টানা + IC ব্যাকটেস্ট + AI কল), যা ঘণ্টাভিত্তিক স্তরে সম্পাদন করা যথেষ্ট; পজিশন সুরক্ষা একটি সময়-সংবেদনশীল কাজ, যার সেকেন্ড-স্তরের প্রতিক্রিয়া প্রয়োজন। দুটিকে ভিন্ন ফ্রিকোয়েন্সির ট্রিগারে বিভক্ত করে, একে অপরকে বাধা দেওয়া এড়ানো হয়।


পাঁচ, লাইভ পর্যবেক্ষণ: ফ্যাক্টর পুনরাবৃত্তি প্রক্রিয়া

লাইভ চলার দুই দিন পর নিম্নলিখিত ঘটনাগুলি পর্যবেক্ষণ করা হয়েছে:

  • প্রথম দিকে পুলে প্রবেশ করা ফ্যাক্টরগুলির ঐতিহাসিক IC সাধারণত ০.০৪ থেকে ০.০৭ এর মধ্যে ছিল, যা মৌলিক থ্রেশহোল্ড অতিক্রম করে।
  • পুনরাবৃত্তি এগিয়ে যাওয়ার সাথে সাথে, প্রায় সব ফ্যাক্টরের সাম্প্রতিক IC কমতে শুরু করে, কারও কারও ০.০৬ থেকে ০.০০৮-এ নেমে যায়, কেউ কেউ ঋণাত্মক মানে পৌঁছে যায়। এটি ইঙ্গিত দেয় যে এই ফ্যাক্টরগুলি বর্তমান বাজার পরিবেশে যে সিগন্যাল ধরছিল তা ব্যর্থ হচ্ছে।
  • সিস্টেম হ্রাস শনাক্ত করার পর, পরবর্তী রাউন্ডে অগ্রাধিকার দিয়ে এখনও কভার না হওয়া ডাইমেনশনগুলি অনুসন্ধান করে, নতুন প্রার্থী ফ্যাক্টর খুঁজে প্রতিস্থাপন করতে। পুরো প্রক্রিয়াটিতে কোনো মানব হস্তক্ষেপের প্রয়োজন হয় না।

img

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


ছয়, শেষ কথা

এই সিস্টেমটি তৈরি করার উদ্দেশ্য এটা প্রমাণ করা নয় যে AI বাজারকে পরাজিত করতে পারে। বরং বলতে চাই, এই AI যুগে, অতীতে যেসব কাজ শুধুমাত্র শীর্ষ প্রতিষ্ঠানগুলোই করতে পারত, সেগুলো সাধারণ মানুষও চেষ্টা করার সুযোগ পাচ্ছে।

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

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

⚠️ ঝুঁকি সতর্কতা: যেকোনো কৌশলে লোকসানের ঝুঁকি রয়েছে। এই কন্টেন্ট শুধুমাত্র প্রযুক্তিগত শিক্ষার রেফারেন্সের জন্য, এটি বিনিয়োগের পরামর্শ নয়। লাইভ ট্রেডিংয়ের আগে অবশ্যই পর্যাপ্ত পরীক্ষা করুন।

কৌশল সোর্স কোড: অভিযোজিত ফ্যাক্টর মাইনিং কোয়ান্টিটেটিভ স্ট্র্যাটেজি বিটা সংস্করণ

Comment
All comments (0)
No data
No data
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)