指標的調(diào)用
均線指標
#property copyright "shiyingpan"
#property link "https://aijy.github.io"
#property version "1.00"
#property strict
void OnStart()
{
//---------- 默認幣種4小時周期例隆,前三根K線14日均線值 -----------//
string 幣種=Symbol(); //----幣種Symbol為圖表幣種,也可直接定義如“EURUSD”
int 時間周期=240; //----時間周期指圖表周期奕坟,240(分鐘)是4小時圖,使用0,則默認圖表周期
int 均線周期=14; //----均線周期,本例指14均線
double ma_0=iMA(幣種,時間周期,均線周期,0,MODE_EMA,PRICE_CLOSE,0); //---最后一個參數(shù)表示第幾根k線煞聪,0是從右往左第一根,即最近的一根K線
double ma_1=iMA(幣種,時間周期,均線周期,0,MODE_EMA,PRICE_CLOSE,1); //---第二根逝慧,從右往左昔脯。注意第n+1根K線的標號為n啄糙。
double ma_2=iMA(幣種,時間周期,均線周期,0,MODE_EMA,PRICE_CLOSE,2);
PrintFormat("前三根K線均線值為:%.5f,%.5f,%.5f",ma_0,ma_1,ma_2);
//---------- 獲取 EURUSD 日線50日周期的前日收盤均線值 -----------//
double ma_eurusd=iMA("EURUSD",PERIOD_D1,50,0,MODE_EMA,PRICE_CLOSE,1);
PrintFormat("EURUSD的均線值為:%.5f",ma_eurusd);
}
MACD指標
#property copyright "shiyingpan"
#property link "https://aijy.github.io"
#property version "1.00"
#property strict
void OnStart()
{
/*
設置幣種4小時周期,前根K線MACD值,MACD有2個返回值macd的值云稚,與macd的均線值
*/
string 幣種=Symbol(); //----幣種Symbol為圖表幣種隧饼,也可直接定義如“EURUSD”
int 時間周期=240; //----時間周期指圖表周期,240(分鐘)是4小時圖静陈,使用0燕雁,則默認圖表周期
int 慢周期=26,快周期=12,均滑周期=9;
double macd_main=iMACD(幣種,時間周期,快周期,慢周期,均滑周期,PRICE_CLOSE,MODE_MAIN,1); //---最后一個參數(shù)表示第幾根k線,0是從右往左第一根鲸拥,即最近的一根K線
double macd_signal=iMACD(幣種,時間周期,快周期,慢周期,均滑周期,PRICE_CLOSE,MODE_SIGNAL,1); //---第二根拐格,從右往左。注意第n+1根K線的標號為n刑赶。
PrintFormat("MACD值為:%.5f,SIGNAL:%.5f",macd_main,macd_signal);
//---------- 獲取 EURUSD 日線當前MACD值 -----------//
macd_main=iMACD("EURUSD",PERIOD_D1,快周期,慢周期,均滑周期,PRICE_CLOSE,MODE_MAIN,0); //---最后一個參數(shù)表示第幾根k線捏浊,0是從右往左第一根,即最近的一根K線
macd_signal=iMACD("EURUSD",PERIOD_D1,快周期,慢周期,均滑周期,PRICE_CLOSE,MODE_SIGNAL,0); //---第二根撞叨,從右往左金踪。注意第n+1根K線的標號為n。
PrintFormat("MACD值為:%.5f,SIGNAL:%.5f",macd_main,macd_signal);
}
布林線
#property copyright "shiyingpan"
#property link "https://aijy.github.io"
#property version "1.00"
#property strict
void OnStart()
{
/*
設置幣種4小時周期牵敷,前根K線布林線上胡岔、中、下軌值
*/
string 幣種=Symbol(); //----幣種Symbol為圖表幣種枷餐,也可直接定義如“EURUSD”
int 時間周期=240; //----時間周期指圖表周期靶瘸,240(分鐘)是4小時圖,使用0尖淘,則默認圖表周期
int 布林線周期=20,布林線方差=2;
double bands_upper =iBands(幣種,時間周期,布林線周期,布林線方差,0,PRICE_CLOSE,MODE_UPPER,1); //---第二根k線奕锌,布林線上軌值
double bands_middle =iBands(幣種,時間周期,布林線周期,布林線方差,0,PRICE_CLOSE,MODE_MAIN,1); //---第二根k線,布林線中軌值
double bands_lower =iBands(幣種,時間周期,布林線周期,布林線方差,0,PRICE_CLOSE,MODE_LOWER,1); //---第二根k線村生,布林線下軌值
PrintFormat("4小時布林線前K線上軌值:%.5f,中軌值:%.5f,下軌值:%.5f",bands_upper,bands_middle,bands_lower);
//---------- 獲取 EURUSD 日線當前布林線值 -----------//
bands_upper =iBands("EURUSD",PERIOD_D1,20,2,0,PRICE_CLOSE,MODE_UPPER,0); //--- 布林線上軌值
bands_middle =iBands("EURUSD",PERIOD_D1,20,2,0,PRICE_CLOSE,MODE_MAIN,0); //--- 布林線中軌值
bands_lower =iBands("EURUSD",PERIOD_D1,20,2,0,PRICE_CLOSE,MODE_LOWER,0); //--- 布林線下軌值
PrintFormat("當前日線布林線上軌值:%.5f,中軌值:%.5f,下軌值:%.5f",bands_upper,bands_middle,bands_lower);
}
RSI
#property copyright "shiyingpan"
#property link "https://aijy.github.io"
#property version "1.00"
#property strict
void OnStart()
{
//---------- 設置幣種4小時周期惊暴,前三根K線14日RSI值 -----------//
string 幣種=Symbol(); //----幣種Symbol為圖表幣種,也可直接定義如“EURUSD”
int 時間周期=240; //----時間周期指圖表周期趁桃,240(分鐘)是4小時圖辽话,使用0,則默認圖表周期
int RSI周期=14; //----均線周期卫病,本例指14均線
double rsi_0=iRSI(幣種,時間周期,RSI周期,PRICE_CLOSE,0); //---最后一個參數(shù)表示第幾根k線油啤,0是從右往左第一根,即最近的一根K線
double rsi_1=iRSI(幣種,時間周期,RSI周期,PRICE_CLOSE,1); //---第二根蟀苛,從右往左益咬。注意第n+1根K線的標號為n。
double rsi_2=iRSI(幣種,時間周期,RSI周期,PRICE_CLOSE,2);
PrintFormat("前三根K線RSI值為:%.5f,%.5f,%.5f",rsi_0,rsi_1,rsi_2);
//---------- 獲取 EURUSD 日線日收盤RSI值 -----------//
double rsi_eurusd=iRSI("EURUSD",PERIOD_D1,14,PRICE_CLOSE,1);
PrintFormat("EURUSD日線的RSI值為:%.5f",rsi_eurusd);
}
KD指標
#property copyright "shiyingpan"
#property link "https://aijy.github.io"
#property version "1.00"
#property strict
void OnStart()
{
/*
設置幣種4小時周期帜平,前根K線KD值,KD有2個返回值K值幽告,與D值
*/
string 幣種=Symbol(); //----幣種Symbol為圖表幣種梅鹦,也可直接定義如“EURUSD”
int 時間周期=240; //----時間周期指圖表周期,240(分鐘)是4小時圖冗锁,使用0齐唆,則默認圖表周期
int K周期=5,D周期=3,均滑周期=3;
double kd_main=iStochastic(幣種,時間周期,K周期,D周期,均滑周期,MODE_EMA,0,MODE_MAIN,1); //---最后一個參數(shù)表示第幾根k線,0是從右往左第一根冻河,即最近的一根K線
double kd_signal=iStochastic(幣種,時間周期,K周期,D周期,均滑周期,MODE_EMA,0,MODE_SIGNAL,1); //---第二根箍邮,從右往左。注意第n+1根K線的標號為n叨叙。
PrintFormat("KD值為:%.5f,SIGNAL:%.5f",kd_main,kd_signal);
//---------- 獲取 EURUSD 日線當前KD值 -----------//
kd_main=iStochastic("EURUSD",PERIOD_D1,5,3,3,MODE_EMA,0,MODE_MAIN,0); //---最后一個參數(shù)表示第幾根k線锭弊,0是從右往左第一根,即最近的一根K線
kd_signal=iStochastic("EURUSD",PERIOD_D1,5,3,3,MODE_EMA,0,MODE_SIGNAL,0); //---第二根擂错,從右往左廷蓉。注意第n+1根K線的標號為n。
PrintFormat("KD值為:%.5f,SIGNAL:%.5f",kd_main,kd_signal);
}
其他系統(tǒng)自帶指標
其他系統(tǒng)自帶指標參照幫助文件中的指標調(diào)用方式調(diào)用马昙,調(diào)用形式都是一樣的。
自定義指標
#property copyright "shiyingpan"
#property link "https://aijy.github.io"
#property version "1.00"
#property strict
void OnStart()
{
//---------- 調(diào)用自定義指標刹悴,指標需在指標文件夾中 -----------//
/*---- iCustom用法
iCustom(貨幣對名稱, 時間周期, 指標名, 指標輸入?yún)?shù)1,指標輸入?yún)?shù)2,第幾個數(shù)據(jù),第幾根K線);
*/
string 幣種=Symbol(); //----幣種Symbol為圖表幣種行楞,也可直接定義如“EURUSD”
int 時間周期=240; //----時間周期指圖表周期,240(分鐘)是4小時圖土匀,使用0子房,則默認圖表周期
string 指標名="RSI";
double value_0=iCustom(幣種,時間周期,指標名,14,0,0); //---最后一個參數(shù)表示第幾根k線,0是從右往左第一根就轧,即最近的一根K線
double value_1=iCustom(幣種,時間周期,指標名,14,0,1); //---第二根证杭,從右往左。注意第n+1根K線的標號為n妒御。
double value_2=iCustom(幣種,時間周期,指標名,14,0,2);
PrintFormat("前三根K線RSI值為:%.5f,%.5f,%.5f",value_0,value_1,value_2);
//---------- 獲取 EURUSD 日線的zigzag值 -----------//
double zz_value=0;
double position=0;
for(int i=0;i<100;i++)
{
zz_value=iCustom("EURUSD", PERIOD_D1, "ZigZag", 12, 5, 3, 0, i);
if(zz_value!=0)
{
position=i;
break;
}
}
PrintFormat("EURUSD日線上個峰值/底值為:%.5f,第%d根K線",zz_value,position);
}
基于KD指標的下單程序
本例有以下幾個要點:
- 移動止損
- 一根K線下一次單
- 如何避免無限重復下單
#property copyright "shiyingpan"
#property link "https://aijy.github.io"
#property version "1.00"
#property strict
input double 單量=0.2;
input int 止損=400;
input int 移動止損=100;
input int 啟動移動止損=300;
input int 交易開始時間=2;
input int 交易停止時間=22;
int Magic_num=445678;
datetime trade_time;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
if(AccountNumber()==0) //----通過判斷賬戶號解愤,確定是否連接網(wǎng)絡
return;
double kd15_main,kd15_main_prv,kd15_sig,kd15_sig_prv;
int ticket;
bool long_order_exist=false,short_order_exist=false;
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol())
{
if(OrderType()==OP_BUY && OrderMagicNumber()==Magic_num)
{
long_order_exist=true;
//--首先價格要超過啟動止損位置,然后還要比當前止損大 移動止損以上
if(Bid>(OrderOpenPrice()+啟動移動止損*Point) && (Bid-OrderStopLoss())>移動止損*Point)
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-移動止損*Point,0,0,clrNONE);// 設置移動止損
}
if(OrderType()==OP_SELL && OrderMagicNumber()==Magic_num)
{
short_order_exist=true;
if(Ask<(OrderOpenPrice()-啟動移動止損*Point) && (OrderStopLoss()-Ask)>移動止損*Point)
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+移動止損*Point,0,0,clrNONE);// 設置移動止損
}
}
}
//-- TimeHour() 函數(shù)返回 時間參數(shù) 的小時數(shù)
if(TimeHour(TimeCurrent())>=交易停止時間 || TimeHour(TimeCurrent())<交易開始時間) //---------在流動性差的時間段不交易(點差高)
return;
if(trade_time==iTime(Symbol(),PERIOD_M15,0)) //---每隔15分鐘計算一次是否要下單
{
return;
}
trade_time=iTime(Symbol(),PERIOD_M15,0);
kd15_main=iStochastic(Symbol(),PERIOD_M15,5,3,3,MODE_EMA,0,MODE_MAIN,1);
kd15_sig=iStochastic(Symbol(),PERIOD_M15,5,3,3,MODE_EMA,0,MODE_SIGNAL,1);
kd15_main_prv=iStochastic(Symbol(),PERIOD_M15,5,3,3,MODE_EMA,0,MODE_MAIN,2);
kd15_sig_prv=iStochastic(Symbol(),PERIOD_M15,5,3,3,MODE_EMA,0,MODE_SIGNAL,2);
if(long_order_exist==false) //---當前有多單乎莉,就不再下多單
{
// 在35以下的金叉買入
if(kd15_main_prv<kd15_sig_prv && kd15_main>kd15_sig && kd15_main_prv<35 && kd15_sig_prv<35 && kd15_main<35 && kd15_sig<35)
{
ticket=OrderSend(Symbol(),OP_BUY,單量,Ask,3,止損*Point,0,"KD_long",Magic_num,0,clrRed);
if(ticket==0)
{
Print("open buy order error:",GetLastError());
}
}
}
if(short_order_exist==false) //---當前有空單送讲,就不再下空單
{
//--在65以上的死叉賣出
if(kd15_main_prv>kd15_sig_prv && kd15_main<kd15_sig && kd15_main_prv>65 && kd15_sig_prv>65 && kd15_main>65 && kd15_sig>65)
{
ticket=OrderSend(Symbol(),OP_SELL,單量,Bid,3,止損*Point,0,"KD_short",Magic_num,0,clrYellow);
if(ticket==0)
{
Print("open sell order error:",GetLastError());
}
}
}
}
指標的編寫
KD指標代碼解讀
#property copyright "2005-2014, MetaQuotes Software Corp."
#property link "http://www.mql4.com"
#property description "Stochastic Oscillator"
#property strict
#property indicator_separate_window //-- 顯示在附圖上,若要主圖顯示用 indicator_chart_window
#property indicator_minimum 0 //-- 指標下限(可選)
#property indicator_maximum 100 //-- 指標上限(可選)
#property indicator_buffers 2 //-- 指標數(shù)據(jù)緩存,2表示這個指標有2個數(shù)據(jù)惋啃。非常重要
#property indicator_color1 LightSeaGreen //-- 第一根指標線的顏色
#property indicator_color2 Red //-- 第二根指標線的顏色
#property indicator_level1 20.0 //-- 指標數(shù)值參考線
#property indicator_level2 80.0 //-- 指標數(shù)值參考線
#property indicator_levelcolor clrSilver //-- 指標數(shù)值參考線顏色(統(tǒng)一的顏色)
#property indicator_levelstyle STYLE_DOT //-- 指標數(shù)值參考線類型(統(tǒng)一的類型)哼鬓,本例點線
//--- input parameters
input int InpKPeriod=5; // K Period 參數(shù)定義與輸入
input int InpDPeriod=3; // D Period
input int InpSlowing=3; // Slowing
//-- 定義需要使用的緩存器,按需定義。只要要定義上面設置的數(shù)據(jù)緩存數(shù)目
double ExtMainBuffer[]; //-- 定義主緩存空間
double ExtSignalBuffer[]; //-- 定義Signal數(shù)值的緩存空間
double ExtHighesBuffer[]; //-- 中間變量空間边灭,供中間計算
double ExtLowesBuffer[]; //-- 中間變量空間异希,供中間計算
//---
int draw_begin1=0;
int draw_begin2=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit(void)
{
string short_name;
//--- 2 additional buffers are used for counting.
IndicatorBuffers(4); //-- 聲明4個緩存空間
SetIndexBuffer(2, ExtHighesBuffer); //-- 緩存空間與編號要一一對應,ExtHighesBuffer對應2
SetIndexBuffer(3, ExtLowesBuffer); //-- ExtLowesBuffer對應3绒瘦,問題:為什么中間變量空間不對應0和1称簿?
//-- 答:編號首先供指標緩存使用扣癣,然后才能給中間變量空間使用
//--- indicator lines
SetIndexStyle(0,DRAW_LINE); //-- 設置數(shù)據(jù)1是線型
SetIndexBuffer(0, ExtMainBuffer); //-- 指定數(shù)據(jù)1的緩存空間
SetIndexStyle(1,DRAW_LINE); //-- 設置數(shù)據(jù)2是線型
SetIndexBuffer(1, ExtSignalBuffer); //-- 指定數(shù)據(jù)2的緩存空間
//--- name for DataWindow and indicator subwindow label
short_name="Sto("+IntegerToString(InpKPeriod)+","+IntegerToString(InpDPeriod)+","+IntegerToString(InpSlowing)+")";
IndicatorShortName(short_name); //--指標名
SetIndexLabel(0,short_name); //-- 數(shù)據(jù)1的名稱
SetIndexLabel(1,"Signal"); //-- 數(shù)據(jù)2的名稱
//---
draw_begin1=InpKPeriod+InpSlowing;
draw_begin2=draw_begin1+InpDPeriod;
SetIndexDrawBegin(0,draw_begin1); //-- 數(shù)據(jù)1畫線起始位置
SetIndexDrawBegin(1,draw_begin2); //-- 數(shù)據(jù)2畫線起始位置
//--- initialization done
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Stochastic oscillator |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
int i,k,pos;
//--- rates_total是當前可用的K線數(shù)量,如果太小予跌,則不能計算指標
if(rates_total<=InpKPeriod+InpDPeriod+InpSlowing)
return(0);
//--- 指標的數(shù)據(jù)存儲是按K線從左到右計算的搏色,不需要反向
ArraySetAsSeries(ExtMainBuffer,false);
ArraySetAsSeries(ExtSignalBuffer,false);
ArraySetAsSeries(ExtHighesBuffer,false);
ArraySetAsSeries(ExtLowesBuffer,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(close,false);
//---
pos=InpKPeriod-1;
if(pos+1<prev_calculated) //---prev_calculated表示未參與運算的K線數(shù)
pos=prev_calculated-2;
else
{
for(i=0; i<pos; i++) //-- 通過for循環(huán)為最初沒有用到的空間賦初值0
{ //-- 比如highbuffer是記錄前5日的高點的,那么0-4的值是沒有的券册,賦為0
ExtLowesBuffer[i]=0.0;
ExtHighesBuffer[i]=0.0;
}
}
//--- calculate HighesBuffer[] and ExtHighesBuffer[]
for(i=pos; i<rates_total && !IsStopped(); i++) //-- 從未計算的K線開始频轿,一直計算到所有K線
{
double dmin=1000000.0;
double dmax=-1000000.0;
for(k=i-InpKPeriod+1; k<=i; k++)
{
if(dmin>low[k])
dmin=low[k]; //-- 前InpKPeriod(5)根K線的低點
if(dmax<high[k])
dmax=high[k]; //-- 前InpKPeriod(5)根K線的高點
}
ExtLowesBuffer[i]=dmin; //-- ExtLowesBuffer[i],指的是第i根K線前InpKPeriod(5)根K線的低點
ExtHighesBuffer[i]=dmax; //-- ExtLowesBuffer[i]烁焙,指的是第i根K線前InpKPeriod(5)根K線的低點
}
//--- 為未使用到的K值存儲空間賦初值0
pos=InpKPeriod-1+InpSlowing-1;
if(pos+1<prev_calculated)
pos=prev_calculated-2;
else
{
for(i=0; i<pos; i++)
ExtMainBuffer[i]=0.0;
}
//--- 計算K值航邢,主循環(huán),
for(i=pos; i<rates_total && !IsStopped(); i++)
{
//-- 自定義指標的的數(shù)據(jù)緩存空間的計算主要在這個位置進行計算
//-- 以下是K值計算方法骄蝇,每種指標計算方法不同膳殷,理解這種結構和操作形式即可
double sumlow=0.0;
double sumhigh=0.0;
for(k=(i-InpSlowing+1); k<=i; k++)
{
sumlow +=(close[k]-ExtLowesBuffer[k]); //-- 計算均滑(3)日的總和值。
sumhigh+=(ExtHighesBuffer[k]-ExtLowesBuffer[k]);
}
if(sumhigh==0.0)
ExtMainBuffer[i]=100.0;
else
ExtMainBuffer[i]=sumlow/sumhigh*100.0;
}
//--- 計算D值九火,主循環(huán)
pos=InpDPeriod-1;
if(pos+1<prev_calculated)
pos=prev_calculated-2;
else
{
for(i=0; i<pos; i++)
ExtSignalBuffer[i]=0.0;
}
for(i=pos; i<rates_total && !IsStopped(); i++)
{
double sum=0.0;
for(k=0; k<InpDPeriod; k++)
sum+=ExtMainBuffer[i-k];
ExtSignalBuffer[i]=sum/InpDPeriod;
}
//--- 到此計算結束赚窃,只要在計算中給緩存空間賦值即可,圖表會根據(jù)數(shù)值和設定的圖表類型自動畫上去岔激。
return(rates_total);
}
三色線指標代碼實現(xiàn)
/*--------------------------------
本例制作一款趨勢類型的變色均線指標勒极,
紅色是跌勢
黃色是震蕩
綠線是上漲
均線周期可選
----------------------------------*/
#property copyright "shiyingpan"
#property link "https://aijy.github.io"
#property version "1.00"
#property strict
//---定義指標屬性
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_color2 Green
#property indicator_color3 Yellow
//---設置輸入?yún)?shù)
input int 短周期=10;
input int 中周期=20;
input int 長周期=30;
//---定義指標緩存空間
double LongBuffer[];
double ShortBuffer[];
double NoTrendBuffer[];
//--- 指標起始點
int draw_begin=0;
int OnInit()
{
//-- 為指標取個名字
string short_name="趨勢指標("+IntegerToString(短周期)+IntegerToString(中周期)+IntegerToString(長周期)+")";
IndicatorShortName(short_name);
//-- 設置指標緩存空間數(shù)量,設置線型并做連接,在此都設置為線型
IndicatorBuffers(3);
SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2);
SetIndexBuffer(0,LongBuffer);
SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,2);
SetIndexBuffer(1,ShortBuffer);
SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,2);
SetIndexBuffer(2,NoTrendBuffer);
//-- 設置指標起始的地方,小于長周期的K線并沒有值
draw_begin=長周期;
SetIndexDrawBegin(0,draw_begin);
//-- 返回初始化成功虑鼎,若返回 INIT_FAILED則指標不會成功加載
return(INIT_SUCCEEDED);
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//-- 若K線數(shù)量小于長周期數(shù)目辱匿,則不夠計算
if(rates_total<=長周期)
return(0);
//-- 緩存空間順序是從左到右的,最左邊是1
ArraySetAsSeries(LongBuffer,false);
ArraySetAsSeries(ShortBuffer,false);
ArraySetAsSeries(NoTrendBuffer,false);
double ma_fast,ma_mid,ma_slow;
double ma_fast_prv,ma_mid_prv,ma_slow_prv;
//-- 為顯示趨勢變化快慢炫彩,為較短的周期賦予較大的權重
double sum=短周期+中周期+長周期;
double w1=長周期/sum,w2=中周期/sum,w3=短周期/sum;
for(int i=draw_begin+1; i<=rates_total && !IsStopped(); i++)
{
ma_fast = iMA(Symbol(),0,短周期,0,MODE_EMA,PRICE_CLOSE,rates_total-i);
ma_mid = iMA(Symbol(),0,中周期,0,MODE_EMA,PRICE_CLOSE,rates_total-i);
ma_slow = iMA(Symbol(),0,長周期,0,MODE_EMA,PRICE_CLOSE,rates_total-i);
ma_fast_prv = iMA(Symbol(),0,短周期,0,MODE_EMA,PRICE_CLOSE,rates_total-i+1);
ma_mid_prv = iMA(Symbol(),0,中周期,0,MODE_EMA,PRICE_CLOSE,rates_total-i+1);
ma_slow_prv = iMA(Symbol(),0,長周期,0,MODE_EMA,PRICE_CLOSE,rates_total-i+1);
if(ma_fast>ma_mid && ma_mid>ma_slow) //--- 多頭排列匾七,上漲趨勢
{
LongBuffer[i]=(ma_fast+ma_mid+ma_slow)/3; //-- 計算本根和上一根的值,做不同趨勢的連接
LongBuffer[i-1]=(ma_fast_prv+ma_mid_prv+ma_slow_prv)/3;
//LongBuffer[i] =ma_fast*w1+ma_mid*w2+ma_slow*w3;
//LongBuffer[i-1]=ma_fast_prv*w1+ma_mid_prv*w2+ma_slow_prv*w3;
}
else if(ma_fast<ma_mid && ma_mid<ma_slow) //--- 空頭排列江兢,下跌趨勢
{
ShortBuffer[i]=(ma_fast+ma_mid+ma_slow)/3;
ShortBuffer[i-1]=(ma_fast_prv+ma_mid_prv+ma_slow_prv)/3;
//ShortBuffer[i] =ma_fast*w1+ma_mid*w2+ma_slow*w3;
//ShortBuffer[i-1]=ma_fast_prv*w1+ma_mid_prv*w2+ma_slow_prv*w3;
}
else //-- 除了上漲昨忆、下跌趨勢,就是歸納于震蕩
{
NoTrendBuffer[i]=(ma_fast+ma_mid+ma_slow)/3;
NoTrendBuffer[i-1]=(ma_fast_prv+ma_mid_prv+ma_slow_prv)/3;
//NoTrendBuffer[i] =ma_fast*w1+ma_mid*w2+ma_slow*w3;
//NoTrendBuffer[i-1]=ma_fast_prv*w1+ma_mid_prv*w2+ma_slow_prv*w3;
}
}
return(rates_total);
}
賬戶的操作
- 賬號
- 賬戶名
- 賬戶資金
- 賬戶類型
賬戶凈值風險控制
#property copyright "shiyingpan"
#property link "https://aijy.github.io"
#property version "1.00"
#property strict
int 授權賬號=123;
double 初始資金=0;
int OnInit()
{
while(AccountNumber()==0) //-- 加載前可先使用賬戶號判斷時候可交易杉允,網(wǎng)絡未連接時扔嵌,賬號為0
Sleep(500); //-- 程序在此停留0.5秒,啥也不干夺颤,再判斷賬號值
if(AccountNumber()!=授權賬號)
{
Alert("非授權賬號");
return INIT_FAILED; //-- 非授權賬號痢缎,不能加載成功
}
Print("賬號名:",AccountName()); //-- 獲取賬戶名
初始資金=AccountEquity(); //-- 加載EA時獲取當前賬戶凈值
if(!IsDemo()) //-- 如果是實盤
{
Alert("當前賬戶為實盤賬戶!");
}
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
void OnTick()
{
//--------------- 賬戶凈值風險控制 ----------------//
if(AccountEquity()<初始資金*0.8)
{
Alert("當前賬戶凈值虧損20%世澜,已停止交易");
//-- 添加平倉操作(平倉退出)
ExpertRemove(); //-- 退出EA
return;
}
}
文件夾操作
文件夾操作可用于提取一定格式數(shù)據(jù)独旷,用于分析。
提取隔夜利息
#property copyright "shiyingpan"
#property link "https://aijy.github.io"
#property version "1.00"
#property strict
/* ------------------------------------------------------------------+
本例統(tǒng)計平臺的貨幣對隔夜利息
//+-----------------------------------------------------------------*/
string forex_name[29]={"EURUSD","AUDUSD","GBPUSD","NZDUSD","USDJPY","USDCAD",
"USDCHF","EURGBP","EURJPY","EURCHF","EURCAD","EURAUD","EURNZD","AUDCHF","AUDJPY","AUDNZD","AUDCAD","CADCHF",
"CADJPY","GBPCAD","CHFJPY","GBPAUD","GBPNZD","GBPJPY","NZDCAD","NZDJPY","NZDCHF","GBPCHF","XAUUSD"};
string forex_data_name[58],file_name="隔夜利息.csv";
string first_line="forex_name",second_line="LONG",third_line="SHORT";
double swaplong[29],swapshort[29];
void OnStart()
{
//---
for(int i=0;i<29;i++)
{
first_line=first_line+","+forex_name[i];
}
for(int i=0;i<29;i++)
{
swaplong[i]=MarketInfo(forex_name[i],MODE_SWAPLONG);
swapshort[i]=MarketInfo(forex_name[i],MODE_SWAPSHORT);
second_line=second_line+","+DoubleToStr(swaplong[i],2);
third_line=third_line+","+DoubleToStr(swapshort[i],2);
}
int handle=FileOpen(file_name,FILE_CSV|FILE_WRITE|FILE_ANSI,',');
if(handle>0)
{
FileSeek(handle,0,SEEK_CUR);
FileWrite(handle,first_line);
FileWrite(handle,second_line);
FileWrite(handle,third_line);
}
FileClose(handle);
}
提取實時點差
#property copyright "shiyingpan"
#property link "https://aijy.github.io"
#property version "1.00"
#property strict
#property indicator_chart_window
string forex_file_name;
int handle;
int spread1;
int k=0;
int flag=0;
string spread_write;
int count=0;
int start_count=0;
int OnInit()
{
//--- indicator buffers mapping
//---
return(INIT_SUCCEEDED);
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
//---
if(flag==0 && DayOfWeek()==2)
{
forex_file_name=Symbol()+"_SPREAD.csv";
spread_write=TimeToStr(TimeCurrent());
start_count=1;
flag=1;
handle=FileOpen(forex_file_name,FILE_CSV|FILE_WRITE,';');
}
if(start_count==1)
{
RefreshRates();
spread1=MarketInfo(Symbol(),MODE_SPREAD);
spread_write=spread_write+";"+spread1;
count++;
// Print("count:",count);
if(count==400)
{
if(handle>0)
{
FileSeek(handle,0,SEEK_CUR);
FileWriteString(handle,spread_write+"\r\n");
}
k=k+1;
spread_write=TimeToStr(TimeCurrent());
count=0;
if(k%1000==0)
Print("k:",k);
}
if(k==300)
{
FileClose(handle);
start_count=0;
Alert("data is full,time:",TimeCurrent());
}
}
//--- return value of prev_calculated for next call
return(rates_total);
}
編寫馬丁EA
馬丁策略是一種倉位管理方式,它的基本原理基于金字塔式的加倉方式嵌洼。在訂單被套的時候案疲,不斷同方向間隔加倉,攤薄成本麻养。只要行情回撤褐啡,就可以讓被套的系列訂單解套。
轉(zhuǎn)載于:http://www.reibang.com/p/4ab42f1f761e
馬丁策略優(yōu)點
馬丁策略的原理簡單鳖昌。只要死扛备畦,資金量足夠大,馬丁在理論上不會爆倉许昨。而市場行情總是在不同時間周期內(nèi)來回切換擺動懂盐,一個回撤就可以解放所有的被套訂單。
馬丁策略的回撤是可計算的糕档。馬丁的加倉與回撤莉恼,在等間距、加倉倍數(shù)恒定的情況下速那,是可以事先計算出來的俐银。這意味著馬丁策略從數(shù)學意義上講,是可以測算的端仰。
馬丁在程序化上代碼編寫的難度要小悉患。相對于其它策略,馬丁策略的代碼編寫難度要小榆俺。在外匯EA編寫人才缺乏的現(xiàn)狀下,受到各方開發(fā)者的青睞坞淮。
好的馬丁策略茴晋,對付震蕩型行情可以通殺完勝。馬丁怕單邊回窘,愛震蕩诺擅。在可測算的震蕩型行情里,馬丁策略可以達到大小通吃的完美結果啡直,這對于自動化交易者來說烁涌,極具魅力。
代碼實現(xiàn)
為方便理解酒觅,本次代碼分為多頭馬丁和空頭馬丁撮执,多頭馬丁只會下買單,而空頭馬丁只會下空單舷丹。
多頭馬妒闱:
#property copyright "aijy.github.io"
#property link "https://aijy.github.io"
#property version "1.00"
input bool UseAdd=true; // 是否使用加倉策略,true:是
input double LotExponent=1; // 加倉系數(shù)
input int slip=3; // 滑點
input double Lots=0.05; // 初始單量
input int LotsDigits=2; //單量精確到小數(shù)點后2位
input double TakeProfit=200; // 止盈
input double PipStep=300; // 加倉間隔,當一根K線的開盤價與上次開倉價之間價格大于這個數(shù)值谋币,才加倍開倉
input int MaxTrades=10; //最大訂單數(shù)
input bool UseEquityStop=true; //未使用
input double TotalEquityRisk=20; //loss as a percentage of equity
int MagicNumber=123456;
double PriceTarget,StartEquity,BuyTarget,SellTarget;
double AveragePrice,SellLimit,BuyLimit;
double LastBuyPrice,LastSellPrice,ClosePrice,Spread;
string EAName="BUY";
datetime timeprev=0;
int NumOfTrades=0;
double iLots;
int cnt=0,total;
bool TradeNow=false,LongTrade=false,ShortTrade=false;
bool NewOrdersPlaced=false;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int init()
{
Spread=MarketInfo(Symbol(),MODE_SPREAD)*Point;
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnTick()
{
//---------開倉條件
bool long_trade=false;
if(iClose(Symbol(),PERIOD_M1,2)<iClose(Symbol(),PERIOD_M1,1))
long_trade=true;
//------------------------
//---獲取平均的開倉價格---
//------------------------
int ticket;
total=CountTrades();
AveragePrice=0;
double Count=0;
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_BUY || OrderType()==OP_SELL)
{
AveragePrice=AveragePrice+OrderOpenPrice()*OrderLots();
Count=Count+OrderLots();
}
}
if(total>0)
AveragePrice=NormalizeDouble(AveragePrice/Count,Digits);
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
{
if(OrderType()==OP_BUY)
{
PriceTarget=AveragePrice+TakeProfit*Point;
if(Bid>PriceTarget && PriceTarget>0)
{
CloseThisSymbolAll();
}
}
}
}
if(timeprev==Time[0])
{
return;
}
timeprev=Time[0];
double CurrentPairProfit=CalculateProfit();
if(UseEquityStop)
{ //當資金損失低于風險值仗扬,不再開倉
if(CurrentPairProfit<0 && MathAbs(CurrentPairProfit)>(TotalEquityRisk/100)*AccountEquityHigh())
{
if(TimeCurrent()%120==0)
Print("stop opening new orders");
return;
}
}
Print("貨幣對"+Symbol()+"的止盈:",PriceTarget);
total=CountTrades(); //計算本貨幣對訂單總數(shù)(不包括其他貨幣對)
NumOfTrades=total;
double LastBuyLots;
double LastSellLots;
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
//統(tǒng)計所有訂單,從中間查找本EA執(zhí)行的本貨幣對訂單蕾额,判斷之前下的是多單還是空單早芭,供后續(xù)使用
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_BUY)
{
LongTrade=true;
ShortTrade=false;
LastBuyLots=OrderLots();
break;
}
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_SELL)
{
LongTrade=false;
ShortTrade=true;
LastSellLots=OrderLots();
break;
}
}
if(total>0 && total<=MaxTrades) //有訂單且訂單總量小于最大值
{
LastBuyPrice=FindLastBuyPrice(); //得到上次開倉的買價(多單)
LastSellPrice=FindLastSellPrice();//得到上次開倉的賣價(空單)
if(LongTrade && (LastBuyPrice-Ask)>=(PipStep*Point))//判斷是否要增開多倉
{
TradeNow=true;
}
if(ShortTrade && (Bid-LastSellPrice)>=(PipStep*Point))//判斷是否要增開空倉
{
TradeNow=true;
}
}
if(total<1) //無訂單的情況
{
ShortTrade=false;
LongTrade=false;
TradeNow=true;
StartEquity=AccountEquity();
}
if(TradeNow && total>0) //如果之前判斷要加倉則執(zhí)行if
{
LastBuyPrice=FindLastBuyPrice(); //得到上次開倉的買價(多單)
LastSellPrice=FindLastSellPrice();//得到上次開倉的賣價(空單)
if(ShortTrade) //如果是空倉
{
NumOfTrades=total;
iLots=fGetLots(OP_SELL);//獲得增加倉位的訂單手數(shù)
if(UseAdd)//按以上計算出來的加倉手數(shù)下單
{
if(iLots>0)
{//#
RefreshRates();
ticket=OpenPendingOrder(OP_SELL,iLots,Bid,slip,Ask,0,0,EAName+"-"+IntegerToString(NumOfTrades),MagicNumber,0,HotPink);
if(ticket<0){Print("Error: ",GetLastError()); return;}
LastSellPrice=FindLastSellPrice();
TradeNow=false;
NewOrdersPlaced=true;
}//#
}
}
else if(LongTrade)//如果是多倉
{
NumOfTrades=total;
iLots=fGetLots(OP_BUY);//獲得增加倉位的訂單手數(shù)
if(UseAdd)//按以上計算出來的加倉手數(shù)下單
{
if(iLots>0)
{//#
ticket=OpenPendingOrder(OP_BUY,iLots,Ask,slip,Bid,0,0,EAName+"-"+NumOfTrades,MagicNumber,0,Lime);
if(ticket<0)
{Print("Error: ",GetLastError()); return;}
LastBuyPrice=FindLastBuyPrice();
TradeNow=false;
NewOrdersPlaced=true;
}//#
}
}
}
if(TradeNow && total<1)//當前無本貨幣對訂單,并且需要交易
{
SellLimit=Bid;
BuyLimit=Ask;
if(!ShortTrade && !LongTrade)//當前既無多單又無空單
{
NumOfTrades=total;
if(long_trade==true)//多單
{
iLots=fGetLots(OP_BUY);
if(iLots>0)
{//#
ticket=OpenPendingOrder(OP_BUY,iLots,BuyLimit,slip,BuyLimit,0,0,EAName+"-"+NumOfTrades,MagicNumber,0,Lime);
if(ticket<0)
{
Print(iLots,"Error: ",GetLastError());
return;
}
LastSellPrice=FindLastSellPrice();
NewOrdersPlaced=true;
}//#
}
}
TradeNow=false;
}
//------------------------------------------------------
//---以平均開倉價格诅蝶,計算出止損供所有本貨幣對倉位使用---
//------------------------------------------------------
if(NewOrdersPlaced)
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_BUY) // Calculate profit/stop target for long
{
PriceTarget=AveragePrice+(TakeProfit*Point);
BuyTarget=PriceTarget;
}
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_SELL) // Calculate profit/stop target for short
{
PriceTarget=AveragePrice-(TakeProfit*Point);
SellTarget=PriceTarget;
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double fGetLots(int aTradeType)
{
double tLots;
tLots=NormalizeDouble(Lots*MathPow(LotExponent,NumOfTrades),LotsDigits);
if(AccountFreeMarginCheck(Symbol(),aTradeType,tLots)<=0)
{
return(-1);
}
if(GetLastError()==134)
{
return(-2);
}
return(tLots);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CountTrades()
{
int count=0;
int trade;
for(trade=OrdersTotal()-1;trade>=0;trade--)
{
if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_SELL || OrderType()==OP_BUY)
count++;
}//for
return(count);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseThisSymbolAll()
{
int trade;
for(trade=OrdersTotal()-1;trade>=0;trade--)
{
if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
{
if(OrderType()==OP_BUY)
OrderClose(OrderTicket(),OrderLots(),Bid,slip,Blue);
if(OrderType()==OP_SELL)
OrderClose(OrderTicket(),OrderLots(),Ask,slip,Red);
}
Sleep(1000);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int OpenPendingOrder(int pType,double pLots,double pLevel,int sp,double pr,int sl,int tp,string pComment,int pMagic,datetime pExpiration,color pColor)
{
int ticket=0;
int err=0;
int c=0;
int NumberOfTries=100;
switch(pType)
{
case OP_BUYLIMIT:
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderSend(Symbol(),OP_BUYLIMIT,pLots,pLevel,sp,StopLong(pr,sl),TakeLong(pLevel,tp),pComment,pMagic,pExpiration,pColor);
err=GetLastError();
if(err==0)
{
break;
}
else
{
if(err==4 || err==137 || err==146 || err==136) //Busy errors
{
Sleep(1000);
continue;
}
else //normal error
{
break;
}
}
}
break;
case OP_BUYSTOP:
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderSend(Symbol(),OP_BUYSTOP,pLots,pLevel,sp,StopLong(pr,sl),TakeLong(pLevel,tp),pComment,pMagic,pExpiration,pColor);
err=GetLastError();
if(err==0)
{
break;
}
else
{
if(err==4 || err==137 || err==146 || err==136) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
break;
}
}
}
break;
case OP_BUY:
for(c=0;c<NumberOfTries;c++)
{
RefreshRates();
ticket=OrderSend(Symbol(),OP_BUY,pLots,Ask,sp,StopLong(Bid,sl),TakeLong(Ask,tp),pComment,pMagic,pExpiration,pColor);
err=GetLastError();
if(err==0)
{
break;
}
else
{
if(err==4 || err==137 || err==146 || err==136) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
break;
}
}
}
break;
case OP_SELLLIMIT:
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderSend(Symbol(),OP_SELLLIMIT,pLots,pLevel,sp,StopShort(pr,sl),TakeShort(pLevel,tp),pComment,pMagic,pExpiration,pColor);
err=GetLastError();
if(err==0)
{
break;
}
else
{
if(err==4 || err==137 || err==146 || err==136) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
break;
}
}
}
break;
case OP_SELLSTOP:
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderSend(Symbol(),OP_SELLSTOP,pLots,pLevel,sp,StopShort(pr,sl),TakeShort(pLevel,tp),pComment,pMagic,pExpiration,pColor);
err=GetLastError();
if(err==0)
{
break;
}
else
{
if(err==4 || err==137 || err==146 || err==136) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
break;
}
}
}
break;
case OP_SELL:
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderSend(Symbol(),OP_SELL,pLots,Bid,sp,StopShort(Ask,sl),TakeShort(Bid,tp),pComment,pMagic,pExpiration,pColor);
err=GetLastError();
if(err==0)
{
break;
}
else
{
if(err==4 || err==137 || err==146 || err==136) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
break;
}
}
}
break;
}
return(ticket);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double StopLong(double price,int stop)
{
if(stop==0)
return(0);
else
return(price-(stop*Point));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double StopShort(double price,int stop)
{
if(stop==0)
return(0);
else
return(price+(stop*Point));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double TakeLong(double price,int take)
{
if(take==0)
return(0);
else
return(price+(take*Point));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double TakeShort(double price,int take)
{
if(take==0)
return(0);
else
return(price-(take*Point));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CalculateProfit()
{
double Profit=0;
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_BUY || OrderType()==OP_SELL)
{
Profit=Profit+OrderProfit();
}
}
return(Profit);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double AccountEquityHigh()
{
static double AccountEquityHighAmt,PrevEquity;
if(CountTrades()==0) AccountEquityHighAmt=AccountEquity();
if(AccountEquityHighAmt<PrevEquity) AccountEquityHighAmt=PrevEquity;
else AccountEquityHighAmt=AccountEquity();
PrevEquity=AccountEquity();
return(AccountEquityHighAmt);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double FindLastBuyPrice()
{
double oldorderopenprice=0,orderprice=0;
int cnt_temp,oldticketnumber=0,ticketnumber;
for(cnt_temp=OrdersTotal()-1;cnt_temp>=0;cnt_temp--)
{
if(OrderSelect(cnt_temp,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber && OrderType()==OP_BUY)
{
ticketnumber=OrderTicket();
if(ticketnumber>oldticketnumber)
{
orderprice=OrderOpenPrice();
oldorderopenprice=orderprice;
oldticketnumber=ticketnumber;
}
}
}
return(orderprice);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double FindLastSellPrice()
{
double oldorderopenprice=0,orderprice=0;
int cnt_temp,oldticketnumber=0,ticketnumber;
for(cnt_temp=OrdersTotal()-1;cnt_temp>=0;cnt_temp--)
{
if(OrderSelect(cnt_temp,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber && OrderType()==OP_SELL)
{
ticketnumber=OrderTicket();
if(ticketnumber>oldticketnumber)
{
orderprice=OrderOpenPrice();
oldorderopenprice=orderprice;
oldticketnumber=ticketnumber;
}
}
}
return(orderprice);
}
//+------------------------------------------------------------------+
空頭馬锻烁觥:
#property copyright "aijy.github.io"
#property link "https://aijy.github.io"
#property version "1.00"
input bool UseAdd=true; // 是否使用加倉策略,true:是
input double LotExponent=1; // 加倉系數(shù)
input int slip=3; // 滑點
input double Lots=0.05; // 初始單量
input int LotsDigits=2; //單量精確到小數(shù)點后2位
input double TakeProfit=200; // 止盈
input double PipStep=300; // 加倉間隔秤涩,當一根K線的開盤價與上次開倉價之間價格大于這個數(shù)值帜乞,才加倍開倉
input int MaxTrades=10; //最大訂單數(shù)
input bool UseEquityStop=true; //未使用
input double TotalEquityRisk=20; //loss as a percentage of equity
int MagicNumber=654321;
double PriceTarget,StartEquity,BuyTarget,SellTarget;
double AveragePrice,SellLimit,BuyLimit;
double LastBuyPrice,LastSellPrice,ClosePrice,Spread;
string EAName="SELL";
datetime timeprev=0,expiration;
int NumOfTrades=0;
double iLots;
int cnt=0,total;
double Stopper=0;
bool TradeNow=false,LongTrade=false,ShortTrade=false;
bool NewOrdersPlaced=false;
int init()
{
Spread=MarketInfo(Symbol(),MODE_SPREAD)*Point;
return(0);
}
int deinit()
{
return(0);
}
void OnTick()
{
//---------開倉條件
bool sell_trade=false;
if(iClose(Symbol(),PERIOD_M1,2)>iClose(Symbol(),PERIOD_M1,1))
sell_trade=true;
//------------------------
//---獲取平均的開倉價格---
//------------------------
int ticket;
total=CountTrades();
if(total>=3)
{
int total_profit=CalculateTotalProfit();
if(total_profit>0)
{
}
}
AveragePrice=0;
double Count=0;
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_BUY || OrderType()==OP_SELL)
{
AveragePrice=AveragePrice+OrderOpenPrice()*OrderLots();
Count=Count+OrderLots();
}
}
if(total>0)
AveragePrice=NormalizeDouble(AveragePrice/Count,Digits);
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
{
if(OrderType()==OP_SELL)
{
PriceTarget=AveragePrice-TakeProfit*Point;
if(Ask<PriceTarget)
{
CloseThisSymbolAll();
}
}
}
}
if(timeprev==Time[0])
{
return;
}
timeprev=Time[0];
double CurrentPairProfit=CalculateProfit();
if(UseEquityStop)
{
//當資金損失低于風險值,不再開倉
if(CurrentPairProfit<0 && MathAbs(CurrentPairProfit)>(TotalEquityRisk/100)*AccountEquityHigh())
{
if(TimeCurrent()%120==0)
Print("stop opening new orders");
return;
}
}
Print("貨幣對"+Symbol()+"的止盈:",PriceTarget);
total=CountTrades(); //計算本貨幣對訂單總數(shù)(不包括其他貨幣對)
NumOfTrades=total;
double LastBuyLots;
double LastSellLots;
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
//統(tǒng)計所有訂單筐眷,從中間查找本EA執(zhí)行的本貨幣對訂單黎烈,判斷之前下的是多單還是空單,供后續(xù)使用
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_BUY)
{
LongTrade=true;
ShortTrade=false;
LastBuyLots=OrderLots();
break;
}
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_SELL)
{
LongTrade=false;
ShortTrade=true;
LastSellLots=OrderLots();
break;
}
}
if(total>0 && total<=MaxTrades) //有訂單且訂單總量小于最大值
{
LastBuyPrice=FindLastBuyPrice(); //得到上次開倉的買價(多單)
LastSellPrice=FindLastSellPrice();//得到上次開倉的賣價(空單)
if(LongTrade && (LastBuyPrice-Ask)>=(PipStep*Point))//判斷是否要增開多倉
{
TradeNow=true;
}
if(ShortTrade && (Bid-LastSellPrice)>=(PipStep*Point))//判斷是否要增開空倉
{
TradeNow=true;
}
}
if(total<1) //無訂單的情況
{
ShortTrade=false;
LongTrade=false;
TradeNow=true;
StartEquity=AccountEquity();
}
if(TradeNow && total>0) //如果之前判斷要加倉則執(zhí)行if
{
LastBuyPrice=FindLastBuyPrice(); //得到上次開倉的買價(多單)
LastSellPrice=FindLastSellPrice();//得到上次開倉的賣價(空單)
if(ShortTrade) //如果是空倉
{
NumOfTrades=total;
iLots=fGetLots(OP_SELL);//獲得增加倉位的訂單手數(shù)
if(UseAdd)//按以上計算出來的加倉手數(shù)下單
{
if(iLots>0)
{//#
RefreshRates();
ticket=OpenPendingOrder(OP_SELL,iLots,Bid,slip,Ask,0,0,EAName+"-"+IntegerToString(NumOfTrades),MagicNumber,0,HotPink);
if(ticket<0){Print("Error: ",GetLastError()); return;}
LastSellPrice=FindLastSellPrice();
TradeNow=false;
NewOrdersPlaced=true;
}//#
}
}
else if(LongTrade)//如果是多倉
{
NumOfTrades=total;
iLots=fGetLots(OP_BUY);//獲得增加倉位的訂單手數(shù)
if(UseAdd)//按以上計算出來的加倉手數(shù)下單
{
if(iLots>0)
{//#
ticket=OpenPendingOrder(OP_BUY,iLots,Ask,slip,Bid,0,0,EAName+"-"+NumOfTrades,MagicNumber,0,Lime);
if(ticket<0)
{
Print("Error: ",GetLastError());
return;
}
LastBuyPrice=FindLastBuyPrice();
TradeNow=false;
NewOrdersPlaced=true;
}//#
}
}
}
if(TradeNow && total<1)//當前無本貨幣對訂單匀谣,并且需要交易
{
SellLimit=Bid;
BuyLimit=Ask;
if(!ShortTrade && !LongTrade)//當前既無多單又無空單
{
NumOfTrades=total;
if(sell_trade==true)//如果第二個K線收盤價大于第一根K線收盤價照棋,下空單(首次下單的判定條件)
{
iLots=fGetLots(OP_SELL);
if(iLots>0)
{//#
ticket=OpenPendingOrder(OP_SELL,iLots,SellLimit,slip,SellLimit,0,0,EAName+"-"+NumOfTrades,MagicNumber,0,HotPink);
if(ticket<0)
{
Print(iLots,"Error: ",GetLastError());
return;
}
LastBuyPrice=FindLastBuyPrice();
NewOrdersPlaced=true;
}//#
}
}
TradeNow=false;
}
//------------------------------------------------------
//---以平均開倉價格,計算出止損供所有本貨幣對倉位使用---
//------------------------------------------------------
if(NewOrdersPlaced)
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_BUY) // Calculate profit/stop target for long
{
PriceTarget=AveragePrice+(TakeProfit*Point);
BuyTarget=PriceTarget;
}
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_SELL) // Calculate profit/stop target for short
{
PriceTarget=AveragePrice-(TakeProfit*Point);
SellTarget=PriceTarget;
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double fGetLots(int aTradeType)
{
double tLots;
tLots=NormalizeDouble(Lots*MathPow(LotExponent,NumOfTrades),LotsDigits);
if(AccountFreeMarginCheck(Symbol(),aTradeType,tLots)<=0)
{
return(-1);
}
if(GetLastError()==134)
{
return(-2);
}
return(tLots);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CountTrades()
{
int count=0;
int trade;
for(trade=OrdersTotal()-1;trade>=0;trade--)
{
if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_SELL || OrderType()==OP_BUY)
count++;
}//for
return(count);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseThisSymbolAll()
{
int trade;
for(trade=OrdersTotal()-1;trade>=0;trade--)
{
if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
{
if(OrderType()==OP_BUY)
OrderClose(OrderTicket(),OrderLots(),Bid,slip,Blue);
if(OrderType()==OP_SELL)
OrderClose(OrderTicket(),OrderLots(),Ask,slip,Red);
}
Sleep(1000);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int OpenPendingOrder(int pType,double pLots,double pLevel,int sp,double pr,int sl,int tp,string pComment,int pMagic,datetime pExpiration,color pColor)
{
int ticket=0;
int err=0;
int c=0;
int NumberOfTries=100;
switch(pType)
{
case OP_BUYLIMIT:
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderSend(Symbol(),OP_BUYLIMIT,pLots,pLevel,sp,StopLong(pr,sl),TakeLong(pLevel,tp),pComment,pMagic,pExpiration,pColor);
err=GetLastError();
if(err==0)
{
break;
}
else
{
if(err==4 || err==137 || err==146 || err==136) //Busy errors
{
Sleep(1000);
continue;
}
else //normal error
{
break;
}
}
}
break;
case OP_BUYSTOP:
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderSend(Symbol(),OP_BUYSTOP,pLots,pLevel,sp,StopLong(pr,sl),TakeLong(pLevel,tp),pComment,pMagic,pExpiration,pColor);
err=GetLastError();
if(err==0)
{
break;
}
else
{
if(err==4 || err==137 || err==146 || err==136) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
break;
}
}
}
break;
case OP_BUY:
for(c=0;c<NumberOfTries;c++)
{
RefreshRates();
ticket=OrderSend(Symbol(),OP_BUY,pLots,Ask,sp,StopLong(Bid,sl),TakeLong(Ask,tp),pComment,pMagic,pExpiration,pColor);
err=GetLastError();
if(err==0)
{
break;
}
else
{
if(err==4 || err==137 || err==146 || err==136) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
break;
}
}
}
break;
case OP_SELLLIMIT:
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderSend(Symbol(),OP_SELLLIMIT,pLots,pLevel,sp,StopShort(pr,sl),TakeShort(pLevel,tp),pComment,pMagic,pExpiration,pColor);
err=GetLastError();
if(err==0)
{
break;
}
else
{
if(err==4 || err==137 || err==146 || err==136) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
break;
}
}
}
break;
case OP_SELLSTOP:
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderSend(Symbol(),OP_SELLSTOP,pLots,pLevel,sp,StopShort(pr,sl),TakeShort(pLevel,tp),pComment,pMagic,pExpiration,pColor);
err=GetLastError();
if(err==0)
{
break;
}
else
{
if(err==4 || err==137 || err==146 || err==136) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
break;
}
}
}
break;
case OP_SELL:
for(c=0;c<NumberOfTries;c++)
{
ticket=OrderSend(Symbol(),OP_SELL,pLots,Bid,sp,StopShort(Ask,sl),TakeShort(Bid,tp),pComment,pMagic,pExpiration,pColor);
err=GetLastError();
if(err==0)
{
break;
}
else
{
if(err==4 || err==137 || err==146 || err==136) //Busy errors
{
Sleep(5000);
continue;
}
else //normal error
{
break;
}
}
}
break;
}
return(ticket);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double StopLong(double price,int stop)
{
if(stop==0)
return(0);
else
return(price-(stop*Point));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double StopShort(double price,int stop)
{
if(stop==0)
return(0);
else
return(price+(stop*Point));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double TakeLong(double price,int take)
{
if(take==0)
return(0);
else
return(price+(take*Point));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double TakeShort(double price,int take)
{
if(take==0)
return(0);
else
return(price-(take*Point));
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CalculateProfit()
{
double Profit=0;
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
if(OrderType()==OP_BUY || OrderType()==OP_SELL)
{
Profit=Profit+OrderProfit();
}
}
return(Profit);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double AccountEquityHigh()
{
static double AccountEquityHighAmt,PrevEquity;
if(CountTrades()==0) AccountEquityHighAmt=AccountEquity();
if(AccountEquityHighAmt<PrevEquity) AccountEquityHighAmt=PrevEquity;
else AccountEquityHighAmt=AccountEquity();
PrevEquity=AccountEquity();
return(AccountEquityHighAmt);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double FindLastBuyPrice()
{
double oldorderopenprice=0,orderprice=0;
int cnt_temp,oldticketnumber=0,ticketnumber;
for(cnt_temp=OrdersTotal()-1;cnt_temp>=0;cnt_temp--)
{
if(OrderSelect(cnt_temp,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber && OrderType()==OP_BUY)
{
ticketnumber=OrderTicket();
if(ticketnumber>oldticketnumber)
{
orderprice=OrderOpenPrice();
oldorderopenprice=orderprice;
oldticketnumber=ticketnumber;
}
}
}
return(orderprice);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double FindLastSellPrice()
{
double oldorderopenprice=0,orderprice=0;
int cnt_temp,oldticketnumber=0,ticketnumber;
for(cnt_temp=OrdersTotal()-1;cnt_temp>=0;cnt_temp--)
{
if(OrderSelect(cnt_temp,SELECT_BY_POS,MODE_TRADES))
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber && OrderType()==OP_SELL)
{
ticketnumber=OrderTicket();
if(ticketnumber>oldticketnumber)
{
orderprice=OrderOpenPrice();
oldorderopenprice=orderprice;
oldticketnumber=ticketnumber;
}
}
}
return(orderprice);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double CalculateTotalProfit()
{
double Profit=0;
for(cnt=OrdersTotal()-1;cnt>=0;cnt--)
{
if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES) && OrderMagicNumber()==MagicNumber)
{
Profit=Profit+OrderProfit();
}
}
return(Profit);
}
馬丁策略的改良方法
馬丁策略在單邊行情越大時風險越大武翎。下面烈炭,我們簡單探討一下馬丁的風險控制。
在加倉間距上進行控制宝恶,使用較大的加倉可減小風險符隙,過大的加倉間距可能遲遲不能盈利出場,這點比較難把控垫毙。
在加倉倍數(shù)上進行控制霹疫,使用較小的加倉倍數(shù)睡榆,策略會更穩(wěn)健压汪。
馬丁也可以結合止盈止損,該止損的時候不能猶豫雾鬼,如果真的觸碰了止損線膀藐,就要反思參數(shù)設置的合理性了屠阻。
可以改變馬丁加倉的位置,加倉的位置可以是K線有回調(diào)的時候才加额各。
EA的風險控制
EA風險控制是重中之重国觉。
凈值風險控制
#property copyright "shiyingpan"
#property link "https://aijy.github.io"
#property version "1.0"
#property strict
enum mybool
{
是=1,
否=0,
};
input mybool 是否手動輸入凈值=否;
input double 手動輸入初始資金=0;
input double 凈值風險率=15; //--- 凈值虧損15%時,強平出場
input double 盈利提示一=5; //--- 凈值盈利到5%時虾啦,提示關注
input double 盈利提示二=10; //--- 凈值盈利到10%時蛉加,強平出場
input double 虧損提示一=5; //--- 凈值虧損到5%時蚜枢,提示關注
input double 虧損提示二=10; //--- 凈值虧損到10%時,搶平出場
double 初始資金=0;
int flag[4]={0,0,0,0}; //--- 凈值浮動狀態(tài)
int OnInit()
{
while(AccountNumber()==0)
Sleep(10000);
// 初始資金=AccountEquity();
if(是否手動輸入凈值==否)
初始資金=AccountBalance();
else
初始資金=手動輸入初始資金;
if(初始資金==0)
{
Alert("當前賬戶無資金针饥!");
return(INIT_FAILED);
}
if(AccountEquity()<初始資金*(100-凈值風險率)/100)
{
Alert("當前凈值虧損超過凈值風險率厂抽,無法加載!");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
void OnTick()
{
if(AccountEquity()<初始資金*(100-凈值風險率)/100)
{
Alert("資金虧損超過"+DoubleToString(凈值風險率,1)+"%,全部平倉丁眼。虧損:",DoubleToStr(AccountEquity()-初始資金,2)," 凈值:",AccountEquity());
SendMail("資金虧損超過"+DoubleToString(凈值風險率,1)+"%,全部平倉筷凤。虧損:"+DoubleToStr(AccountEquity()-初始資金,2)+" 凈值:"+DoubleToStr(AccountEquity()),"");
flag[1]=1;flag[2]=1;
close_chart(); //改Return 為close_chart();
close_all();
Sleep(5000);
}
if(AccountEquity()<初始資金*(100-虧損提示一)/100 && flag[1]==0)
{
Alert("資金虧損超過"+DoubleToString(虧損提示一,1)+"%,虧損:",DoubleToStr(AccountEquity()-初始資金,2)," 凈值:",AccountEquity());
SendMail("資金虧損超過"+DoubleToString(虧損提示一,1)+"%,虧損:"+DoubleToStr(AccountEquity()-初始資金,2)+" 凈值:"+DoubleToStr(AccountEquity()),"");
flag[1]=1;
return;
}
if(AccountEquity()<初始資金*(100-虧損提示二)/100 && flag[2]==0)
{
Alert("資金虧損超過"+DoubleToString(虧損提示二,1)+"%,虧損:",DoubleToStr(AccountEquity()-初始資金,2)," 凈值:",AccountEquity());
SendMail("資金虧損超過"+DoubleToString(虧損提示二,1)+"%,虧損:"+DoubleToStr(AccountEquity()-初始資金,2)+" 凈值:"+DoubleToStr(AccountEquity()),"");
flag[2]=1;
close_chart();
close_all();
ExpertRemove();
Sleep(100000);
return;
}
if(AccountEquity()>初始資金*(100+盈利提示一)/100 && flag[3]==0)
{
Alert("資金盈利超過"+DoubleToString(盈利提示一,1)+"%,盈利:",DoubleToStr(AccountEquity()-初始資金,2)," 凈值:",AccountEquity());
SendMail("資金盈利超過"+DoubleToString(盈利提示一,1)+"%,盈利:"+DoubleToStr(AccountEquity()-初始資金,2)+" 凈值:"+DoubleToStr(AccountEquity()),"");
flag[3]=1;
return;
}
if(AccountEquity()>初始資金*(100+盈利提示二)/100 && flag[4]==0)
{
Alert("資金盈利超過"+DoubleToString(盈利提示二,1)+"%,盈利:",DoubleToStr(AccountEquity()-初始資金,2)," 凈值:",AccountEquity());
SendMail("資金盈利超過"+DoubleToString(盈利提示二,1)+"%,盈利:"+DoubleToStr(AccountEquity()-初始資金,2)+" 凈值:"+DoubleToStr(AccountEquity()),"");
flag[4]=1;
close_chart();
close_all();
ExpertRemove();
Sleep(100000);
return;
}
Sleep(500);
}
void close_all() //--- 平掉所有倉位
{
int ticket[200],cnt=0;
for(int i=0;i<=OrdersTotal()-1;i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
ticket[cnt]=OrderTicket();
cnt++;
}
}
for(int i=0;i<=cnt-1;i++)
{
if(OrderSelect(ticket[i],SELECT_BY_TICKET,MODE_TRADES))
{
if(OrderType()==OP_BUY)
if(!OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3,clrRed))
OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3,clrRed);
if(OrderType()==OP_SELL)
if(!OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3,clrRed))
OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3,clrRed);
if(OrderType()==OP_BUYLIMIT || OrderType()==OP_SELLLIMIT || OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP)
if(!OrderDelete(OrderTicket(),clrRed))
OrderDelete(OrderTicket(),clrRed);
}
}
}
void close_chart() //--- 關閉所有圖表和EA
{
long chart_total[100];
long currChart,prevChart=ChartFirst();
chart_total[0]=prevChart;
int i=0,limit=100;
while(i<limit)// We have certainly not more than 100 open charts
{
currChart=ChartNext(prevChart); // Get the new chart ID by using the previous chart ID
if(currChart<0) break; // Have reached the end of the chart list
prevChart=currChart;// let's save the current chart ID for the ChartNext()
i=i+1;// Do not forget to increase the counter
chart_total[i]=prevChart;
Print(i,chart_total[i]);
}
for(int j=0;j<=i;j++)
if(chart_total[j]!=ChartID())
ChartClose(chart_total[j]);
}
單量風險控制
#property copyright "shiyingpan"
#property link "https://aijy.github.io"
#property version "1.00"
#property strict
input double 萬美金最大單量=2; //--- 一萬美金可下幾首單量,按比例縮減
bool new_orders=true;
double max_lots=0;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int OnInit()
{
while(AccountNumber()==0)
Sleep(10000);
max_lots=AccountEquity()/10000*萬美金最大單量;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnTick()
{
double total_lots=0;
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
total_lots=total_lots+OrderLots();
}
}
if(total_lots>max_lots)
{
new_orders=false;
}
if(new_orders==true)
{
Print("當前單量未超最大單量苞七,允許下單");
}
}