رد:موضوع مخصص للأسئلة البرمجية
اقتباس:
المشاركة الأصلية كتبت بواسطة kira-h
السلام عليكم ورحمة الله وبركاته
تحية طيبة اخواني الكرام
أواجه مشكلة بدالة المضاعفات حيث لا يتم اختصار اللوت العشري المكون من 3 أرقام بعد الفاصلة إلى رقمين... والناتجة عن المضاعفة x1.5 مع اللوت الابتدائي 0.01
في حين لا يوجد أي مشكلة عند استخدام المضاعفة x2
لدينا الكود التالي والمرجو فضلا لا أمرا تعديله بما يتناسب مع طريقتي البرمجية البسيطة :asvc:
كود PHP:
void BuyOrder()
{
double profit = 0;
int cnt = OrdersHistoryTotal();
for (int i=cnt-1; i >= 0; i--)
{
if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
if ((OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNo)
{
profit = OrderProfit();
CurrentLots = OrderLots(); // take lots from the last order
break;
}
}
if (profit > 0) // had profit
{
CurrentLots = CurrentLots * LotsMpOnProfit ;
if (LotsResetOnProfit)
CurrentLots = Lots;
}
else if (profit < 0) // had loss
{
CurrentLots = CurrentLots * 1.5 ;
if (LotsResetOnLoss) CurrentLots = Lots;
}
if (CurrentLots > 100)
{
CurrentLots = 100;
}
double lotvalue = CurrentLots;
if (lotvalue < MarketInfo(Symbol(), MODE_MINLOT)) // make sure lot is not smaller than allowed value
{
lotvalue = MarketInfo(Symbol(), MODE_MINLOT);
}
if (lotvalue > MarketInfo(Symbol(), MODE_MAXLOT)) // make sure lot is not greater than allowed value
{
lotvalue = MarketInfo(Symbol(), MODE_MAXLOT);
}
double SL = Ask - Stoploss*PipValue*Point;
if (Stoploss == 0) SL = 0;
double TP = Ask + Takeprofit1*PipValue*Point;
if (Takeprofit1 == 0) TP = 0;
FirstLotsMgm = false;
int ticket = -1;
if (ECNBroker)
ticket = OrderSend(Symbol(), OP_BUY, lotvalue, Ask, Slippage, 0, 0, "My Expert", MagicNo, 0, Blue);
else
ticket = OrderSend(Symbol(), OP_BUY, lotvalue, Ask, Slippage, SL, TP, "My Expert", MagicNo, 0, Blue);
if (ticket > -1)
{
if (ECNBroker)
{
OrderSelect(ticket, SELECT_BY_TICKET);
bool ret = OrderModify(OrderTicket(), OrderOpenPrice(), SL, TP, 0, Blue);
if (ret == false)
Print("OrderModify() error - ", ErrorDescription(GetLastError()));
}
}
else
{
Print("OrderSend() error - ", ErrorDescription(GetLastError()));
}
}
وعملت محاولة باستبدال الجزء
كود PHP:
else if (profit < 0) // had loss
{
CurrentLots = CurrentLots * 1.5;
if (LotsResetOnLoss) CurrentLots = Lots;
}
بهذا الجزء باضافة الوظيفة MathMin
كود PHP:
else if (profit < 0) // had loss
{
CurrentLots=MathMin(CurrentLots*1.5,MarketInfo(Symbol(),MODE_MAXLOT));
if (LotsResetOnLoss) CurrentLots = Lots;
}
لا يوجد أخطاء بالكمبايل وعند التجربة بالباكتيست والديمو يفتح الاكسبيرت صفقات المضاعفات بلوت 0.01
وجزاكم الله خيرا :eh_s(7):
وعليكم السلام حسن ، اللوت 0.01 لو استخدمت آله حاسبة وضربت في 1.5 سيكون 0.015 ولن تقبله اي منصة الا اذا كان الحساب بالسنت ، واذا اردت استخدام كود للتقريب فأستخدم MathMax بدلا من MathMin .
3 مرفق
رد:موضوع مخصص للأسئلة البرمجية
اقتباس:
المشاركة الأصلية كتبت بواسطة Jmeel
عزيزي المشكلة ليست مشكلتك في البرمجة لكن المشكلة في اللوت 0.01 فالمنصات لاتقبل اللوت ب 15 سنت مالم يكن اللوت في المنصة يقبل السنت الواحد ، جرب نفس الكود وضع اللوت اكبر مثلا اللوت الأبتدائي الى 0.02 وسيعمل جيدا ، ثانيا لاتحتاج اضافة MathMax يوجد في كودك MarketInfo(Symbol(), MODE_MINLOT وهذه تعني اقل لوت تقبله المنصة بعد العملية الحسابية .
بارك الله فيك :eh_s(7):
فعلا بدون أي تعديل على الكود الأصلي وباستخدام اللوت 0.02 تعمل مضاعفات النسبة 1.5 بكفاءة
لكن ماذا عن هذه الصورة وهي نتيجة باكتيست لاكسبيرت مستر دولار الشهير للاوامر المعلقة
https://forum.arabictrader.com/attac...1&d=1381515665
يعمل جيدا بمضاعفات النسبة 1.5 وبلوت ابتدائي 0.01 وفي نفس المنصة (ستاندرد) !!!!
أيضا نفس الشيء باكسبيرت الأخ الكريم Spiders102 يعمل بكفاءة (بالمرفقات)
استخرجت كود المضاعفات من الاكسبيرت لكن لم أعرف كيف أدمجه مع اكسبيرتي :no3:
كود PHP:
if(UseMultiplier){
if(WinorLoss()==false){Lots=MathMin(lastlot()*Multiplier,MarketInfo(Symbol(),MODE_MAXLOT));}
if(WinorLoss()==true){Lots=Firstlot;}
}
كود PHP:
// Limiting Orders
int orderstotal(){
int cnt=0;
for(int i=0;i<OrdersTotal();i++){
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if(OrderSymbol()==Symbol() && MagicNumber==OrderMagicNumber()){
cnt++;
}
}
return(cnt);
}
int OrdershistoryTotal(){
int cnt=0;
for(int i=0;i<OrdersHistoryTotal();i++){
OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
if(OrderSymbol()==Symbol() && MagicNumber==OrderMagicNumber()){
cnt++;
}
}
return(cnt);
}
//+------------------------------------------------------------------+
// OrdersHistoryTotal -- MODE_HISTORY -- Closed Orders //
// OrdersTotal -- MODE_TRADES -- Opend Orders //
//+------------------------------------------------------------------+
// lastlot & WinorLoss Functions //
// Lot Multiplier for Closed Lots //
double lastlot(){
for(int i=0;i<OrdershistoryTotal();i++){
OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
if(OrderSymbol()==Symbol() && MagicNumber==OrderMagicNumber()){
double lotsnumber=OrderLots();
}
}
return(lotsnumber);
}
// Lot Multiplier for Opened Lots //
double lastlot2(){
for(int i=0;i<orderstotal();i++){
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if(OrderSymbol()==Symbol() && MagicNumber==OrderMagicNumber()){
double lotsnumber=OrderLots();
}
}
return(lotsnumber);
}
bool WinorLoss(){
bool win=true;
for(int i=0;i<OrdershistoryTotal();i++){
OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
if(OrderSymbol()==Symbol() && MagicNumber==OrderMagicNumber()){
if(OrderProfit()>0){
win=true;
}
else{
win=false;
}
}
}
return(win);
}
double LastLot(int M,int Q){
int d;
for(int i=OrdershistoryTotal();i>=0;i--){
OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
double L=OrderLots();
if(OrderSymbol()==Symbol()&&OrderMagicNumber()==M){
d++;
if(d==Q)return(L);
}
}
}
int NumberOfLosses(){
int N;
for(int i=OrdershistoryTotal();i>=0;i--){
OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
if(OrderSymbol()==Symbol() && MagicNumber==OrderMagicNumber()){
if(OrderProfit()>0){
return(N);
}
else{
N++;
}
}
}
return(N);
}
فما العمل ؟ لابد من استخدام اللوت 0.01
بالمرفقات اكسبيرت تجريبي test ياريت تضيف له الكود فضلا وشكرا جزيلا :eh_s(7):
تحياتي
1 مرفق
رد:موضوع مخصص للأسئلة البرمجية
تمت اضافة النص المقترح لكن لايعطي المطلوب ربما يوجد صيغة برمجية أخرى لا أعرفها ويفيدنا بها أستاذي الفاضل أسامة .
1 مرفق
رد:موضوع مخصص للأسئلة البرمجية
اقتباس:
المشاركة الأصلية كتبت بواسطة Jmeel
أستاذ محمد الأستاذ اسامه اعطاك دالة تعود بتوقيت فتح آخر صفقة اغلقت ، اعمل نسخه منها ثم غير بدل History الى MODE_TRADE و ORDERSTRADE فتستعود لك بتوقيت افتتاح آخر صفقة ولازالت شغاله ، سيكون لدينا دالتين في هذه الحالة ، ثم ستعدل الشرط الى مقارنة مع الدالتين في التوقيت بدلا من الدالة الواحدة ، هذه الطريقة الأسهل .
اقتباس:
المشاركة الأصلية كتبت بواسطة MR.dollar
يمكنك أن تقوم بتعريف متغير لحفظ الشمعه التي تم فتح صفقه فيها
كود PHP:
static datetime Time0;
ثم ستضع من ضمن شروط الإكسبرت
كود PHP:
if(Time0!=Time[0])
وعندما يتم فتح صفقة سوف تضع الكود
بالتالي لن تفتح صفقة أخرى في نفس هذه الشمعه التي تحققت فيها الشروط إلا مره واحده فقط
اقتباس:
المشاركة الأصلية كتبت بواسطة Jmeel
نعم تستطيع كما اخبرك استاذي اسامة ان تستخدم
كود PHP:
static datetime LastOpen;
وبنهاية دالة البيع أو الشراء
كود PHP:
LastOpen=OrderOpenTime();
سيأخذ المتغير زمن آخر افتتاح ويحتفظ به .
ثم تستخدمه ضمن الشروط .
بارك الله فيكم يا اخوان ،، قمت باستخدام الدوال التي ذكرتوها كما هي في الاكسبيرت أعلاه وما زال الاكسبيرت يفتح اكثر من صفقة .. الرجاء الإطلاع على الإكسبيرت وإبداء الرأي وشكراً لكم .
رد:موضوع مخصص للأسئلة البرمجية
اقتباس:
المشاركة الأصلية كتبت بواسطة kira-h
بارك الله فيك أستاذ جميل ما قصرت
اشتغلت المضاعفات النصفية 1.5x ويوجد فقط خطأ حسابي مثلا ينتقل من اللوت 0.03 إلى اللوت 0.06
علما أن اللوت 0.03 مضروب في 1.5 = 0.045 إذن من المفترض أن يفتح المضاعفة الموالية بلوت 0.05
......
منتظرين أستاذنا الفاضل مستر دولار
بالمرفقات اكسبيرت معدل لطريقة الدخول بصفقة واحدة لتتضح متوالية المضاعفات
تحياتي وشكرا جزيلا مرة أخرى :eh_s(7):
ينقصك فقط أن تستخدم الداله NormalizeDouble لتقريب حجم اللوت إلى الرقم العشري المسموح به في الصفقه
مثال
كود PHP:
lotvalue=MathMin(NormalizeDouble(CurrentLots*LotsMpOnLoss,2),MarketInfo(Symbol(),MODE_MAXLOT)) ;
2 لأن البروكر يقبل حجم لوت مايكرو 0.01 أما إذا كان أقل حجم لوت يقبله البروكر هو 0.1 فسوف تجعله 1
رد:موضوع مخصص للأسئلة البرمجية
اقتباس:
المشاركة الأصلية كتبت بواسطة محمد آل مسيري
بارك الله فيكم يا اخوان ،، قمت باستخدام الدوال التي ذكرتوها كما هي في الاكسبيرت أعلاه وما زال الاكسبيرت يفتح اكثر من صفقة .. الرجاء الإطلاع على الإكسبيرت وإبداء الرأي وشكراً لكم .
الشروط صحيحه قمت بتجربة الإكسبرت وهو يفتح صفقة واحده فقط في الشمعه لكن يمكن أن يفتح صفقة بيع وشراء في نفس الشمعه إذا أردت أن يفتح صفقة واحده فقط سواء بيع أو شراء فسوف تستخدم متغير واحد فقط في نفس شروط البيع و الشراء
1 مرفق
رد:موضوع مخصص للأسئلة البرمجية
اقتباس:
المشاركة الأصلية كتبت بواسطة MR.dollar
ينقصك فقط أن تستخدم الداله NormalizeDouble لتقريب حجم اللوت إلى الرقم العشري المسموح به في الصفقه
مثال
كود PHP:
lotvalue=MathMin(NormalizeDouble(CurrentLots*LotsMpOnLoss,2),MarketInfo(Symbol(),MODE_MAXLOT)) ;
2 لأن البروكر يقبل حجم لوت مايكرو 0.01 أما إذا كان أقل حجم لوت يقبله البروكر هو 0.1 فسوف تجعله 1
جزاك الله خيرا أستاذي الغالي
اشتغلت المضاعفات النصفية جيدا
كنت غيرت الوظيفة MathMin بالوظيفة NormalizeDouble لكن لم تخطر على بالي فكرة دمجهما معا في سطر واحد :doh:
ماشاء الله تبارك الله
شكرا جزيلا على المساعدة الدائمة :eh_s(7):