将记录附加到 csv 文件的批处理脚本

将记录附加到 csv 文件的批处理脚本

我有一堆以 csv 格式保存的股票数据,用于回测交易策略。问题是,如果昨天发现信号,我的策略会以开盘价买入,不幸的是,我的数据仅在当天结束时发布,这意味着直到数据发布后市场收盘时我才知道是否应该进行交易。但由于我的策略仅基于昨天的数据进行交易,我认为一种解决方法是简单地将一条记录附加到代表下一个交易日的数据末尾,并将当天的价格显示为昨天的收盘价,以免影响利润损失。例如,我的一个 csv 看起来像这样(虽然不是这种格式,但实际文件没有标题并且以逗号分隔)

Date     |   Open  |   High  |   Low   |   Close  |  Volume  |
20121228 |  12.23  |  12.80  |  12.23  |   12.60  |  129690  |
20121231 |  13.16  |  13.20  |  12.83  |   13.10  |  141290  |
20130102 |  13.03  |  13.42  |  12.97  |   13.23  |  112390  |
20130103 |  13.23  |  13.80  |  12.23  |   12.60  |  100990  |
20130104 |  12.83  |  12.84  |  12.23  |   12.40  |   89690  |

我想附加以下记录:

20130105 |  12.40  |  12.40  |  12.40  |   12.40  |   89690  |

因此我需要将日期增加 1,然后将之前的收盘价复制到其他定价字段,我认为最好保持交易量不变。这将每天循环遍历文件夹,以便向所有文件添加虚拟字段,这样我就可以更及时地获取信号。然后在每天结束时,我都会有另一个批处理文件,我已经在处理它来清除我的数据文件夹并用真实的定价数据覆盖。

答案1

这可能比您想象的要容易,或者我可能过度简化了您的需求,但我读了您的问题,因为您想将 CSV 文件附加到现有文件,并且在 Windows 和大多数命令 shell 系统上,命令将如下所示:

类型UNIX、LINUX 和 OSX 上的 cat 新WCSV文件名>>现有CSV文件

这是命令,但是由于您还要为这些数据付费,因此需要遵循一定的方法。作为交易员,您已经有一些备份 PC 数据的方法,但我鼓励您保留原始数据,因此在大多数 Windows PC 上以批处理文件的形式尝试将这一系列命令保存为批处理文件:

@echo off

title=Pricing Data Appender executed on %date% at %time% by %username%

copy **EXISTINGCSVFILE** **EXISTINGCSVFILE.%date%_bak** && attrib +r **EXISTINGCSVFILE.%date%_bak**

type *cat on UNIX, LINUX and OSX* **NEWCSVFILENAME** >> **EXISTINGCSVFILE*

title=Pricing Data Appender COMPLETED on %date% at %time% by %username%

这样,在编辑现有定价数据库之前,就会对其进行备份,并作为一种次要的保护措施,将其设置为只读属性,至少在最坏的情况下发出警告,不要删除该文件,并从您的 shell 和各种实用程序中保护它免遭删除。

如果您受到 SarBox 或任何其他法规的约束,甚至包括影响小型精品交易商的法规,还有一些其他命令将按照 SarbaneOxley 第 404 条和多德 - 弗兰克法案职责分离条款的要求,在您的系统事件日志中记录该过程的独立条目。

我有兴趣提供更多帮助,所以如果您需要详细说明或者想要测试并确认/调试,今天是让我知道的好日子。

答案2

如果数据.csv包含:

20121228,12.23,12.80,12.23,12.60,129690
20121231,13.16,13.20,12.83,13.10,141290
20130102,13.03,13.42,12.97,13.23,112390
20130103,13.23,13.80,12.23,12.60,100990
20130104,12.83,12.84,12.23,12.40,89690

并且您希望在每次运行脚本时将以下行附加到其中:

20130117,12.40,12.40,12.40,12.40,89690

(IE ”当前日期 (YYYYMMDD),前收盘价,前收盘价,前收盘价,前收盘价,前成交量“)

尝试保存如下内容更新程序

@echo off
for /f "usebackq tokens=1,5,6 delims=," %%i in (Data.csv) do (
    REM set /a date=%%i+1 // Wrong way to increment a date!
    set close=%%j
    set volume=%%k
)
echo %date:~6%%date:~3,2%%date:~0,2%,%close%,%close%,%close%,%close%,%volume%>>Data.csv

如果要在目录中对多个 CSV 运行此操作,请将两个实例都替换为数据.csv以上%1.现在更新单个文件,即数据.csv,你可以使用以下命令:

update Data.csv

要更新多个 CSV,您可以使用以下命令:

for %f in (*.csv) do @update "%f"

注释1:确切的日期格式取决于您在地区和语言控制面板小程序。请参阅这里了解详情。

笔记2:我认为日期递增和验证逻辑(包括闰年计算等)可以也可以批量实施(是的,也许如果有人拿枪指着我的头!),但那时我会开始怀疑提问者的理智(除了怀疑我自己的理智),严重地建议一个更好的(读实际的) 编程语言来实现这一点。

答案3

如果您熟悉 C++,那么您可能可以处理一些 C#。

没有错误检查,它会在不备份的情况下更改您的 csv 文件,并且如果 csv 文件很大,那么它不是特别高效(因为它将整个文件读入内存),但应该给您一个大概的概念。

如果您拥有 Windows 7,那么您应该已经拥有 dotnet 框架,因此您可以将其复制到文件中并使用 csc filename.cs 从命令行进行编译,它应该会生成 filename.exe。

using System.Collections.Generic;
using System;
using System.Linq;

public class Sample
{

    public static void Main()
    {
        string path = @"c:\temp\temp.csv";

        var lines     = System.IO.File.ReadAllLines(path).ToList();
        var lastLine = lines[lines.Count-1];
        var sections = lastLine.Split(new char[] { ','});

        DateTime lastDate = DateTime.ParseExact(sections[0], "yyyyMMdd" , null );
        DateTime newDate  = lastDate.AddDays(1);
        string newLine    = String.Format("{0},{1},{1},{1},{1},{2}", 
                    newDate.ToString("yyyyMMdd"), sections[4] , sections[5]);
        lines.Add(newLine);

        System.IO.File.WriteAllLines(path, lines.ToArray());

    }

}

不过,由于你需要做一些编辑,我建议你下载林克帕德然后将主要方法复制到其中(并选择 C# 程序)并点击运行,它将编译并运行它。

答案4

如果您运行的是 Windows 7(问题标签表明了这一点),那么使用 powershell 可以更轻松地实现这一点。尝试查看Import-CsvExport-Csv命令(后者有一个-Append非常有用的参数。

如果您愿意,请查看命令文档:

导入-Csv:https://technet.microsoft.com/en-us/library/ee176874.aspx

导出-CSV:https://technet.microsoft.com/pt-br/library/ee176825.aspx

它会是这样的:

$Path = "C:\PathToFile"
$Objects = Import-Csv $Path
# Here $Objects will be an array of objects, which you can access its 
# properties by the same name in the header of your csv
# you can then do whatever you want in the list:
foreach ($Object in $Objects){
    $Object.Date = $SomeDate
}
# or you can add a new object to the list
$NewObject = [pscustomobject]@{
     Date = Get-Date;
     Open = "12.58";
}
$Objects += $NewObject
# and then finally save it with:
$Objects | Export-csv $Path -Force -NoTypeInformation
# Alternatively, you can add just the object at the end with append, like this
$NewObject | Export-Csv $Path -Append

相关内容