外汇交易策略代码解析:魔术码、止损止盈和补仓策略
以下代码展示了一个外汇交易策略,使用魔术码管理订单,并包含止损止盈和补仓策略。
extern int MagicNumber = 92133; // 魔术码
extern double InitialLotSize = 0.5; // 初始手数
extern int Gap = 100; // 间距
extern double AddLotMultiplier = 0.6; // 补仓倍数
extern int MaxAddLotCount = 5; // 补仓次数
extern double ProfitTarget = 40; // 盈利目标(美金)
extern int Slippage = 3; // 滑点值
void OnTick()
{
double latestPrice = MarketInfo(Symbol(), MODE_BID); // 获取最新价格
int totalOrders = OrdersTotal(); // 获取订单总数
// 检查当前魔术码是否持仓
bool hasPosition = false;
for (int i = 0; i < totalOrders; i++)
{
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber)
{
hasPosition = true;
break;
}
}
// 如果没有持仓
if (!hasPosition)
{
double entryPrice = latestPrice;
double lotSize = InitialLotSize;
// 根据最新价格加100点挂单一次多单
double buyStopPrice = entryPrice + Gap;
int buyStopOrderTicket = OrderSend(Symbol(), OP_BUYSTOP, lotSize, buyStopPrice, 0, 0, 0, 'Buy Stop', MagicNumber, 0, Blue);
// 根据最新价格减100点挂单一次空单
double sellStopPrice = entryPrice - Gap;
int sellStopOrderTicket = OrderSend(Symbol(), OP_SELLSTOP, lotSize, sellStopPrice, 0, 0, 0, 'Sell Stop', MagicNumber, 0, Red);
// 设置挂单的止损和止盈
if (buyStopOrderTicket > -1)
{
if (!OrderModify(buyStopOrderTicket, OrderOpenPrice(), NormalizeDouble(entryPrice - Gap * 2, Digits), OrderTakeProfit(), 0, Green))
{
Print('Failed to modify buy stop order: ', GetLastError());
}
}
if (sellStopOrderTicket > -1)
{
if (!OrderModify(sellStopOrderTicket, OrderOpenPrice(), NormalizeDouble(entryPrice + Gap * 2, Digits), OrderTakeProfit(), 0, Green))
{
Print('Failed to modify sell stop order: ', GetLastError());
}
}
}
else // 如果持仓
{
double firstOrderProfitTarget = 0;
for (int j = 0; j < totalOrders; j++)
{
if (OrderSelect(j, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MagicNumber)
{
double orderProfit = OrderProfit();
// 判断当前魔术码下的所有持仓订单
if (orderProfit >= ProfitTarget)
{
if (!OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, Red))
{
Print('Failed to close order: ', GetLastError());
}
}
else
{
if (j == 0) // 第一单
{
firstOrderProfitTarget = orderProfit;
// 如果持仓多单,最新价小于第一单多单100点时,以初始手数0.5手做空
if (OrderType() == OP_BUY && latestPrice < OrderOpenPrice() - Gap)
{
if (!OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, Red))
{
Print('Failed to close initial buy order: ', GetLastError());
}
int shortOrderTicket = OrderSend(Symbol(), OP_SELL, InitialLotSize, 0, 0, 0, 0, 'Initial Short', MagicNumber, 0, Red);
if (shortOrderTicket < 0)
{
Print('Failed to open initial short order: ', GetLastError());
}
}
// 如果持仓空单,最新价大于第一单空单100点时,以初始手数0.5手做多
if (OrderType() == OP_SELL && latestPrice > OrderOpenPrice() + Gap)
{
if (!OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, Red))
{
Print('Failed to close initial sell order: ', GetLastError());
}
int longOrderTicket = OrderSend(Symbol(), OP_BUY, InitialLotSize, 0, 0, 0, 0, 'Initial Long', MagicNumber, 0, Blue);
if (longOrderTicket < 0)
{
Print('Failed to open initial long order: ', GetLastError());
}
}
}
else // 非第一单
{
int addLotCount = MathFloor(orderProfit / Gap); // 补仓次数计数
if (OrderType() == OP_BUY) // 多单
{
for (int k = 1; k <= addLotCount && k <= MaxAddLotCount; k++)
{
double addLotSize = InitialLotSize * MathPow(AddLotMultiplier, k);
double addLotEntryPrice = firstOrderProfitTarget + Gap * k;
int buyOrderTicket = OrderSend(Symbol(), OP_BUY, addLotSize, addLotEntryPrice, 0, 0, 0, 'Buy Add', MagicNumber, 0, Blue);
if (buyOrderTicket < 0)
{
Print('Failed to open buy add order: ', GetLastError());
}
}
}
else if (OrderType() == OP_SELL) // 空单
{
for (int k = 1; k <= addLotCount && k <= MaxAddLotCount; k++)
{
double addLotSize = InitialLotSize * MathPow(AddLotMultiplier, k);
double addLotEntryPrice = firstOrderProfitTarget - Gap * k;
int sellOrderTicket = OrderSend(Symbol(), OP_SELL, addLotSize, addLotEntryPrice, 0, 0, 0, 'Sell Add', MagicNumber, 0, Red);
if (sellOrderTicket < 0)
{
Print('Failed to open sell add order: ', GetLastError());
}
}
}
}
}
}
}
}
}
代码解析
- 魔术码:
MagicNumber用于识别和管理由同一策略生成的订单。在代码中,它被用来区分不同策略的订单。 - 初始手数:
InitialLotSize定义了初始订单的手数,在本例中为 0.5 手。 - 间距:
Gap定义了挂单价格与最新价格之间的点差,在本例中为 100 点。 - 补仓倍数:
AddLotMultiplier定义了每次补仓的倍数,在本例中为 0.6 倍。 - 补仓次数:
MaxAddLotCount定义了最大补仓次数,在本例中为 5 次。 - 盈利目标:
ProfitTarget定义了订单盈利的目标,在本例中为 40 美金。 - 滑点值:
Slippage定义了允许的滑点,在本例中为 3 点。
交易逻辑
该交易策略主要包含以下逻辑:
- 判断是否持仓: 首先,代码会检查当前魔术码是否持仓。如果未持仓,则进行挂单操作;如果已持仓,则进行平仓或补仓操作。
- 挂单操作: 如果没有持仓,代码会根据最新价格计算挂单价格,并分别发送买入止损和卖出止损订单。同时,代码还会设置挂单的止损和止盈。
- 平仓操作: 如果持仓,代码会遍历所有持仓订单,并检查每个订单的盈利情况。如果订单的盈利达到盈利目标,则进行平仓操作。
- 补仓操作: 如果持仓,代码会判断是否需要补仓。补仓的条件是当前订单的盈利超过了
Gap的倍数,并且补仓次数没有超过MaxAddLotCount。代码会根据补仓倍数计算补仓的手数和价格,并发送补仓订单。
代码说明
该代码只是一个示例,实际应用中需要根据具体的交易策略进行调整和完善。
注意: 以下内容需要根据具体的交易平台和语言进行修改。
MarketInfo(Symbol(), MODE_BID): 获取当前交易品种的最新卖出报价。OrdersTotal(): 获取当前所有订单的数量。OrderSelect(i, SELECT_BY_POS, MODE_TRADES): 选择第 i 个交易订单。OrderMagicNumber(): 获取订单的魔术码。OrderSend(Symbol(), OP_BUYSTOP, lotSize, buyStopPrice, 0, 0, 0, 'Buy Stop', MagicNumber, 0, Blue): 发送买入止损挂单。OrderModify(buyStopOrderTicket, OrderOpenPrice(), NormalizeDouble(entryPrice - Gap * 2, Digits), OrderTakeProfit(), 0, Green): 修改止损订单。OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, Red): 平仓订单。OrderProfit(): 获取订单的盈利。OrderType(): 获取订单的类型(买入或卖出)。OrderOpenPrice(): 获取订单的开仓价格。OrderLots(): 获取订单的手数。Bid: 获取当前的买入报价。Ask: 获取当前的卖出报价。MathFloor(orderProfit / Gap): 计算补仓次数。MathPow(AddLotMultiplier, k): 计算补仓倍数。NormalizeDouble(entryPrice - Gap * 2, Digits): 将止损价格格式化。Print('Failed to modify buy stop order: ', GetLastError()): 打印错误信息。
免责声明: 本文提供的代码仅供参考,不构成任何投资建议。任何交易行为都需要根据自身情况进行谨慎判断。
原文地址: http://www.cveoy.top/t/topic/chMH 著作权归作者所有。请勿转载和采集!