feat: 修复止盈价计算逻辑
This commit is contained in:
@@ -742,12 +742,47 @@ bool OpenPosition(ENUM_ORDER_TYPE order_type, double wave_high, double wave_low,
|
|||||||
if(lots <= 0)
|
if(lots <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
double current_price = (order_type == ORDER_TYPE_BUY) ?
|
// 生成包含有效波段信息的注释
|
||||||
SymbolInfoDouble(_Symbol, SYMBOL_ASK) :
|
string comment = StringFormat("%s H%.0f L%.0f T%.0f",
|
||||||
SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
(order_type == ORDER_TYPE_BUY ? "B" : "S"),
|
||||||
|
wave_high,
|
||||||
|
wave_low,
|
||||||
|
threshold_points);
|
||||||
|
|
||||||
// 计算止损和止盈(基于开仓价的百分比)
|
bool result = false;
|
||||||
double stop_loss_amount = current_price * InpStopLossPercent / 100.0;
|
|
||||||
|
// 先以市价开仓(不带SL/TP),成交后再根据实际成交价设置SL/TP
|
||||||
|
if(order_type == ORDER_TYPE_BUY) {
|
||||||
|
result = trade.Buy(lots, _Symbol, 0, 0, 0, comment);
|
||||||
|
} else {
|
||||||
|
result = trade.Sell(lots, _Symbol, 0, 0, 0, comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!result) {
|
||||||
|
Print("开仓失败: ", trade.ResultRetcode(), " - ", trade.ResultRetcodeDescription());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取刚刚开仓的订单ticket
|
||||||
|
ulong ticket = trade.ResultOrder();
|
||||||
|
if(ticket == 0) {
|
||||||
|
ticket = trade.ResultDeal();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等待持仓信息更新
|
||||||
|
Sleep(100);
|
||||||
|
|
||||||
|
// 选择该持仓
|
||||||
|
if(!PositionSelectByTicket(ticket)) {
|
||||||
|
Print("无法选择持仓 ticket:", ticket);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取实际成交价
|
||||||
|
double open_price = PositionGetDouble(POSITION_PRICE_OPEN);
|
||||||
|
|
||||||
|
// 基于实际成交价计算止损金额
|
||||||
|
double stop_loss_amount = open_price * InpStopLossPercent / 100.0;
|
||||||
|
|
||||||
// 确保止损金额不小于最小止损点数
|
// 确保止损金额不小于最小止损点数
|
||||||
double min_stop_loss = InpMinStopLossPoints * _Point;
|
double min_stop_loss = InpMinStopLossPoints * _Point;
|
||||||
@@ -756,50 +791,37 @@ bool OpenPosition(ENUM_ORDER_TYPE order_type, double wave_high, double wave_low,
|
|||||||
}
|
}
|
||||||
|
|
||||||
double sl = 0, tp = 0;
|
double sl = 0, tp = 0;
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
// 生成包含有效波段信息的注释
|
|
||||||
string comment = StringFormat("%s H%.0f L%.0f T%.0f",
|
|
||||||
(order_type == ORDER_TYPE_BUY ? "B" : "S"),
|
|
||||||
wave_high,
|
|
||||||
wave_low,
|
|
||||||
threshold_points);
|
|
||||||
|
|
||||||
if(order_type == ORDER_TYPE_BUY) {
|
if(order_type == ORDER_TYPE_BUY) {
|
||||||
// 先标准化止损价
|
// 先标准化止损价
|
||||||
sl = NormalizeDouble(current_price - stop_loss_amount, _Digits);
|
sl = NormalizeDouble(open_price - stop_loss_amount, _Digits);
|
||||||
// 根据标准化后的实际止损金额重新计算止盈金额,确保盈亏比准确
|
// 根据标准化后的实际止损金额重新计算止盈金额,确保盈亏比准确
|
||||||
double actual_sl_amount = current_price - sl;
|
double actual_sl_amount = open_price - sl;
|
||||||
double take_profit_amount = actual_sl_amount * InpRiskRewardRatio;
|
double take_profit_amount = actual_sl_amount * InpRiskRewardRatio;
|
||||||
tp = NormalizeDouble(current_price + take_profit_amount, _Digits);
|
tp = NormalizeDouble(open_price + take_profit_amount, _Digits);
|
||||||
|
|
||||||
result = trade.Buy(lots, _Symbol, 0, sl, tp, comment);
|
|
||||||
if(result) {
|
|
||||||
Print("开多单成功 - 手数:", lots,
|
|
||||||
" 波段:H:", wave_high, " L:", wave_low,
|
|
||||||
" 开仓价:", current_price,
|
|
||||||
" 止损:", sl, "(", InpStopLossPercent, "%)",
|
|
||||||
" 止盈:", tp, "(盈亏比", InpRiskRewardRatio, ")");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 先标准化止损价
|
// 先标准化止损价
|
||||||
sl = NormalizeDouble(current_price + stop_loss_amount, _Digits);
|
sl = NormalizeDouble(open_price + stop_loss_amount, _Digits);
|
||||||
// 根据标准化后的实际止损金额重新计算止盈金额,确保盈亏比准确
|
// 根据标准化后的实际止损金额重新计算止盈金额,确保盈亏比准确
|
||||||
double actual_sl_amount = sl - current_price;
|
double actual_sl_amount = sl - open_price;
|
||||||
double take_profit_amount = actual_sl_amount * InpRiskRewardRatio;
|
double take_profit_amount = actual_sl_amount * InpRiskRewardRatio;
|
||||||
tp = NormalizeDouble(current_price - take_profit_amount, _Digits);
|
tp = NormalizeDouble(open_price - take_profit_amount, _Digits);
|
||||||
|
|
||||||
result = trade.Sell(lots, _Symbol, 0, sl, tp, comment);
|
|
||||||
if(result) {
|
|
||||||
Print("开空单成功 - 手数:", lots,
|
|
||||||
" 波段:H:", wave_high, " L:", wave_low,
|
|
||||||
" 开仓价:", current_price,
|
|
||||||
" 止损:", sl, "(", InpStopLossPercent, "%)",
|
|
||||||
" 止盈:", tp, "(盈亏比", InpRiskRewardRatio, ")");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
// 修改持仓的SL/TP
|
||||||
|
if(!trade.PositionModify(ticket, sl, tp)) {
|
||||||
|
Print("修改SL/TP失败: ", trade.ResultRetcode(), " - ", trade.ResultRetcodeDescription());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Print(order_type == ORDER_TYPE_BUY ? "开多单成功" : "开空单成功",
|
||||||
|
" - 手数:", lots,
|
||||||
|
" 波段:H:", wave_high, " L:", wave_low,
|
||||||
|
" 实际成交价:", open_price,
|
||||||
|
" 止损:", sl, "(", InpStopLossPercent, "%)",
|
||||||
|
" 止盈:", tp, "(盈亏比", InpRiskRewardRatio, ")");
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
|
|||||||
Reference in New Issue
Block a user