源码下载地址:https://gitee.com/topview999/TopViewQHTCtpCom
![](https://img-blog.csdnimg.cn/img_convert/defbd0467d088120271d9422fc81aff1.png)
private void button1_Click(object sender, EventArgs e)
{
int verrorid = 0;
String verrstr = "11111111111111111111111111111111111111111111111111111111111111111";
tVQhtICtpClientAPI.OnTradeConnected += MyOnTdForntConnectd;
tVQhtICtpClientAPI.OnTradeDisconnected += MyOnTradeDisconnected;
tVQhtICtpClientAPI.OnMDConnected += MyOnMDConnected;
tVQhtICtpClientAPI.OnMDDisconnected += MyOnMDDisconnected;
tVQhtICtpClientAPI.OnMarketData += MyOnSubMaker;
tVQhtICtpClientAPI.OnEventsInfo += MyOnEventsInfo;
tVQhtICtpClientAPI.OnOrder += MyOnOrder;
tVQhtICtpClientAPI.OnRspQryOrder += MyOnRsqQryOrder;
tVQhtICtpClientAPI.OnTrade += MyOnTrade;
tVQhtICtpClientAPI.OnOrderActionFailed += MyOnOrderActionFailed;
tVQhtICtpClientAPI.OnOrderCanceled += MyOnOrderCanceled;
tVQhtICtpClientAPI.OnInstrumentStatus += MyOnInstrumentStatus;
//tVQhtICtpClientAPI.OnGetPositionDetail += MyOnGetPositionDetail;
tVQhtICtpClientAPI.OnGetInstrument += MyOnGetInstrument;
tVQhtICtpClientAPI.OnRspError += MyOnRspError;
tVQhtICtpClientAPI.OnRspQryTrade += MyOnRspQryTrade;
tVQhtICtpClientAPI.OnOutProgress += MyOnOutProgress;
tVQhtICtpClientAPI.OnInitFinished += MyOnInitFinished;
tVQhtICtpClientAPI.OnPushCancleOrder += OnPushCancleOrder;
tVQhtICtpClientAPI.OnDepthMarketData += OnDepthMarketData;
tVQhtICtpClientAPI.OnOutPosition += OnOutPosition;
tVQhtICtpClientAPI.OnOutBars += MyOnBars;
tVQhtICtpClientAPI.OnOutExchangeTradeTimes += MyOnOutExchangeTradeTimes;
//=======================以上接口======================================
tVQhtICtpClientAPI.SetOrderCloseMode(0, out verrorid);
tVQhtICtpClientAPI.Login("config.ini", this.textBox5.Text.ToString(),
this.textBox6.Text.ToString(), out verrorid, out verrstr);
this.textBox1.AppendText("Loginid:" + verrorid.ToString() +
" LogInfo:" + verrstr.ToString() + " GetAPIVersion:=" +
tVQhtICtpClientAPI.GetAPIVersion());
}
//===========================刷新持仓仓位及盈利\ 账户资金状况.========================================
//==================================刷新账户资金状况线程===============
delegate void SetTable2Callback();// 将text更新的界面控件的委托类型
private void ThreadProcTable2()
{
this.BeginInvoke(new SetTable2Callback(SetTable2));
}
private void SetTable2()
{
double PreBalance, Balance, PreMargin, Available, WithdrawQuota, ExchangeMargin, CloseProfit, PositionProfit;
tVQhtICtpClientAPI.GetAccount(out PreBalance, out Balance, out PreMargin, out Available,
out WithdrawQuota, out ExchangeMargin, out CloseProfit, out PositionProfit);
this.dataGridView2.Rows[0].Cells[0].Value = PreBalance.ToString();//静态权益
this.dataGridView2.Rows[0].Cells[1].Value = Balance.ToString();// 结算保证金
this.dataGridView2.Rows[0].Cells[2].Value = PreMargin.ToString();//占用保证金
this.dataGridView2.Rows[0].Cells[3].Value = Available.ToString();//可用资金
this.dataGridView2.Rows[0].Cells[4].Value = WithdrawQuota.ToString();//可取资金
this.dataGridView2.Rows[0].Cells[5].Value = ExchangeMargin.ToString();//交易所保证金
this.dataGridView2.Rows[0].Cells[6].Value = PositionProfit.ToString();//持仓盈亏或浮动盈亏
this.dataGridView2.Rows[0].Cells[7].Value = CloseProfit.ToString();//平仓盈亏
}
delegate void MyUpdatelabel1(string text);
private void Settextlabel1(string text)
{
this.label1.Text = text;
}
public void RefAccountPositionThPro()
{
while (true)
{
Thread.Sleep(1000);
int NowSec = DateTime.Now.Second;
if (NowSec != MyUseVar.RefSec)
{
MyUseVar.RefSec = NowSec;
vMyTimeStr = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
this.BeginInvoke(new MyUpdatelabel1(Settextlabel1), "时间:" + vMyTimeStr);
//==================刷新持仓仓位及盈利\ 账户资金状况.
Thread demoThread = new Thread(new ThreadStart(ThreadProcTable2));// 账户资金状况.这是两种不同的线程刷新代码 不知那种合理正确.看来如果刷新可视控件,此行代码正确.
demoThread.IsBackground = true;
demoThread.Start();
for (int i = 0; i < MyPositionsList.Count; i++)//刷新持仓仓位及盈利\ 账户资金状况.
{
if (MyPositionsList[i].买卖.ToString() == " 卖")
{
int vd1, vd2;
double lprice, sprice, lpp, spp, bidprice, askprice;
tVQhtICtpClientAPI.GetPositionPlus(MyPositionsList[i].合约名称.ToString(), out MyUseVar.MyPostion.LongPostion, out MyUseVar.MyPostion.LongYDPostion,
out MyUseVar.MyPostion.LongFrozen, out vd1, out lprice, out lpp, out MyUseVar.MyPostion.ShortPostion, out MyUseVar.MyPostion.ShortYDPostion,
out MyUseVar.MyPostion.ShortFrozen, out vd2, out sprice, out spp, out bidprice, out askprice);
MyPositionsList[i].BidPrice = bidprice;
MyPositionsList[i].AskPrice = askprice;
MyPositionsList[i].持仓盈亏 = spp;
try
{
MyPositionsList[i + 1].BidPrice = bidprice;
MyPositionsList[i + 1].AskPrice = askprice;
MyPositionsList[i + 1].持仓盈亏 = lpp;
}
catch { }
}
}
Thread demoThread1 = new Thread(new ThreadStart(ThreadSetDbTable4Source)); //更新持仓列表表格数据源 这是两种不同的线程刷新代码 不知那种合理正确.
demoThread1.IsBackground = true;
demoThread1.Start();//只刷新数据源的话,此行代码正确可执行.如果刷新中有可视控件则程序崩溃.
//Thread demoThread1 = new Thread(ThreadSetDbTable4Source); //更新持仓列表表格数据源 这是两种不同的线程刷新代码 不知那种合理正确.
//demoThread1.Start(MyPositionsList);//只刷新数据源的话,此行代码正确可执行.如果刷新中有可视控件则程序崩溃.
}
}
}
public void MyOnInitFinished() //初始化完成后回报。
{
this.textBox1.AppendText("MyOnInitFinished OK! \r\n");
Thread RefAccountPositionThread = new Thread(new ThreadStart(RefAccountPositionThPro)); //开始刷新账户资金及持仓盈亏数据.用线程 CPU 占用率99%.奇怪了.c#是个另类.其他语言线程占用率极小.
RefAccountPositionThread.IsBackground = true;
RefAccountPositionThread.Start();
}
//#==================循环开平仓操作=================================
delegate void MyUpdateOpenClose();
private void OpenCloseTimeCount()
{
while (true)
{
Thread.Sleep(MyUseVar.Interval);
if (MyUseVar.BeginOpenClose == 1)
{
this.BeginInvoke(new MyUpdateOpenClose(OpenCloseDoIt));
}
}
}
private void OpenCloseDoIt()
{
if (MyUseVar.vloop == 0)
{
this.textBox4.AppendText("\r\n======TickCount:" + System.Environment.TickCount.ToString() + "=======================\r\n");
double vd1, vd2;
tVQhtICtpClientAPI.GetPosition(MyUseVar.sInstrumentID, out MyUseVar.MyPostion.LongPostion, out MyUseVar.MyPostion.LongYDPostion,
out MyUseVar.MyPostion.LongFrozen, out vd1, out MyUseVar.MyPostion.ShortPostion, out MyUseVar.MyPostion.ShortYDPostion,
out MyUseVar.MyPostion.ShortFrozen, out vd2);
this.textBox4.AppendText(" Tick:" + System.Environment.TickCount.ToString() + " 多头仓位:" + MyUseVar.MyPostion.LongPostion.ToString() +
" 昨仓:" + MyUseVar.MyPostion.LongYDPostion.ToString() + " 冻结仓位:" + MyUseVar.MyPostion.LongFrozen.ToString() +
" 空头仓位:" + MyUseVar.MyPostion.ShortPostion.ToString() + " 昨仓:" + MyUseVar.MyPostion.ShortYDPostion.ToString() +
" 冻结仓位:" + MyUseVar.MyPostion.ShortFrozen.ToString() + "\r\n");
MyUseVar.vIsCanC = 0;
MyUseVar.vIsCanC1 = 0;
MyUseVar.vIsCanC2 = 0;
MyUseVar.vIsCanC3 = 0;
if (MyUseVar.MyPostion.LongOrder > 0 || MyUseVar.MyPostion.LongOrder1 > 0 || MyUseVar.MyPostion.ShortOrder > 0 || MyUseVar.MyPostion.ShortOrder1 > 0)
{//有订单号时 判断是否有可撤订单
if (MyUseVar.MyPostion.LongOrder > 0)
{
this.tVQhtICtpClientAPI.IsOrderOpen(MyUseVar.MyPostion.LongOrder, out MyUseVar.vIsCanC);
this.textBox4.AppendText(string.Format("LongOrder订单:{0} 是否可撤:{1} (0 :不可撤 1:可撤)\r\n", MyUseVar.MyPostion.LongOrder, MyUseVar.vIsCanC));
}
if (MyUseVar.MyPostion.LongOrder1 > 0)
{
this.tVQhtICtpClientAPI.IsOrderOpen(MyUseVar.MyPostion.LongOrder1, out MyUseVar.vIsCanC1);
this.textBox4.AppendText(string.Format("LongOrder1订单:{0} 是否可撤:{1} (0 :不可撤 1:可撤)\r\n", MyUseVar.MyPostion.LongOrder1, MyUseVar.vIsCanC1));
}
if (MyUseVar.MyPostion.ShortOrder > 0)
{
this.tVQhtICtpClientAPI.IsOrderOpen(MyUseVar.MyPostion.ShortOrder, out MyUseVar.vIsCanC2);
this.textBox4.AppendText(string.Format("ShortOrder订单:{0} 是否可撤:{1} (0 :不可撤 1:可撤)\r\n", MyUseVar.MyPostion.ShortOrder, MyUseVar.vIsCanC2));
}
if (MyUseVar.MyPostion.ShortOrder1 > 0)
{
this.tVQhtICtpClientAPI.IsOrderOpen(MyUseVar.MyPostion.ShortOrder1, out MyUseVar.vIsCanC3);
this.textBox4.AppendText(string.Format("ShortOrder1订单:{0} 是否可撤:{1} (0 :不可撤 1:可撤)\r\n", MyUseVar.MyPostion.ShortOrder1, MyUseVar.vIsCanC3));
}
}
if (MyUseVar.vIsCanC == 1 || MyUseVar.vIsCanC1 == 1 || MyUseVar.vIsCanC2 == 1 || MyUseVar.vIsCanC3 == 1) MyUseVar.vloop = 1;
else MyUseVar.vloop = 4;
}//结束vloop=0 步骤
if (MyUseVar.vloop == 1) //有订单可撤时 等待时间
{
MyUseVar.vWaitInCancle = MyUseVar.vWaitInCancle + 1;
if (MyUseVar.vWaitInCancle >= MyUseVar.vWaitCancleInt)
{
MyUseVar.vWaitInCancle = 0;
MyUseVar.vloop = 2;
}//结束判断撤单后时间间隔
}// 结束vloop=1 步骤
if (MyUseVar.vloop == 2)// #有订单可撤 撤单
{
if (MyUseVar.vIsCanC == 1)// #longorder可撤
{
tVQhtICtpClientAPI.CancelOrder(MyUseVar.MyPostion.LongOrder, out MyUseVar.vIsCanC);
this.textBox4.AppendText(string.Format("LongOrder订单:{0} 空头撤单 状态:{1}【0:撤单成功 其它:撤单不成功】\r\n",
MyUseVar.MyPostion.LongOrder, MyUseVar.vIsCanC));
}
if (MyUseVar.vIsCanC1 == 1)// #longorder可撤
{
tVQhtICtpClientAPI.CancelOrder(MyUseVar.MyPostion.LongOrder1, out MyUseVar.vIsCanC1);
this.textBox4.AppendText(string.Format("LongOrder1订单:{0} 空头撤单 状态:{1}【0:撤单成功 其它:撤单不成功】\r\n",
MyUseVar.MyPostion.LongOrder1, MyUseVar.vIsCanC1));
}
if (MyUseVar.vIsCanC2 == 1)// #Shortorder可撤
{
tVQhtICtpClientAPI.CancelOrder(MyUseVar.MyPostion.ShortOrder, out MyUseVar.vIsCanC2);
this.textBox4.AppendText(string.Format("ShortOrder订单:{0} 空头撤单 状态:{1}【0:撤单成功 其它:撤单不成功】\r\n",
MyUseVar.MyPostion.ShortOrder, MyUseVar.vIsCanC2));
}
if (MyUseVar.vIsCanC3 == 1)// #Shortorder可撤
{
tVQhtICtpClientAPI.CancelOrder(MyUseVar.MyPostion.ShortOrder1, out MyUseVar.vIsCanC3);
this.textBox4.AppendText(string.Format("ShortOrder1订单:{0} 空头撤单 状态:{1}【0:撤单成功 其它:撤单不成功】\r\n",
MyUseVar.MyPostion.ShortOrder1, MyUseVar.vIsCanC3));
}
MyUseVar.vloop = 3;
}//#有订单可撤 撤单结束 vloop==2
if (MyUseVar.vloop == 3) //: #有订单可撤时 等待时间
{
MyUseVar.vWaitInCancle = MyUseVar.vWaitInCancle + 1;
if (MyUseVar.vWaitInCancle >= MyUseVar.vWaitCancleInt)
{
MyUseVar.vWaitInCancle = 0;
MyUseVar.vloop = 4;
}//#结束判断撤单后时间间隔
}//#结束vloop=3 步骤
if (MyUseVar.vloop == 4)//: #循环开平仓开始 random.randint(1,10)
{
//#==================多头开平仓操作=================================
int vrandtvol;
if (MyUseVar.MyPostion.LongPostion > 0 && MyUseVar.MyPostion.LongPostion < MyUseVar.iVolT)
{
if (MyUseVar.MyPostion.LongOrderFlag == 1)//上次平仓
{
vrandtvol = GetRandom(1, MyUseVar.MyPostion.LongPostion);// # 产生随机开平仓手数量
tVQhtICtpClientAPI.Sell(MyUseVar.sInstrumentID, vrandtvol, vMyBidPrice, out MyUseVar.MyPostion.LongOrder, out MyUseVar.MyPostion.LongOrder1);
this.textBox4.AppendText(vMyTimeStr + " Tick:" + System.Environment.TickCount.ToString() + " LongOrder:" + MyUseVar.MyPostion.LongOrder.ToString() +
" LongOrder1:" + MyUseVar.MyPostion.LongOrder1.ToString() + " 继续平多头仓位:" + vrandtvol.ToString() + "\r\n");
}//MyUseVar.MyPostion.LongOrderFlag == 1
else
{
vrandtvol = GetRandom(1, MyUseVar.iVolT);// # 产生随机开平仓手数量
tVQhtICtpClientAPI.Buy(MyUseVar.sInstrumentID, vrandtvol, vMyAskPrice, out MyUseVar.MyPostion.LongOrder);
this.textBox4.AppendText(vMyTimeStr + " Tick:" + System.Environment.TickCount.ToString() + " LongOrder:" + MyUseVar.MyPostion.LongOrder.ToString() +
" 继续多头买开仓:" + vrandtvol.ToString() + "\r\n");
}//MyUseVar.MyPostion.LongOrderFlag != 1
}//MyUseVar.MyPostion.LongPostion > 0 && MyUseVar.MyPostion.LongPostion < MyUseVar.iVolT
else
{
if (MyUseVar.MyPostion.LongPostion >= MyUseVar.iVolT)
{
int vrandtvol1 = GetRandom(1, MyUseVar.MyPostion.LongPostion);// # 产生随机开平仓手数量
tVQhtICtpClientAPI.Sell(MyUseVar.sInstrumentID, vrandtvol1, vMyBidPrice, out MyUseVar.MyPostion.LongOrder, out MyUseVar.MyPostion.LongOrder1);
this.textBox4.AppendText(vMyTimeStr + " Tick:" + System.Environment.TickCount.ToString() + " LongOrder:" + MyUseVar.MyPostion.LongOrder.ToString() +
" LongOrder1:" + MyUseVar.MyPostion.LongOrder1.ToString() + " 平多头多余仓位:" + vrandtvol1.ToString() + "\r\n");
MyUseVar.MyPostion.LongOrderFlag = 1;
}
if (MyUseVar.MyPostion.LongPostion <= 0)//无持仓时
{
int vrandtvol1 = GetRandom(1, MyUseVar.iVolT);// # 产生随机开平仓手数量
tVQhtICtpClientAPI.Buy(MyUseVar.sInstrumentID, vrandtvol1, vMyAskPrice, out MyUseVar.MyPostion.LongOrder);
this.textBox4.AppendText(vMyTimeStr + " Tick:" + System.Environment.TickCount.ToString() + " LongOrder:" + MyUseVar.MyPostion.LongOrder.ToString() +
" 多头买开仓:" + vrandtvol1.ToString() + "\r\n");
MyUseVar.MyPostion.LongOrderFlag = 0;
}
}//MyUseVar.MyPostion.LongPostion <= 0|| MyUseVar.MyPostion.LongPostion >= MyUseVar.iVolT
//================================多头开平仓操作===========================================================================
//================================空头开平仓操作===========================================================================
if (MyUseVar.MyPostion.ShortPostion > 0 && MyUseVar.MyPostion.ShortPostion < MyUseVar.iVolT)
{
if (MyUseVar.MyPostion.ShortOrderFlag == 1)
{
vrandtvol = GetRandom(1, MyUseVar.MyPostion.ShortPostion);// # 产生随机开平仓手数量
tVQhtICtpClientAPI.Cover(MyUseVar.sInstrumentID, vrandtvol, vMyAskPrice, out MyUseVar.MyPostion.ShortOrder, out MyUseVar.MyPostion.ShortOrder1);
this.textBox4.AppendText(vMyTimeStr + " Tick:" + System.Environment.TickCount.ToString() + " ShortOrder:" + MyUseVar.MyPostion.ShortOrder.ToString() +
" ShortOrder1:" + MyUseVar.MyPostion.ShortOrder1.ToString() + " 继续平空头仓位:" + vrandtvol.ToString() + "\r\n");
}//MyUseVar.MyPostion.ShortOrderFlag == 1
else
{
vrandtvol = GetRandom(1, MyUseVar.iVolT);// # 产生随机开平仓手数量
tVQhtICtpClientAPI.Short(MyUseVar.sInstrumentID, vrandtvol, vMyBidPrice, out MyUseVar.MyPostion.ShortOrder);
this.textBox4.AppendText(vMyTimeStr + " Tick:" + System.Environment.TickCount.ToString() + " ShortOrder:" + MyUseVar.MyPostion.ShortOrder.ToString() +
" 继续空头卖开仓:" + vrandtvol.ToString() + "\r\n");
}//MyUseVar.MyPostion.ShortOrderFlag != 1
}//MyUseVar.MyPostion.ShortPostion > 0 && MyUseVar.MyPostion.ShortPostion < MyUseVar.iVolT
else
{
if (MyUseVar.MyPostion.ShortPostion >= MyUseVar.iVolT)
{
int vrandtvol1 = GetRandom(1, MyUseVar.MyPostion.ShortPostion);// # 产生随机开平仓手数量
tVQhtICtpClientAPI.Cover(MyUseVar.sInstrumentID, vrandtvol1, vMyAskPrice, out MyUseVar.MyPostion.ShortOrder, out MyUseVar.MyPostion.ShortOrder1);
this.textBox4.AppendText(vMyTimeStr + " Tick:" + System.Environment.TickCount.ToString() + " ShortOrder:" + MyUseVar.MyPostion.ShortOrder.ToString() +
" ShortOrder1:" + MyUseVar.MyPostion.ShortOrder1.ToString() + " 平空头多余仓位:" + vrandtvol1.ToString() + "\r\n");
MyUseVar.MyPostion.ShortOrderFlag = 1;
}
if (MyUseVar.MyPostion.ShortPostion <= 0)
{
int vrandtvol1 = GetRandom(1, MyUseVar.iVolT);// # 产生随机开平仓手数量
tVQhtICtpClientAPI.Short(MyUseVar.sInstrumentID, vrandtvol1, vMyBidPrice, out MyUseVar.MyPostion.ShortOrder);
this.textBox4.AppendText(vMyTimeStr + " Tick:" + System.Environment.TickCount.ToString() + " ShortOrder:" + MyUseVar.MyPostion.ShortOrder.ToString() +
" 空头卖开仓:" + vrandtvol1.ToString() + "\r\n");
MyUseVar.MyPostion.ShortOrderFlag = 0;
}
}//MyUseVar.MyPostion.ShortPostion <= 0|| MyUseVar.MyPostion.ShortPostion >= MyUseVar.iVolT
//#==================空头开平仓操作=================================
MyUseVar.vloop = 5;
}
if (MyUseVar.vloop == 5)//: #有等待时间
{
MyUseVar.vWaitInOrder = MyUseVar.vWaitInOrder + 1;
if (MyUseVar.vWaitInOrder >= MyUseVar.vWaitOrderInt)
{
MyUseVar.vWaitInOrder = 0;
MyUseVar.vloop = 0;
this.textBox4.AppendText("===================================================================================\r\n");
}
}
}//OpenCloseDoIt()
private void button8_Click(object sender, EventArgs e)
{
MyUseVar.BeginOpenClose = 1 - MyUseVar.BeginOpenClose;
if (MyUseVar.BeginOpenClose == 1)
{
button8.Text = "暂停开平仓循环测试";
OpenCloseThread = new Thread(new ThreadStart(OpenCloseTimeCount));// 账户资金状况.
OpenCloseThread.IsBackground = true;
OpenCloseThread.Start();
}
else
{
button8.Text = "开始开平仓循环测试";
OpenCloseThread.Abort();
}
//开始刷新账户资金及持仓盈亏数据,并准备开始开平仓测试操作.线程启动放在OnInitFinished事件中.
}