微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从回测结果中找出每日利润 已知解决方案:片段:

如何解决从回测结果中找出每日利润 已知解决方案:片段:

我在 TRX/USDT(5m 间隔)上进行了回测,并将结果导出到 JSON。然后,我能够计算整个测试期间的累积利润百分比和总利润百分比。我现在想计算每日利润,这在 python (pandas) 中本来是 daily_profit = results.resample('1day',on='close_date')['profit_percent'].sum()。我尝试使用 deedle 做到这一点,但我不确定它是如何工作的。我在下面提供了完整的代码,因此可以对其进行编译和测试。它从我在下面链接的 pastebin 代码获取 JSON 数据。知道如何获得每日利润吗?

我也愿意接受其他解决方案,不仅仅是 deedle

计算每日利润后,以下是一些预期值:

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,DateTimeKind.Utc));

            // Summary on daily basis

            Console.ReadLine();
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。