ตัวอย่างการสร้างและเรียกใช้ฟังก์ชัน

IUX Markets Bonus

ตัวอย่างการสร้างและเรียกใช้ฟังก์ชัน

ฟังก์ชันเป็นส่วนสำคัญในการเขียนโปรแกรม MQL4 ที่ช่วยให้เราสามารถจัดระเบียบโค้ด ลดการเขียนโค้ดซ้ำซ้อน และทำให้โปรแกรมอ่านง่ายขึ้น

ตัวอย่างการสร้างและเรียกใช้ฟังก์ชัน
ตัวอย่างการสร้างและเรียกใช้ฟังก์ชัน

มาดูตัวอย่างการสร้างและเรียกใช้ฟังก์ชันแบบต่างๆ กัน:

1. ฟังก์ชันพื้นฐานไม่มีการรับค่าและส่งค่า

 


void PrintWelcomeMessage()
{
    Print("Welcome to my Expert Advisor!");
    Print("Current Symbol: ", Symbol());
    Print("Current Timeframe: ", Period());
}

// เรียกใช้ฟังก์ชัน
void OnStart()
{
    PrintWelcomeMessage();
}

ฟังก์ชันที่รับค่าใน MQL4:

  1. คำอธิบาย:
    • ฟังก์ชัน PrintTradeInfo รับค่า 3 ตัว:
      • symbol (string): ชื่อคู่สกุลเงิน
      • volume (double): ปริมาณการเทรด
      • type (int): ประเภทของการเทรด (ซื้อหรือขาย)
    • ฟังก์ชันนี้ไม่ส่งค่ากลับ (void) แต่ใช้ค่าที่รับเข้ามาในการแสดงข้อมูล
  2. ประโยชน์:
    • ทำให้ฟังก์ชันมีความยืดหยุ่น สามารถทำงานกับข้อมูลที่แตกต่างกันได้
    • ช่วยลดการเขียนโค้ดซ้ำซ้อน เพราะสามารถใช้ฟังก์ชันเดียวกับข้อมูลที่ต่างกันได้
  3. ข้อควรระวัง:
    • ต้องส่งค่าให้ครบตามจำนวนและชนิดของพารามิเตอร์ที่กำหนดไว้
    • ควรตรวจสอบความถูกต้องของค่าที่รับเข้ามาก่อนนำไปใช้งาน
  4. การใช้งานจริง:
    • ใช้ในการคำนวณค่าต่างๆ เช่น การคำนวณขนาดล็อต, การคำนวณจุดเข้าเทรด
    • ใช้ในการตรวจสอบเงื่อนไขต่างๆ เช่น การตรวจสอบว่าควรเข้าเทรดหรือไม่

ฟังก์ชันที่รับค่าช่วยให้การเขียนโปรแกรม Expert Advisor หรือ Script มีความยืดหยุ่นและสามารถนำกลับมาใช้ซ้ำได้ง่ายขึ้น ทำให้โค้ดมีโครงสร้างที่ดีและง่ายต่อการบำรุงรักษา

2. ฟังก์ชันที่รับค่าพารามิเตอร์


void OpenOrder(int orderType, double lotSize)
{
    if(orderType == OP_BUY) {
        OrderSend(Symbol(), OP_BUY, lotSize, Ask, 3, 0, 0, "Buy Order", 0, 0, clrGreen);
    } else if(orderType == OP_SELL) {
        OrderSend(Symbol(), OP_SELL, lotSize, Bid, 3, 0, 0, "Sell Order", 0, 0, clrRed);
    }
}

// เรียกใช้ฟังก์ชัน
void OnTick()
{
    if(SomeCondition()) {
        OpenOrder(OP_BUY, 0.1);
    } else if(AnotherCondition()) {
        OpenOrder(OP_SELL, 0.1);
    }
}

