
مقدمه
قصد دارم در این مقاله، اکسپرت هج را معرفی کنم که ایدهای بسیار سادهای هم دارد. اما ابتدا یادداشتی مهم دربارهی مبانی اکسپرت هج را با هم بخوانیم:
- هج (برگرفته از ویکیپدیا، دانشنامهی آزاد)
برگرفته از مدخل (Hedging)
در امور مالی، “هج”، یک نوع خاصی از سرمایهگذاری است که بهطور ویژه برای کاهش یا از بین بردن ریسک، در یک سرمایهگذاری دیگر، استفاده میشود. هجینگ (hedging)، یک استراتژی برای بهحداقلرساندنِ ضرر در کسبوکار است، و در همان حال اجازه میدهد، آن کسبوکار برای ما سود هم داشته باشد. عموماً، کسی که این کار را انجام میدهد، یا بهعبارتی، فرد هجر (hedger)، روی اوراقِ بهاداری سرمایهگذاری میکند که باور دارد نسبت به “اَرزش واقعیشان” زیر قیمت آمدهاند
(برای مثال، وام مسکنی که او گرفته)، و وی این [موضوع] را با فروش موقت[۲] اوراق بهادار مرتبط، ترکیب میکند. بنابراین، در اینجا فرد اهمیتی نمیدهد که اَرزش مجموعهی بازار بالا میرود یا پایین میآید. هولبروک ورکینگ (Holbrook Working)، که یکی از پیشگامان تئوری هجینگ است، این استراتژی را استراتژی “احتکار در پایه” (Speculation in the basis) مینامد – جاییکه این پایه، اختلافِ بین اَرزش تئوری هج، و اَرزش واقعی آن (یا بین قیمتهای واقعی، و قیمتهای آینده در زمان هولبروک ورکینگ) بهحساب میآید.
در هر نوع فعالیت کاری، طبیعتاً ریسکهایی داریم. و برخی از این ریسکها برای مشاغل یا فعالیتهایی خاص، “عادی” محسوب میشوند؛ مثلاً بالا رفتن یا پایین آمدن قیمت نفت در شرکتهای استخراج و پخش فرآوردههای نفتی، اَمری طبیعی حساب میشود. اما برخی دیگر از ریسکها، طبیعی نیستند و اصلاً مشتاق آنها هم نیستیم، ولی بدون پوشش و حمایت، نمیتوان از آنها جلوگیری کرد. کسی که فروشگاه دارد، میتواند از ریسکهایی مانند رقابت، محصولات ضعیف یا مشتریناپسند، خود را محفوظ نگه دارد. اما در آتش سوختنِ اجناس، طبیعتاً ناخواسته است ولی میشود با بیمهی آتشسوزی این ریسک را “پوشاند” [در اصلِ مقاله، برای لغت “پوشاند” معادل hedge آورده شدهاست، که در معنی کلی، یعنی پوشاندن و حفظ کردن با پوشش، تا بهنوعی به بحث هجینگ در مقاله ربط پیدا کند].
تمام هجها [یعنی تمام پوشش دادنها] اَبزارهای مالی نیستند: برای مثال، تولیدکنندهای که به کشور دیگری صادرات میکند، با پول کشور مقصد هزینههای خود را انجام میدهد و کالا میفروشد تا اینگونه از ریسک بهوجودآمده بهخاطر اختلاف پول دو کشور، جلوگیری کند و آن را پوشش دهد (=هج کند).
بیشتر در این مورد بخوانید.
- تمام چیزهایی که از سِرور نیاز داریم را باید با تابع MarketInfo (string symbol, int type) فراخوانی کنیم. این تابع به ما اجازه میدهد هر دادهای را وَرای دادههایی که روی نمودارِ فعال، دیده میشوند، فراخوانی کنیم. و همچنین اجازه خواهیم داشت هر نوع معاملهای در هر اَرزی را، فراتر از نمودار اَرزی که جلوی ماست، انجام دهیم. و میتوانیم دو اَرز را بهسادگی هج کنیم. جا دارد از خداوند بزرگ بهخاطر دانشی که به ما بخشیده، و تیم متاتریدر ۴ تشکر کنیم که کار را برای ما بسیار ساده کردهاند!
- یک موضوع مهم در هجینگ، همبستگی بین دو اَرزِ درحال رصد است که میتوان توابع کوچکی را از آنها استخراج کرد و در ادامه آنها را نشان خواهیم داد.
همبستگی (Correlation)، در دنیای مالی، اندازهگیری آماری در ارتباطِ بین دو سند بهادار، بهحساب میآید. ضریب همبستگی بین ۱- و ۱+ متغییر است. همبستگی ۱+ یعنی دو جفتاَرز ۱۰۰ درصد در یک جهت، در یک زمان، حرکت خواهند کرد. و ۱- نیز میگوید دو جفتاَرز ۱۰۰ درصد در جهت مخالف خواهند رفت. این عدد اگر صفر باشد، رابطهی بین این دو جفتاَرز کاملاً رَندوم خواهد بود. بیشتر بخوانید.
مطالب بالا چیزهای سادهای هستند، و فارکس هجرهایی که از اکسپرت متاتریدر ۴ استفاده میکنند، باید این مطالب را بدانند. اکنون میتوانیم ساختن یک اکسپرت هج را شروع کنیم.
قدم به قدم با کدنویسی اکسپرت هج
مرحله اول: پارامترهای ورودی
قبل از شروع نوشتن اکسپرت هج، نیاز داریم که ۲ اَرز دارای همبستگی را انتخاب کنیم؛ بهعبارت دیگر:
- GBPUSD وEURUSD که همیشه در یک جهت حرکت میکنند؛
- EURUSD و USDCHF که همیشه در جهت مخالف میکنند؛
- و غیره.
در این مقاله، دو جفتاَرز هج مورد علاقهی خودم را انتخاب میکنم کهEURJPY و GBPJPY هستند. این دو همیشه در یک جهت حرکت میکنند و برای ثبت معاملهی هج، کار سادهتری خواهیم داشت. بیایید شروع کنیم. برای شروع کار بیایید با این متغیرهای ورودی آشنا شویم.
// this is to block the order sending function but // not to block the close function. extern bool BlockOpening = false; extern string BaseSymbol = "EURJPY";//the 1st symbol extern string H_Symbol = "GBPJPY";//the 2nd symbol extern bool MoveSameWay = true;//they move the same way or not extern int CorPeriod = 5;//your favorite correlation period extern double BaseLotSize = 1.5;//1st symbol lotsize extern double H_LotsSize = 1.0;//2nd symbol lotsize extern double ExpectProfit$ = 137;//your expect profit in USD //your acceptable loss in USD in case any error occurred extern double AcceptableLoss$ = -77; extern string ExpectCor = "______";//your expect correlation to hedge //this is the upper expect cor value and has to be greater than "And" extern double Between = 1.05; extern double And = 0.9;//this is the lower expect cor level extern string MISC = "______";//some thing more extern int MagicNo = 318;//your favorite magic number extern bool ShowStatus = true;//to show the present hedging status //to play sound when SendH and CloseH function done extern bool PlayAudio = false;
مرحله دوم: اعلام متغیر
در زیر، متغیرهایی را میبینید که در این اکسپرت استفاده شده، و من فقط متغیری را توضیح میدهم که برای درک عملکرد اکسپرت ضروری است.
int BSP // the spread of base symbol , HSP // the spread of hedge symbol , gsp , BOP = -1 // base symbol order type , HOP = -1 // hedge symbol order type , up = 0 , Hcnt = 0 , u = 0 , d = 0 , day = 0 , sent=0 , firstopen , expire; double Lot , BaseOpen // base symbol order open price , HOpen // hedge symbol order open price , BPt // base symbol Point value , HPt // hedge symbol Point value , BSwapL // base symbol swap long value , BSwapS // base symbol swap short value , HSwapL // hedge symbol swap long value , HSwapS; // hedge symbol swap short value bool SResult = false, BResult = false, H1.profitswap, H2.profitswap, H3.profitswap; bool SwapMode = true, allmeetcor = false, BlockOpen = false, buy,sell,cleared = false; string H1.string = "", H2.string = "", H3.string = "", OrdComment = "", candletxt,tdstxt = "";
مرحله سوم: دریافت تمام پارامترهای آماری مورد نیاز
اکنون بیایید بعضی از مقادیر (values) آماری که در قسمت init() ثبت میشوند را مشخص کنیم.
//+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- BSP = MarketInfo(BaseSymbol,MODE_SPREAD); HSP = MarketInfo(H_Symbol ,MODE_SPREAD); BPt = MarketInfo(BaseSymbol,MODE_POINT); HPt = MarketInfo(H_Symbol ,MODE_POINT); BSwapL = MarketInfo(BaseSymbol,MODE_SWAPLONG); BSwapS = MarketInfo(BaseSymbol,MODE_SWAPSHORT); HSwapL = MarketInfo(H_Symbol,MODE_SWAPLONG); HSwapS = MarketInfo(H_Symbol,MODE_SWAPSHORT); //---- return(0); }
مرحله چهارم: توابع کاربردی
قبل از اینکه جذابترین بخش کار که منتظرش هستیم، یعنی تابع “start()”، را اِستارت بزنیم، بیایید با توابعی شروع کنیم که در این اکسپرت از آنها استفاده شدهاست. اما لطفاً توجه داشته باشید که تمامی این توابع خارج از تابع start() خواهند بود.
- تابع همبستگی
ابتدا نیاز داریم با توابعِ محاسباتیِ همبستگی آغاز کنیم. توابع زیر برای فردی است که ابتدا از آنها استفاده کرده و سپس اندیکاتور همبستگی (igorad2004@list.ru)را رایگان در اختیار عموم گذاشته و من نیز آنها را برای استفاده در این اکسپرت، سادهسازی کردهام، و اینگونه دیگر نیازی به فراخوانی مقدار همبستگی از اندیکاتور خارجی نداریم. ایدهی خوبیست، نه؟
//+------------------------------------------------------------------+ //| CORRELATION | //+------------------------------------------------------------------+ double symboldif(string symbol, int shift) { return(iClose(symbol, 1440, shift) - iMA(symbol, 1440, CorPeriod, 0, MODE_SMA, PRICE_CLOSE, shift)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double powdif(double val) { return(MathPow(val, 2)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double u(double val1,double val2) { return((val1*val2)); } //+------------------------------------------------------------------+ //| The real correlation function to call is here. | //+------------------------------------------------------------------+ double Cor(string base, string hedge) { double u1=0,l1=0,s1=0; for(int i = CorPeriod - 1; i >= 0; i--) { u1 += u(symboldif(base, i), symboldif(hedge, i)); l1 += powdif(symboldif(base, i)); s1 += powdif(symboldif(hedge, i)); } if(l1*s1 > 0) return(u1 / MathSqrt(l1*s1)); } //+------------------------------------------------------------------+
متغیرCorPeriod را بهعنوان یک متغیر ورودی، خارج میکنیم تا اجازهی تغییر آن را داشته باشیم. وقتی میخواهید همبستگی بین دو اَرز را محاسبه کنید، فقط کافیست تابع Cor(string base,string hedge) را فرا بخوانید، مانند این Cor(EURJPY,GBPJPY). کار سادهایست…
- تابع ارسال هج (Send Hedge Function)
بهنظرم سادهتر این است که چگونگی ارسال معاملات هج را با ساختن تابعSendH ، مدیریت کنیم.
//+------------------------------------------------------------------+ //| SEND HEDGE | //+------------------------------------------------------------------+ bool SendH(string symbol, int op, double lots, double price, int sp, string comment, int magic) { if(OrderSend(symbol , op , lots , price , sp , ۰ , ۰ , comment , magic , ۰ , CLR_NONE) > 0) { return(true); if(PlayAudio) PlaySound("expert.wav"); } else { Print(symbol, ": ", magic, " : " , ErrorDescription(GetLastError())); return(false); } } //+------------------------------------------------------------------+
میتوانید از این لینک درمورد تابعOrderSend بیشتر بخوانید.
تابع ErrorDescription(GetLastError())که در بالا آمده است، اجازه میدهد اکسپرت ما به ما بگوید هنگامی که تابع ترید مشغول به کار بوده، چه خطایی رخ داده است. برای استفاده از آن باید فایل stdlib.mqh را با استفاده از کد زیر، جایگذاری کنیم:
//+------------------------------------------------------------------+ //| MyHedge.mq4 | //| myHedge | //| http://dailyh.blogspot.com/ | //+------------------------------------------------------------------+ #property copyright "myHedge" #property link "http://dailyh.blogspot.com/" #include <stdlib.mqh> //+------------------------------------------------------------------+
و برای استفاده از آن، تابع ErrorDescription() را، همانطور که در بالا نشان داده شد، فرا بخوانید.
- تابع بستن هج
فراتر از ارسال معاملات، نیاز به تابعی داریم که تمام معاملات هج را وقتی به سود مورد نظر ما رسیدند، ببندد.
و در اینجا آن را مشاهده میکنید:
//+------------------------------------------------------------------+ //| CLOSE HEDGE | //+------------------------------------------------------------------+ bool CloseHedge(int magic) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == magic) { if(OrderClose(OrderTicket() , OrderLots() , OrderClosePrice() , MarketInfo(OrderSymbol(), MODE_SPREAD) , CLR_NONE)) SResult = true; } } if(SResult) { return(true); if(PlayAudio) { PlaySound("ok.wav"); } } else Print("CloseHedge Error: ", ErrorDescription(GetLastError())); RefreshRates(); // return(0); } //+------------------------------------------------------------------+
این تابع فقط معاملاتی را میبندد که عدد جادویی مشابه دارند؛ به این معنی که در کار معاملات هجی که دیگر اعداد جادویی را دارند، دخالت نمیکند. چیزی نیست که نگران آن باشید. قبل از استفاده از این تابع [برای] بستن معاملات، باید تعریف کنیم که “اکنون چقدر داریم”، آنهم با تابع زیر.
- تابع یافتن سود کلی
//+------------------------------------------------------------------+ //| TOTAL PROFIT | //+------------------------------------------------------------------+ double TotalCurProfit(int magic) { double MyCurrentProfit = 0; for(int cnt = 0 ; cnt < OrdersTotal() ; cnt++) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber() == magic) { MyCurrentProfit += (OrderProfit() + OrderSwap()); } } return(MyCurrentProfit); } //+------------------------------------------------------------------+
همانند تابعِ بستن معاملات، برای دانستن سود هج، فقط باید معاملاتی را رصد کنیم که عدد جادویی یکسانی دارند، تا بتوانیم آنها را دُرست ببندیم. برای استفاده، آنها را مانند زیر کدنویسی کنید:
if(TotalCurProfit(318) > 100) CloseHedge(318);
تمام مقادیر سود به دلار آمریکا محاسبه شدهاند. از خط بالا درمییابیم که وقتی سود کلی معاملاتی که عدد جادویی آنها ۳۱۸ است، بیش از ۱۰۰ دلار باشد، آن معاملات بسته خواهند شد. همین. برای باز کردن معاملات هج باید بدانیم که هیچ معاملهی دیگری در همان اَرز و با همان عدد جادویی، در حال حاضر باز، وجود ندارد. این کار را میتوان با این تابع انجام داد.
- دریافت حجم پوزیشنهای موجود
//+------------------------------------------------------------------+ //| EXISTING POSITIONS | //+------------------------------------------------------------------+ int ExistPositions(string symbol, int magic) { int NumPos = 0; for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == symbol && OrderMagicNumber() == magic) { NumPos++; } } return(NumPos); } //+------------------------------------------------------------------+
میتوان بدین شکل از آن استفاده کرد:
ExistPositions("GBPJPY",318)
این تابع، این را به ما برمیگرداند که در لحظه “چه تعداد معاملهی باز GBPJPY با عدد جادویی ۳۱۸ وجود دارد”. یک تابع دیگر هم داریم برای تعریف نوع معاملات باز.
- پیدا کردن نوع معامله در پوزیشن مشخصشدهی موجود
//+------------------------------------------------------------------+ //| EXISTING OP POSITION | //+------------------------------------------------------------------+ int ExistOP(string symbol, int magic) { int NumPos = -1; for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == symbol && OrderMagicNumber() == magic) { NumPos = OrderType(); } } return(NumPos); } //+------------------------------------------------------------------+
این تابع مقدار صحیح نوع معامله، برای اَرز و عدد جادویی مشخصشده، که در لحظه باز هستند، را به ما برمیگرداند. اگر معاملهی باز GBPJPY، OP_BUY باشد، مقدار برگشتی صفر خواهد بود. این تابع فقط با تابع ترید کار نمیکند، بلکه با تابعی که وضعیت هجینگ کنونی را نشان میدهد هم کار میکند. این تابع را “OP2Str” مینامند.
- نشان دادن وضعیت ترید
//+------------------------------------------------------------------+ //| Transform OP Value To string | //+------------------------------------------------------------------+ string OP2Str(int op) { switch(op) { case OP_BUY : return("BUY"); case OP_SELL: return("SELL"); default : return("~~"); } } //+------------------------------------------------------------------+
چیز خاصی برای گفتن نداریم. خود تابع گویای نحوهی عملکرد خود است.
- بستن تمام انواع معاملات مشخصشده
این هم یک تابع دیگر است برای بستن مستقیم فقط یک معامله (فرقی نمیکند چه نوع معاملهای باشد)، درصورتیکه هنگام ارسال یا بستن هج، خطایی رخ دهد.
//+------------------------------------------------------------------+ //| CLOSE SCRAP | //+------------------------------------------------------------------+ bool CloseScrap(string sym, int op, int magic) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && amp; OrderMagicNumber() == magic && OrderSymbol() == sym && OrderType() == op) { if(OrderClose(OrderTicket() , OrderLots() , OrderClosePrice() , MarketInfo(OrderSymbol(), MODE_SPREAD) , CLR_NONE)) BResult = true; } } if(BResult) { return(true); if(PlayAudio) { PlaySound("ok.wav"); } } else Print("CloseScrap Error: ", ErrorDescription(GetLastError())); RefreshRates(); // return(0); }
نگاه کنید به CloseScrap(“GBPJPY”,OP_BUY,318): این [تابع] فقط معاملهی بلندمدت GBPJPY با عدد جادویی ۳۱۸ را میبندد. ساده است… یک تابع دیگر هم برای آشنایی با آن داریم.
- نشان دادن هر وضعیت منطقیای[۳] که شما میخواهید
//+------------------------------------------------------------------+ //| Translate bool to string | //+------------------------------------------------------------------+ string bool2str( bool boolval) { if(boolval == true) return("Yes"); if(boolval == false) return("No"); } //+------------------------------------------------------------------+
چیز پیچیدهای نیست. این تابع وضعیت منطقی بعضی از پارامترها، مانند مقدار BlockOpening را نشان میدهد. وقتی آن را true تعیین میکنید، این تابع روی صفحهی نمایش Yes را به شما نشان میدهد. و وقتی آن را false تعیین میکنید، روی صفحهی نمایش No نشان داده میشود. تمام مطلب همین است. پس بیایید از فرآیند کدنویسی هج لذت ببریم.
مرحله پنجم: هستهی اکسپرت
ابتدا با این شروع کنید:
//+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() {
سپس دامنهی همبستگی را مشخص کنید.
if(Cor(BaseSymbol, H_Symbol) > Between || Cor(BaseSymbol, H_Symbol) < And) // Block opening when the correlation is out of // expected range. BlockOpen = true; else BlockOpen = false;
پس از آن مسیر هج را مشخص کنید (این فقط یک مثال است)، در این مقاله من سبک ترید خود را با مقدار سوآپ انتخاب میکنم، سپس فقط به روشی که بتوانم از سوآپ هر روز درآمد داشته باشم، ترید خواهم کرد.
// if they move the same way we will open long & short if(MoveSameWay) { if(((BSwapL*BaseLotSize) + (HSwapS*H_LotSize)) > 0) { BOP = OP_BUY; HOP = OP_SELL; } else if(((BSwapS*BaseLotSize) + (HSwapL*H_LotSize)) > 0) { BOP = OP_SELL; HOP = OP_BUY; } } // end MoveSameWay // if the move the opposite way we will open short & short or long & long else { if(((BSwapL*BaseLotSize) + (HSwapL*H_LotSize)) > 0) { BOP = OP_BUY; HOP = OP_BUY; } else if(((BSwapS*BaseLotSize) + (HSwapS*H_LotSize)) > 0) { BOP = OP_SELL; HOP = OP_SELL; } }
اکنون زمان ارسال هج رسیده است:
// if they meet the correlation range and // you're not blocking them if(!BlockOpen && !BlockOpening) { if(BOP == OP_BUY) // define the opening price BaseOpen = MarketInfo(BaseSymbol, MODE_ASK); else BaseOpen = MarketInfo(BaseSymbol, MODE_BID); if(HOP == OP_BUY) HOpen = MarketInfo(H_Symbol, MODE_ASK); else HOpen = MarketInfo(H_Symbol, MODE_BID); // In case there is no any swap condition to gain // from BOP & HOP will be -1. if(BOP >= 0 && HOP >= 0) { if(ExistPositions(BaseSymbol, MagicNo) == 0 && ExistPositions(H_Symbol, MagicNo) == 0) { SendH(BaseSymbol, BOP, BaseLotSize, BaseOpen, BSP, "COR : " + DoubleToStr(Cor(BaseSymbol, H_Symbol), 2), MagicNo); SendH(H_Symbol, HOP, H_LotsSize, HOpen, HSP, "COR : " + DoubleToStr(Cor(BaseSymbol, H_Symbol), 2), MagicNo); } else // in case ping failed or requote { if(ExistPositions(BaseSymbol, MagicNo) == 1&& TotalCurProfit(MagicNo)>AcceptableLoss$) { CloseScrap(BaseSymbol, ExistOP(BaseSymbol, MagicNo), MagicNo); } else if(ExistPositions(H_Symbol, MagicNo) == 1&& TotalCurProfit(MagicNo) > AcceptableLoss$) { CloseScrap(H_Symbol, ExistOP(H_Symbol, MagicNo), MagicNo); } } } else // if one of BOP and HOP is less than 0 { string swaptxt = "No Swap Condition To Gain From :" + "pls modify one or more input parameter(s)."; } }
سپس آنها را وقتی که به سود مورد نظر میرسند، ببندید.
if((TotalCurProfit(MagicNo) > ExpectProfit$) { CloseHedge(MagicNo); }
و یک چیز جالبتر: بخشShowStatus .
if(ShowStatus) { Comment("\nCorrel: " + DoubleToStr(Cor(BaseSymbol , H_Symbol), 2) , "\nBlockOpen : " + bool2str(BlockOpen || BlockOpening) , "\n" + swaptxt , "\n~~~~~~~" , "\nB/H [sp] : " + BaseSymbol + " [" + BSP + "]" + " / " + H_Symbol+" ["+HSP+"]" , "\nCurOp [Lots]: " + OP2Str(ExistOP(BaseSymbol, MagicNo)) + " [" + DoubleToStr(BaseLotSize, 2) + "]" + " ~ " + OP2Str(ExistOP(H_Symbol, MagicNo)) + " [" + DoubleToStr(H_LotsRatio*BaseLotSize, 2) + "]" , "\nCurPF [Expect]: $" + DoubleToStr(TotalCurProfit(MagicNo), 2) + " [$"+DoubleToStr(ExpectProfit$, 2) + "]"); } else Comment("");
و پایان هر اکسپرت.
return(0); }
مرحله ششم: سَرِهمکردن همهچیز
در اینجا میبینید که myHedge.mq4 من این شکلی خواهد بود:
//+------------------------------------------------------------------+ //| MyHedge.mq4 | //| myHedge | //| http://dailyh.blogspot.com/ | //+------------------------------------------------------------------+ #property copyright "myHedge" #property link "http://dailyh.blogspot.com/" //---- #include <stdlib.mqh> // this is to block the order sending function but not to block the // close function. extern bool BlockOpening = false; extern string BaseSymbol = "EURJPY"; // the 1st symbol extern string H_Symbol = "GBPJPY"; // the 2nd symbol extern bool MoveSameWay = true; // they move the same way or not extern int CorPeriod = 5; // your favorite correlation period extern double BaseLotSize = 1.5; // 1st symbol lotsize extern double H_LotSize = 1.0; // 2nd symbol lotsize extern double ExpectProfit$ = 137; // your expect profit in USD // your acceptable loss in USD in case any error occurred extern double AcceptableLoss$ = -77; extern string ExpectCor = "______"; // your expect correlation to // hedge this is the upper expect cor value and has to be greater // than "And" extern double Between = 1.05; extern double And = 0.9; // this is the lower expect cor level extern string MISC = "______"; // some thing more extern int MagicNo = 318; // your favorite magic number extern bool ShowStatus = true; // to show the present hedging status // to play sound when SendH and CloseH function done extern bool PlayAudio = false; //---- int BSP // the spread of base symbol ,HSP // the spread of hedge symbol ,gsp ,BOP = -1 // base symbol order type ,HOP = -1 // hedge symbol order type ,up = 0 ,Hcnt = 0 ,u = 0 ,d = 0 ,day = 0 ,sent = 0 ,firstopen ,expire; double Lot ,BaseOpen // base symbol order open price ,HOpen // hedge symbol order open price ,BPt // base symbol Point value ,HPt // hedge symbol Point value ,BSwapL // base symbol swap long value ,BSwapS // base symbol swap short value ,HSwapL // hedge symbol swap long value ,HSwapS; // hedge symbol swap short value bool SResult = false, BResult = false, H1.profitswap, H2.profitswap, H3.profitswap; bool SwapMode = true, allmeetcor = false, BlockOpen = false, buy, sell, cleared = false; string H1.string = "", H2.string = "", H3.string = "", OrdComment = "", candletxt,tdstxt = ""; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { BSP = MarketInfo(BaseSymbol, MODE_SPREAD); HSP = MarketInfo(H_Symbol, MODE_SPREAD); //---- BPt = MarketInfo(BaseSymbol, MODE_POINT); HPt = MarketInfo(H_Symbol, MODE_POINT); //---- BSwapL = MarketInfo(BaseSymbol, MODE_SWAPLONG); BSwapS = MarketInfo(BaseSymbol, MODE_SWAPSHORT); //---- HSwapL = MarketInfo(H_Symbol, MODE_SWAPLONG); HSwapS = MarketInfo(H_Symbol, MODE_SWAPSHORT); //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { if(Cor(BaseSymbol, H_Symbol) > Between || Cor(BaseSymbol, H_Symbol) < And) // Block opening when the correlation is out of expected range. BlockOpen = true; else BlockOpen = false; //---- if(MoveSameWay) { if((BSwapL*BaseLotSize) + (HSwapS*H_LotSize) > 0) { BOP = OP_BUY; HOP = OP_SELL; } else if((BSwapS*BaseLotSize) + (HSwapL*H_LotSize) > 0) { BOP = OP_SELL; HOP = OP_BUY; } } else { if((BSwapL*BaseLotSize) + (HSwapL*H_LotSize) > 0) { BOP = OP_BUY; HOP = OP_BUY; } else if((BSwapS*BaseLotSize) + (HSwapS*H_LotSize) > 0) { BOP = OP_SELL; HOP = OP_SELL; } } if(!BlockOpen && !BlockOpening) { if(BOP == OP_BUY) BaseOpen = MarketInfo(BaseSymbol, MODE_ASK); else BaseOpen = MarketInfo(BaseSymbol, MODE_BID); if(HOP == OP_BUY) HOpen = MarketInfo(H_Symbol, MODE_ASK); else HOpen = MarketInfo(H_Symbol, MODE_BID); // In case there is no any swap condition that we can gain from. if(BOP >= 0 && HOP >= 0) { if(ExistPositions(BaseSymbol, MagicNo) == 0 && ExistPositions(H_Symbol,MagicNo) == 0) { SendH(BaseSymbol, BOP, BaseLotSize, BaseOpen, BSP, "COR : " + DoubleToStr(Cor(BaseSymbol, H_Symbol), ۲), MagicNo); SendH(H_Symbol, HOP, H_LotSize, HOpen, HSP, "COR : " + DoubleToStr(Cor(BaseSymbol, H_Symbol), 2), MagicNo); } else // in case ping failed or requote { if(ExistPositions(BaseSymbol, MagicNo) == 1 && TotalCurProfit(MagicNo) > AcceptableLoss$) { CloseScrap(BaseSymbol, ExistOP(BaseSymbol, MagicNo), MagicNo); } else if(ExistPositions(H_Symbol, MagicNo) == 1 && TotalCurProfit(MagicNo) > AcceptableLoss$) { CloseScrap(H_Symbol, ExistOP(H_Symbol, MagicNo), MagicNo); } } } else { string swaptxt = "No Swap Condition To Gain From : pls " + "modify one or more input parameter(s)."; } } if(TotalCurProfit(MagicNo) > ExpectProfit$) { CloseHedge(MagicNo); } if(ShowStatus) { Comment("\nCorrel: "+DoubleToStr(Cor(BaseSymbol, H_Symbol), 2) , "\nBlockOpen : " + bool2str(BlockOpen || BlockOpening) , "\n" + swaptxt , "\n~~~~~~~" , "\nB/H [sp] : " + BaseSymbol + " [" + BSP + "]" + " / " + H_Symbol + " [" + HSP + "]" , "\nCurOp [Lots]: " + OP2Str(ExistOP(BaseSymbol, MagicNo)) + " [" + DoubleToStr(BaseLotSize, 2) + "]" + " ~ " + OP2Str(ExistOP(H_Symbol, MagicNo)) + " [" + DoubleToStr(H_LotSize, 2) + "]" , "\nCurPF [Expect]: $" + DoubleToStr(TotalCurProfit(MagicNo), 2) + " [$" + DoubleToStr(ExpectProfit$, 2) + "]"); } else Comment(""); return(0); } //+------------------------------------------------------------------+ //| CORRELATION | //+------------------------------------------------------------------+ double symboldif(string symbol, int shift) { return(iClose(symbol, 1440, shift) - iMA(symbol, 1440, CorPeriod, 0, MODE_SMA, PRICE_CLOSE, shift)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double powdif(double val) { return(MathPow(val, 2)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double u(double val1, double val2) { return((val1*val2)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double Cor(string base, string hedge) { double u1 = 0, l1 = 0, s1 = 0; for(int i = CorPeriod - 1; i >= 0; i--) { u1 += u(symboldif(base, i), symboldif(hedge, i)); l1 += powdif(symboldif(base, i)); s1 += powdif(symboldif(hedge, i)); } if(l1*s1 > 0) return(u1 / MathSqrt(l1*s1)); } //+------------------------------------------------------------------+ //| SEND HEDGE | //+------------------------------------------------------------------+ bool SendH(string symbol, int op, double lots, double price, int sp, string comment, int magic) { if(OrderSend(symbol ,op ,lots ,price ,sp ,۰ ,۰ ,comment ,magic ,۰ ,CLR_NONE) >0) { return(true); if(PlayAudio) PlaySound("expert.wav"); } else { Print(symbol, ": ", magic, " : " ,ErrorDescription(GetLastError())); return(false); } } //+------------------------------------------------------------------+ //| CLOSE HEDGE | //+------------------------------------------------------------------+ bool CloseHedge(int magic) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == magic) { if(OrderClose(OrderTicket() , OrderLots() , OrderClosePrice() , MarketInfo(OrderSymbol(), MODE_SPREAD) , CLR_NONE)) SResult = true; } } if(SResult) { return(true); if(PlayAudio) { PlaySound("ok.wav"); } } else Print("CloseHedge Error: ", ErrorDescription(GetLastError())); RefreshRates(); // return(0); } //+------------------------------------------------------------------+ //| TOTAL PROFIT | //+------------------------------------------------------------------+ double TotalCurProfit(int magic) { double MyCurrentProfit = 0; for(int cnt = 0; cnt < OrdersTotal(); cnt++) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber() == magic) { MyCurrentProfit += (OrderProfit() + OrderSwap()); } } return(MyCurrentProfit); } //+------------------------------------------------------------------+ //| EXISTING POSITION | //+------------------------------------------------------------------+ int ExistPositions(string symbol,int magic) { int NumPos = 0; for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == symbol && OrderMagicNumber() == magic) { NumPos++; } } return(NumPos); } //+------------------------------------------------------------------+ //| EXISTING OP POSITION | //+------------------------------------------------------------------+ int ExistOP(string symbol,int magic) { int NumPos = -1; for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderSymbol() == symbol && OrderMagicNumber() == magic) { NumPos = OrderType(); } } return(NumPos); } //+------------------------------------------------------------------+ //| Transform OP Value To string | //+------------------------------------------------------------------+ string OP2Str(int op) { switch(op) { case OP_BUY : return("BUY"); case OP_SELL: return("SELL"); default : return("~~"); } } //+------------------------------------------------------------------+ //| CLOSE SCRAP | //+------------------------------------------------------------------+ bool CloseScrap(string sym,int op,int magic) { for(int i = OrdersTotal() - 1; i >= 0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == magic && OrderSymbol() == sym && OrderType() == op) { if(OrderClose(OrderTicket() , OrderLots() , OrderClosePrice() , MarketInfo(OrderSymbol(), MODE_SPREAD) , CLR_NONE)) BResult = true; } } if(SResult || BResult) { return(true); if(PlayAudio) { PlaySound("ok.wav"); } } else Print("CloseScrap Error: ", ErrorDescription(GetLastError())); RefreshRates(); // return(0); } //+------------------------------------------------------------------+ //| Translate bool to string | //+------------------------------------------------------------------+ string bool2str(bool boolval) { if(boolval == true) return("Yes"); if(boolval == false) return("No"); } //+------------------------------------------------------------------+
نتیجهگیری
این فقط یک مثال ساده از اکسپرت هج بود. قطعاً باید آن را منطبق با نیازها و سبک خود، تغییر دهید. مطمئناً سبکها (استراتژیهای) بسیاری وجود دارند که به شما کمک میکنند. توجه داشته باشید که این نوع اکسپرت را بهخاطر محدودیتهایش نمیتوانید با استراتژیتستر، تست کنید. فقط باید آن را در شرایط واقعی امتحان کرد. مثالی از نتیجهی تست یک اکسپرت هج را مشاهده میکنید:
و تابع ShowStatus هم چنین چیزی را به شما خواهد داد:
امیدوارم از این مقاله لذت برده باشید و بتوانید اکسپرت هج خود را، عالی بسازید.
این مقاله دارای فایل پیوست است.
[۱]) هج “hedge” یعنی همپوشانی. اگر روی یک اَرز، با حجم یکسان و در همان تایمفریم، دو معامله، یکی buy و یکی sellهمزمان باز کنیم، آنگاه اصطلاحاً معاملهی hedge یا معاملهی همپوشانی باز کردهایم.
[۲]) فروش موقت یعنی فروختن چیزی موقتاً، با این قصد که بعداً دوباره آن را با قیمت پایینتر بخریم.
[۳]) Boolean (bool) دادههای بولی یا همان دادههای منطقی
۲۳ مورد نظر
medications for ed
cialis over the counter in spain cialis usa prescription buy cialis viagra
stromectol 3 mg for scabies ivermectin for foxes pour on ivermectin for cats
cheap pet meds without vet prescription treatment of ed comfortis for dogs without vet prescription
prednisone for sale without a prescription buy prednisone online canine prednisone 5mg no prescription
cialis reviews patients purchasing cialis in the usa cialis and viagra together forum
how to purchase prednisone online generic prednisone where can i order prednisone 20mg
ivermectin 8 mg durvet ivermectin sheep drench does simparica trio have ivermectin
finasteride hair propecia 5 mg for sale buy propecia tablets
propecia drug buy finasteride propecia without a doctor prescription
amoxicillin without a doctor’s prescription ed meds online without prescription or membership buy anti biotics without prescription
ivermectin injectable dosage for sheep maximum dose of ivermectin oral ivermectin
online prescription for ed meds buy prescription drugs without doctor buy canadian drugs
propecia 5 mg for sale propecia without prescription generic propecia usa
comfortis for dogs without vet prescription ed meds online without prescription or membership prescription drugs canada buy online
order prescriptions online without doctor highest rated canadian pharmacies pharmacy without dr prescriptions
prescription drugs without doctor approval buying from canadian online pharmacies pharmacy without dr prescriptions
discount prescription drugs online prescription drugs without doctor approval canadian pharmacy online ship to usa
clomid tablets for sale where to buy cheap clomid online buy clomid
stromectol without a doctor prescription stromectol for sale ivermectin without a doctor prescription
stromectol stromectol pills for humans prescribing stromectol
stromectol 12 mg tablets prescribing stromectol stromectol 12 mg tablets
stromectol stromectol for humans for sale prescribing stromectol