Shooting HDU - 4866 主席树+思维

本文探讨了射击游戏中玩家如何选择最优射击位置以获取最大奖励点数的问题,通过使用主席树和离散化技巧,实现了高效的算法解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

In the shooting game, the player can choose to stand in the position of [1, X] to shoot, you can shoot all the nearest K targets. The value of K may be different on different shootings. There are N targets to shoot, each target occupy the position of [Li, Ri] , the distance from the starting line is Di(1<=i<=N). Shooting a target can get the bonus points equal to the distance to the starting line. After each shooting targets still exist. Additional, if the previous bonus points is more than P, then as a reward for the shooting present bonus points doubled(and then check the next one). Player wants to know the bonus points he got in each shot. 

Input

The input consists several test cases. 
The first line has two integers, N, M, X, P(1<=N, M ,X<=100000, P<=1000000000), N represents the total number of target shooting, M represents the number of shooting.
The next N lines of three integers L, R, D (1<=L<=R<=X, 1<=D<=10000000), occupy the position of [L, R] and the distance from the starting line is D. 
The next M lines, each line contains four integers x, a, b, c (1<=x<=X, 0<=a,b<=N, 1<=c<=10000000), and K = ( a * Pre + b ) % c. Pre is the bonus point of previous shooting , and for the first shooting Pre=1. It denotes standing in the position x and the player can shoot the nearest K targets.

Output

Output M lines each corresponds to one integer.

Sample Input

4 3 5 8
1 2 6
2 3 3
2 4 7
1 5 2
2 2 1 5
3 1 1 10
4 2 3 7

Sample Output

11
10
18

题意:给你n,m,X,p。n表示有n个线段,m表示有m次询问。接下来n行,每行有3个数l,r,d,表示线段的左端点右端点以及线段的高度。接下来m行,每行4个数x,a,b,c,k=(lastans*a+b)%c,表示你从x这个点向上开枪,能击穿k条线段,每击穿一条线段,你获得的价值为该线段的高度。如果该点上面的线段小于k,其上线段条数为x,那么获得的总价值为x条线段的价值加上x上面最高的线段的高度*(k-x)。并且,如果lastans>p,那么本次开枪获得的价值讲翻倍。输出每次开枪的获得的价值。

思路:能击穿的k条线段,一定是x向上的前k高的线段,这时我们很容易想到主席树求区间前k小的值,很容易联想到主席树。那么主席树就维护高度,由于高度最大是1e7,因此我们需要进行离散化。那么我们怎么向主席树里插入这些线段呢?我们可以将一个线段拆成2个点:l和r+1,类似于差分的思想,在l处+1,在r+1处-1,按位置从小到大排序,依次插入到主席树中。我们再记录一个cnt,表示现在主席树中有几条线段,二分找前k个即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+100;
int n,m,X,l,r,d,cnt,cont,ct,x,k;
int root[maxn],b[maxn];
ll p,pre,ans,A,B,C;
struct node{
	int pos;
	int d;
	int flag;
	friend bool operator < (node x,node y)
	{
		if(x.pos==y.pos) return x.d<y.d;
		else return x.pos<y.pos;
	}
}a[maxn<<1];
struct Node{
	int l;
	int r;
	ll sum;
	int cnt;
}tree[maxn*40];
int getid(int x)
{
	return lower_bound(b+1,b+1+cont,x)-b;
}
void build(int &cur,int l,int r)
{
	cur=++ct;
	tree[cur].sum=0;
	tree[cur].cnt=0;
	if(l==r) return ;
	int m=(l+r)>>1;
	build(tree[cur].l,l,m);
	build(tree[cur].r,m+1,r);
}
void update(int &now,int last,int tar,int flag,ll val,int l,int r)
{
	now=++ct;
	tree[now]=tree[last];
	tree[now].sum+=flag*val;
	tree[now].cnt+=flag;
	if(l==r) return ;
	int m=(l+r)>>1;
	if(tar<=m) update(tree[now].l,tree[last].l,tar,flag,val,l,m);
	else update(tree[now].r,tree[last].r,tar,flag,val,m+1,r);
}
ll query(int cur,int k,int l,int r)
{
	if(tree[cur].cnt<=k) return tree[cur].sum;
	if(l==r) return (ll)(tree[cur].sum/tree[cur].cnt)*k;
	int m=(l+r)>>1;
	if(tree[tree[cur].l].cnt>=k) return query(tree[cur].l,k,l,m);
	else return tree[tree[cur].l].sum+query(tree[cur].r,k-tree[tree[cur].l].cnt,m+1,r); 
}
int main()
{
	while(~scanf("%d%d%d%lld",&n,&m,&X,&p))
	{
		cnt=0;pre=1;ct=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d%d",&l,&r,&d);
			a[++cnt].pos=l;
			a[cnt].d=d;
			a[cnt].flag=1;
			a[++cnt].pos=r+1;
			a[cnt].d=d;
			a[cnt].flag=-1;
			b[i]=d;
		}
		sort(b+1,b+1+n);
		sort(a+1,a+1+cnt);
		cont=unique(b+1,b+1+n)-(b+1);
		build(root[0],1,cont);
		for(int i=1;i<=cnt;i++) update(root[i],root[i-1],getid(a[i].d),a[i].flag,a[i].d,1,cont);
		while(m--)
		{
			scanf("%d%lld%lld%lld",&x,&A,&B,&C);
			k=((A*pre)%C+B)%C;
			node tmp;
			tmp.pos=x;tmp.flag=0;tmp.d=0x3fffffff;
			int id=upper_bound(a+1,a+1+cnt,tmp)-a-1;
			if(id<=0) ans=0;
			else ans=query(root[id],k,1,cont);
			if(pre>p) ans*=2;
			printf("%lld\n",ans);
			pre=ans;
		}
	}
	return 0;
}

 

 

 

 

 

 

 

