概览:
脚本目录:
MQL4\Experts\E_Auto_TradeBy_Strategy.mq4
MQL4\Libraries\E_Common_Help.mq4
MQL4\Include\E_Common_Help.mqh
懂的自然知道怎么用。仅供参考,照搬不一定盈利。
交易有风险,祝早日实现稳定盈利。
代码:
1)E_Auto_TradeBy_Strategy.mq4
//+------------------------------------------------------------------+
//| E_Auto_TradeBy_Strategy.mq4 |
//| wouter.zhong |
//| 策略交易 |
//+------------------------------------------------------------------+
#property library
#property copyright "wouter.zhong"
#include <E_Common_Help.mqh> //加载辅助类
//配置参数
int trendLineNums = 10; //趋势行情K线数
int shakeLineNums = 12; //震荡行情K线数
int imaBackLineNums = 10; //均线回踩行情K线数
int slipPoint = 30; //滑点数
//1.缺口策略不适用的币种
string strategyGapNoSym[] = {"XAUUSD"}; //黄金缺口经常不回补
//2.三宾策略不适用的币种
string strategyThreeLineNoSym[] = {};
//3.趋势跟进策略不适用的币种
string strategyImaTrendNoSym[] = {};
//4.均线回踩策略不适用的币种
string strategyImaBackNoSym[] = {"USDCHF"};
//5.震荡策略不适用的币种
string strategyShakeNoSym[] = {"XAUUSD", "CADCHF"};
//6.旗型策略不适用的币种
string strategyFlagNoSym[] = {"USDJPY", "USDCHF", "CADCHF"};
/**
* 辅助函数1:判断币种是否不适用某策略
* @return bool
*/
bool isSmybolSuitStrategy(string symbol="", int straType=1)
{
if(symbol==""){
symbol = Symbol();
}
//待校验的策略
string strategyNoSym[];
switch (straType){
case 1:
ArrayCopy(strategyNoSym, strategyGapNoSym, 0, 0, WHOLE_ARRAY); //缺口
break;
case 2:
ArrayCopy(strategyNoSym, strategyThreeLineNoSym, 0, 0, WHOLE_ARRAY); //三宾
break;
case 3:
ArrayCopy(strategyNoSym, strategyImaTrendNoSym, 0, 0, WHOLE_ARRAY); //趋势跟进
break;
case 4:
ArrayCopy(strategyNoSym, strategyImaBackNoSym, 0, 0, WHOLE_ARRAY); //均线回踩
break;
case 5:
ArrayCopy(strategyNoSym, strategyShakeNoSym, 0, 0, WHOLE_ARRAY); //震荡
break;
case 6:
ArrayCopy(strategyNoSym, strategyFlagNoSym, 0, 0, WHOLE_ARRAY); //旗型
break;
}
//数组为空,对所有币种都适用
int size = ArrayRange(strategyNoSym, 0);
if(size==0){
return true;
}
//循环匹配
int i;
for(i=0; i<size; i++){
if(strategyNoSym[i] == symbol){
//Print("当前策略限制当前币种:"+ symbol +",策略:"+ straType);
return false;
}
}
return true;
}
/**
* 策略一:缺口
* @return null
*/
void makeOrderByGap(string symbol="", int period=PERIOD_H1)
{
if(symbol==""){
symbol = Symbol();
}
//校验币种是否适用
bool checkIsSuit = isSmybolSuitStrategy(symbol, 1);
if(checkIsSuit == false){
//Print("缺口策略-限制当前币种:"+ symbol);
return;
}
//缺口数据
double gapPrice = getGapInfo(symbol, period, 1); //缺口价差
double gapRatio = getGapInfo(symbol, period, 2); //缺口价差比例
//小于5个点的缺口不值得做
if(gapRatio <= 0.05){
return;
}
//检查是否重复下单
bool checkRepeatOrder = hasRepeatEaOrder(symbol, period, 201);
if(checkRepeatOrder==true){
//Print("缺口策略,重复下单。币种:"+ symbol);
return;
}
//币种小数位
int precision = cuSymbolPrecision();
//下挂单
if(gapRatio > 0.05){
string orderType; //挂单类型
double orderLots = getMakeLots(); //下单量
double openPoint = DoubleToStr(iOpen(symbol,period,0) + 1.5*gapPrice, precision); //挂单价格
double lossPoint = DoubleToStr(iOpen(symbol,period,0) + 2.5*gapPrice, precision); //止损价格
double winPoint = DoubleToStr(iOpen(symbol,period,0) - gapPrice, precision); //止盈价格
string comment = "缺口"; //备注
int magic = 201; //magic number
string arrowColor = Yellow; //颜色
string expiration = TimeToStr(iTime(symbol, period, 0) + 18*60*period); //有效期
if(gapPrice > 0){ //跳多
orderType = OP_SELLLIMIT;
}else{ //跳空
orderType = OP_BUYLIMIT;
}
double lossPointNums = MathAbs(100*(openPoint - lossPoint)); //止损点数
double winPointNums = MathAbs(100*(openPoint - winPoint)); //止盈点数
//打日志
Print("缺口策略下单,币种:"+ symbol +", 类型:"+ orderType +", 手数:"+ orderLots +", 挂单价格:"+ openPoint +", 止损:"+ lossPoint+
", 止损点数:"+ lossPointNums+", 止盈:"+ winPoint +", 止盈点数:"+ winPointNums +",过期时间:"+ expiration + ", gapPrice:"+gapPrice+", gapRatio:"+gapRatio);
//发邮件 Todo
//挂单
int ticket = OrderSend(symbol, orderType, orderLots, openPoint, slipPoint, lossPoint, winPoint, comment, magic, expiration, arrowColor);
if(ticket < 0){
Print("OrderSend Error Code = #", getErrorMsgByCode(GetLastError()));
}
}
}
/**
* 策略二:依据黑/白三宾K线下单
* @return null
*/
void makeOrderByThreeLine(string symbol="", int period=PERIOD_H1)
{
if(symbol==""){
symbol = Symbol();
}
//校验币种是否适用
bool checkIsSuit = isSmybolSuitStrategy(symbol, 2);
if(checkIsSuit == false){
//Print("三宾策略-限制当前币种:"+ symbol);
return;
}
//判断是否白三宾/黑三宾
int checkRet = checkThreeLineSignal(symbol, period);
if(checkRet==0){
//Print("非三宾行情。币种:"+ symbol + ",周期:"+period);
return;
}
//检查是否重复下单
bool checkRepeatOrder = hasRepeatEaOrder(symbol, period, 202);
if(checkRepeatOrder==true){
//Print("均线策略,重复下单。币种:"+ symbol);
return;
}
//币种小数位
int precision = cuSymbolPrecision();
//下单
if(checkRet > 0){
string orderType; //挂单类型
double orderLots = getMakeLots(); //下单量
double openPoint; //挂单价
double lossPoint; //止损价
double winPoint; //止盈价
string comment = "ThreeLine order"; //备注
int magic = 202; //自定义数字;订单的指定号码。可以当作用户定义的识别码使用
string arrowColor = Yellow; //颜色
string str_name; //策略名
double blockLength = MathAbs(iClose(symbol,period,1) - iOpen(symbol,period,3)); //三根线总长
string expiration = TimeToStr(iTime(symbol, period, 0) + 9*60*period); //有效期
if(checkRet==1){ //白三宾
orderType = OP_BUY;
openPoint = DoubleToStr(MathMax(Ask, iOpen(symbol, period, 1)), precision); //下单价
lossPoint = DoubleToStr(iOpen(symbol,period,3) - 0.25*blockLength, precision); //止损价
winPoint = DoubleToStr(iClose(symbol,period,1) + 1.25*blockLength, precision); //止盈价
str_name = comment = "白三宾";
}else if(checkRet==2){ //黑三宾
orderType = OP_SELL;
openPoint = DoubleToStr(MathMin(Bid, iOpen(symbol, period, 1)), precision);
lossPoint = DoubleToStr(iOpen(symbol,period,3) + 0.25*blockLength, precision);
winPoint = DoubleToStr(iClose(symbol,period,1) - 1.25*blockLength, precision);
str_name = comment = "黑三宾";
}
double lossPointNums = MathAbs(100*(openPoint - lossPoint)); //止损点数
double winPointNums = MathAbs(100*(openPoint - winPoint)); //止盈点数
//打日志
Print(str_name +"策略下单,币种:"+ symbol +", 类型:"+ orderType +", 手数:"+ orderLots +", 下单价格:"+ openPoint +", 止损:"+ lossPoint+
", 止损点数:"+ lossPointNums+", 止盈:"+ winPoint +", 止盈点数:"+ winPointNums +",过期时间:"+ expiration);
//下单
int ticket = OrderSend(symbol, orderType, orderLots, openPoint, slipPoint, lossPoint, winPoint, comment, magic, 0, arrowColor);
if(ticket < 0){
Print("OrderSend Error Code = #", getErrorMsgByCode(GetLastError()));
}
}
}
/**
* 策略三:趋势跟进
* @return null
*/
void makeOrderByImaTrend(string symbol="", int period=PERIOD_H1)
{
if(symbol==""){
symbol = Symbol();
}
//校验币种是否适用
bool checkIsSuit = isSmybolSuitStrategy(symbol, 3);
if(checkIsSuit == false){
//Print("均线策略-限制当前币种:"+ symbol);
return;
}
//判断上升or下跌趋势
int checkTrend = checkTendencyByIma(symbol, period, trendLineNums);
if(checkTrend==0){
return;
}
//检查是否重复下单
bool checkRepeatOrder = hasRepeatEaOrder(symbol, period, 203);
if(checkRepeatOrder==true){
//Print("均线策略,重复下单。币种:"+ symbol);
return;
}
//币种小数位
int precision = cuSymbolPrecision();
//下现价单
if(checkTrend > 0){
string orderType; //挂单类型
double orderLots = getMakeLots(); //下单量
double openPoint; //挂单价
double lossPoint; //止损价
double winPoint; //止盈价
string comment = "趋势"; //备注
int magic = 203; //自定义数字
string arrowColor = Yellow; //颜色
string orderTypeName;
string expiration = TimeToStr(iTime(symbol, period, 0) + 9*60*period); //有效期
double blockLength = MathAbs(iOpen(symbol, period, trendLineNums) - iOpen(symbol, period, 1)); //K线区域长度
if(checkTrend==1){ //上升趋势
orderType = OP_BUY; //1
orderTypeName = "BUY";
openPoint = DoubleToStr(MathMax(Ask, iOpen(symbol, period, 1)), precision); //下单价
lossPoint = DoubleToStr(openPoint - 0.5*blockLength, precision); //止损价
winPoint = DoubleToStr(openPoint + 1.5*blockLength, precision); //止盈价
}else if(checkTrend==2){ //下跌趋势
orderType = OP_SELL; //0
orderTypeName = "SELL";
openPoint = DoubleToStr(MathMin(Bid, iOpen(symbol, period, 1)), precision);
lossPoint = DoubleToStr(openPoint + 0.5*blockLength, precision);
winPoint = DoubleToStr(openPoint - 1.5*blockLength, precision);
}
//止损点数
double lossPointNums = MathAbs(100*(openPoint - lossPoint));
//止盈点数
double winPointNums = MathAbs(100*(openPoint - winPoint));
//打日志
Print("趋势策略下单,币种:"+ symbol +", 类型:"+ orderTypeName +", 手数:"+ orderLots +", 建仓:"+ openPoint +", 止损:"+ lossPoint+
", 止损点数:"+ lossPointNums+", 止盈:"+ winPoint +", 止盈点数:"+ winPointNums +",过期时间:"+ expiration);
int ticket = OrderSend(symbol, orderType, orderLots, openPoint, slipPoint, lossPoint, winPoint, comment, magic, expiration, arrowColor);
if(ticket < 0){
Print("OrderSend Error Code = #", getErrorMsgByCode(GetLastError()));
}
}
}
/**
* 策略四:均线回踩
* @return null
*/
void makeOrderByImaBack(string symbol="", int period=PERIOD_H4)
{
if(symbol==""){
symbol = Symbol();
}
//校验币种是否适用
bool checkIsSuit = isSmybolSuitStrategy(symbol, 3);
if(checkIsSuit == false){
//Print("均线策略-限制当前币种:"+ symbol);
return;
}
//检查是否重复下单
bool checkRepeatOrder = hasRepeatEaOrder(symbol, period, 203);
if(checkRepeatOrder==true){
//Print("均线策略,重复下单。币种:"+ symbol);
return;
}
//判断上升回踩or下跌回踩
int checkImaBack = checkImBackType(symbol, period, imaBackLineNums);
if(checkImaBack==0){
return;
}
//币种小数位
int precision = cuSymbolPrecision();
//区间K线最高价
double MaxPrice = getGroupKLinesData(symbol, period, imaBackLineNums, 1);
//区间K线最低价
double MinPrice = getGroupKLinesData(symbol, period, imaBackLineNums, 2);
//区间K线平均长度
double MeanHeight = DoubleToStr(getGroupKLinesData(symbol, period, imaBackLineNums, 3), precision);
//下现价单
if(checkImaBack > 0){
string orderType; //挂单类型
double orderLots = getMakeLots(); //下单量
double openPoint; //挂单价
double lossPoint; //止损价
double winPoint; //止盈价
string comment = "均线"; //备注
int magic = 204; //自定义数字
string arrowColor = Yellow; //颜色
string expiration = 0; //有效期
string orderTypeName;
if(checkImaBack==1){ //上升回踩
orderType = OP_BUY; //1
orderTypeName = "BUY";
openPoint = DoubleToStr(MathMax(Ask, iOpen(symbol, period, 1)), precision); //下单价
lossPoint = DoubleToStr(openPoint - 2*MeanHeight, precision); //止损价
winPoint = DoubleToStr(MaxPrice + 6*MeanHeight, precision); //止盈价
}else if(checkImaBack==2){ //下跌回踩
orderType = OP_SELL; //0
orderTypeName = "SELL";
openPoint = DoubleToStr(MathMin(Bid, iOpen(symbol, period, 1)), precision);
lossPoint = DoubleToStr(openPoint + 2*MeanHeight, precision);
winPoint = DoubleToStr(MinPrice - 6*MeanHeight, precision);
}
//止损点数
double lossPointNums = MathAbs(100*(openPoint - lossPoint));
//止盈点数
double winPointNums = MathAbs(100*(openPoint - winPoint));
//打日志
Print("均线回踩策略下单,币种:"+ symbol +", 类型:"+ orderTypeName +", 手数:"+ orderLots +", 建仓:"+ openPoint +", 止损:"+ lossPoint+
", 止损点数:"+ lossPointNums+", 止盈:"+ winPoint +", 止盈点数:"+ winPointNums +",过期时间:"+ expiration);
int ticket = OrderSend(symbol, orderType, orderLots, openPoint, slipPoint, lossPoint, winPoint, comment, magic, expiration, arrowColor);
if(ticket < 0){
Print("OrderSend Error Code = #", getErrorMsgByCode(GetLastError()));
}
}
}
/**
* 策略五:震荡
* @ 往前15根K线,
* @ 最高价 - 最低价 <= 平均K线长度的50%
* @return null
*/
void makeOrderByShake(string symbol="", int period=PERIOD_H1)
{
if(symbol==""){
symbol = Symbol();
}
//校验币种是否适用
bool checkIsSuit = isSmybolSuitStrategy(symbol, 3);
if(checkIsSuit == false){
//Print("均线策略-限制当前币种:"+ symbol);
return;
}
//检查是否重复下单
bool checkRepeatOrder = hasRepeatEaOrder(symbol, period, 204);
if(checkRepeatOrder==true){
//Print("震荡策略,重复下单。币种:"+ symbol);
return;
}
//K线最高价
double MaxPrice = getGroupKLinesData(symbol, period, shakeLineNums, 1);
//K线最低价
double MinPrice = getGroupKLinesData(symbol, period, shakeLineNums, 2);
//K线平均长度
double MeanHeight = DoubleToStr(getGroupKLinesData(symbol, period, shakeLineNums, 3), 4); //保留4位小数
//Print("最高价:"+ MaxPrice +",最低价:"+ MinPrice +",最大价差:"+ (MaxPrice-MinPrice) +",平均K线长度:"+MeanHeight +",周期:"+ period +",K线数:"+ shakeLineNums);
//非震荡行情
double priceGap = MaxPrice - MinPrice;
if(priceGap > 2*MeanHeight || MeanHeight < 50*Point){
return;
}
//币种小数位
int precision = cuSymbolPrecision();
//震荡行情,下挂单(OP_BUYLIMIT)
string orderType = OP_BUYLIMIT; //挂单类型
double orderLots = getMakeLots(); //下单量
double openPoint = DoubleToStr(MinPrice + 0.1*MeanHeight, precision); //挂单价
double lossPoint = DoubleToStr(MinPrice - 0.5*MeanHeight, precision); //止损价
double winPoint = DoubleToStr(MaxPrice - 0.1*MeanHeight, precision); //止盈价
string comment = "震荡"; //备注
int magic = 205; //自定义数字
string arrowColor = Green; //颜色
string expiration = TimeToStr(iTime(symbol, period, 0) + 10*60*period); //有效期
int ticketBuy = OrderSend(symbol,orderType,orderLots,openPoint,slipPoint,lossPoint,winPoint,comment,magic,expiration,arrowColor);
if(ticketBuy < 0){
Print("BUYLIMIT OrderSend Error Code = #", getErrorMsgByCode(GetLastError()));
}
double lossPointNums = MathAbs(100*openPoint - lossPoint); //止损点数
double winPointNums = MathAbs(100*openPoint - winPoint); //止盈点数
Print("震荡策略下单,币种:"+ symbol +", 类型:BUYLIMIT, 手数:"+orderLots+", 挂单价格:"+openPoint+", 止损:"+lossPoint+
", 止损点数:"+ lossPointNums+", 止盈:"+ winPoint +", 止盈点数:"+ winPointNums +",过期时间:"+ expiration);
//下挂单(OP_SELLLIMIT)
string orderType_s = OP_SELLLIMIT; //挂单类型
double orderLots_s = getMakeLots(); //下单量
double openPoint_s = DoubleToStr(MaxPrice - 0.1*MeanHeight, precision); //挂单价
double lossPoint_s = DoubleToStr(MaxPrice + 0.5*MeanHeight, precision); //止损价
double winPoint_s = DoubleToStr(MinPrice + 0.1*MeanHeight, precision); //止盈价
string comment_s = "震荡"; //备注
int magic_s = 204; //自定义数字
string arrowColor_s = Yellow; //颜色
int ticketSell = OrderSend(symbol,orderType_s,orderLots_s,openPoint_s,slipPoint,lossPoint_s,winPoint_s,comment_s,magic_s,expiration,arrowColor_s);
if(ticketSell < 0){
Print("SELLLIMIT OrderSend Error Code = #", getErrorMsgByCode(GetLastError()));
}
//止损点数
double lossPointNums_s = MathAbs(100*(openPoint_s - lossPoint_s));
//止盈点数
double winPointNums_s = MathAbs(100*(openPoint_s - winPoint_s));
Print("震荡策略下单,币种:"+symbol+", 类型:SELLLIMIT, 手数:"+orderLots_s+", 挂单价格:"+openPoint_s+", 止损:"+lossPoint_s+
", 止损点数:"+ lossPointNums_s+", 止盈:"+ winPoint_s +", 止盈点数:"+ winPointNums_s +",过期时间:"+ expiration);
}
/**
* 策略六:旗型
* @return null
*/
void makeOrderByFlag(string symbol="", string period=PERIOD_H1)
{
if(symbol==""){
symbol = Symbol();
}
//校验币种是否适用
bool checkIsSuit = isSmybolSuitStrategy(symbol, 3);
if(checkIsSuit == false){
//Print("均线策略-限制当前币种:"+ symbol);
return;
}
//Todo
}
/**
* 报价变动事件
*/
void OnTick()
{
//风控 -- 生命线!!!
if(AccountEquity()> 0){
//makeOrderByGap(Symbol(), PERIOD_H1); //1.缺口
//makeOrderByThreeLine(Symbol(), PERIOD_H1); //2.三宾
//makeOrderByImaTrend(Symbol(), PERIOD_H1); //3.趋势跟进
makeOrderByImaBack(Symbol(), PERIOD_H1); //4.均线回踩
//makeOrderByShake(Symbol(), PERIOD_H1); //5.震荡
//makeOrderByFlag(Symbol(), PERIOD_H1); //6.旗型
}
}
2)E_Common_Help.mq4
//+------------------------------------------------------------------+
//| E_Common_Help.mq4 |
//| wouter.zhong |
//| 辅助函数模块 -- 实现 |
//+------------------------------------------------------------------+
#property copyright "2021,wouter.zhong"
#property library
/**
* 常用函数列表
*/
void helpList()
{
/**
# 账户函数
Print("账户余额:" + MTDAccountBalance());
Print("账户净值:" + MTDAccountEquity());
Print("已用保证金:" + MTDAccountMargin());
Print("可用保证金:" + MTDAccountFreeMargin());
Print("杠杆:" + MTDAccountLeverage());
Print("总盈亏:" + MTDAccountProfit());
# 数学函数
Print("比例:" + MathMod(205,100)); //取模
Print("比例:" + MathFloor(200/100)); //比例 向下取整
# 交易函数
Print("当前币种:" + Symbol());
Print("当前币种-昨天开盘价:" + iOpen(Symbol(), PERIOD_D1, 1));
Print("当前币种-昨天收盘价:" + iClose(Symbol(), PERIOD_D1, 1));
Print("当前币种-今天开盘价:" + iOpen(Symbol(), PERIOD_D1, 0));
Print("当前币种-上根K线开盘价(H1):" + iOpen(Symbol(), PERIOD_H1, 1));
Print("当前币种-上根K线收盘价(H1):" + iClose(Symbol(), PERIOD_H1, 1));
Print("当前币种-当前K线开盘价(H1):" + iOpen(Symbol(), PERIOD_H1, 0));
Print("当前币种-当前K线开盘时间(H1):" + iTime(Symbol(), PERIOD_H1, 0));
# 订单函数
Print("订单编号:" + OrderProfit());
Print("订单盈亏:" + OrderProfit());
# 时间函数
Print("PERIOD_H1:"+PERIOD_H1); //输出60
Print("PERIOD_H1,当前K线开盘时间:"+ iTime(symbol, period, 0)); //1482818400
Print("PERIOD_H1,当前K线开盘时间,延迟H1:"+ (iTime(symbol, period, 0) + PERIOD_H1)); //1482818460
Print("PERIOD_H4:"+PERIOD_H4);
Print("PERIOD_D1:"+PERIOD_D1);
*/
}
/**
* 获取当前挂单数量
*/
int getPendingOrderNums()
{
int i;
int num = 0;
for(i=OrdersTotal()-1;i>=0;i--){
if(OrderSelect(i,SELECT_BY_POS)){
if(OrderType()!=OP_BUY && OrderType()!=OP_SELL){ //挂单
num ++;
}
}
}
return num;
}
/**
* 获取最近一个非挂单的订单号
*/
string getLastCuTicket(){
int i;
int num = 0;
string orderTicket = "";
for(i=OrdersTotal()-1;i>=0;i--){
if(OrderSelect(i,SELECT_BY_POS)){
if(OrderType()==OP_BUY || OrderType()==OP_SELL){
orderTicket = OrderTicket();
return orderTicket;
}
}
}
return orderTicket;
}
/**
* 获取MTDMarketInfo的mode
*/
string getModeByType(string orderType)
{
string mode;
if(orderType == OP_SELL){
mode = MODE_ASK;
}else if(orderType == OP_BUY){
mode = MODE_BID;
}else{
mode = MODE_BID;
}
return mode;
}
/**
* 获取缺口点数信息
* @param smybol 币种
* @param period 周期级别
* @param dataType 返回数据类型
* @return double
*/
double getGapInfo(string symbol="", string period=PERIOD_H1, int dataType=1)
{
if(symbol==""){
symbol = Symbol();
}
double gapPrice = iOpen(symbol, period, 0) - iClose(symbol, period, 1); //当前K线开盘价 - 上根K线收盘价
double gapRatio = 100*MathAbs(gapPrice)/iClose(symbol, period, 1);
if(dataType==1){
return gapPrice;
}else if(dataType==2){
return gapRatio;
}
return 0.00;
}
/**
* 获取可下单手数
* @ 依据现有保证金
* @return int
*/
double getMakeLots()
{
double lots;
double lotsBase = 0.01;
double freeMargin = AccountFreeMargin(); //账户可用保证金
int multiple = MathFloor(freeMargin/100); //倍数向下取整。等于100时值为1
if(freeMargin < 200){
lots = lotsBase;
}else if(freeMargin <= 2000){
lots = multiple*lotsBase; //2千美元下0.2手,即10%仓位
}else if(freeMargin <= 10000){
lots = 0.8*multiple*lotsBase; //1万美元下0.08手,即8%仓位
}else if(freeMargin <= 50000){
lots = 0.6*multiple*lotsBase; //6%仓位
}else if(freeMargin <= 200000){
lots = 0.4*multiple*lotsBase; //4%仓位
}else if(freeMargin <= 800000){
lots = 0.3*multiple*lotsBase; //3%仓位
}else{
lots = 0.2*multiple*lotsBase; //2%仓位
}
return lots;
}
/**
* 获取某期间内 下单总数
* @(不含被删除/未触发的挂单,不含未平仓订单)
* @param smybol 筛选的币种
* @param noSmybol 排除的币种
* @PS:系统时间加6小时,即北京时间
*/
int getPeriodOrderNums(int days=1, string smybol="", string noSmybol="")
{
string year = TimeYear(TimeLocal()); //北京时间
string month = TimeMonth(TimeLocal());
string day = TimeDay(TimeLocal());
string localDayEnd = year +"."+ month +"."+ day +" 23:59:59"; //期间截至日的时间
int i;
int num = 0;
int startCount = OrdersHistoryTotal(); //历史总订单数
for(i=0; i<startCount; i++){ //倒序
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)){
//Print("编号:"+ i +", 币种:"+ OrderSymbol() +", 订单开仓时间:" + (OrderOpenTime()+6*3600) +", 类型: "+ OrderType() +", 盈亏: "+ OrderProfit());
//筛选币种判断
if(smybol != "" && OrderSymbol()!=smybol){
continue;
}
//排除币种判断
if(noSmybol != "" && OrderSymbol()==noSmybol){
continue;
}
//统计
if(OrderOpenTime() < StrToTime(localDayEnd)
&& OrderOpenTime() >= (StrToTime(localDayEnd) - 86400*days)
&& (OrderType()==OP_BUY || OrderType()==OP_SELL))
{
num++;
}
}
}
//Print("开始时间:" + TimeToStr((StrToTime(localDayEnd) - 86400*days)) + ";截至时间:" + localDayEnd + "。期间下单总数: "+ num);
return num;
}
/**
* 获取某期间内的总盈亏
* @(不含被删除/未触发的挂单,不含未平仓订单)
* @PS:系统时间加6小时,即北京时间
*/
int getPeriodOrderLoss(int days=1)
{
string year = TimeYear(TimeLocal()); //北京时间
string month = TimeMonth(TimeLocal());
string day = TimeDay(TimeLocal());
string localDayEnd = year +"."+ month +"."+ day +" 23:59:59"; //期间截至日的时间
int i;
int lossNum = 0;
int startCount = OrdersHistoryTotal(); //历史总订单数
for(i=0; i<startCount; i++){ //倒序
if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)){
//Print("编号:"+ i +", 币种:"+ OrderSymbol() +", 订单开仓时间:" + (OrderOpenTime()+6*3600) +", 类型: "+ OrderType() +", 盈亏: "+ OrderProfit());
//统计
if(OrderOpenTime() < StrToTime(localDayEnd)
&& OrderOpenTime() >= (StrToTime(localDayEnd) - 86400*days)
&& (OrderType()==OP_BUY || OrderType()==OP_SELL))
{
lossNum = lossNum + OrderProfit();
}
}
}
return lossNum;
}
/**
* 判断是否白/黑三宾信号
* @param smybol 币种
* @param period 周期级别
* @return bool
*/
int checkThreeLineSignal(string symbol="", string period=PERIOD_H1)
{
if(symbol==""){
symbol = Symbol();
}
//前第1根K线
double openPrice_1 = iOpen(symbol, period, 1); //开盘价
double closePrice_1 = iClose(symbol, period, 1); //收盘价
double pGapRatio_1 = MathAbs(10000*(closePrice_1 - openPrice_1)/openPrice_1); //价差比例
//前第2根K线
double openPrice_2 = iOpen(symbol, period, 2); //开盘价
double closePrice_2 = iClose(symbol, period, 2); //收盘价
double pGapRatio_2 = MathAbs(10000*(closePrice_2 - openPrice_2)/openPrice_2); //价差比例
//前第3根K线
double openPrice_3 = iOpen(symbol, period, 3); //开盘价
double closePrice_3 = iClose(symbol, period, 3); //收盘价
double pGapRatio_3 = MathAbs(10000*(closePrice_3-openPrice_3)/openPrice_3); //价差比例
//Print("closePrice_1:"+ closePrice_1 +",openPrice_1:"+openPrice_1+ ",价差比例:"+ 10000*(closePrice_1-openPrice_1)/openPrice_1);
//Print("closePrice_2:"+ closePrice_2 +",openPrice_2:"+openPrice_2+ ",价差比例:"+ 10000*(closePrice_2-openPrice_2)/openPrice_2);
//Print("closePrice_3:"+ closePrice_3 +",openPrice_3:"+openPrice_3+ ",价差比例:"+ 10000*(closePrice_3-openPrice_3)/openPrice_3);
//iMA线,顺势判断
double mPrice23_1 = iMA(symbol, 0, 23, 0, MODE_SMA, PRICE_CLOSE, 1);
double mPrice23_2 = iMA(symbol, 0, 23, 0, MODE_SMA, PRICE_CLOSE, 2);
double mPrice23_3 = iMA(symbol, 0, 23, 0, MODE_SMA, PRICE_CLOSE, 3);
//白三宾(价差3到15最好,杆杠*100)
if((closePrice_1-openPrice_1>0 && openPrice_1>mPrice23_1 && pGapRatio_1>=3 && pGapRatio_1<=10) &&
(closePrice_2-openPrice_2>0 && openPrice_2>mPrice23_2 && pGapRatio_2>=3 && pGapRatio_2<=10) &&
(closePrice_3-openPrice_3>0 && openPrice_3>mPrice23_3 && pGapRatio_3>=3 && pGapRatio_3<=10))
{
return 1;
}
//黑三宾
if((openPrice_1-closePrice_1>0 && openPrice_1<mPrice23_1 && pGapRatio_1>=3 && pGapRatio_1<=10) &&
(openPrice_2-closePrice_2>0 && openPrice_2<mPrice23_2 && pGapRatio_2>=3 && pGapRatio_2<=10) &&
(openPrice_3-closePrice_3>0 && openPrice_3<mPrice23_3 && pGapRatio_3>=3 && pGapRatio_3<=10))
{
return 2;
}
return 0;
}
/**
* 判断上升/下跌趋势
* @param smybol 币种
* @param period 周期级别
* @param kLineNums K线根数
* double iMA(
* string symbol, // 计算指标数据上的货币对名称. NULL表示当前货币对
* int timeframe, // 时间周期。 可以时间周期列举任意值. 0表示当前图表的时间周期
* int ma_period, // 平均周期计算
* int ma_shift, // MA转移。 指标线垂直与图表的时间周期
* int ma_method, // MA方法。 它可以是其中任意 滑动平均值列举值
* int applied_price, // 应用的价格。 它可以是应用价格列举的任意值
* int shift // 显示缓冲采取的值的索引(往前第几根K线)
* );
* Open[1] 上跟K线的开盘价
* @return bool
*/
int checkTendencyByIma(string symbol="", string period=PERIOD_H1, int kLineNums=5)
{
if(symbol==""){
symbol = Symbol();
}
double maPrice23[];
double maPrice65[];
double openPrice[];
double closePrice[];
//set size
ArrayResize(maPrice23, kLineNums);
ArrayResize(maPrice65, kLineNums);
ArrayResize(openPrice, kLineNums);
ArrayResize(closePrice, kLineNums);
int i=0;
for(i=0; i<kLineNums; i++){
//往前第i+1根K线
//Print("iMA_Price:"+iMA(symbol, 0, 23, 0, MODE_SMA, PRICE_CLOSE, i+1) + ",索引i:"+i);
ArrayFill(maPrice23, i, 1, iMA(symbol, 0, 23, 0, MODE_SMA, PRICE_CLOSE, i+1)); //23MA线价格
ArrayFill(maPrice65, i, 1, iMA(symbol, 0, 65, 0, MODE_SMA, PRICE_CLOSE, i+1)); //65MA线价格
ArrayFill(openPrice, i, 1, Open[i+1]); //行情线开盘价
ArrayFill(closePrice, i, 1, Close[i+1]); //收盘价
//printf("maPrice23[%d] = %.6f", i, maPrice23[i]);
}
int upTrendNums = 0; //上升K线数
int downTrendNums = 0; //下降K线数
for(i=0; i<kLineNums; i++){
//Print("maPrice65_"+ i + ":"+ maPrice65[i] +",maPrice23_"+ i + ":"+ maPrice23[i] +",openPrice"+ i +":"+ openPrice[i]+",closePrice"+ i +":"+ closePrice[i]);
if(maPrice65[i]<maPrice23[i] && maPrice23[i]<openPrice[i] && openPrice[i]<closePrice[i]){
upTrendNums++;
}
if(maPrice65[i]>maPrice23[i] && maPrice23[i]>openPrice[i] && openPrice[i]>closePrice[i]){
downTrendNums++;
}
}
//Print("上升K线数:"+ upTrendNums +",下降K线数:"+ downTrendNums);
//上升趋势
if(upTrendNums >= MathFloor(kLineNums*0.8)){
return 1;
}
//下跌趋势
if(downTrendNums >= MathFloor(kLineNums*0.8)){
return 2;
}
//非趋势
return 0;
}
/**
* 判断上升回踩/下跌回踩
* 判断K线是否在均线 上/下
* @param smybol 币种
* @param period 周期级别
* @param kLineNums K线根数
* @return bool
*/
int checkImBackType(string symbol="", string period=PERIOD_H1, int kLineNums=10)
{
if(symbol==""){
symbol = Symbol();
}
double maPrice23[];
double maPrice65[];
double openPrice[];
double closePrice[];
//set size
ArrayResize(maPrice23, kLineNums);
ArrayResize(maPrice65, kLineNums);
ArrayResize(openPrice, kLineNums);
ArrayResize(closePrice, kLineNums);
int i=0;
for(i=0; i<kLineNums; i++){
//往前第i+1根K线
ArrayFill(maPrice23, i, 1, iMA(symbol, 0, 23, 0, MODE_SMA, PRICE_CLOSE, i+1)); //23MA线价格
ArrayFill(maPrice65, i, 1, iMA(symbol, 0, 65, 0, MODE_SMA, PRICE_CLOSE, i+1)); //65MA线价格
ArrayFill(openPrice, i, 1, Open[i+1]); //行情线开盘价
ArrayFill(closePrice, i, 1, Close[i+1]); //收盘价
}
int upTrendNums = 0; //上升K线数
int downTrendNums = 0; //下降K线数
for(i=0; i<kLineNums; i++){
if(maPrice65[i]<maPrice23[i] && maPrice23[i]<openPrice[i] && openPrice[i]<closePrice[i]){
upTrendNums++;
}
if(maPrice65[i]>maPrice23[i] && maPrice23[i]>openPrice[i] && openPrice[i]>closePrice[i]){
downTrendNums++;
}
}
//上升回踩(除了往前第一根K线刺破均线,其他都高于均线)
if(upTrendNums==kLineNums-1 && iLow(symbol, period, 1)<maPrice23[1]){
return 1;
}
//下跌回踩(同理)
if(downTrendNums==kLineNums-1 && iHigh(symbol, period, 1)>maPrice23[1]){
return 2;
}
return 0;
}
/**
* 获取一组K线的数据
* @ 最高价、最低价、平均K线长度(|收盘-开盘|)
* @param smybol 币种
* @param period 周期级别
* @param kLineNums K线根数i
* @param dataType 返回数据的类型
* @return bool
*/
double getGroupKLinesData(string symbol="", string period=PERIOD_H1, int kLineNums=15, int dataType=1)
{
if(symbol==""){
symbol = Symbol();
}
double highPrice[]; //K线最高价
double lowPrice[]; //K线最低价
double lineHeight[]; //K线长度
double lineHeightAll; //总K线长度
//set size
ArrayResize(highPrice, kLineNums);
ArrayResize(lowPrice, kLineNums);
ArrayResize(lineHeight, kLineNums);
//set value
int i=1;
for(i=0; i<kLineNums; i++){
//往前第i+1根K线
ArrayFill(highPrice, i, 1, iHigh(symbol, period, i+1));
ArrayFill(lowPrice, i, 1, iLow(symbol, period, i+1));
ArrayFill(lineHeight, i, 1, (iHigh(symbol, period, i+1) - iLow(symbol, period, i+1)));
lineHeightAll += iHigh(symbol, period, i+1) - iLow(symbol, period, i+1);
}
//最高价
double MaxPrice = highPrice[ArrayMaximum(highPrice, WHOLE_ARRAY, 0)];
//最低价
double MinPrice = lowPrice[ArrayMinimum(lowPrice, WHOLE_ARRAY, 0)];
//平均K线长度
double MeanHeight = lineHeightAll/kLineNums;
//返回数据
if(dataType>0){
switch (dataType){
case 1 :return MaxPrice; break;
case 2 :return MinPrice; break;
case 3 :return MeanHeight; break;
}
}
return(0.00);
}
/**
* 根据MQL4错误码,返回错误信息
* @param code 错误码
* @return string
*/
string getErrorMsgByCode(int code=0){
string errorMsg;
if(code>0){
switch (code){
case 0 :errorMsg="交易报错码:0 没有错误返回";break;
case 1 :errorMsg="交易报错码:1 没有错误返回,可能是反复同价修改";break;
case 2 :errorMsg="交易报错码:2 一般错误";break;
case 3 :errorMsg="交易报错码:3 交易参数出错";break;
case 4 :errorMsg="交易报错码:4 交易服务器繁忙";break;
case 5 :errorMsg="交易报错码:5 客户终端软件版本太旧";break;
case 6 :errorMsg="交易报错码:6 没有连接交易服务器";break;
case 7 :errorMsg="交易报错码:7 操作权限不够";break;
case 8 :errorMsg="交易报错码:8 交易请求过于频繁";break;
case 9 :errorMsg="交易报错码:9 交易操作故障";break;
case 64 :errorMsg="交易报错码:64 账户被禁用";break;
case 65 :errorMsg="交易报错码:65 无效账户";break;
case 128 :errorMsg="交易报错码:128 交易超时";break;
case 129 :errorMsg="交易报错码:129 无效报价";break;
case 130 :errorMsg="交易报错码:130 止损错误";break;
case 131 :errorMsg="交易报错码:131 交易量错误";break;
case 132 :errorMsg="交易报错码:132 休市";break;
case 133 :errorMsg="交易报错码:133 禁止交易";break;
case 134 :errorMsg="交易报错码:134 资金不足";break;
case 135 :errorMsg="交易报错码:135 报价发生改变";break;
case 136 :errorMsg="交易报错码:136 建仓价过期";break;
case 137 :errorMsg="交易报错码:137 经纪商很忙";break;
case 138 :errorMsg="交易报错码:138 需要重新报价";break;
case 139 :errorMsg="交易报错码:139 定单被锁定";break;
case 140 :errorMsg="交易报错码:140 只允许做买入类型操作";break;
case 141 :errorMsg="交易报错码:141 请求过多";break;
case 145 :errorMsg="交易报错码:145 过于接近报价,禁止修改";break;
case 146 :errorMsg="交易报错码:146 交易繁忙";break;
case 147 :errorMsg="交易报错码:147 交易期限被经纪商取消";break;
case 148 :errorMsg="交易报错码:148 持仓单数量超过经纪商的规定";break;
case 149 :errorMsg="交易报错码:149 禁止对冲";break;
case 150 :errorMsg="交易报错码:150 FIFO禁则";break;
case 4000:errorMsg="运行报错码:4000 没有错误返回";break;
case 4001:errorMsg="运行报错码:4001 函数指针错误";break;
case 4002:errorMsg="运行报错码:4002 数组越界";break;
case 4003:errorMsg="运行报错码:4003 调用栈导致内存不足";break;
case 4004:errorMsg="运行报错码:4004 递归栈溢出";break;
case 4005:errorMsg="运行报错码:4005 堆栈参数导致内存不足";break;
case 4006:errorMsg="运行报错码:4006 字符串参数导致内存不足";break;
case 4007:errorMsg="运行报错码:4007 临时字符串导致内存不足";break;
case 4008:errorMsg="运行报错码:4008 字符串变量缺少初始化赋值";break;
case 4009:errorMsg="运行报错码:4009 字符串数组缺少初始化赋值";break;
case 4010:errorMsg="运行报错码:4010 字符串数组空间不够";break;
case 4011:errorMsg="运行报错码:4011 字符串太长";break;
case 4012:errorMsg="运行报错码:4012 因除数为零导致的错误";break;
case 4013:errorMsg="运行报错码:4013 除数为零";break;
case 4014:errorMsg="运行报错码:4014 错误的命令";break;
case 4015:errorMsg="运行报错码:4015 错误的跳转";break;
case 4016:errorMsg="运行报错码:4016 数组没有初始化";break;
case 4017:errorMsg="运行报错码:4017 禁止调用DLL ";break;
case 4018:errorMsg="运行报错码:4018 库文件无法调用";break;
case 4019:errorMsg="运行报错码:4019 函数无法调用";break;
case 4020:errorMsg="运行报错码:4020 禁止调用智EA函数";break;
case 4021:errorMsg="运行报错码:4021 函数中临时字符串返回导致内存不够";break;
case 4022:errorMsg="运行报错码:4022 系统繁忙";break;
case 4023:errorMsg="运行报错码:4023 DLL函数调用错误";break;
case 4024:errorMsg="运行报错码:4024 内部错误";break;
case 4025:errorMsg="运行报错码:4025 内存不够";break;
case 4026:errorMsg="运行报错码:4026 指针错误";break;
case 4027:errorMsg="运行报错码:4027 过多的格式定义";break;
case 4028:errorMsg="运行报错码:4028 参数计数器越界";break;
case 4029:errorMsg="运行报错码:4029 数组错误";break;
case 4030:errorMsg="运行报错码:4030 图表没有响应";break;
case 4050:errorMsg="运行报错码:4050 参数无效";break;
case 4051:errorMsg="运行报错码:4051 参数值无效";break;
case 4052:errorMsg="运行报错码:4052 字符串函数内部错误";break;
case 4053:errorMsg="运行报错码:4053 数组错误";break;
case 4054:errorMsg="运行报错码:4054 数组使用不正确";break;
case 4055:errorMsg="运行报错码:4055 自定义指标错误";break;
case 4056:errorMsg="运行报错码:4056 数组不兼容";break;
case 4057:errorMsg="运行报错码:4057 全局变量处理错误";break;
case 4058:errorMsg="运行报错码:4058 没有发现全局变量";break;
case 4059:errorMsg="运行报错码:4059 测试模式中函数被禁用";break;
case 4060:errorMsg="运行报错码:4060 函数未确认";break;
case 4061:errorMsg="运行报错码:4061 发送邮件错误";break;
case 4062:errorMsg="运行报错码:4062 String参数错误";break;
case 4063:errorMsg="运行报错码:4063 Integer参数错误";break;
case 4064:errorMsg="运行报错码:4064 Double参数错误";break;
case 4065:errorMsg="运行报错码:4065 数组参数错误";break;
case 4066:errorMsg="运行报错码:4066 刷新历史数据错误";break;
case 4067:errorMsg="运行报错码:4067 交易内部错误";break;
case 4068:errorMsg="运行报错码:4068 没有发现资源文件";break;
case 4069:errorMsg="运行报错码:4069 不支持资源文件";break;
case 4070:errorMsg="运行报错码:4070 重复的资源文件";break;
case 4071:errorMsg="运行报错码:4071 自定义指标没有初始化";break;
case 4099:errorMsg="运行报错码:4099 文件末尾";break;
case 4100:errorMsg="运行报错码:4100 文件错误";break;
case 4101:errorMsg="运行报错码:4101 文件名称错误";break;
case 4102:errorMsg="运行报错码:4102 打开文件过多";break;
case 4103:errorMsg="运行报错码:4103 不能打开文件";break;
case 4104:errorMsg="运行报错码:4104 不兼容的文件";break;
case 4105:errorMsg="运行报错码:4105 没有选择定单";break;
case 4106:errorMsg="运行报错码:4106 未知的商品名称";break;
case 4107:errorMsg="运行报错码:4107 价格无效";break;
case 4108:errorMsg="运行报错码:4108 报价无效";break;
case 4109:errorMsg="运行报错码:4109 禁止交易,请尝试修改EA属性";break;
case 4110:errorMsg="运行报错码:4110 禁止买入类型交易,请尝试修改EA属性";break;
case 4111:errorMsg="运行报错码:4111 禁止卖出类型交易,请尝试修改EA属性";break;
case 4200:errorMsg="运行报错码:4200 对象已经存在";break;
case 4201:errorMsg="运行报错码:4201 未知的对象属性";break;
case 4202:errorMsg="运行报错码:4202 对象不存在";break;
case 4203:errorMsg="运行报错码:4203 未知的对象类型";break;
case 4204:errorMsg="运行报错码:4204 对象没有命名";break;
case 4205:errorMsg="运行报错码:4205 对象坐标错误";break;
case 4206:errorMsg="运行报错码:4206 没有指定副图窗口";break;
case 4207:errorMsg="运行报错码:4207 图形对象错误";break;
case 4210:errorMsg="运行报错码:4210 未知的图表属性";break;
case 4211:errorMsg="运行报错码:4211 没有发现主图";break;
case 4212:errorMsg="运行报错码:4212 没有发现副图";break;
case 4213:errorMsg="运行报错码:4210 图表中没有发现指标";break;
case 4220:errorMsg="运行报错码:4220 商品选择错误";break;
case 4250:errorMsg="运行报错码:4250 消息传递错误";break;
case 4251:errorMsg="运行报错码:4251 消息参数错误";break;
case 4252:errorMsg="运行报错码:4252 消息被禁用";break;
case 4253:errorMsg="运行报错码:4253 消息发送过于频繁";break;
case 5001:errorMsg="运行报错码:5001 文件打开过多";break;
case 5002:errorMsg="运行报错码:5002 错误的文件名";break;
case 5003:errorMsg="运行报错码:5003 文件名过长";break;
case 5004:errorMsg="运行报错码:5004 无法打开文件";break;
case 5005:errorMsg="运行报错码:5005 文本文件缓冲区分配错误";break;
case 5006:errorMsg="运行报错码:5006 文无法删除文件";break;
case 5007:errorMsg="运行报错码:5007 文件句柄无效";break;
case 5008:errorMsg="运行报错码:5008 文件句柄错误";break;
case 5009:errorMsg="运行报错码:5009 文件必须设置为FILE_WRITE";break;
case 5010:errorMsg="运行报错码:5010 文件必须设置为FILE_READ";break;
case 5011:errorMsg="运行报错码:5011 文件必须设置为FILE_BIN";break;
case 5012:errorMsg="运行报错码:5012 文件必须设置为FILE_TXT";break;
case 5013:errorMsg="运行报错码:5013 文件必须设置为FILE_TXT或FILE_CSV";break;
case 5014:errorMsg="运行报错码:5014 文件必须设置为FILE_CSV";break;
case 5015:errorMsg="运行报错码:5015 读文件错误";break;
case 5016:errorMsg="运行报错码:5016 写文件错误";break;
case 5017:errorMsg="运行报错码:5017 二进制文件必须指定字符串大小";break;
case 5018:errorMsg="运行报错码:5018 文件不兼容";break;
case 5019:errorMsg="运行报错码:5019 目录名非文件名";break;
case 5020:errorMsg="运行报错码:5020 文件不存在";break;
case 5021:errorMsg="运行报错码:5021 文件不能被重复写入";break;
case 5022:errorMsg="运行报错码:5022 错误的目录名";break;
case 5023:errorMsg="运行报错码:5023 目录名不存在";break;
case 5024:errorMsg="运行报错码:5024 指定文件而不是目录";break;
case 5025:errorMsg="运行报错码:5025 不能删除目录";break;
case 5026:errorMsg="运行报错码:5026 不能清空目录";break;
case 5027:errorMsg="运行报错码:5027 改变数组大小错误";break;
case 5028:errorMsg="运行报错码:5028 改变字符串大小错误";break;
case 5029:errorMsg="运行报错码:5029 结构体包含字符串或者动态数组";break;
}
}
return errorMsg;
}
/**
* 获取趋势系统-道氏点
* @ 前20根K线的最低/最高点
* @param smybol 币种
* @param period 周期级别
* @return bool
*/
double getDaoShiPointForTendency(string symbol="", string period=PERIOD_H1)
{
//Todo
return 0.01;
}
/**
* 趋势是否结束信息
* @param smybol 币种
* @param period 周期级别
* @return bool
*/
bool isTrendOverSignal(string symbol="", string period=PERIOD_H1)
{
//Todo
return false;
}
/**
* 获取币种价格的小数位数
* @param smybol 币种
* @return bool
*/
int cuSymbolPrecision()
{
string symbol = Symbol();
//2位小数的币种
string symbolPrecision2[] = {"XAUUSD"};
int i;
for(i=0; i<ArrayRange(symbolPrecision2, 0); i++){
if(symbolPrecision2[i] == symbol){
return 2;
}
}
//3位小数的币种
string symbolPrecision3[] = {"USDJPY","AUDJPY","NZDJPY","CADJPY","EURJPY","GBPJPY","CHFJPY","NZDJPY"};
int p;
for(p=0; p<ArrayRange(symbolPrecision3, 0); p++){
if(symbolPrecision3[p] == symbol){
return 3;
}
}
return 5; //大部分是5位小数
}
/**
* 判断是否重复下单
* @ 对于高并发时无用,
* @ 因:交易指令同一时间全堆到OrderSend时,根本没有已生成订单,因此校验无效
* @··借鉴PHP的锁机制?
* @return bool
*/
bool hasRepeatEaOrder(string symbol="", string period=PERIOD_H1, int magicNum=0)
{
Sleep(2000); //休眠2秒
//当前K线开盘时间
string cLineOpenTime = iTime(symbol, period, 0);
//有比当前K线开盘时间更晚的订单,就是EA单
//假设前提:不会频繁开仓
int orderNum = 0;
int i;
for(i=OrdersTotal()-1;i>=0;i--){
if(OrderSelect(i, SELECT_BY_POS)){
if(OrderSymbol()==symbol){
orderNum++;
}
}
}
if(orderNum > 0){
return true;
}else{
return false;
}
}
3)E_Common_Help.mqh
//+------------------------------------------------------------------+
//| E_Common_Help.mqh |
//| wouter.zhong |
//| 辅助函数模块 -- 声明 |
//+------------------------------------------------------------------+
//辅助类声明
#import "E_Common_Help.ex4"
void helpList();
//根据MQL4错误码,返回错误信息
string getErrorMsgByCode(int code);
//获取MarketInfo的mode
string getModeByType(string orderType);
//获取可下单手数
double getMakeLots();
//获取某期间内的下单总数
int getPeriodOrderNums(int days, string smybol, string noSmybol);
//获取某期间内的总盈亏
int getPeriodOrderLoss(int days);
//获取当前挂单数量
int getPendingOrderNums();
//获取最近一个非挂单的订单号
string getLastCuTicket();
//获取缺口信息
double getGapInfo(string symbol, string period, int dataType);
//判断是否白/黑三宾信号
int checkThreeLineSignal(string symbol, string period);
//判断上升or下跌趋势
int checkTendencyByIma(string symbol, string period, int kLineNums);
//获取一组K线的数据
double getGroupKLinesData(string symbol,string period,int kLineNums,int dataType);
//判断上升回踩or下跌回踩
int checkImBackType(string symbol, string period, int kLineNums);
//获取道氏点
double getDaoShiPointForTendency(string symbol, string period);
//趋势是否反转
bool isTrendOverSignal(string symbol, string period);
//获取币种价格的小数位数
int cuSymbolPrecision();
bool hasRepeatEaOrder(string symbol, string period, int magicNum);
#import