ฟังก์ชัน OpenOrder นี้เป็นตัวอย่างที่ดีของฟังก์ชันที่รับค่าพารามิเตอร์ใน MQL4 ผมจะอธิบายรายละเอียดดังนี้:

  1. โครงสร้างของฟังก์ชัน:
    • ชื่อฟังก์ชัน: OpenOrder
    • ชนิดการส่งคืน: void (ไม่มีการส่งค่ากลับ)
    • พารามิเตอร์:
      • orderType (int): ระบุประเภทของคำสั่ง (ซื้อหรือขาย)
      • lotSize (double): ระบุขนาดล็อตของคำสั่ง
  2. การทำงานของฟังก์ชัน:
    • ตรวจสอบประเภทของคำสั่งโดยใช้ if-else
    • ใช้ฟังก์ชัน OrderSend() เพื่อส่งคำสั่งซื้อหรือขาย
    • ใช้ค่า Ask สำหรับคำสั่งซื้อ และ Bid สำหรับคำสั่งขาย
    • ใช้สีเขียวสำหรับคำสั่งซื้อ และสีแดงสำหรับคำสั่งขาย
  3. การใช้งานฟังก์ชัน:
    • เรียกใช้ในฟังก์ชัน OnTick() ซึ่งทำงานทุกครั้งที่ราคาเปลี่ยนแปลง
    • ใช้เงื่อนไข SomeCondition() และ AnotherCondition() (ซึ่งไม่ได้แสดงในโค้ด) เพื่อตัดสินใจว่าจะเปิดคำสั่งซื้อหรือขาย
    • ส่งค่า OP_BUY หรือ OP_SELL เป็นพารามิเตอร์แรก และขนาดล็อต 0.1 เป็นพารามิเตอร์ที่สอง
  4. ข้อดีของการใช้ฟังก์ชันแบบนี้:
    • ลดการเขียนโค้ดซ้ำซ้อน: ใช้ฟังก์ชันเดียวสำหรับทั้งคำสั่งซื้อและขาย
    • เพิ่มความยืดหยุ่น: สามารถเปลี่ยนขนาดล็อตได้ง่ายเมื่อเรียกใช้ฟังก์ชัน
    • ทำให้โค้ดในส่วน OnTick() อ่านง่ายและกระชับขึ้น
  5. ข้อควรระวัง:
    • ไม่มีการตรวจสอบความถูกต้องของ orderType (ควรเพิ่มการตรวจสอบ)
    • ไม่มีการจัดการข้อผิดพลาดหากการส่งคำสั่งไม่สำเร็จ
    • ใช้ Stop Loss และ Take Profit เป็น 0 ซึ่งอาจไม่เหมาะสมในบางกรณี
HFM Market Promotion

ฟังก์ชันนี้เป็นตัวอย่างที่ดีของการใช้พารามิเตอร์เพื่อทำให้ฟังก์ชันมีความยืดหยุ่นและใช้งานได้หลากหลายสถานการณ์ในการเทรด

3. ฟังก์ชันที่ส่งค่ากลับ



double CalculateAveragePrice(int periods)
{
    double sum = 0;
    for(int i = 0; i < periods; i++) {
        sum += iClose(Symbol(), 0, i);
    }
    return sum / periods;
}

// เรียกใช้ฟังก์ชัน
void OnTick()
{
    double avg = CalculateAveragePrice(20);
    Print("Average price over last 20 periods: ", avg);
}

