コード例 #1
0
        public override void Update(TimeSlice slice)
        {
            decimal StillInvestedGetter(Operation o)
            {
                if (o.Symbol.Asset == Amount.Asset)
                {
                    return(o.AmountRemaining);
                }
                else if (o.Symbol.QuoteAsset == Amount.Asset)
                {
                    return(o.QuoteAmountRemaining);
                }
                else
                {
                    throw new NotSupportedException("Only supported operations where asset or quoteAsset coincide with budget asset");
                }
            }

            //check the free budget - the used budget is the sum of all money still invested in operations
            var totalInvested = Algo.ActiveOperations.Sum(StillInvestedGetter);
            var freeBudged    = MaxInvested - totalInvested;

            if (freeBudged <= 0)
            {
                Algo.StopEntries();
                PendingSignals.AddRange(slice.NewSignals);
            }
            else
            {
                Algo.ResumeEntries();

                //for each signal allocate a fixed amount
                foreach (Signal signal in slice.NewSignals)
                {
                    var newAmount = Amount.Amount;
                    if (ProportionalToProfit)
                    {
                        var profit = Math.Abs(signal.PriceTarget - signal.PriceEntry) / signal.PriceEntry;
                        newAmount = newAmount * TargetProfit / profit;
                    }

                    var symData = Algo.SymbolsData[signal.Symbol.Key];
                    if (symData.AllocatorData == null)
                    {
                        symData.AllocatorData = new MySymbolData();
                    }

                    DateTime lastInvestment = (symData.AllocatorData as MySymbolData).LastInvestmentTime;

                    if (Algo.Time >= lastInvestment + CoolDown && symData.ActiveOperations.Count < this.MaxActiveOperationsPerSymbol)
                    {
                        //if cooldown has elapsed we can open a new operation
                        var freeSymbolBudget = MaxInvestedPerSymbol - Algo.Executor.GetInvestedOrLockedAmount(signal.Symbol, Amount.Asset);

                        var budget = new[] { freeSymbolBudget, freeBudged, newAmount }.Min();

                        if (budget >= 0.2m * newAmount)
                        {
                            //create operations
                            var operType = signal.Kind == SignalKind.Buy ? OperationType.BuyThenSell : OperationType.SellThenBuy;
                            var newOper  = new Operation(Algo.GetNewOperationId(), signal, new AssetAmount(Amount.Asset, budget), operType);
                            newOper.OnNewTrade += (o, t) => { (symData.AllocatorData as MySymbolData).LastInvestmentTime = t.Time; };
                            slice.Add(newOper);
                        }
                        else
                        {
                            PendingSignals.Add(signal);
                        }
                    }
                }
                //todo it is possible that for a given symbol some budget get freed , in this case we should allocate this margin to existent operations
            }
        }
コード例 #2
0
 private void Feed_OnData(ISymbolFeed symFeed, IBaseData dataRecord)
 {
     //todo bisogna accertartci che i dati che riceviamo sono del giusto timeframe!
     lock (WorkingSliceLock)
         WorkingSlice.Add(symFeed.Symbol, dataRecord);
 }