اصول بسته سهام معامله از خیلی وقت پیش ها شناخته شده است. با تقسیم سرمایه در چندین جهت، سرمایه گذاران بسته سهام خود را می سازند تا خطر زیان کلی را کاهش داده و رشد درآمد را بیشتر سازند. تئوری بسته سهام در ساله 1950 به محبوبیت رسید وقتی که اولین مدل ریاضی بسته سهام توسط Harry Markowitz ارائه شد. در دهه 1980، یک گروه تحقیقاتی از Morgan Stanley اولین استراتژی معامله گسترده را ارائه دادند که راهی برای گروهی از استراتژی خنثی باز روشن ساخت. تئوری بسته سهام معامله حال حاضر متنوع و پیچیده است که تقریبا توضیح تمام استراتژی های بسته سهام را در یک مقاله غیرممکن می نماید. بنابراین، فقط محدوده کوچکی از استراتژی های پرخطر به همراه اجرای احتمالی آنها در پلات فرم MetaTrader 4 در اینجا در نظر گرفته می شود.
بیشتر بخوانید: آموزش متوسطه mql4
بعضی از تعاریف اعمال شده در این مقاله به شرح زیر است:
- بسته سهام (سبد، ابزار مصنوعی)- دسته ای از موقعیت ها در چندین ابزار معامله با حجم های دلخواه محاسبه شده. موقعیت ها برای مدتی باز باقی می مانند، به عنوان یک آیتم ردیابی می شوند و توسط بعضی از نتایج اقتصادی معمول بسته می شوند.
- تنظیم بسته سهام (سبد، ابزار مصنوعی)- تغییر دسته ای از ابزارهای بسته سهام و یا حجم آنها به منظور کاهش زیان ها یا بهبود نتایج واسطه.
- حجم مصنوعی- تعداد موقعیت های مصنوعی (تعداد دفعاتی که بسته سهام خریده یا فروخته می شود).
- سود/زیان مجازی- نتیجه اقتصادی که می تواند حاصل شود وقتی که یک موقعیت در چند فاصله زمانی باشد.
بسته سهام سرمایه ای کلاسیک معمولا در بازارهای سهام اعمال می شوند. با این وجود، چنین رویکردی خیلی مناسب فارکس نیست چرا که اکثر بسته های سهام در اینجا پرخطر می باشند. آنها کمی متفاوت تر ساخته و معامله می شوند. تا آنجاییکه به فارکس مربوط می شود، معامله بسته سهام عملا یک معامله چند ارزی است، با این وجود تمامی استراتژی های چند ارزی از نوع بسته سهام نیستند. اگر نمادها مستقلا معامله شوند و دینامیک نتیجه نهایی ردیابی نشود، یک معامله چند نمادی خواهد بود. اگر چندین سیستم مستقل بر روی یک حساب معاملاتی منفرد معامله می کنند، یک استراتژی بسته سهام می باشد. در اینجا یک معامله بسته سهام به مفهوم دقیق را کلمه در نظر می گیریم- وقتی که موقعیت مصنوعی از چندین نماد تشکیل شود و بعد از آن مدیریت می شود.
اصول بسته سهام معامله
توسعه بسته سهام معامله دو مرحله است: انتخاب نمادها و محاسبه سهم ها و جهت آنها. در اینجا فقط درباره چند روش توسعه بسته سهام ساده به همراه نمونه های الگوریتمی بحث می کنیم. مخصوصا، روش کوچکترین مریعات معمولی (OLS) و تحلیل مولفه اصلی (PCA) را به عنوان مبانی امر ارائه می دهیم. اطلاعات بیشتر می توانند در اینجا به دست آیند:
- کمترین مربعات
- تحلیل مولفه اصلی (PCA)
وقتی یک بسته سهام معامله ارائه می دهیم، معمولا باید رفتار گراف بسته سهام موردنظر را تعریف کنیم. گراف بسته سهام تغییرات سود کل تمام موقعیت ها را شامل بسته سهام درون بعضی از فواصل زمانی ارائه می دهد. بهینه سازی بسته سهام تحقیقی برای ترکیب سهم ها و بهترین جهت منطبق بر رفتار بسته سهام دلخواه می باشد. به عنوان مثال، بر اساس مورد ما، شاید لازم باشد که بسته سهام یک تکرار به مقدار متوسط یا حاوی یک روند مشخصا واضح باشد یا نمودارش می بایست مشابه یک نمودار تابع باشد.
سه نوع بسته سهام (متمایل، مسطح، تابعی) عبارتند از:
شکل اول
یک بسته سهام می تواند توسط معادله زیر ارائه شود:
A*k1 + B*k2 + C*k3 + … = F
که در آن
A، B، C … سری های زمانی مرتبط با نماد های بسته سهام می باشند.
K1، k2، k3 … نماد سهم ها می باشند (مثبت- خرید، منفی-فروش)
F تابع هدف (توسط مقادیر نقاط سری های زمانی تنظیم می شود).
این یک معادله رگرسیون خطی چندمتغیره با یک عبارت ثابت صفر می باشد. ریشه های آن می تواند به راحتی با استفاده از OLS به دست آیند. اول از همه، سری های زمانی باید قابل مقایسه ساخته شوند بدین معنی که نقاط قیمت باید به یک ارز وثیقه آورده شوند. در این مورد، هر المان سری های زمانی نماینده مقدار سود مجازی یک سهم منفرد نماد مناسب در یک زمان خاص می باشد. لگاریتم قیمت ابتدایی یا استفاده از اختلاف قیمت معمولا در موارد کاربرد آماری پیشنهاد می شوند. با این وجود، این امر در مورد ما شاید غیر لازم و حتی مضر باشد چرا که داده های دینامیک نمادهای کل بحرانی در طول مسیر از بین خواهند رفت.
تابع هدف نوع گراف بسته سهام را تعریف می نماید. در نتیجه مقادیر تابع هدف باید از ابتدا در هر نقطه محاسبه شوند. به عنوان مثال، هنگام ایجاد یک بسته سهام صعودی ساده (بسته سهام متمایل)، بسته سهام هدف مقادیر 0، 1*S، 2*S، 3*S و غیره خواهد داشت، که در آن S یک نمو می باشد- ارزش پول برای بسته سهام در هر میله روی یک فاصله از پیش تعیین شده باید افزایش یابد. الگوریتم OLS سری های زمانی A، B، C و … را به گونه ای اضافه می کند که جمع کلی آنها به نظر می رسد که نمودار تابع هدف را تکرار می کنند. برای رسیدن به این هدف، الگوریتم OLS مجموع مربع انحرافات بین جمع جمع سری ها و تابع هدف را به حداقل می رساند. این یک امر آماری استاندارد است. هیچ فهم دقیقی از عمل الگوریتم لازم نیست چرا که می توانید از یک کتابخانه آماده به کار استفاده کنید.
همچنین شاید اتفاق بیافتد که تابع هدف فقط حاوی مقادیر صفر (بسته سهام مسطح) باشد. در این مورد، یک حد مجموع نسبی اضافی باید (مثلا: k1+k2+k3+…=1) اضافه شود تا حل معادله رگرسیون با ریشه های صفر را کنار بگذارد. راه دیگر این است که یک عبارت معادله به سمت راست انتقال یابد تا آن را یک تابع هدف با تناسب -1 بسازد در حالی که بقیه عبارات طبق معمول بهینه می شوند. در این مورد، ما سبد ابزارها را با یک ابزار منتخب معادل سازی می نماییم، در نتیجه یک بسته سهام پراکنده می سازیم. در نهایت، الگوریتم PCA پیشرفته تر می تواند برای ایجاد چنین بسته سهام هایی استفاده شود. این الگوریتم ماتریس کوواریانس ابزار را برای محاسبه بردار ضریب مربوط به سطح مقطع ابری هایپرلان نقطه دارای واریانس مینیمم بسته سهام اعمال می کند. مجددا، لازم نیست که جزئیات الگوریتم را در اینجا بدانید چرا که می توانیم از کتابخانه آماده به کار استفاده کنیم.
الگوریتم ها
حال وقت آن است که تمام نظریات فوق الذکر با استفاده از زبان MQL اجرا شود. ما از کتابخانه ریاضی ALGLIB شناخته شده و منطبق با MT4 استفاده خواهیم کرد. گاهی اوقات، مسائلی شاید در طول نصب آن پیش بیاید، بنابراین بیشتر روی آن متمرکز می شویم. اگر چندین ترمینال بر روی یک PC نصب شوند، خیلی مهم است که پوشه داده های صحیح را پیدا کنیم چرا که کامپایلر کتابخانه را نمی بیند اگر در یک پوشه داده ترمینال دیگر قرار بگیرد.
نصب کتابخانه ALGLIB:
- کتابخانه را از آدرس (https://www.mql5.com/en/code/11077) دانلود و فایل فشرده را باز کنید.
- پوشه include را باز کنید و درون آن دایرکتوری Math را پیدا کنید؛
- پلاتفرم MetaTrader 4، که کتابخانه باید به آن اضافه شود، راه اندازی نمایید؛
- دستور منو را انتخاب کنید: File — Open Data Folder؛
- زیر پوشه MQL4 و Include را باز کنید؛
- پوشه Math را داخل پوشه Include ترمینال کپی کنید؛
- نتیجه را بررسی کنی: فایل های *.mhq باید درون MQL4\Include\Math\Alglib باشند.
اولین مرحله اصلی: تبدیل سری های زمانی از نقاط قیمت به ارز وثیقه. برای این کار، می بایست تابع مخصوصی را برای محاسبه قیمت قراردادی در هر زمان داده شده بنویسیم. تابع MarketInfo مرسوم خیلی مناسب این امر نمی باشد چرا که نقاط قیمت صحیح را فقط برای نمودار میله ای آخر فراهم می آورد. مسئله این است که انحراف به طور اجتناب ناپذیری در تاریخچه ظاهر می شود به گونه ای که نقاط قیمت بعضی از نمادها به طور مداوم تغییر می کند. بنابراین، خیلی حیاتی است که به طور صحیحی سری های داده ها تبدیل شوند تا از عدم تعادل های مشهود در بسته سهام اجتناب شود. تابع نمونه محاسبه کننده قیمت قرارداد در زیر نشان داده شده است:
double ContractValue(string symbol,datetime time,int period) { double value=MarketInfo(symbol,MODE_LOTSIZE); // receive lot size string quote=SymbolInfoString(symbol,SYMBOL_CURRENCY_PROFIT); // receive calculation currency if(quote!="USD") // if the calculation currency is not USD, perform conversion { string direct=FX_prefix+quote+"USD"+FX_postfix; // form a direct quote for calculation currency if(MarketInfo(direct,MODE_POINT)!=0) // check if it exists { int shift=iBarShift(direct,period,time); // find the bar by time double price=iClose(direct,period,shift); // receive the bar's quote if(price>0) value*=price; // calculate the price } else { string indirect=FX_prefix+"USD"+quote+FX_postfix; // form a reverse quote for the calculation currency int shift=iBarShift(indirect,period,time); // find the bar by time double price=iClose(indirect,period,shift); // receive the bar's quote if(price>0) value/=price; // calculate the price } } if(Chart_Currency!="USD") // if the target currency is not USD, perform a conversion { string direct=FX_prefix+Chart_Currency+"USD"+FX_postfix; // form a direct quote for the target currency if(MarketInfo(direct,MODE_POINT)!=0) // check if it exists { int shift=iBarShift(direct,period,time); // find the bar by time double price=iClose(direct,period,shift); // receive the bar's quote if(price>0) value/=price; // calculate the price } else { string indirect=FX_prefix+"USD"+Chart_Currency+FX_postfix; // form a reverse quote for the target currency int shift=iBarShift(indirect,period,time); // find the bar by time double price=iClose(indirect,period,shift); // receive the bar's quote if(price>0) value*=price; // calculate the price } } return(value); }
کد اول
این تابع همواره در آینده استفاده خواهد شد. این با جفت های ارزی، شاخص ها، آینده ها و CFD ها کار می کند. به علاوه پیشوندها و پسوندهای نمادهای (FX_prefix، FX_postfix) اعمال شده توسط بعضی از کارگزاران در نظر گرفته می شوند. نتیجه به ارز هدف (Chart_Currency) تبدیل می شود. اگر مفدار تابع برگشتی را در قیمت نماد کنونی ضرب کنیم، قیمت نماد یک سهم را به دست می آوریم. بعد از تجمیع تمام قیمت های قراردادی در بسته سهام شامل سهم، قیمت تمام بسته سهام معامله را به دست می آوریم. اگر مقدار تابع را در اختلاف قیمت در زمان ضرب می نماییم، سود و زیان تولید شده در مدت تغییر قیمت را به دست می آوریم.
مرحله بعد محاسبه سود مجازی تمام قراردادهای سهم منفرد می باشد. محاسبه توسط یک آرایه دوبعدی انجام می شود که بعد اول شاخص نقطه در فاصله محاسبه شده است در حالی که بعد دوم شاخص نماد است (اندازه بعد دوم با تعدادی از اعداد محدود می شوند که مقدار نمادها در بسته سهام مشخصا از آن تجاوز نکند):
double EQUITY[][100]; // first dimension is for bars, while the second one is for symbols
کد دوم
اول، باید قیمت های اولیه برای تمام نمادها را ذخیره کنیم (در مرز چپ فاصله محاسبه شده). سپس، اختلاف بین قیمت های اولیه و نهایی در هر نقطه از فواصل محاسبه شده و در قیمت قراردادی ضرب می شود. هر بار، با یک فاصله زمانی به سمت راست در لوپ شیفت می کنیم:
for(int i=0; i<variables+constants; i++) // portfolio symbols loop (variable and model constants) { int shift=iBarShift(SYMBOLS[i],Timeframe,zero_time); // receive bar index by time for a zero point opening[i]=iClose(SYMBOLS[i],Timeframe,shift); // receive the bar's price and save it in the array } points=0; // calculate points in the variable datetime current_time=zero_time; // start a loop from the zero point while(current_time<=limit_time) // pass along the time labels in the optimization interval { bool skip_bar=false; for(int i=0; i<variables+constants; i++) // portfolio symbol loop (variables and model constants) if(iBarShift(SYMBOLS[i],Timeframe,current_time,true)==-1) // check bar existence for the symbol skip_bar=true; // if the bar does not exist, skip it for other symbols if(!skip_bar) // continue operation if the bar is synchronized between all symbols { points++; // increase the number of points by one TIMES[points-1]=current_time; // store time label in memory for(int i=0; i<variables+constants; i++) // main profit calculation loop for all symbols in the point { int shift=iBarShift(SYMBOLS[i],Timeframe,current_time); // receive the bar index by time closing[i]=iClose(SYMBOLS[i],Timeframe,shift); // receive the bar's price double CV=ContractValue(SYMBOLS[i],current_time,Timeframe); // calculate the contract price profit[i]=(closing[i]-opening[i])*CV; // calculate profit by price difference and cost EQUITY[points-1,i]=profit[i]; // save the profit value } } current_time+=Timeframe*60; // shift to the next time interval
کد سوم
در بخش کدی بالا، zero_time- زمان فاصله محاسبه شده مرز سمت چپ، limit_time زمان فاصله محاسبه شده مرز سمت راست، Timeframe- تعداد دقایق در یک میله بازه زمانی فعال، points- تعداد کل نقاط تشخیص داده شده در فاصله زمانی محاسبه شده می باشند. قانون پذیرش محدود لیبل زمان در مثال بالا استفاده می شود. اگر یک میله برای لیبل زمان خاصی حتی در یک نماد وجود نداشته باشد، یک موقعیت صرف نظر می شود و یک شیفت به بعدی صورت می پذیرد. مدیریت لیبل های زمان برای آماده سازی داده های ابتدایی خیلی مهم است چرا که عدم تطابق داده ها روی نمادهی مختلف ممکن است که انحرافات جدی را در بسته سهام سبب شود.
داده های بسته سهام معامله نمونه برای سه نماد و یک تابع مستقل (ریشه دوم سهمی) عبارتند از:
DATE/TIME AUDJPY GBPUSD EURCAD MODEL 03.08.16 14:00 0 0 0 0 03.08.16 15:00 -61,34 -155 -230,06 10,21 03.08.16 16:00 -82,04 -433 -219,12 14,43 03.08.16 17:00 -39,5 -335 -356,68 17,68 03.08.16 18:00 147,05 -230 -516,15 20,41 03.08.16 19:00 169,73 -278 -567,1 22,82 03.08.16 20:00 -14,81 -400 -703,02 25 03.08.16 21:00 -109,76 -405 -753,15 27 03.08.16 22:00 -21,74 -409 -796,49 28,87 03.08.16 23:00 51,37 -323 -812,04 30,62 04.08.16 00:00 45,43 -367 -753,36 32,27 04.08.16 01:00 86,88 -274 -807,34 33,85 04.08.16 02:00 130,26 -288 -761,16 35,36 04.08.16 03:00 321,92 -194 -1018,51 36,8 04.08.16 04:00 148,58 -205 -927,15 38,19 04.08.16 05:00 187 -133 -824,26 39,53 04.08.16 06:00 243,08 -249 -918,82 40,82 04.08.16 07:00 325,85 -270 -910,46 42,08 04.08.16 08:00 460,02 -476 -907,67 43,3 04.08.16 09:00 341,7 -671 -840,46 44,49
جدول اول
حالا که داده های آماده را داریم، زمان آن است که آنها را به مدل بهینه سازی ارسال کنیم. بهینه سازی باید با استفاده از توابع LRBuildZ، LSFitLinearC و PCABuilBasis از کتابخانه ALGLIB انجام شود. این توابع به طور خلاصه درون کتابخانه خودش، به همراه وبسایت رسمی پروژه Http://www.alglib.net/ dataanalysis/linearregression.php و در اینجا http://www.alglib.net/dataanalysis/ principalcomponentsanalysis.php توضیح داده شده است.
اول، از بودن کتابخانه Include مطمئن شوید:
#include <Math\Alglib\alglib.mqh>
کد چهارم
سپس، بخش کدی حاوی خصوصیات مدل باید برای هر مدل بهینه سازی تنظیم شود. اول، مدل متمایل نمونه ای را امتحان می کنیم:
if(Model_Type==trend) { int info,i,j; // define working variables CLinearModelShell LM; // define a special object model CLRReportShell AR; // define a special object report CLSFitReportShell report; // define yet another object CMatrixDouble MATRIX(points,variables+1); // define a matrix for storing all data if(Model_Growth==0) { Alert("Zero model growth!"); error=true; return; } // verify the model parameters for(j=0; j<points; j++) // calculate the target function by optimization interval points { double x=(double)j/(points-1)-Model_Phase; // calculate the X coordinate if(Model_Absolute) x=MathAbs(x); // make the model symmetrical if necessary MODEL[j]=Model_Growth*x; // calculate the Y coordinate } double zero_shift=-MODEL[0]; if(zero_shift!=0) for(j=0; j<points; j++) MODEL[j]+=zero_shift; // shift the model vertically to the zero point for(i=0; i<variables; i++) for(j=0; j<points; j++) MATRIX[j].Set(i,EQUITY[j,i]); // download the symbol data to the matrix for(j=0; j<points; j++) MATRIX[j].Set(variables,MODEL[j]); // download the model data to the matrix CAlglib::LRBuildZ(MATRIX,points,variables,info,LM,AR); // launch the regression calculation if(info<0) { Alert("Error in regression model!"); error=true; return; } // check the result CAlglib::LRUnpack(LM,ROOTS,variables); // receive equation roots }
کد پنجم
در ابتدا، به نظر پیچیده می رسد اما اساسا همه چیز ساده است. در شروع، تابع افزایش خطی محاسبه و مقادیر در آرایه MODEL قرار داده می شود. پارامتر Model_Growth مقدار رشد تمام فاصله زمانی محاسبه را تنظیم می کند (مقدار، توسط بسته سهامی که در ارز وثیقه رشد می کند، معین می شود). پارامترهای Model_Absolute و Model_Phase اختیاری هستند و در مرحله حاضر بدون اهمیت هستند. ماتریس برای محاسبات ساخته می شود (MATRIX). داده های سود مجازی تمام قراردادهای آرایه EQUITY، همانند مقادیر تابع هدف از آرایه MODEL بر روی آخرین ردیف ماتریش بارگذاری می شوند. تعداد متغیرهای مستقل معادله رگرسیون در variables ذخیره می شوند. تابع LRBuildZ بعد از آن فراخوانده می شود تا محاسبات را انجام دهد. بعد از آن، ریشه های معادله رگرسیون در آرایه ROOTS با استفاده از تابع LRUnpack نوشته می شوند. تمام ریاضیات پیچیده درون کتابخانه قرار می گیرد، با اینحال می توانید از توابع آماده به کار استفاده کنید. مشکل اصلی طبیعت تکنیکال اینجا و مرتبط با تنظیمات صحیح تمام فراخوان ها و حفظ داده ها در طول آماده سازی می باشد.
همان بخش کد می تواند برای هر تابعی استفاده شود. به سادگی محتویات آرایه MODEL را با تابع هدف خود جایگزین کنید. محاسبه تابع سهمی ریشه مربع نمونه در زیر نشان داده شده است:
for(j=0; j<points; j++) // calculate the target function by optimization interval points { double x=(double)j/(points-1)-Model_Phase; // calculate the X axis value int sign=(int)MathSign(x); // define the value sign if(Model_Absolute) sign=1; // make the model symmetrical if necessary MODEL[j]=sign*Model_Growth*MathSqrt(MathAbs(x)); // calculate the Y axis value }
کد ششم
در زیر نمونه ای از تابع پیچیده تر نماینده جمع یک افزایش خطی و نوسان هارمونیک می باشد:
for(j=0; j<points; j++) // calculate the target function by optimization interval points { double x=(double)j/(points-1)*Model_Cycles-Model_Phase; // calculate the X axis value if(Model_Absolute) x=MathAbs(x); // make the model symmetrical if necessary MODEL[j]=Model_Amplitude*MathSin(2*M_PI*x); // calculate the Y axis value }
کد هفتم
در مثال فوق، احتمال دارد اندازه افزایش (با استفاده از پارامتر Model_Growth) و دامنه نوسان (با استفاده از پارامتر Model_Amplitude) مدیریت شود. تعداد سیکل های نوسان با Model_Cycles تنظیم می شود در حالی که شیفت فاز نوسان با استفاده از Model_Phase اجرا می شود.
به علاوه، شیفت عمودی باید اجرا شود تا به تابع اجازه دهد که در نقطه صفر برابر صفر شود تا صحت محاسبات تضمین گردد:
double zero_shift=-MODEL[0]; // read the model value at the zero point if(zero_shift!=0) // make sure it is not zero for(j=0; j<points; j++) // pass along all interval points MODEL[j]+=zero_shift; // shift all model points
کد هشتم
این مثال ها ارائه یک تابع دلخواه را ساده می کند. می توانید هر نوع تابعی را بر اساس تنظیمات معامله و نیاز خود بسازید. هرچه نوع تابع پیچیده تر باشد، انتخاب بهترین روش مشکل تر می گردد چرا که بازار ملزم به پیروی از تابع نمی باشد. در اینجا، تابع فقط یه تقریب می باشد.
شما نیاز به تابع هدف برای ساخت بسته های سهام مسطح برگشتی و پراکنده ندارید. به عنوان مثال، اگر بخواهید یک تابع پراکنده بین دو سبد نماد بسازید، سبد بهینه برای بخش اصلی ماتریس بارگذاری می شود در حالی که سبد مرجع به عنوان تابع هدف استفاده شده و بر روی آخرین ستون ماتریس یه عنوان مقدار کل بارگذاری می شود:
for(i=0; i<variables; i++) // cycle by the optimized basket symbols for(j=0; j<points; j++) // cycle by the calculated interval points MATRIX[j].Set(i,EQUITY[j,i]); // upload symbol values of the optimized basket to the matrix columns for(i=variables; i<variables+constants; i++) // cycle by the reference basket symbols for(j=0; j<points; j++) // cycle by the calculated interval points MODEL[j]+=EQUITY[j,i]*LOTS[i]; // upload symbol values of the reference basket to the matrix last column
کد نهم
در زیر نمونه ای از محاسبه بسته سهام معامله مسطح می باشد که در آن تابع LSFitLinearC بسته سهامی را حتی الامکان متقارن نسبت به صفر درون فواصل محاسبه شده می سازد:
if(Model_Type==fitting) { int info,i,j; // define working variables CLSFitReportShell report; // define the special object model CMatrixDouble CONSTRAIN(1,variables+1); // define the matrix of linear limitations CMatrixDouble MATRIX(points,variables); // define the matrix for storing all data ArrayInitialize(MODEL,0); // fill the model with zeros CONSTRAIN[0].Set(variables,1); // set the only limitation for(i=0; i<variables; i++) CONSTRAIN[0].Set(i,1); // sum of roots should be equal to one for(i=0; i<variables; i++) for(j=0; j<points; j++) MATRIX[j].Set(i,EQUITY[j,i]); // download symbol data to the matrix CAlglib::LSFitLinearC(MODEL,MATRIX,CONSTRAIN,points,variables,1,info,ROOTS,report); // calculate the optimization model using OLS if(info<0) { Alert("Error in linear fitting model!"); error=true; return; } // check the result }
کد دهم
در زیر نمونه مهم دیگری از محاسبه بسته سهام مسطح با واریانس مینیمم توسط روش PCA می باشد. در اینجا، تابع PCABuilBasis تناسبات را به گونه ای محاسبه می کند که گراف بسته سهام حتی المقدور در فاصله محاسبه باقی بماند:
if(Model_Type==principal) { int info,i,j; // define working variables double VAR[]; // define the variance array ArrayResize(VAR,variables); // convert the array to the necessary dimension CMatrixDouble VECTOR(variables,variables); // define the coefficient vector matrix CMatrixDouble MATRIX(points,variables); // define the matrix for storing all data for(i=0; i<variables; i++) for(j=0; j<points; j++) MATRIX[j].Set(i,EQUITY[j,i]); // upload symbol data to the matrix CAlglib::PCABuildBasis(MATRIX,points,variables,info,VAR,VECTOR); // calculate the orthogonal basis using PCA if(info<0) { Alert("Error in principal component model!"); error=true; return; } // check the result for(i=0; i<variables; i++) ROOTS[i]=VECTOR[i][variables-1]; // upload optimal ratios }
کد یازدهم
اگر با این مفاهیم ریاضی احساس سردرگمی می نمایید، نگران نباشید. همانطور که قبلا گفتم، لازم نیست تمام جزئیات ریاضیاتی را برای اجرا و استفاده از بسته سهام بفهمید. به طور کلی، توالی مراحله به ترتیب زیر می باشد:
- محاسبه سود مجازی برای نمادهای بسته سهام دارای سهم های منفرد
- محاسبه مقادیر تابع هدف
- الگوریتم بهینه سازی سهم
- نرمال سازی حجم بسته سهام
- محاسبه گراف و معامله با ایتفاده از بسته سهام
حال که آرایه ROOTS تناسبات بهینه با ایتفاده از یک سری فرآیندها به دست آورده ایم، وقت آن است که تناسبات به سهم ها تبدیل شوند. برای این کار، به نرمال سازی احتیاج داریم: مقیاس بندی و گرد کردن. قراردادن مقیاس لازم باعث می شود که سهم ها به راحتی معامله شوند. گرد کردن لازم است تا ظرفیت سهم ها در راستای نیازهای کارگزاران قرار گیرند. بعضی اوقات، توصیه می شود که نرمال سازی توسط محدوده کلی بسته سهام اجرا شود اما این روش معایب جدی دارد (چرا که محدوده نمادهای منفرد متفاوت بوده و می توانند تغییر کنند). بنابراین، معقول تر است که نرمال سازی توسط قیمت بسته سهام یا تغییرپذیری آن انجام شود.
در زیر نمونه ای از الگوریتم نرمال سازی توسط قیمت بسته سهام می باشد:
double total_value=0; // define the variable for the portfolio price for(int i=0; i<variables+constants; i++) // pass along all portfolio symbols total_value+=closing[i]*ContractValue(SYMBOLS[i],limit_time,Timeframe)*MathAbs(LOTS[i]); // calculate and sum the price components if(total_value==0) { Alert("Zero portfolio value!"); error=true; return; } // make sure the result is not zero scale_volume=Portfolio_Value/total_value; // find a scaling ratio for(int i=0; i<variables+constants; i++) // pass along all portfolio symbols again LOTS[i]=NormalizeDouble(LOTS[i]*scale_volume,Lots_Digits);
کد دوازدهم
در اینجا قیمت بسته سهام با قیمت لازم از طریق مناسبات معادل سازی می شود. Portfolio_Value- قیمت بسته سهام لازم، total_value- قیمت بسته سهام کل با نیب های پیش فرض، scale_volume- نسبت مقیاس بندی، Lots_Digits- ظرفیت سهم، LOTS- آرایه مقادیر مناسب معامله می باشند.
مقادیر سهم از ساختار نهایی بسته سهام شکل می گیرد. سهم های مثبت مربوط به یک موقعیت طولانی می باشد در حالی که سهم های منفی مرتبط با موقعیت کوتاه است. با دانستن ساختار بسته سهام می توانیم نمودار آن را رسم و معاملات را با بسته سهام انجام دهیم. در زیر یک ساختار بسته سهام نمونه بعد از نرمال سازی می باشد:
Symbol | AUDJPY | GBPUSD | EURCAD |
Lot | -0,07 | -0,11 | -0,11 |
جدول دوم
گراف بسته سهام فقط توسط قیمت های پایانی ترسیم می شوند و در یک زیر پنجره شاخص جداگانه نمایش داده می شوند. به منظور ساخت گراف بسته سهام، لازم است تا هر میله نمودار به همان روش سودهای مجازی برای نمادهای جداگانه قبلا محاسبه شده، محاسبه کنیم. با این وجود، اکنون با احتساب سهم های ثبت شده به شکل زیر خلاصه می شود:
for(int j=draw_begin; j>=draw_end; j--) // cycle by chart bars within the drawing interval { double profit=0; // start with the value for(int i=0; i<variables; i++) // pass along all symbols { if(Fast_Period>0 && Slow_Period>0 && number!=N_TOTAL) // perform auxiliary checks { int shift=iBarShift(SYMBOLS[i],Period(),Time[j]); // obtain bar index by time double CV=ContractValue(SYMBOLS[i],Time[j],Period()); // calculate the contract price double fast=iMA(SYMBOLS[i],Period(),Fast_Period,0,MODE_SMA,PRICE_CLOSE,shift); // calculate the slow average double slow=iMA(SYMBOLS[i],Period(),Slow_Period,0,MODE_SMA,PRICE_CLOSE,shift); // calculate the fast average profit+=(fast-slow)*CV*LOTS[i]; // calculate the oscillation model } else { int shift=iBarShift(SYMBOLS[i],Period(),Time[j]); // receive the bar index by time double closing=iClose(SYMBOLS[i],Period(),shift); // receive the symbol price in the point double CV=ContractValue(SYMBOLS[i],Time[j],Period()); // calculate the contract price profit+=(closing-OPENINGS[i])*CV*LOTS[i]; // calculate profit by price difference and cost } } BUFFERS[number].buffer[j]=NormalizeDouble(profit,2); // save the profit value in the indicator array }
کد سیزدهم
در این قسمت کد، می توانیم ببینیم که نمودار بین میله های آغازی و پایانی ترسیم شده است: draw_begin و draw_end. مقدار بسته سهام برابر با مجموع سودها/زیان های تمام نمادهای محاسبه شده به عنوان اختلاف قیمت ضربدر قیمت قراردادی و سهم قبلا محاسبه شده، می باشد. اینجانب از جنبه های تکنیکال مربوط به بافرهای شاخص، قالب بندی و مانند آن صرف نظر کرده ام. شاخص بسته سهام آماده به کار نمونه در بخش زیر توضیح داده شده است.
در اینجا می توانید ساخت گراف بسته سهام نمونه (زیرپنجره پایینی شاخص) با گراف تابع هدف متصل به آن را آزمایش کنید:
شکل اول
در اینجا سهمی ریشه دوم متقارن نسبت به نقطه مرجع (Model_Absolute=true) به عنوان تابع هدف استفاده شده است. مرزهای بازه محاسبه شده با نقطه های قرمز رنگ نشان داده شده است در حالی که گراف بسته سهام تمایل به حرکت در راستای خط تابع هدف چه درون و چه بیرون بازه محاسبه شده دارد.
می توانید تحلیل تکنیکال گراف های بسته سهام را مشابه با نمودارهای قیمت نماد معمولی، شامل متوسط های متحرک، شیب خطوط و سطوح، انجام دهید. این امر قابلیت های تحلیلی و معامله را گسترش می دهد تا بتوانید ساختار بسته سهام را برای تشکیل یک معامله بر روی گراف بسته سهام، مثلا تصحیح بعد از تغییر ناگهانی شیب، ضعف شیب، خارج شدن از وضعیت مسطح، خرید اشباع-فروش اشباع، همگرایی-واگرایی، ورشکستگی، تثبیت سطح و سایر تنظیمات، انتخاب کنید. کیفیت تنظیم معامله متاثر از ترکیب بسته سهام، روش بهینه سازی، تابع هدف و بخش منتخب تاریخچه می باشد.
لازم به ذکر است که تغییر پذیری بسته سهام بشناسید تا یک حجم معامله مناسب انتخاب کنید. از آنجاییکه نمودار بسته سهام معامله در ابتدا بر اساس ارز وثیقه می باشد، شما می توانید یک محدوده نوسان بسته سهام و عمق افت بالقوه در آن نرخ ارز را با استفاده از حالت مکان نما crosshair و pulling تعیین کنید.
یک سیستم معاملاتی باید بر اساس خصوصیات رفتاری و تنظیمات آماری باشد. تا کنون، به این واقعیت اشاره نکردیم که رفتار بسته سهام شاید شدیدا در خارج از بازه بهینه سازی تغییر کند. یک تابع مسطح شاید به یک تابع متمایل تغییر کند در حالی که یک تابع متمایل شاید به یک تابع بازگشتی تبدیل شود. یک سیستم معاملاتی نیز باید در نظر بگیرد که خصوصیات بسته سهام آماده تغییر در طول زمان باشد. این مسئله در زیر بحث خواهد شد.
انجام معاملات با یک ببسته سهام معامله شامل خرید/فروش یکجا تمام نمادهای بسته سهام با حجم های محاسبه شده می باشد. برای راحتی بیشتر، معقول خواهد بود که یک ربات معامله گر مخصوص برای تمام کارهای متداول، شامل کسب داده های ساختار بسته سهام، تهیه موقعیت های مصنوعی، ردیابی ورودی سطوح، تثبیت سود و محدودیت زیان داشته باشید. ما این عبارات را با توجه به انجام آنها در ربات معامله گر اعمال خواهیم کرد: موقعیت بسته سهام مصنوعی طولانی و موقعیت بسته سهام مصنوعی کوتاه (که در آن موقعیت های طولانی با موقعیت های کوتاه جایگزین می شوند و برعکس). ربات معامله گر باید قادر باشد تا موقعیت ها را جمع آوری کند، حجم های مصنوعی را ردیابی نماید، علاوه بر اینکه شبکه بندی و انتقال بسته سهام را انجام دهد. ربات معامله گر نمونه در بخش بعد در نظر گرفته می شود اگر چه ساختارشش به دلیل محدودیت حجم مقاله توضیح داده نمی شود.
در زیر رابط مینیمالیستی نمونه برای ربات معامله گر بسته سهام را نشان می دهد:
شکل دوم
گاهی اوقات، لازم است تا نه یکی که بلکه چندین بسته سهام معامله بسازیم. در ساده ترین مورد، لازم است تا دو نوع بسته سهام با هم مقایسه شوند. بعضی موارد نیاز به سریه های بسته سهام کلی دارند تا بر روی یک بخش تاریخچه منفرد حاصل از دسته ای از بسته های سهام شامل یک الگو ساخته شوند. نمونه اجرای چنین شاخصی را می توان در بخش بعدی یافت. در اینجا، قصد داریم فقط بحرانی ترین خصوصیات اجرایی آن را توضیح دهیم.
لازم داریم که یک آرایه ساختاری برای ذخیره داده های بسته های سهام چندگانه بسازیم، به عنوان مثال:
struct MASSIVE // define the structure containing multiple data types { string symbol[MAX_SYMBOLS]; // text array for the portfolio symbols double lot[MAX_SYMBOLS]; // numerical array for lots string formula; // string with the portfolio equation double direction; // portfolio direction attribute double filter; // filter attribute }; MASSIVE PORTFOLIOS[DIM_SIZE]; // create the structure array for the group of portfolios
کد چهاردهم
در این بخش کد، DIM_SIZE اندازه ماکزیمم را برای ذخیره بسته های سهام تنظیم می کند. ساختار به روش زیر انجام می شود: symbol_portfolio- آرایه نماد، lot- آرایه سهم برای نمادهای بسته سهام، formula- رشته متنی با معادله بسته سهام، direction- جهت بسته سهام (طولانی یا کوتاه)، filter- اندازه فیلتر (وجود/عدم وجود). اعمال آرایه ساختاری راحت تر و معقول تر از استفاده آرایه های جداگانه می باشد.
آرایه ساختاری همچنین می تواند با آرایه های بافر ذخیره بسته سهام ساخته شود:
struct STREAM{double buffer[];}; // define the structure containing a numerical array STREAM BUFFERS[DIM_SIZE]; // create the structure array
کد پانزدهم
بسته های سهام درون مجموعه توسط ترکیب های نمادشان متفاوت هستند. این ترکیب ها شاید از قبل تعریف شده باشند یا مطابق با یک سری قوانین تولید شوند. کار با مجموعه ای از بسته های سهام بر حسب نیاز شاید شامل چندین مرحله باشد. ترتیب زیر از مراحل را در اینجا در نظر می گیریم:
- محاسبه نمودارهای بسته های سهام جداگانه
- ترکیب مجموعه ای از نقاط صفر
- برگشت بسته های سهام متناسب با سطح صفر
- اعمال فیلتر بر روی مجموعه ای از بسته های سهام
- خلاصه سازی- تشکیل یک بسته سهام پیشرفته
اول، بسته های سهام جداگانه درون یک مجموعه مطابق با اصول از پیش توصیف شده محاسبه می شوند. ترکیب بسته های سهام در نقطه صفر برای راحتی تحلیل لازم است. برای این کار، نقطه ای که در آن تمام بسته های سهام برابر با صفر هستند، انتخاب می شوند. برگشت بسته های سهام مطابق با یک سطح صفر نیز می تواند برای ساده سازی تحلیل مفید باشد. بسته های سهام نزولی بعد از معکوس نمودن سهم ها از نوع صعودی می شوند. فیلتر بسته های سهام درون یک مجموعه به معنی انتخاب بهترین بسته های سهام توسط چند معیار، مثلا سرعت رشد، انحراف از صفر، موقعیت درون یک مجموعه مرتبط با دیگر بسته های سهام، می باشد. بنابراین، بهترین بسته های سهام انتخاب و درون یک سبد از بسته های سهام، یا بسته سهام مادر (موقعیت مادر بسته های سهام) گذاشته می شوند.
تصویر زیر این مراحل را نمایش می دهد:
شکل سوم
یک شیفت عمودی برای ترکیب بسته های سهام به کار می رود. بسته سهام با ضربدر -1 معکوس می شوند. در نهایت، یک فیلتر برای مرتب سازی و نمونه گیری مقادیر اعمال می شود. در اینجا هیچ توصیف دقیقی از این الگوریتم ها برای اجتناب از حجم زیادی از کدهای متداول نیامده است.
در زیر یک مجموعه نمونه از بسته های سهام ساخته شده با اصول ذکر شده در ادامه نشان داده شده است:
شکل چهارم
گراف مجموعه ای از بسته های سهام محاسبه شده به روش مدل PCA با دوره کوتاه مدت را نشان می دهد. مرزهای بازه محاسبه شده با خطهای نقطه چین قرمز رنگ نشان داده شده اند. در اینجا می توانیم گسترش مجموعه را در هر طرف بازه بهینه سازی ببینیم. نقطه صفر در مرز سمت چپ بازه بهینه سازی انتخاب می شود در حالی که لحظات معکوس نسبت به صفر و اعمال فیلتر با نقطه چین های بنفش رنگ نشان گذاری شده اند. خط ضخیم بسته سهام مادر شامل فعال ترین بسته های سهام و در نتیجه آن دارای فاصله مناسب از نقطه صفر را نشان می دهد.
ترکیب نمودن بسته های سهام احتمالات دیگری را برای تحلیل و توسعه استراتژی های معامله، مثلا گوناگونی بین بسته های سهام، پراکندگی بین آنها، همگرایی- واگرایی مجموعه آنها، انتظار درهم تنیدگی یک مجموعه بسته سهام معامله، انتقال از یک بسته سهام به دیگری و سایر رویکردها، فراهم می آورد.
نمونه های اجرا
روش های توصیف شده در مقاله حاضر یه عنوان یک شاخص بسته سهام معامله و یک ربات معامله گر نیمه خودکار اجرا شده اند. در اینجا می توانید دستورالعمل ها را بیابید، کد مرجع را دانلود کنید و آن را با نیازهای خود تطبیق دهید:
- مدل ساز بسته سهام- توسعه دهنده و بهینه ساز بسته سهام. چندین نوع مدل بهینه سازی با پارامترهای قابل تنظیم فراهم می کند. علاوه بر آن، میتوانید مدل و توایع هدف خودتان را اضافه نمایید.
- بسته سهام چندگراف- تولیدکننده مجموعه های بسته سهام با مدل ها و پارامترهای مشابه و گزینه های اضافی برای انتقال بسته سهام و فیلترسازی به علاوه ساخت یک بسته سهام مادر.
- مدیر بسته سهام- ربات معامله گری برای بسته های سهام و بسته های سهام مادر. همزمان با شاخص بسته سهام کار می کند و اجازه گشایش و مدیریت موقعیت های مصنوعی را می دهد، علاوه بر اینکه عملکرد تصحیح بسته سهام و حالت معامله خودکار بر اساس خطوط گرافیکی سفارشات مجازی را دارد.
لینک دانلود: https://www.mgl5.com/ru/code/11859 (به زبان روسی)
این مقاله ترجمه شده توسط تیم آکادمی ایران ام کیو ال می باشد.
پاسخها