老师,我想将手中的主观开仓,用公式进行跟踪出场。
Params
Array<String> syms(["T2603.CFFEX","RB2603.SHFE"]); //参数里手动 想要公式跟踪出场的合约练习以下代码,能否帮我看下是否存在订阅的数据源和发单不对应的问题。从画线上看,还是都按照Data0 在计算指标。
我觉得不对啊, 但一时也找不出问题。还望指教订阅数据和 参数Syms对应的问题。
Params
// 策略参数
String AccID("100"); // 账户号
Array<String> syms(["T2603.CFFEX","0.SHFE","1040.DCE","1040.CZCE","ec2604.INE"]);//合约列表
Numeric Split(1); // 仓位分割比例 半仓就是 0.5
Enum<String>Type(["按10日均线","按ATR","按盈利回撤"]);
Vars
Numeric RestartInterval(0.03); // 3小时之内
Global Numeric LastRestartTime(0); // 全局变量记录重启时间
Array<Integer> layerId;
Array<String> InPosSymbols; // 读取到的账户持仓Symbol
Global Map<String, Integer> LayerToSym; // 数据源映射: 合约代码 -> 订阅序号
Global Map<String, Integer> InPosMap; // 持仓映射: 合约代码 -> 持仓手数(多正空负)
Numeric MaxBars(1000); // 订阅1000根bar
Integer TradeLots;
Global Integer i;
Defs
Events
// 初始化事件函数,策略运行期间,首先运行且只有一次
OnInit()
{
//获取账户持仓的合约代码,并循环查找持仓合约在之前图层的序号
Integer accountIndex = A_AccountIndex(AccID,27);//账户索引 "100560213" ,BrokerID 是27
Bool ret = A_GetPositionSymbols(InPosSymbols, accountIndex);
//Print("所有持仓品种:" + IIFString(ret, "True", "False") + "," + TextArray(InPosSymbols));
For i = 0 to GetArraySize(InPosSymbols) - 1
{
Position pos;
A_GetPosition(InPosSymbols[i], pos, "", AccountIndex);
If(pos.longCurrentVolume > 0) // 持多仓
{
InPosMap[InPosSymbols[i]] = pos.longCurrentVolume; // 写入MAP
}
If(pos.shortCurrentVolume > 0) // 持空仓
{
InPosMap[InPosSymbols[i]] = - pos.shortCurrentVolume; // 写入MAP
}
}
Print(TextMap(InPosMap));
// 订阅行情并建立图层-合约映射
For i=0 To GetArraySize(InPosSymbols)-1
{
// 订阅合约行情
layerId = SubscribeBarCounts(InPosSymbols[i], "5m", MaxBars);
LayerToSym[InPosSymbols[i]] = layerId[i];
//Print("订阅合约:" + InPosSymbols[i] + ",图层ID:" + Text(layerId[i]));
}
Print(TextMap(LayerToSym));
}
//Bar更新事件函数,参数indexs表示变化的数据源图层ID数组
OnBar(ArrayRef<Integer> indexs)
{
// LayerToSym; 数据源映射: 合约代码 -> 订阅序号
// InPosMap; 持仓映射: 合约代码 -> 持仓手数(多正空负)
For i = 0 to DataCount - 1
{
Integer j;
For j = 0 to GetArraySize(Syms)
{
If(Data[i].Symbol == Syms[j])
{
Integer TradeLots = RoundUp(InPosMap[Syms[j]] * Split, 0);
Print(syms[j] + " = [" + Text(TradeLots) + "]" + " 手");
If(Type == "按10日均线")
{
// 根据持仓手数进行平仓
If(InPosMap[Syms[j]] > 0) // 多仓
{
Numeric StopLine = Data[i].MA4Day(10) * 0.997;
PlotNumeric("StopLine", StopLine, 0, Green);
If(Data[i].Close[1] < StopLine && Data[i].Open < StopLine)
{
Sell(Abs(TradeLots), Data[i].Open);
Commentary("多头平仓 / " + Syms[j] + " / [" + Text(TradeLots) + "]" + " 手 / 委托价格 =" + Text(Data[i].Open));
}
}
Else If(InPosMap[Syms[j]] < 0) // 空仓
{
// 平空仓逻辑
Numeric StopLine = Data[i].MA4Day(10) * (1 + 0.003);
PlotNumeric("StopLine", StopLine, 0, Green);
If(Data[i].Close[1] > StopLine && Data[i].Open > StopLine)
{
BuyToCover(Abs(TradeLots), Data[i].Open);
Commentary("空头平仓 / " + Syms[j] + " / [" + Text(TradeLots) + "]" + " 手 / 委托价格 =" + Text(Data[i].Open));
}
}
}
If(Type == "按ATR")
{
Numeric ATR = Data[i].DayATR(2);
// 根据持仓手数进行平仓
If(InPosMap[Syms[j]] > 0) // 多仓
{
Numeric StopLine = Data[i].Highest(High, 30) - ATR;
PlotNumeric("StopLine", StopLine, 0, Green);
If(Data[i].Low < StopLine)
{
Sell(Abs(TradeLots), StopLine);
Commentary("多头平仓 / " + Syms[j] + " / [" + Text(TradeLots) + "]" + " 手 / 委托价格 =" + Text(StopLine));
}
}
Else If(InPosMap[Syms[j]] < 0) // 空仓
{
// 平空仓逻辑
Numeric StopLine = Data[i].Lowest(Low, 30) + ATR;
PlotNumeric("StopLine", StopLine, 0, Green);
If(Data[i].High > StopLine)
{
BuyToCover(Abs(TradeLots), StopLine);
Commentary("空头平仓 / " + Syms[j] + " / [" + Text(TradeLots) + "]" + " 手 / 委托价格 =" + Text(StopLine));
}
}
}
}
}
}
}