Params
Numeric OffsetShort(10); // 高于基准价做空操作
Numeric OffsetLong(10); // 低于基准价做多操作
Numeric FirstLoss(10); // 第一次补仓亏损点数
Numeric SecondLoss(25); // 第二次补仓亏损点数
Numeric StopLoss1(25); // 止损点数亏损达到
Numeric ShortTakeProfit(25); // 空头止盈点数
Numeric LongTakeProfit(25); // 多头止盈点数
Vars
Bool IsNightSession(true);
Bool IsBasePriceSet(false);
Numeric lastTradeDate;
// 使用Natural修饰的序列变量来存储基准价
Natural Series<Numeric> basePrice(0, 20);
Numeric priceChange; // 价格变化量
// 用于存储报单索引
Global Array<Integer> sOrderId;
Global Array<Integer> sOrderId_1;
Global Array<Integer> sOrderId_2;
Global Array<Integer> bOrderId; //多头oid
Global Array<Integer> bOrderId1;
Global Array<Integer> bOrderId2;
Global Numeric value;
Global Numeric value1;
// 新增:记录多头和空头建仓次数
Global Numeric longEntryCount;
Global Numeric shortEntryCount;
Global Numeric con; //开仓开关
Global Numeric con1;
Global Numeric con2;
Events
OnInit()
{
IsNightSession = true;
lastTradeDate = TrueDate(0);
Commentary("策略初始化,初始日期: " + Text(lastTradeDate));
longEntryCount = 0;
shortEntryCount = 0;
con = 0;
con1 = 0;
con2 = 0;
}
OnOrder(OrderRef ord)
{
Print("oid" + Text(ord.status));
if(ord.status == Enum_Declared and ord.orderId == sOrderId[0]) //空头开仓正在报单锁定
{ con = 1; } Print("空头建仓oid" + Text(sOrderId[0]));
if(ord.status == Enum_Declared and ord.orderId == sOrderId_1[0]) //空头第一次补仓报单锁定
{ con1 = 1; } Print("空第一次补仓oid" + Text(sOrderId_1[0]));
if(ord.status == Enum_Declared and ord.orderId == sOrderId_2[0]) //空头第二次补仓报单锁定
{ con2 = 1; } Print("空第二次补仓oid" + Text(sOrderId_2[0]));
//---------------------------------------------------------------------------------------------------
if(ord.status == Enum_Declared and ord.orderId == bOrderId[0]) //多头开仓正在报单锁定
{ con = 1; } Print("多头建仓oid" + Text(bOrderId[0]));
if(ord.status == Enum_Declared and ord.orderId == bOrderId1[0]) //多头第一次补仓报单锁定
{ con1 = 1; } Print("多头建仓oid" + Text(bOrderId1[0]));
if(ord.status == Enum_Declared and ord.orderId == bOrderId2[0]) //多头第二次补仓报单锁定
{ con2 = 1; } Print("多头建仓oid" + Text(bOrderId2[0]));
}
OnBar(ArrayRef<Integer> indexs)
{
Integer i;
For i = 0 To A_AccountCount - 1
{
String id = A_AccountID(i);
value = A_BuyPosition(i);
value1 = A_SellPosition(i);
Commentary("实盘账户:" + id);
Commentary("多头实盘持仓:" + Text(value));
Commentary("空头实盘持仓:" + Text(value1));
}
Numeric currentTradeDate = TrueDate(0);
Commentary("进入OnBar事件,当前日期: " + Text(currentTradeDate));
// 如果是新的交易日,重置相关变量
if (currentTradeDate!= lastTradeDate and A_BuyPosition() <= 0 and A_SellPosition() <= 0)
{
IsBasePriceSet = false;
lastTradeDate = currentTradeDate;
Commentary("新交易日,重置相关变量,日期: " + Text(lastTradeDate));
}
if (!IsBasePriceSet)
{
basePrice[0] = Q_Open();
IsBasePriceSet = true;
Commentary("成功获取开盘价作为基准价,基准价: " + Text(basePrice[0]));
}
// 计算价格变化
if (IsBasePriceSet)
{
Numeric currentPrice = Close();
priceChange = currentPrice - basePrice[0];
Commentary("价格变化: " + Text(priceChange));
}
// 比较当前价格与基准价进行交易判断
if (IsBasePriceSet)
{
Numeric askPrice = Q_AskPrice();
Numeric bidPrice = Q_BidPrice();
if (bidPrice <= basePrice[0] - OffsetLong and A_BuyPosition() == 0 and A_SellPosition() == 0) //多头开仓
{
if (BarStatus == 2 and con == 0)
{
Bool buyRet = A_SendOrderEx(Enum_Buy, Enum_Entry, 1, bidPrice+2, bOrderId);
if(A_BuyPosition >= 1)
{
con = 1;
}
}
Commentary("当前为多头持仓,检查补仓、止损和止盈条件");
// 根据持仓均价计算多头持仓盈亏金额
Numeric buyAvgPrice = A_BuyAvgPriceO();
Numeric currentPrice = Close();
Numeric profitLossAmount = currentPrice - buyAvgPrice;
Commentary("多头持仓盈亏(金额): " + Text(profitLossAmount));
if (currentPrice <= buyAvgPrice - FirstLoss)
{
if (BarStatus == 2 and con1 == 0)
{
Bool buyRet = A_SendOrderEx(Enum_Buy, Enum_Entry, 1, currentPrice+5, bOrderId1);
if (A_BuyPosition>= 2)
{
con1 = 1;
}
}
else if (BarStatus == 2 and currentPrice <= buyAvgPrice - SecondLoss) //多头第二次补仓
{
if(con2 == 0)
{
Bool buyRet = A_SendOrderEx(Enum_Buy, Enum_Entry, 1, currentPrice+1, bOrderId2);
}
if (A_BuyPosition > 3)
{ con2 = 1;
Commentary("多仓第二次补仓,亏损达到 " + Text(SecondLoss, 2)) ;
}
else
{
Commentary("买入补仓订单下达失败");
}
}
}
else
{
Commentary("多头未满足补仓条件");
}
if (profitLossAmount <= -StopLoss1) //多头止损
{
Integer longContracts = A_BuyPosition();
Array<Integer> sellOrderIdsTemp;
Bool sellRet = A_SendOrderEx(Enum_Sell, Enum_Exit, longContracts, currentPrice+1, sellOrderIdsTemp);
if (A_BuyPosition <= 0)
{
con = 0;
con1 = 0;
con2 = 0;
AddTradeFlag(Enum_Strategy_Finished); //多头止损后停止自动交易
Commentary("多仓止损,亏损达到 " + Text(StopLoss1, 2));
}
}
else if (profitLossAmount >= LongTakeProfit) //多头止盈
{
Integer longContracts = A_BuyPosition();
Array<Integer>sellOrderIdsTemp;
Bool sellRet = A_SendOrderEx(Enum_Sell, Enum_Exit, longContracts, currentPrice+1, sellOrderIdsTemp);
if (A_BuyPosition() <= 0)
{
con = 0;
con1 = 0;
con2 = 0;
// AddTradeFlag(Enum_Strategy_Finished); //止盈后停止自动交易
Commentary("多仓止盈,盈利达到 " + Text(LongTakeProfit, 2) + " 点,已下达多头止盈平仓订单,多头持仓合约数: " + Text(longContracts));
}
}
}
if (askPrice >= basePrice[0] + OffsetShort and A_SellPosition() == 0 and A_BuyPosition == 0) //空头开仓****
{
Commentary("当前无持仓,检查开仓条件");
if ( BarStatus == 2 and con == 0)
{
Bool sellShortRet = A_SendOrderEx(Enum_Sell, Enum_Entry, 1, askPrice, sOrderId);
if (A_SellPosition >= 1)
{ con = 1;
Commentary("做空操作,卖一价高于基准价 " + Text(OffsetShort, 2));
}
else
{
Commentary("卖空订单下达失败");
}
}
}
else if (A_SellPosition() > 1)
{
Commentary("当前为空头持仓,检查补仓、止损和止盈条件");
// 根据持仓均价计算空头持仓盈亏金额
Numeric sellAvgPrice = A_SellAvgPriceO();
Numeric currentPrice = Close();
Numeric profitLossAmount = sellAvgPrice - currentPrice;
Commentary("空头持仓盈亏(金额): " + Text(profitLossAmount));
if (A_SellPosition > 1 and currentPrice >= sellAvgPrice + FirstLoss)
{
if (BarStatus == 2 and con1 == 0)
{
Array<Integer> sellOrderIdsTemp;
Bool sellShortRet = A_SendOrderEx(Enum_Sell, Enum_Entry, 1, currentPrice+1, sOrderId_1);
con1 = 1;
}
}
else if (shortEntryCount > 2 and currentPrice >= sellAvgPrice + SecondLoss) //空头第一次补仓
{
if (BarStatus == 2 and con2 == 0)
{
Array<Integer> sellOrderIdsTemp;
Bool sellShortRet = A_SendOrderEx(Enum_Sell, Enum_Entry, 1, currentPrice+1, sOrderId_1);
con2 = 1;
}
}
if (Abs(profitLossAmount) >= StopLoss1) //止损
{
Integer shortContracts = A_SellPosition();
Array<Integer> buyToCoverOrderIdsTemp;
Bool buyToCoverRet = A_SendOrderEx(Enum_Buy, Enum_Exit, 1, currentPrice, buyToCoverOrderIdsTemp);
if (A_SellPosition == 0)
{
con = 0;
con1 = 0;
con2 = 0;
AddTradeFlag(Enum_Strategy_Finished);
Commentary("空仓止损,亏损达到 " + Text(StopLoss1, 2));
}
else
{
Commentary("空头止损平仓订单下达失败");
}
}
else if (profitLossAmount >= ShortTakeProfit) //空头止盈
{
Integer shortContracts = A_SellPosition();
Array<Integer> buyToCoverOrderIdsTemp;
Bool buyToCoverRet = A_SendOrderEx(Enum_Buy, Enum_Exit, shortContracts, currentPrice, buyToCoverOrderIdsTemp);
if (A_SellPosition == 0)
{ con = 0;
con1 = 0;
con2 = 0;
// AddTradeFlag(Enum_Strategy_Finished);
Commentary("空仓止盈,盈利达到 " + Text(ShortTakeProfit, 2));
}
}
那多次建仓用多个开关思路会错吗? 和第一个开关会冲突吗
最可靠的办法就是输出打断点,光看逻辑思路,很难准确判断
a函数只能靠自己输出断点调试了