ฟังก์ชัน CalculateAveragePrice นี้เป็นตัวอย่างที่ดีของฟังก์ชันที่ส่งค่ากลับใน MQL4 ผมจะอธิบายรายละเอียดดังนี้:

  1. โครงสร้างของฟังก์ชัน:
    • ชื่อฟังก์ชัน: CalculateAveragePrice
    • ชนิดการส่งคืน: double (ส่งค่ากลับเป็นตัวเลขทศนิยม)
    • พารามิเตอร์:
      • periods (int): จำนวนช่วงเวลาที่ต้องการคำนวณค่าเฉลี่ย
  2. การทำงานของฟังก์ชัน:
    • ใช้ลูป for เพื่อรวมราคาปิดของแท่งเทียนตามจำนวน periods ที่กำหนด
    • ใช้ฟังก์ชัน iClose() เพื่อดึงราคาปิดของแต่ละแท่งเทียน
    • คำนวณค่าเฉลี่ยโดยหารผลรวมด้วยจำนวน periods
    • ส่งค่าเฉลี่ยกลับด้วยคำสั่ง return
  3. การใช้งานฟังก์ชัน:
    • เรียกใช้ในฟังก์ชัน OnTick() ซึ่งทำงานทุกครั้งที่ราคาเปลี่ยนแปลง
    • ส่งค่า 20 เป็นพารามิเตอร์ เพื่อคำนวณค่าเฉลี่ยของ 20 ช่วงเวลาล่าสุด
    • เก็บค่าที่ส่งกลับมาในตัวแปร avg
    • แสดงผลค่าเฉลี่ยที่คำนวณได้ด้วยฟังก์ชัน Print()
  4. ข้อดีของการใช้ฟังก์ชันแบบนี้:
    • แยกการคำนวณออกจากส่วนหลักของโปรแกรม ทำให้โค้ดอ่านง่ายขึ้น
    • สามารถนำไปใช้ซ้ำได้ง่าย โดยเปลี่ยนจำนวน periods ตามต้องการ
    • ส่งค่ากลับเป็น double ทำให้สามารถนำไปใช้ในการคำนวณอื่นๆ ต่อได้

ฟังก์ชันนี้เป็นตัวอย่างที่ดีของการใช้ฟังก์ชันที่ส่งค่ากลับ ซึ่งช่วยในการคำนวณและวิเคราะห์ข้อมูลราคา ทำให้สามารถนำไปใช้ในการตัดสินใจเทรดหรือการวิเคราะห์ทางเทคนิคอื่นๆ ได้อย่างมีประสิทธิภาพ

4. ฟังก์ชันที่รับค่าแบบอ้างอิง (by reference)



void CalculateSupport(double& supportLevel, int periods)
{
    supportLevel = Low[iLowest(NULL, 0, MODE_LOW, periods, 0)];
}

// เรียกใช้ฟังก์ชัน
void OnTick()
{
    double support;
    CalculateSupport(support, 20);
    Print("Support level: ", support);
}
  1. โครงสร้างของฟังก์ชัน:
    • ชื่อฟังก์ชัน: CalculateSupport
    • ชนิดการส่งคืน: void (ไม่มีการส่งค่ากลับโดยตรง)
    • พารามิเตอร์:
      • supportLevel (double&): ตัวแปรอ้างอิงที่จะเก็บค่าระดับแนวรับ
      • periods (int): จำนวนช่วงเวลาที่ต้องการใช้ในการคำนวณ
  2. การทำงานของฟังก์ชัน:
    • ใช้ฟังก์ชัน iLowest() เพื่อหาแท่งเทียนที่มีราคาต่ำสุดในช่วงเวลาที่กำหนด
    • ใช้ค่าที่ได้จาก iLowest() เพื่อดึงราคาต่ำสุดจากอาร์เรย์ Low[]
    • กำหนดค่าราคาต่ำสุดนี้ให้กับตัวแปร supportLevel ที่ส่งมาแบบอ้างอิง
  3. การใช้งานฟังก์ชัน:
    • เรียกใช้ในฟังก์ชัน OnTick() ซึ่งทำงานทุกครั้งที่ราคาเปลี่ยนแปลง
    • สร้างตัวแปร support เพื่อเก็บค่าระดับแนวรับ
    • ส่งตัวแปร support และค่า 20 (จำนวนช่วงเวลา) เข้าไปในฟังก์ชัน
    • แสดงผลค่าระดับแนวรับที่คำนวณได้ด้วยฟังก์ชัน Print()
  4. ข้อดีของการใช้ฟังก์ชันแบบนี้:
    • สามารถเปลี่ยนแปลงค่าของตัวแปรที่อยู่นอกฟังก์ชันได้โดยตรง
    • ประหยัดหน่วยความจำเมื่อต้องทำงานกับข้อมูลขนาดใหญ่
    • เหมาะสำหรับการคำนวณที่ต้องการส่งกลับหลายค่า
  5. ข้อควรระวัง:
    • การใช้งานต้องระมัดระวังเพราะสามารถเปลี่ยนแปลงค่าของตัวแปรภายนอกได้โดยตรง
    • อาจทำให้โค้ดเข้าใจยากขึ้นหากใช้ไม่เหมาะสม
    • ไม่มีการตรวจสอบความถูกต้องของค่า periods

