docker files fixes from liaqat
This commit is contained in:
251
src/Managing.Application.Tests/ProfitAndLossTests.cs
Normal file
251
src/Managing.Application.Tests/ProfitAndLossTests.cs
Normal file
@@ -0,0 +1,251 @@
|
||||
using Managing.Domain.Trades;
|
||||
using Xunit;
|
||||
using static Managing.Common.Enums;
|
||||
|
||||
namespace Managing.Application.Tests
|
||||
{
|
||||
public class ProfitAndLossTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(1, 100, 110, 10)]
|
||||
[InlineData(2, 100, 110, 20)]
|
||||
public void Should_Return_Correct_ProfitAndLoss_Amount(decimal quantity, decimal price, decimal exitPrice, decimal expectedResult)
|
||||
{
|
||||
// Arrange
|
||||
var init = new List<Tuple<decimal, decimal>>();
|
||||
init.Add(new Tuple<decimal, decimal>(quantity, price));
|
||||
|
||||
var pnl = new ProfitAndLoss(init, TradeDirection.Long);
|
||||
|
||||
// Act
|
||||
var result = pnl.FloatingForTheoriticalExit(exitPrice);
|
||||
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedResult, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Correct_Pnl_For_Short_failed_Position_After_Took_One_Profit()
|
||||
{
|
||||
// Arrange
|
||||
var position = GetFakeShortPosition();
|
||||
|
||||
// Setup Open and first take profit
|
||||
var orders = new List<Tuple<decimal, decimal>>
|
||||
{
|
||||
new Tuple<decimal, decimal>(position.Open.Quantity, position.Open.Price),
|
||||
new Tuple<decimal, decimal>(-position.TakeProfit1.Quantity, position.TakeProfit1.Price)
|
||||
};
|
||||
|
||||
// Act
|
||||
position.ProfitAndLoss = new ProfitAndLoss(orders, position.OriginDirection);
|
||||
|
||||
// Trigger Stop Loss
|
||||
position.ProfitAndLoss.AddFill(-position.TakeProfit2.Quantity, position.StopLoss.Price, position.OriginDirection);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(20, position.ProfitAndLoss.Realized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Correct_Pnl_For_Long_Solana_failed_Position_After_Took_One_Profit()
|
||||
{
|
||||
// Arrange
|
||||
var position = GetSolanaLongPosition();
|
||||
|
||||
// Setup Open and first take profit
|
||||
var orders = new List<Tuple<decimal, decimal>>
|
||||
{
|
||||
new Tuple<decimal, decimal>(position.Open.Quantity, position.Open.Price),
|
||||
new Tuple<decimal, decimal>(-position.TakeProfit1.Quantity, position.TakeProfit1.Price)
|
||||
};
|
||||
|
||||
// Act
|
||||
position.ProfitAndLoss = new ProfitAndLoss(orders, position.OriginDirection);
|
||||
|
||||
// Trigger Stop Loss
|
||||
position.ProfitAndLoss.AddFill(-position.TakeProfit2.Quantity, position.StopLoss.Price, position.OriginDirection);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(3.97005582759999752M, position.ProfitAndLoss.Realized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Correct_Pnl_For_Long_Solana_failed_Position_After_Took_One_Profit2()
|
||||
{
|
||||
// Arrange
|
||||
var position = GetSolanaLongPosition();
|
||||
|
||||
// Setup Open and first take profit
|
||||
var orders = new List<Tuple<decimal, decimal>>
|
||||
{
|
||||
new Tuple<decimal, decimal>(position.Open.Quantity, position.Open.Price),
|
||||
new Tuple<decimal, decimal>(-position.TakeProfit1.Quantity, position.TakeProfit1.Price),
|
||||
new Tuple<decimal, decimal>(-position.TakeProfit2.Quantity, position.StopLoss.Price)
|
||||
};
|
||||
|
||||
// Act
|
||||
position.ProfitAndLoss = new ProfitAndLoss(orders, position.OriginDirection);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(3.97005582759999752M, position.ProfitAndLoss.Realized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Correct_Pnl_For_Short_failed_Position_After_Took_One_Profit2()
|
||||
{
|
||||
// Arrange
|
||||
var position = GetFakeShortPosition();
|
||||
|
||||
// Setup Open and first take profit
|
||||
var orders = new List<Tuple<decimal, decimal>>
|
||||
{
|
||||
new Tuple<decimal, decimal>(position.Open.Quantity, position.Open.Price),
|
||||
new Tuple<decimal, decimal>(-position.TakeProfit1.Quantity, position.TakeProfit1.Price),
|
||||
new Tuple<decimal, decimal>(-position.TakeProfit2.Quantity, position.StopLoss.Price)
|
||||
};
|
||||
|
||||
// Act
|
||||
position.ProfitAndLoss = new ProfitAndLoss(orders, position.OriginDirection);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(20, position.ProfitAndLoss.Realized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Correct_Pnl_For_Short_failed_Position_After_Took_One_Profit3()
|
||||
{
|
||||
// Arrange
|
||||
var position = GetFakeShortPosition();
|
||||
|
||||
// Setup Open and first take profit
|
||||
var orders = new List<Tuple<decimal, decimal>>
|
||||
{
|
||||
new Tuple<decimal, decimal>(position.Open.Quantity, position.Open.Price)
|
||||
};
|
||||
|
||||
// Act
|
||||
position.ProfitAndLoss = new ProfitAndLoss(orders, position.OriginDirection);
|
||||
position.ProfitAndLoss.AddFill(-position.TakeProfit1.Quantity, position.TakeProfit1.Price, TradeDirection.Short);
|
||||
position.ProfitAndLoss.AddFill(-position.TakeProfit2.Quantity, position.StopLoss.Price, TradeDirection.Short);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(20, position.ProfitAndLoss.Realized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Correct_Pnl_For_Short_Succeeded_Position_After_Two_Take_Profit()
|
||||
{
|
||||
// Arrange
|
||||
var position = GetFakeShortPosition();
|
||||
|
||||
// Setup Open and first take profit
|
||||
var orders = new List<Tuple<decimal, decimal>>
|
||||
{
|
||||
new Tuple<decimal, decimal>(position.Open.Quantity, position.Open.Price),
|
||||
new Tuple<decimal, decimal>(-position.TakeProfit1.Quantity, position.TakeProfit1.Price)
|
||||
};
|
||||
|
||||
// Act
|
||||
position.ProfitAndLoss = new ProfitAndLoss(orders, position.OriginDirection);
|
||||
|
||||
// Trigger Stop Loss
|
||||
position.ProfitAndLoss.AddFill(-position.TakeProfit2.Quantity, position.TakeProfit2.Price, TradeDirection.Short);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(120, position.ProfitAndLoss.Realized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Correct_Pnl_For_Long_failed_Position_After_Took_One_Profit()
|
||||
{
|
||||
// Arrange
|
||||
var position = GetFakeLongPosition();
|
||||
|
||||
// Setup Open and first take profit
|
||||
var orders = new List<Tuple<decimal, decimal>>
|
||||
{
|
||||
new Tuple<decimal, decimal>(position.Open.Quantity, position.Open.Price),
|
||||
new Tuple<decimal, decimal>(-position.TakeProfit1.Quantity, position.TakeProfit1.Price)
|
||||
};
|
||||
|
||||
// Act
|
||||
position.ProfitAndLoss = new ProfitAndLoss(orders, position.OriginDirection);
|
||||
|
||||
// Trigger Stop Loss
|
||||
position.ProfitAndLoss.AddFill(-position.TakeProfit2.Quantity, position.StopLoss.Price, TradeDirection.Long);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(20, position.ProfitAndLoss.Realized);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Should_Return_Correct_Pnl_For_Long_Succeeded_Position_After_Two_Take_Profit()
|
||||
{
|
||||
// Arrange
|
||||
var position = GetFakeLongPosition();
|
||||
|
||||
// Setup Open and first take profit
|
||||
var orders = new List<Tuple<decimal, decimal>>
|
||||
{
|
||||
new Tuple<decimal, decimal>(position.Open.Quantity, position.Open.Price),
|
||||
new Tuple<decimal, decimal>(-position.TakeProfit1.Quantity, position.TakeProfit1.Price)
|
||||
};
|
||||
|
||||
// Act
|
||||
position.ProfitAndLoss = new ProfitAndLoss(orders, position.OriginDirection);
|
||||
|
||||
// Trigger Stop Loss
|
||||
position.ProfitAndLoss.AddFill(-position.TakeProfit2.Quantity, position.TakeProfit2.Price, TradeDirection.Long);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(120, position.ProfitAndLoss.Realized);
|
||||
}
|
||||
|
||||
private static Position GetFakeShortPosition()
|
||||
{
|
||||
return new Position("FakeAccount", TradeDirection.Short, Ticker.BTC, null, PositionInitiator.PaperTrading, DateTime.UtcNow)
|
||||
{
|
||||
Open = new Trade(DateTime.Now, TradeDirection.Short, TradeStatus.Filled,
|
||||
TradeType.Market, Ticker.ADA, 10, 100, 1, "OpenOrderId", ""),
|
||||
StopLoss = new Trade(DateTime.Now, TradeDirection.Long, TradeStatus.PendingOpen,
|
||||
TradeType.StopMarket, Ticker.ADA, 10, 110, 1, "StopLossOrderId", ""),
|
||||
TakeProfit1 = new Trade(DateTime.Now, TradeDirection.Long, TradeStatus.PendingOpen,
|
||||
TradeType.TakeProfitLimit, Ticker.ADA, 6, 90, 1, "TakeProfit1OrderId", ""),
|
||||
TakeProfit2 = new Trade(DateTime.Now, TradeDirection.Long, TradeStatus.PendingOpen,
|
||||
TradeType.TakeProfitLimit, Ticker.ADA, 4, 85, 1, "TakeProfit1OrderId", "")
|
||||
};
|
||||
}
|
||||
|
||||
private static Position GetSolanaLongPosition()
|
||||
{
|
||||
return new Position("FakeAccount", TradeDirection.Long, Ticker.BTC, null, PositionInitiator.PaperTrading, DateTime.UtcNow)
|
||||
{
|
||||
Open = new Trade(DateTime.Now, TradeDirection.Long, TradeStatus.Filled,
|
||||
TradeType.Market, Ticker.ADA, (decimal)6.0800904000245037980887037491, (decimal)81.6200, 1, "OpenOrderId", ""),
|
||||
StopLoss = new Trade(DateTime.Now, TradeDirection.Short, TradeStatus.PendingOpen,
|
||||
TradeType.StopMarket, Ticker.ADA, (decimal)3.6480542400147022788532222495, (decimal)79.987600, 1, "StopLossOrderId", ""),
|
||||
TakeProfit1 = new Trade(DateTime.Now, TradeDirection.Short, TradeStatus.PendingOpen,
|
||||
TradeType.TakeProfitLimit, Ticker.ADA, (decimal)2.4320361600098015192354814996, (decimal)85.701000, 1, "TakeProfit1OrderId", ""),
|
||||
TakeProfit2 = new Trade(DateTime.Now, TradeDirection.Short, TradeStatus.PendingOpen,
|
||||
TradeType.TakeProfitLimit, Ticker.ADA, (decimal)3.6480542400147022788532222495, (decimal)89.782000, 1, "TakeProfit1OrderId", "")
|
||||
};
|
||||
}
|
||||
|
||||
private static Position GetFakeLongPosition()
|
||||
{
|
||||
return new Position("FakeAccount", TradeDirection.Long, Ticker.BTC, null, PositionInitiator.PaperTrading, DateTime.UtcNow)
|
||||
{
|
||||
Open = new Trade(DateTime.Now, TradeDirection.Short, TradeStatus.Filled,
|
||||
TradeType.Market, Ticker.ADA, 10, 100, 1, "OpenOrderId", ""),
|
||||
StopLoss = new Trade(DateTime.Now, TradeDirection.Long, TradeStatus.PendingOpen,
|
||||
TradeType.StopMarket, Ticker.ADA, 10, 90, 1, "StopLossOrderId", ""),
|
||||
TakeProfit1 = new Trade(DateTime.Now, TradeDirection.Long, TradeStatus.PendingOpen,
|
||||
TradeType.TakeProfitLimit, Ticker.ADA, 6, 110, 1, "TakeProfit1OrderId", ""),
|
||||
TakeProfit2 = new Trade(DateTime.Now, TradeDirection.Long, TradeStatus.PendingOpen,
|
||||
TradeType.TakeProfitLimit, Ticker.ADA, 4, 115, 1, "TakeProfit1OrderId", "")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user