c#编写fix接口量化交易系统源码demo

c#编写fix接口量化交易系统源码demo

using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using TradingFrontend.Enummerations;
using TradingFrontend.Managers.JsonObjects;
using TradingFrontend.Managers.Models;
using TradingFrontend.Managers.ViewModels;
using TradingFrontend.Utilities;
using UtilitiesLib.Json;
using UtilitiesLib.Windows;

namespace TradingFrontend.Managers
{
	public class OrderManager : Singleton<OrderManager>
	{
		/*
		 * Variables
		 */
		private const String m_broker = "FLEXTRADE";
		private ConcurrentDictionary<String, OrderModel> m_orders = new ConcurrentDictionary<string,OrderModel>(); // Key is OrderID
		private ConcurrentDictionary<String, PositionModel> m_positions = new ConcurrentDictionary<String, PositionModel>(); // Key is symbol

		private ObservableCollection<OrdersWindow_Order> m_ordersWindowPendingVMs = new ObservableCollection<OrdersWindow_Order>();
		private ObservableCollection<OrdersWindow_Order> m_ordersWindowExecutedVMs = new ObservableCollection<OrdersWindow_Order>();
		private ObservableCollection<OrdersWindow_Order> m_ordersWindowCancelledVMs = new ObservableCollection<OrdersWindow_Order>();
		private ObservableCollection<OrdersWindow_Order> m_ordersWindowProcessingVMs = new ObservableCollection<OrdersWindow_Order>();

		private ObservableCollection<PositionsWindow_Position> m_openPositionWindowVMs = new ObservableCollection<PositionsWindow_Position>();
		private ObservableCollection<PositionsWindow_Position> m_closedPositionWindowVMs = new ObservableCollection<PositionsWindow_Position>();

		private System.Threading.Mutex ordersCollectionMutex = new System.Threading.Mutex();
		private System.Threading.Mutex positionsCollectionMutex = new System.Threading.Mutex();

		#region Properties
		public ObservableCollection<OrdersWindow_Order> OrdersWindowPendingVMs { get { return m_ordersWindowPendingVMs; } }
		public ObservableCollection<OrdersWindow_Order> OrdersWindowExecutedVMs { get { return m_ordersWindowExecutedVMs; } }
		public ObservableCollection<OrdersWindow_Order> OrdersWindowCancelledVMs { get { return m_ordersWindowCancelledVMs; } }
		public ObservableCollection<OrdersWindow_Order> OrdersWindowProcessingVMs { get { return m_ordersWindowProcessingVMs; } }
		public ObservableCollection<PositionsWindow_Position> OpenPositionsWindowVMs { get { return m_openPositionWindowVMs; } }
		public ObservableCollection<PositionsWindow_Position> ClosedPositionsWindowVMs { get { return m_closedPositionWindowVMs; } }
		#endregion

