ভলিউম রিভার্সাল ট্রেন্ড ক্যাপচার কৌশল

SMA ATR VOLUME ETH RTH TP SL
সৃষ্টির তারিখ: 2025-05-13 10:39:29 অবশেষে সংশোধন করুন: 2025-05-13 10:39:29
অনুলিপি: 1 ক্লিকের সংখ্যা: 346
2
ফোকাস
319
অনুসারী

ভলিউম রিভার্সাল ট্রেন্ড ক্যাপচার কৌশল ভলিউম রিভার্সাল ট্রেন্ড ক্যাপচার কৌশল

কৌশল ওভারভিউ

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

কৌশল নীতি

এই কৌশলটির মূল নীতিটি বাজারের অস্বাভাবিক লেনদেনের পরে প্রবণতা বিপরীত হওয়ার উপর ভিত্তি করে। এর সুনির্দিষ্ট অপারেশন লজিকটি নিম্নরূপঃ

  1. অস্বাভাবিক লেনদেন সনাক্ত করুন: সিস্টেমটি পরীক্ষা করে যে পূর্ববর্তী কে লাইনের লেনদেনের পরিমাণ গড়ের তুলনায় উল্লেখযোগ্যভাবে বেশি কিনা। নিয়মিত লেনদেনের সময়কালে (RTH), লেনদেনের পরিমাণ সাম্প্রতিক গড় লেনদেনের পরিমাণের চেয়ে 3 গুণ বেশি হওয়া দরকার (নিয়মিত); বন্ধের পরে বা বিশেষ সময়কালে (ETH), 5 গুণ বেশি হওয়া দরকার। গড় লেনদেনের পরিমাণ গণনা স্বয়ংক্রিয়ভাবে RTH প্রান্ত সময়, বন্ধের পরে 4-6 ঘন্টা এবং রবিবার বন্ধের আগে সময়কে বাদ দেয়।

  2. ট্রেডিং কমেছে: বর্তমান K-লাইনের লেনদেনের পরিমাণ অবশ্যই পূর্ববর্তী K-লাইনের তুলনায় কম হতে হবে, যা নির্দেশ করে যে বড় লেনদেনের কাজ শেষ হয়েছে।

  3. প্রবণতা নির্ধারণ: অস্বাভাবিক লেনদেনের K-লাইন আগে বন্ধের দামের সাথে SMA-র (Simple Moving Average) সম্পর্কের তুলনা করে প্রবণতার দিকনির্দেশনা নির্ধারণ করুন।

  4. বিপরীতমুখী প্রবেশের সংকেত

    • একাধিক সিগন্যালঃ যখন অস্বাভাবিক লেনদেনের পরিমাণ K লাইনের আগে নিম্নমুখী প্রবণতা ((SMA এর নিচে ক্লোজিং মূল্য) এবং বর্তমান K লাইনের লেনদেনের পরিমাণ কম থাকে।
    • খালি করার সংকেত: যখন অস্বাভাবিক লেনদেনের পরিমাণ K লাইন আগে মুদ্রাস্ফীতির প্রবণতা ((SMA এর চেয়ে বেশি মূল্যের সমাপ্তি), এবং বর্তমান K লাইন লেনদেনের পরিমাণ কমে যায়।
  5. ইনস্টল করা

    • আরও বেশি করুনঃ অস্বাভাবিক লেনদেনের পরিমাণের জন্য K- লাইনের সর্বনিম্ন মূল্য নির্ধারণ করুন।
    • খালি করাঃ অস্বাভাবিক লেনদেনের পরিমাণের K লাইনের সর্বোচ্চ মূল্য নির্ধারণ করে লিমিট বিক্রয় আদেশ।
  6. ঝুঁকি ব্যবস্থাপনা: বিভিন্ন জাতের বৈশিষ্ট্যের উপর নির্ভর করে, সিস্টেমটি দুটি স্টপ লস / স্টপ স্টপ সেটিং প্রদান করেঃ

    • নির্দিষ্ট জাতের জন্য (যেমন এনকিউ): স্টপ লস এবং স্টপ ক্যাচ ব্যবহার করে একটি নির্দিষ্ট পয়েন্ট সেট করুন।
    • অন্যান্য প্রজাতির জন্যঃ এটিআর-ভিত্তিক গতিশীল স্টপ/স্টপ বা একটি নির্দিষ্ট পয়েন্ট ব্যবহার করে।
  7. সময় ফিল্টারকৌশলটি RTH-এর প্রথম এবং শেষ 15 মিনিটের ট্রেডিং সিগন্যালগুলিকে বাছাই করে ফিল্টার করতে পারে এবং সর্বদা বন্ধের পরে বন্ধের সময় (৪-৬ টা) এবং রবিবারের বন্ধের আগে সংকেতগুলিকে ফিল্টার করে।

কৌশলগত সুবিধা

  1. একটি গুরুত্বপূর্ণ পরিবর্তনকে ধরা

  2. সঠিক প্রবেশ পয়েন্ট: অস্বাভাবিক লেনদেনের পরিমাণের K লাইনের উচ্চ / নিম্ন পয়েন্টগুলিতে সীমিত মূল্যের একক ব্যবহার করে লেনদেনের প্রযুক্তিগতভাবে গুরুত্বপূর্ণ মূল্যের স্তরে লেনদেন নিশ্চিত করে লেনদেনের যথার্থতা বাড়ানো।

  3. স্বনির্ধারণের পরিমাণকৌশলঃ অস্বাভাবিক লেনদেনের পরিমাণ নির্ধারণের মানদণ্ডটি বিভিন্ন লেনদেনের সময় (সাধারণ লেনদেনের সময় বনাম বন্ধের পরে / বিশেষ সময়) এর উপর ভিত্তি করে গতিশীলভাবে সামঞ্জস্য করা হয়, যা বাজারের বাস্তবতার সাথে আরও মিলিত হয়।

  4. নমনীয় ঝুঁকি ব্যবস্থাপনা: নির্দিষ্ট পয়েন্ট এবং ATR-এর উপর ভিত্তি করে স্টপ/স্টপ বিকল্প প্রদান করা হয়, যা বিভিন্ন জাতের বৈশিষ্ট্য এবং অস্থিরতার উপর ভিত্তি করে ব্যক্তিগতকৃত করা যায়।

  5. স্মার্ট টাইম ফিল্টার: স্বয়ংক্রিয়ভাবে কম তরলতা এবং অস্থির ট্রেডিংয়ের সময়গুলি সনাক্ত এবং ফিল্টার করুন যাতে বাজার খোলার এবং বন্ধের আশেপাশে সহজেই মিথ্যা সংকেত দেখা যায়।

  6. স্পষ্ট ভিজ্যুয়াল ফিডব্যাককৌশলঃ চার্টগুলিতে স্বজ্ঞাত ভিজ্যুয়াল নির্দেশাবলী সরবরাহ করে, যার মধ্যে রয়েছে অস্বাভাবিক লেনদেনের কে লাইন উজ্জ্বলতা, ট্রেন্ডিং এসএমএ লাইন, স্টপ-ড্রপ স্টপ সমতা, যা ব্যবসায়ীদের পর্যবেক্ষণ এবং বিশ্লেষণের জন্য সুবিধাজনক।

  7. স্বয়ংক্রিয়ভাবে সম্পাদন: একবার শর্ত পূরণ হয়ে গেলে, সিস্টেমটি স্বয়ংক্রিয়ভাবে সীমিত মূল্যের অর্ডার এবং স্টপ লস স্টপ সেটিংগুলি সম্পাদন করে, মানুষের হস্তক্ষেপ হ্রাস করে এবং লেনদেনের শৃঙ্খলা বজায় রাখে।

কৌশলগত ঝুঁকি

  1. ভুয়া আক্রমণের ঝুঁকি: অস্বাভাবিক লেনদেনের পরিমাণ দামকে স্বল্পমেয়াদী গুরুত্বপূর্ণ স্তরের ব্রেকডাউন করতে পারে, তবে তারপরে দ্রুত ফিরে যেতে পারে, যা ভুল সংকেত দেয়। এই ঝুঁকি প্রশমিত করার জন্য, নিশ্চিতকরণ সূচকগুলি যুক্ত করার বিষয়টি বিবেচনা করা যেতে পারে, যেমন আরএসআই ওভারবই / ওভারসোল্ড নিশ্চিতকরণ বা ব্রেকডাউন ধারাবাহিকতার প্রয়োজনীয়তা।

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

  3. বাজার পরিবর্তনের ঝুঁকি: একটি শক্তিশালী প্রবণতা বাজারে, বিপরীতমুখী লেনদেনের জন্য অবিরত প্রতিকূল মূল্যের গতিপথের মুখোমুখি হতে পারে। দীর্ঘমেয়াদী প্রবণতা ফিল্টার যুক্ত করার বিষয়টি বিবেচনা করা যেতে পারে, যাতে শক্তিশালী প্রবণতা পরিবেশে বিপরীতমুখী লেনদেন করা যায় না।

  4. সীমিত মূল্যের ইস্যুর ঝুঁকি: যদি পরবর্তী K লাইনে দাম নির্ধারিত সীমা স্তরের উপরে না পৌঁছায়, তবে ট্রেডিং সিগন্যালটি কার্যকর হবে না। সর্বোচ্চ কার্যকর সময়সীমা নির্ধারণের বিষয়টি বিবেচনা করা যেতে পারে, অথবা নির্দিষ্ট শর্তে, এটি কেবলমাত্র বাজার মূল্যে কার্যকর করা যেতে পারে।

  5. স্বল্প তরলতার ঝুঁকি: যদিও কৌশলটিতে সময় ফিল্টারিং বৈশিষ্ট্য অন্তর্ভুক্ত করা হয়েছে, কিছু জাতের নির্দিষ্ট সময়ে এখনও তরলতার অভাবের সমস্যা হতে পারে। ট্রেডিং জাতের বৈশিষ্ট্য অনুসারে ট্রেডিং সময়ের সীমাবদ্ধতা সামঞ্জস্য করার পরামর্শ দেওয়া হয়েছে।

  6. প্যারামিটার অপ্টিমাইজেশান ঝুঁকি: অতিরিক্ত অপ্টিমাইজেশান কৌশলগত প্যারামিটারগুলি অতীতের ডেটাতে অতিরিক্ত ফিট করে এবং ভবিষ্যতে খারাপ পারফরম্যান্সের কারণ হতে পারে। প্যারামিটারগুলি যুক্তিসঙ্গত সীমার মধ্যে রয়েছে তা নিশ্চিত করা উচিত এবং কৌশলটির স্থায়িত্ব প্রমাণ করার জন্য নমুনা পরীক্ষা করা উচিত।

কৌশল অপ্টিমাইজেশনের দিকনির্দেশনা

  1. বহু-সময়-প্রান্তিক নিশ্চিতকরণ: একটি উচ্চতর সময়কালের প্রবণতা ফিল্টার যুক্ত করুন, যাতে বৃহত্তর প্রবণতা দিকের উচ্চতর বিজয়ী হার নিশ্চিত করা যায়। উদাহরণস্বরূপ, আপনি সূর্যমুখী প্রবণতা দিকটি পরীক্ষা করতে পারেন, কেবলমাত্র সূর্যমুখী প্রবণতার সাথে সামঞ্জস্য থাকলে প্রবেশ করুন।

  2. লেনদেনের পরিমাণ ও গুণমানের মূল্যায়নখাঁটি ভলিউম ছাড়াও, লেনদেনের ভলিউমের গুণমানের মূল্যায়ন বিবেচনা করা যেতে পারে, যেমন লেনদেনের ভলিউম ওজনের গড় মূল্যের (ভিডাব্লুএপি) বিচ্যুতি, যাতে বড় লেনদেনের পিছনে বাজারের আচরণ আরও ভালভাবে বোঝা যায়।

  3. ডায়নামিক স্টপ লস স্ট্র্যাটেজি: অস্থিরতার উপর ভিত্তি করে গতিশীল স্টপ-অফ উপলব্ধ, স্বয়ংক্রিয়ভাবে স্টপ-অফ অবস্থানগুলি সামঞ্জস্য করে এবং ট্রেডিংয়ের সুবিধাজনক দিকের দিকে অগ্রসর হওয়ার সাথে সাথে মুনাফার অংশটি লক করে দেয়। উদাহরণস্বরূপ, ট্র্যাকিং স্টপ ব্যবহার করা যেতে পারে বা ক্রিয়াকলাপের পরে স্টপ-অফকে ব্যয়-মূল্যে স্থানান্তরিত করা যেতে পারে।

  4. মাল্টি-প্রজাতির প্রাসঙ্গিকতা ফিল্টার: সংশ্লিষ্ট জাতের জন্য (যেমন স্টক ইন্ডেক্স ফিউচার ও ক্যাশ, গোল্ড এবং সিলভার ইত্যাদি) সংশ্লিষ্ট জাতের নিশ্চিতকরণ সূচক যুক্ত করা সংকেতের গুণমান উন্নত করে। যখন একাধিক সংশ্লিষ্ট জাতের একই সাথে অস্বাভাবিক লেনদেনের পরিমাণ এবং মূল্যের আচরণ ঘটে তখন সংকেতটি আরও নির্ভরযোগ্য হতে পারে।

  5. মেশিন লার্নিং অপ্টিমাইজেশন: মেশিন লার্নিং অ্যালগরিদমের মাধ্যমে ঐতিহাসিক ডেটাতে সবচেয়ে সফল অস্বাভাবিক লেনদেনের পরিমাণের মডেলের বৈশিষ্ট্য বিশ্লেষণ করে, প্রবেশের শর্ত এবং প্যারামিটারগুলিকে গতিশীলভাবে সামঞ্জস্য করে। উদাহরণস্বরূপ, সিদ্ধান্ত গাছ বা র্যান্ডম বন ব্যবহার করে প্রদত্ত অস্বাভাবিক লেনদেনের পরিমাণের বৈশিষ্ট্যগুলির অধীনে সর্বোত্তম কর্মের পূর্বাভাস দেওয়া যেতে পারে।

  6. অস্থিরতার হার: বাজারের বর্তমান ওঠানামার অবস্থার উপর ভিত্তি করে অস্বাভাবিক লেনদেনের পরিমাণ নির্ধারণের মানদণ্ড এবং স্টপ লস / স্টপ স্তরগুলিকে সামঞ্জস্য করুন। উচ্চ ওঠানামার পরিবেশে অস্বাভাবিক পরিমাণ বাড়ানো থ্রেশহোল্ড নির্ধারণ করতে পারে এবং স্টপ লস দূরত্বকে হ্রাস করতে পারে; কম ওঠানামার পরিবেশে বিপরীত।

  7. মৌলিক ফিল্টার যোগ করুন: গুরুত্বপূর্ণ অর্থনৈতিক তথ্য প্রকাশের দিন বা ত্রৈমাসিক আর্থিক প্রতিবেদন প্রকাশের দিন কৌশলগত প্যারামিটারগুলিকে মৌসুমীভাবে সামঞ্জস্য করুন বা নিউজফেস ব্যাঘাতের কারণে ভুল সংকেত এড়াতে ব্যবসায় স্থগিত করুন।

সারসংক্ষেপ

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

কৌশলটির মূল সুবিধা হল যে এটি বাজারের “মধ্যম আকার” সম্পর্কে সঠিকভাবে ধরা যায় যা বাজারের অংশগ্রহণকারীদের প্রচুর পরিমাণে প্রবেশের পরে এবং তারপরে প্রত্যাহারের সময় প্রায়শই স্বল্পমেয়াদী বিপরীত সুযোগ তৈরি করে। এই কৌশলটি মূল মূল্যের স্তরে সঠিকভাবে অবস্থান নির্ধারণের মাধ্যমে এবং যুক্তিসঙ্গত স্টপ লস স্টপ ম্যানেজমেন্টের সাথে যুক্ত হয়ে একটি শৃঙ্খলাবদ্ধ ট্রেডিং পদ্ধতি সরবরাহ করে।

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

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

কৌশল সোর্স কোড
/*backtest
start: 2024-05-13 00:00:00
end: 2025-05-11 08:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
// Strategy Title Reflects Latest Logic
strategy(title="Middle Finger Trading Strategy",
         shorttitle="Middle_Finger",
         overlay=true,
         pyramiding=0, // Only one entry at a time
         default_qty_type=strategy.percent_of_equity,
         default_qty_value=1, // Trade 1% of equity
         commission_value=0.04, // Example commission (adjust as needed)
         commission_type=strategy.commission.percent,
         initial_capital = 10000, // Example starting capital
         process_orders_on_close=false // Important for limit orders to potentially fill intra-bar
         )

// --- Inputs ---

// Volume Settings Group
grp_vol = "Volume Settings"
float rthHugeVolMultiplier = input.float(3.0, title="1. RTH Huge Vol. Multiplier (> Avg)", minval=1.1, step=0.1, group=grp_vol, tooltip="Multiplier for core RTH (9:45-15:44 ET)")
float ethHugeVolMultiplier = input.float(5.0, title="2. ETH/Excluded Huge Vol. Multiplier (> Avg)", minval=1.1, step=0.1, group=grp_vol, tooltip="Multiplier for ETH and first/last 15min RTH (default 5x)")
int   volLookback         = input.int(20, title="3. Volume SMA Lookback", minval=1, group=grp_vol, tooltip="Lookback for calculating the filtered average volume (Used ONLY for identifying the HUGE spike)")
// Removed normalVolMultiplier as it's no longer used for entry confirmation

// Trend Settings Group
grp_trend = "Trend Settings"
int   trendLookback       = input.int(20, title="1. Trend SMA Lookback", minval=2, group=grp_trend, tooltip="Lookback period for the Simple Moving Average used to determine the trend before the spike")

// Risk Management Group
grp_risk = "Risk Management (SL/TP)"
string nqTargetTickerId   = input.string("CME:NQ1!", title="1. Target Ticker ID for Fixed NQ Points", group=grp_risk, tooltip="Specify the exact Ticker ID (e.g., CME:NQ1!, TVC:NDX) for fixed SL/TP. Found in Symbol Info.")
float nqFixedStopPoints   = input.float(20.0, title="2. Fixed SL Points (for Target Ticker)", group=grp_risk, minval=0.1, step=0.1)
float nqFixedTpPoints     = input.float(50.0, title="3. Fixed TP Points (for Target Ticker)", group=grp_risk, minval=0.1, step=0.1)

// General SL/TP Settings (used if NOT the target ticker)
bool  useAtrStops         = input.bool(true, title="4. Use ATR for SL/TP (Other Tickers)?", group=grp_risk)
int   atrLookback         = input.int(14, title="5. ATR Lookback", group=grp_risk, inline="atr_other")
float atrStopMultiplier   = input.float(2.0, title="6. ATR SL Multiplier", group=grp_risk, inline="atr_other", minval=0.1, step=0.1)
float atrTpMultiplier     = input.float(4.0, title="7. ATR TP Multiplier", group=grp_risk, inline="atr_other", minval=0.1, step=0.1)
float fixedStopPoints     = input.float(100.0, title="6. Fixed SL Points (Other Tickers)", group=grp_risk, inline="fixed_other", minval=1)
float fixedTpPoints       = input.float(200.0, title="7. Fixed TP Points (Other Tickers)", group=grp_risk, inline="fixed_other", minval=1)

// Time Filter Settings Group
grp_time = "Time Filter (ET)"
bool  enableEntryFilterRthEdges = input.bool(true, title="1. Filter Entries First/Last 15 Min RTH (ET)?", group=grp_time, tooltip="If checked, ignores entries from 9:30-9:44 ET and 15:45-15:59 ET. Avg Vol calc *always* filters these times, 4-6PM ET, and Sun pre-6PM ET.")
string targetTimezone     = "America/New_York" // Specify Eastern Time zone

// --- Time Calculation Function ---
isTimeInSession(t, tz, sessionString) =>
    not na(time(timeframe.period, sessionString, tz))

// --- Time Context Functions ---
getTimeContext(t, tz) =>
    h = hour(t, tz)
    m = minute(t, tz)
    d = dayofweek(t, tz)

    // Core RTH: 9:45 AM to 15:44 PM ET (Mon-Fri)
    bool isCoreRTH = d >= dayofweek.monday and d <= dayofweek.friday and
       ((h == 9 and m >= 45) or (h >= 10 and h <= 14) or (h == 15 and m <= 44))

    // Excluded RTH Edges: 9:30-9:44 ET and 15:45-15:59 ET (Mon-Fri)
    bool isExcludedRTH = d >= dayofweek.monday and d <= dayofweek.friday and
       ((h == 9 and m >= 30 and m <= 44) or (h == 15 and m >= 45))

    // After Hours Closed: 4:00 PM to 5:59 PM ET (Mon-Fri)
    bool isAfterHoursClosed = d >= dayofweek.monday and d <= dayofweek.friday and
       (h >= 16 and h < 18)

    // Sunday Pre-Market: Sunday before 6:00 PM ET
    bool isSundayPreMarket = d == dayofweek.sunday and h < 18

    // Combine ALL periods where activity should be ignored or volume excluded from avg
    bool isExcludedPeriod = isExcludedRTH or isAfterHoursClosed or isSundayPreMarket

    [isCoreRTH, isExcludedRTH, isAfterHoursClosed, isSundayPreMarket, isExcludedPeriod]

// --- Get Time Context for Current and Previous Bar ---
[isCurrentBarCoreRTH, isCurrentBarExcludedRTH, isCurrentBarAfterHoursClosed, isCurrentBarSundayPreMarket, isCurrentBarExcludedPeriod] = getTimeContext(time, targetTimezone)
[isPreviousBarCoreRTH, isPreviousBarExcludedRTH, isPreviousBarAfterHoursClosed, isPreviousBarSundayPreMarket, isPreviousBarExcludedPeriod] = getTimeContext(time[1], targetTimezone)

// --- Calculations ---

// Volume Averaging: Exclude RTH edges, 4-6 PM ET, and Sunday Pre-6 PM ET ALWAYS
// This average is *only* used to define the huge volume spike threshold
bool excludeCurrentVolFromAvg = isCurrentBarExcludedPeriod
float volumeForAvgCalc = excludeCurrentVolFromAvg ? na : volume
float avgVolume = ta.sma(volumeForAvgCalc, volLookback)

// Dynamic Huge Volume Multiplier: Based on *previous* bar's time (Core RTH or not)
float activeHugeVolMultiplier = isPreviousBarCoreRTH ? rthHugeVolMultiplier : ethHugeVolMultiplier
// Use avgVolume[1] as current avgVolume excludes current bar, and we compare previous volume to avg *before* it
float hugeVolThreshold   = nz(avgVolume[1]) * activeHugeVolMultiplier

// --- MODIFIED Volume Conditions ---
// 1. Check if the *previous* bar had huge volume compared to its preceding average
bool isHugeVolumePrevBar = volume[1] > hugeVolThreshold and hugeVolThreshold > 0
// 2. Check if the *current* bar's volume is simply lower than the previous (huge) bar's volume
bool isVolumeLowerThanSpike = volume < volume[1]

// Trend Condition
float priceSma = ta.sma(close, trendLookback)
// Ensure trend condition uses close[2] vs sma[2] (trend state *before* the spike bar)
bool isBullishTrendBeforeSpike = close[2] > nz(priceSma[2])
bool isBearishTrendBeforeSpike = close[2] < nz(priceSma[2])

// --- Entry Time Filtering ---
// Always filter After Hours Closed and Sunday Pre-Market.
// Optionally filter RTH Edges based on input.
bool shouldFilterRthEdges = enableEntryFilterRthEdges and isCurrentBarExcludedRTH
bool isIgnoreEntryTime = shouldFilterRthEdges or isCurrentBarAfterHoursClosed or isCurrentBarSundayPreMarket

// --- MODIFIED Base Conditions ---
// Uses the simplified `isVolumeLowerThanSpike` check
bool baseLongCondition = isBearishTrendBeforeSpike and isHugeVolumePrevBar and isVolumeLowerThanSpike
bool baseShortCondition = isBullishTrendBeforeSpike and isHugeVolumePrevBar and isVolumeLowerThanSpike

// Final Conditions (Apply Time Filter)
bool finalLongCondition = baseLongCondition and not isIgnoreEntryTime
bool finalShortCondition = baseShortCondition and not isIgnoreEntryTime

// --- Stop Loss & Take Profit Calculation (Conditional Logic) ---
// This part remains the same
float atrValue = ta.atr(atrLookback)
float tickValue = syminfo.mintick
int stopLossTicks = 100 // Default fallback SL ticks
int takeProfitTicks = 200 // Default fallback TP ticks

// Check if the current symbol matches the target ticker ID
bool isTargetTicker = str.upper(syminfo.tickerid) == str.upper(nqTargetTickerId) // Case-insensitive comparison

if (isTargetTicker and tickValue > 0)
    // --- Target Ticker Logic (e.g., NQ Fixed Points) ---
    float ticksPerPoint = 1.0 / tickValue
    stopLossTicks := math.max(1, math.round(nqFixedStopPoints * ticksPerPoint))
    takeProfitTicks := math.max(1, math.round(nqFixedTpPoints * ticksPerPoint))
else if tickValue > 0 // Use only if tickValue is valid
    // --- Standard Logic (Other Tickers: ATR or Fixed) ---
    float stopLossDistance = useAtrStops ? atrValue * atrStopMultiplier : fixedStopPoints * tickValue
    float takeProfitDistance = useAtrStops ? atrValue * atrTpMultiplier : fixedTpPoints * tickValue

    // Calculate ticks, ensuring it's at least 1 tick
    stopLossTicks := na(stopLossDistance) ? 100 : math.max(1, math.round(stopLossDistance / tickValue))
    takeProfitTicks := na(takeProfitDistance) ? 200 : math.max(1, math.round(takeProfitDistance / tickValue))

// Final check to ensure SL/TP are not na
stopLossTicks := nz(stopLossTicks, 100)
takeProfitTicks := nz(takeProfitTicks, 200)


// --- Strategy Execution ---
// Uses Limit Orders based on previous bar's low/high - Remains the same
float limitEntryPriceLong = low[1]  // Target entry at the low of the huge volume bar
float limitEntryPriceShort = high[1] // Target entry at the high of the huge volume bar

if (finalLongCondition and strategy.position_size == 0)
    strategy.cancel("S") // Cancel any pending short limit order first
    strategy.entry("L", strategy.long, limit = limitEntryPriceLong)
    strategy.exit("L SL/TP", from_entry="L", loss=stopLossTicks, profit=takeProfitTicks)

if (finalShortCondition and strategy.position_size == 0)
    strategy.cancel("L") // Cancel any pending long limit order first
    strategy.entry("S", strategy.short, limit = limitEntryPriceShort)
    strategy.exit("S SL/TP", from_entry="S", loss=stopLossTicks, profit=takeProfitTicks)


// --- Plotting & Visuals ---
plot(avgVolume, title="Filtered Avg Volume", color=color.new(color.blue, 60), style=plot.style_line)
// Removed the plot for the normal volume threshold as it's no longer used

// Highlight huge volume bar (previous bar that triggered the signal)
bgcolor(isHugeVolumePrevBar[1] ? color.new(color.yellow, 85) : na, title="Huge Volume Bar [-1]")

// Highlight bars excluded from volume average calculation
bgcolor(excludeCurrentVolFromAvg ? color.new(color.teal, 90) : na, title="Vol Excluded from Avg Calc")

// Highlight bars where entries are ignored due to time filters
bgcolor(isIgnoreEntryTime and (baseLongCondition or baseShortCondition) ? color.new(color.gray, 75) : na, title="Entry Time Filtered Bar")

// --- MODIFIED Highlight base conditions met ---
// Reflects the updated base conditions using isVolumeLowerThanSpike
bgcolor(baseLongCondition and not isIgnoreEntryTime ? color.new(color.green, 90) : na, title="Base Long Condition Met")
bgcolor(baseShortCondition and not isIgnoreEntryTime ? color.new(color.red, 90) : na, title="Base Short Condition Met")

plot(priceSma, title="Trend SMA", color=color.gray)

// Plot SL/TP levels for visualization - Remains the same
var float entryPrice = na
var float slLevel = na
var float tpLevel = na

if (strategy.opentrades > 0 and strategy.opentrades[1] == 0) // Just entered a trade
    entryPrice := strategy.opentrades.entry_price(0)
    if (strategy.position_size > 0) // Long
        slLevel := entryPrice - stopLossTicks * tickValue
        tpLevel := entryPrice + takeProfitTicks * tickValue
    else // Short
        slLevel := entryPrice + stopLossTicks * tickValue
        tpLevel := entryPrice - takeProfitTicks * tickValue
else if (strategy.opentrades == 0 and strategy.opentrades[1] > 0) // Position closed
    entryPrice := na
    slLevel := na
    tpLevel := na
else if (strategy.opentrades > 0) // Position still open
    entryPrice := strategy.opentrades.entry_price(0)
    if (strategy.position_size > 0) // Long
        slLevel := entryPrice - stopLossTicks * tickValue
        tpLevel := entryPrice + takeProfitTicks * tickValue
    else // Short
        slLevel := entryPrice + stopLossTicks * tickValue
        tpLevel := entryPrice - takeProfitTicks * tickValue

plot(strategy.opentrades > 0 ? slLevel : na, title="Stop Loss Level", color=color.red, style=plot.style_linebr)
plot(strategy.opentrades > 0 ? tpLevel : na, title="Take Profit Level", color=color.green, style=plot.style_linebr)

// Optional Debugging Plots
// plotchar(isHugeVolumePrevBar, "HugeVol[1]", "H", location.bottom, color.yellow, size=size.tiny)
// plotchar(isVolumeLowerThanSpike, "VolLow", "v", location.bottom, color.purple, size=size.tiny) // Changed char
// plotchar(finalLongCondition, "FinalLong", "L", location.top, color.green, size=size.tiny)
// plotchar(finalShortCondition, "FinalShort", "S", location.top, color.red, size=size.tiny)
// plot(finalLongCondition ? limitEntryPriceLong : na, "Long Limit Target", color.lime, style=plot.style_circles, linewidth=2)
// plot(finalShortCondition ? limitEntryPriceShort : na, "Short Limit Target", color.fuchsia, style=plot.style_circles, linewidth=2)