//+------------------------------------------------------------------+ //| MACD_Quantitative_EA.mq4 | //| Copyright 2025, Expert Advisor Developer | //| https://yourwebsite.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, Your Name" #property link "https://yourwebsite.com/" #property version "1.00" #property strict // 输入参数 input int FastEMA = 12; // 快速EMA周期 input int SlowEMA = 26; // 慢速EMA周期 input int SignalSMA = 9; // 信号线周期 input double LotSize = 0.1; // 固定交易手数 input int StopLoss = 100; // 止损点数 input int TakeProfit = 200; // 止盈点数 input int TrailingStart = 50; // 启动跟踪止损的盈利点数 input int TrailingStop = 30; // 跟踪止损点数 input bool UseTrailingStop = true; // 是否启用跟踪止损 input bool UseMACDAreaSignal = true; // 是否启用MACD面积缩小信号 input bool UseMACDAreaClose = true; // 是否启用MACD面积扩大平仓 input double MinMACDArea = 0.0001; // MACD最小有效面积 input int AreaLookback = 5; // 面积回溯周期 input int MaxTrendBars = 8; // 趋势末端最大连续上涨/下跌根数 input int DivergenceLookback = 20; // 背离检测周期 input int CrossAngleLookback = 3; // MACD交叉角度检测周期 input double DistanceThreshold = 0.0002; // MACD线与信号线最小距离 input int AccelerationLookback = 5; // 加速度计算周期 // 全局变量 int ticket = 0; //+------------------------------------------------------------------+ //| 初始化函数 | //+------------------------------------------------------------------+ int OnInit() { Print("MACD量化交易EA已加载"); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 主函数 OnTick | //+------------------------------------------------------------------+ void OnTick() { if (OrdersTotal() > 0) { if (UseMACDAreaClose) CheckMACDAreaClose(); // 检查MACD面积是否扩大,决定是否平仓 ManageTrailingStop(); // 管理跟踪止损 } if (OrdersTotal() == 0) { int signal = 0; // 1. 基础金叉/死叉 signal = GetMACDSignal(); if (signal == 0 && UseMACDAreaSignal) signal = GetMACDAreaSignal(); // 如果没有金叉/死叉,再判断面积缩小信号 if (signal == 0) signal = GetMACDTrendSignal(); // 最后判断趋势延续信号 if (signal == 0) signal = DetectMACDTopBottom(); // 判断顶部/底部信号 if (signal == 0) signal = DetectMACDCombinedDivergence(); // 加入背离信号 if (signal == 0) signal = IsMACDPeakOrValley(); // 加入柱形态信号 if (signal == 0) signal = IsMACDHistogramCrossZero(); // 新增:柱零轴穿越 if (signal == 0) signal = GetMACDSignalWithZeroZone(); // 新增:判断金叉是否在0轴上方 if (signal == 0) signal = CheckMACDHistogramReacceleration(); // 新增:二次放大信号 if (signal == 0) signal = DetectMACDTrendAcceleration(); // 新增:线斜率变化 if (signal == 1) OpenBuyOrder(); // 做多 else if (signal == -1) OpenSellOrder(); // 做空 } } //+------------------------------------------------------------------+ //| 获取MACD金叉/死叉信号 | //+------------------------------------------------------------------+ int GetMACDSignal() { double macdMain = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 0, 0); double macdSignal = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 1, 0); double macdPrevMain = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 0, 1); double macdPrevSignal = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 1, 1); // 金叉:当前MACD线上穿信号线 if (macdPrevMain < macdPrevSignal && macdMain > macdSignal) { if (IsMACDCrossWithSteepAngle() && GetMACDLineDistanceFromSignal() > DistanceThreshold) return 1; } // 死叉:当前MACD线下穿信号线 if (macdPrevMain > macdPrevSignal && macdMain < macdSignal) { if (IsMACDCrossWithSteepAngle() && GetMACDLineDistanceFromSignal() > DistanceThreshold) return -1; } return 0; } //+------------------------------------------------------------------+ //| 获取MACD面积缩小信号(优化版:连续5根K线) | //+------------------------------------------------------------------+ int GetMACDAreaSignal() { double hist[5] = {0, 0, 0, 0, 0}; // 显式初始化 for (int i = 0; i < 5; i++) { hist[i] = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 2, i); } // 做多信号:负柱状图连续缩小(下跌动能减弱) bool shrinkingNegative = true; for (int i = 0; i < 4; i++) { if (MathAbs(hist[i]) >= MathAbs(hist[i + 1])) { shrinkingNegative = false; break; } } if (shrinkingNegative && hist[0] < 0 && hist[1] < 0 && hist[2] < 0 && hist[3] < 0 && hist[4] < 0) return 1; // 做空信号:正柱状图连续缩小(上涨动能减弱) bool shrinkingPositive = true; for (int i = 0; i < 4; i++) { if (hist[i] <= hist[i + 1]) { shrinkingPositive = false; break; } } if (shrinkingPositive && hist[0] > 0 && hist[1] > 0 && hist[2] > 0 && hist[3] > 0 && hist[4] > 0) return -1; return 0; // 无信号 } //+------------------------------------------------------------------+ //| 获取MACD趋势信号(在0轴上方未跌破则继续做多,反之做空) | //+------------------------------------------------------------------+ int GetMACDTrendSignal() { double hist[5] = {0, 0, 0, 0, 0}; // 显式初始化 for (int i = 0; i < 5; i++) { hist[i] = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 2, i); } // 多头趋势:所有MACD柱都在0轴上方,且未跌破 bool allAboveZero = true; for (int i = 0; i < 5; i++) { if (hist[i] <= 0) { allAboveZero = false; break; } } if (allAboveZero) return 1; // 空头趋势:所有MACD柱都在0轴下方,且未上穿 bool allBelowZero = true; for (int i = 0; i < 5; i++) { if (hist[i] >= 0) { allBelowZero = false; break; } } if (allBelowZero) return -1; return 0; // 无趋势信号 } //+------------------------------------------------------------------+ //| 判断MACD是否出现顶部/底部形态(连续上涨/下跌后反转) | //+------------------------------------------------------------------+ int DetectMACDTopBottom() { int trendBars = CountMACDBarTrend(); double currentHist = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 2, 0); double prevHist = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 2, 1); // 顶部:连续上涨超过阈值,且当前柱反转 if (currentHist > 0 && prevHist > 0 && currentHist < prevHist && trendBars >= MaxTrendBars) return -1; // 底部:连续下跌超过阈值,且当前柱反转 if (currentHist < 0 && prevHist < 0 && currentHist > prevHist && trendBars >= MaxTrendBars) return 1; return 0; } //+------------------------------------------------------------------+ //| 检测MACD面积与价格背离 | //+------------------------------------------------------------------+ int DetectMACDAreaDivergence() { double priceHigh = iHigh(NULL, 0, iHighest(NULL, 0, MODE_HIGH, DivergenceLookback, 0)); double priceLow = iLow(NULL, 0, iLowest(NULL, 0, MODE_LOW, DivergenceLookback, 0)); double areaHigh = CalculateMACDArea(DivergenceLookback); double areaLow = CalculateMACDArea(DivergenceLookback); // 顶部背离:价格创新高,但MACD面积未创新高 if (Bid > priceHigh && areaHigh < CalculateMACDArea(DivergenceLookback - 5)) return -1; // 底部背离:价格创新低,但MACD面积未创新低 if (Ask < priceLow && areaLow > CalculateMACDArea(DivergenceLookback - 5)) return 1; return 0; } //+------------------------------------------------------------------+ //| 检测MACD柱连续上涨/下跌与价格背离 | //+------------------------------------------------------------------+ int DetectMACDBarDivergence() { double priceHigh = iHigh(NULL, 0, iHighest(NULL, 0, MODE_HIGH, DivergenceLookback, 0)); double priceLow = iLow(NULL, 0, iLowest(NULL, 0, MODE_LOW, DivergenceLookback, 0)); int trendBars = CountMACDBarTrend(); // 顶部背离:价格创新高,但MACD连续上涨根数未创新高 if (Bid > priceHigh && trendBars < DivergenceLookback - 3) return -1; // 底部背离:价格创新低,但MACD连续下跌根数未创新低 if (Ask < priceLow && trendBars < DivergenceLookback - 3) return 1; return 0; } //+------------------------------------------------------------------+ //| 检测MACD面积和根数双重背离(最强信号) | //+------------------------------------------------------------------+ int DetectMACDCombinedDivergence() { int areaSignal = DetectMACDAreaDivergence(); int barSignal = DetectMACDBarDivergence(); if (areaSignal == -1 && barSignal == -1) return -1; // 双重顶部背离 if (areaSignal == 1 && barSignal == 1) return 1; // 双重底部背离 return 0; } //+------------------------------------------------------------------+ //| 检测MACD柱是否出现“山峰”或“谷底”形态(动能衰竭) | //+------------------------------------------------------------------+ int IsMACDPeakOrValley(int lookback = 5) { double hist[5] = {0, 0, 0, 0, 0}; // 显式初始化 for (int i = 0; i < 5; i++) hist[i] = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 2, i); // 山峰形态(中间最高) if (hist[1] < hist[2] && hist[2] > hist[3] && hist[0] < hist[2]) return 1; // 谷底形态(中间最低) if (hist[1] > hist[2] && hist[2] < hist[3] && hist[0] > hist[2]) return -1; return 0; } //+------------------------------------------------------------------+ //| 判断MACD线与信号线交叉是否角度陡峭 | //+------------------------------------------------------------------+ bool IsMACDCrossWithSteepAngle(int lookback = 3) { double angle = 0; for (int i = 0; i < lookback - 1; i++) { double currentMain = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 0, i); double currentSignal = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 1, i); double nextMain = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 0, i + 1); double nextSignal = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 1, i + 1); angle += MathAbs(currentMain - currentSignal) - MathAbs(nextMain - nextSignal); } return MathAbs(angle) > 0.0001; } //+------------------------------------------------------------------+ //| 计算MACD线与信号线之间的平均距离(用于衡量趋势强度) | //+------------------------------------------------------------------+ double GetMACDLineDistanceFromSignal(int lookback = 5) { double sum = 0; for (int i = 0; i < lookback; i++) { double macd = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 0, i); double signal = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 1, i); sum += MathAbs(macd - signal); } return sum / lookback; } //+------------------------------------------------------------------+ //| 判断MACD线是否刚刚穿越 0 轴(趋势强度信号) | //+------------------------------------------------------------------+ int IsMACDLineCrossZero() { double macdMain0 = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 0, 0); double macdMain1 = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 0, 1); if (macdMain1 < 0 && macdMain0 > 0) return 1; // 从下向上穿越 if (macdMain1 > 0 && macdMain0 < 0) return -1; // 从上向下穿越 return 0; } //+------------------------------------------------------------------+ //| 判断MACD柱是否刚刚穿越零轴(趋势延续信号) | //+------------------------------------------------------------------+ int IsMACDHistogramCrossZero() { double hist0 = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 2, 0); double hist1 = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 2, 1); if (hist1 < 0 && hist0 > 0) return 1; // 从下向上穿越 if (hist1 > 0 && hist0 < 0) return -1; // 从上向下穿越 return 0; } //+------------------------------------------------------------------+ //| 判断金叉是否发生在0轴上方/下方(增强信号强度) | //+------------------------------------------------------------------+ int GetMACDSignalWithZeroZone() { double macdMain = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 0, 0); double macdSignal = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 1, 0); double macdPrevMain = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 0, 1); double macdPrevSignal = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 1, 1); if (macdPrevMain < macdPrevSignal && macdMain > macdSignal) { if (macdMain > 0) return 1; // 在0轴上方金叉,强度更高 else return 0; // 在0轴下方金叉,不采用 } if (macdPrevMain > macdPrevSignal && macdMain < macdSignal) { if (macdMain < 0) return -1; // 在0轴下方死叉,强度更高 else return 0; // 在0轴上方死叉,不采用 } return 0; } //+------------------------------------------------------------------+ //| 检测MACD线斜率变化(判断趋势是否加速/减速) | //+------------------------------------------------------------------+ int DetectMACDTrendAcceleration() { double slope = 0; for (int i = 0; i < 3; i++) { double current = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 0, i); double next = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 0, i + 1); slope += (next - current); } if (slope > 0) return 1; // 加速上涨 if (slope < 0) return -1; // 加速下跌 return 0; } //+------------------------------------------------------------------+ //| 检测MACD柱的“二次放大”信号 | //+------------------------------------------------------------------+ int CheckMACDHistogramReacceleration() { double hist[5] = {0, 0, 0, 0, 0}; for (int i = 0; i < 5; i++) hist[i] = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 2, i); // 判断是否先缩小后放大(二次加速) if (hist[0] < hist[1] && hist[1] > hist[2] && hist[2] < hist[3] && hist[3] < hist[4]) return 1; // 多头二次加速 if (hist[0] > hist[1] && hist[1] < hist[2] && hist[2] > hist[3] && hist[3] > hist[4]) return -1; // 空头二次加速 return 0; } //+------------------------------------------------------------------+ //| 检查MACD面积是否缩小(用于平仓) | //+------------------------------------------------------------------+ void CheckMACDAreaClose() { for (int i = 0; i < OrdersTotal(); i++) { if (!OrderSelect(i, SELECT_BY_POS)) continue; if (OrderSymbol() != Symbol()) continue; double currentArea = CalculateMACDArea(AreaLookback); if (currentArea == 0) continue; int type = OrderType(); if (type == OP_BUY) { // 多单:MACD面积缩小 + 持续下降趋势 if (MathAbs(currentArea) < MinMACDArea || IsMACDAreaShrinking(AreaLookback)) { if (!OrderClose(OrderTicket(), OrderLots(), Bid, 3, clrRed)) Print("平仓失败,错误码: ", GetLastError()); else Print("【MACD面积衰减】多单平仓 @ ", DoubleToStr(Bid, Digits)); } } if (type == OP_SELL) { // 空单:MACD面积缩小 + 持续下降趋势 if (MathAbs(currentArea) < MinMACDArea || IsMACDAreaShrinking(AreaLookback)) { if (!OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrRed)) Print("平仓失败,错误码: ", GetLastError()); else Print("【MACD面积衰减】空单平仓 @ ", DoubleToStr(Ask, Digits)); } } } } //+------------------------------------------------------------------+ //| 开多单 | //+------------------------------------------------------------------+ void OpenBuyOrder() { double sl = Ask - StopLoss * Point; double tp = Ask + TakeProfit * Point; ticket = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, sl, tp, "MACD Buy", 0, 0, clrGreen); if (ticket < 0) Print("多单开仓失败,错误码: ", GetLastError()); else Print("【多单开仓】价格: ", DoubleToStr(Ask, Digits), " 止损: ", DoubleToStr(sl, Digits), " 止盈: ", DoubleToStr(tp, Digits)); } //+------------------------------------------------------------------+ //| 开空单 | //+------------------------------------------------------------------+ void OpenSellOrder() { double sl = Bid + StopLoss * Point; double tp = Bid - TakeProfit * Point; ticket = OrderSend(Symbol(), OP_SELL, LotSize, Bid, 3, sl, tp, "MACD Sell", 0, 0, clrRed); if (ticket < 0) Print("空单开仓失败,错误码: ", GetLastError()); else Print("【空单开仓】价格: ", DoubleToStr(Bid, Digits), " 止损: ", DoubleToStr(sl, Digits), " 止盈: ", DoubleToStr(tp, Digits)); } //+------------------------------------------------------------------+ //| 管理跟踪止损 | //+------------------------------------------------------------------+ void ManageTrailingStop() { for (int i = 0; i < OrdersTotal(); i++) { if (!OrderSelect(i, SELECT_BY_POS)) continue; if (OrderSymbol() != Symbol()) continue; double openPrice = OrderOpenPrice(); double currentPrice = (OrderType() == OP_BUY) ? Bid : Ask; double profitPoints = (OrderType() == OP_BUY) ? (currentPrice - openPrice) / Point : (openPrice - currentPrice) / Point; if (UseTrailingStop && profitPoints >= TrailingStart) { double newStopLoss = 0; if (OrderType() == OP_BUY) newStopLoss = currentPrice - TrailingStop * Point; else newStopLoss = currentPrice + TrailingStop * Point; if (newStopLoss != OrderStopLoss()) { if (!OrderModify(OrderTicket(), openPrice, newStopLoss, OrderTakeProfit(), 0, clrGreen)) Print("跟踪止损更新失败,错误码: ", GetLastError()); else Print("【跟踪止损更新】新止损: ", DoubleToStr(newStopLoss, Digits)); } } } } //+------------------------------------------------------------------+ //| 计算MACD面积(Histogram的累计值) | //+------------------------------------------------------------------+ double CalculateMACDArea(int bars = 5) { double area = 0; for (int i = 0; i < bars; i++) { double hist = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 2, i); area += hist; } return area; } //+------------------------------------------------------------------+ //| 判断MACD面积是否连续缩小(用于趋势衰减判断) | //+------------------------------------------------------------------+ bool IsMACDAreaShrinking(int bars = 5) { double areas[]; ArrayResize(areas, bars); for (int i = 0; i < bars; i++) { areas[i] = 0; for (int j = 0; j <= i; j++) { double hist = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 2, j); areas[i] += hist; } } // 多头:面积持续缩小(正值减少) if (areas[0] > 0) { for (int i = 0; i < bars - 1; i++) if (MathAbs(areas[i]) <= MathAbs(areas[i + 1])) return false; return true; } // 空头:面积持续缩小(负值减少) else if (areas[0] < 0) { for (int i = 0; i < bars - 1; i++) if (MathAbs(areas[i]) <= MathAbs(areas[i + 1])) return false; return true; } return false; } //+------------------------------------------------------------------+ //| 判断MACD柱状图连续上涨/下跌的根数 | //+------------------------------------------------------------------+ int CountMACDBarTrend(int maxBars = 20) { int count = 0; double prevHist = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 2, 0); for (int i = 1; i < maxBars; i++) { double currentHist = iMACD(NULL, 0, FastEMA, SlowEMA, SignalSMA, PRICE_CLOSE, 2, i); if ((prevHist > 0 && currentHist > prevHist) || (prevHist < 0 && currentHist < prevHist)) { count++; prevHist = currentHist; } else break; } return count; } 帮我加K线形态
最新发布
07-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值