		/*
		 * Public
		 */
		public void NewOrder(MarketDataModel marketData, String currency, OrderSide side, Double? quantity, OrderType orderType,
			OrderValidity? orderValidity, DateTimeOffset? expireTime, Double? limitPrice, Double? stopPrice, Action onSuccess)
		{
			// Nullify unused
			if (orderType != OrderType.LIMIT)
			{
				orderValidity = null;
				expireTime = null;
			}
			else if (orderValidity != OrderValidity.GTD)
			{
				expireTime = null;
			}

			if (orderType != OrderType.LIMIT && orderType != OrderType.OCO)
				limitPrice = null;

			if (orderType != OrderType.STOP && orderType != OrderType.OCO)
				stopPrice = null;

			// Get placed price
			Double? placedPrice;
			if (side.Equals(OrderSide.BUY))
				placedPrice = marketData.AskPrice;
			else
				placedPrice = marketData.BidPrice;

			// Set up request
			NewOrderReqJson newOrderReqJson = new NewOrderReqJson();
			newOrderReqJson.Token = AccountManager.Instance.Token;
			newOrderReqJson.TraderID = AccountManager.Instance.TraderId;
			newOrderReqJson.MarketDataID = marketData.MarketDataId;
			newOrderReqJson.Currency = currency;
			newOrderReqJson.Side = side.ToString();
			newOrderReqJson.Quantity = quantity;
			newOrderReqJson.OrderType = orderType.ToString();
			newOrderReqJson.Validity = (orderValidity.HasValue ? orderValidity.Value.ToString() : null);
			newOrderReqJson.ExpireTime = expireTime;
			newOrderReqJson.LimitPrice = limitPrice;
			newOrderReqJson.StopPrice = stopPrice;
			newOrderReqJson.PlacedPrice = placedPrice;
			newOrderReqJson.MaxPriceDeviation = SettingsManager.Instance.MaxPriceDeviation;

			// Send
			HttpManager.Instance.SendPostAsync("order/NewOrder", newOrderReqJson, true,
				// On success
				(NewOrderRespJson respObject) =>
				{
					// Create order
					OrderModel order = new OrderModel(respObject.OrderID, marketData.Symbol, currency, side, quantity, orderType,
						orderValidity, expireTime, limitPrice, stopPrice, respObject.PlacedTime, placedPrice);

					m_orders.TryAdd(order.Id, order);
					UpdatePosition(order.Symbol);
					UpdateOrderContainers(order);

					// Callback
					if (onSuccess != null)
						onSuccess();
				}, null, null);
		}

		public void ModifyOrder(OrderModel order, Double? quantity, Double? limitPrice, Double? stopPrice, Double? maxPriceDeviation, Action onSuccess)
		{
			// Set up request
			ModifyOrderReqJson modifyOrderReqJson = new ModifyOrderReqJson();
			modifyOrderReqJson.Token = AccountManager.Instance.Token;
			modifyOrderReqJson.TraderID = AccountManager.Instance.TraderId;
			modifyOrderReqJson.OrderID = order.Id;
			modifyOrderReqJson.Quantity = quantity;
			modifyOrderReqJson.LimitPrice = limitPrice;
			modifyOrderReqJson.StopPrice = stopPrice;
			modifyOrderReqJson.MaxPriceDeviation = maxPriceDeviation;

			// Send
			HttpManager.Instance.SendPostAsync("order/ModifyOrder", modifyOrderReqJson, true,
				// On success
				(ModifyOrderRespJson respObject) =>
				{
					// Update status
					order.Status = OrderStatus.PENDING_REPLACE;
					UpdatePosition(order.Symbol);
					UpdateOrderContainers(order);

					// Callback
					if (onSuccess != null)
						onSuccess();
				}, null, null);
		}

		public void CancelOrder(OrderModel order)
		{
			// Set up request
			CancelOrderReqJson cancelOrderReqJson = new CancelOrderReqJson();
			cancelOrderReqJson.Token = AccountManager.Instance.Token;
			cancelOrderReqJson.TraderID = AccountManager.Instance.TraderId;
			cancelOrderReqJson.OrderID = order.Id;

			// Send
			HttpManager.Instance.SendPostAsync("order/CancelOrder", cancelOrderReqJson, true,
				// On success
				(CancelOrderRespJson respObject) =>
				{
					// Update status
					order.Status = OrderStatus.PENDING_CANCEL;
					UpdatePosition(order.Symbol);
					UpdateOrderContainers(order);
				}, null, null);
		}

		public void CancelOrders(String symbol)
		{

			foreach (var orderPair in m_orders)
			{
				OrderModel order = orderPair.Value;

				// Check for matching symbol
				if (order.Symbol != symbol)
					continue;

				// Check if order can be cancelled
				if (order.Status == OrderStatus.CANCELLED || 
					order.Status == OrderStatus.REJECTED ||
					order.Status == OrderStatus.PENDING_NEW)
					continue;

				// Cancel
				CancelOrder(order);
			}
		}

