代码之家  ›  专栏  ›  技术社区  ›  nop

从回溯测试结果中寻找每日利润

  •  0
  • nop  · 技术社区  · 4 年前

    我在TRX/USDT上运行了回溯测试(间隔5m),并将结果导出到JSON。然后我就可以计算整个测试期间的累计利润%和总利润%。我现在要计算每日利润 daily_profit = results.resample('1day', on='close_date')['profit_percent'].sum() pandas ). 我试着用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
    

    代码段:

    我的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, 0, 0, DateTimeKind.Utc));
    
                // Summary on daily basis
    
                Console.ReadLine();
            }
        }
    }
    
    0 回复  |  直到 4 年前
    推荐文章