5. ฟังก์ชันที่ใช้ตัวแปร static



int CountTrades()
{
    static int tradeCount = 0;
    tradeCount++;
    return tradeCount;
}

// เรียกใช้ฟังก์ชัน
void OnTick()
{
    if(SomeCondition()) {
        int currentTradeNumber = CountTrades();
        Print("Opening trade number: ", currentTradeNumber);
        // เปิดออเดอร์ที่นี่
    }
}
  1. โครงสร้างของฟังก์ชัน:
    • ชื่อฟังก์ชัน: CountTrades
    • ชนิดการส่งคืน: int (ส่งค่ากลับเป็นจำนวนเต็ม)
    • ไม่มีพารามิเตอร์
  2. การทำงานของฟังก์ชัน:
    • ใช้ตัวแปร static int tradeCount เพื่อเก็บจำนวนการเรียกใช้ฟังก์ชัน
    • เพิ่มค่า tradeCount ขึ้นทีละ 1 ทุกครั้งที่ฟังก์ชันถูกเรียกใช้
    • ส่งค่า tradeCount กลับ
  3. การใช้งานฟังก์ชัน:
    • เรียกใช้ในฟังก์ชัน OnTick() ภายใต้เงื่อนไข SomeCondition()
    • เก็บค่าที่ส่งกลับมาในตัวแปร currentTradeNumber
    • แสดงผลจำนวนการเทรดปัจจุบันด้วยฟังก์ชัน Print()
  4. ความสำคัญของ static:
    • ตัวแปร static จะถูกสร้างขึ้นเพียงครั้งเดียวและคงอยู่ตลอดการทำงานของโปรแกรม
    • ค่าของตัวแปร static จะไม่ถูกรีเซ็ตเมื่อออกจากฟังก์ชัน
    • ทำให้สามารถนับจำนวนการเรียกใช้ฟังก์ชันได้อย่างต่อเนื่อง
  5. ข้อดีของการใช้ฟังก์ชันแบบนี้:
    • สามารถติดตามจำนวนการเรียกใช้ฟังก์ชันหรือการเกิดเหตุการณ์บางอย่างได้
    • ไม่ต้องใช้ตัวแปรกลอบอล ทำให้โค้ดเป็นระเบียบและปลอดภัยมากขึ้น
    • เหมาะสำหรับการนับจำนวนหรือการทำงานที่ต้องการความต่อเนื่อง
  6. ข้อควรระวัง:
    • ค่าของตัวแปร static จะไม่ถูกรีเซ็ตเมื่อรีรัน EA หรือเปลี่ยนช่วงเวลา (timeframe)
    • อาจทำให้เกิดความสับสนหากไม่เข้าใจการทำงานของ static

6. ฟังก์ชันที่มีค่าเริ่มต้นของพารามิเตอร์


void SetStopLoss(int ticket, double stopLoss, int slippage = 3)
{
    if(OrderSelect(ticket, SELECT_BY_TICKET)) {
        OrderModify(ticket, OrderOpenPrice(), stopLoss, OrderTakeProfit(), 0, clrRed);
    }
}

