1

我从股票 API 获得以下数据:

0, 0, 0, 1, 0, 4, 71, 79, 79, 71, 0, 0, 0, 0, 4, 68, 93, -17, -65, -67, 82, 68, 95, 5 , 31, >68, 93, 64, 0, 68, 93, -17, -65, -67, -17, -65, -67, 70, -17, -65, -67, 52, -17, -65, -67, >0, 0, 1, 63, -17, -65, -67, 99, 30, 0, 68, 92, -17, -65, -67, -17, -65, - 67, 68, 94, -17, >-65, -67, 0, 68, 91, 81, 72, 68, 94, -17, -65, -67, -17, -65, -67, 70, -17, -65, -67, -17, >-65, -67, 87, 0, 0, 1, 63, -17, -65, -67, -17, -65, -67, 122, 0 , 68, 93, -17, -65, -67, >-17, -65, -67, 68, 94, 74, -17, -65, -67, 68, 91, -17, -65, - 67, 0, 68, 91, -17, -65, -67, >70, 34, 107, 10, 0, 0, 1, 63, -17, -65, -67, -17, -65, - 67, -17, -65, -67, 0, 68, 95, 95, >92, 68, 95, -17, -65, -67, 61, 68, 93, -17, -65, -67, -17, -65, -67, 68, 94, -17, -65, >-67, 0, 70, 127, -17, -65, -67, 0, 0, 1, 63, -17, - 65, -67, -17, -65, -67

这是通过下面的代码成功读取的一段二进制文件,它返回数组 {error=0.0, symbol=GOOG, count=1, bars=4, length=4, bar=[]}:

0, 0, 0, 1, 0, 4, 71, 79, 79, 71, 0, 0, 0, 0, 4

从这一点开始,我一直在苦苦挣扎:

68, 93, -17, -65, -67, 82, 68, 95, 5, 31, >68, 93, 64, 0, 68, 93, -17, -65, -67, -17, -65 , >-67, 70, -17, -65, -67, 52, -17, -65, -67, >0, 0, 1, 63, -17, -65, -67, 99, 30, 0 , 68, 92, >-17, -65, -67, -17, -65, -67, 68, 94, -17, >-65, -67, 0, 68, 91, 81, 72, 68, 94, -17, -65, >-67, -17, -65, -67, 70, -17, -65, -67, -17, >-65, -67, 87, 0, 0, 1, 63, -17, -65, -67, >-17, -65, -67, 122, 0, 68, 93, -17, -65, -67, >-17, -65, -67, 68, 94, 74, -17, -65, -67, >68, 91, -17, -65, -67, 0, 68, 91, -17, -65, -67, >70, 34, 107, 10 , 0, 0, 1, 63, -17, -65, >-67, -17, -65, -67, -17, -65, -67, 0, 68, 95, 95, >92, 68, 95, -17, -65, -67, 61, 68, 93, >-17, -65, -67, -17, -65, -67, 68, 94, -17, -65, >-67, 0, 70, 127, -17, -65, -67, 0, 0, 1, >63, -17, -65, -67, -17, -65, -67

以上是四个“条”代码,包括收盘价、最高价、最低价、开盘价、成交量和时间图。所有这些都是 4 字节浮点数,除了 Volume 是一个长度为 8 的 Long。API 将长度描述为 8 位字节。

我在解析代码的第一位时没有问题(尽管它可能并不完美)。我遇到了其他问题。在 API 网站上,数据的结构如下:

字段类型 长度(8 位字节) 描述


Symbol Count Integer 4 正在为其返回数据的符号数。随后的部分重复了很多次

重复符号数据

Symbol Length Short 2 符号字段的长度

Symbol String 变量 返回历史数据的交易品种

错误代码字节 1 0=OK,1=ERROR

错误长度短 2 仅在错误代码=1 时返回。错误字符串的长度

错误文本字符串变量仅在错误代码=1 时返回。描述错误的字符串

Bar Count Integer 4 # 图表条数;仅当错误代码=0

重复价格数据

close Float 4 high Float 4 low Float 4 open Float 4 volume Float 4(以 100 为单位)时间戳 Long 8 时间,从 1970 年 1 月 1 日 UTC 00:00:00 开始以毫秒为单位

重复价格数据结束

终结符字节 2 0xFF、0XFF

重复符号数据结束 PriceHistory 响应采用二进制格式,由符号、图表数量表示

重复符号数据结束

我能够提取计数、长度、符号、错误代码和条数。但它正在解析我遇到问题的酒吧。我没有得到任何数据,而是像 D]�R9 这样的乱码。

