2

这有点复杂(至少对我来说很好)。

这是我必须做的:假设我有以下数据集:

date    price   volume
02-Sep  40  100
03-Sep  45  200
04-Sep  46  150
05-Sep  43  300

假设我有一个断点,希望在我的数据集中创建一个区间。例如,让我的断点 = 200 卷交易。

我想要的是创建一个 ID 列并为每个断点 = 200 记录一个 ID 变量 =1,2,3,...。当您对每个 ID 的所有体积求和时,该值必须在所有 ID 变量中保持不变。

因此,使用上面的示例,我的最终数据集应如下所示:

date    price   volume  id
02-Sep  40  100 1
03-Sep  45  100 1
03-Sep  45  100 2
04-Sep  46  100 2
04-Sep  46  50  3
05-Sep  43  150 3
05-Sep  43  150 4 

(最后一行可能会错过一些价值,但这很好。我会踢出最后一个 id)

如您所见,我必须“分解”一些行(例如第二行,我将 200 分成两个 100 卷),以便在所有 ID 中保持总和 200 的恒定值。

4

2 回答 2

4

看起来您正在为流量毒性 VPIN 计算进行体积分桶。我认为这有效:

%let bucketsize = 200;

data buckets(drop=bucket volume rename=(vol=volume));
    set tmp;
    retain bucket &bucketsize id 1;

    do until(volume=0);
        vol=min(volume,bucket);
        output;
        volume=volume-vol;
        bucket=bucket-vol;
        if bucket=0 then do;
            bucket=&bucketsize;
            id=id+1;
        end;
    end;
run;

我用您的数据集对此进行了测试,它看起来正确,但我会仔细检查几个案例以确认它是否正常工作。

于 2012-06-17T00:42:18.070 回答
1

如果您有一个指示“买入”或“卖出”的变量,那么您可以试试这个。假设这个变量被称为类型并取值“B”或“S”。使用此方法的一个优点是更容易处理“按组”(如果有)。

%let bucketsize = 200;

data tmp2;
  set tmp;
  retain volsumb idb volusums ids;

  /* Initialize. */
  volusumb = 0; idb = 1; volsums = 0; ids = 1;

  /* Store the current total for each type. */
  if type = 'B' then volsumb = volsumb + volume;
  else if type = 'S' then volsums = volsums + volume;

  /* If the total has reached 200, then reset and increment id. */
  /* You have not given the algorithm if the volume exceeds 200, for example the first two values are 150 and 75. */
  if volsumb = &bucketsize then do; idb = idb + 1; volsumb = 0; end;
  if volsums = &bucketsize then do; ids = ids + 1; volsums = 0; end;

  drop volsumb volsums;
run;
于 2012-06-18T15:47:35.797 回答