详细的问题和描述如下,主要有两个问题,帮忙解答一下,谢谢,如下:
以下是QuantConnect云平台的代码,而我已经升级为研究院+1个节点的版本。但是有两个问题,第一个问题是我设置的日期是SetStartDate(2024, 8, 5);
SetEndDate(2024, 8, 6);而实际日志输出的是更老的日期,如下1157
|
2:51:53
:
UTC Time: 2024-05-08 23:10:00Z, Local Time: 2024-05-08 23:10:00Z, ETHUSDT - Open: 3000.39, High: 3000.4, Low: 2999.25, Close: 2999.26
1158
|
2:51:53
:
UTC Time: 2024-05-08 23:20:00Z, Local Time: 2024-05-08 23:20:00Z, ETHUSDT - Open: 2988.56, High: 2989.89, Low: 2987.98, Close: 2989.6
1159
|
2:51:53
:
UTC Time: 2024-05-08 23:30:00Z, Local Time: 2024-05-08 23:30:00Z, ETHUSDT - Open: 2993.66, High: 2994.51, Low: 2993.66, Close: 2994.5
1160
|
2:51:53
:
UTC Time: 2024-05-08 23:40:00Z, Local Time: 2024-05-08 23:40:00Z, ETHUSDT - Open: 2999.82, High: 2999.82, Low: 2996.93, Close: 2998.58
1161
|
2:51:53
:
UTC Time: 2024-05-08 23:50:00Z, Local Time: 2024-05-08 23:50:00Z, ETHUSDT - Open: 2998, High: 2998.99, Low: 2997.01, Close: 2997.01
1162
|
2:51:53
:
UTC Time: 2024-05-09 00:00:00Z, Local Time: 2024-05-09 00:00:00Z, ETHUSDT - Open: 2999.8, High: 2999.81, Low: 2997.9, Close: 2997.9
1163
|
2:51:53
:
OnEndOfAlgorithm called
1164
|
2:51:53
:
Total Trades (inside OnEndOfAlgorithm): 0
1165
|
2:51:53
:
Total Profit (inside OnEndOfAlgorithm): 0
1166
|
2:51:53
:
Total Return: 0.00%
1167
|
2:51:53
:
Algorithm Id:(854e32fa35bb032150b05533de736ed1) completed in 0.41 seconds at 7k data points per second. Processing total of 2,996 data points.而另一个问题是即便是我验证当前日志中的开盘价收盘价等都和设置的币安交易所的价格差距很大,完全对不上:#region imports
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Drawing;
using QuantConnect;
using QuantConnect.Algorithm.Framework;
using QuantConnect.Algorithm.Framework.Selection;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Portfolio.SignalExports;
using QuantConnect.Algorithm.Framework.Execution;
using QuantConnect.Algorithm.Framework.Risk;
using QuantConnect.Algorithm.Selection;
using QuantConnect.Api;
using QuantConnect.Parameters;
using QuantConnect.Benchmarks;
using QuantConnect.Brokerages;
using QuantConnect.Configuration;
using QuantConnect.Util;
using QuantConnect.Interfaces;
using QuantConnect.Algorithm;
using QuantConnect.Indicators;
using QuantConnect.Data;
using QuantConnect.Data.Auxiliary;
using QuantConnect.Data.Consolidators;
using QuantConnect.Data.Custom;
using QuantConnect.Data.Custom.IconicTypes;
using QuantConnect.DataSource;
using QuantConnect.Data.Fundamental;
using QuantConnect.Data.Market;
using QuantConnect.Data.Shortable;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Notifications;
using QuantConnect.Orders;
using QuantConnect.Orders.Fees;
using QuantConnect.Orders.Fills;
using QuantConnect.Orders.OptionExercise;
using QuantConnect.Orders.Slippage;
using QuantConnect.Orders.TimeInForces;
using QuantConnect.Python;
using QuantConnect.Scheduling;
using QuantConnect.Securities;
using QuantConnect.Securities.Equity;
using QuantConnect.Securities.Future;
using QuantConnect.Securities.Option;
using QuantConnect.Securities.Positions;
using QuantConnect.Securities.Forex;
using QuantConnect.Securities.Crypto;
using QuantConnect.Securities.CryptoFuture;
using QuantConnect.Securities.Interfaces;
using QuantConnect.Securities.Volatility;
using QuantConnect.Storage;
using QuantConnect.Statistics;
using QCAlgorithmFramework = QuantConnect.Algorithm.QCAlgorithm;
using QCAlgorithmFrameworkBridge = QuantConnect.Algorithm.QCAlgorithm;
#endregion
using QuantConnect;
using QuantConnect.Algorithm;
using QuantConnect.Data.Market;
using QuantConnect.Indicators;
using QuantConnect.Orders;
using QuantConnect.Brokerages;
using System;
using System.Collections.Generic;
public class TechnicalIndicatorsAlgorithm : QCAlgorithm
{
private List<Symbol> symbols;
private Dictionary<Symbol, Dictionary<string, dynamic>> indicators;
private List<string> tradeLog;
private decimal totalProfit;
private int totalTrades;
private decimal initialCash;
private decimal leverage = 1m;
public override void Initialize()
{
SetStartDate(2024, 8, 5);
SetEndDate(2024, 8, 6);
SetCash(100000); // 确保设置足够的初始现金
// 设置经纪商为币安
SetBrokerageModel(BrokerageName.Binance, AccountType.Cash);
tradeLog = new List<string>();
totalProfit = 0;
totalTrades = 0;
initialCash = Portfolio.Cash;
symbols = new List<Symbol>
{
AddCrypto("ETHUSDT", Resolution.Minute).Symbol, // 使用分钟级数据以减少数据量
};
indicators = new Dictionary<Symbol, Dictionary<string, dynamic>>();
foreach (var symbol in symbols)
{
indicators[symbol] = new Dictionary<string, dynamic>
{
{ "ma7", SMA(symbol, 7, Resolution.Minute) },
{ "ma20", SMA(symbol, 20, Resolution.Minute) },
{ "ma60", SMA(symbol, 60, Resolution.Minute) },
{ "ma200", SMA(symbol, 200, Resolution.Minute) },
{ "macd", MACD(symbol, 12, 26, 9, MovingAverageType.Wilders, Resolution.Minute) },
{ "entry_price", 0m },
{ "stop_price", 0m },
{ "quantity", 0 }
};
}
var fiveMinuteConsolidator = new TradeBarConsolidator(TimeSpan.FromMinutes(5));
fiveMinuteConsolidator.DataConsolidated += OnFiveMinuteData;
SubscriptionManager.AddConsolidator("ETHUSDT", fiveMinuteConsolidator);
}
public override void OnData(Slice data)
{
foreach (var symbol in symbols)
{
if (data.Bars.ContainsKey(symbol))
{
var tradeBar = data.Bars[symbol];
var open = tradeBar.Open;
var high = tradeBar.High;
var low = tradeBar.Low;
var close = tradeBar.Close;
var utcTime = Time.ToUniversalTime(); // UTC时间
var localTime = Time.ToLocalTime(); // 本地时间
// 仅在必要时输出日志,避免浏览器消息限速
if (Time.Minute % 10 == 0) // 每10分钟输出一次日志
{
Debug($"UTC Time: {utcTime:u}, Local Time: {localTime:u}, {symbol} - Open: {open}, High: {high}, Low: {low}, Close: {close}");
}
}
}
}
private void OnFiveMinuteData(object sender, TradeBar bar)
{
foreach (var symbol in symbols)
{
if (bar.Symbol != symbol)
continue;
var price = bar.Close;
var symbolIndicators = indicators[symbol];
var ma7 = symbolIndicators["ma7"];
var ma20 = symbolIndicators["ma20"];
var ma60 = symbolIndicators["ma60"];
var ma200 = symbolIndicators["ma200"];
var macd = symbolIndicators["macd"];
if (!ma7.IsReady || !ma20.IsReady || !macd.IsReady)
continue;
if (macd.Current.Value > macd.Signal.Current.Value && ma7.Current.Value > ma20.Current.Value)
{
if (!Portfolio[symbol].Invested)
{
var buyingPower = Portfolio.MarginRemaining * leverage;
var allocation = 0.25m;
var maxOrderValue = buyingPower * allocation;
var orderQuantity = (int)(maxOrderValue / price);
if (orderQuantity > 0 && buyingPower >= orderQuantity * price)
{
SetHoldings(symbol, allocation * leverage);
symbolIndicators["entry_price"] = price;
symbolIndicators["stop_price"] = price * 0.90m;
symbolIndicators["quantity"] = orderQuantity;
LogTrade(symbol, price, "BUY", 0);
}
}
}
else if (Portfolio[symbol].Invested && Portfolio[symbol].Quantity > 0 && macd.Current.Value < macd.Signal.Current.Value && macd.Current.Value < 1.2m)
{
var entryPrice = symbolIndicators["entry_price"];
var quantity = Portfolio[symbol].Quantity;
var profit = (price - entryPrice) * quantity;
totalProfit += profit;
totalTrades++;
LogTrade(symbol, price, "SELL", profit);
Liquidate(symbol);
symbolIndicators["entry_price"] = 0m;
symbolIndicators["stop_price"] = 0m;
symbolIndicators["quantity"] = 0;
}
if (macd.Current.Value < macd.Signal.Current.Value && ma7.Current.Value < ma20.Current.Value && macd.Current.Value < -1.2m)
{
if (!Portfolio[symbol].Invested)
{
var buyingPower = Portfolio.MarginRemaining * leverage;
var allocation = -0.25m;
var maxOrderValue = buyingPower * allocation;
var orderQuantity = (int)(maxOrderValue / price);
if (orderQuantity > 0 && buyingPower >= orderQuantity * price)
{
SetHoldings(symbol, allocation * leverage);
symbolIndicators["entry_price"] = price;
symbolIndicators["stop_price"] = price * 1.10m;
symbolIndicators["quantity"] = orderQuantity;
LogTrade(symbol, price, "SELL SHORT", 0);
}
}
}
else if (Portfolio[symbol].Invested && Portfolio[symbol].Quantity < 0 && macd.Current.Value > macd.Signal.Current.Value && macd.Current.Value > 1.2m)
{
var entryPrice = symbolIndicators["entry_price"];
var quantity = Portfolio[symbol].Quantity;
var profit = (entryPrice - price) * Math.Abs(quantity);
totalProfit += profit;
totalTrades++;
LogTrade(symbol, price, "COVER SHORT", profit);
Liquidate(symbol);
symbolIndicators["entry_price"] = 0m;
symbolIndicators["stop_price"] = 0m;
symbolIndicators["quantity"] = 0;
}
if (Portfolio[symbol].Invested && symbolIndicators["entry_price"] != 0m)
{
var entryPrice = symbolIndicators["entry_price"];
var stopPrice = symbolIndicators["stop_price"];
if ((Portfolio[symbol].Quantity > 0 && price < stopPrice) ||
(Portfolio[symbol].Quantity < 0 && price > stopPrice))
{
var quantity = Portfolio[symbol].Quantity;
var profit = (price - entryPrice) * Math.Abs(quantity);
totalProfit += profit;
totalTrades++;
LogTrade(symbol, price, "STOP-LOSS", profit);
Liquidate(symbol);
symbolIndicators["entry_price"] = 0m;
symbolIndicators["stop_price"] = 0m;
symbolIndicators["quantity"] = 0;
}
}
}
}
private void LogTrade(Symbol symbol, decimal price, string action, decimal profit)
{
var utcTime = Time.ToUniversalTime().ToString("u");
var localTime = Time.ToLocalTime().ToString("u"); // 将UTC时间转换为本地时间
var log = $"{localTime} - {action} {symbol} at {price}, Profit: {profit}, UTC Time: {utcTime}";
tradeLog.Add(log);
// 减少日志输出
if (Time.Minute % 10 == 0) // 每10分钟输出一次日志
{
//Debug(log);
}
}
public override void OnEndOfAlgorithm()
{
Debug("OnEndOfAlgorithm called");
foreach (var log in tradeLog)
{
//Debug(log);
}
Debug($"Total Trades (inside OnEndOfAlgorithm): {totalTrades}");
Debug($"Total Profit (inside OnEndOfAlgorithm): {totalProfit}");
decimal totalReturn = (Portfolio.TotalPortfolioValue - initialCash) / initialCash;
Debug($"Total Return: {totalReturn * 100}%");
}
}
请基于以上两个问题,帮我提供解决方案,非常感谢!
Louis Szeto
Hi Az131476
We cannot reproduce your first issue. The log looks normal to me.
For your second issue, there could be several reasons:
Best
Louis
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Az131476
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!