如果你想看看我到目前为止有多糟糕,可以在这里找到代码:):http: //pastebin.com/5eq9XPjT

  for (i=0;i<=dataArray.length;i++) {
if (i<=5) {
  symbolDetails['count'] = Utilities.newBlob(dataArray[0] + dataArray[1] + dataArray[2] + dataArray[3]).getDataAsString(); //Symbol count
  symbolDetails['length'] = Utilities.newBlob(dataArray[4] + dataArray[5]).getDataAsString(); // Length of record
  i=5; // jump ahead
} else if (i>5 && i<6+Number(symbolDetails['length'])) {
  for (j=0;j<Number(symbolDetails['length']);j++) {
    symbolDetails['symbol'][j] = dataArray[i];
    i++
  }
  i = 10;
  Logger.log(symbolDetails['symbol']);
  symbolDetails['symbol'] = Utilities.newBlob(symbolDetails['symbol']).getDataAsString();
  // partTwo is the sequence of data after the symbol. As symbol can be of varying length, this will help us know where we are.
  var partTwo = 5 + Number(symbolDetails['length']);
} else {
  // Get Error Code
  if (i == partTwo) {
    symbolDetails['error'] = Utilities.newBlob(dataArray[i]).getDataAsString();
  } else if (i>= Number(partTwo + 1) && i<=Number(partTwo+5)) {
    // Get Bar Count
    for (j=0;j<4;j++) {
      symbolDetails['bars'] =+ dataArray[i];
      i++;
    }
    symbolDetails['bars'] = Utilities.newBlob(symbolDetails['bars']).getDataAsString();
  }
}

}

希望有人可以帮助解决这个问题。非常感谢。

4

1 回答 1

0

我不完全确定您的数据,但我会假设它是一系列带符号的 8 位值。

首先让我们将其视为十六进制,因为它比有符号值更容易处理:

00 00 00 01 00 04 47 4f 4f 47 00 00 00 00 04 44 5d ef bf bd
52 44 5f 05 1f 44 5d 40 00 44 5d ef bf bd ef bf bd 46 ef bf
bd 34 ef bf bd 00 00 01 3f ef bf bd 63 1e 00 44 5c ef bf bd
ef bf bd 44 5e ef bf bd 00 44 5b 51 48 44 5e ef bf bd ef bf
bd 46 ef bf bd ef bf bd 57 00 00 01 3f ef bf bd ef bf bd 7a
00 44 5d ef bf bd ef bf bd 44 5e 4a ef bf bd 44 5b ef bf bd
00 44 5b ef bf bd 46 22 6b 0a 00 00 01 3f ef bf bd ef bf bd
ef bf bd 00 44 5f 5f 5c 44 5f ef bf bd 3d 44 5d ef bf bd ef
bf bd 44 5e ef bf bd 00 46 7f ef bf bd 00 00 01 3f ef bf bd

让我们按顺序进行:

# Symbol Count = 1
00 00 00 01

# Symbol Length = 4
00 04

# Symbol = 'GOOG'
47 4f 4f 47

# Error Code = 0
00

# Error Length & Error Text are not present since Error Code == 0

# Bar Count = 4
00 00 00 04

现在到问题区域。下一个值是浮点数。具体来说,它是小端格式的浮点数。这个问题可以帮助将字节转换为浮点数。请注意,您的字节顺序与问题中的不同,因此您需要反转字节。

# Close = $887.74
44 5d ef bf

这是一些 Javascript 代码来解码这个值并打印出来。它使用之前引用的 SO 答案的Bytes2Float32功能。

function Bytes2Float32(bytes)
{
    var sign = (bytes & 0x80000000) ? -1 : 1;
    var exponent = ((bytes >> 23) & 0xFF) - 127;
    var significand = (bytes & ~(-1 << 23));

    if (exponent == 128) 
        return sign * ((significand) ? Number.NaN : Number.POSITIVE_INFINITY);

    if (exponent == -127) {
        if (significand == 0) return sign * 0.0;
        exponent = -126;
        significand /= (1 << 22);
    } else significand = (significand | (1 << 23)) / (1 << 23);

    return sign * significand * Math.pow(2, exponent);
}

var bytes = new Array(0x44, 0x5D, 0xEF, 0xBF);
var asInt = (bytes[3] & 0xFF) 
          | ((bytes[2] & 0xFF) << 8)  
          | ((bytes[1] & 0xFF) << 16) 
          | ((bytes[0] & 0xFF) << 24);

write("As Int: " + asInt + "\n");
var asFloat = Bytes2Float32(asInt);
write("Closing Price: " + asFloat);

实际上,这打印出 887.74603,这听起来与 GOOG 收盘价差不多。

您将对高低、开盘和成交量值执行相同的操作(请记住,根据 API 规范将成交量乘以 100)。对于时间戳,它很长,因此将这 8 个字节转换为长并找到正确的 Date API 以将值转换为 Date 对象。

于 2013-07-18T05:08:28.413 回答