最近,我一直在考虑如何使用趋势线。如何选择绘制趋势线的点以及绘制的精确度一直是个问题。我决定使用分形来作为基础。
我的主要工作是分析市场,也能花些时间来做交易。你不能仅仅在长时间框架下绘制趋势线,应能够通过极点精确到15分钟图表上。原因是长时间框架上的分形时间并不总是等于M15上的极值点的时间。简而言之,自动化在此能够派上用场。我开始用MQL5编写代码然后移植到MQL4上,因为我需要程序运行于MetaTrader 4。
在本文中,我将以MQL4和MQL5两种语言来呈现问题的解决方案。虽然在本文中对两种语言进行了比较,但并不是为了对比MQL4和MQL5的执行效率。当然我也意识到可能有比我更好的解决方法。本文对使用MQL4或MQL5编写脚本的初学者有帮助,尤其是那些计划使用分形和趋势线的朋友。
我使用如下变量作为参数:
input color Resistance_Color=Red; // 设置阻力线颜色 input ENUM_LINE_STYLE Resistance_Style; // 设置阻力线类型 input int Resistance_Width=1; // 设置阻力线宽度 input color Support_Color=Red; // 设置支撑线颜色 input ENUM_LINE_STYLE Support_Style; // 设置支撑线类型 input int Support_Width=1; // 设置支撑线宽度
这些变量对于MQL4和MQL5都是一样的。
在MQL5中我们得先创建指标:
//--- iFractals 指标句柄 int Fractal; //+------------------------------------------------------------------+ //| EA初始化函数 | //+------------------------------------------------------------------+ int OnInit() { //--- 获取iFractals指标句柄 Fractal=iFractals(Symbol(),PERIOD_D1); //--- return(INIT_SUCCEEDED); }
因为程序将绘制图形对象,那么有必要在EA从图标上移除的同时删除它们。
void OnDeinit(const int reason) { ObjectDelete(0,"TL_Resistance"); ObjectDelete(0,"TL_Support"); }
绘制两条直线(支撑和阻力线)需要四个点。要确定点需要知道时间和价格。
坐标以如下顺序确定:首选,我们找到极点所在K线,找到它我们就能确定极点的价格和时间。
在OnTick()函数中声明变量:
MQL4 |
---|
//--- 声明变量 int n,UpperFractal_1,UpperFractal_2,LowerFractal_1,LowerFractal_2; |
MQL5 |
---|
//--- 声明变量 int n,UpperFractal_1,UpperFractal_2,LowerFractal_1,LowerFractal_2; //--- 声明用于写入iFractal指标值的缓存数组 double FractalDown[],FractalUp[]; double UpFractal_1,UpFractal_2,LowFractal_1,LowFractal_2; |
首先,我仅仅声明了那些用于存储形成分形的K线索引变量。
在MQL4中:
在MQL5中我们引入额外的变量:
要找到形成最近分形的K线,我们使用for循环操作符。
让我们确定最先的两个K线的索引,它们对应第一和第二上分形。
MQL4 |
---|
//--- 找到最近的上分形K线索引 for(n=0; n<(Bars-1);n++) { if(iFractals(NULL,1440,MODE_UPPER,n)!=NULL) break; UpperFractal_1=n+1; } //--- 找到第二近的上分形K线索引 for(n=UpperFractal_1+1; n<(Bars-1);n++) { if(iFractals(NULL,1440,MODE_UPPER,n)!=NULL) break; UpperFractal_2=n+1; } |
MQL5 |
---|
//--- 首先,我们要将分形指标缓存值写入数组 //--- 用缓存值填充数组 CopyBuffer(Fractal,0,TimeCurrent(),Bars(Symbol(),PERIOD_D1),FractalUp); CopyBuffer(Fractal,1,TimeCurrent(),Bars(Symbol(),PERIOD_D1),FractalDown); //--- 索引类似时间序列 ArraySetAsSeries(FractalUp,true); ArraySetAsSeries(FractalDown,true); //--- 接下来我们使用for循环来查找第一个上分形 for(n=0; n<Bars(Symbol(),PERIOD_D1); n++) { //--- 如果值非空,跳出循环体 if(FractalUp[n]!=EMPTY_VALUE) break; } //--- 将第一个分形的价格写入变量 UpFractal_1=FractalUp[n]; //--- 将其索引写入变量 UpperFractal_1=n; //--- 查找第二个上分形 for(n=UpperFractal_1+1; n<Bars(Symbol(),PERIOD_D1); n++) { if(FractalUp[n]!=EMPTY_VALUE) //如果值非空,跳出循环体 break; } //--- 将第二个分形的价格写入变量 UpFractal_2=FractalUp[n]; //--- 将第二个分形的索引写入变量 UpperFractal_2=n; |
在这里我清楚的揭示了MQL5和MQL4的区别 - 使用获取时间序列的函数。
在MQL4中,我立即开始查找形成分形的K线索引,但是在MQL5中我定义了FractalUp[]和FractalDown[]数组来存储上下分形的值,它们通过iFractals指标和CopyBuffer()函数获取。接下来,我使用ArraySetAsSeries()函数将这些数组设置为时间序列。
在MQL4中和仅仅获得分形对应K线的索引,但是在MQL5中我使用CopyBuffer()函数获取分形的索引和其对应的价格。
类似的,我们找到了最近的两个下分形:
MQL4 |
---|
//--- 找到最近的下分K线形索引 for(n=0; n<(Bars-1);n++) { if(iFractals(NULL,1440,MODE_LOWER,n)!=NULL) break; LowerFractal_1=n+1; } //--- 找到第二近的下分形K线索引 for(n=LowerFractal_1+1; n<(Bars-1);n++) { if(iFractals(NULL,1440,MODE_LOWER,n)!=NULL) break; LowerFractal_2=n+1; } |
MQL5 |
---|
//--- 找到下分形的值 //--- 查找最近的下分形 for(n=0; n<Bars(Symbol(),PERIOD_D1); n++) { //--- 如果值非空,跳出循环体 if(FractalDown[n]!=EMPTY_VALUE) break; } //--- 将第一个分形的价格写入变量 LowFractal_1=FractalDown[n]; //--- 将其索引写入变量 LowerFractal_1=n; //--- 查找第二个下分形 for(n=LowerFractal_1+1; n<Bars(Symbol(),PERIOD_D1); n++) { if(FractalDown[n]!=EMPTY_VALUE) break; } //--- 将第二个分形的价格写入变量 LowFractal_2=FractalDown[n]; //--- 将第二个分形的索引写入变量 LowerFractal_2=n; |
如你所见,MQL4和MQL5代码非常类似。只有一些句法上细微的区别。
要绘制趋势线,我们需要确定分形的时间和价格。当然,在MQL4中我们可以简单的使用High[]和Low[]预定义时间序列变量,以及iTime()函数,然而我们也需要获取更为精确的坐标来确保绘制趋势线的准确性。
图1-2显示了H4和M15时间框架下极点时间的差别。
图1. H4图表上的极点时间。
图2. M15图表上的极点时间
我得出结论,M15上的极点精度对我来说已经足够。
总的来说,极点确定的原则在MQL4和MQL5上几乎是一样的,但是细节上还是略有差异:
MQL4 | MQL5 |
---|---|
|
|
每一步的代码如下:
MQL4 |
---|
// Step 1. 在大时间框架下确定极点时间: //--- 确定分形的时间 datetime UpFractalTime_1=iTime(NULL, 1440,UpperFractal_1); datetime UpFractalTime_2=iTime(NULL, 1440,UpperFractal_2); datetime LowFractalTime_1=iTime(NULL, 1440,LowerFractal_1); datetime LowFractalTime_2=iTime(NULL, 1440,LowerFractal_2); |
// Step 2. 在较小的时间框架上确定极点所在K线的索引 //--- 在M15上查找分形索引 int UpperFractal_1_m15=iBarShift(NULL, 15, UpFractalTime_1,true); int UpperFractal_2_m15=iBarShift(NULL, 15, UpFractalTime_2,true); int LowerFractal_1_m15=iBarShift(NULL, 15, LowFractalTime_1,true); int LowerFractal_2_m15=iBarShift(NULL, 15, LowFractalTime_2,true); |
// Step 3. 在M15上使用数组查找极点: //--- 使用数组查找极点 //--- 声明i变量用于循环 int i; //--- 1. 首先,查找低值极点 //--- 3.1 查找最近的低值极点 //--- 声明存储K线索引值的数组 int Lower_1_m15[96]; //--- 声明存储价格的数组 double LowerPrice_1_m15[96]; //--- 开始循环: for(i=0;i<=95;i++) { //--- 用K线索引值填充数组 Lower_1_m15[i]=LowerFractal_1_m15-i; //--- 用价格填充数组 LowerPrice_1_m15[i]=iLow(NULL,15,LowerFractal_1_m15-i); } //--- 确定数组中的最低价 int LowestPrice_1_m15=ArrayMinimum(LowerPrice_1_m15,WHOLE_ARRAY,0); //--- 确定数组中最低价对应的K线索引 int LowestBar_1_m15=Lower_1_m15[LowestPrice_1_m15]; //--- 确定最低价K线所在的时间 datetime LowestBarTime_1_m15=iTime(NULL,15,Lower_1_m15[LowestPrice_1_m15]); //--- 3.2 查找第二极值点 int Lower_2_m15[96]; double LowerPrice_2_m15[96]; for(i=0;i<=95;i++) { //--- 用K线索引值填充数组 Lower_2_m15[i]=LowerFractal_2_m15-i; //--- 用价格填充数组 LowerPrice_2_m15[i]=iLow(NULL,15,LowerFractal_2_m15-i); } //--- 确定数组中的最低价 int LowestPrice_2_m15=ArrayMinimum(LowerPrice_2_m15,WHOLE_ARRAY,0); //--- 确定数组中最低价对应的K线索引 int LowestBar_2_m15=Lower_2_m15[LowestPrice_2_m15]; //--- 确定最低价K线所在的时间 datetime LowestBarTime_2_m15=iTime(NULL,15,Lower_2_m15[LowestPrice_2_m15]); //--- 3.3 查找最近的高值极点 int Upper_1_m15[96]; double UpperPrice_1_m15[96]; for(i=0;i<=95;i++) { //--- 用K线索引值填充数组 Upper_1_m15[i]=UpperFractal_1_m15-i; //--- 用价格填充数组 UpperPrice_1_m15[i]=iHigh(NULL,15,UpperFractal_1_m15-i); } //--- 确定数组中的最高价 int HighestPrice_1_m15=ArrayMaximum(UpperPrice_1_m15,WHOLE_ARRAY,0); //--- 确定数组中最高价对应的K线索引 int HighestBar_1_m15=Upper_1_m15[HighestPrice_1_m15]; //--- 确定最高价K线所在的时间 datetime HighestBarTime_1_m15=iTime(NULL,15,Upper_1_m15[HighestPrice_1_m15]); //--- 3.4 查找第二高值极值点 int Upper_2_m15[96]; double UpperPrice_2_m15[96]; for(i=0;i<=95;i++) { //--- 用K线索引值填充数组 Upper_2_m15[i]=UpperFractal_2_m15-i; //--- 用价格填充数组 UpperPrice_2_m15[i]=iHigh(NULL,15,UpperFractal_2_m15-i); } |
MQL5 |
---|
// Step 1. 在大时间框架下确定极点时间: //--- 声明存储较大时间框架下K线对应的时间的数组 datetime UpFractalTime_1[],LowFractalTime_1[],UpFractalTime_2[],LowFractalTime_2[]; //--- 确定较大时间框架下分形的时间 CopyTime(Symbol(),PERIOD_D1,UpperFractal_1,1,UpFractalTime_1); CopyTime(Symbol(),PERIOD_D1,LowerFractal_1,1,LowFractalTime_1); CopyTime(Symbol(),PERIOD_D1,UpperFractal_2,1,UpFractalTime_2); CopyTime(Symbol(),PERIOD_D1,LowerFractal_2,1,LowFractalTime_2); |
// Step 2. 确定下一个日线的开始时间 //--- 确定下一个日线的开始时间(CopyHigh(),CopyLow() 和 CopyTime()的结束时间) datetime UpFractalTime_1_15=UpFractalTime_1[0]+86400; datetime UpFractalTime_2_15=UpFractalTime_2[0]+86400; datetime LowFractalTime_1_15=LowFractalTime_1[0]+86400; datetime LowFractalTime_2_15=LowFractalTime_2[0]+86400; |
// Step 3. 声明和填充15分钟时间框架下的时间和价格数组: //--- 声明存储最大和最小价格值的数组 double High_1_15[],Low_1_15[],High_2_15[],Low_2_15[]; //--- 用CopyHigh() 和 CopyLow() 函数填充数组 CopyHigh(Symbol(),PERIOD_M15,UpFractalTime_1[0],UpFractalTime_1_15,High_1_15); CopyHigh(Symbol(),PERIOD_M15,UpFractalTime_2[0],UpFractalTime_2_15,High_2_15); CopyLow(Symbol(),PERIOD_M15,LowFractalTime_1[0],LowFractalTime_1_15,Low_1_15); CopyLow(Symbol(),PERIOD_M15,LowFractalTime_2[0],LowFractalTime_2_15,Low_2_15); //--- 声明存储对应极点所在K线时间的数组 datetime High_1_15_time[],High_2_15_time[],Low_1_15_time[],Low_2_15_time[]; //--- 填充数组 CopyTime(Symbol(),PERIOD_M15,UpFractalTime_1[0],UpFractalTime_1_15,High_1_15_time); CopyTime(Symbol(),PERIOD_M15,UpFractalTime_2[0],UpFractalTime_2_15,High_2_15_time); CopyTime(Symbol(),PERIOD_M15,LowFractalTime_1[0],LowFractalTime_1_15,Low_1_15_time); CopyTime(Symbol(),PERIOD_M15,LowFractalTime_2[0],LowFractalTime_2_15,Low_2_15_time); |
// Step 4. 查找最低和最高价格,以及极点对应的时间值 //--- 用ArrayMaximum() 和 ArrayMinimum() 函数确定最高和最低价格以及时间 int Max_M15_1=ArrayMaximum(High_1_15,0,96); int Max_M15_2=ArrayMaximum(High_2_15,0,96); int Min_M15_1=ArrayMinimum(Low_1_15,0,96); int Min_M15_2=ArrayMinimum(Low_2_15,0,96); |
最后,我们确定了下面趋势线的坐标:
1. 支撑线:
MQL4 | MQL5 |
---|---|
|
|
2. 对于阻力线:
MQL4 | MQL5 |
---|---|
|
|
现在,当我们知道了直线的坐标后,我们仅仅需要创建图形对象了:
MQL4 |
---|
//--- 创建支撑线 ObjectCreate(0,"TL_Support",OBJ_TREND,0,LowestBarTime_2_m15,LowerPrice_2_m15[LowestPrice_2_m15], LowestBarTime_1_m15,LowerPrice_1_m15[LowestPrice_1_m15]); ObjectSet("TL_Support",OBJPROP_COLOR,Support_Color); ObjectSet("TL_Support",OBJPROP_STYLE,Support_Style); ObjectSet("TL_Support",OBJPROP_WIDTH,Support_Width); //--- 创建阻力线 ObjectCreate(0,"TL_Resistance",OBJ_TREND,0,HighestBarTime_2_m15,UpperPrice_2_m15[HighestPrice_2_m15], HighestBarTime_1_m15,UpperPrice_1_m15[HighestPrice_1_m15]); ObjectSet("TL_Resistance",OBJPROP_COLOR,Resistance_Color); ObjectSet("TL_Resistance",OBJPROP_STYLE,Resistance_Style); ObjectSet("TL_Resistance",OBJPROP_WIDTH,Resistance_Width); |
MQL5 |
---|
//--- 创建支撑线 ObjectCreate(0,"TL_Support",OBJ_TREND,0,Low_2_15_time[Min_M15_2],Low_2_15[Min_M15_2],Low_1_15_time[Min_M15_1],Low_1_15[Min_M15_1]); ObjectSetInteger(0,"TL_Support",OBJPROP_RAY_RIGHT,true); ObjectSetInteger(0,"TL_Support",OBJPROP_COLOR,Support_Color); ObjectSetInteger(0,"TL_Support",OBJPROP_STYLE,Support_Style); ObjectSetInteger(0,"TL_Support",OBJPROP_WIDTH,Support_Width); //--- 创建阻力线 ObjectCreate(0,"TL_Resistance",OBJ_TREND,0,High_2_15_time[Max_M15_2],High_2_15[Max_M15_2],High_1_15_time[Max_M15_1],High_1_15[Max_M15_1]); ObjectSetInteger(0,"TL_Resistance",OBJPROP_RAY_RIGHT,true); ObjectSetInteger(0,"TL_Resistance",OBJPROP_COLOR,Resistance_Color); ObjectSetInteger(0,"TL_Resistance",OBJPROP_STYLE,Resistance_Style); ObjectSetInteger(0,"TL_Resistance",OBJPROP_WIDTH,Resistance_Width); |
至此我创建了需要的线并且基于输入参数确定了他们的参数。
现在我们要绘制趋势线了。
当市场情况发生变化时,例如,当新的极点出现时,我们要将已有的线移除:
MQL4 |
---|
//--- 重绘支撑线 //--- 将支撑线的时间坐标写入变量中 datetime TL_TimeLow2=ObjectGet("TL_Support",OBJPROP_TIME2); datetime TL_TimeLow1=ObjectGet("TL_Support",OBJPROP_TIME1); //--- 如果线的坐标不符合当前坐标 if(TL_TimeLow2!=LowestBarTime_1_m15 && TL_TimeLow1!=LowestBarTime_2_m15) { //--- 移除直线 ObjectDelete(0,"TL_Support"); } //--- 重绘支撑线 //--- 将阻力线的时间坐标写入变量中 datetime TL_TimeUp2=ObjectGet("TL_Resistance",OBJPROP_TIME2); datetime TL_TimeUp1=ObjectGet("TL_Resistance",OBJPROP_TIME1); //--- 如果线的坐标不符合当前坐标 if(TL_TimeUp2!=HighestBarTime_1_m15 && TL_TimeUp1!=HighestBarTime_2_m15) { //--- 移除直线 ObjectDelete(0,"TL_Resistance"); } |
MQL5 |
---|
//--- 重绘支撑线 //--- 将支撑线的时间坐标写入变量中 datetime TL_TimeLow2=(datetime)ObjectGetInteger(0,"TL_Support",OBJPROP_TIME,0); datetime TL_TimeLow1=(datetime)ObjectGetInteger(0,"TL_Support",OBJPROP_TIME,1); //--- 如果线的坐标不符合当前坐标 if(TL_TimeLow2!=Low_2_15_time[Min_M15_2] && TL_TimeLow1!=Low_1_15_time[Min_M15_1]) { //--- 移除直线 ObjectDelete(0,"TL_Support"); } //--- 重绘支撑线 //--- 将阻力线的时间坐标写入变量中 datetime TL_TimeUp2=(datetime)ObjectGetInteger(0,"TL_Resistance",OBJPROP_TIME,0); datetime TL_TimeUp1=(datetime)ObjectGetInteger(0,"TL_Resistance",OBJPROP_TIME,1); //--- 如果线的坐标不符合当前坐标 if(TL_TimeUp2!=High_2_15_time[Max_M15_2] && TL_TimeUp1!=High_1_15_time[Max_M15_1]) { //--- 移除直线 ObjectDelete(0,"TL_Resistance"); } |
在测试中我发现这些线并不总是能够正确绘制。
起先我向可能是代码中有bug或者我的解决方案有问题。但是后来我意识到问题是由于较小时间框架如M15上的历史数据加载不完全导致的。为了提醒用户这种情况的出现,我决定增加额外的代码来检查M15上K线是否足够。
为了实现这一目标,我使用MQL4中的iBarShift()函数,这也是我在“确定分形的价格和时间值”时用到过的函数。
如果没有找到K线,iBarShift()函数会返回-1。因此,我们输出以下警告:
MQL4 |
---|
//--- 检查历史数据加载情况 //--- 如果至少有一个分形对应的K线在M15上没有找到 if(UpperFractal_1_m15==-1 || UpperFractal_2_m15==-1 || LowerFractal_1_m15==-1 || LowerFractal_2_m15==-1) { Alert("The loaded history is insufficient for the correct work!"); } |
在MQl5中我使用Bars()函数,如果时间序列数据没有在生成,它会返回一个空值:
//--- 检查历史数据加载情况 //--- 1. 确定特定时间框架下的K线数量 int High_M15_1=Bars(Symbol(),PERIOD_M15,UpFractalTime_1[0],UpFractalTime_1_15); int High_M15_2=Bars(Symbol(),PERIOD_M15,UpFractalTime_2[0],UpFractalTime_2_15); int Low_M15_1=Bars(Symbol(),PERIOD_M15,LowFractalTime_1[0],LowFractalTime_1_15); int Low_M15_2=Bars(Symbol(),PERIOD_M15,LowFractalTime_2[0],LowFractalTime_2_15); //--- 2. 检查用于正确绘制线段的历史数据是否足够 //--- 如果至少有一个没有找到 if(High_M15_1==0 || High_M15_2==0 || Low_M15_1==0 || Low_M15_2==0) { Alert("The loaded history is insufficient for the correct work!"); } |
为了使图完整,我决定当趋势线被突破时增加一个提示信号。趋势线由日时间框架下的极点绘制,但是为了能够早些确认突破,在H4图上K线必须收盘低于或高于趋势线。
总的来说,我们可以将此过程分为三步:
MQL4 |
---|
// 1. 获取趋势线的价格参数 //--- 确定索引为1的K线的收盘价 double Price_Close_H4=iClose(NULL,240,1); //--- 确定索引为1的K线的时间 datetime Time_Close_H4=iTime(NULL,240,1); //---确定H4图上K线的索引 int Bar_Close_H4=iBarShift(NULL,240,Time_Close_H4); //--- 确定H4图上趋势线的价格 double Price_Resistance_H4=ObjectGetValueByShift("TL_Resistance",Bar_Close_H4); //--- 确定H4图上趋势线的价格 double Price_Support_H4=ObjectGetValueByShift("TL_Support",Bar_Close_H4); |
// 2. 突破趋势线的条件 //--- 突破支撑线 bool breakdown=(Price_Close_H4<Price_Support_H4); //--- 突破阻力线 bool breakup=(Price_Close_H4>Price_Resistance_H4); |
// 3. 发送推送消息 if(breakdown==true) { //---每4小时只发送一次通知 int SleepMinutes=240; static int LastTime=0; if(TimeCurrent()>LastTime+SleepMinutes*60) { LastTime=TimeCurrent(); SendNotification(Symbol()+"The price has broken through the support line"); } } if(breakup==true) { //---每4小时只发送一次通知 SleepMinutes=240; LastTime=0; if(TimeCurrent()>LastTime+SleepMinutes*60) { LastTime=TimeCurrent(); SendNotification(Symbol()+"The price has broken through the resistance line"); } } |
MQL5 |
---|
// 1. 获取趋势线的价格参数 double Close[]; CopyClose(Symbol(),PERIOD_H4,TimeCurrent(),10,Close); //--- 设置数组索引顺序 ArraySetAsSeries(Close,true); //--- datetime Close_time[]; CopyTime(Symbol(),PERIOD_H4,TimeCurrent(),10,Close_time); //--- 设置数组索引顺序 ArraySetAsSeries(Close_time,true); //--- double Price_Support_H4=ObjectGetValueByTime(0,"TL_Support",Close_time[1]); double Price_Resistance_H4=ObjectGetValueByTime(0,"TL_Resistance",Close_time[1]); |
// 2. 突破趋势线的条件 bool breakdown=(Close[1]<Price_Support_H4); bool breakup=(Close[1]>Price_Resistance_H4); |
// 3. 发送推送消息 if(breakdown==true) { //---每4小时只发送一次通知 int SleepMinutes=240; static int LastTime=0; if(TimeCurrent()>LastTime+SleepMinutes*60) { LastTime=(int)TimeCurrent(); SendNotification(Symbol()+"The price has broken through the support line"); } } if(breakup==true) { //---每4小时只发送一次通知 int SleepMinutes=240; static int LastTime=0; if(TimeCurrent()>LastTime+SleepMinutes*60) { LastTime=(int)TimeCurrent(); SendNotification(Symbol()+"The price has broken through the resistance line"); } } |
为了确定一个突破,在MQL4中我使用ObjectGetValueByShift()函数,在MQL5中使用ObjectGetValueByTime()函数。
获取我仅仅可以设置1来代替Bar_Close_H4作为ObjectGetValueByShift()的参数,但是我决定先确定H4图上的索引号。我使用这个论坛帖子所介绍的方法来限制消息发送次数,在这里非常感谢这篇帖子的作者。
最简单的办法是:确定一个突破,等待回踩后再入场。
理想状态下,会有如下情况:
图 3. 突破趋势线
你可以使用想象力来尝试确定形态,例如,技术分析的形态,三角形。
图4. 三角模式
上图中较小时间框架下的趋势线没有说明。
全文总结,希望那个对你有用。本文面向和我一样的业务初级程序开发者。
在撰写本文时我获益匪浅:首先,我开始更多地对代码进行注释;其次,刚开始时我使用较为笨拙和繁复的方法来查找极点,但是后来我慢慢的使用更为简单的解决方案,正如文中所呈现的。
感谢您,有任何问题都请联系我。
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...