/// <summary> /// Create a new order /// </summary> /// <param name="instrument">Required Instrument to open the order on</param> /// <param name="units">Required The number of units to open order for</param> /// <param name="side">Required Direction of the order, either "buy" or "sell"</param> /// <param name="expiry">Required If order type is "limit", "stop", or "marketIfTouched". The order expiration time in UTC. The value specified must be in a valid datetime format</param> /// <param name="price">Required If order type is "limit", "stop", or "marketIfTouched". The price where the order is set to trigger at</param> /// <returns></returns> public async Task<OrderMarketIfTouchedOpen> CreateMarketIfTouchedOrder(string instrument, int units, OandaTypes.Side side, DateTime expiry, float price) { Dictionary<string, string> routeParams = new Dictionary<string, string>(); routeParams.Add("accountId", _accountId.ToString()); Dictionary<string, string> properties = new Dictionary<string, string>(); properties.Add("instrument", instrument); properties.Add("units", units.ToString()); properties.Add("side", side.ToString()); properties.Add("type", OandaTypes.OrderType.marketIfTouched.ToString()); properties.Add("expiry", expiry.ToString("o")); properties.Add("price", price.ToString()); OrderMarketIfTouchedOpen orderMarketIfTouchedOpen = await Post<OrderMarketIfTouchedOpen>(routeParams, properties, _ordersRoute); return orderMarketIfTouchedOpen; }
/// <summary> /// Create a new order /// </summary> /// <param name="instrument">Required Instrument to open the order on</param> /// <param name="units">Required The number of units to open order for</param> /// <param name="side">Required Direction of the order, either "buy" or "sell"</param> /// <param name="type">Required The type of the order "limit", "stop", "marketIfTouched’ or "market"</param> /// <param name="expiry">Required If order type is "limit", "stop", or "marketIfTouched". The order expiration time in UTC. The value specified must be in a valid datetime format</param> /// <param name="price">Required If order type is "limit", "stop", or "marketIfTouched". The price where the order is set to trigger at</param> /// <param name="lowerBound">Optional The minimum execution price</param> /// <param name="upperBound">Optional The maximum execution price</param> /// <param name="stopLoss">The stop loss price</param> /// <param name="takeProfit">Optional The take profit price</param> /// <param name="trailingStop">Optional The trailing stop distance in pips, up to one decimal place</param> /// <returns></returns> public async Task<OrderOpen> CreateOrder(string instrument, int units, OandaTypes.Side side, OandaTypes.OrderType type, DateTime? expiry, float? price, float? lowerBound, float? upperBound, float? stopLoss, float? takeProfit, float? trailingStop) { Dictionary<string, string> routeParams = new Dictionary<string, string>(); routeParams.Add("accountId", _accountId.ToString()); Dictionary<string, string> properties = new Dictionary<string, string>(); properties.Add("instrument", instrument); properties.Add("units", units.ToString()); properties.Add("side", side.ToString()); properties.Add("type", type.ToString()); if (expiry != null) properties.Add("expiry", expiry.Value.ToString("o")); if (price != null) properties.Add("price", price.ToString()); if (lowerBound != null) properties.Add("lowerBound", lowerBound.ToString()); if (upperBound != null) properties.Add("upperBound", upperBound.ToString()); if (stopLoss != null) properties.Add("stopLoss", stopLoss.ToString()); if (takeProfit != null) properties.Add("takeProfit", takeProfit.ToString()); if (trailingStop != null) properties.Add("trailingStop", trailingStop.ToString()); if (type == OandaTypes.OrderType.market) { OrderMarketOpen orderMarket = await Post<OrderMarketOpen>(routeParams, properties, _ordersRoute); return orderMarket; } else { OrderCustumOpen customOrder = await Post<OrderCustumOpen>(routeParams, properties, _ordersRoute); return customOrder; } }
/// <summary> /// Create a new market order /// </summary> /// <param name="instrument">Required Instrument to open the order on</param> /// <param name="units">Required The number of units to open order for</param> /// <param name="side">Required Direction of the order, either "buy" or "sell"</param> /// <param name="stopLoss">The stop loss price</param> /// <param name="takeProfit">Optional The take profit price</param> /// <returns></returns> public async Task<OrderMarketOpen> CreateMarketOrder(string instrument, int units, OandaTypes.Side side, float stopLoss, float takeProfit) { Dictionary<string, string> routeParams = new Dictionary<string, string>(); routeParams.Add("accountId", _accountId.ToString()); Dictionary<string, string> properties = new Dictionary<string, string>(); properties.Add("instrument", instrument); properties.Add("units", units.ToString()); properties.Add("side", side.ToString()); properties.Add("stopLoss", stopLoss.ToString()); properties.Add("takeProfit", takeProfit.ToString()); properties.Add("type", OandaTypes.OrderType.market.ToString()); OrderMarketOpen orderMarketOpen = await Post<OrderMarketOpen>(routeParams, properties, _ordersRoute); return orderMarketOpen; }
/// <summary> /// Get a list of open trades (especially usefull for closing trades in FIFO style) /// </summary> /// <param name="instrument">Retrieve open trades for a specific instrument only</param> /// <param name="side">Retrieve open trades for a specific side only</param> /// <param name="units">Retrieve open trades with a specific number of units</param> /// <returns></returns> public async Task<List<Trade>> GetTrades(string instrument, OandaTypes.Side side, int units) { Dictionary<string, string> routeParams = new Dictionary<string, string>(); routeParams.Add("accountId", _accountId.ToString()); Dictionary<string, object> properties = new Dictionary<string, object>(); properties.Add("instrument", instrument); TradesWrapper tradesWrapper = await Get<TradesWrapper>(routeParams, properties, _tradesRoute); return tradesWrapper.Trades.Where(x => x.Side == side && x.Units == units).OrderBy(x => x.Id).ToList(); }
/// <summary> /// Close an open trade by using th FIFO algorithem... /// </summary> /// <param name="instrument">Retrieve open trades for a specific instrument only</param> /// <param name="side">Retrieve open trades for a specific side only</param> /// <param name="units">Retrieve open trades with a specific number of units</param> /// <returns></returns> public async Task<TradeClosed> CloseTrade(string instrument, OandaTypes.Side side, int units) { TradeClosed tradeClosed; List<Trade> trades = await GetTrades(instrument, side, units); if (trades.Any()) { // FIFO algorithem is implemented because GetTrades() is ordered by TradeId ascending... tradeClosed = await CloseTrade(trades.First().Id); } else { throw new Exception(string.Format("No trade closed because no trades were found for Instrument: {0}, Side: {1} and Units: {2}.", instrument, side, units)); } return tradeClosed; }
private Dictionary<string, object> MakeCandle(string instrument, OandaTypes.GranularityType? granularity, int? count, DateTime? start, DateTime? end, OandaTypes.CandleFormat? candleFormat, bool? includeFirst, byte? dailyAlignment, OandaTypes.WeeklyAlignment? weeklyAlignment) { Dictionary<string, object> fields = new Dictionary<string, object>(); if (string.IsNullOrWhiteSpace(instrument)) throw new Exception("The instrument param can't be empty or null"); fields.Add("instrument", instrument); if (granularity == null) granularity = OandaTypes.GranularityType.S5; fields.Add("granularity", granularity); if (count != null && start == null && end == null) fields.Add("count", count); if (start != null && end != null) { fields.Add("start", start.Value.ToString("o")); fields.Add("end", end.Value.ToString("o")); } else if (start != null) { fields.Add("start", start.Value.ToString("o")); } if (candleFormat != null) fields.Add("candleFormat", candleFormat.ToString()); if (includeFirst == null) includeFirst = true; if (start != null) fields.Add("includeFirst", includeFirst.ToString().ToLower()); if (dailyAlignment == null) { dailyAlignment = 22; } else if (dailyAlignment > 23) throw new Exception("The dailyAlignment must be between 0 and 23"); fields.Add("dailyAlignment", dailyAlignment); if (weeklyAlignment == null) weeklyAlignment = OandaTypes.WeeklyAlignment.Friday; fields.Add("weeklyAlignment", weeklyAlignment.ToString()); return fields; }
/// <summary> /// Retrieve instrument history /// Get historical information on an instrument /// </summary> /// <param name="instrument"> /// Required Name of the instrument to retrieve history for. /// The instrument should be one of the available instrument from the /v1/instruments response /// </param> /// <param name="granularity"> /// Optional The time range represented by each candlestick. The value specified will determine the alignment of the first candlestick. /// </param> /// <param name="count"> /// The number of candles to return in the response. /// This parameter may be ignored by the server depending on the time range provided. /// See “Time and Count Semantics” below for a full description. /// If not specified, count will default to 500. The maximum acceptable value for count is 5000. /// Count should not be specified if both the start and end parameters are also specified. /// </param> /// <param name="candleFormat"> /// Candlesticks representation (about candestick representation). /// This can be one of the following: “midpoint” - Midpoint based candlesticks. /// “bidask” - Bid/Ask based candlesticks The default for candleFormat is “bidask” if the candleFormat parameter is not specified. /// </param> /// <param name="includeFirst"> /// A boolean field which may be set to “true” or “false”. /// If it is set to “true”, the candlestick covered by the start timestamp will be returned. /// If it is set to “false”, this candlestick will not be returned. /// This field exists so clients may easily ensure that they can poll for all candles more recent than their last received candle. /// The default for includeFirst is “true” if the includeFirst parameter is not specified. /// </param> /// <param name="dailyAlignment"> /// The hour of day used to align candles with hourly, daily, weekly, or monthly granularity. /// The value specified is interpretted as an hour in the timezone set through the /// alignmentTimezone parameter and must be an integer between 0 and 23. /// The default for dailyAlignment is 21 when Eastern Daylight Time is in effect and 22 when /// Eastern Standard Time is in effect. This corresponds to 17:00 local time in New York. /// </param> /// <param name="weeklyAlignment"> /// Optional The timezone to be used for the dailyAlignment parameter. /// This parameter does NOT affect the returned timestamp, the start or end parameters, these will always be in UTC. /// The timezone format used is defined by the http://en.wikipedia.org/wiki/Tz_database, a full list of the /// timezones supported by the REST API can be found http://developer.oanda.com/docs/timezones.txt. /// </param> /// <returns></returns> /// <returns></returns> public async Task<object> GetCandles(string instrument, OandaTypes.GranularityType? granularity, int? count, OandaTypes.CandleFormat? candleFormat, bool? includeFirst, byte? dailyAlignment, OandaTypes.WeeklyAlignment? weeklyAlignment) { Dictionary<string, object> properties = MakeCandle(instrument, granularity, count, null, null, candleFormat, includeFirst, dailyAlignment, weeklyAlignment); object candle = null; if (candleFormat == OandaTypes.CandleFormat.bidask) { candle = await Get<Candle<CandleBidAsk>>(null, properties, _candleRoute); } else if (candleFormat == OandaTypes.CandleFormat.midpoint) { candle = await Get<Candle<CandleMid>>(null, properties, _candleRoute); } return candle; }
/// <summary> /// Retrieve instrument history /// Get historical information on an instrument /// </summary> /// <param name="instrument"> /// Required Name of the instrument to retrieve history for. /// The instrument should be one of the available instrument from the /v1/instruments response /// </param> /// <param name="granularity"> /// Optional The time range represented by each candlestick. The value specified will determine the alignment of the first candlestick. /// </param> /// <param name="start"> /// The start timestamp for the range of candles requested. The value specified must be in a valid datetime format. /// </param> /// <param name="end"> /// The end timestamp for the range of candles requested. The value specified must be in a valid datetime format. /// </param> /// <returns></returns> public async Task<Candle<CandleMid>> GetCandlesMid(string instrument, OandaTypes.GranularityType granularity, DateTime start, DateTime end) { Dictionary<string, object> properties = new Dictionary<string, object>(); properties.Add("instrument", instrument); properties.Add("granularity", granularity); properties.Add("start", start.ToString("o")); properties.Add("end", end.ToString("o")); properties.Add("candleFormat", OandaTypes.CandleFormat.midpoint); Candle<CandleMid> result = await Get<Candle<CandleMid>>(null, properties, _candleRoute); return result; }
/// <summary> /// Retrieve instrument history /// Get historical information on an instrument /// </summary> /// <param name="instrument"> /// Required Name of the instrument to retrieve history for. /// The instrument should be one of the available instrument from the /v1/instruments response /// </param> /// <param name="granularity"> /// Optional The time range represented by each candlestick. The value specified will determine the alignment of the first candlestick. /// </param> /// <param name="count"> /// The number of candles to return in the response. /// This parameter may be ignored by the server depending on the time range provided. /// See “Time and Count Semantics” below for a full description. /// If not specified, count will default to 500. The maximum acceptable value for count is 5000. /// Count should not be specified if both the start and end parameters are also specified. /// </param> /// <returns></returns> public async Task<Candle<CandleMid>> GetCandlesMid(string instrument, OandaTypes.GranularityType granularity, int count) { Dictionary<string, object> properties = new Dictionary<string, object>(); properties.Add("instrument", instrument); properties.Add("granularity", granularity); properties.Add("count", count); properties.Add("candleFormat", OandaTypes.CandleFormat.midpoint); Candle<CandleMid> result = await Get<Candle<CandleMid>>(null, properties, _candleRoute); return result; }
/// <summary> /// Retrieve instrument history /// Get historical information on an instrument /// </summary> /// <param name="instrument"> /// Required Name of the instrument to retrieve history for. /// The instrument should be one of the available instrument from the /v1/instruments response /// </param> /// <param name="granularity"> /// Optional The time range represented by each candlestick. The value specified will determine the alignment of the first candlestick. /// </param> /// <returns></returns> public async Task<Candle<CandleBidAsk>> GetCandles(string instrument, OandaTypes.GranularityType granularity) { Dictionary<string, object> properties = new Dictionary<string, object>(); properties.Add("instrument", instrument); properties.Add("granularity", granularity); properties.Add("candleFormat", OandaTypes.CandleFormat.bidask); Candle<CandleBidAsk> result = await Get<Candle<CandleBidAsk>>(null, properties, _candleRoute); return result; }