public void InitAndAdjust() { string sym = "IBM"; ForexSecurity ts = new ForexSecurity(sym); IAccount account = new SimAccount("TEST"); account.Securities.AddSecurity(ts); // startup position tracker PositionTracker pt = new PositionTracker(account); PositionTracker pt2 = new PositionTracker(account); // give pt our initial position PositionImpl init = new PositionImpl(ts, 0, 0, 0, account); pt.Adjust(init); pt2.Adjust(init); // fill a trade in both places TradeImpl fill = new TradeImpl(ts.Name, 100, 100); fill.Account = account; fill.Security = ts; pt.Adjust(fill); pt2.Adjust(fill); // make sure it's only 100 in both places Assert.Equal(100, pt[sym].Size); Assert.Equal(100, pt2[sym].Size); }
public void MOCs() { SimBroker broker = new SimBroker(); broker.BrokerModel = _trans; ForexSecurity tsec = new ForexSecurity(S); tsec.LotSize = 1; tsec.OrderStepSize = 1; OrderImpl moc = new OrderImpl(tsec, Direction.Long, 200); moc.ValidInstruct = OrderInstructionType.MOC; PendingOrderImpl pmoc = new PendingOrderImpl(moc); Assert.True(moc.ValidInstruct == OrderInstructionType.MOC, "unexpected order instruction: " + moc.ValidInstruct); Assert.Equal(0, broker.SendOrderStatus(pmoc)); TickImpl openingTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(9, 30, 00, 000), 9, 10000, "NYS"); TickImpl endMornTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(12, 00, 00, 000), 9, 10000, "NYS"); TickImpl endLunchTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(14, 15, 00, 000), 9, 10000, "NYS"); TickImpl closingTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(16, 00, 00, 000), 9, 10000, "NYS"); int c = 0; c = broker.Execute(openingTick); Assert.Equal(0, c); c = broker.Execute(endMornTick); Assert.Equal(0, c); c = broker.Execute(endLunchTick); Assert.Equal(0, c); c = broker.Execute(closingTick); Assert.Equal(1, c); // should execute on the first tick at/after 16:00:00 }
public void Adjust() { string s = "IBM"; ForexSecurity ts = new ForexSecurity(s); IAccount account = new SimAccount("TEST", "testing", 1000M, 100, "SIM"); account.Securities.AddSecurity(ts); TradeImpl t1 = new TradeImpl(s, 100, 100); t1.Account = account; t1.Security = ts; PositionTracker pt = new PositionTracker(account); // make we have no position yet Assert.True(pt[t1.Symbol].IsFlat); // send some adjustments decimal cpl = 0; cpl += pt.Adjust(t1); cpl += pt.Adjust(t1); // verify that adjustments took hold Assert.Equal(0, cpl); Assert.Equal(200, pt[t1.Symbol].Size); }
public void PositionAccountTest() { ForexSecurity ts = new ForexSecurity(s); IAccount account = new SimAccount("ME"); account.Securities.AddSecurity(ts); TradeImpl t = new TradeImpl("TST", 100, 100); t.Account = account; t.Security = ts; TradeImpl t2 = new TradeImpl("TST", 200, 200); Assert.True(t.IsValid); Assert.True(t2.IsValid); t2.AccountName = "HIM"; PositionImpl p = new PositionImpl(t); p.Adjust(t); bool failed = false; try { p.Adjust(t2); } catch (Exception) { failed = true; } Assert.True(failed); }
public void DayFill() { SimBroker broker = new SimBroker(); broker.BrokerModel = _trans; ForexSecurity tsec = new ForexSecurity(S); tsec.LotSize = 1; tsec.OrderStepSize = 1; OrderImpl day = new OrderImpl(tsec, Direction.Long, 200); PendingOrderImpl pday = new PendingOrderImpl(day); broker.SendOrderStatus(pday); TickImpl openingTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(9, 30, 00, 000), 9, 10000, "NYS"); TickImpl endMornTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(12, 00, 00, 000), 9, 10000, "NYS"); TickImpl endLunchTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(14, 15, 00, 000), 9, 10000, "NYS"); TickImpl closingTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(16, 00, 00, 000), 9, 10000, "NYS"); int c; c = broker.Execute(openingTick); Assert.Equal(1, c); // should execute on first received tick c = broker.Execute(endMornTick); Assert.Equal(0, c); c = broker.Execute(endLunchTick); Assert.Equal(0, c); c = broker.Execute(closingTick); Assert.Equal(0, c); }
public void Fill_RegularLiquidity() { SimBroker broker = new SimBroker(); broker.BrokerModel = _trans; ForexSecurity tsec = new ForexSecurity(S); tsec.LotSize = 1; tsec.OrderStepSize = 1; OrderImpl limitBuy = new OrderImpl(tsec, Direction.Long, 1, 133m); OrderImpl limitSell = new OrderImpl(tsec, Direction.Short, 1, 133.5m); OrderImpl stopBuy = new OrderImpl(tsec, Direction.Long, 3, 0, 135.70m); OrderImpl stopSell = new OrderImpl(tsec, Direction.Short, 4, 0, 135.75m); PendingOrderImpl plimitBuy = new PendingOrderImpl(limitBuy); PendingOrderImpl plimitSell = new PendingOrderImpl(limitSell); PendingOrderImpl pstopBuy = new PendingOrderImpl(stopBuy); PendingOrderImpl pstopSell = new PendingOrderImpl(stopSell); broker.SendOrderStatus(plimitBuy); broker.SendOrderStatus(plimitSell); broker.SendOrderStatus(pstopBuy); broker.SendOrderStatus(pstopSell); // OHLC for 6/21/2012 on SPY TickImpl openingTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(9, 30, 00, 000), 135.67m, 10670270, "NYS"); TickImpl endMornTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(12, 00, 00, 000), 135.78m, 10670270, "NYS"); TickImpl endLunchTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(14, 15, 00, 000), 132.33m, 10670270, "NYS"); TickImpl closingTick = TickImpl.NewTrade(S, Util.ToQLDate(DateTime.Now), Util.QL2FT(16, 00, 00, 000), 132.44m, 10670270, "NYS"); broker.Execute(openingTick); broker.Execute(endMornTick); broker.Execute(endLunchTick); broker.Execute(closingTick); List <Trade> trades = broker.GetTradeList(); Assert.True(trades.Count == 4); foreach (Trade trade in trades) { if (trade.Xsize == 1) { Assert.Equal(132.33m, trade.Xprice); } else if (trade.Xsize == 2) { Assert.Equal(132.33m, trade.Xprice); } else if (trade.Xsize == 3) { Assert.Equal(135.78m, trade.Xprice); } else if (trade.Xsize == 4) { Assert.Equal(135.78m, trade.Xprice); } } }
public void UsingTrades() { // long string s = "IBM"; ForexSecurity ts = new ForexSecurity(s); ts.LotSize = 1; ts.PipValue = 1; ts.PipSize = 1; PortfolioManager portfolio = new TradingPortfolio(); IAccount account = new SimAccount("TEST"); portfolio.SetAccount(account); portfolio.Securities.AddSecurity(ts); TradeImpl t1 = new TradeImpl(s, 80, 100, dt); t1.Account = account; t1.Security = ts; PositionImpl p = new PositionImpl(t1); Assert.True(p.IsLong); Assert.True(p.Size == 100); TradeImpl t2 = new TradeImpl(s, 84, -100, dt); t2.Account = account; t2.Security = ts; decimal pl = p.Adjust(t2); Assert.True(p.IsFlat); Assert.Equal((84 - 80) * 100, pl); // short TradeImpl t3 = new TradeImpl(s, 84, -100, dt); t3.Account = account; t3.Security = ts; p = new PositionImpl(t3); Assert.True(!p.IsLong); Assert.True(p.Size == -100); TradeImpl t4 = new TradeImpl(s, 80, 100, dt); t4.Account = account; t4.Security = ts; pl = p.Adjust(new TradeImpl(t4)); Assert.True(pl == (84 - 80) * 100); Assert.True(p.IsFlat); }
public TestCalc() { ForexSecurity ls = new ForexSecurity(stock); lp = new PositionImpl(ls, entry, lsize); sp = new PositionImpl(ls, entry, ssize); //closing trades lc = new TradeImpl(ls.Name, last, lsize / -2); sc = new TradeImpl(ls.Name, last, -ssize); }
public void OpGs() { SimBroker broker = new SimBroker(); broker.BrokerModel = _trans; const string s = "NYS"; ForexSecurity tsec = new ForexSecurity(s); tsec.LotSize = 1; tsec.OrderStepSize = 1; // build and send an OPG order OrderImpl opg = new OrderImpl(tsec, Direction.Long, 200, 10); PendingOrderImpl popg = new PendingOrderImpl(opg); Assert.Equal(0, broker.SendOrderStatus(popg)); // build a tick on another exchange TickImpl it = TickImpl.NewTrade(s, 9, 100); it.Exchange = "ISLD"; // fill order (should fail) int c = broker.Execute(it); Assert.Equal(0, c); // build opening price for desired exchange TickImpl nt = TickImpl.NewTrade(s, 9, 10000); nt.Exchange = "NYS"; // fill order (should work) c = broker.Execute(nt); Assert.Equal(1, c); // add another OPG, make sure it's not filled with another tick TickImpl next = TickImpl.NewTrade(s, 9, 2000); next.Exchange = "NYS"; OrderImpl late = new OrderImpl(tsec, Direction.Long, 200, 10); PendingOrderImpl plate = new PendingOrderImpl(late); broker.SendOrderStatus(plate); c = broker.Execute(next); Assert.Equal(0, c); }
public void NewPosition() { string s = "IBM"; ForexSecurity ts = new ForexSecurity(s); IAccount account = new SimAccount("TEST"); account.Securities.AddSecurity(ts); PositionImpl p = new PositionImpl(ts, 80, 500, 0, account); PositionTracker pt = new PositionTracker(account); Assert.True(pt[s].IsFlat); pt.NewPosition(p); Assert.Equal(500, pt[s].Size); }
public void Basics() { ForexSecurity tsec = new ForexSecurity(S); tsec.LotSize = 1; tsec.PipValue = 1; tsec.PipSize = 1; tsec.OrderStepSize = 1; SimAccount account = new SimAccount("TEST", "testing", 1000M, 100); account.Securities.AddSecurity(tsec); SimBroker broker = new SimBroker(account, _trans); broker.BrokerModel = _trans; broker.GotFill += broker_GotFill; broker.GotOrder += broker_GotOrder; OrderImpl o = new OrderImpl(); PendingOrderImpl po = new PendingOrderImpl(o); int error = broker.SendOrderStatus(po); Assert.NotEqual((int)StatusType.OK, error); Assert.True(_orders == 0); Assert.True(_fills == 0); o = new OrderImpl(tsec, Direction.Long, 100); po = new PendingOrderImpl(o); broker.SendOrderStatus(po); Assert.True(_orders == 1); Assert.True(_fills == 0); Assert.True(broker.Execute(TickImpl.NewTrade(S, 10, 200)) == 1); Assert.True(_fills == 1); // test that a limit order is not filled outside the market o = new OrderImpl(tsec, Direction.Long, 100, 9); po = new PendingOrderImpl(o); broker.SendOrderStatus(po); Assert.Equal(0, broker.Execute(TickImpl.NewTrade(S, 10, 100))); Assert.True(_fills == 1); // redundant but for counting // test that limit order is filled inside the market Assert.Equal(1, broker.Execute(TickImpl.NewTrade(S, 8, 100))); Assert.True(_fills == 2); }
public void MultiAccount() { _broker.BrokerModel = _trans; const string sym = "TST"; ForexSecurity tsec = new ForexSecurity(sym); tsec.LotSize = 1; tsec.OrderStepSize = 1; const string me = "tester"; const string other = "anotherguy"; SimAccount a = new SimAccount(me); SimAccount b = new SimAccount(other); SimAccount c = new SimAccount("sleeper"); OrderImpl oa = new OrderImpl(tsec, Direction.Long, 100); OrderImpl ob = new OrderImpl(tsec, Direction.Long, 100); oa.AccountName = me; ob.AccountName = other; // send order to accounts PendingOrderImpl poa = new PendingOrderImpl(oa, a); PendingOrderImpl pob = new PendingOrderImpl(ob, b); _broker.SendOrderStatus(poa); _broker.SendOrderStatus(pob); TickImpl t = new TickImpl(sym) { Trade = 100m, Size = 200 }; Assert.Equal(2, _broker.Execute(t)); Position apos = _broker.GetOpenPosition(tsec, a); Position bpos = _broker.GetOpenPosition(tsec, b); Position cpos = _broker.GetOpenPosition(tsec, c); Assert.True(apos.IsLong); Assert.Equal(100, apos.Size); Assert.True(bpos.IsLong); Assert.Equal(100, bpos.Size); Assert.True(cpos.IsFlat); // make sure that default account doesn't register // any trades Assert.True(_broker.GetOpenPosition(tsec).IsFlat); }
public void ClosedPL() { const string sym = "RYN"; ForexSecurity ts = new ForexSecurity(sym); IAccount acc = new SimAccount("TST"); acc.Securities.AddSecurity(ts); PositionTracker pt = new PositionTracker(acc); Position p = new PositionImpl(ts, 44.39m, 800, 0, acc); pt.Adjust(p); Position p2 = new PositionImpl(ts, 44.39m, -800, 0, acc); pt.Adjust(p2); Assert.Equal(0, pt[sym].GrossPnL); }
public void CreateInvalidFromSymbol() { const string sym = "TST"; ForexSecurity ts = new ForexSecurity(sym); bool except = false; Position p = null; try { p = new PositionImpl(ts); } catch { except = true; } Assert.NotNull(p); Assert.True(p.IsValid); Assert.False(except); }
public void MaxDD() { const string sym = "TST"; SimAccount account = new SimAccount("TEST", "testing", 1000M, 100); ForexSecurity sec = new ForexSecurity(sym); sec.PipValue = 1; sec.LotSize = 1; sec.PipSize = 1; account.Securities.AddSecurity(sec); IPositionTracker pt = account.Positions; System.Collections.Generic.List <Trade> fills = new System.Collections.Generic.List <Trade>(); TradeImpl t = new TradeImpl(sym, 10, 100); t.Security = sec; t.Account = account; System.Collections.Generic.List <decimal> ret = new System.Collections.Generic.List <decimal>(); fills.Add(t); pt.Adjust(t); t = new TradeImpl(sym, 11, -100); t.Security = sec; t.Account = account; fills.Add(t); ret.Add(pt.Adjust(t)); t = new TradeImpl(sym, 11, -100); t.Security = sec; t.Account = account; pt.Adjust(t); fills.Add(t); t = new TradeImpl(sym, 13, 100); t.Account = account; t.Security = sec; fills.Add(t); ret.Add(pt.Adjust(t)); decimal maxdd = Calc.MaxDdVal(ret.ToArray()); decimal maxddp = Calc.MaxDDPct(fills); Assert.Equal(-300, maxdd); Assert.Equal(-.18m, Math.Round(maxddp, 2)); }
public void BlankPositionReq() { string sym = "IBM"; ForexSecurity ts = new ForexSecurity(sym); IAccount account = new SimAccount("TEST"); account.Securities.AddSecurity(ts); PositionTracker pt = new PositionTracker(account); bool except = false; int s = 100; try { s = pt[sym].Size; } catch { except = true; } Assert.Equal(0, s); Assert.False(except); }
private static PortfolioManager Get(string symbol) { //Initialize TradingPortfolio np = new TradingPortfolio(); //ADD INITIAL SECURITIES ForexSecurity security = new ForexSecurity(symbol); security.LotSize = 100000; //Lots security.PipSize = 0.0001M; //PipSize in 4 decimal places security.TickSize = 0.00001M; //Size of one tick security.PipValue = 1M; //PipValue, if unable to calculate to base currency security.Digits = 5; var account = new SimAccount("SIMULATED", "Sim account for backtesting", 10000, 100, "SIM"); np.SetAccount(account); np.Securities.AddSecurity(security); //ADD AGENT AND INJECT TEMPLATES np.InjectAgent <ExampleTradingAgent>(); //Set streams TradingAgent agent = (TradingAgent)np.Agents[0]; agent.AgentId = 115230; agent.TimeFrame = TimeSpan.FromSeconds(TimeFrameInSeconds); OHLCBarStream ls = new OHLCBarStream(np.Securities[symbol], np.Agents[0].TimeFrame); agent.SetDefaultStream(ls); ls.Initialize(); agent.Initialize(); agent.Start(); SimpleBacktester.OnMessage += SimpleBacktester_OnMessage; SimpleBacktester.OnProgress += SimpleBacktester_OnProgress; return(np); }
public void AdjustedDateTime() { // long string s = "IBM"; ForexSecurity ts = new ForexSecurity(s); ts.LotSize = 1; ts.PipValue = 1; ts.PipSize = 1; IAccount account = new SimAccount("TEST"); account.Securities.AddSecurity(ts); TradeImpl t1 = new TradeImpl(s, 80, 100, dt); t1.Account = account; t1.Security = ts; PositionImpl p = new PositionImpl(t1); p.LastModified.Should().BeAfter(DateTime.MinValue); }
public void FlipSideInOneTrade() { // this is illegal on the exchanges, but supported by certain // retail brokers so we're going to allow Quantler to support it // BE CAREFUL WITH THIS FEATURE. make sure you won't be fined for doing this, before you do it. string s = "IBM"; ForexSecurity ts = new ForexSecurity(s); ts.LotSize = 1; ts.PipValue = 1; ts.PipSize = 1; PortfolioManager portfolio = new TradingPortfolio(); IAccount account = new SimAccount("TEST"); portfolio.SetAccount(account); portfolio.Securities.AddSecurity(ts); // long position var t = new TradeImpl(s, 100m, 200); t.Account = account; t.Security = ts; decimal cpl = portfolio.Positions.Adjust(t); Assert.Equal(cpl, 0); // sell more than we've got to change sides TradeImpl flip = new TradeImpl(s, 99, -400); flip.Account = account; flip.Security = ts; cpl = portfolio.Positions.Adjust(flip); // make sure we captured close of trade Assert.Equal(-200, cpl); // make sure we captured new side and price Assert.Equal(-200, portfolio.Positions[s].Size); Assert.Equal(99, portfolio.Positions[s].AvgPrice); }
public void ClosePLWithPipValueAndLotSize() { decimal pl = -490M; ForexSecurity ts = (ForexSecurity)sp.Security; sc.Security = sp.Security; ts.PipSize = 2; ts.LotSize = 1; // Lot size as micro lots ts.PipValue = 2; // Normal pip value is 2 dollars per pip profit per lot Assert.Equal(pl, Calc.ClosePL(sp, sc)); pl /= 2; ts.PipValue = 1; //If the pip value is twice as low, the results are twice as low due to the value of one pip Assert.Equal(pl, Calc.ClosePL(sp, sc)); pl /= 2; ts.LotSize = 2; //If lotsize is twice as high, results are twice as low since the pip value is based on lotsize Assert.Equal(pl, Calc.ClosePL(sp, sc)); }
public void MultipleAccount() { // setup defaults for 1st and 2nd accounts and positions string s = "TST"; ForexSecurity sym = new ForexSecurity(s); IAccount a1 = new SimAccount("account1"); a1.Securities.AddSecurity(sym); IAccount a2 = new SimAccount("account2"); a1.Securities.AddSecurity(sym); int s1 = 300; int s2 = 500; decimal p = 100m; // create position tracker PositionTracker pt = new PositionTracker(a1); // set initial position in 1st account pt.Adjust(new PositionImpl(sym, p, s1, 0, a1)); // set initial position in 2nd account pt.Adjust(new PositionImpl(sym, p, s2, 0, a2)); // verify I can query default account and it's correct Assert.Equal(s1, pt[sym].Size); // change default to 2nd account pt.DefaultAccount = a2; // verify I can query default and it's correct Assert.Equal(s2, pt[sym].Size); // verify I can query 1st account and correct Assert.Equal(s1, pt[sym, a1].Size); // verify I can query 2nd account and correct Assert.Equal(s2, pt[sym, a2].Size); // get fill in sym for 1st account TradeImpl f = new TradeImpl(sym.Name, p, s1); f.Account = a1; f.Security = sym; pt.Adjust(f); // get fill in sym for 2nd account TradeImpl f2 = new TradeImpl(sym.Name, p, s2); f2.Account = a2; f2.Security = sym; pt.Adjust(f2); // verify that I can querry 1st account and correct Assert.Equal(s1 * 2, pt[sym, a1].Size); // verify I can query 2nd account and correct Assert.Equal(s2 * 2, pt[sym, a2].Size); // reset pt.Clear(); // ensure I can query first and second account and get flat symbols Assert.Equal(0, pt[sym].Size); Assert.Equal(0, pt[sym, a1].Size); Assert.Equal(0, pt[sym, a2].Size); Assert.True(pt[sym, a1].IsFlat); Assert.True(pt[sym, a2].IsFlat); Assert.True(pt[sym].IsFlat); Assert.Equal(null, pt.DefaultAccount); }
public void RoundTurnStat() { ForexSecurity ts = new ForexSecurity(sym); ts.LotSize = 1; ts.PipSize = 1; IAccount account = new SimAccount("TEST"); account.Securities.AddSecurity(ts); rt = new Results(.01m, account); // get some trades List <Trade> fills = new List <Trade>(new Trade[] { // go long new TradeImpl(sym, p, s) { Security = ts, Account = account }, // increase bet new TradeImpl(sym, p + inc, s * 2) { Security = ts, Account = account }, // take some profits new TradeImpl(sym, p + inc * 2, s * -1) { Security = ts, Account = account }, // go flat (round turn) new TradeImpl(sym, p + inc * 2, s * -2) { Security = ts, Account = account }, // go short new TradeImpl(sym, p, s * -2) { Security = ts, Account = account }, // decrease bet new TradeImpl(sym, p, s) { Security = ts, Account = account }, // exit (round turn) new TradeImpl(sym, p + inc, s) { Security = ts, Account = account }, // do another entry new TradeImpl(sym, p, s) { Security = ts, Account = account } }); //fill all trades foreach (var t in fills) { account.Positions.Adjust(t); } // check trade count Assert.Equal(fills.Count, rt.Trades); // check round turn count Assert.Equal(2, rt.RoundTurns); // verify trade winners Assert.Equal(2, rt.Winners); // verify round turn winners Assert.Equal(1, rt.RoundWinners); // verify round turn losers Assert.Equal(1, rt.RoundLosers); }
public void AccountBalanceUpdateForex() { //Arrange SimAccount testaccount = new SimAccount("SIM1", "Menno's Account", initialbalance, leverage); ForexSecurity ts = new ForexSecurity(sym); ts.LotSize = 1000; ts.ContractSize = ts.LotSize; ts.PipSize = 0.0001M; ts.TickSize = ts.PipSize / 10; testaccount.Securities.AddSecurity(ts); TickImpl tick = TickImpl.NewQuote(sym, p, p, int.MaxValue, int.MaxValue, ts.DestEx, ts.DestEx); TickImpl secondtick = TickImpl.NewQuote(sym, p + inc, p + inc, int.MaxValue, int.MaxValue, ts.DestEx, ts.DestEx); List <Trade> fills = new List <Trade>(new Trade[] { // go long new TradeImpl(sym, p, s) { Security = ts, Account = testaccount, Commission = 1 }, // 1000 @ $1 // increase bet new TradeImpl(sym, p + inc, s * 2) { Security = ts, Account = testaccount, Commission = 2 }, // 2000 @ $1.1 // take some profits new TradeImpl(sym, p + inc * 2, s * -1) { Security = ts, Account = testaccount, Commission = 1 }, // -1000 @ $1.2 (profit = 1000 * (1.2 - 1.0) = 200) // go flat (round turn) new TradeImpl(sym, p + inc * 2, s * -2) { Security = ts, Account = testaccount, Commission = 2 }, // -2000 @ $1.2 (profit = 2000 * (1.2 - 1.1) = 200) // go short new TradeImpl(sym, p, s * -2) { Security = ts, Account = testaccount, Commission = 2 }, // -2000 @ $1 // decrease bet new TradeImpl(sym, p, s) { Security = ts, Account = testaccount, Commission = 1 }, // 1000 @ $1 // exit (round turn) new TradeImpl(sym, p + inc, s) { Security = ts, Account = testaccount, Commission = 1 }, // 1000 @ $1 (loss = 1000 * (1.2 - 1.0) = 100) // do another entry new TradeImpl(sym, p, s) { Security = ts, Account = testaccount, Commission = 1 } // 100 @ 100 }); //Act, fill all trades testaccount.OnTick(tick); testaccount.OnTick(secondtick); foreach (var t in fills) { testaccount.OnFill(t); } //Assert Assert.True(testaccount.Balance == 10300); Assert.True(testaccount.Margin == 11); Assert.True(testaccount.MarginLevel == (testaccount.Equity / testaccount.Margin) * 100); }
public void BBO() { SimBroker broker = new SimBroker(); broker.BrokerModel = _trans; ForexSecurity tsec = new ForexSecurity(S); tsec.LotSize = 1; tsec.OrderStepSize = 1; const decimal p1 = 10m; const decimal p2 = 11m; const int x = 100; Order bid, offer; // send bid, make sure it's BBO (since it's only order on any book) broker.SendOrderStatus(new PendingOrderImpl(new OrderImpl(tsec, Direction.Long, x, p1))); bid = broker.BestBid(S); offer = broker.BestOffer(S); Assert.True(bid.IsValid && (bid.LimitPrice == p1) && (bid.Quantity == x), bid.ToString()); Assert.True(!offer.IsValid, offer.ToString()); // add better bid, make sure it's BBO OrderImpl o; // Order#1... 100 shares buy at $11 o = new OrderImpl(tsec, Direction.Long, x, p2); PendingOrderImpl po = new PendingOrderImpl(o); broker.SendOrderStatus(po); bid = broker.BestBid(S); offer = broker.BestOffer(S); Assert.True(bid.IsValid); Assert.Equal(p2, bid.LimitPrice); Assert.Equal(x, bid.Size); Assert.True(!offer.IsValid, offer.ToString()); // add another bid at same price on another account, make sure it's additive //order #2... 100 shares buy at $11 o = new OrderImpl(tsec, Direction.Long, x, p2); po = new PendingOrderImpl(o, new SimAccount("ANOTHER_ACCOUNT")); o.AccountName = "ANOTHER_ACCOUNT"; broker.SendOrderStatus(po); bid = broker.BestBid(S); offer = broker.BestOffer(S); Assert.True(bid.IsValid); Assert.Equal(p2, bid.LimitPrice); Assert.Equal(x * 2, bid.Size); Assert.True(!offer.IsValid, offer.ToString()); // cancel order and make sure bbo returns po.Cancel(); bid = broker.BestBid(S); offer = broker.BestOffer(S); Assert.True(bid.IsValid); Assert.Equal(p2, bid.LimitPrice); Assert.Equal(x, bid.Size); Assert.True(!offer.IsValid, offer.ToString()); // other test ideas // replicate above tests for sell-side }
public void LowMarginLevel() { //Arrange SimAccount testaccount = new SimAccount("SIM1", "Menno's Account", initialbalance, leverage); ForexSecurity ts = new ForexSecurity(sym); ts.LotSize = 1000; ts.PipSize = 0.0001M; ts.TickSize = ts.PipSize / 10; testaccount.Securities.AddSecurity(ts); TickImpl tick = TickImpl.NewQuote(sym, p, p, int.MaxValue, int.MaxValue, ts.DestEx, ts.DestEx); TickImpl secondtick = TickImpl.NewQuote(sym, p + inc, p + inc, int.MaxValue, int.MaxValue, ts.DestEx, ts.DestEx); List <Trade> fills = new List <Trade>(new Trade[] { // go long new TradeImpl(sym, p, s) { Security = ts, Account = testaccount, Commission = 1 }, // 100 @ $100 // increase bet new TradeImpl(sym, p + inc, s * 2) { Security = ts, Account = testaccount, Commission = 2 }, // 300 @ $100.066666 // take some profits new TradeImpl(sym, p + inc * 2, s * -1) { Security = ts, Account = testaccount, Commission = 1 }, // 200 @ 100.0666 (profit = 100 * (100.20 - 100.0666) = 13.34) / maxMIU(= 300*100.06666) = .04% ret // go flat (round turn) new TradeImpl(sym, p + inc * 2, s * -2) { Security = ts, Account = testaccount, Commission = 2 }, // 0 @ 0 // go short new TradeImpl(sym, p, s * -2) { Security = ts, Account = testaccount, Commission = 2 }, // -200 @ 100 // decrease bet new TradeImpl(sym, p, s) { Security = ts, Account = testaccount, Commission = 1 }, // -100 @100 // exit (round turn) new TradeImpl(sym, p + inc, s * 5000) { Security = ts, Account = testaccount, Commission = 1 }, // 0 @ 0 (gross profit = -0.10*100 = -$10) // do another entry new TradeImpl(sym, p, s) { Security = ts, Account = testaccount, Commission = 1 } // 100 @ 100 }); //Act, fill all trades testaccount.OnTick(tick); testaccount.OnTick(secondtick); foreach (var t in fills) { testaccount.OnFill(t); } //Assert Assert.True(testaccount.Balance == 10300); Assert.True(testaccount.Margin == 55000); //Lower than 20% (Margin Call) Assert.True(testaccount.MarginLevel < 20M); }