rsi上涨继续,下跌继续源码
//+------------------------------------------------------------------+//| RSIOMA_Final.mq4 |
//| Copyright © 2025, EarnForex.com |
//| Chinese Label & Cooldown Modification by AI Assistant |
//| Based on indicator by Kalenzo bartlomiej.gorski@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2025, EarnForex.com"
#property link "https://www.earnforex.com"
#property version "2.01_Final_CN"
#property strict
#property description "RSIOMA显示一个基于MA相对强弱构建的RSI。"
#property description "核心信号: '续涨' 和 '续跌' 已在K线上标注。"
#property indicator_separate_window
#property indicator_buffers 8
#property indicator_color1 clrBlue
#property indicator_type1DRAW_LINE
#property indicator_width1 3
#property indicator_label1 "RSIOMA"
#property indicator_color2 clrRed
#property indicator_type2DRAW_HISTOGRAM
#property indicator_label2 "下跌趋势"
#property indicator_color3 clrGreen
#property indicator_type3DRAW_HISTOGRAM
#property indicator_label3 "上涨趋势"
#property indicator_color4 clrMagenta
#property indicator_type4DRAW_HISTOGRAM
#property indicator_label4 "顶部反转预警"
#property indicator_color5 clrDodgerBlue
#property indicator_type5DRAW_HISTOGRAM
#property indicator_label5 "底部反转预警"
#property indicator_color6 clrBlueViolet
#property indicator_type6DRAW_LINE
#property indicator_label6 "MA of RSIOMA"
#property indicator_minimum -10
#property indicator_maximum 100
// --- 中文标注输入参数 ---
input stringGroupName = "--- 中文K线标注设置 ---";
input bool EnableChineseLabels = true; // 启用中文K线标注
// vvvvvvvvvv这里是您要求的修改vvvvvvvvvv
input stringUpContinueText = "续涨"; // 上涨继续文字
input color UpContinueColor = clrLimeGreen; // 上涨文字颜色
input stringDownContinueText = "续跌"; // 下跌继续文字
// ^^^^^^^^^^这里是您要求的修改^^^^^^^^^^
input color DownContinueColor = clrRed; // 下跌文字颜色
input int LabelDistance = 20; // 标签与K线的距离(点)
input int SignalCooldown = 10; // 信号冷却K线数 (N根内只显示一次)
// --- 原始输入参数 ---
input stringOriginalGroupName = "--- 原始指标参数 ---";
input int RSIOMA = 14; // RSIOMA 周期
input ENUM_MA_METHOD RSIOMA_MODE = MODE_EMA; // RSIOMA 模式
input ENUM_APPLIED_PRICE RSIOMA_PRICE = PRICE_CLOSE;// RSIOMA 应用价格
input int Ma_RSIOMA = 21; // MA of RSIOMA 周期
input ENUM_MA_METHOD Ma_RSIOMA_MODE = MODE_EMA; // MA of RSIOMA 模式
input int BuyTrigger = 20;
input int SellTrigger = 80;
input int MainTrendLong = 50;
input int MainTrendShort = 50;
input bool MainAlerts = false;
input bool AuxiliaryAlerts = false;
input bool EnableNativeAlerts = false;
input bool EnableEmailAlerts = false;
input bool EnablePushAlerts = false;
input bool EnableSoundAlerts = false;
input stringSoundFile = "alert.wav";
input ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT; // 时间周期
// Indicator buffers:
double RSIBuffer[];
double PosBuffer[];
double NegBuffer[];
double bdn[], bup[]; // bdn - Red(下跌), bup - Green(上涨)
double sdn[], sup[]; // sdn - Magenta(顶部预警), sup - DodgerBlue(底部预警)
double marsioma[];
// Global variables:
string short_name;
string obj_prefix; // 对象唯一前缀,用于清理
datetime LastAlertTime = D'01.01.1970';
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
SetIndexBuffer(0, RSIBuffer);
SetIndexBuffer(1, bdn);
SetIndexBuffer(2, bup);
SetIndexBuffer(3, sdn);
SetIndexBuffer(4, sup);
SetIndexBuffer(5, marsioma);
SetIndexBuffer(6, PosBuffer);
SetIndexBuffer(7, NegBuffer);
SetIndexDrawBegin(0, RSIOMA);
SetIndexDrawBegin(1, RSIOMA);
SetIndexDrawBegin(2, RSIOMA);
SetIndexDrawBegin(3, RSIOMA);
SetIndexDrawBegin(4, RSIOMA);
SetIndexDrawBegin(5, RSIOMA);
short_name = StringConcatenate("RSIOMA(", RSIOMA, ")");
IndicatorShortName(short_name);
IndicatorSetInteger(INDICATOR_DIGITS, 2);
// 创建唯一的对象前缀,防止不同图表/周期的对象冲突
obj_prefix = short_name + "_" + (string)ChartID() + "_";
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// 清理本指标实例创建的所有图表对象
ObjectsDeleteAll(0, obj_prefix);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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(Bars <= RSIOMA) return(0);
int limit;
if(prev_calculated == 0 || rates_total < prev_calculated)
{
limit = rates_total - RSIOMA - 2;
}
else
{
limit = rates_total - prev_calculated;
}
for(int i = limit; i >= 0; i--)
{
double sumn = 0.0, sump = 0.0;
double rel, negative, positive;
double ccma = iMA(Symbol(), TimeFrame, RSIOMA, 0, RSIOMA_MODE, RSIOMA_PRICE, i);
double ppma = iMA(Symbol(), TimeFrame, RSIOMA, 0, RSIOMA_MODE, RSIOMA_PRICE, i + 1);
rel = ccma - ppma;
if(rel > 0) sump = rel;
else sumn = -rel;
positive = (PosBuffer * (RSIOMA - 1) + sump) / RSIOMA;
negative = (NegBuffer * (RSIOMA - 1) + sumn) / RSIOMA;
PosBuffer = positive;
NegBuffer = negative;
bup = 0; bdn = 0; sdn = 0; sup = 0;
if(negative != 0.0)
{
RSIBuffer = 100.0 - 100.0 / (1.0 + positive / negative);
if(RSIBuffer > MainTrendLong) bup = -10;
if(RSIBuffer < MainTrendShort) bdn = -10;
if(RSIBuffer < BuyTrigger && RSIBuffer > RSIBuffer) sup = -10;
if(RSIBuffer > SellTrigger && RSIBuffer < RSIBuffer) sdn = -10;
}
else
{
RSIBuffer = 0.0;
}
}
for(int i = limit; i >= 0; i--)
{
marsioma = iMAOnArray(RSIBuffer, 0, Ma_RSIOMA, 0, Ma_RSIOMA_MODE, i);
}
// --- 中文标注和冷却逻辑 ---
if(EnableChineseLabels)
{
static int upCooldown = 0;
static int downCooldown = 0;
int check_limit = rates_total - prev_calculated;
if (prev_calculated == 0) check_limit = rates_total - 2;
for(int i = check_limit; i >= 1; i--)
{
// 每一根K线都减少冷却计数器
if(upCooldown > 0) upCooldown--;
if(downCooldown > 0) downCooldown--;
// 信号1: 上涨继续 (前一根洋红 -> 当前绿色) 并且冷却结束
if(sdn != 0 && bup != 0 && upCooldown == 0)
{
string obj_name = obj_prefix + "UpCont_" + (string)Time;
DrawLabel(obj_name, i, High + LabelDistance * _Point, UpContinueText, UpContinueColor, ANCHOR_LEFT);
// 重置冷却计数器
upCooldown = SignalCooldown;
}
// 信号2: 下跌继续 (前一根浅蓝 -> 当前红色) 并且冷却结束
if(sup != 0 && bdn != 0 && downCooldown == 0)
{
string obj_name = obj_prefix + "DownCont_" + (string)Time;
DrawLabel(obj_name, i, Low - LabelDistance * _Point, DownContinueText, DownContinueColor, ANCHOR_RIGHT);
// 重置冷却计数器
downCooldown = SignalCooldown;
}
}
}
// --- 原始警报逻辑 (保持不变) ---
if(Time > LastAlertTime)
{
int candle = 1; // 检查已收盘的K线
string Text;
if (MainAlerts)
{
if ((RSIBuffer < SellTrigger) && (RSIBuffer >= SellTrigger))
{
Text = "RSIOMA: " + Symbol() + " - " + StringSubstr(EnumToString((ENUM_TIMEFRAMES)Period()), 7) + " - Crossed " + IntegerToString(SellTrigger) + " from above.";
IssueAlerts(Text);
}
if ((RSIBuffer > BuyTrigger) && (RSIBuffer <= BuyTrigger))
{
Text = "RSIOMA: " + Symbol() + " - " + StringSubstr(EnumToString((ENUM_TIMEFRAMES)Period()), 7) + " - Crossed " + IntegerToString(BuyTrigger) + " from below.";
IssueAlerts(Text);
}
}
if (AuxiliaryAlerts)
{
if ((sdn != 0) && (sdn == 0))
{
Text = "RSIOMA: " + Symbol() + " - " + StringSubstr(EnumToString((ENUM_TIMEFRAMES)Period()), 7) + " - Bearish reversal imminent.";
IssueAlerts(Text);
}
if ((sup != 0) && (sup == 0))
{
Text = "RSIOMA: " + Symbol() + " - " + StringSubstr(EnumToString((ENUM_TIMEFRAMES)Period()), 7) + " - Bullish reversal imminent.";
IssueAlerts(Text);
}
}
}
return(rates_total);
}
//+------------------------------------------------------------------+
//| Helper functions |
//+------------------------------------------------------------------+
void IssueAlerts(string text)
{
if (EnableNativeAlerts) Alert(text);
if (EnableEmailAlerts) SendMail("RSIOMA Alert", text);
if (EnablePushAlerts) SendNotification(text);
if (EnableSoundAlerts) PlaySound(SoundFile);
LastAlertTime = Time;
}
void DrawLabel(string obj_name, int bar, double price, string text, color clr, ENUM_ANCHOR_POINT anchor)
{
if(ObjectFind(0, obj_name) < 0)
{
ObjectCreate(0, obj_name, OBJ_TEXT, 0, Time, price);
ObjectSetString(0, obj_name, OBJPROP_TEXT, text);
ObjectSetInteger(0, obj_name, OBJPROP_COLOR, clr);
ObjectSetInteger(0, obj_name, OBJPROP_FONTSIZE, 10);
ObjectSetString(0, obj_name, OBJPROP_FONT, "Arial");
ObjectSetInteger(0, obj_name, OBJPROP_ANCHOR, anchor);
ObjectSetInteger(0, obj_name, OBJPROP_SELECTABLE, false);
}
}
//+------------------------------------------------------------------+
页:
[1]