如何解决从回测结果中找出每日利润 已知解决方案:片段:
我在 TRX/USDT(5m 间隔)上进行了回测,并将结果导出到 JSON。然后,我能够计算整个测试期间的累积利润百分比和总利润百分比。我现在想计算每日利润,这在 python (pandas) 中本来是 daily_profit = results.resample('1day',on='close_date')['profit_percent'].sum()
。我尝试使用 deedle 做到这一点,但我不确定它是如何工作的。我在下面提供了完整的代码,因此可以对其进行编译和测试。它从我在下面链接的 pastebin 代码中获取 JSON 数据。知道如何获得每日利润吗?
计算每日利润后,以下是一些预期值:
daily_profit = results.resample('1d',on='close_date')['profit_percent'].sum()
backtest_worst_day = min(daily_profit) // -0.26123255999999995
backtest_best_day = max(daily_profit) // 0.029468
winning_days = sum(daily_profit > 0) // 11
draw_days = sum(daily_profit == 0) // 0
losing_days = sum(daily_profit < 0) // 20
已知解决方案:
- deedle,例如。 QuantConnect's Lean 正在使用它。
- Resample,aggregate,and interpolate of TimeSeries trend data(@Ashley Davis 的帖子)
- 有更多与 stackoverflow 相关的主题,但我没有找到方法。
片段:
我的 JSON 数据:https://pastebin.com/raw/0bASqR47
using deedle;
using deedle.Math;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
namespace Test
{
class Program
{
public class JsonTimestampConverter : DateTimeConverterBase
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(long) || objectType == typeof(string);
}
public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer)
{
long milliseconds;
if (reader.TokenType == JsonToken.Integer)
{
milliseconds = (long)reader.Value!;
}
else if (reader.TokenType == JsonToken.String)
{
if (!long.TryParse((string)reader.Value!,out milliseconds))
{
throw new JsonSerializationException($"Cannot convert invalid value to {objectType}.");
}
}
else
{
throw new JsonSerializationException($"Unexpected token parsing date. Expected Integer or String,got {reader.TokenType}.");
}
return DateTimeOffset.FromUnixTimeMilliseconds(milliseconds).DateTime;
}
public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer)
{
DateTime utcTime;
if (value is DateTime dateTime)
{
utcTime = DateTime.SpecifyKind(dateTime,DateTimeKind.Utc);
}
else
{
throw new JsonSerializationException("Expected date object value.");
}
writer.WriterawValue($"{((DateTimeOffset)utcTime).ToUnixTimeMilliseconds()}");
}
}
public class BResult
{
[JsonProperty("pair")]
public string Pair { get; set; }
[JsonProperty("profit_percent")]
public decimal ProfitPercentage { get; set; }
[JsonProperty("profit_abs")]
public decimal ProfitAbs { get; set; }
[JsonProperty("open_rate")]
public decimal OpenRate { get; set; }
[JsonProperty("close_rate")]
public decimal CloseRate { get; set; }
[JsonProperty("open_date")]
[JsonConverter(typeof(JsonTimestampConverter))]
public DateTime OpenDate { get; set; }
[JsonProperty("close_date")]
[JsonConverter(typeof(JsonTimestampConverter))]
public DateTime CloseDate { get; set; }
[JsonProperty("open_fee")]
public decimal OpenFee { get; set; }
[JsonProperty("close_fee")]
public decimal CloseFee { get; set; }
[JsonProperty("amount")]
public decimal Amount { get; set; }
[JsonProperty("Trade_duration")]
public decimal TradeDuration { get; set; }
[JsonProperty("open_at_end")]
public bool OpenAtEnd { get; set; }
[JsonProperty("sell_reason")]
public string SellReason { get; set; }
}
static void Main(string[] args)
{
// Take JSON data from pastebin
using var webClient = new WebClient();
var json = webClient.DownloadString("https://pastebin.com/raw/0bASqR47");
// Deserialize the data
var data = JsonConvert.DeserializeObject<List<BResult>>(json);
// Summary
foreach (var result in data.GroupBy(e => e.Pair)
.Select(e => new { Pair = e.Key,Count = e.Count(),Value = e }))
{
var pairsCount = 1;
var key = result.Pair;
var Trades = result.Count;
var profitSum = result.Value.Sum(e => e.ProfitPercentage);
var profitSumPercentage = profitSum * 100;
var profitTotal = profitSum / pairsCount;
var profitTotalPercentage = profitTotal * 100;
Console.WriteLine($"Cumulative Profit %: {profitSumPercentage:f2}% | Total Profit %: {profitTotalPercentage:f2}%");
}
// Create series
var series = data.Select(e => keyvalue.Create(e.CloseDate,e)).ToSeries();
// Resample data
var resampled = series.ResampleEquivalence(dt => new DateTime(dt.Year,dt.Month,dt.Day,dt.Hour,DateTimeKind.Utc));
// Summary on daily basis
Console.ReadLine();
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。