// เรียกใช้ฟังก์ชัน
void OnTick()
{
    if(OrdersTotal() > 0) {
        int ticket = OrderTicket();
        double newStopLoss = Bid - 20 * Point;
        SetStopLoss(ticket, newStopLoss);  // ใช้ค่า slippage เริ่มต้น
        // หรือ
        // SetStopLoss(ticket, newStopLoss, 5);  // กำหนดค่า slippage เอง
    }
}

  1. โครงสร้างของฟังก์ชัน:
    • ชื่อฟังก์ชัน: SetStopLoss
    • ชนิดการส่งคืน: void (ไม่มีการส่งค่ากลับ)
    • พารามิเตอร์:
      • ticket (int): หมายเลขคำสั่งซื้อขาย
      • stopLoss (double): ระดับ Stop Loss ใหม่
      • slippage (int, ค่าเริ่มต้น = 3): ค่าความคลาดเคลื่อนที่ยอมรับได้
  2. การทำงานของฟังก์ชัน:
    • ใช้ OrderSelect() เพื่อเลือกคำสั่งซื้อขายตาม ticket
    • ถ้าเลือกคำสั่งได้สำเร็จ, ใช้ OrderModify() เพื่อแก้ไข Stop Loss
    • ใช้ค่า slippage ที่กำหนดหรือค่าเริ่มต้น 3 pip
  3. การใช้งานฟังก์ชัน:
    • เรียกใช้ในฟังก์ชัน OnTick() เมื่อมีคำสั่งซื้อขายเปิดอยู่
    • สามารถเรียกใช้โดยไม่ระบุค่า slippage (ใช้ค่าเริ่มต้น 3)
    • หรือสามารถระบุค่า slippage เองได้
  4. ความสำคัญของค่าเริ่มต้นพารามิเตอร์:
    • ช่วยให้ฟังก์ชันมีความยืดหยุ่นในการใช้งาน
    • ลดความซับซ้อนในการเรียกใช้ฟังก์ชันเมื่อไม่ต้องการระบุค่าทุกพารามิเตอร์
    • ทำให้โค้ดสั้นลงและอ่านง่ายขึ้นในกรณีที่ใช้ค่าเริ่มต้นบ่อยๆ
  5. ข้อดีของการใช้ฟังก์ชันแบบนี้:
    • เพิ่มความยืดหยุ่นในการใช้งาน สามารถใช้ค่าเริ่มต้นหรือกำหนดเองได้
    • ลดโอกาสเกิดข้อผิดพลาดจากการลืมใส่ค่าพารามิเตอร์
    • ทำให้โค้ดสั้นและกระชับขึ้นเมื่อใช้ค่าเริ่มต้นบ่อยๆ
  6. ข้อควรระวัง:
    • ต้องแน่ใจว่าค่าเริ่มต้นที่กำหนดเหมาะสมกับสถานการณ์ส่วนใหญ่
    • อาจทำให้เกิดความสับสนหากผู้ใช้ไม่ทราบว่ามีค่าเริ่มต้นอยู่
  7. ข้อสังเกตเพิ่มเติม:
    • การใช้ค่าเริ่มต้น slippage = 3 เป็นการตั้งค่าที่ค่อนข้างทั่วไป แต่อาจต้องปรับตามสภาพตลาดหรือคู่สกุลเงิน
    • ฟังก์ชันนี้ไม่ได้ตรวจสอบว่าการแก้ไข Stop Loss สำเร็จหรือไม่ ซึ่งควรเพิ่มการตรวจสอบนี้ในการใช้งานจริง

ฟังก์ชันนี้แสดงให้เห็นถึงการใช้ค่าเริ่มต้นของพารามิเตอร์ใน MQL4 ซึ่งช่วยเพิ่มความยืดหยุ่นในการใช้งานและทำให้โค้ดสั้นลงในกรณีที่ใช้ค่าทั่วไปบ่อยๆ ทำให้การเขียนและบำรุงรักษาโค้ดทำได้ง่ายขึ้น

7. การใช้ฟังก์ชันร่วมกันในสถานการณ์จริง


