开拓者期货期权程序化系统交易论坛

标题: tb数据库读写bug [打印本页]

作者: zxjt10224500    时间: 2016-1-13 15:24:50     标题: tb数据库读写bug

前提,用A程序写入数据库变量,频率很低,只有发生信号才会写,6个B程序读取A写入的数据库变量,B程序是tick出发读取,不写入。
发现绝大部分程序运行正常,但小概率事件会出现,其中5个B程序读取正常,1个B程序读取错误,这个错误并不是invalidstring类型,而是数据库别的某个变量值。这个数值正确与否比较难判断。
很闹心,万一读错了,造成大量开仓和平仓是件非常可怕的事情。希望tb能解决上述数据库读写bug。


作者: zxjt10224500    时间: 2016-1-13 15:25:47

补充一下:每个程序分别占用一个图表。
作者: superwin    时间: 2016-1-13 16:22:07

是的,我也发现了,特别是读写的程序一多,就会出现读写错误,会读写到别的健名上,比如我这里有30个公式(A01—A30)每个TICK对数据库进行读写,30个公式分别读写同一个块名(Section)下30个不同键名(Key)下的值(Value),经常就会出现交叉写入跟交叉读取的情况,比如A01公式正常是读写键名A01下的值,却读到键名A05的值,写数据时写到键名A12下。这个情况发生的几率很低,只是偶尔会出现,原因不明,现在我暂时的处理就是在每个值后面加上一个编号标识,然后在公式里验证,防止错误。
作者: zxjt10224500    时间: 2016-1-13 16:28:29

