EA Programing => ปัญหาที่พบในการเขียน EA => Topic started by: sAcIw on มกราคม 29, 2013, 12:43:45 pm
-
ผมก็ได้ค้นหาในเว็บนี้หลายๆกระทู้ที่เกี่ยวกับ ZigZag แต่ผมก็ยังไม่เข้าใจว่า
ตัว iCustom จะส่งค่าอะไรออกมา
คือผมอยากได้ว่า ตรง High กับ Low ล่าสุดที่เกิดนั้น อยู่ที่ราคาเท่าไรครับ
เช่น High=1.34594, Low=1.34000 ประมาณนี้ครับ
เพราะผมจะเอาไปคำนวณระยะห่างของ High กับ Low ครับ
-
iCustom จะคืนค่า High ของแท่งเทียน กรณีเป็นจุดสูงสุด หรือ ค่า Low ของแท่งเทียน กรณีที่เป็นจุดต่ำสุด หรือ 0 กรณีที่ไม่ใช่จุดสูงสุดหรือต่ำสุด
code ข้างล่างนี้ เป็นการหาตำแหน่งและค่าของจุดสูงสุดและจุดต่ำสุดล่าสุด
int zigzagIndex[2];
double zigzagValue[2];
void updateZigzag(){
double value;
int Found = 0;
int idx = 0;
while(Found <= 2){ // เอาแค่ต่ำสุดกับสูงสุดอันล่าสุด รวม 2 จุด
value = iCustom(NULL, 0, "ZigZag", 12, 5, 3, 0, idx);
if(value != 0){
zigzagIndex[Found] = idx;
zigzagValue[Found] = value;
Found++;
}
idx++;
}
}
แล้วก็เอาไปเทียบค่าอีกทีว่า อันไหนสูงสุด อันไหนต่ำสุด
แต่ถ้าแค่หาระยะห่าง ก็ MathAbs(zigzagValue[0]-zigzagValue[1]) ไปเลย
ลองเอาไปปรับดูครับ
-
:-* :-* :-* :-* :-*
ขอบคุณท่าน hyperxeon มากมายครับ
-
ขอถามต่อครับ 2 ฟังก์ชั่นของผมไม่ยอมทำงานครับ ช่วยดูให้หน่อยครับ
โค้ดการตรวจสอบเวลาการเปิดออเดอร์นานเกินกำหนดครับ
โดยตรวจสอบออเดอร์ล่าสุด ว่าเปิดนานเกินที่กำหนดหรือไม่
ถ้านานเกินกว่ากำหนด ให้ไปตรวจสอบว่า Profit ทั้งหมดเป็นบวกมั้ย
ถ้าบวกมากกว่า 0 ให้ปิดออเดอร์ทั้งหมดเลย
ถ้าลบก็ไม่ต้องทำอะไร
เช่น ถ้าเรากำหนด CloseOrderTime = 2
extern int CloseOrderTime = 0;
//+------------------------------------------------------------------+
//| validate Overtime Order to Close ฟังก์ชั้นตรวจสอบเวลา |
//+------------------------------------------------------------------+
int CloseOrderTimeed(){
datetime time1,time2;
int type,timeh1,timeh2;
for(int i=OrdersTotal()-1;i<=0;i--){
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) break;
if(OrderSymbol()==Symbol()){
type = OrderType();
if((type==OP_BUY) || (type==OP_SELL)){
time1 = OrderOpenTime();
time2 = TimeCurrent();
time2 = time2-time1;
timeh1 = CloseOrderTime*3600;
timeh2 = TimeHour(time2);
if(timeh2>timeh1){
double profit = AccountProfit();
int cPrice=(CountOrder(OP_BUY)+CountOrder(OP_BUY)-1)*abs;
if(cPrice<0)cPrice=0;
if(profit>cPrice){
//--|||
for(i=OrdersTotal()-1;i<=0;i--){
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) break;
if(OrderSymbol()==Symbol()){
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
type = OrderType();
if(type==OP_BUY)OrderClose(OrderTicket(),OrderLots(),Bid,3,Yellow);
if(type==OP_SELL)OrderClose(OrderTicket(),OrderLots(),Ask,3,Yellow);
if(type!=OP_SELL && type!=OP_BUY)OrderDelete(OrderTicket());
}
}
//--|||
}
}
}
}
}
return(0);
}
ฟังก์ชั่น กำหนดความเสี่ยง ถ้ากำหนด 10
ให้ฟังก์ชั่นไปตรวจสอบการขาดทุนเท่าที่เรากำหนด
โดยเอาเงินทุนที่ของเราไปคิด
ถ้าติดลบถึงที่เรากำหนด ก็จะปิดออเดอร์ทั้งหมด
extern double Risk = 0;//10%
//+------------------------------------------------------------------+
//| Calculate Risk |
//+------------------------------------------------------------------+
int RiskOrder(){
Print("RiskOrder() Not: 001");
double profit = AccountProfit();
if(profit<0){
double persen = Risk/100;
int type,wasted = AccountFreeMargin()*persen;
profit = MathAbs(profit);
if(profit>=wasted){
//Close Order
Print("--------------------RiskOrder--------------------------");
for(int i=OrdersTotal()-1;i<=0;i--){
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) break;
if(OrderSymbol()==Symbol()){
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
type = OrderType();
if(type==OP_BUY)OrderClose(OrderTicket(),OrderLots(),Bid,3,Yellow);
if(type==OP_SELL)OrderClose(OrderTicket(),OrderLots(),Ask,3,Yellow);
if(type!=OP_SELL && type!=OP_BUY)OrderDelete(OrderTicket());
}
}
}
}
//---- wait for 10 seconds
//Sleep(10000);
return(0);
}
-
มันมี code ส่วนอื่นด้วยนิครับ นอกเหนือจากที่คุณโพสลงเวบ
-
ใช่ครับ admin
แต่ตอนนี้เหมือนแก้ไขจะได้แล้วครับ
เดียวมีปัญหาจะมาถามใหม่ครับ
ขอบคุณแห่งเว็บนี้มากมายเลยครับ
-
admin ครับ
จะมีวิธีการจำกัดว่าแต่ละวัน จะเปิดออเดอร์ได้ไม่เกินที่เรากำหนดครับ
ต้องเขียนอย่างไรบ้างครับ
มีตัวอย่างโค้ดให้ศึกษามั้ยครับ
-
ตัวอย่างไม่มีอะไครับ แต่สิงที่คุณต้องการต้องใช้หลักการดังนี้ครับ
1.สร้างตัวแปรขึ้นมา 3 ตัวเอาไวนับจำนวน Order ดังต่อไปนี้
1.1 Order ที่เปิดอยู่แล้วมี OrderopenTime เป็นวันนี้
1.2 Order ที่ปิดไปแล้วแต่มีOrderopentime เป้นวันนี้
1.3 ผลรวมของข้อ 1.1+1.2 คือจำนวน Order ทั้งหมดที่มี Orderopentime .นวันนี้ครับ
2.ทำการวน loop ใช้ Orderselect เพื่อตรวจสอบเวลาเปิดของ ที่กำลังเปิด โดยใช้เงื่อนไขตรวจสอบ Orderopentime ของ Order ว่าตรงกับวันนี้หรือไม่ถ้าตรงให้เราบวก ตัวแปรที่ค่าในข้อ 1.1 ไปทีละ 1
3.ทำการวน loop ใช้ Orderselect เพื่อตรวจสอบเวลาเปิดของ ที่ปิดไปแล้ว โดยใช้เงื่อนไขตรวจสอบ Orderopentime ของ Order ว่าตรงกับวันนี้หรือไม่ถ้าตรงให้เราบวก ตัวแปรที่ค่าในข้อ 1.2 ไปทีละ 1
4.ให้เอาผลลัพท์ในข้อ 2+3 จะได้จำนวน Order ที่เปิดในวันนี้ทั้งหมด จากนั่นขึ้นก็ใช้เงื่อนไขตรวจสอบต่อไปถ้าผลลัทธ์ที่ได้มากกว่าหรือเท่ากับค่าที่ตั้งไวให้เปิดได้ต่อวันก็ใช้ return 0 จบการทำงาน EA ออกไปครับ
-
ขอบคุณมากครับ admin เข้าใจล่ะ
-
admin ครับ
ผมมีข้อสงสัยอยู่ข้อนึงครับ
คือการเปิดออเดอร์ไม่ได้อาจจะมีหลายสาเหตุ
การเปิดของผมจะเป็น 0.01,0.02,0.04 (x 2 ไปเรื่อยๆครับ)
1.การเปิดออเดอร์ครั้งแรกจะเป็น lost=0.01 และตั้ง pending order เอาไว้ lost=0.01*2
2.เมื่อการฟวิ่งไปชนออเดอร์ที่ 2(ที่ตั้ง pending ไว้) ea จะตั้ง pending order อีก 1 ออเดอร์สแตนบายไว้เลยที่ lost=0.04
3.ถ้ายังไม่ชน TP จะทำตาม(ข้อ 2.) แบบนี้ไปเรื่อยๆครับ แต่ถ้าชน TP แล้วจะไปเริ่มใหม่ที่ (ข้อ 1.)
ปัญหาที่เจอคือ
1.ถ้า profit เป็นลบ ไปเรื่อยๆ จะไม่สามารถเปิดออเดอร์ได้
2. ถ้าคำนวน(x2) ได้ lost ที่จะเปิดออเดอร์แล้ว แต่ดังมากเกิน NormalizeDouble(MarketInfo(Symbol(), MODE_MAXLOT),2);
ผมจะทำไงดีครับ
คิดได้อย่างเดียวคือ
เช่น
ออเดอร์ที่ตั้ง pending lost=0.06 แต่ส่งคำสั่งไปไม่สามารถตั้งได้
จะเอา 0.06 ทำอย่างไงก็ได้ให้ตั้งออเดอร์ได้
โดยอาจจะแบ่ง lost ให้ย่อยๆเป็น 0.01 (6ไม้) หรือ 0.02 (3ไม้)
หรือว่ามีวิธีที่ดีกว่านี่ครับ
และเขียนโค้ดไม่ออกเลยครับ
-
1.ถ้า profit เป็นลบ ไปเรื่อยๆ จะไม่สามารถเปิดออเดอร์ได้
สาเหตุที่คาดว่าน่าจะเป็น
(1) Margin Level ต่ำกว่า 100%
(2) Margin ที่จะใช้ซื้อใน Order ใหม่ มากกว่า Account Equity ที่มีอยู่
แต่ถ้าให้ชัวร์ ดูว่า Error code อะไร แล้วไล่แก้โค๊ดใน EA อีกที
2. ถ้าคำนวน(x2) ได้ lost ที่จะเปิดออเดอร์แล้ว แต่ดังมากเกิน NormalizeDouble(MarketInfo(Symbol(), MODE_MAXLOT),2);
สำหรับปัญหานี้ต้อง แบ่งซอย Lot เอาอย่างเดียว ไม่สามารถเปิดเกิน MAXLOT ที่ Broker กำหนดได้
หลักการของ EA ของคุณ ดูแล้วจะเป็นลักษณะแบบ Martingale หรือ ทบล็อต
ขอแนะนำว่า ต้องบริหาร Margin Level หรือจำกัดจำนวนไม้ที่จะซื้อให้ดีๆ แต่ถ้าอยากวางไม้เยอะๆ ให้ลดตัวคูณลง จาก 2.0 -> 1.5 หรืออะไรตามใจชอบก็ได้
ไม่อย่างนั้น ถ้าโดนลากผิดทาง EA จะเปิดไม้ใหม่เรื่อยๆด้วย Lot ที่ใหญ่ขึ้นเรื่อยๆเช่นกัน ที่นี้แหล่ะ จำนวน Lots รวมทั้งหมดมันเยอะ เวลามันขยับ pip นึง คุณจะได้ลุ้นตัวโก่ง และโอกาสที่จะล้างพอร์ตมีสูงขึ้น
-
ขอบคุณ hyperxeon มากครับ
แล้วผมจะทำไงดีครับ ที่เขียนอีเอนี่
เพราะอามรมณ์ไม่แข็งพอ ก็คิดได้ว่าเขียนอีเอเทรดเองเลย
ตัดปัญหาเรื่องอารมณ์ไปล
จึงเอาระบบ Lucky7 และ zigzag มาผสมกัน
ลองเขียนอีเอเอง
แต่ก็ไม่สำเร็จ
Back Test ได้ตามที่แนบไฟล์นี้ มันไม่ใช่สิ่งที่ต้องการ
เพราะผมเลือก Model:Control points แต่เลือก Every Tick ผลที่ได้กลับเป็นคนล่ะอย่างเลยครับ
ผมเองก้ไม่เคยใช้ back test มาก่อน
และใน http://thailandinvestorclub.com/index.php?topic=1086.0
คุณ tiktok บอกว่า Every Tick ใกล้เคียงกับตลาดจริงที่สุดแล้ว ผมจึงอยากจะแก้ไขให้ใช้งานจริงๆ