-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #32 from alexpung/FutureContractSupport
Future contract support
- Loading branch information
Showing
40 changed files
with
968 additions
and
442 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
BlazorApp-Investment Tax Calculator/Enum/FuturePositionType.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace Enum; | ||
|
||
public enum FuturePositionType | ||
{ | ||
OPENLONG, | ||
OPENSHORT, | ||
CLOSELONG, | ||
CLOSESHORT | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
BlazorApp-Investment Tax Calculator/Model/Interfaces/IChangeTradeMatchingInBetween.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
using Model.UkTaxModel; | ||
using Model.UkTaxModel.Stocks; | ||
|
||
namespace Model.Interfaces; | ||
|
||
|
13 changes: 7 additions & 6 deletions
13
BlazorApp-Investment Tax Calculator/Model/Interfaces/ITradeTaxCalculation.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,24 @@ | ||
using Enum; | ||
|
||
using Model.TaxEvents; | ||
using Model.UkTaxModel; | ||
using Model.UkTaxModel.Stocks; | ||
|
||
namespace Model.Interfaces; | ||
public interface ITradeTaxCalculation : ITextFilePrintable, IAssetDatedEvent | ||
{ | ||
TradeType BuySell { get; init; } | ||
bool CalculationCompleted { get; } | ||
List<TradeMatch> MatchHistory { get; init; } | ||
WrappedMoney TotalNetMoneyPaidOrReceived { get; } | ||
WrappedMoney TotalCostOrProceed { get; } | ||
decimal TotalQty { get; } | ||
List<Trade> TradeList { get; init; } | ||
WrappedMoney UnmatchedNetMoneyPaidOrReceived { get; } | ||
WrappedMoney UnmatchedCostOrProceed { get; } | ||
decimal UnmatchedQty { get; } | ||
WrappedMoney TotalProceeds { get; } | ||
WrappedMoney TotalAllowableCost { get; } | ||
WrappedMoney Gain { get; } | ||
WrappedMoney GetNetAmount(decimal qty) => TotalNetMoneyPaidOrReceived / TotalQty * qty; | ||
|
||
(decimal matchedQty, WrappedMoney matchedValue) MatchAll(); | ||
(decimal matchedQty, WrappedMoney matchedValue) MatchQty(decimal demandedQty); | ||
WrappedMoney GetProportionedCostOrProceed(decimal qty) => TotalCostOrProceed / TotalQty * qty; | ||
void MatchWithSection104(UkSection104 ukSection104); | ||
void MatchQty(decimal demandedQty); | ||
} |
26 changes: 26 additions & 0 deletions
26
BlazorApp-Investment Tax Calculator/Model/TaxEvents/FutureContractTrade.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 0 additions & 15 deletions
15
BlazorApp-Investment Tax Calculator/Model/UkTaxModel/FutureTraceTaxCalculation.cs
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
BlazorApp-Investment Tax Calculator/Model/UkTaxModel/Futures/FutureTradeTaxCalculation.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
using Enum; | ||
|
||
using Model.UkTaxModel.Stocks; | ||
|
||
using TaxEvents; | ||
|
||
namespace Model.UkTaxModel.Futures; | ||
|
||
public class FutureTradeTaxCalculation : TradeTaxCalculation | ||
{ | ||
public override TradeType BuySell => PositionType is FuturePositionType.OPENLONG or FuturePositionType.OPENSHORT ? TradeType.BUY : TradeType.SELL; | ||
public FuturePositionType PositionType => ((FutureContractTrade)TradeList[0]).FuturePositionType; | ||
public WrappedMoney TotalContractValue { get; private set; } | ||
public decimal ContractFxRate { get; private init; } | ||
public WrappedMoney UnmatchedContractValue { get; private set; } | ||
public WrappedMoney GetProportionedContractValue(decimal qty) => TotalContractValue * qty / TotalQty; | ||
public FutureTradeTaxCalculation(IEnumerable<FutureContractTrade> trades) : base(trades) | ||
{ | ||
TotalContractValue = trades.Sum(trade => trade.ContractValue.Amount); | ||
ContractFxRate = trades.First().ContractValue.FxRate; | ||
UnmatchedContractValue = TotalContractValue; | ||
// This special case require modification as Future contract start from 0 cost | ||
// normally commission are deducted from money received in a sell trade | ||
// In case of open short is a buy trade and TotalCostOrProceed is cost of getting the contract commissions are added instead | ||
// The opposite is true for CLOSELONG | ||
if (PositionType is FuturePositionType.OPENSHORT or FuturePositionType.CLOSELONG) | ||
{ | ||
TotalCostOrProceed *= -1; | ||
UnmatchedCostOrProceed *= -1; | ||
} | ||
} | ||
|
||
public override void MatchQty(decimal demandedQty) | ||
{ | ||
base.MatchQty(demandedQty); | ||
UnmatchedContractValue -= TotalContractValue * demandedQty / TotalQty; | ||
} | ||
|
||
public override void MatchWithSection104(UkSection104 ukSection104) | ||
{ | ||
if (BuySell is TradeType.BUY) | ||
{ | ||
Section104History section104History = ukSection104.AddAssets(this, UnmatchedQty, UnmatchedCostOrProceed, UnmatchedContractValue); | ||
MatchHistory.Add(TradeMatch.CreateSection104Match(UnmatchedQty, UnmatchedCostOrProceed, WrappedMoney.GetBaseCurrencyZero(), section104History)); | ||
MatchQty(UnmatchedQty); | ||
} | ||
else if (BuySell is TradeType.SELL) | ||
{ | ||
if (ukSection104.Quantity == 0m) return; | ||
decimal matchQty = Math.Min(UnmatchedQty, ukSection104.Quantity); | ||
Section104History section104History = ukSection104.RemoveAssets(this, UnmatchedQty); | ||
WrappedMoney contractGain = GetProportionedContractValue(matchQty) + section104History.ContractValueChange; | ||
WrappedMoney contractGainInBaseCurrency = new((contractGain * ContractFxRate).Amount); | ||
WrappedMoney acquisitionValue = (section104History.ValueChange * -1) + GetProportionedCostOrProceed(matchQty); | ||
WrappedMoney disposalValue = WrappedMoney.GetBaseCurrencyZero(); | ||
if (contractGainInBaseCurrency.Amount > 0) | ||
{ | ||
disposalValue += contractGainInBaseCurrency; | ||
} | ||
else | ||
{ | ||
acquisitionValue += contractGainInBaseCurrency * -1; | ||
} | ||
MatchHistory.Add(TradeMatch.CreateSection104Match(matchQty, acquisitionValue, disposalValue, section104History)); | ||
MatchQty(matchQty); | ||
} | ||
} | ||
} |
Oops, something went wrong.