superwin 发表于 2016-1-13 16:22
是的,我也发现了,特别是读写的程序一多,就会出现读写错误,会读写到别的健名上,比如我这里有30个公式( ...

你说的确实是个不错的解决方案,我试试。
作者: fqxing95    时间: 2016-1-22 13:58:28

我也发现读写数据库有问题,希望tb马上处理。
作者: fqxing95    时间: 2016-1-22 14:01:52

if(xxxx==InvalidNumeric){return;}都无效。
作者: fqxing95    时间: 2016-1-22 14:24:49

读写数据库有问题,我是这样发现的。我的目的是公式每5分钟检查一下数据库持仓和实际持仓(A_BuyPosition、A_SellPosition)的差别,以便按数据库持仓为准来调整实际持仓,因交易时间或其他原因会造成实际持仓和数据库持仓的不同步。
我当初以为是函数A_BuyPosition、A_SellPosition有问题,看来不是。后来我在读数据库持仓时,加入if(xxxx==InvalidNumeric){return;}也无法避免错误出现。也就是说,当我的数据库持仓和实际持仓相等时,程序也会做出调整持仓的动作(其实是错误的),而后又出现纠错的调整(这次是正确的)。这样就造成无谓的交易动作,损失手续费的同时,还有可能出现交易损失(当然有可能出现交易获利),非常郁闷,找不出具体问题根源,希望tb做出回应,如确实是读写数据库问题,请尽快纠正。
作者: fqxing95    时间: 2016-1-22 14:28:36

buycc=A_BuyPosition();
sellcc=A_SellPosition();
if(buycc==InvalidNumeric or sellcc==InvalidNumeric or buycc>10000 or sellcc>10000 or BuyLotsz01==InvalidNumeric or BuyLotsz02==InvalidNumeric or BuyLotsz01>10000 or BuyLotsz02>10000) {return;}
if(TimeDiff(GetGlobalVar(44),SystemDateTime)>300)
{
  if(strValued_x=="x+1" and buycc<>BuyLotsz01)
   {
                                   if(buycc>BuyLotsz01)  {A_SendOrder(Enum_Sell,Enum_Exit,buycc-BuyLotsz01,Q_BidPrice-3*chajia);SetGlobalVar(44,SystemDateTime);return;}
                                   if(buycc<BuyLotsz01)  {A_SendOrder(Enum_Buy,Enum_Entry,BuyLotsz01-buycc,Q_AskPrice+3*chajia);SetGlobalVar(44,SystemDateTime);return;}
                                   }
  if(strValuek_x=="x-1" and sellcc<>BuyLotsz02)
   {
                                   if(sellcc>BuyLotsz02) {A_SendOrder(Enum_Buy,Enum_Exit,sellcc-BuyLotsz02,Q_AskPrice+3*chajia);SetGlobalVar(44,SystemDateTime);return;}
                                   if(sellcc<BuyLotsz02) {A_SendOrder(Enum_Sell,Enum_Entry,BuyLotsz02-sellcc,Q_BidPrice-3*chajia);SetGlobalVar(44,SystemDateTime);return;}
                                   }
  if(strValued_x=="xdt" and buycc<>0)    {A_SendOrder(Enum_Sell,Enum_Exit,buycc,Q_BidPrice-3*chajia);SetGlobalVar(44,SystemDateTime);return;}
  if(strValuek_x=="xkt" and sellcc<>0)   {A_SendOrder(Enum_Buy,Enum_Exit,sellcc,Q_AskPrice+3*chajia);SetGlobalVar(44,SystemDateTime);return;}
                   }
if((strValued_x=="x+1" and buycc<>BuyLotsz01) or (strValuek_x=="x-1" and sellcc<>BuyLotsz02) or (strValued_x=="xdt" and buycc<>0) or (strValuek_x=="xkt" and sellcc<>0)) {return;}
作者: fqxing95    时间: 2016-1-22 14:32:32

本帖最后由 fqxing95 于 2016-1-22 14:33 编辑

strValued_x=="x+1"-------多头有持仓
strValuek_x=="x-1"--------空头有持仓
BuyLotsz01-------数据库多头持仓数量
BuyLotsz02-------数据库空头持仓数量
strValued_x=="xdt"---------多头无持仓
strValuek_x=="xkt"---------空头无持仓

作者: fqxing95    时间: 2016-1-22 14:35:03

以上读数据库出现问题,也没有什么规律,而是偶尔出现错误。
作者: zxjt10224500    时间: 2016-1-22 14:38:38

完全无规律,有时候就是读到别的数据库变量里边了,有时候竟然还能读一半别的变量,
还有一个隐晦的问题,就是一张图表里边加载两个合约,第二个合约是指数合约,读取data1.Q_Last类似的东西会出错,虽然概率很低,但有时候足够让程序平仓了,也是很狗血。
作者: 小米    时间: 2016-1-22 14:58:29

zxjt10224500 发表于 2016-1-22 14:38
完全无规律,有时候就是读到别的数据库变量里边了,有时候竟然还能读一半别的变量,
还有一个隐晦的问题, ...

有于data1.q_last的问题,请将您所使用的环境具体描述一下。。
我们安排同一样的环境测试一下,看能否重现问题并找出原因所在。
作者: zxjt10224500    时间: 2016-1-25 10:51:26

win 7 旗舰版 sp1 32位系统
cpu=intel g1610 2.6ghz
ram=2gb

tb=5.2.0.37  

5个工作区,每个工作区平均5个图表,每个图表加载3个合约,data0=主力合约,data1=指数合约,data3=次主力合约
每个图表加载的程序都涉及数据库读写。使用data1_Q_last 引发信号。

作者: fqxing95    时间: 2016-1-25 13:21:56

我的问题小米回复一下吧?
作者: 小米    时间: 2016-1-25 16:39:17

fqxing95 发表于 2016-1-25 13:21
我的问题小米回复一下吧?

什么问题?
作者: 小米    时间: 2016-1-25 16:42:47

zxjt10224500 发表于 2016-1-25 10:51
win 7 旗舰版 sp1 32位系统
cpu=intel g1610 2.6ghz
ram=2gb

读取data1.q_last出错是如何发现的??表现是什么样的?请具体一下
作者: fqxing95    时间: 2016-1-25 21:01:50

本帖最后由 fqxing95 于 2016-1-25 21:26 编辑
小米 发表于 2016-1-25 16:39
什么问题?


7楼的问题,8楼的代码。
上面那段代码有问题么?
作者: fqxing95    时间: 2016-1-26 00:47:01

这样问吧:账户实际有持仓,函数A_BuyPosition、A_SellPosition在什么情况下返回值为0
作者: 小米    时间: 2016-1-26 08:48:32

fqxing95 发表于 2016-1-26 00:47
这样问吧:账户实际有持仓,函数A_BuyPosition、A_SellPosition在什么情况下返回值为0 ...

看一下持仓与图表上data0的合约是否同一个??
会不会图表弄成指数或是连续合约了?
作者: fqxing95    时间: 2016-1-26 09:46:39

小米 发表于 2016-1-26 08:48
看一下持仓与图表上data0的合约是否同一个??
会不会图表弄成指数或是连续合约了? ...

不会,我是A函数发单的,一个图表对应一个品种。
作者: fqxing95    时间: 2016-1-26 09:55:04

现在问题是,在某种未知情况下,要不就两个持仓函数返回值为0,要不就是数据库读数错误。还是我的代码有问题,我发现不了?
作者: fqxing95    时间: 2016-1-26 10:51:20

fqxing95 发表于 2016-1-26 09:55
现在问题是,在某种未知情况下,要不就两个持仓函数返回值为0,要不就是数据库读数错误。还是我的代码有问 ...

如果代码有问题,也应该不是偶尔会出错,而是频频出错,所以困惑。
作者: 小米    时间: 2016-1-26 11:11:52

fqxing95 发表于 2016-1-26 09:46
不会,我是A函数发单的,一个图表对应一个品种。

方便远程 吗??如果对应好的,这个读错的可能 性不太大呢。。
或者重置一下数据再看看?如果是数据库损坏导致的读取数据错误,通过重置数据可以修复
作者: fqxing95    时间: 2016-1-26 11:33:13

到月底我清空数据库看看是否还会出错,我现在不在计算机旁,谢谢小米。
作者: zxjt10224500    时间: 2016-1-26 14:01:01

Data1_Q_Last=Data1.Q_Last;
Data0_Q_bid=Q_BidPrice;
Data0_Q_Ask=Q_AskPrice;
        If(BarStatus==2&&(Data0_Q_bid==InvalidNumeric||Data0_Q_Ask==InvalidNumeric||Data1_Q_last==InvalidNumeric||Data1_Q_last>Data1.High*1.008||Data1_Q_last<Data1.low*0.992)) //实时数据是否正确有效
        {
                FileAppend("d:\\log\\bd_system_1_"+Account_S1+symbol_000+"_error.log",DateTimeToString(CurrentDate+CurrentTime)+"行情数据错误:ask="+Text(Data0_Q_ask)+" bid="+Text(Data0_Q_bid)+" last="+Text(Data1_Q_last));
                return;
        }

这段代码记录错误的Q_last数据,极少出现,但会出现从螺纹的图表上读取到了橡胶图表的数据。会引发止损。
作者: fqxing95    时间: 2016-1-29 01:33:38

小米 发表于 2016-1-26 11:11
方便远程 吗??如果对应好的,这个读错的可能 性不太大呢。。
或者重置一下数据再看看?如果是数据库损 ...

我目前还没有清空数据库,到底数据库有没有损坏也不敢肯定。今天晚上又出现相同的问题了。从目前情况看来,A_sellposition这个函数,肯定在某种未知情况下,账户本来有持仓而返回值是0,郁闷!!!
作者: fqxing95    时间: 2016-1-29 09:34:21

昨天下午3:00前就持仓空头的rb,到昨天晚盘11:29程序检测到无持仓而进行仓位调整,即重新开空单。300秒后程序再次检查仓位,平掉新开的空单,保持原来的持仓。
作者: fqxing95    时间: 2016-1-29 09:50:12

目前只有rb和rm两个品种,不存在公式对应搞错的可能,且持仓过程中rb没有加减仓的操作,rm也有正常交易。
作者: xunsun    时间: 2016-1-29 10:21:17

fqxing95 发表于 2016-1-29 01:33
我目前还没有清空数据库,到底数据库有没有损坏也不敢肯定。今天晚上又出现相同的问题了。从目前情况看来 ...

A_sellposition和A_buyposition 在有持仓的情况却返回0,我也碰到过,一直不明白啥问题。
作者: fqxing95    时间: 2016-1-29 10:23:27

我是按数据库持仓来调整,这样看来数据库是没有问题的,还是持仓函数的问题。。。。。。。。。
作者: 小米    时间: 2016-1-29 11:10:09

fqxing95 发表于 2016-1-29 10:23
我是按数据库持仓来调整,这样看来数据库是没有问题的,还是持仓函数的问题。。。。。。。。。 ...

好的,这个我转交开发人员排查 一下吧。
作者: fqxing95    时间: 2016-1-29 13:39:45

小米 发表于 2016-1-29 11:10
好的,这个我转交开发人员排查 一下吧。

谢谢,结果如何希望能在这里反馈一下。
作者: fqxing95    时间: 2016-1-29 15:20:27

if(BarStatus()==2 and jytime==True)
{
buycc=A_BuyPosition();
sellcc=A_SellPosition();
if(buycc==InvalidNumeric or sellcc==InvalidNumeric or buycc>10000 or sellcc>10000 or BuyLotsz01==InvalidNumeric or BuyLotsz02==InvalidNumeric or BuyLotsz01>10000 or BuyLotsz02>10000) {
                   FileAppend("d:\\A"+Symbol+"_"+Text(CurrentDate)+".txt",DateTimeToString(SystemDateTime)+"多头"+Text(buycc)+"数据库多头"+text(BuyLotsz01)+"空头"+text(sellcc)+"数据库空头"+text(BuyLotsz02)+"无效值返回");
                                   return;}
if(TimeDiff(Myvar0,SystemDateTime)>300)
{
  if(strValued_x=="x+1" and buycc<>BuyLotsz01)
   {
                                   if(buycc>BuyLotsz01)  {A_SendOrder(Enum_Sell,Enum_Exit,buycc-BuyLotsz01,Q_BidPrice-3*chajia);SetGlobalVar(44,SystemDateTime);
                                   FileAppend("d:\\A"+Symbol+"_"+Text(CurrentDate)+".txt",DateTimeToString(SystemDateTime)+"多头"+Text(buycc)+"数据库多头"+text(BuyLotsz01)+"空头"+text(sellcc)+"数据库空头"+text(BuyLotsz02)+"多头错误1");
                                   return;}
                                   if(buycc<BuyLotsz01)  {A_SendOrder(Enum_Buy,Enum_Entry,BuyLotsz01-buycc,Q_AskPrice+3*chajia);SetGlobalVar(44,SystemDateTime);
                                   FileAppend("d:\\A"+Symbol+"_"+Text(CurrentDate)+".txt",DateTimeToString(SystemDateTime)+"多头"+Text(buycc)+"数据库多头"+text(BuyLotsz01)+"空头"+text(sellcc)+"数据库空头"+text(BuyLotsz02)+"多头错误2");
                                   return;}
                                   }
  if(strValuek_x=="x-1" and sellcc<>BuyLotsz02)
   {
                                   if(sellcc>BuyLotsz02) {A_SendOrder(Enum_Buy,Enum_Exit,sellcc-BuyLotsz02,Q_AskPrice+3*chajia);SetGlobalVar(44,SystemDateTime);
                                   FileAppend("d:\\A"+Symbol+"_"+Text(CurrentDate)+".txt",DateTimeToString(SystemDateTime)+"多头"+Text(buycc)+"数据库多头"+text(BuyLotsz01)+"空头"+text(sellcc)+"数据库空头"+text(BuyLotsz02)+"空头错误1");
                                   return;}
                                   if(sellcc<BuyLotsz02) {A_SendOrder(Enum_Sell,Enum_Entry,BuyLotsz02-sellcc,Q_BidPrice-3*chajia);SetGlobalVar(44,SystemDateTime);
                                   FileAppend("d:\\A"+Symbol+"_"+Text(CurrentDate)+".txt",DateTimeToString(SystemDateTime)+"多头"+Text(buycc)+"数据库多头"+text(BuyLotsz01)+"空头"+text(sellcc)+"数据库空头"+text(BuyLotsz02)+"空头错误2");
                                   return;}
                                   }
  if(strValued_x=="xdt" and buycc<>0)    {A_SendOrder(Enum_Sell,Enum_Exit,buycc,Q_BidPrice-3*chajia);SetGlobalVar(44,SystemDateTime);return;}
  if(strValuek_x=="xkt" and sellcc<>0)   {A_SendOrder(Enum_Buy,Enum_Exit,sellcc,Q_AskPrice+3*chajia);SetGlobalVar(44,SystemDateTime);return;}
                   }
if((strValued_x=="x+1" and buycc<>BuyLotsz01) or (strValuek_x=="x-1" and sellcc<>BuyLotsz02) or (strValued_x=="xdt" and buycc<>0) or (strValuek_x=="xkt" and sellcc<>0)) {
                   FileAppend("d:\\A"+Symbol+"_"+Text(CurrentDate)+".txt",DateTimeToString(SystemDateTime)+"多头"+Text(buycc)+"数据库多头"+text(BuyLotsz01)+"空头"+text(sellcc)+"数据库空头"+text(BuyLotsz02)+"错误返回");
                                   return;}

//记录一下,到底是什么东西错误。下午测了30分钟也没有发现问题,毕竟好像3天左右出现一次。
作者: uniwin    时间: 2016-1-29 19:23:12

本帖最后由 uniwin 于 2016-1-29 21:54 编辑

TB 版本 5257 32 位。同时交易10个品种。碰到好几次JD1605空头有持仓,然后数据库键值会莫名清0。 而其它品种,以及多头持仓好象没发现类似问题。
作者: fqxing95    时间: 2016-1-29 21:07:17

uniwin 发表于 2016-1-29 19:23
同时交易10个品种。碰到好几次JD1605空头有持仓,然后数据库键值会莫名清0。 而其它品种,以及多头持仓好象 ...

最近两次也是空头,前面有点忘记了有没有多头出问题。
作者: fqxing95    时间: 2016-2-1 11:37:53

本帖最后由 fqxing95 于 2016-2-1 17:17 编辑

通过输出信息分析,发现我自己读写数据库错误,数据库错误是平仓后数据库持仓数据没有清零。但是判断数据库持仓时前面还有加一个条件判断,而再次交易时,数据库是必须重新写的,好像也不至于造成和实际持仓不符的情况,再观察看看。。。
作者: zxjt10224500    时间: 2016-2-24 09:25:53

今天测试发现,数据库错误和机器运行速度有一定关系,高内存,将内存虚拟成磁盘,然后将tb安装进去,错误率降低很多,但还不能完全不出错。
作者: luyuan126    时间: 2017-4-13 07:25:41

fqxing95 发表于 2016-1-26 00:47
这样问吧:账户实际有持仓,函数A_BuyPosition、A_SellPosition在什么情况下返回值为0 ...

个人卓见:持仓是读取的交易所的数据,网络的原因,丢包引起的
作者: luyuan126    时间: 2017-4-13 07:28:25

网络丢包引起的
作者: hupnos    时间: 2017-6-26 10:15:54

请问频繁读数据库数据发生的读出数据错误后来解决了吗?各位前辈是怎么处理这个问题的?前些天突然就错误把我仓位平掉了,太可怕了!!
作者: ZhJCH1976    时间: 2017-8-5 12:32:02

luyuan126 发表于 2017-4-13 07:25
个人卓见:持仓是读取的交易所的数据,网络的原因,丢包引起的

正解!频繁读取交易服务器数据,会堵塞,尤其是多品种同时进行这样的操作!交易服务器主要是用于交易的!
作者: ZhJCH1976    时间: 2017-10-28 05:55:24

这个问题困扰了很多人,从编程的角度看,尤其是多图表同时读写文件(我用的是setTBProfileString2File 和 GetTBProfileString2File)时,当一个图表还没有运行完整一遍时,其他图表也在读写,造成数据出现混乱,解决的办法是 增加文件读写的锁,就是当一个图表需要读写文件时,先把文件设定为锁定状态,其它图表不能读写,当这个图表读写完时,打开锁定状态,其它图表再读写!
希望TB尽快推出这样锁定函数 和解锁函数!
作者: lcxamm    时间: 2019-11-22 16:50:34

superwin 发表于 2016-1-13 16:22
是的,我也发现了,特别是读写的程序一多,就会出现读写错误,会读写到别的健名上,比如我这里有30个公式( ...

今天遇到这个情况,pta的value读到了ma的值,请问如何加编号标识,只出现了一次,但是市价止盈了8手pta
可以加qq聊聊么




欢迎光临 开拓者期货期权程序化系统交易论坛 (http://bbs.tb18.net/) Powered by Discuz! X2