这有点复杂(至少对我而言)。
以下是我必须做的事情: 假设我有以下数据集:
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的总和值。
答案 0 :(得分: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;
我用你的数据集对它进行了测试,看起来是正确的,但我会仔细检查几个案例以确认它是否正常。
答案 1 :(得分:1)
如果您有一个表示“买入”或“卖出”的变量,那么您可以试试这个。假设这个变量叫做type,取值为'B'或'S'。使用这种方法的一个优点是,如果有的话,更容易处理'by-groups'。
%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;