		public void QueryOrder(String orderId)
		{
			// Set up request
			QueryOrderReqJson reqJson = new QueryOrderReqJson();
			reqJson.Token = AccountManager.Instance.Token;
			reqJson.TraderID = AccountManager.Instance.TraderId;
			reqJson.OrderID = orderId;

			// Send
			HttpManager.Instance.SendPostAsync("order/QueryOrder", reqJson, false,
				// On success
				(QueryOrderRespJson respObject) =>
				{
					OrderSide side = (OrderSide)Enum.Parse(typeof(OrderSide), respObject.Side);
					OrderStatus status = (OrderStatus)Enum.Parse(typeof(OrderStatus), respObject.OrderStatus);
					OrderType type = (OrderType)Enum.Parse(typeof(OrderType), respObject.OrderType);
					OrderValidity? validity = null;

					if (respObject.Validity != null)
						validity = (OrderValidity)Enum.Parse(typeof(OrderValidity), respObject.Validity);

					// Find order
					OrderModel order;
					m_orders.TryGetValue(orderId, out order);
					if (order != null)
					{
						// Update order
						order.Update(status, respObject.QuantityFilled, respObject.AvgPrice, respObject.Quantity,
							type, validity, respObject.ExpireTime, respObject.LimitPrice, respObject.StopPrice);
					}
					else
					{
						// Create order
						order = new OrderModel(orderId, respObject.Symbol, respObject.Currency, side, respObject.Quantity,
							type, validity, respObject.ExpireTime, respObject.LimitPrice, respObject.StopPrice, respObject.PlacedTime, respObject.PlacedPrice);
						order.Update(status, respObject.QuantityFilled, respObject.AvgPrice);

						m_orders.TryAdd(orderId, order);
					}

					// Update containers
					UpdatePosition(order.Symbol);
					UpdateOrderContainers(order);
				}, null, null);
		}

		public void UpdateOrder(String orderId, OrderStatus status, Double quantityFilled, Double avgPrice,
			Double? quantity, OrderType? type, OrderValidity? validity, DateTimeOffset? expireTime, Double? limitPrice,
			Double? stopPrice)
		{
			// Find order
			OrderModel order = null;
			m_orders.TryGetValue(orderId, out order);
			if(order != null)
			{
				// Update order
				order.Update(status, quantityFilled, avgPrice, quantity, type, validity, expireTime, limitPrice, stopPrice);

				// Update containers
				UpdatePosition(order.Symbol);
				UpdateOrderContainers(order);
			}
			else
			{
				// Query for order
				QueryOrder(orderId);
			}
		}

		public void LoadAccountOrders()
		{
			// Set up request
			QueryAccountOrdersReqJson queryAccountOrdersReqJson = new QueryAccountOrdersReqJson();
			queryAccountOrdersReqJson.Token = AccountManager.Instance.Token;
			queryAccountOrdersReqJson.Days = 1;

			// Send
			HttpManager.Instance.SendPostAsync("order/QueryAccountOrders", queryAccountOrdersReqJson, false,
				// On success
				(QueryAccountOrdersRespJson respObject) =>
				{
					// Add orders
					foreach(QueryAccountOrdersOrderJson orderJson in respObject.Orders)
					{
						OrderSide sideEnum = (OrderSide)Enum.Parse(typeof(OrderSide), orderJson.Side);
						OrderType orderTypeEnum = (OrderType)Enum.Parse(typeof(OrderType), orderJson.OrderType);
						OrderValidity? validityEnum = (orderJson.Validity != null ? (OrderValidity?)Enum.Parse(typeof(OrderValidity), orderJson.Validity) : null);
						OrderStatus statusEnum = (OrderStatus)Enum.Parse(typeof(OrderStatus), orderJson.OrderStatus);

						// Create order
						OrderModel order = new OrderModel(orderJson.OrderID, orderJson.Symbol, orderJson.Currency, sideEnum,
							orderJson.Quantity, orderTypeEnum, validityEnum, orderJson.ExpireTime, orderJson.LimitPrice,
							orderJson.StopPrice, orderJson.PlacedTime, orderJson.PlacedPrice);

						order.Update(statusEnum, orderJson.QuantityFilled, orderJson.AvgPrice);

						m_orders.TryAdd(order.Id, order);
						UpdatePosition(order.Symbol);
						UpdateOrderContainers(order);
					}
				}, null, null);
		}

