Is there a way to obtain the Intraday Margin for a particular Instrument via Ninjascript?
I am currently trying to edit my current strategy with the ability to limit how many contracts I can use. I would like to further limit this by accessing the amount of Cash Value my account has, and dividing that by the amount of that instrument’s Intraday Margin, to give the total max Contracts I could potentially trade. Trading any more, of course would create an error, as you are exceeding the amount of margin you can have.
Is there a way to access this via Ninjascript? I’d rather not deal with trying to hardcode it, with the possibility of it changing, or the need to hardcode every single instrument I intend to use.
1 Like
Here’s sample strategy code. If you run it it will produce this output:
using System;
using System.Linq;
using NinjaTrader.Cbi;
namespace NinjaTrader.NinjaScript.Strategies.Studies
{
public class StudiesIntradayMargin : Strategy
{
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Name = "Studies - Intraday Margin";
}
else if (State == State.DataLoaded)
{
Risk risk = GetRisk();
if (risk != null)
{
Instrument n = Instruments[0];
var instrumentRisk = risk.ByMasterInstrument[n.MasterInstrument];
if (n.MasterInstrument.InstrumentType == InstrumentType.Future)
{
Print($"Symbol={n.FullName}, InitialMargin={instrumentRisk.InitialMargin}");
Print($"Symbol={n.FullName}, BuyIntradayMargin={instrumentRisk.BuyIntradayMargin}");
Print($"Symbol={n.FullName}, SellIntradayMargin={instrumentRisk.SellIntradayMargin}");
Print($"Symbol={n.FullName}, MaintenanceMargin={instrumentRisk.MaintenanceMargin}");
Print($"Symbol={n.FullName}, MaxOrderSize={instrumentRisk.MaxOrderSize}");
Print($"Symbol={n.FullName}, MaxPositionSize={instrumentRisk.MaxPositionSize}");
}
}
else
{
throw new Exception("No risk template found.");
}
}
}
private Risk GetRisk()
{
// A risk template normally comes straight from the current account.
// Account.Risk. But in StrategyAnalyzer it's null. This method tries a
// few things to ensure we get a risk template regardless of our current
// context.
// If the current account has Risk use it.
if (Account.Risk != null)
{
return Account.Risk;
}
// Strategy Analyzer is different so let's try to get a risk template
// from the Sim101 account.
if (IsInStrategyAnalyzer)
{
var sim101Account = Account.All.FirstOrDefault(a => a.Name == "Sim101");
if (sim101Account.Risk != null)
{
return sim101Account.Risk;
}
}
// At this point, just look for any account that has a risk template.
var acct2 = Account.All.Where(a => a.Risk != null).FirstOrDefault();
if (acct2 != null)
{
return acct2.Risk;
}
// Finally, we can try to get the default NT risk template
Risk rsk = Risk.Get("NinjaTrader Brokerage Default");
if (rsk != null)
{
return rsk;
}
// Can't find any risk templates
return null;
}
}
}
2 Likes
Thank you. I think that part will work just fine for using the Intraday Margin for the Instrument I happen to use.
Any idea how to access the Account Cash Value at anytime? Looking at the NinjaTrader documentation, I have only seen OnAccountUpdate() which makes sense, but that is event driven and gets called while you’re in a position, which is good for Unrealized Profit and loss, but I need to know my Cash Value BEFORE I enter a position so I can ensure I don’t go over Margin-wise.
Edit
I figured it out. I can use Get() to get the Cash Value using Account.Get(AccountItem.CashValue, Currency.UsDollar)
2 Likes