/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
namespace QuantConnect
{
///
/// Markets Collection: Soon to be expanded to a collection of items specifying the market hour, timezones and country codes.
///
public static class Market
{
// the upper bound (non-inclusive) for market identifiers
private const int MaxMarketIdentifier = 1000;
private static readonly object _lock = new object();
private static readonly Dictionary Markets = new Dictionary();
private static readonly Dictionary ReverseMarkets = new Dictionary();
private static readonly IEnumerable> HardcodedMarkets = new List>
{
Tuple.Create("empty", 0),
Tuple.Create(USA, 1),
Tuple.Create(FXCM, 2),
Tuple.Create(Oanda, 3),
Tuple.Create(Dukascopy, 4),
Tuple.Create(Bitfinex, 5),
Tuple.Create(Globex, 6),
Tuple.Create(NYMEX, 7),
Tuple.Create(CBOT, 8),
Tuple.Create(ICE, 9),
Tuple.Create(CBOE, 10),
Tuple.Create(NSE, 11),
Tuple.Create(GDAX, 12),
Tuple.Create(Kraken, 13),
Tuple.Create(Bittrex, 14),
Tuple.Create(Bithumb, 15),
Tuple.Create(Binance, 16),
Tuple.Create(Poloniex, 17),
Tuple.Create(Coinone, 18),
Tuple.Create(HitBTC, 19),
Tuple.Create(OkCoin, 20),
Tuple.Create(Bitstamp, 21),
};
static Market()
{
// initialize our maps
foreach (var market in HardcodedMarkets)
{
Markets[market.Item1] = market.Item2;
ReverseMarkets[market.Item2] = market.Item1;
}
}
///
/// USA Market
///
public const string USA = "usa";
///
/// Oanda Market
///
public const string Oanda = "oanda";
///
/// FXCM Market Hours
///
public const string FXCM = "fxcm";
///
/// Dukascopy Market
///
public const string Dukascopy = "dukascopy";
///
/// Bitfinex market
///
public const string Bitfinex = "bitfinex";
// Futures exchanges
///
/// CME Globex
///
public const string Globex = "cmeglobex";
///
/// NYMEX
///
public const string NYMEX = "nymex";
///
/// CBOT
///
public const string CBOT = "cbot";
///
/// ICE
///
public const string ICE = "ice";
///
/// CBOE
///
public const string CBOE = "cboe";
///
/// NSE
///
public const string NSE = "nse";
///
/// GDAX
///
public const string GDAX = "gdax";
///
/// Kraken
///
public const string Kraken = "kraken";
///
/// Bitstamp
///
public const string Bitstamp = "bitstamp";
///
/// OkCoin
///
public const string OkCoin = "okcoin";
///
/// Bithumb
///
public const string Bithumb = "bithumb";
///
/// Binance
///
public const string Binance = "binance";
///
/// Poloniex
///
public const string Poloniex = "poloniex";
///
/// Coinone
///
public const string Coinone = "coinone";
///
/// HitBTC
///
public const string HitBTC = "hitbtc";
///
/// Bittrex
///
public const string Bittrex = "bittrex";
///
/// Adds the specified market to the map of available markets with the specified identifier.
///
/// The market string to add
/// The identifier for the market, this value must be positive and less than 1000
public static void Add(string market, int identifier)
{
if (identifier >= MaxMarketIdentifier)
{
var message = string.Format("The market identifier is limited to positive values less than {0}.", MaxMarketIdentifier);
throw new ArgumentOutOfRangeException("identifier", message);
}
market = market.ToLower();
// we lock since we don't want multiple threads getting these two dictionaries out of sync
lock (_lock)
{
int marketIdentifier;
if (Markets.TryGetValue(market, out marketIdentifier) && identifier != marketIdentifier)
{
throw new ArgumentException("Attempted to add an already added market with a different identifier. Market: " + market);
}
string existingMarket;
if (ReverseMarkets.TryGetValue(identifier, out existingMarket))
{
throw new ArgumentException("Attempted to add a market identifier that is already in use. New Market: " + market + " Existing Market: " + existingMarket);
}
// update our maps
Markets[market] = identifier;
ReverseMarkets[identifier] = market;
}
}
///
/// Gets the market code for the specified market. Returns null if the market is not found
///
/// The market to check for (case sensitive)
/// The internal code used for the market. Corresponds to the value used when calling
public static int? Encode(string market)
{
lock (_lock)
{
int code;
return !Markets.TryGetValue(market, out code) ? (int?) null : code;
}
}
///
/// Gets the market string for the specified market code.
///
/// The market code to be decoded
/// The string representation of the market, or null if not found
public static string Decode(int code)
{
lock (_lock)
{
string market;
return !ReverseMarkets.TryGetValue(code, out market) ? null : market;
}
}
}
}