package ofxgo_test import ( "github.com/aclindsa/ofxgo" "math/big" "strings" "testing" "time" ) func TestMarshalInvStatementRequest(t *testing.T) { var expectedString string = ` 20160224131905.000[-5:EST] 1998124 Sup3eSekrit ENG First Bank 01 MYAPP 1234 382827d6-e2d0-4396-bf3b-665979285420 fi.example.com 82736664 20160101000000.000[-5:EST] Y Y Y Y ` var client = ofxgo.Client{ AppId: "MYAPP", AppVer: "1234", SpecVersion: "203", } var request ofxgo.Request request.Signon.UserId = "1998124" request.Signon.UserPass = "Sup3eSekrit" request.Signon.Org = "First Bank" request.Signon.Fid = "01" EST := time.FixedZone("EST", -5*60*60) dtstart := ofxgo.Date(time.Date(2016, 1, 1, 0, 0, 0, 0, EST)) statementRequest := ofxgo.InvStatementRequest{ TrnUID: "382827d6-e2d0-4396-bf3b-665979285420", InvAcctFrom: ofxgo.InvAcct{ BrokerId: "fi.example.com", AcctId: "82736664", }, DtStart: &dtstart, Include: true, IncludeOO: true, IncludePos: true, IncludeBalance: true, } request.InvStmt = append(request.InvStmt, &statementRequest) request.SetClientFields(&client) // Overwrite the DtClient value set by SetClientFields to time.Now() request.Signon.DtClient = ofxgo.Date(time.Date(2016, 2, 24, 13, 19, 5, 0, EST)) marshalCheckRequest(t, &request, expectedString) } func TestUnmarshalInvStatementResponse(t *testing.T) { responseReader := strings.NewReader(` 0 INFO 20170401201244 ENG INVSTRUS 9999 1a0117ad-692b-4c6a-a21b-020d37d34d49 0 INFO 20170331000000 USD invstrus.com 91827364 20170101000000 20170331000000 729483191 20170203 20170207 78462F103 CUSIP 100 229.00 9.00 -22909.00 CASH CASH BUY CREDIT 20170120 20170118 20170123 22000.00 993838 DEPOSIT CHECK 19980 CASH 78462F103 CUSIP CASH LONG 200 235.74 47148.00 20170331160000 Price as of previous close 129887339 CUSIP CASH LONG 1 3 300 20170331160000 16.73 -819.20 0 Sweep Int Rate Current interest rate for sweep account balances PERCENT 0.25 20170401 76464632 922908645 CUSIP 20170310124445 10 CASH GOODTILCANCEL NONE 168.50 BUY SHARES 999387423 899422348 CUSIP 20170324031900 25 CASH GOODTILCANCEL ALLORNONE 19.75 BUY 78462F103 CUSIP S&P 500 ETF SPY 99184 1.92 OTHER 129887339 CUSIP John's Fertilizer Puts FERTP 882919 PUT 79.00 20170901 100 983322180 CUSIP LARGESTOCK 899422348 CUSIP Whatchamacallit, Inc. WHAT 883897 17 SMALLSTOCK 922908645 CUSIP Mid-Cap Index Fund Admiral Shares VIMAX `) var expected ofxgo.Response GMT := time.FixedZone("GMT", 0) expected.Version = "203" expected.Signon.Status.Code = 0 expected.Signon.Status.Severity = "INFO" expected.Signon.DtServer = ofxgo.Date(time.Date(2017, 4, 1, 20, 12, 44, 0, GMT)) expected.Signon.Language = "ENG" expected.Signon.Org = "INVSTRUS" expected.Signon.Fid = "9999" var units1, unitprice1, commission1, total1, amount2 big.Rat units1.SetFrac64(100, 1) unitprice1.SetFrac64(229, 1) commission1.SetFrac64(9, 1) total1.SetFrac64(-22909, 1) amount2.SetFrac64(22000, 1) dtuser := ofxgo.Date(time.Date(2017, 1, 18, 0, 0, 0, 0, GMT)) dtavail := ofxgo.Date(time.Date(2017, 1, 23, 0, 0, 0, 0, GMT)) dtsettle := ofxgo.Date(time.Date(2017, 2, 7, 0, 0, 0, 0, GMT)) invtranlist := ofxgo.InvTranList{ DtStart: ofxgo.Date(time.Date(2017, 1, 1, 0, 0, 0, 0, GMT)), DtEnd: ofxgo.Date(time.Date(2017, 3, 31, 0, 0, 0, 0, GMT)), InvTransactions: []ofxgo.InvTransaction{ ofxgo.BuyStock{ InvBuy: ofxgo.InvBuy{ InvTran: ofxgo.InvTran{ FiTId: "729483191", DtTrade: ofxgo.Date(time.Date(2017, 2, 3, 0, 0, 0, 0, GMT)), DtSettle: &dtsettle, }, SecId: ofxgo.SecurityId{ UniqueId: "78462F103", UniqueIdType: "CUSIP", }, Units: ofxgo.Amount(units1), UnitPrice: ofxgo.Amount(unitprice1), Commission: ofxgo.Amount(commission1), Total: ofxgo.Amount(total1), SubAcctSec: "CASH", SubAcctFund: "CASH", }, BuyType: "BUY", }, }, BankTransactions: []ofxgo.InvBankTransaction{ ofxgo.InvBankTransaction{ Transactions: []ofxgo.Transaction{ ofxgo.Transaction{ TrnType: "CREDIT", DtPosted: ofxgo.Date(time.Date(2017, 1, 20, 0, 0, 0, 0, GMT)), DtUser: &dtuser, DtAvail: &dtavail, TrnAmt: ofxgo.Amount(amount2), FiTId: "993838", Name: "DEPOSIT", Memo: "CHECK 19980", }, }, SubAcctFund: "CASH", }, }, } var availcash, marginbalance, shortbalance, balvalue big.Rat availcash.SetFrac64(1673, 100) marginbalance.SetFrac64(-8192, 10) shortbalance.SetFrac64(0, 1) balvalue.SetFrac64(25, 100) baldtasof := ofxgo.Date(time.Date(2017, 4, 1, 0, 0, 0, 0, GMT)) invbalance := ofxgo.InvBalance{ AvailCash: ofxgo.Amount(availcash), MarginBalance: ofxgo.Amount(marginbalance), ShortBalance: ofxgo.Amount(shortbalance), BalList: []ofxgo.Balance{ ofxgo.Balance{ Name: "Sweep Int Rate", Desc: "Current interest rate for sweep account balances", BalType: "PERCENT", Value: ofxgo.Amount(balvalue), DtAsOf: &baldtasof, }, }, } var balamt, availbalamt, posunits1, posunitprice1, posmktval1, posunits2, posunitprice2, posmktval2, oounits1, oolimitprice1, oounits2, oolimitprice2 big.Rat balamt.SetFrac64(20029, 100) availbalamt.SetFrac64(20029, 100) posunits1.SetFrac64(200, 1) posunitprice1.SetFrac64(23574, 100) posmktval1.SetFrac64(47148, 1) posunits2.SetFrac64(1, 1) posunitprice2.SetFrac64(3, 1) posmktval2.SetFrac64(300, 1) oounits1.SetFrac64(10, 1) oolimitprice1.SetFrac64(16850, 100) oounits2.SetFrac64(25, 1) oolimitprice2.SetFrac64(1975, 100) statementResponse := ofxgo.InvStatementResponse{ TrnUID: "1a0117ad-692b-4c6a-a21b-020d37d34d49", Status: ofxgo.Status{ Code: 0, Severity: "INFO", }, DtAsOf: ofxgo.Date(time.Date(2017, 3, 31, 0, 0, 0, 0, GMT)), CurDef: "USD", InvAcctFrom: ofxgo.InvAcct{ BrokerId: "invstrus.com", AcctId: "91827364", }, InvTranList: &invtranlist, InvPosList: ofxgo.PositionList{ ofxgo.StockPosition{ InvPos: ofxgo.InvPosition{ SecId: ofxgo.SecurityId{ UniqueId: "78462F103", UniqueIdType: "CUSIP", }, HeldInAcct: "CASH", PosType: "LONG", Units: ofxgo.Amount(posunits1), UnitPrice: ofxgo.Amount(posunitprice1), MktVal: ofxgo.Amount(posmktval1), DtPriceAsOf: ofxgo.Date(time.Date(2017, 3, 31, 16, 0, 0, 0, GMT)), Memo: "Price as of previous close", }, }, ofxgo.OptPosition{ InvPos: ofxgo.InvPosition{ SecId: ofxgo.SecurityId{ UniqueId: "129887339", UniqueIdType: "CUSIP", }, HeldInAcct: "CASH", PosType: "LONG", Units: ofxgo.Amount(posunits2), UnitPrice: ofxgo.Amount(posunitprice2), MktVal: ofxgo.Amount(posmktval2), DtPriceAsOf: ofxgo.Date(time.Date(2017, 3, 31, 16, 0, 0, 0, GMT)), }, }, }, InvBal: &invbalance, InvOOList: ofxgo.OOList{ ofxgo.OOBuyMF{ OO: ofxgo.OO{ FiTId: "76464632", SecId: ofxgo.SecurityId{ UniqueId: "922908645", UniqueIdType: "CUSIP", }, DtPlaced: ofxgo.Date(time.Date(2017, 3, 10, 12, 44, 45, 0, GMT)), Units: ofxgo.Amount(oounits1), SubAcct: "CASH", Duration: "GOODTILCANCEL", Restriction: "NONE", LimitPrice: ofxgo.Amount(oolimitprice1), }, BuyType: "BUY", UnitType: "SHARES", }, ofxgo.OOBuyStock{ OO: ofxgo.OO{ FiTId: "999387423", SecId: ofxgo.SecurityId{ UniqueId: "899422348", UniqueIdType: "CUSIP", }, DtPlaced: ofxgo.Date(time.Date(2017, 3, 24, 3, 19, 0, 0, GMT)), Units: ofxgo.Amount(oounits2), SubAcct: "CASH", Duration: "GOODTILCANCEL", Restriction: "ALLORNONE", LimitPrice: ofxgo.Amount(oolimitprice2), }, BuyType: "BUY", }, }, } expected.InvStmt = append(expected.InvStmt, &statementResponse) var yield1, yield2, strikeprice big.Rat yield1.SetFrac64(192, 100) yield2.SetFrac64(17, 1) strikeprice.SetFrac64(79, 1) seclist := ofxgo.SecurityList{ Securities: []ofxgo.Security{ ofxgo.StockInfo{ SecInfo: ofxgo.SecInfo{ SecId: ofxgo.SecurityId{ UniqueId: "78462F103", UniqueIdType: "CUSIP", }, SecName: "S&P 500 ETF", Ticker: "SPY", FiId: "99184", }, Yield: ofxgo.Amount(yield1), AssetClass: "OTHER", }, ofxgo.OptInfo{ SecInfo: ofxgo.SecInfo{ SecId: ofxgo.SecurityId{ UniqueId: "129887339", UniqueIdType: "CUSIP", }, SecName: "John's Fertilizer Puts", Ticker: "FERTP", FiId: "882919", }, OptType: "PUT", StrikePrice: ofxgo.Amount(strikeprice), DtExpire: ofxgo.Date(time.Date(2017, 9, 1, 0, 0, 0, 0, GMT)), ShPerCtrct: 100, SecId: &ofxgo.SecurityId{ UniqueId: "983322180", UniqueIdType: "CUSIP", }, AssetClass: "LARGESTOCK", }, ofxgo.StockInfo{ SecInfo: ofxgo.SecInfo{ SecId: ofxgo.SecurityId{ UniqueId: "899422348", UniqueIdType: "CUSIP", }, SecName: "Whatchamacallit, Inc.", Ticker: "WHAT", FiId: "883897", }, Yield: ofxgo.Amount(yield2), AssetClass: "SMALLSTOCK", }, ofxgo.MFInfo{ SecInfo: ofxgo.SecInfo{ SecId: ofxgo.SecurityId{ UniqueId: "922908645", UniqueIdType: "CUSIP", }, SecName: "Mid-Cap Index Fund Admiral Shares", Ticker: "VIMAX", }, }, }, } expected.SecList = append(expected.SecList, &seclist) response, err := ofxgo.ParseResponse(responseReader) if err != nil { t.Fatalf("Unexpected error unmarshalling response: %s\n", err) } checkResponsesEqual(t, &expected, response) }