// ฟังก์ชันตรวจสอบสัญญาณการเทรด
int CheckTradeSignal()
{
    double ma20 = iMA(Symbol(), 0, 20, 0, MODE_SMA, PRICE_CLOSE, 0);
    double ma50 = iMA(Symbol(), 0, 50, 0, MODE_SMA, PRICE_CLOSE, 0);
    
    if(ma20 > ma50 && Close[1] > ma20) {
        return 1;  // สัญญาณซื้อ
    } else if(ma20 < ma50 && Close[1] < ma20) {
        return -1;  // สัญญาณขาย
    }
    return 0;  // ไม่มีสัญญาณ
}

// ฟังก์ชันคำนวณขนาด Lot
double CalculateLotSize(double riskPercent)
{
    double accountBalance = AccountBalance();
    double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
    double stopLoss = 20 * Point;  // ตั้งค่า Stop Loss ที่ 20 pips
    
    double lotSize = (accountBalance * riskPercent) / (stopLoss * tickValue * 100);
    return NormalizeDouble(lotSize, 2);
}

// ฟังก์ชันหลัก
void OnTick()
{
    if(OrdersTotal() == 0) {  // ถ้ายังไม่มีออเดอร์เปิดอยู่
        int signal = CheckTradeSignal();
        if(signal != 0) {
            double lotSize = CalculateLotSize(0.01);  // risk 1% ของพอร์ต
            
            if(signal == 1) {
                OpenOrder(OP_BUY, lotSize);
            } else if(signal == -1) {
                OpenOrder(OP_SELL, lotSize);
            }
        }
    }
}

ในตัวอย่างสุดท้ายนี้ เราใช้หลายฟังก์ชันร่วมกันเพื่อสร้าง EA ที่สมบูรณ์ขึ้น โดยแต่ละฟังก์ชันทำหน้าที่เฉพาะของตัวเอง ทำให้โค้ดอ่านง่ายและจัดการได้ง่ายขึ้น

1. ฟังก์ชัน CheckTradeSignal()

ฟังก์ชันนี้ใช้สำหรับตรวจสอบสัญญาณการเทรด โดย:

  • คำนวณ Moving Average 20 และ 50 คาบ
  • ตรวจสอบการตัดกันของ MA และตำแหน่งของราคาปิดล่าสุด
  • ส่งคืนค่า 1 สำหรับสัญญาณซื้อ, -1 สำหรับสัญญาณขาย, 0 เมื่อไม่มีสัญญาณ

2. ฟังก์ชัน CalculateLotSize()

ฟังก์ชันนี้คำนวณขนาด Lot ตามเปอร์เซ็นต์ความเสี่ยงที่กำหนด:

  • ใช้ยอดเงินในบัญชี (AccountBalance) เป็นฐานในการคำนวณ
  • คำนวณขนาด Lot โดยคำนึงถึง Stop Loss ที่ 20 pips
  • ปรับค่า Lot size ให้เป็นทศนิยม 2 ตำแหน่งด้วย NormalizeDouble

3. ฟังก์ชัน OnTick()

ฟังก์ชัน OnTick() เป็นฟังก์ชันหลักที่ทำงานทุกครั้งที่มีการเปลี่ยนแปลงราคา:

  • ตรวจสอบว่ายังไม่มีออเดอร์เปิดอยู่
  • เรียกใช้ CheckTradeSignal() เพื่อตรวจสอบสัญญาณ
  • ถ้ามีสัญญาณ, คำนวณขนาด Lot โดยใช้ CalculateLotSize() ด้วยความเสี่ยง 1%
  • เปิดออเดอร์ตามสัญญาณที่ได้รับ (ซื้อหรือขาย) ด้วยฟังก์ชัน OpenOrder() (ไม่ได้แสดงในโค้ดตัวอย่าง)
FOREXDUCK Logo

FOREXDUCK (นามปากกา) นักเขียนของเรามีประสบการณ์การเงินการลงทุนกว่า 10 ปี มีความเชี่ยวชาญในการวิเคราะห์ตลาด Forex และคริปโต โดยเฉพาะการวิเคราะห์ทางเทคนิค รวมถึงเทคนิคต่าง

HFM Promotion