Skip to content

Commit 72eadfc

Browse files
author
EarnForex
authored
1.11
Fixed incorrect commission calculation when broker uses a percentage value for a given trading instrument.
1 parent 0a87748 commit 72eadfc

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

PositionSizer/PositionSizer/Model/Main/Model.cs

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public interface IModelResources
1313
bool InputSurpassBrokerMaxPositionSizeWithMultipleTrades { get; }
1414
//--
1515
Symbol Symbol { get; }
16+
Symbols Symbols { get; }
17+
Assets Assets { get; }
1618
Positions Positions { get; }
1719
TimeFrame TimeFrame { get; }
1820
PendingOrders PendingOrders { get; }
@@ -34,6 +36,8 @@ public partial class Model : IModel
3436
private TimeFrame TimeFrame => _resources.TimeFrame;
3537
private PendingOrders PendingOrders => _resources.PendingOrders;
3638
private Symbol Symbol => _resources.Symbol;
39+
private Symbols Symbols => _resources.Symbols;
40+
private Assets Assets => _resources.Assets;
3741

3842
public Model(IModelResources resources)
3943
{
@@ -245,14 +249,40 @@ public double CommissionFromVolume()
245249

246250
public double StandardCommission()
247251
{
248-
return Symbol.CommissionType switch
252+
//regardless of the commission type, we must return commission per 1 lot
253+
254+
var usdAsset = Assets.GetAsset("USD");
255+
var baseAsset = Symbol.BaseAsset;
256+
var accountAsset = Account.Asset;
257+
258+
if (Symbol.CommissionType == SymbolCommissionType.UsdPerMillionUsdVolume)
249259
{
250-
SymbolCommissionType.UsdPerMillionUsdVolume => Symbol.Commission / 1_000_000,
251-
SymbolCommissionType.UsdPerOneLot => Symbol.Commission,
252-
SymbolCommissionType.PercentageOfTradingVolume => TradeSize.Volume * Symbol.Commission / 100,
253-
SymbolCommissionType.QuoteCurrencyPerOneLot => Symbol.Commission * Symbol.PipValue,
254-
_ => throw new ArgumentOutOfRangeException()
255-
};
260+
var lotSizeOfBaseAssetInAccountCurrency = baseAsset.Convert(accountAsset, Symbol.LotSize);
261+
var commissionPerLotInAccountCurrency = Symbol.Commission / 1_000_000.0 * lotSizeOfBaseAssetInAccountCurrency;
262+
263+
return commissionPerLotInAccountCurrency;
264+
}
265+
266+
if (Symbol.CommissionType == SymbolCommissionType.UsdPerOneLot)
267+
{
268+
return usdAsset.Convert(accountAsset, Symbol.Commission);
269+
}
270+
271+
if (Symbol.CommissionType == SymbolCommissionType.QuoteCurrencyPerOneLot)
272+
{
273+
//example if it's EUR/JPY, then the quote currency is JPY
274+
//the commission is in JPY per 1 lot
275+
//we need to convert it to account currency
276+
277+
return usdAsset.Convert(Symbol.QuoteAsset, Symbol.Commission);
278+
}
279+
280+
if (Symbol.CommissionType == SymbolCommissionType.PercentageOfTradingVolume)
281+
{
282+
return -1;
283+
}
284+
285+
throw new Exception("Unknown commission type");
256286
}
257287

258288
//Use stringBuilder, a new line for every property that has a getter and setter

PositionSizer/PositionSizer/PositionSizer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public partial class PositionSizer : Robot,
2626
public event EventHandler TimerEvent;
2727
public event EventHandler StopEvent;
2828
public IModel Model { get; set; }
29-
public const string Version = "v1.09";
29+
public const string Version = "v1.11";
3030
public CustomStyle CustomStyle { get; private set; }
3131
public BreakEven BreakEven { get; private set; }
3232
public TrailingStop TrailingStop { get; private set; }

0 commit comments

Comments
 (0)