		/*
		 * Private
		 */
		private void UpdateOrderContainers(OrderModel order)
		{
			App.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
			{
				ordersCollectionMutex.WaitOne();

				OrdersWindow_Order vm = new OrdersWindow_Order(order);

				// Remove item first
				m_ordersWindowProcessingVMs.Remove(vm);
				m_ordersWindowExecutedVMs.Remove(vm);
				m_ordersWindowCancelledVMs.Remove(vm);
				m_ordersWindowPendingVMs.Remove(vm);

				// Place in new container
				switch (order.Status)
				{
					case OrderStatus.PENDING_NEW:
					case OrderStatus.PENDING_REPLACE:
					case OrderStatus.PENDING_CANCEL:
						m_ordersWindowProcessingVMs.Add(vm);
						break;

					case OrderStatus.FILLED:
					case OrderStatus.DONE_FOR_DAY:
					case OrderStatus.EXPIRED:
						m_ordersWindowExecutedVMs.Add(vm);
						break;

					case OrderStatus.CANCELLED:
					case OrderStatus.STOPPED:
					case OrderStatus.REJECTED:
						m_ordersWindowCancelledVMs.Add(vm);
						break;

					default:
						m_ordersWindowPendingVMs.Add(vm);
						break;
				}

				ordersCollectionMutex.ReleaseMutex();
			}));
		}

		private void UpdatePosition(String symbol)
		{
			App.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
			{
				positionsCollectionMutex.WaitOne();

				// Create initial position if missing
				PositionModel position;
				m_positions.TryGetValue(symbol, out position);
				if (position == null)
				{
					position = new PositionModel(symbol);
					m_positions.TryAdd(symbol, position);
				}

				// Update position model
				Double totalBought = 0;
				Double totalSold = 0;
				Double totalBuy = 0;
				Double totalSell = 0;
				Double realizedProfit = 0;

				foreach (var orderPair in m_orders)
				{
					OrderModel order = orderPair.Value;

					// Check for matching symbol
					if (order.Symbol != symbol)
						continue;

					// Check if orders are closed
					bool closed = (order.Status == OrderStatus.FILLED ||
						order.Status == OrderStatus.DONE_FOR_DAY ||
						order.Status == OrderStatus.EXPIRED ||
						order.Status == OrderStatus.CANCELLED ||
						order.Status == OrderStatus.STOPPED ||
						order.Status == OrderStatus.REJECTED);


					// Accumulate sold / bought data
					switch (order.Side)
					{
						case OrderSide.BUY:
							totalBuy += (closed == false ? order.Quantity.Value : order.QuantityFilled.Value);
							totalBought += order.QuantityFilled.Value;
							realizedProfit -= order.QuantityFilled.Value * order.AvgPrice.Value;
							break;

						case OrderSide.SELL:
							totalSell += (closed == false ? order.Quantity.Value : order.QuantityFilled.Value);
							totalSold += order.QuantityFilled.Value;
							realizedProfit += order.QuantityFilled.Value * order.AvgPrice.Value;
							break;
					}
				}

				position.Update(totalBought, totalSold, totalBuy, totalSell, realizedProfit);

				// Update containers
				PositionsWindow_Position position_vm = new PositionsWindow_Position(position);

				m_openPositionWindowVMs.Remove(position_vm);
				m_closedPositionWindowVMs.Remove(position_vm);

				if (Math.Abs(position.TotalBuy - position.TotalBought) < 0.00001 &&
					Math.Abs(position.TotalSell - position.TotalSold) < 0.00001 && 
					Math.Abs(position.TotalBuy - position.TotalSell) < 0.00001)
				{
					m_closedPositionWindowVMs.Add(position_vm);
				}
				else
				{
					m_openPositionWindowVMs.Add(position_vm);
				}

				positionsCollectionMutex.ReleaseMutex();
			}));
		}
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

筱璦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值